From bb1892e45841c10938ccd658665f8a3ecb5b0aa8 Mon Sep 17 00:00:00 2001 From: brilliantjc Date: Tue, 12 Feb 2019 10:04:28 -0800 Subject: [PATCH] something --- .DS_Store | Bin 0 -> 8196 bytes flaskr/.DS_Store | Bin 0 -> 8196 bytes flaskr/__init__.py | 43 + flaskr/__init__.pyc | Bin 0 -> 1373 bytes flaskr/auth.py | 93 + flaskr/auth.pyc | Bin 0 -> 3342 bytes flaskr/base.html | 24 + flaskr/blog.py | 100 + flaskr/blog.pyc | Bin 0 -> 3311 bytes flaskr/db.py | 43 + flaskr/db.pyc | Bin 0 -> 1882 bytes flaskr/login.html | 15 + flaskr/register.html | 15 + flaskr/schema.sql | 17 + flaskr/static/style.css | 26 + flaskr/templates/.DS_Store | Bin 0 -> 6148 bytes flaskr/templates/auth/.DS_Store | Bin 0 -> 6148 bytes flaskr/templates/auth/login.html | 15 + flaskr/templates/auth/register.html | 15 + flaskr/templates/base.html | 24 + flaskr/templates/blog/create.html | 15 + flaskr/templates/blog/index.html | 28 + flaskr/templates/blog/update.html | 20 + instance/flaskr.sqlite | Bin 0 -> 20480 bytes venv/bin/activate | 76 + venv/bin/activate.csh | 37 + venv/bin/activate.fish | 75 + venv/bin/easy_install | 11 + venv/bin/easy_install-3.7 | 11 + venv/bin/pip | 11 + venv/bin/pip3 | 11 + venv/bin/pip3.7 | 11 + venv/bin/python | 1 + venv/bin/python3 | 1 + .../__pycache__/easy_install.cpython-37.pyc | Bin 0 -> 333 bytes .../python3.7/site-packages/easy_install.py | 5 + .../pip-18.1.dist-info/INSTALLER | 1 + .../pip-18.1.dist-info/LICENSE.txt | 20 + .../site-packages/pip-18.1.dist-info/METADATA | 70 + .../site-packages/pip-18.1.dist-info/RECORD | 614 ++ .../site-packages/pip-18.1.dist-info/WHEEL | 6 + .../pip-18.1.dist-info/entry_points.txt | 5 + .../pip-18.1.dist-info/top_level.txt | 1 + .../python3.7/site-packages/pip/__init__.py | 1 + .../python3.7/site-packages/pip/__main__.py | 19 + .../pip/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 204 bytes .../pip/__pycache__/__main__.cpython-37.pyc | Bin 0 -> 458 bytes .../site-packages/pip/_internal/__init__.py | 78 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1850 bytes .../__pycache__/build_env.cpython-37.pyc | Bin 0 -> 5059 bytes .../__pycache__/cache.cpython-37.pyc | Bin 0 -> 6844 bytes .../__pycache__/configuration.cpython-37.pyc | Bin 0 -> 9843 bytes .../__pycache__/download.cpython-37.pyc | Bin 0 -> 20911 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 11564 bytes .../__pycache__/index.cpython-37.pyc | Bin 0 -> 23173 bytes .../__pycache__/locations.cpython-37.pyc | Bin 0 -> 4240 bytes .../__pycache__/pep425tags.cpython-37.pyc | Bin 0 -> 7299 bytes .../__pycache__/pyproject.cpython-37.pyc | Bin 0 -> 2723 bytes .../__pycache__/resolve.cpython-37.pyc | Bin 0 -> 8490 bytes .../__pycache__/wheel.cpython-37.pyc | Bin 0 -> 20852 bytes .../site-packages/pip/_internal/build_env.py | 142 + .../site-packages/pip/_internal/cache.py | 202 + .../pip/_internal/cli/__init__.py | 4 + .../cli/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 281 bytes .../__pycache__/autocompletion.cpython-37.pyc | Bin 0 -> 5094 bytes .../__pycache__/base_command.cpython-37.pyc | Bin 0 -> 6319 bytes .../cli/__pycache__/cmdoptions.cpython-37.pyc | Bin 0 -> 15040 bytes .../__pycache__/main_parser.cpython-37.pyc | Bin 0 -> 2241 bytes .../cli/__pycache__/parser.cpython-37.pyc | Bin 0 -> 8945 bytes .../__pycache__/status_codes.cpython-37.pyc | Bin 0 -> 410 bytes .../pip/_internal/cli/autocompletion.py | 152 + .../pip/_internal/cli/base_command.py | 278 + .../pip/_internal/cli/cmdoptions.py | 714 ++ .../pip/_internal/cli/main_parser.py | 96 + .../site-packages/pip/_internal/cli/parser.py | 261 + .../pip/_internal/cli/status_codes.py | 8 + .../pip/_internal/commands/__init__.py | 79 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2509 bytes .../commands/__pycache__/check.cpython-37.pyc | Bin 0 -> 1311 bytes .../__pycache__/completion.cpython-37.pyc | Bin 0 -> 3083 bytes .../__pycache__/configuration.cpython-37.pyc | Bin 0 -> 6435 bytes .../__pycache__/download.cpython-37.pyc | Bin 0 -> 4663 bytes .../__pycache__/freeze.cpython-37.pyc | Bin 0 -> 2879 bytes .../commands/__pycache__/hash.cpython-37.pyc | Bin 0 -> 2073 bytes .../commands/__pycache__/help.cpython-37.pyc | Bin 0 -> 1249 bytes .../__pycache__/install.cpython-37.pyc | Bin 0 -> 11845 bytes .../commands/__pycache__/list.cpython-37.pyc | Bin 0 -> 8922 bytes .../__pycache__/search.cpython-37.pyc | Bin 0 -> 4315 bytes .../commands/__pycache__/show.cpython-37.pyc | Bin 0 -> 5896 bytes .../__pycache__/uninstall.cpython-37.pyc | Bin 0 -> 2705 bytes .../commands/__pycache__/wheel.cpython-37.pyc | Bin 0 -> 4926 bytes .../pip/_internal/commands/check.py | 41 + .../pip/_internal/commands/completion.py | 94 + .../pip/_internal/commands/configuration.py | 227 + .../pip/_internal/commands/download.py | 174 + .../pip/_internal/commands/freeze.py | 96 + .../pip/_internal/commands/hash.py | 57 + .../pip/_internal/commands/help.py | 37 + .../pip/_internal/commands/install.py | 535 ++ .../pip/_internal/commands/list.py | 306 + .../pip/_internal/commands/search.py | 135 + .../pip/_internal/commands/show.py | 168 + .../pip/_internal/commands/uninstall.py | 78 + .../pip/_internal/commands/wheel.py | 183 + .../pip/_internal/configuration.py | 387 + .../site-packages/pip/_internal/download.py | 921 ++ .../site-packages/pip/_internal/exceptions.py | 268 + .../site-packages/pip/_internal/index.py | 899 ++ .../site-packages/pip/_internal/locations.py | 194 + .../pip/_internal/models/__init__.py | 2 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 269 bytes .../__pycache__/candidate.cpython-37.pyc | Bin 0 -> 1104 bytes .../__pycache__/format_control.cpython-37.pyc | Bin 0 -> 2439 bytes .../models/__pycache__/index.cpython-37.pyc | Bin 0 -> 1173 bytes .../models/__pycache__/link.cpython-37.pyc | Bin 0 -> 4771 bytes .../pip/_internal/models/candidate.py | 23 + .../pip/_internal/models/format_control.py | 62 + .../pip/_internal/models/index.py | 29 + .../pip/_internal/models/link.py | 141 + .../pip/_internal/operations/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 205 bytes .../__pycache__/check.cpython-37.pyc | Bin 0 -> 3382 bytes .../__pycache__/freeze.cpython-37.pyc | Bin 0 -> 6337 bytes .../__pycache__/prepare.cpython-37.pyc | Bin 0 -> 9203 bytes .../pip/_internal/operations/check.py | 148 + .../pip/_internal/operations/freeze.py | 264 + .../pip/_internal/operations/prepare.py | 355 + .../site-packages/pip/_internal/pep425tags.py | 317 + .../site-packages/pip/_internal/pyproject.py | 144 + .../pip/_internal/req/__init__.py | 69 + .../req/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1573 bytes .../__pycache__/constructors.cpython-37.pyc | Bin 0 -> 6971 bytes .../req/__pycache__/req_file.cpython-37.pyc | Bin 0 -> 8672 bytes .../__pycache__/req_install.cpython-37.pyc | Bin 0 -> 22822 bytes .../req/__pycache__/req_set.cpython-37.pyc | Bin 0 -> 5786 bytes .../__pycache__/req_tracker.cpython-37.pyc | Bin 0 -> 2897 bytes .../__pycache__/req_uninstall.cpython-37.pyc | Bin 0 -> 12869 bytes .../pip/_internal/req/constructors.py | 298 + .../pip/_internal/req/req_file.py | 340 + .../pip/_internal/req/req_install.py | 860 ++ .../pip/_internal/req/req_set.py | 181 + .../pip/_internal/req/req_tracker.py | 76 + .../pip/_internal/req/req_uninstall.py | 460 + .../site-packages/pip/_internal/resolve.py | 353 + .../pip/_internal/utils/__init__.py | 0 .../utils/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 200 bytes .../utils/__pycache__/appdirs.cpython-37.pyc | Bin 0 -> 7921 bytes .../utils/__pycache__/compat.cpython-37.pyc | Bin 0 -> 5991 bytes .../__pycache__/deprecation.cpython-37.pyc | Bin 0 -> 2574 bytes .../utils/__pycache__/encoding.cpython-37.pyc | Bin 0 -> 1136 bytes .../__pycache__/filesystem.cpython-37.pyc | Bin 0 -> 667 bytes .../utils/__pycache__/glibc.cpython-37.pyc | Bin 0 -> 1558 bytes .../utils/__pycache__/hashes.cpython-37.pyc | Bin 0 -> 3335 bytes .../utils/__pycache__/logging.cpython-37.pyc | Bin 0 -> 5368 bytes .../utils/__pycache__/misc.cpython-37.pyc | Bin 0 -> 23914 bytes .../utils/__pycache__/models.cpython-37.pyc | Bin 0 -> 1949 bytes .../utils/__pycache__/outdated.cpython-37.pyc | Bin 0 -> 3921 bytes .../__pycache__/packaging.cpython-37.pyc | Bin 0 -> 2400 bytes .../setuptools_build.cpython-37.pyc | Bin 0 -> 395 bytes .../utils/__pycache__/temp_dir.cpython-37.pyc | Bin 0 -> 2812 bytes .../utils/__pycache__/typing.cpython-37.pyc | Bin 0 -> 1344 bytes .../utils/__pycache__/ui.cpython-37.pyc | Bin 0 -> 11869 bytes .../pip/_internal/utils/appdirs.py | 258 + .../pip/_internal/utils/compat.py | 248 + .../pip/_internal/utils/deprecation.py | 89 + .../pip/_internal/utils/encoding.py | 33 + .../pip/_internal/utils/filesystem.py | 28 + .../pip/_internal/utils/glibc.py | 84 + .../pip/_internal/utils/hashes.py | 94 + .../pip/_internal/utils/logging.py | 225 + .../site-packages/pip/_internal/utils/misc.py | 940 ++ .../pip/_internal/utils/models.py | 40 + .../pip/_internal/utils/outdated.py | 154 + .../pip/_internal/utils/packaging.py | 75 + .../pip/_internal/utils/setuptools_build.py | 8 + .../pip/_internal/utils/temp_dir.py | 82 + .../pip/_internal/utils/typing.py | 29 + .../site-packages/pip/_internal/utils/ui.py | 421 + .../pip/_internal/vcs/__init__.py | 509 + .../vcs/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 15566 bytes .../vcs/__pycache__/bazaar.cpython-37.pyc | Bin 0 -> 3829 bytes .../vcs/__pycache__/git.cpython-37.pyc | Bin 0 -> 9134 bytes .../vcs/__pycache__/mercurial.cpython-37.pyc | Bin 0 -> 3802 bytes .../vcs/__pycache__/subversion.cpython-37.pyc | Bin 0 -> 6404 bytes .../site-packages/pip/_internal/vcs/bazaar.py | 112 + .../site-packages/pip/_internal/vcs/git.py | 346 + .../pip/_internal/vcs/mercurial.py | 101 + .../pip/_internal/vcs/subversion.py | 213 + .../site-packages/pip/_internal/wheel.py | 831 ++ .../site-packages/pip/_vendor/__init__.py | 110 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2870 bytes .../__pycache__/appdirs.cpython-37.pyc | Bin 0 -> 20617 bytes .../_vendor/__pycache__/distro.cpython-37.pyc | Bin 0 -> 36150 bytes .../__pycache__/ipaddress.cpython-37.pyc | Bin 0 -> 66460 bytes .../__pycache__/pyparsing.cpython-37.pyc | Bin 0 -> 203064 bytes .../__pycache__/retrying.cpython-37.pyc | Bin 0 -> 8098 bytes .../_vendor/__pycache__/six.cpython-37.pyc | Bin 0 -> 25003 bytes .../site-packages/pip/_vendor/appdirs.py | 604 ++ .../pip/_vendor/cachecontrol/__init__.py | 11 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 558 bytes .../__pycache__/_cmd.cpython-37.pyc | Bin 0 -> 1561 bytes .../__pycache__/adapter.cpython-37.pyc | Bin 0 -> 3044 bytes .../__pycache__/cache.cpython-37.pyc | Bin 0 -> 1774 bytes .../__pycache__/compat.cpython-37.pyc | Bin 0 -> 765 bytes .../__pycache__/controller.cpython-37.pyc | Bin 0 -> 7644 bytes .../__pycache__/filewrapper.cpython-37.pyc | Bin 0 -> 2162 bytes .../__pycache__/heuristics.cpython-37.pyc | Bin 0 -> 4682 bytes .../__pycache__/serialize.cpython-37.pyc | Bin 0 -> 4246 bytes .../__pycache__/wrapper.cpython-37.pyc | Bin 0 -> 666 bytes .../pip/_vendor/cachecontrol/_cmd.py | 57 + .../pip/_vendor/cachecontrol/adapter.py | 133 + .../pip/_vendor/cachecontrol/cache.py | 39 + .../_vendor/cachecontrol/caches/__init__.py | 2 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 302 bytes .../__pycache__/file_cache.cpython-37.pyc | Bin 0 -> 3236 bytes .../__pycache__/redis_cache.cpython-37.pyc | Bin 0 -> 1558 bytes .../_vendor/cachecontrol/caches/file_cache.py | 146 + .../cachecontrol/caches/redis_cache.py | 33 + .../pip/_vendor/cachecontrol/compat.py | 29 + .../pip/_vendor/cachecontrol/controller.py | 367 + .../pip/_vendor/cachecontrol/filewrapper.py | 80 + .../pip/_vendor/cachecontrol/heuristics.py | 135 + .../pip/_vendor/cachecontrol/serialize.py | 186 + .../pip/_vendor/cachecontrol/wrapper.py | 29 + .../pip/_vendor/certifi/__init__.py | 3 + .../pip/_vendor/certifi/__main__.py | 2 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 285 bytes .../__pycache__/__main__.cpython-37.pyc | Bin 0 -> 268 bytes .../certifi/__pycache__/core.cpython-37.pyc | Bin 0 -> 1220 bytes .../pip/_vendor/certifi/cacert.pem | 4300 +++++++++ .../site-packages/pip/_vendor/certifi/core.py | 37 + .../pip/_vendor/chardet/__init__.py | 39 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 852 bytes .../__pycache__/big5freq.cpython-37.pyc | Bin 0 -> 27187 bytes .../__pycache__/big5prober.cpython-37.pyc | Bin 0 -> 1128 bytes .../chardistribution.cpython-37.pyc | Bin 0 -> 6314 bytes .../charsetgroupprober.cpython-37.pyc | Bin 0 -> 2235 bytes .../__pycache__/charsetprober.cpython-37.pyc | Bin 0 -> 3445 bytes .../codingstatemachine.cpython-37.pyc | Bin 0 -> 2892 bytes .../chardet/__pycache__/compat.cpython-37.pyc | Bin 0 -> 363 bytes .../__pycache__/cp949prober.cpython-37.pyc | Bin 0 -> 1135 bytes .../chardet/__pycache__/enums.cpython-37.pyc | Bin 0 -> 2626 bytes .../__pycache__/escprober.cpython-37.pyc | Bin 0 -> 2613 bytes .../chardet/__pycache__/escsm.cpython-37.pyc | Bin 0 -> 7074 bytes .../__pycache__/eucjpprober.cpython-37.pyc | Bin 0 -> 2421 bytes .../__pycache__/euckrfreq.cpython-37.pyc | Bin 0 -> 12071 bytes .../__pycache__/euckrprober.cpython-37.pyc | Bin 0 -> 1136 bytes .../__pycache__/euctwfreq.cpython-37.pyc | Bin 0 -> 27191 bytes .../__pycache__/euctwprober.cpython-37.pyc | Bin 0 -> 1136 bytes .../__pycache__/gb2312freq.cpython-37.pyc | Bin 0 -> 19115 bytes .../__pycache__/gb2312prober.cpython-37.pyc | Bin 0 -> 1144 bytes .../__pycache__/hebrewprober.cpython-37.pyc | Bin 0 -> 2978 bytes .../__pycache__/jisfreq.cpython-37.pyc | Bin 0 -> 22143 bytes .../chardet/__pycache__/jpcntx.cpython-37.pyc | Bin 0 -> 38022 bytes .../langbulgarianmodel.cpython-37.pyc | Bin 0 -> 23636 bytes .../langcyrillicmodel.cpython-37.pyc | Bin 0 -> 29092 bytes .../__pycache__/langgreekmodel.cpython-37.pyc | Bin 0 -> 23594 bytes .../langhebrewmodel.cpython-37.pyc | Bin 0 -> 22223 bytes .../langhungarianmodel.cpython-37.pyc | Bin 0 -> 23625 bytes .../__pycache__/langthaimodel.cpython-37.pyc | Bin 0 -> 22202 bytes .../langturkishmodel.cpython-37.pyc | Bin 0 -> 22225 bytes .../__pycache__/latin1prober.cpython-37.pyc | Bin 0 -> 2935 bytes .../mbcharsetprober.cpython-37.pyc | Bin 0 -> 2240 bytes .../mbcsgroupprober.cpython-37.pyc | Bin 0 -> 1131 bytes .../chardet/__pycache__/mbcssm.cpython-37.pyc | Bin 0 -> 15686 bytes .../sbcharsetprober.cpython-37.pyc | Bin 0 -> 2993 bytes .../sbcsgroupprober.cpython-37.pyc | Bin 0 -> 1621 bytes .../__pycache__/sjisprober.cpython-37.pyc | Bin 0 -> 2447 bytes .../universaldetector.cpython-37.pyc | Bin 0 -> 5837 bytes .../__pycache__/utf8prober.cpython-37.pyc | Bin 0 -> 1978 bytes .../__pycache__/version.cpython-37.pyc | Bin 0 -> 447 bytes .../pip/_vendor/chardet/big5freq.py | 386 + .../pip/_vendor/chardet/big5prober.py | 47 + .../pip/_vendor/chardet/chardistribution.py | 233 + .../pip/_vendor/chardet/charsetgroupprober.py | 106 + .../pip/_vendor/chardet/charsetprober.py | 145 + .../pip/_vendor/chardet/cli/__init__.py | 1 + .../cli/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 204 bytes .../cli/__pycache__/chardetect.cpython-37.pyc | Bin 0 -> 2693 bytes .../pip/_vendor/chardet/cli/chardetect.py | 85 + .../pip/_vendor/chardet/codingstatemachine.py | 88 + .../pip/_vendor/chardet/compat.py | 34 + .../pip/_vendor/chardet/cp949prober.py | 49 + .../pip/_vendor/chardet/enums.py | 76 + .../pip/_vendor/chardet/escprober.py | 101 + .../pip/_vendor/chardet/escsm.py | 246 + .../pip/_vendor/chardet/eucjpprober.py | 92 + .../pip/_vendor/chardet/euckrfreq.py | 195 + .../pip/_vendor/chardet/euckrprober.py | 47 + .../pip/_vendor/chardet/euctwfreq.py | 387 + .../pip/_vendor/chardet/euctwprober.py | 46 + .../pip/_vendor/chardet/gb2312freq.py | 283 + .../pip/_vendor/chardet/gb2312prober.py | 46 + .../pip/_vendor/chardet/hebrewprober.py | 292 + .../pip/_vendor/chardet/jisfreq.py | 325 + .../pip/_vendor/chardet/jpcntx.py | 233 + .../pip/_vendor/chardet/langbulgarianmodel.py | 228 + .../pip/_vendor/chardet/langcyrillicmodel.py | 333 + .../pip/_vendor/chardet/langgreekmodel.py | 225 + .../pip/_vendor/chardet/langhebrewmodel.py | 200 + .../pip/_vendor/chardet/langhungarianmodel.py | 225 + .../pip/_vendor/chardet/langthaimodel.py | 199 + .../pip/_vendor/chardet/langturkishmodel.py | 193 + .../pip/_vendor/chardet/latin1prober.py | 145 + .../pip/_vendor/chardet/mbcharsetprober.py | 91 + .../pip/_vendor/chardet/mbcsgroupprober.py | 54 + .../pip/_vendor/chardet/mbcssm.py | 572 ++ .../pip/_vendor/chardet/sbcharsetprober.py | 132 + .../pip/_vendor/chardet/sbcsgroupprober.py | 73 + .../pip/_vendor/chardet/sjisprober.py | 92 + .../pip/_vendor/chardet/universaldetector.py | 286 + .../pip/_vendor/chardet/utf8prober.py | 82 + .../pip/_vendor/chardet/version.py | 9 + .../pip/_vendor/colorama/__init__.py | 7 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 452 bytes .../colorama/__pycache__/ansi.cpython-37.pyc | Bin 0 -> 3350 bytes .../__pycache__/ansitowin32.cpython-37.pyc | Bin 0 -> 7063 bytes .../__pycache__/initialise.cpython-37.pyc | Bin 0 -> 1671 bytes .../colorama/__pycache__/win32.cpython-37.pyc | Bin 0 -> 3886 bytes .../__pycache__/winterm.cpython-37.pyc | Bin 0 -> 4575 bytes .../pip/_vendor/colorama/ansi.py | 102 + .../pip/_vendor/colorama/ansitowin32.py | 236 + .../pip/_vendor/colorama/initialise.py | 82 + .../pip/_vendor/colorama/win32.py | 156 + .../pip/_vendor/colorama/winterm.py | 162 + .../pip/_vendor/distlib/__init__.py | 23 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1050 bytes .../distlib/__pycache__/compat.cpython-37.pyc | Bin 0 -> 32060 bytes .../__pycache__/database.cpython-37.pyc | Bin 0 -> 42533 bytes .../distlib/__pycache__/index.cpython-37.pyc | Bin 0 -> 17346 bytes .../__pycache__/locators.cpython-37.pyc | Bin 0 -> 38653 bytes .../__pycache__/manifest.cpython-37.pyc | Bin 0 -> 10298 bytes .../__pycache__/markers.cpython-37.pyc | Bin 0 -> 4484 bytes .../__pycache__/metadata.cpython-37.pyc | Bin 0 -> 27693 bytes .../__pycache__/resources.cpython-37.pyc | Bin 0 -> 10894 bytes .../__pycache__/scripts.cpython-37.pyc | Bin 0 -> 11070 bytes .../distlib/__pycache__/util.cpython-37.pyc | Bin 0 -> 47891 bytes .../__pycache__/version.cpython-37.pyc | Bin 0 -> 20434 bytes .../distlib/__pycache__/wheel.cpython-37.pyc | Bin 0 -> 25084 bytes .../pip/_vendor/distlib/_backport/__init__.py | 6 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 492 bytes .../_backport/__pycache__/misc.cpython-37.pyc | Bin 0 -> 1089 bytes .../__pycache__/shutil.cpython-37.pyc | Bin 0 -> 21405 bytes .../__pycache__/sysconfig.cpython-37.pyc | Bin 0 -> 15870 bytes .../__pycache__/tarfile.cpython-37.pyc | Bin 0 -> 62735 bytes .../pip/_vendor/distlib/_backport/misc.py | 41 + .../pip/_vendor/distlib/_backport/shutil.py | 761 ++ .../_vendor/distlib/_backport/sysconfig.cfg | 84 + .../_vendor/distlib/_backport/sysconfig.py | 788 ++ .../pip/_vendor/distlib/_backport/tarfile.py | 2607 ++++++ .../pip/_vendor/distlib/compat.py | 1120 +++ .../pip/_vendor/distlib/database.py | 1336 +++ .../pip/_vendor/distlib/index.py | 516 ++ .../pip/_vendor/distlib/locators.py | 1292 +++ .../pip/_vendor/distlib/manifest.py | 393 + .../pip/_vendor/distlib/markers.py | 131 + .../pip/_vendor/distlib/metadata.py | 1091 +++ .../pip/_vendor/distlib/resources.py | 355 + .../pip/_vendor/distlib/scripts.py | 415 + .../site-packages/pip/_vendor/distlib/t32.exe | Bin 0 -> 92672 bytes .../site-packages/pip/_vendor/distlib/t64.exe | Bin 0 -> 102400 bytes .../site-packages/pip/_vendor/distlib/util.py | 1755 ++++ .../pip/_vendor/distlib/version.py | 736 ++ .../site-packages/pip/_vendor/distlib/w32.exe | Bin 0 -> 89088 bytes .../site-packages/pip/_vendor/distlib/w64.exe | Bin 0 -> 99328 bytes .../pip/_vendor/distlib/wheel.py | 984 ++ .../site-packages/pip/_vendor/distro.py | 1197 +++ .../pip/_vendor/html5lib/__init__.py | 35 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1321 bytes .../__pycache__/_ihatexml.cpython-37.pyc | Bin 0 -> 13768 bytes .../__pycache__/_inputstream.cpython-37.pyc | Bin 0 -> 22659 bytes .../__pycache__/_tokenizer.cpython-37.pyc | Bin 0 -> 41560 bytes .../__pycache__/_utils.cpython-37.pyc | Bin 0 -> 3313 bytes .../__pycache__/constants.cpython-37.pyc | Bin 0 -> 66225 bytes .../__pycache__/html5parser.cpython-37.pyc | Bin 0 -> 97822 bytes .../__pycache__/serializer.cpython-37.pyc | Bin 0 -> 10838 bytes .../pip/_vendor/html5lib/_ihatexml.py | 288 + .../pip/_vendor/html5lib/_inputstream.py | 923 ++ .../pip/_vendor/html5lib/_tokenizer.py | 1721 ++++ .../pip/_vendor/html5lib/_trie/__init__.py | 14 + .../_trie/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 434 bytes .../_trie/__pycache__/_base.cpython-37.pyc | Bin 0 -> 1517 bytes .../_trie/__pycache__/datrie.cpython-37.pyc | Bin 0 -> 2036 bytes .../_trie/__pycache__/py.cpython-37.pyc | Bin 0 -> 2239 bytes .../pip/_vendor/html5lib/_trie/_base.py | 37 + .../pip/_vendor/html5lib/_trie/datrie.py | 44 + .../pip/_vendor/html5lib/_trie/py.py | 67 + .../pip/_vendor/html5lib/_utils.py | 124 + .../pip/_vendor/html5lib/constants.py | 2947 ++++++ .../pip/_vendor/html5lib/filters/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 209 bytes .../alphabeticalattributes.cpython-37.pyc | Bin 0 -> 1325 bytes .../filters/__pycache__/base.cpython-37.pyc | Bin 0 -> 859 bytes .../inject_meta_charset.cpython-37.pyc | Bin 0 -> 1879 bytes .../filters/__pycache__/lint.cpython-37.pyc | Bin 0 -> 2643 bytes .../__pycache__/optionaltags.cpython-37.pyc | Bin 0 -> 2770 bytes .../__pycache__/sanitizer.cpython-37.pyc | Bin 0 -> 16445 bytes .../__pycache__/whitespace.cpython-37.pyc | Bin 0 -> 1363 bytes .../filters/alphabeticalattributes.py | 29 + .../pip/_vendor/html5lib/filters/base.py | 12 + .../html5lib/filters/inject_meta_charset.py | 73 + .../pip/_vendor/html5lib/filters/lint.py | 93 + .../_vendor/html5lib/filters/optionaltags.py | 207 + .../pip/_vendor/html5lib/filters/sanitizer.py | 896 ++ .../_vendor/html5lib/filters/whitespace.py | 38 + .../pip/_vendor/html5lib/html5parser.py | 2791 ++++++ .../pip/_vendor/html5lib/serializer.py | 409 + .../_vendor/html5lib/treeadapters/__init__.py | 30 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 948 bytes .../__pycache__/genshi.cpython-37.pyc | Bin 0 -> 1545 bytes .../__pycache__/sax.cpython-37.pyc | Bin 0 -> 1495 bytes .../_vendor/html5lib/treeadapters/genshi.py | 54 + .../pip/_vendor/html5lib/treeadapters/sax.py | 50 + .../_vendor/html5lib/treebuilders/__init__.py | 88 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 3329 bytes .../__pycache__/base.cpython-37.pyc | Bin 0 -> 11252 bytes .../__pycache__/dom.cpython-37.pyc | Bin 0 -> 9282 bytes .../__pycache__/etree.cpython-37.pyc | Bin 0 -> 11861 bytes .../__pycache__/etree_lxml.cpython-37.pyc | Bin 0 -> 11801 bytes .../pip/_vendor/html5lib/treebuilders/base.py | 417 + .../pip/_vendor/html5lib/treebuilders/dom.py | 236 + .../_vendor/html5lib/treebuilders/etree.py | 340 + .../html5lib/treebuilders/etree_lxml.py | 366 + .../_vendor/html5lib/treewalkers/__init__.py | 154 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 4006 bytes .../__pycache__/base.cpython-37.pyc | Bin 0 -> 7002 bytes .../__pycache__/dom.cpython-37.pyc | Bin 0 -> 1731 bytes .../__pycache__/etree.cpython-37.pyc | Bin 0 -> 3538 bytes .../__pycache__/etree_lxml.cpython-37.pyc | Bin 0 -> 6647 bytes .../__pycache__/genshi.cpython-37.pyc | Bin 0 -> 1905 bytes .../pip/_vendor/html5lib/treewalkers/base.py | 252 + .../pip/_vendor/html5lib/treewalkers/dom.py | 43 + .../pip/_vendor/html5lib/treewalkers/etree.py | 130 + .../html5lib/treewalkers/etree_lxml.py | 213 + .../_vendor/html5lib/treewalkers/genshi.py | 69 + .../pip/_vendor/idna/__init__.py | 2 + .../idna/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 266 bytes .../idna/__pycache__/codec.cpython-37.pyc | Bin 0 -> 3073 bytes .../idna/__pycache__/compat.cpython-37.pyc | Bin 0 -> 626 bytes .../idna/__pycache__/core.cpython-37.pyc | Bin 0 -> 9158 bytes .../idna/__pycache__/idnadata.cpython-37.pyc | Bin 0 -> 20590 bytes .../idna/__pycache__/intranges.cpython-37.pyc | Bin 0 -> 1806 bytes .../__pycache__/package_data.cpython-37.pyc | Bin 0 -> 220 bytes .../idna/__pycache__/uts46data.cpython-37.pyc | Bin 0 -> 175662 bytes .../site-packages/pip/_vendor/idna/codec.py | 118 + .../site-packages/pip/_vendor/idna/compat.py | 12 + .../site-packages/pip/_vendor/idna/core.py | 399 + .../pip/_vendor/idna/idnadata.py | 1893 ++++ .../pip/_vendor/idna/intranges.py | 53 + .../pip/_vendor/idna/package_data.py | 2 + .../pip/_vendor/idna/uts46data.py | 8179 +++++++++++++++++ .../site-packages/pip/_vendor/ipaddress.py | 2419 +++++ .../pip/_vendor/lockfile/__init__.py | 347 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 9916 bytes .../__pycache__/linklockfile.cpython-37.pyc | Bin 0 -> 2297 bytes .../__pycache__/mkdirlockfile.cpython-37.pyc | Bin 0 -> 2659 bytes .../__pycache__/pidlockfile.cpython-37.pyc | Bin 0 -> 4859 bytes .../__pycache__/sqlitelockfile.cpython-37.pyc | Bin 0 -> 3758 bytes .../symlinklockfile.cpython-37.pyc | Bin 0 -> 2182 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 | 66 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2078 bytes .../__pycache__/_version.cpython-37.pyc | Bin 0 -> 227 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 2183 bytes .../__pycache__/fallback.cpython-37.pyc | Bin 0 -> 24555 bytes .../pip/_vendor/msgpack/_version.py | 1 + .../pip/_vendor/msgpack/exceptions.py | 41 + .../pip/_vendor/msgpack/fallback.py | 977 ++ .../pip/_vendor/packaging/__about__.py | 21 + .../pip/_vendor/packaging/__init__.py | 14 + .../__pycache__/__about__.cpython-37.pyc | Bin 0 -> 728 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 566 bytes .../__pycache__/_compat.cpython-37.pyc | Bin 0 -> 1018 bytes .../__pycache__/_structures.cpython-37.pyc | Bin 0 -> 2870 bytes .../__pycache__/markers.cpython-37.pyc | Bin 0 -> 8869 bytes .../__pycache__/requirements.cpython-37.pyc | Bin 0 -> 3885 bytes .../__pycache__/specifiers.cpython-37.pyc | Bin 0 -> 19796 bytes .../__pycache__/utils.cpython-37.pyc | Bin 0 -> 1464 bytes .../__pycache__/version.cpython-37.pyc | Bin 0 -> 11982 bytes .../pip/_vendor/packaging/_compat.py | 30 + .../pip/_vendor/packaging/_structures.py | 70 + .../pip/_vendor/packaging/markers.py | 301 + .../pip/_vendor/packaging/requirements.py | 130 + .../pip/_vendor/packaging/specifiers.py | 774 ++ .../pip/_vendor/packaging/utils.py | 63 + .../pip/_vendor/packaging/version.py | 441 + .../pip/_vendor/pep517/__init__.py | 4 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 289 bytes .../__pycache__/_in_process.cpython-37.pyc | Bin 0 -> 5354 bytes .../pep517/__pycache__/check.cpython-37.pyc | Bin 0 -> 4753 bytes .../__pycache__/colorlog.cpython-37.pyc | Bin 0 -> 2918 bytes .../pep517/__pycache__/compat.cpython-37.pyc | Bin 0 -> 1027 bytes .../__pycache__/envbuild.cpython-37.pyc | Bin 0 -> 4184 bytes .../__pycache__/wrappers.cpython-37.pyc | Bin 0 -> 4751 bytes .../pip/_vendor/pep517/_in_process.py | 182 + .../site-packages/pip/_vendor/pep517/check.py | 194 + .../pip/_vendor/pep517/colorlog.py | 110 + .../pip/_vendor/pep517/compat.py | 23 + .../pip/_vendor/pep517/envbuild.py | 150 + .../pip/_vendor/pep517/wrappers.py | 134 + .../pip/_vendor/pkg_resources/__init__.py | 3149 +++++++ .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 96034 bytes .../__pycache__/py31compat.cpython-37.pyc | Bin 0 -> 651 bytes .../pip/_vendor/pkg_resources/py31compat.py | 23 + .../pip/_vendor/progress/__init__.py | 127 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 3919 bytes .../progress/__pycache__/bar.cpython-37.pyc | Bin 0 -> 2741 bytes .../__pycache__/counter.cpython-37.pyc | Bin 0 -> 1583 bytes .../__pycache__/helpers.cpython-37.pyc | Bin 0 -> 3025 bytes .../__pycache__/spinner.cpython-37.pyc | Bin 0 -> 1500 bytes .../site-packages/pip/_vendor/progress/bar.py | 94 + .../pip/_vendor/progress/counter.py | 48 + .../pip/_vendor/progress/helpers.py | 91 + .../pip/_vendor/progress/spinner.py | 44 + .../site-packages/pip/_vendor/pyparsing.py | 5742 ++++++++++++ .../pip/_vendor/pytoml/__init__.py | 3 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 339 bytes .../pytoml/__pycache__/core.cpython-37.pyc | Bin 0 -> 948 bytes .../pytoml/__pycache__/parser.cpython-37.pyc | Bin 0 -> 11151 bytes .../pytoml/__pycache__/writer.cpython-37.pyc | Bin 0 -> 3850 bytes .../site-packages/pip/_vendor/pytoml/core.py | 13 + .../pip/_vendor/pytoml/parser.py | 374 + .../pip/_vendor/pytoml/writer.py | 127 + .../pip/_vendor/requests/__init__.py | 138 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 3796 bytes .../__pycache__/__version__.cpython-37.pyc | Bin 0 -> 559 bytes .../_internal_utils.cpython-37.pyc | Bin 0 -> 1317 bytes .../__pycache__/adapters.cpython-37.pyc | Bin 0 -> 16782 bytes .../requests/__pycache__/api.cpython-37.pyc | Bin 0 -> 6508 bytes .../requests/__pycache__/auth.cpython-37.pyc | Bin 0 -> 8353 bytes .../requests/__pycache__/certs.cpython-37.pyc | Bin 0 -> 642 bytes .../__pycache__/compat.cpython-37.pyc | Bin 0 -> 1652 bytes .../__pycache__/cookies.cpython-37.pyc | Bin 0 -> 18761 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 5514 bytes .../requests/__pycache__/help.cpython-37.pyc | Bin 0 -> 2706 bytes .../requests/__pycache__/hooks.cpython-37.pyc | Bin 0 -> 1006 bytes .../__pycache__/models.cpython-37.pyc | Bin 0 -> 23973 bytes .../__pycache__/packages.cpython-37.pyc | Bin 0 -> 519 bytes .../__pycache__/sessions.cpython-37.pyc | Bin 0 -> 18578 bytes .../__pycache__/status_codes.cpython-37.pyc | Bin 0 -> 4175 bytes .../__pycache__/structures.cpython-37.pyc | Bin 0 -> 4388 bytes .../requests/__pycache__/utils.cpython-37.pyc | Bin 0 -> 21958 bytes .../pip/_vendor/requests/__version__.py | 14 + .../pip/_vendor/requests/_internal_utils.py | 42 + .../pip/_vendor/requests/adapters.py | 530 ++ .../site-packages/pip/_vendor/requests/api.py | 152 + .../pip/_vendor/requests/auth.py | 305 + .../pip/_vendor/requests/certs.py | 18 + .../pip/_vendor/requests/compat.py | 75 + .../pip/_vendor/requests/cookies.py | 546 ++ .../pip/_vendor/requests/exceptions.py | 126 + .../pip/_vendor/requests/help.py | 120 + .../pip/_vendor/requests/hooks.py | 34 + .../pip/_vendor/requests/models.py | 952 ++ .../pip/_vendor/requests/packages.py | 16 + .../pip/_vendor/requests/sessions.py | 741 ++ .../pip/_vendor/requests/status_codes.py | 120 + .../pip/_vendor/requests/structures.py | 103 + .../pip/_vendor/requests/utils.py | 976 ++ .../site-packages/pip/_vendor/retrying.py | 267 + .../site-packages/pip/_vendor/six.py | 891 ++ .../pip/_vendor/urllib3/__init__.py | 97 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2431 bytes .../__pycache__/_collections.cpython-37.pyc | Bin 0 -> 10755 bytes .../__pycache__/connection.cpython-37.pyc | Bin 0 -> 10276 bytes .../__pycache__/connectionpool.cpython-37.pyc | Bin 0 -> 23810 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 10409 bytes .../urllib3/__pycache__/fields.cpython-37.pyc | Bin 0 -> 5877 bytes .../__pycache__/filepost.cpython-37.pyc | Bin 0 -> 2769 bytes .../__pycache__/poolmanager.cpython-37.pyc | Bin 0 -> 12708 bytes .../__pycache__/request.cpython-37.pyc | Bin 0 -> 5600 bytes .../__pycache__/response.cpython-37.pyc | Bin 0 -> 17426 bytes .../pip/_vendor/urllib3/_collections.py | 332 + .../pip/_vendor/urllib3/connection.py | 403 + .../pip/_vendor/urllib3/connectionpool.py | 906 ++ .../pip/_vendor/urllib3/contrib/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 208 bytes .../__pycache__/appengine.cpython-37.pyc | Bin 0 -> 8956 bytes .../__pycache__/ntlmpool.cpython-37.pyc | Bin 0 -> 3256 bytes .../__pycache__/pyopenssl.cpython-37.pyc | Bin 0 -> 14283 bytes .../securetransport.cpython-37.pyc | Bin 0 -> 17905 bytes .../contrib/__pycache__/socks.cpython-37.pyc | Bin 0 -> 4914 bytes .../contrib/_securetransport/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 225 bytes .../__pycache__/bindings.cpython-37.pyc | Bin 0 -> 10320 bytes .../__pycache__/low_level.cpython-37.pyc | Bin 0 -> 7501 bytes .../contrib/_securetransport/bindings.py | 593 ++ .../contrib/_securetransport/low_level.py | 346 + .../pip/_vendor/urllib3/contrib/appengine.py | 305 + .../pip/_vendor/urllib3/contrib/ntlmpool.py | 112 + .../pip/_vendor/urllib3/contrib/pyopenssl.py | 457 + .../urllib3/contrib/securetransport.py | 804 ++ .../pip/_vendor/urllib3/contrib/socks.py | 192 + .../pip/_vendor/urllib3/exceptions.py | 246 + .../pip/_vendor/urllib3/fields.py | 178 + .../pip/_vendor/urllib3/filepost.py | 98 + .../pip/_vendor/urllib3/packages/__init__.py | 5 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 322 bytes .../__pycache__/ordered_dict.cpython-37.pyc | Bin 0 -> 8416 bytes .../packages/__pycache__/six.cpython-37.pyc | Bin 0 -> 24410 bytes .../urllib3/packages/backports/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 219 bytes .../__pycache__/makefile.cpython-37.pyc | Bin 0 -> 1317 bytes .../urllib3/packages/backports/makefile.py | 53 + .../_vendor/urllib3/packages/ordered_dict.py | 259 + .../pip/_vendor/urllib3/packages/six.py | 868 ++ .../packages/ssl_match_hostname/__init__.py | 19 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 563 bytes .../_implementation.cpython-37.pyc | Bin 0 -> 3322 bytes .../ssl_match_hostname/_implementation.py | 157 + .../pip/_vendor/urllib3/poolmanager.py | 449 + .../pip/_vendor/urllib3/request.py | 150 + .../pip/_vendor/urllib3/response.py | 676 ++ .../pip/_vendor/urllib3/util/__init__.py | 54 + .../util/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1000 bytes .../__pycache__/connection.cpython-37.pyc | Bin 0 -> 3077 bytes .../util/__pycache__/queue.cpython-37.pyc | Bin 0 -> 1049 bytes .../util/__pycache__/request.cpython-37.pyc | Bin 0 -> 3230 bytes .../util/__pycache__/response.cpython-37.pyc | Bin 0 -> 1911 bytes .../util/__pycache__/retry.cpython-37.pyc | Bin 0 -> 12663 bytes .../util/__pycache__/ssl_.cpython-37.pyc | Bin 0 -> 10001 bytes .../util/__pycache__/timeout.cpython-37.pyc | Bin 0 -> 8779 bytes .../util/__pycache__/url.cpython-37.pyc | Bin 0 -> 5189 bytes .../util/__pycache__/wait.cpython-37.pyc | Bin 0 -> 3162 bytes .../pip/_vendor/urllib3/util/connection.py | 126 + .../pip/_vendor/urllib3/util/queue.py | 21 + .../pip/_vendor/urllib3/util/request.py | 118 + .../pip/_vendor/urllib3/util/response.py | 81 + .../pip/_vendor/urllib3/util/retry.py | 411 + .../pip/_vendor/urllib3/util/ssl_.py | 396 + .../pip/_vendor/urllib3/util/timeout.py | 242 + .../pip/_vendor/urllib3/util/url.py | 230 + .../pip/_vendor/urllib3/util/wait.py | 153 + .../pip/_vendor/webencodings/__init__.py | 342 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 9684 bytes .../__pycache__/labels.cpython-37.pyc | Bin 0 -> 4098 bytes .../__pycache__/mklabels.cpython-37.pyc | Bin 0 -> 1920 bytes .../__pycache__/tests.cpython-37.pyc | Bin 0 -> 5061 bytes .../__pycache__/x_user_defined.cpython-37.pyc | Bin 0 -> 2673 bytes .../pip/_vendor/webencodings/labels.py | 231 + .../pip/_vendor/webencodings/mklabels.py | 59 + .../pip/_vendor/webencodings/tests.py | 153 + .../_vendor/webencodings/x_user_defined.py | 325 + .../site-packages/pkg_resources/__init__.py | 3171 +++++++ .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 96877 bytes .../__pycache__/py31compat.cpython-37.pyc | Bin 0 -> 646 bytes .../pkg_resources/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 209 bytes .../__pycache__/appdirs.cpython-37.pyc | Bin 0 -> 20697 bytes .../__pycache__/pyparsing.cpython-37.pyc | Bin 0 -> 203052 bytes .../_vendor/__pycache__/six.cpython-37.pyc | Bin 0 -> 24410 bytes .../pkg_resources/_vendor/appdirs.py | 608 ++ .../_vendor/packaging/__about__.py | 21 + .../_vendor/packaging/__init__.py | 14 + .../__pycache__/__about__.cpython-37.pyc | Bin 0 -> 745 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 583 bytes .../__pycache__/_compat.cpython-37.pyc | Bin 0 -> 1035 bytes .../__pycache__/_structures.cpython-37.pyc | Bin 0 -> 2887 bytes .../__pycache__/markers.cpython-37.pyc | Bin 0 -> 8895 bytes .../__pycache__/requirements.cpython-37.pyc | Bin 0 -> 3900 bytes .../__pycache__/specifiers.cpython-37.pyc | Bin 0 -> 19813 bytes .../__pycache__/utils.cpython-37.pyc | Bin 0 -> 514 bytes .../__pycache__/version.cpython-37.pyc | Bin 0 -> 10580 bytes .../_vendor/packaging/_compat.py | 30 + .../_vendor/packaging/_structures.py | 68 + .../_vendor/packaging/markers.py | 301 + .../_vendor/packaging/requirements.py | 127 + .../_vendor/packaging/specifiers.py | 774 ++ .../pkg_resources/_vendor/packaging/utils.py | 14 + .../_vendor/packaging/version.py | 393 + .../pkg_resources/_vendor/pyparsing.py | 5742 ++++++++++++ .../pkg_resources/_vendor/six.py | 868 ++ .../pkg_resources/extern/__init__.py | 73 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2428 bytes .../site-packages/pkg_resources/py31compat.py | 23 + .../setuptools-40.6.2.dist-info/INSTALLER | 1 + .../setuptools-40.6.2.dist-info/LICENSE | 19 + .../setuptools-40.6.2.dist-info/METADATA | 73 + .../setuptools-40.6.2.dist-info/RECORD | 188 + .../setuptools-40.6.2.dist-info/WHEEL | 6 + .../dependency_links.txt | 2 + .../entry_points.txt | 65 + .../setuptools-40.6.2.dist-info/top_level.txt | 3 + .../setuptools-40.6.2.dist-info/zip-safe | 1 + .../site-packages/setuptools/__init__.py | 195 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 6533 bytes .../_deprecation_warning.cpython-37.pyc | Bin 0 -> 564 bytes .../__pycache__/archive_util.cpython-37.pyc | Bin 0 -> 5145 bytes .../__pycache__/build_meta.cpython-37.pyc | Bin 0 -> 6281 bytes .../__pycache__/config.cpython-37.pyc | Bin 0 -> 17013 bytes .../__pycache__/dep_util.cpython-37.pyc | Bin 0 -> 871 bytes .../__pycache__/depends.cpython-37.pyc | Bin 0 -> 5280 bytes .../__pycache__/dist.cpython-37.pyc | Bin 0 -> 38455 bytes .../__pycache__/extension.cpython-37.pyc | Bin 0 -> 1991 bytes .../__pycache__/glibc.cpython-37.pyc | Bin 0 -> 1556 bytes .../__pycache__/glob.cpython-37.pyc | Bin 0 -> 3766 bytes .../__pycache__/launch.cpython-37.pyc | Bin 0 -> 870 bytes .../__pycache__/lib2to3_ex.cpython-37.pyc | Bin 0 -> 2449 bytes .../__pycache__/monkey.cpython-37.pyc | Bin 0 -> 4650 bytes .../__pycache__/msvc.cpython-37.pyc | Bin 0 -> 34447 bytes .../__pycache__/namespaces.cpython-37.pyc | Bin 0 -> 3628 bytes .../__pycache__/package_index.cpython-37.pyc | Bin 0 -> 32482 bytes .../__pycache__/pep425tags.cpython-37.pyc | Bin 0 -> 7219 bytes .../__pycache__/py27compat.cpython-37.pyc | Bin 0 -> 827 bytes .../__pycache__/py31compat.cpython-37.pyc | Bin 0 -> 1213 bytes .../__pycache__/py33compat.cpython-37.pyc | Bin 0 -> 1436 bytes .../__pycache__/py36compat.cpython-37.pyc | Bin 0 -> 2208 bytes .../__pycache__/sandbox.cpython-37.pyc | Bin 0 -> 15552 bytes .../__pycache__/site-patch.cpython-37.pyc | Bin 0 -> 1518 bytes .../__pycache__/ssl_support.cpython-37.pyc | Bin 0 -> 6807 bytes .../__pycache__/unicode_utils.cpython-37.pyc | Bin 0 -> 1185 bytes .../__pycache__/version.cpython-37.pyc | Bin 0 -> 344 bytes .../__pycache__/wheel.cpython-37.pyc | Bin 0 -> 7032 bytes .../windows_support.cpython-37.pyc | Bin 0 -> 1027 bytes .../setuptools/_deprecation_warning.py | 7 + .../setuptools/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 206 bytes .../__pycache__/pyparsing.cpython-37.pyc | Bin 0 -> 203049 bytes .../_vendor/__pycache__/six.cpython-37.pyc | Bin 0 -> 24407 bytes .../setuptools/_vendor/packaging/__about__.py | 21 + .../setuptools/_vendor/packaging/__init__.py | 14 + .../__pycache__/__about__.cpython-37.pyc | Bin 0 -> 742 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 580 bytes .../__pycache__/_compat.cpython-37.pyc | Bin 0 -> 1032 bytes .../__pycache__/_structures.cpython-37.pyc | Bin 0 -> 2884 bytes .../__pycache__/markers.cpython-37.pyc | Bin 0 -> 8889 bytes .../__pycache__/requirements.cpython-37.pyc | Bin 0 -> 3891 bytes .../__pycache__/specifiers.cpython-37.pyc | Bin 0 -> 19810 bytes .../__pycache__/utils.cpython-37.pyc | Bin 0 -> 511 bytes .../__pycache__/version.cpython-37.pyc | Bin 0 -> 10577 bytes .../setuptools/_vendor/packaging/_compat.py | 30 + .../_vendor/packaging/_structures.py | 68 + .../setuptools/_vendor/packaging/markers.py | 301 + .../_vendor/packaging/requirements.py | 127 + .../_vendor/packaging/specifiers.py | 774 ++ .../setuptools/_vendor/packaging/utils.py | 14 + .../setuptools/_vendor/packaging/version.py | 393 + .../setuptools/_vendor/pyparsing.py | 5742 ++++++++++++ .../site-packages/setuptools/_vendor/six.py | 868 ++ .../site-packages/setuptools/archive_util.py | 173 + .../site-packages/setuptools/build_meta.py | 182 + .../site-packages/setuptools/cli-32.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/cli-64.exe | Bin 0 -> 74752 bytes .../site-packages/setuptools/cli.exe | Bin 0 -> 65536 bytes .../setuptools/command/__init__.py | 18 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 752 bytes .../command/__pycache__/alias.cpython-37.pyc | Bin 0 -> 2420 bytes .../__pycache__/bdist_egg.cpython-37.pyc | Bin 0 -> 14208 bytes .../__pycache__/bdist_rpm.cpython-37.pyc | Bin 0 -> 1799 bytes .../__pycache__/bdist_wininst.cpython-37.pyc | Bin 0 -> 990 bytes .../__pycache__/build_clib.cpython-37.pyc | Bin 0 -> 2469 bytes .../__pycache__/build_ext.cpython-37.pyc | Bin 0 -> 9723 bytes .../__pycache__/build_py.cpython-37.pyc | Bin 0 -> 8599 bytes .../__pycache__/develop.cpython-37.pyc | Bin 0 -> 6440 bytes .../__pycache__/dist_info.cpython-37.pyc | Bin 0 -> 1395 bytes .../__pycache__/easy_install.cpython-37.pyc | Bin 0 -> 64851 bytes .../__pycache__/egg_info.cpython-37.pyc | Bin 0 -> 21672 bytes .../__pycache__/install.cpython-37.pyc | Bin 0 -> 4027 bytes .../install_egg_info.cpython-37.pyc | Bin 0 -> 2428 bytes .../__pycache__/install_lib.cpython-37.pyc | Bin 0 -> 4104 bytes .../install_scripts.cpython-37.pyc | Bin 0 -> 2307 bytes .../__pycache__/py36compat.cpython-37.pyc | Bin 0 -> 4640 bytes .../__pycache__/register.cpython-37.pyc | Bin 0 -> 797 bytes .../command/__pycache__/rotate.cpython-37.pyc | Bin 0 -> 2546 bytes .../__pycache__/saveopts.cpython-37.pyc | Bin 0 -> 941 bytes .../command/__pycache__/sdist.cpython-37.pyc | Bin 0 -> 6237 bytes .../command/__pycache__/setopt.cpython-37.pyc | Bin 0 -> 4539 bytes .../command/__pycache__/test.cpython-37.pyc | Bin 0 -> 8134 bytes .../command/__pycache__/upload.cpython-37.pyc | Bin 0 -> 5220 bytes .../__pycache__/upload_docs.cpython-37.pyc | Bin 0 -> 6150 bytes .../site-packages/setuptools/command/alias.py | 80 + .../setuptools/command/bdist_egg.py | 502 + .../setuptools/command/bdist_rpm.py | 43 + .../setuptools/command/bdist_wininst.py | 21 + .../setuptools/command/build_clib.py | 98 + .../setuptools/command/build_ext.py | 321 + .../setuptools/command/build_py.py | 270 + .../setuptools/command/develop.py | 218 + .../setuptools/command/dist_info.py | 36 + .../setuptools/command/easy_install.py | 2342 +++++ .../setuptools/command/egg_info.py | 716 ++ .../setuptools/command/install.py | 125 + .../setuptools/command/install_egg_info.py | 62 + .../setuptools/command/install_lib.py | 121 + .../setuptools/command/install_scripts.py | 65 + .../setuptools/command/launcher manifest.xml | 15 + .../setuptools/command/py36compat.py | 136 + .../setuptools/command/register.py | 18 + .../setuptools/command/rotate.py | 66 + .../setuptools/command/saveopts.py | 22 + .../site-packages/setuptools/command/sdist.py | 200 + .../setuptools/command/setopt.py | 149 + .../site-packages/setuptools/command/test.py | 270 + .../setuptools/command/upload.py | 196 + .../setuptools/command/upload_docs.py | 206 + .../site-packages/setuptools/config.py | 635 ++ .../site-packages/setuptools/dep_util.py | 23 + .../site-packages/setuptools/depends.py | 186 + .../site-packages/setuptools/dist.py | 1147 +++ .../site-packages/setuptools/extension.py | 57 + .../setuptools/extern/__init__.py | 73 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2429 bytes .../site-packages/setuptools/glibc.py | 86 + .../site-packages/setuptools/glob.py | 174 + .../site-packages/setuptools/gui-32.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/gui-64.exe | Bin 0 -> 75264 bytes .../site-packages/setuptools/gui.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/launch.py | 35 + .../site-packages/setuptools/lib2to3_ex.py | 62 + .../site-packages/setuptools/monkey.py | 179 + .../site-packages/setuptools/msvc.py | 1301 +++ .../site-packages/setuptools/namespaces.py | 107 + .../site-packages/setuptools/package_index.py | 1128 +++ .../site-packages/setuptools/pep425tags.py | 319 + .../site-packages/setuptools/py27compat.py | 28 + .../site-packages/setuptools/py31compat.py | 32 + .../site-packages/setuptools/py33compat.py | 55 + .../site-packages/setuptools/py36compat.py | 82 + .../site-packages/setuptools/sandbox.py | 491 + .../setuptools/script (dev).tmpl | 6 + .../site-packages/setuptools/script.tmpl | 3 + .../site-packages/setuptools/site-patch.py | 74 + .../site-packages/setuptools/ssl_support.py | 260 + .../site-packages/setuptools/unicode_utils.py | 44 + .../site-packages/setuptools/version.py | 6 + .../site-packages/setuptools/wheel.py | 210 + .../setuptools/windows_support.py | 29 + venv/pyvenv.cfg | 3 + 832 files changed, 138942 insertions(+) create mode 100644 .DS_Store create mode 100644 flaskr/.DS_Store create mode 100644 flaskr/__init__.py create mode 100644 flaskr/__init__.pyc create mode 100644 flaskr/auth.py create mode 100644 flaskr/auth.pyc create mode 100644 flaskr/base.html create mode 100644 flaskr/blog.py create mode 100644 flaskr/blog.pyc create mode 100644 flaskr/db.py create mode 100644 flaskr/db.pyc create mode 100644 flaskr/login.html create mode 100644 flaskr/register.html create mode 100644 flaskr/schema.sql create mode 100644 flaskr/static/style.css create mode 100644 flaskr/templates/.DS_Store create mode 100644 flaskr/templates/auth/.DS_Store create mode 100644 flaskr/templates/auth/login.html create mode 100644 flaskr/templates/auth/register.html create mode 100644 flaskr/templates/base.html create mode 100644 flaskr/templates/blog/create.html create mode 100644 flaskr/templates/blog/index.html create mode 100644 flaskr/templates/blog/update.html create mode 100644 instance/flaskr.sqlite create mode 100644 venv/bin/activate create mode 100644 venv/bin/activate.csh create mode 100644 venv/bin/activate.fish create mode 100755 venv/bin/easy_install create mode 100755 venv/bin/easy_install-3.7 create mode 100755 venv/bin/pip create mode 100755 venv/bin/pip3 create mode 100755 venv/bin/pip3.7 create mode 120000 venv/bin/python create mode 120000 venv/bin/python3 create mode 100644 venv/lib/python3.7/site-packages/__pycache__/easy_install.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/easy_install.py create mode 100644 venv/lib/python3.7/site-packages/pip-18.1.dist-info/INSTALLER create mode 100644 venv/lib/python3.7/site-packages/pip-18.1.dist-info/LICENSE.txt create mode 100644 venv/lib/python3.7/site-packages/pip-18.1.dist-info/METADATA create mode 100644 venv/lib/python3.7/site-packages/pip-18.1.dist-info/RECORD create mode 100644 venv/lib/python3.7/site-packages/pip-18.1.dist-info/WHEEL create mode 100644 venv/lib/python3.7/site-packages/pip-18.1.dist-info/entry_points.txt create mode 100644 venv/lib/python3.7/site-packages/pip-18.1.dist-info/top_level.txt create mode 100644 venv/lib/python3.7/site-packages/pip/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/__main__.py create mode 100644 venv/lib/python3.7/site-packages/pip/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/__pycache__/__main__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/build_env.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/cache.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/configuration.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/download.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/exceptions.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/index.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/locations.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/pep425tags.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/pyproject.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/resolve.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/wheel.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/build_env.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cache.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/parser.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/autocompletion.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/base_command.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/cmdoptions.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/main_parser.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/parser.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/status_codes.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/check.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/completion.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/download.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/hash.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/help.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/install.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/list.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/search.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/show.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/check.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/completion.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/configuration.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/download.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/freeze.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/hash.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/help.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/install.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/list.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/search.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/show.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/uninstall.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/wheel.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/configuration.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/download.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/exceptions.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/index.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/locations.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/candidate.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/format_control.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/index.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/link.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/candidate.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/format_control.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/index.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/link.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/check.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/check.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/freeze.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/prepare.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/pep425tags.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/pyproject.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/constructors.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_file.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_install.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_set.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_tracker.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/constructors.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/req_file.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/req_install.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/req_set.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/req_tracker.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/req_uninstall.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/resolve.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/logging.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/misc.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/models.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/outdated.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/typing.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/ui.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/appdirs.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/compat.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/deprecation.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/encoding.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/filesystem.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/glibc.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/hashes.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/logging.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/misc.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/models.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/outdated.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/packaging.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/setuptools_build.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/temp_dir.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/typing.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/ui.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/git.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/bazaar.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/git.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/mercurial.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/subversion.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/wheel.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/appdirs.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/distro.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/ipaddress.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/pyparsing.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/retrying.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/six.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/appdirs.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/_cmd.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/adapter.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/cache.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/compat.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/controller.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/filewrapper.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/heuristics.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/serialize.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/wrapper.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/certifi/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/certifi/__main__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/certifi/__pycache__/__main__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/certifi/cacert.pem create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/certifi/core.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/chardistribution.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/charsetprober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/cp949prober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/enums.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/jisfreq.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langcyrillicmodel.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/utf8prober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/big5freq.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/big5prober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/chardistribution.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/charsetgroupprober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/charsetprober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/cli/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/cli/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/cli/chardetect.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/codingstatemachine.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/compat.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/cp949prober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/enums.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/escprober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/escsm.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/eucjpprober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/euckrfreq.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/euckrprober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/euctwfreq.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/euctwprober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/gb2312freq.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/gb2312prober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/hebrewprober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/jisfreq.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/jpcntx.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/langbulgarianmodel.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/langcyrillicmodel.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/langgreekmodel.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/langhebrewmodel.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/langhungarianmodel.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/langthaimodel.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/langturkishmodel.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/latin1prober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/mbcharsetprober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/mbcsgroupprober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/mbcssm.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/sbcharsetprober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/sbcsgroupprober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/sjisprober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/universaldetector.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/utf8prober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/version.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/ansi.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/ansitowin32.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/initialise.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/win32.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/winterm.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/ansi.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/ansitowin32.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/initialise.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/win32.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/winterm.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/database.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/index.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/locators.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/manifest.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/markers.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/metadata.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/scripts.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/version.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/wheel.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/misc.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/shutil.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/sysconfig.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/tarfile.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/misc.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/shutil.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/sysconfig.cfg create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/sysconfig.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/tarfile.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/compat.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/database.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/index.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/locators.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/manifest.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/markers.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/metadata.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/resources.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/scripts.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/t32.exe create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/t64.exe create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/util.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/version.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/w32.exe create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/w64.exe create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/wheel.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distro.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/_ihatexml.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/_inputstream.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/_tokenizer.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/_utils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/constants.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/html5parser.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/serializer.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_ihatexml.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_inputstream.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_tokenizer.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__pycache__/_base.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__pycache__/datrie.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__pycache__/py.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/_base.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/datrie.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/py.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_utils.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/constants.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/alphabeticalattributes.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/base.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/inject_meta_charset.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/lint.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/optionaltags.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/sanitizer.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/whitespace.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/alphabeticalattributes.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/base.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/inject_meta_charset.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/lint.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/optionaltags.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/sanitizer.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/whitespace.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/html5parser.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/serializer.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/genshi.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/sax.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/genshi.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/sax.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/base.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/dom.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree_lxml.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/base.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/dom.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/etree.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/etree_lxml.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/base.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/dom.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/etree.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/etree_lxml.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/genshi.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/base.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/dom.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/etree.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/etree_lxml.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/genshi.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/codec.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/core.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/uts46data.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/codec.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/compat.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/core.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/idnadata.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/intranges.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/package_data.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/uts46data.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/ipaddress.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/lockfile/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/linklockfile.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/mkdirlockfile.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/pidlockfile.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/sqlitelockfile.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/symlinklockfile.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/lockfile/linklockfile.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/lockfile/mkdirlockfile.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/lockfile/pidlockfile.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/lockfile/sqlitelockfile.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/lockfile/symlinklockfile.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/msgpack/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/_version.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/msgpack/_version.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/msgpack/exceptions.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/msgpack/fallback.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__about__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/__about__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/_compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/_structures.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/_compat.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/_structures.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/markers.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/requirements.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/specifiers.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/utils.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/version.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/_in_process.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/check.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/colorlog.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/envbuild.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/wrappers.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/_in_process.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/check.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/colorlog.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/compat.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/envbuild.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/wrappers.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pkg_resources/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pkg_resources/py31compat.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/progress/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/bar.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/counter.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/helpers.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/spinner.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/progress/bar.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/progress/counter.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/progress/helpers.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/progress/spinner.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pyparsing.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pytoml/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pytoml/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pytoml/__pycache__/core.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pytoml/__pycache__/parser.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pytoml/__pycache__/writer.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pytoml/core.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pytoml/parser.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pytoml/writer.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/api.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/certs.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/help.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/models.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/packages.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/status_codes.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/utils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__version__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/_internal_utils.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/adapters.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/api.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/auth.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/certs.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/compat.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/cookies.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/exceptions.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/help.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/hooks.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/models.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/packages.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/sessions.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/status_codes.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/structures.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/utils.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/retrying.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/six.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/_collections.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/connection.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/exceptions.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/fields.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/filepost.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/request.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/response.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/_collections.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/connection.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/connectionpool.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/appengine.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/securetransport.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/socks.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/exceptions.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/fields.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/filepost.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__pycache__/ordered_dict.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ordered_dict.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/six.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/_implementation.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/poolmanager.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/request.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/response.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/connection.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/queue.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/retry.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/url.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/wait.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/connection.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/queue.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/request.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/response.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/retry.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/ssl_.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/timeout.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/url.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/wait.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/webencodings/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/labels.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/mklabels.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/tests.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/webencodings/labels.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/webencodings/mklabels.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/webencodings/tests.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/webencodings/x_user_defined.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/__pycache__/py31compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/appdirs.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/pyparsing.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/six.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/appdirs.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__about__.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/_compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/markers.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/utils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/version.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/_compat.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/_structures.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/markers.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/requirements.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/specifiers.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/utils.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/version.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/pyparsing.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/six.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/extern/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/extern/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/py31compat.py create mode 100644 venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/INSTALLER create mode 100644 venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/LICENSE create mode 100644 venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/METADATA create mode 100644 venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/RECORD create mode 100644 venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/WHEEL create mode 100644 venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/dependency_links.txt create mode 100644 venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/entry_points.txt create mode 100644 venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/top_level.txt create mode 100644 venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/zip-safe create mode 100644 venv/lib/python3.7/site-packages/setuptools/__init__.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/_deprecation_warning.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/archive_util.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/build_meta.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/config.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/dep_util.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/depends.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/dist.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/extension.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/glibc.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/glob.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/launch.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/lib2to3_ex.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/monkey.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/msvc.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/namespaces.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/package_index.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/pep425tags.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/py27compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/py31compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/py33compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/py36compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/sandbox.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/site-patch.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/ssl_support.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/unicode_utils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/version.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/wheel.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/windows_support.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_deprecation_warning.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/__init__.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/__pycache__/pyparsing.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/__pycache__/six.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__about__.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__init__.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/__about__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/_compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/_structures.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/markers.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/requirements.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/utils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/version.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/_compat.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/_structures.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/markers.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/requirements.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/specifiers.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/utils.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/version.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/pyparsing.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/six.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/archive_util.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/build_meta.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/cli-32.exe create mode 100644 venv/lib/python3.7/site-packages/setuptools/cli-64.exe create mode 100644 venv/lib/python3.7/site-packages/setuptools/cli.exe create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__init__.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/alias.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/bdist_egg.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/bdist_rpm.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/bdist_wininst.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/build_clib.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/build_ext.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/build_py.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/develop.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/dist_info.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/easy_install.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/egg_info.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/install.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/install_egg_info.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/install_lib.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/install_scripts.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/py36compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/register.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/rotate.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/saveopts.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/sdist.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/setopt.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/test.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/upload.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/upload_docs.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/alias.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/bdist_egg.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/bdist_rpm.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/bdist_wininst.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/build_clib.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/build_ext.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/build_py.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/develop.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/dist_info.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/easy_install.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/egg_info.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/install.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/install_egg_info.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/install_lib.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/install_scripts.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/launcher manifest.xml create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/py36compat.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/register.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/rotate.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/saveopts.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/sdist.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/setopt.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/test.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/upload.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/upload_docs.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/config.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/dep_util.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/depends.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/dist.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/extension.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/extern/__init__.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/extern/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/glibc.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/glob.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/gui-32.exe create mode 100644 venv/lib/python3.7/site-packages/setuptools/gui-64.exe create mode 100644 venv/lib/python3.7/site-packages/setuptools/gui.exe create mode 100644 venv/lib/python3.7/site-packages/setuptools/launch.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/lib2to3_ex.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/monkey.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/msvc.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/namespaces.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/package_index.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/pep425tags.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/py27compat.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/py31compat.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/py33compat.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/py36compat.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/sandbox.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/script (dev).tmpl create mode 100644 venv/lib/python3.7/site-packages/setuptools/script.tmpl create mode 100644 venv/lib/python3.7/site-packages/setuptools/site-patch.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/ssl_support.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/unicode_utils.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/version.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/wheel.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/windows_support.py create mode 100644 venv/pyvenv.cfg diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..9b6495df908b21e550cdfad6d9dd1085e7e74f93 GIT binary patch literal 8196 zcmeHM&2Jk;6n`%@?QYUGn>HZ{>cPT7RBD9s(Gn1_(;5a015YIbGCriKO3cRC(x^fQH7W%lOp#g@lGUp}VOlB( zvoW?bl7QIaf*R)=78Fr#EL;6aqg-(RD#^AA)}j>lmGd~hLz+Yofy;^@O{%iCc+{x0xqx$b*mG&%Vj z_8m(-bNqy5^;`X?`fnCD#da}rqehr>gEiSJxY1@gmY0O^JF;6|_SkmG8NMobG1rZ+3QaB7Je@<^6rz z8hv5va(;blXLs*|{SQA=O9qVN4Gijjr@cc`7a?Ay87~sQZ!hvs$7wIq?jJaL>hz#9 zbmr{P@X*M}$g`s(W8=?_mz=X@w{p7{$RB)F_#(*p4YpPbylS!TRyWHWrAP}98`Fvit<3mY3Di&jd`U|0!+?-xYqMV{cRhelU#ghYKl zVq1B>A?S)tqI#h&&BA3CgoHi*E30l0xV*-4J2!o|%=`tO6Hz3#R=kSf`j-!?X{lQX zn4B_msUEHpu!4T~^O8#YH*#m3*#WxmjH9q>}&gWl#_4PMD{-nGP zLeY@!ciNvx>X4S8zhh(s!$5+8W4b>k^Z)syzyBw^OxG}A7rEE=MbBzZ@kO zCv)vI)pe?}NV}Fs4{wwlL^VBl% E4*{v?sQ>@~ literal 0 HcmV?d00001 diff --git a/flaskr/.DS_Store b/flaskr/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..546b899a92c20a847bba47834a563b8dbbc4b73f GIT binary patch literal 8196 zcmeHM&2G~`5T5O?lTy(GQY*Olg2bUhX(cHI~S|cJ0jq8;q zbQ!|ud7F|Mb>}QJ1D?pEnD+2@k$O|s=7wRwFkl!k3>XFs1OEa8cxQ95a^CxL*7Sw} z!@!ATfPX*OXk1s6o=7deI?#y{0D2C$gD7YKeHqD3nBOnP4UZK-=D&SBEF zsCLYAmKP^5sW_LZ4_4a9aRgpkxXMAY?;58?Aevya1vVX^B6_5=Dlo|%E{IhetmI8a z^BMlXB{)jiHil78J#`-%J>QGsQt2a`nVp+oShTF7Ra`Fa);r;_9y{?Msyh7#{OYz7 zcN%JZCk*|gvD3KgwT62uXKsc;?07+|FTkGLg2}^sUf_nqYB&hoNcgGC3Ck*2g}s%v z(P+C|TDLb#T%ebm3kC>5mN z-l#XjZt{>UHQxIs@$YA+I_3SfE_CX~8Eq>#)^VKUaIewg@kI&-K7xD3<_u;G z@)&ZYi-=kz#F1AZUk^|f#2VbAGem3_^o*-u2diT>5ET&XOFCwnD%zGuMh_5sf%O3H zz&t?^Np@kDK)x4(6W$2;KFrr1as0srPW}fVwm@uyXi`RqqTkxVe0BXH&dNBSnoM#l zb?VivPG@ZaPv(ANIy zq;>5qHMvU7s9oA3mzi&$>tZVU(%z~}wu8Voe(DRWQoY#PHs{JH&pFAYo(j@l;=+*# zh!m+?v>X}4V6i5t>D1pm?FPCSVauVIkQ-@4St#QJsWL+TYP~?PhXaBG=O&#<&OK3G z+Nlg#S|+`YwxKO1e3F)>G9&C_fWigeGW9oMkrO|q{;_tCP`5DBZ>~tnyCEh&M4hB# zDU@}dZp)W`$J)XMiME(}iMIwN5)_<6W>7$nitTrCvT~%HmzEFoRF;Q+7f_WdE8b4`^i0o8_t)K1`Ey}z`_lH;5siOS z{Qt-NnZKCC{O3?gCx4!@I{Ectv`Xm$WsBr5lA~OTr${YPJWcTo9lDOcOlp~S&rm!|agE|t zI&_@4PA`cW@>fdjf@sf*cCpm1iuNqUOXbK~Ie!_;<1^*>If_@n`)}Z~-R2r!Jo%e{ zo#rgFw#MXcI#NTO46KEJcGA%Ft;1Z;Vv1IAqE%$=k_dxX>AucJ7#@szVYn~ z*a%at!uUDwQUnhB+~O(sI^9igt8uTh^`J1-EKhs0Q6BYri z15jwCc`q55m9cmPidNrdX>*Z>Jw#sMRbWJ*!Enty*bu3c4+?~3LY7KYn3`9 zan-3Y7U!Hr!J&W;X>`z#!Rk1HG(XD*GXrd%(tf#LETRB3PpE;!_x&OO(C1#aAb z%Q-x`+l1wg_ZCxgnaO{~o9h~vFX@|wgR!uuY!LxuwATPZ0ht6u`j}WheTM=BX&%M_ zd$p(HAQ=RR+^0M&rI6jruB^K?$DkYmPWi}2%*qev-{8+k+@<*)qL;YvAh*GBFOd%3 z@ldvlG6r;caMc7@le-CbT15;y6^DMvoT)M)E>IBw0f*xT_ykM^D1MMW`n~j8zQcD# zTXoPlyTwf+UO*+JE@Aa`CSynyFuDv6a3)Ngz-Ad`KLIb;xO1Y_G$oxT7?7mI$)pcV z-ZFdpq3)SN#%-P^YX4L{hEl(;!{LzO0OOBYmRgQfTXu`r7#h~jXb{;vPmR390uSsss4^$}n#&z`#b ULFJsg?5?@%>+2U+>gT8a0r;1;LI3~& literal 0 HcmV?d00001 diff --git a/flaskr/base.html b/flaskr/base.html new file mode 100644 index 0000000..fb0e460 --- /dev/null +++ b/flaskr/base.html @@ -0,0 +1,24 @@ + +{% block title %}{% endblock %} - Flaskr + + +
+
+ {% block header %}{% endblock %} +
+ {% for message in get_flashed_messages() %} +
{{ message }}
+ {% endfor %} + {% block content %}{% endblock %} +
\ No newline at end of file diff --git a/flaskr/blog.py b/flaskr/blog.py new file mode 100644 index 0000000..7d15578 --- /dev/null +++ b/flaskr/blog.py @@ -0,0 +1,100 @@ +from flask import ( + Blueprint, flash, g, redirect, render_template, request, url_for +) +from werkzeug.exceptions import abort + +from flaskr.auth import login_required +from flaskr.db import get_db + +bp = Blueprint('blog', __name__) + +@bp.route('/') +def index(): + db = get_db() + posts = db.execute( + 'SELECT p.id, title, body, created, author_id, username' + ' FROM post p JOIN user u ON p.author_id = u.id' + ' ORDER BY created DESC' + ).fetchall() + return render_template('blog/index.html', posts=posts) + + +@bp.route('/create', methods=('GET', 'POST')) +@login_required +def create(): + if request.method == 'POST': + title = request.form['title'] + body = request.form['body'] + error = None + + if not title: + error = 'Title is required.' + + if error is not None: + flash(error) + else: + db = get_db() + db.execute( + 'INSERT INTO post (title, body, author_id)' + ' VALUES (?, ?, ?)', + (title, body, g.user['id']) + ) + db.commit() + return redirect(url_for('blog.index')) + + return render_template('blog/create.html') + +def get_post(id, check_author=True): + post = get_db().execute( + 'SELECT p.id, title, body, created, author_id, username' + ' FROM post p JOIN user u ON p.author_id = u.id' + ' WHERE p.id = ?', + (id,) + ).fetchone() + + if post is None: + abort(404, "Post id {0} doesn't exist.".format(id)) + + if check_author and post['author_id'] != g.user['id']: + abort(403) + + return post + + +@bp.route('//update', methods=('GET', 'POST')) +@login_required +def update(id): + post = get_post(id) + + if request.method == 'POST': + title = request.form['title'] + body = request.form['body'] + error = None + + if not title: + error = 'Title is required.' + + if error is not None: + flash(error) + else: + db = get_db() + db.execute( + 'UPDATE post SET title = ?, body = ?' + ' WHERE id = ?', + (title, body, id) + ) + db.commit() + return redirect(url_for('blog.index')) + + return render_template('blog/update.html', post=post) + + + +@bp.route('//delete', methods=('POST',)) +@login_required +def delete(id): + get_post(id) + db = get_db() + db.execute('DELETE FROM post WHERE id = ?', (id,)) + db.commit() + return redirect(url_for('blog.index')) \ No newline at end of file diff --git a/flaskr/blog.pyc b/flaskr/blog.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4029af0854cb151cb0d5f0ace5d0d7021cb3c825 GIT binary patch literal 3311 zcmcguO>-MX5bfEOCCip$N6wcZp|%JVN|mv4;FJpavIQg+{uw_2UiU~=k|LZEWNAFpJJZ|K@AaGU|5{o4^W5%t1Dbvo@c$Nm zrlg1>d=(``siLl;)T6FPsZU*>(gJl0lrB(rfzl#%i6 z$&=n*me+Z?c7#r2>ZUay=d1K(A~uxd3{5G^k8E17Jg)4GwySoX*S5?PwC(2o=2j;dZ^qF^U}Kx;jbJy6 z9&ZGLTw^n^_9ylr%X>UwVst+0r#ko|-1#~fXT}EO;NH&NmOKe2!A=XVP8I~82NO6B zcEasu7~J`G<}=uCwzmwYj`!7wk-p>21Dht29d>IZ#E^lI6zXF=m>{*B`#o(32mK@o zc^7p~h26rpNBOTZ1WF#&fFnN>$ZF33C!qBhT62S<0{2Hi8jpz%%alJNya+=; zu8!bmL0|{kJ`Iapd{_zO5#bQ!RixUU&&8?Uw&C7ZC|Z<3ol$6o z>l`uHg0RG~5=1dom^w_HAU45_#GB?C%y(PuX4nbtwmLhGEcI6ycEXb@!8f<>KWw&x z`pu1izgGm&I5JD{A~*;DW^Fp0=3F>aUx6`{z&N`O0tpW_mrAFVjdaM>Cxi-Rf$)YQ zVNP3KImps9wjpB|^4RfHz#HM1IZ&b25jsu}9J_%29$@umdH^Ol>MT;e#nf@yFch9J0YDAr zm!dqCsRgPbLBkSLsdnhInOBK~%S;av%B9dU2JQbMDUZHthE0(zh|JCS7ocn2!^Ri!tV$3CmNmJuzyftA66RK}R&UnZ# zs|#1y6RHISI?#i|o_mGxj+N}~Q-tH?qk+9Q(3h$pRaU-V^((68T>?eK*tm}K>slP$ zXiUZt#C*UtzzpMR5w84!4!8n}0C*@3&KQ;*MJ!3b$xzOY8Z?KWVc(1@@|r;0Ij60+<%2JOTwFKTOT37U2QphP9|nkR!(~EEg>jZGs%l z&ab&5%}eu5LUa{deE4Adb_aA}aJkQMqZiG3nY0mrnz~^SJFVbTQiNE=F!i#KscOv6qxak(r=<-fzky3~A+ID|#yFQGKo)skwt*YkNPhw1A>Aq$_f zb!L&AG;%QsF(P+-iSqb7lw(OK$J@5N>_?p+KGBo?O?^DjV;g59HQGp<7FDiOrQA9fA(nC;Kb&Q}uA*57_wn71d+Fi+%DU#)` zD!WKd4v=F%p&!`~Xx|JSJ0BoIT+Pnz&dz)DIN`r1NB{H}ziYaELj0fNb?-44{1g>L z^E+G7T!}xRBA`u3^N= zbfd_2$sDpDHh%LynVxJr;j^>&2)X3{;hDw(On;0)Z=1%JKF#XdE6i6hkNyFMUG6W~ zudCAAD}RTrgS9if?j;5U_C%KvHK&9C>wtVn>kgTKo&W~B4v>t(rnD>5h!3p0lpa!v zo5Y^Q9CYeAEwk{4_nP(fBme`lT zB;Rcv%X}qhUQLqOdHUk~?8n!?y*i&ITp^^2P}NSDXsTVh%(SnX>lkjjAKWRXv z+*oJjI?u}0xNfR7?i!yJ)z-{x^JlK@cv)ob@~PhBVlsJ@nbR@SFx!SEcz zBGp%2b)p^wgFrJP#?Ltky<-?m56UiDxe4g4qBmk+_Ne)W?R7{uhyx}Kp~M_uD%gb4 zmL`r^SG5<8tJ3-dICN1t+v_Zm65yaB6v!Rk16e_1tX`)GTIV+=#apHfx6d!Vc|K?tEUZ zh9>jbFe}Ya1F5&e((Z;nTNKuf+!Gx60m(qn`Crz^LEgW}oE=RiY$6x8s>=1HP-gW- zbZVSl4hB1Zd& zKfx>!X>+mU^OjB|B5!*DH%;-4kbA<^w4Z?-Wn66y+b$}k3ZP_&rF$TIEF+_NzNyT% au-`HDZh)bW#_&je8upI+Q7`JNLG(W`wUU$o literal 0 HcmV?d00001 diff --git a/flaskr/login.html b/flaskr/login.html new file mode 100644 index 0000000..b7dd5dc --- /dev/null +++ b/flaskr/login.html @@ -0,0 +1,15 @@ +{% extends 'base.html' %} + +{% block header %} +

{% block title %}Log In{% endblock %}

+{% endblock %} + +{% block content %} +
+ + + + + +
+{% endblock %} \ No newline at end of file diff --git a/flaskr/register.html b/flaskr/register.html new file mode 100644 index 0000000..a3c73cc --- /dev/null +++ b/flaskr/register.html @@ -0,0 +1,15 @@ +{% extends 'base.html' %} + +{% block header %} +

{% block title %}Register{% endblock %}

+{% endblock %} + +{% block content %} +
+ + + + + +
+{% endblock %} \ No newline at end of file diff --git a/flaskr/schema.sql b/flaskr/schema.sql new file mode 100644 index 0000000..efbd3db --- /dev/null +++ b/flaskr/schema.sql @@ -0,0 +1,17 @@ +DROP TABLE IF EXISTS user; +DROP TABLE IF EXISTS post; + +CREATE TABLE user ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + username TEXT UNIQUE NOT NULL, + password TEXT NOT NULL +); + +CREATE TABLE post ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + author_id INTEGER NOT NULL, + created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + title TEXT NOT NULL, + body TEXT NOT NULL, + FOREIGN KEY (author_id) REFERENCES user (id) +); \ No newline at end of file diff --git a/flaskr/static/style.css b/flaskr/static/style.css new file mode 100644 index 0000000..93623a4 --- /dev/null +++ b/flaskr/static/style.css @@ -0,0 +1,26 @@ +html { font-family: sans-serif; background: #eee; padding: 1rem; } +body { max-width: 960px; margin: 0 auto; background: white; } +h1 { font-family: serif; color: #377ba8; margin: 1rem 0; } +a { color: #377ba8; } +hr { border: none; border-top: 1px solid lightgray; } +nav { background: lightgray; display: flex; align-items: center; padding: 0 0.5rem; } +nav h1 { flex: auto; margin: 0; } +nav h1 a { text-decoration: none; padding: 0.25rem 0.5rem; } +nav ul { display: flex; list-style: none; margin: 0; padding: 0; } +nav ul li a, nav ul li span, header .action { display: block; padding: 0.5rem; } +.content { padding: 0 1rem 1rem; } +.content > header { border-bottom: 1px solid lightgray; display: flex; align-items: flex-end; } +.content > header h1 { flex: auto; margin: 1rem 0 0.25rem 0; } +.flash { margin: 1em 0; padding: 1em; background: #cae6f6; border: 1px solid #377ba8; } +.post > header { display: flex; align-items: flex-end; font-size: 0.85em; } +.post > header > div:first-of-type { flex: auto; } +.post > header h1 { font-size: 1.5em; margin-bottom: 0; } +.post .about { color: slategray; font-style: italic; } +.post .body { white-space: pre-line; } +.content:last-child { margin-bottom: 0; } +.content form { margin: 1em 0; display: flex; flex-direction: column; } +.content label { font-weight: bold; margin-bottom: 0.5em; } +.content input, .content textarea { margin-bottom: 1em; } +.content textarea { min-height: 12em; resize: vertical; } +input.danger { color: #cc2f2e; } +input[type=submit] { align-self: start; min-width: 10em; } \ No newline at end of file diff --git a/flaskr/templates/.DS_Store b/flaskr/templates/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..209bce3b0fa0e401218dffb9bb7ab0d6ae3ff990 GIT binary patch literal 6148 zcmeHK!EVz)5S?ue-2@?WsMH>PLE;dhq?85;Az2|DdP6dT1EAK9qu7$;jbghIH9@}d z3&5$TO8f>V_yV}{B`~wQjp7t@1cY{^-8Z{4v&p{E?s@=#_4A+$&;kICjnHah_X{CA zwM(+0XRaYKTH`PlLq8Tij%h(7h5^ICzs&%hT?;(OA%k%3{0`A}{zHn~#L~~7r&E2- zzxdNQO0!PqE8Ez#u3X*Xyvdu_n=jo^%-zh(^0e>Gp3~^DmxaF8p9m2zbtG0<441zpEa=yL& zL`P$(5NA-B3Pn_*OqUo;R}M^tqutT| zr9u@BO#U*iqkoy{3We#ygW1v@n4{42h5^Gsm4Qt)Y|;Dw2+wd${a+0-Bg24U;J;#k zSp#>_$1Ul%_0s0(t+lZoV?h?cj^BUMYa)l;NB|25&iXl#CyhL6N>>ZsB zvC7;hDofl@#Hur1EFDrEb4&$NfuRBupElb6Z|L9L|A(ZUr2?tIpHe`k%hhthPm10; w`Z(>ig}$bL8FMY2!{89WiMHa)qr9Te%&URDqtO{RIx!Cds!Lib@EZ#30c|@t%>V!Z literal 0 HcmV?d00001 diff --git a/flaskr/templates/auth/login.html b/flaskr/templates/auth/login.html new file mode 100644 index 0000000..b7dd5dc --- /dev/null +++ b/flaskr/templates/auth/login.html @@ -0,0 +1,15 @@ +{% extends 'base.html' %} + +{% block header %} +

{% block title %}Log In{% endblock %}

+{% endblock %} + +{% block content %} +
+ + + + + +
+{% endblock %} \ No newline at end of file diff --git a/flaskr/templates/auth/register.html b/flaskr/templates/auth/register.html new file mode 100644 index 0000000..a3c73cc --- /dev/null +++ b/flaskr/templates/auth/register.html @@ -0,0 +1,15 @@ +{% extends 'base.html' %} + +{% block header %} +

{% block title %}Register{% endblock %}

+{% endblock %} + +{% block content %} +
+ + + + + +
+{% endblock %} \ No newline at end of file diff --git a/flaskr/templates/base.html b/flaskr/templates/base.html new file mode 100644 index 0000000..fb0e460 --- /dev/null +++ b/flaskr/templates/base.html @@ -0,0 +1,24 @@ + +{% block title %}{% endblock %} - Flaskr + + +
+
+ {% block header %}{% endblock %} +
+ {% for message in get_flashed_messages() %} +
{{ message }}
+ {% endfor %} + {% block content %}{% endblock %} +
\ No newline at end of file diff --git a/flaskr/templates/blog/create.html b/flaskr/templates/blog/create.html new file mode 100644 index 0000000..ad402e0 --- /dev/null +++ b/flaskr/templates/blog/create.html @@ -0,0 +1,15 @@ +{% extends 'base.html' %} + +{% block header %} +

{% block title %}New Post{% endblock %}

+{% endblock %} + +{% block content %} +
+ + + + + +
+{% endblock %} \ No newline at end of file diff --git a/flaskr/templates/blog/index.html b/flaskr/templates/blog/index.html new file mode 100644 index 0000000..c0b659f --- /dev/null +++ b/flaskr/templates/blog/index.html @@ -0,0 +1,28 @@ +{% extends 'base.html' %} + +{% block header %} +

{% block title %}Posts{% endblock %}

+ {% if g.user %} + New + {% endif %} +{% endblock %} + +{% block content %} + {% for post in posts %} +
+
+
+

{{ post['title'] }}

+
by {{ post['username'] }} on {{ post['created'].strftime('%Y-%m-%d') }}
+
+ {% if g.user['id'] == post['author_id'] %} + Edit + {% endif %} +
+

{{ post['body'] }}

+
+ {% if not loop.last %} +
+ {% endif %} + {% endfor %} +{% endblock %} \ No newline at end of file diff --git a/flaskr/templates/blog/update.html b/flaskr/templates/blog/update.html new file mode 100644 index 0000000..7420f57 --- /dev/null +++ b/flaskr/templates/blog/update.html @@ -0,0 +1,20 @@ +{% extends 'base.html' %} + +{% block header %} +

{% block title %}Edit "{{ post['title'] }}"{% endblock %}

+{% endblock %} + +{% block content %} +
+ + + + + +
+
+
+ +
+{% endblock %} \ No newline at end of file diff --git a/instance/flaskr.sqlite b/instance/flaskr.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..7102bd3e7fcdcdf683317132a47c8f4105fa892f GIT binary patch literal 20480 zcmeI(O>YuG7zgm#@+PDe6GD1)4o!r#F}y5Gsh6%eC9AN|Wl8Lb?6N~j+OjRXM2#o( zQ~0U;7~Z^AZ_a=;P!kiAS`+i1?7+M}GxN({7P8&r<|yQJ=ua-3ke10KqA28$QbI^V z`jXnPM=ca{ z8RqX4k`tac6|G#-MttMcC_Mtap;v@cfX>kHC5B9RfnriK^=IiXsf!et5&&J z)P}VZ*HlqZ9n~wBR8<=mYFZ^F&ZVTk6LD?a_Ytuk1Rwwb2tWV=5P$##AOHafKmY=F zE|7?16!CMy#%APkvhKtqnWU&K{{O!w>FYaR4*?+n0SG_<0uX=z1Rwwb2tWV=5cszO o2_=$E$`=9T^S^lM9|-~wfB*y_009U<00Izz00bZaf&W. +# Ported to Python 3.3 venv by Andrew Svetlov + +alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; test "\!:*" != "nondestructive" && unalias deactivate' + +# Unset irrelevant variables. +deactivate nondestructive + +setenv VIRTUAL_ENV "/Users/canjiang/project/CloudService/flask-tutorial/venv" + +set _OLD_VIRTUAL_PATH="$PATH" +setenv PATH "$VIRTUAL_ENV/bin:$PATH" + + +set _OLD_VIRTUAL_PROMPT="$prompt" + +if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then + if ("venv" != "") then + set env_name = "venv" + else + if (`basename "VIRTUAL_ENV"` == "__") then + # special case for Aspen magic directories + # see http://www.zetadev.com/software/aspen/ + set env_name = `basename \`dirname "$VIRTUAL_ENV"\`` + else + set env_name = `basename "$VIRTUAL_ENV"` + endif + endif + set prompt = "[$env_name] $prompt" + unset env_name +endif + +alias pydoc python -m pydoc + +rehash diff --git a/venv/bin/activate.fish b/venv/bin/activate.fish new file mode 100644 index 0000000..529b11b --- /dev/null +++ b/venv/bin/activate.fish @@ -0,0 +1,75 @@ +# This file must be used with ". bin/activate.fish" *from fish* (http://fishshell.org) +# you cannot run it directly + +function deactivate -d "Exit virtualenv and return to normal shell environment" + # reset old environment variables + if test -n "$_OLD_VIRTUAL_PATH" + set -gx PATH $_OLD_VIRTUAL_PATH + set -e _OLD_VIRTUAL_PATH + end + if test -n "$_OLD_VIRTUAL_PYTHONHOME" + set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME + set -e _OLD_VIRTUAL_PYTHONHOME + end + + if test -n "$_OLD_FISH_PROMPT_OVERRIDE" + functions -e fish_prompt + set -e _OLD_FISH_PROMPT_OVERRIDE + functions -c _old_fish_prompt fish_prompt + functions -e _old_fish_prompt + end + + set -e VIRTUAL_ENV + if test "$argv[1]" != "nondestructive" + # Self destruct! + functions -e deactivate + end +end + +# unset irrelevant variables +deactivate nondestructive + +set -gx VIRTUAL_ENV "/Users/canjiang/project/CloudService/flask-tutorial/venv" + +set -gx _OLD_VIRTUAL_PATH $PATH +set -gx PATH "$VIRTUAL_ENV/bin" $PATH + +# unset PYTHONHOME if set +if set -q PYTHONHOME + set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME + set -e PYTHONHOME +end + +if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" + # fish uses a function instead of an env var to generate the prompt. + + # save the current fish_prompt function as the function _old_fish_prompt + functions -c fish_prompt _old_fish_prompt + + # with the original prompt function renamed, we can override with our own. + function fish_prompt + # Save the return status of the last command + set -l old_status $status + + # Prompt override? + if test -n "(venv) " + printf "%s%s" "(venv) " (set_color normal) + else + # ...Otherwise, prepend env + set -l _checkbase (basename "$VIRTUAL_ENV") + if test $_checkbase = "__" + # special case for Aspen magic directories + # see http://www.zetadev.com/software/aspen/ + printf "%s[%s]%s " (set_color -b blue white) (basename (dirname "$VIRTUAL_ENV")) (set_color normal) + else + printf "%s(%s)%s" (set_color -b blue white) (basename "$VIRTUAL_ENV") (set_color normal) + end + end + + # Restore the return status of the previous command. + echo "exit $old_status" | . + _old_fish_prompt + end + + set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" +end diff --git a/venv/bin/easy_install b/venv/bin/easy_install new file mode 100755 index 0000000..4da2beb --- /dev/null +++ b/venv/bin/easy_install @@ -0,0 +1,11 @@ +#!/Users/canjiang/project/CloudService/flask-tutorial/venv/bin/python3 + +# -*- 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.exit(main()) diff --git a/venv/bin/easy_install-3.7 b/venv/bin/easy_install-3.7 new file mode 100755 index 0000000..4da2beb --- /dev/null +++ b/venv/bin/easy_install-3.7 @@ -0,0 +1,11 @@ +#!/Users/canjiang/project/CloudService/flask-tutorial/venv/bin/python3 + +# -*- 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.exit(main()) diff --git a/venv/bin/pip b/venv/bin/pip new file mode 100755 index 0000000..3aa259e --- /dev/null +++ b/venv/bin/pip @@ -0,0 +1,11 @@ +#!/Users/canjiang/project/CloudService/flask-tutorial/venv/bin/python3 + +# -*- coding: utf-8 -*- +import re +import sys + +from pip._internal import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv/bin/pip3 b/venv/bin/pip3 new file mode 100755 index 0000000..3aa259e --- /dev/null +++ b/venv/bin/pip3 @@ -0,0 +1,11 @@ +#!/Users/canjiang/project/CloudService/flask-tutorial/venv/bin/python3 + +# -*- coding: utf-8 -*- +import re +import sys + +from pip._internal import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv/bin/pip3.7 b/venv/bin/pip3.7 new file mode 100755 index 0000000..3aa259e --- /dev/null +++ b/venv/bin/pip3.7 @@ -0,0 +1,11 @@ +#!/Users/canjiang/project/CloudService/flask-tutorial/venv/bin/python3 + +# -*- coding: utf-8 -*- +import re +import sys + +from pip._internal import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv/bin/python b/venv/bin/python new file mode 120000 index 0000000..b8a0adb --- /dev/null +++ b/venv/bin/python @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/venv/bin/python3 b/venv/bin/python3 new file mode 120000 index 0000000..79ab74b --- /dev/null +++ b/venv/bin/python3 @@ -0,0 +1 @@ +/usr/local/bin/python3 \ No newline at end of file diff --git a/venv/lib/python3.7/site-packages/__pycache__/easy_install.cpython-37.pyc b/venv/lib/python3.7/site-packages/__pycache__/easy_install.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e2f66db9f9f88e15f888669bc0be5d9976ed69a0 GIT binary patch literal 333 zcmYk0&q~BF5XO_XY7zGd7PNTlVVl)OWkEy)4_-W|ry_*3$!_cBA4$5pJ$Uizi}*^t zdh!)Knd*vuF!Rm8@cZUsFxUoOufyX0+53CH{3`Inxi7o#8wELFkitb^c46S69+H!g*3EA&8`1jIkiK#Q4MGKnlC4U$4`s+rpTt z665|v62UOe_bhXbc1m%ZtpOSHP+b2|P3ReKz-)T^Zl4v>rd|@q(2^K5Q=Bqmk*H94 zpz*YwK8znHGuqnY$rJ32Zkszp=G(O*9LpPT7b7oQ468_v$4 N54ZgXQ4qr&_yuE&U-=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.* + +pip +=== + +The `PyPA recommended`_ tool for installing Python packages. + +.. image:: https://img.shields.io/pypi/v/pip.svg + :target: https://pypi.org/project/pip/ + +.. image:: https://img.shields.io/travis/pypa/pip/master.svg?label=travis-ci + :target: https://travis-ci.org/pypa/pip + +.. image:: https://img.shields.io/appveyor/ci/pypa/pip.svg?label=appveyor-ci + :target: https://ci.appveyor.com/project/pypa/pip/history + +.. image:: https://readthedocs.org/projects/pip/badge/?version=latest + :target: https://pip.pypa.io/en/latest + +* `Installation`_ +* `Documentation`_ +* `Changelog`_ +* `GitHub Page`_ +* `Issue Tracking`_ +* `User mailing list`_ +* `Dev mailing list`_ +* User IRC: #pypa on Freenode. +* Dev IRC: #pypa-dev on Freenode. + +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`_. + +.. _PyPA recommended: https://packaging.python.org/en/latest/current/ +.. _Installation: https://pip.pypa.io/en/stable/installing.html +.. _Documentation: https://pip.pypa.io/en/stable/ +.. _Changelog: https://pip.pypa.io/en/stable/news.html +.. _GitHub Page: https://github.com/pypa/pip +.. _Issue Tracking: https://github.com/pypa/pip/issues +.. _User mailing list: https://groups.google.com/forum/#!forum/python-virtualenv +.. _Dev mailing list: https://groups.google.com/forum/#!forum/pypa-dev +.. _PyPA Code of Conduct: https://www.pypa.io/en/latest/code-of-conduct/ + + diff --git a/venv/lib/python3.7/site-packages/pip-18.1.dist-info/RECORD b/venv/lib/python3.7/site-packages/pip-18.1.dist-info/RECORD new file mode 100644 index 0000000..23cff37 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip-18.1.dist-info/RECORD @@ -0,0 +1,614 @@ +../../../bin/pip,sha256=7ZEZ4zq2PHyOyhheECliPgxujRRTTLKua88OUvgr26M,268 +../../../bin/pip3,sha256=7ZEZ4zq2PHyOyhheECliPgxujRRTTLKua88OUvgr26M,268 +../../../bin/pip3.7,sha256=7ZEZ4zq2PHyOyhheECliPgxujRRTTLKua88OUvgr26M,268 +pip-18.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pip-18.1.dist-info/LICENSE.txt,sha256=ORqHhOMZ2uVDFHfUzJvFBPxdcf2eieHIDxzThV9dfPo,1090 +pip-18.1.dist-info/METADATA,sha256=D7pqBJTuqM9w_HTW91a0XGjLT9vynlBAE4pPCt_W_UE,2588 +pip-18.1.dist-info/RECORD,, +pip-18.1.dist-info/WHEEL,sha256=8T8fxefr_r-A79qbOJ9d_AaEgkpCGmEPHc-gpCq5BRg,110 +pip-18.1.dist-info/entry_points.txt,sha256=S_zfxY25QtQDVY1BiLAmOKSkkI5llzCKPLiYOSEupsY,98 +pip-18.1.dist-info/top_level.txt,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pip/__init__.py,sha256=nO-iphoXiDoci_ZAMl-PG2zdd4Y7m88jBDILTYzwGy4,21 +pip/__main__.py,sha256=L3IHqBeasELUHvwy5CT_izVEMhM12tve289qut49DvU,623 +pip/__pycache__/__init__.cpython-37.pyc,, +pip/__pycache__/__main__.cpython-37.pyc,, +pip/_internal/__init__.py,sha256=b0jSFCCViGhB1RWni35_NMkH3Y-mbZrV648DGMagDjs,2869 +pip/_internal/__pycache__/__init__.cpython-37.pyc,, +pip/_internal/__pycache__/build_env.cpython-37.pyc,, +pip/_internal/__pycache__/cache.cpython-37.pyc,, +pip/_internal/__pycache__/configuration.cpython-37.pyc,, +pip/_internal/__pycache__/download.cpython-37.pyc,, +pip/_internal/__pycache__/exceptions.cpython-37.pyc,, +pip/_internal/__pycache__/index.cpython-37.pyc,, +pip/_internal/__pycache__/locations.cpython-37.pyc,, +pip/_internal/__pycache__/pep425tags.cpython-37.pyc,, +pip/_internal/__pycache__/pyproject.cpython-37.pyc,, +pip/_internal/__pycache__/resolve.cpython-37.pyc,, +pip/_internal/__pycache__/wheel.cpython-37.pyc,, +pip/_internal/build_env.py,sha256=zKhqmDMnrX5OTSNQ4xBw-mN5mTGVu6wjiNFW-ajWYEI,4797 +pip/_internal/cache.py,sha256=96_aKtDbwgLEVNgNabOT8GrFCYZEACedoiucqU5ccg8,6829 +pip/_internal/cli/__init__.py,sha256=FkHBgpxxb-_gd6r1FjnNhfMOzAUYyXoXKJ6abijfcFU,132 +pip/_internal/cli/__pycache__/__init__.cpython-37.pyc,, +pip/_internal/cli/__pycache__/autocompletion.cpython-37.pyc,, +pip/_internal/cli/__pycache__/base_command.cpython-37.pyc,, +pip/_internal/cli/__pycache__/cmdoptions.cpython-37.pyc,, +pip/_internal/cli/__pycache__/main_parser.cpython-37.pyc,, +pip/_internal/cli/__pycache__/parser.cpython-37.pyc,, +pip/_internal/cli/__pycache__/status_codes.cpython-37.pyc,, +pip/_internal/cli/autocompletion.py,sha256=ptvsMdGjq42pzoY4skABVF43u2xAtLJlXAulPi-A10Y,6083 +pip/_internal/cli/base_command.py,sha256=ke6af4iWzrZoc3HtiPKnCZJvD6GlX8dRwBwpFCg1axc,9963 +pip/_internal/cli/cmdoptions.py,sha256=WoPPY1uHsDjA_NvZek8Mko38rxraD3pX8eZUkNKvk10,19468 +pip/_internal/cli/main_parser.py,sha256=Ga_kT7if-Gg0rmmRqlGEHW6JWVm9zwzO7igJm6RE9EI,2763 +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=CQAzhVx9ViPtqLNUvAeqnKj5iWfFEcqMx5RlZWjJ30c,2251 +pip/_internal/commands/__pycache__/__init__.cpython-37.pyc,, +pip/_internal/commands/__pycache__/check.cpython-37.pyc,, +pip/_internal/commands/__pycache__/completion.cpython-37.pyc,, +pip/_internal/commands/__pycache__/configuration.cpython-37.pyc,, +pip/_internal/commands/__pycache__/download.cpython-37.pyc,, +pip/_internal/commands/__pycache__/freeze.cpython-37.pyc,, +pip/_internal/commands/__pycache__/hash.cpython-37.pyc,, +pip/_internal/commands/__pycache__/help.cpython-37.pyc,, +pip/_internal/commands/__pycache__/install.cpython-37.pyc,, +pip/_internal/commands/__pycache__/list.cpython-37.pyc,, +pip/_internal/commands/__pycache__/search.cpython-37.pyc,, +pip/_internal/commands/__pycache__/show.cpython-37.pyc,, +pip/_internal/commands/__pycache__/uninstall.cpython-37.pyc,, +pip/_internal/commands/__pycache__/wheel.cpython-37.pyc,, +pip/_internal/commands/check.py,sha256=CyeYH2kfDKSGSURoBfWtx-sTcZZQP-bK170NmKYlmsg,1398 +pip/_internal/commands/completion.py,sha256=hqvCvoxsIHjysiD7olHKTqK2lzE1_lS6LWn69kN5qyI,2929 +pip/_internal/commands/configuration.py,sha256=265HWuUxPggCNcIeWHA3p-LDDiRVnexwFgwmHGgWOHY,7125 +pip/_internal/commands/download.py,sha256=D_iGMp3xX2iD7KZYZAjXlYT3rf3xjwxyYe05KE-DVzE,6514 +pip/_internal/commands/freeze.py,sha256=VvS3G0wrm_9BH3B7Ex5msLL_1UQTtCq5G8dDI63Iemo,3259 +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=tKyzfo5bhDGLVTTQCQJ9PFnDjimQvEWnwIAI2XHpaac,21039 +pip/_internal/commands/list.py,sha256=n740MsR0cG34EuvGWMzdVl0uIA3UIYx1_95FUsTktN0,10272 +pip/_internal/commands/search.py,sha256=sLZ9icKMEEGekHvzRRZMiTd1zCFIZeDptyyU1mQCYzk,4728 +pip/_internal/commands/show.py,sha256=9EVh86vY0NZdlhT-wsuV-zq_MAV6qqV4S1Akn3wkUuw,6289 +pip/_internal/commands/uninstall.py,sha256=h0gfPF5jylDESx_IHgF6bZME7QAEOHzQHdn65GP-jrE,2963 +pip/_internal/commands/wheel.py,sha256=ZuVf_DMpKCUzBVstolvQPAeajQRC51Oky5_hDHzhhFs,7020 +pip/_internal/configuration.py,sha256=KMgG3ufFrUKX_QESi2cMVvFi47tl845Bg1ZkNthlWik,13243 +pip/_internal/download.py,sha256=c5Hkimq39eJdZ6DN0_0etjK43-0a5CK_W_3sVLqH87g,33300 +pip/_internal/exceptions.py,sha256=EIGotnq6qM2nbGtnlgZ8Xp5VfP2W4-9UOCzQGMwy5MY,8899 +pip/_internal/index.py,sha256=6CAtZ8QTLcpw0fJqQ9OPu-Os1ettLZtVY1pPSKia8r8,34789 +pip/_internal/locations.py,sha256=ujNrLnA04Y_EmSriO0nS6qkkw_BkPfobB_hdwIDPvpM,6307 +pip/_internal/models/__init__.py,sha256=3DHUd_qxpPozfzouoqa9g9ts1Czr5qaHfFxbnxriepM,63 +pip/_internal/models/__pycache__/__init__.cpython-37.pyc,, +pip/_internal/models/__pycache__/candidate.cpython-37.pyc,, +pip/_internal/models/__pycache__/format_control.cpython-37.pyc,, +pip/_internal/models/__pycache__/index.cpython-37.pyc,, +pip/_internal/models/__pycache__/link.cpython-37.pyc,, +pip/_internal/models/candidate.py,sha256=zq2Vb5l5JflrVX7smHTJHQciZWHyoJZuYTLeQa1G16c,741 +pip/_internal/models/format_control.py,sha256=aDbH4D2XuyaGjtRjTLQhNzClAcLZdJCKSHO8xbZSmFA,2202 +pip/_internal/models/index.py,sha256=YI1WlhWfS9mVPY0bIboA5la2pjJ2J0qgPJIbvdEjZBk,996 +pip/_internal/models/link.py,sha256=E61PvS2Wrmb9-zT-eAc_8_xI3C-89wJlpL8SL-mlQmg,3998 +pip/_internal/operations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_internal/operations/__pycache__/__init__.cpython-37.pyc,, +pip/_internal/operations/__pycache__/check.cpython-37.pyc,, +pip/_internal/operations/__pycache__/freeze.cpython-37.pyc,, +pip/_internal/operations/__pycache__/prepare.cpython-37.pyc,, +pip/_internal/operations/check.py,sha256=ahcOg5p68nNow6_wy5prYYK0KZq22lm0CsJn8AyDMCI,4937 +pip/_internal/operations/freeze.py,sha256=lskaBcqf3bPZupG032fuLf76QYv5wpAQ6jsiXac56Bg,10450 +pip/_internal/operations/prepare.py,sha256=atoLFj3OD5KfXsa5dYBMC_mI06l068F5yZhF4jle1JA,14280 +pip/_internal/pep425tags.py,sha256=TQhxOPss4RjxgyVgxpSRe31HaTcWmn-LVjWBbkvkjzk,10845 +pip/_internal/pyproject.py,sha256=fpO52MCa3w5xSlXIBXw39BDTGzP8G4570EW34hVvIKQ,5481 +pip/_internal/req/__init__.py,sha256=JnNZWvKUQuqAwHh64LCD3zprzWIVQEXChTo2UGHzVqo,2093 +pip/_internal/req/__pycache__/__init__.cpython-37.pyc,, +pip/_internal/req/__pycache__/constructors.cpython-37.pyc,, +pip/_internal/req/__pycache__/req_file.cpython-37.pyc,, +pip/_internal/req/__pycache__/req_install.cpython-37.pyc,, +pip/_internal/req/__pycache__/req_set.cpython-37.pyc,, +pip/_internal/req/__pycache__/req_tracker.cpython-37.pyc,, +pip/_internal/req/__pycache__/req_uninstall.cpython-37.pyc,, +pip/_internal/req/constructors.py,sha256=97WQp9Svh-Jw3oLZL9_57gJ3zihm5LnWlSRjOwOorDU,9573 +pip/_internal/req/req_file.py,sha256=ORA0GKUjGd6vy7pmBwXR55FFj4h_OxYykFQ6gHuWvt0,11940 +pip/_internal/req/req_install.py,sha256=ry1RtNNCefDHAnf3EeGMpea-9pC6Yk1uHzP0Q5p2Un0,34046 +pip/_internal/req/req_set.py,sha256=nE6oagXJSiQREuuebX3oJO5OHSOVUIlvLLilodetBzc,7264 +pip/_internal/req/req_tracker.py,sha256=zH28YHV5TXAVh1ZOEZi6Z1Edkiu26dN2tXfR6VbQ3B4,2370 +pip/_internal/req/req_uninstall.py,sha256=ORSPah64KOVrKo-InMM3zgS5HQqbl5TLHFnE_Lxstq8,16737 +pip/_internal/resolve.py,sha256=tdepxCewsXXNFKSIYGSxiLvzi1xCv7UVFT9jRCDO90A,13578 +pip/_internal/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_internal/utils/__pycache__/__init__.cpython-37.pyc,, +pip/_internal/utils/__pycache__/appdirs.cpython-37.pyc,, +pip/_internal/utils/__pycache__/compat.cpython-37.pyc,, +pip/_internal/utils/__pycache__/deprecation.cpython-37.pyc,, +pip/_internal/utils/__pycache__/encoding.cpython-37.pyc,, +pip/_internal/utils/__pycache__/filesystem.cpython-37.pyc,, +pip/_internal/utils/__pycache__/glibc.cpython-37.pyc,, +pip/_internal/utils/__pycache__/hashes.cpython-37.pyc,, +pip/_internal/utils/__pycache__/logging.cpython-37.pyc,, +pip/_internal/utils/__pycache__/misc.cpython-37.pyc,, +pip/_internal/utils/__pycache__/models.cpython-37.pyc,, +pip/_internal/utils/__pycache__/outdated.cpython-37.pyc,, +pip/_internal/utils/__pycache__/packaging.cpython-37.pyc,, +pip/_internal/utils/__pycache__/setuptools_build.cpython-37.pyc,, +pip/_internal/utils/__pycache__/temp_dir.cpython-37.pyc,, +pip/_internal/utils/__pycache__/typing.cpython-37.pyc,, +pip/_internal/utils/__pycache__/ui.cpython-37.pyc,, +pip/_internal/utils/appdirs.py,sha256=SPfibHtvOKzD_sHrpEZ60HfLae3GharU4Tg7SB3c-XM,9120 +pip/_internal/utils/compat.py,sha256=LSAvzXcsGY2O2drKIPszR5Ja2G0kup__51l3bx1jR_Q,8015 +pip/_internal/utils/deprecation.py,sha256=yQTe6dyWlBfxSBrOv_MdRXF1RPLER_EWOp-pa2zLoZc,3021 +pip/_internal/utils/encoding.py,sha256=D8tmfStCah6xh9OLhH9mWLr77q4akhg580YHJMKpq3Y,1025 +pip/_internal/utils/filesystem.py,sha256=ZOIHbacJ-SJtuZru4GoA5DuSIYyeaE4G5kfZPf5cn1A,915 +pip/_internal/utils/glibc.py,sha256=prOrsBjmgkDE-hY4Pl120yF5MIlkkmGrFLs8XfIyT-w,3004 +pip/_internal/utils/hashes.py,sha256=rJk-gj6F-sHggXAG97dhynqUHFFgApyZLWgaG2xCHME,2900 +pip/_internal/utils/logging.py,sha256=BQeUDEER3zlK0O4yv6DBfz6TK3f9XoLXyDlnB0mZVf0,6295 +pip/_internal/utils/misc.py,sha256=YscDfBiFx1spYOtSgdI_5hnc5BZUysWAyz1aVL5y-48,29904 +pip/_internal/utils/models.py,sha256=DQYZSRhjvSdDTAaJLLCpDtxAn1S_-v_8nlNjv4T2jwY,1042 +pip/_internal/utils/outdated.py,sha256=BXtCMKR6gjTrvMfP3MWzZ1Y4ZU4qqoCfbRNqQCusVt8,5642 +pip/_internal/utils/packaging.py,sha256=Ru8ls_S8PPKR8RKEn7jMetENY_A9jPet1HlhTZwpFxU,2443 +pip/_internal/utils/setuptools_build.py,sha256=0blfscmNJW_iZ5DcswJeDB_PbtTEjfK9RL1R1WEDW2E,278 +pip/_internal/utils/temp_dir.py,sha256=n2FkVlwRX_hS61fYt3nSAh2e2V6CcZn_dfbPId1pAQE,2615 +pip/_internal/utils/typing.py,sha256=ztYtZAcqjCYDwP-WlF6EiAAskAsZBMMXtuqvfgZIlgQ,1139 +pip/_internal/utils/ui.py,sha256=FW8wdtc7DvNwJClGr_TvGZlqcoO482GYe0UY9nKmpso,13657 +pip/_internal/vcs/__init__.py,sha256=2Ct9ogOwzS6ZKKaEXKN2XDiBOiFHMcejnN1KM21mLrQ,16319 +pip/_internal/vcs/__pycache__/__init__.cpython-37.pyc,, +pip/_internal/vcs/__pycache__/bazaar.cpython-37.pyc,, +pip/_internal/vcs/__pycache__/git.cpython-37.pyc,, +pip/_internal/vcs/__pycache__/mercurial.cpython-37.pyc,, +pip/_internal/vcs/__pycache__/subversion.cpython-37.pyc,, +pip/_internal/vcs/bazaar.py,sha256=rjskVmSSn68O7lC5JrGmDTWXneXFMMJJvj_bbdSM8QA,3669 +pip/_internal/vcs/git.py,sha256=n1cFBqTnLIcxAOClZMgOBqELjEjygDBPZ9z-Q7g0qVQ,12580 +pip/_internal/vcs/mercurial.py,sha256=jVTa0XQpFR6EiBcaqW4E4JjTce_t1tFnKRaIhaIPlS8,3471 +pip/_internal/vcs/subversion.py,sha256=vDLTfcjj0kgqcEsbPBfveC4CRxyhWiOjke-qN0Zr8CE,7676 +pip/_internal/wheel.py,sha256=fg9E936DaI1LyrBPHqtzHG_WEVyuUwipHISkD6N3jNw,32007 +pip/_vendor/__init__.py,sha256=XnhkujjE1qUGRlYGYbIRrEGYYYBcNLBraE27HH48wYw,4756 +pip/_vendor/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/__pycache__/appdirs.cpython-37.pyc,, +pip/_vendor/__pycache__/distro.cpython-37.pyc,, +pip/_vendor/__pycache__/ipaddress.cpython-37.pyc,, +pip/_vendor/__pycache__/pyparsing.cpython-37.pyc,, +pip/_vendor/__pycache__/retrying.cpython-37.pyc,, +pip/_vendor/__pycache__/six.cpython-37.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-37.pyc,, +pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-37.pyc,, +pip/_vendor/cachecontrol/__pycache__/adapter.cpython-37.pyc,, +pip/_vendor/cachecontrol/__pycache__/cache.cpython-37.pyc,, +pip/_vendor/cachecontrol/__pycache__/compat.cpython-37.pyc,, +pip/_vendor/cachecontrol/__pycache__/controller.cpython-37.pyc,, +pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-37.pyc,, +pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-37.pyc,, +pip/_vendor/cachecontrol/__pycache__/serialize.cpython-37.pyc,, +pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-37.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-37.pyc,, +pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-37.pyc,, +pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-37.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=5lCYV1iWxoirX1OAaSHkBYUuZGdcwEjEBS6DS_trL0s,63 +pip/_vendor/certifi/__main__.py,sha256=NaCn6WtWME-zzVWQ2j4zFyl8cY4knDa9CwtHNIeFPhM,53 +pip/_vendor/certifi/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/certifi/__pycache__/__main__.cpython-37.pyc,, +pip/_vendor/certifi/__pycache__/core.cpython-37.pyc,, +pip/_vendor/certifi/cacert.pem,sha256=XA-4HVBsOrBD5lfg-b3PiUzAvwUd2qlIzwXypIMIRGM,263074 +pip/_vendor/certifi/core.py,sha256=xPQDdG_siy5A7BfqGWa7RJhcA61xXEqPiSrw9GNyhHE,836 +pip/_vendor/chardet/__init__.py,sha256=YsP5wQlsHJ2auF1RZJfypiSrCA7_bQiRm3ES_NI76-Y,1559 +pip/_vendor/chardet/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/big5freq.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/big5prober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/chardistribution.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/charsetprober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/compat.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/cp949prober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/enums.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/escprober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/escsm.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/eucjpprober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/euckrfreq.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/euckrprober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/euctwfreq.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/euctwprober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/gb2312freq.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/gb2312prober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/hebrewprober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/jisfreq.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/jpcntx.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/langcyrillicmodel.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/langthaimodel.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/latin1prober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/mbcssm.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/sjisprober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/universaldetector.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/utf8prober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/version.cpython-37.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-37.pyc,, +pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-37.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=V3-Hv_vOa-2lE5Q_0mGkdhZo-9e4XrGTW_44cU81qQY,240 +pip/_vendor/colorama/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/colorama/__pycache__/ansi.cpython-37.pyc,, +pip/_vendor/colorama/__pycache__/ansitowin32.cpython-37.pyc,, +pip/_vendor/colorama/__pycache__/initialise.cpython-37.pyc,, +pip/_vendor/colorama/__pycache__/win32.cpython-37.pyc,, +pip/_vendor/colorama/__pycache__/winterm.cpython-37.pyc,, +pip/_vendor/colorama/ansi.py,sha256=Fi0un-QLqRm-v7o_nKiOqyC8PapBJK7DLV_q9LKtTO0,2524 +pip/_vendor/colorama/ansitowin32.py,sha256=QrieYX2tsaWIO19P6biMa1zUCt-_abudoEp2_IdqZZU,9668 +pip/_vendor/colorama/initialise.py,sha256=cHqVJtb82OG7HUCxvQ2joG7N_CoxbIKbI_fgryZkj20,1917 +pip/_vendor/colorama/win32.py,sha256=5Hc7L1LabubrYDhdWAfRyzlt14ErP3YKDvf_zYaarLk,5426 +pip/_vendor/colorama/winterm.py,sha256=V7U7ojwG1q4n6PKripjEvW_htYQi5ueXSM3LUUoqqDY,6290 +pip/_vendor/distlib/__init__.py,sha256=GxRrh1augb66Eo9NB9jrdwQS02KcBypj9o_-C3oyKZI,581 +pip/_vendor/distlib/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/distlib/__pycache__/compat.cpython-37.pyc,, +pip/_vendor/distlib/__pycache__/database.cpython-37.pyc,, +pip/_vendor/distlib/__pycache__/index.cpython-37.pyc,, +pip/_vendor/distlib/__pycache__/locators.cpython-37.pyc,, +pip/_vendor/distlib/__pycache__/manifest.cpython-37.pyc,, +pip/_vendor/distlib/__pycache__/markers.cpython-37.pyc,, +pip/_vendor/distlib/__pycache__/metadata.cpython-37.pyc,, +pip/_vendor/distlib/__pycache__/resources.cpython-37.pyc,, +pip/_vendor/distlib/__pycache__/scripts.cpython-37.pyc,, +pip/_vendor/distlib/__pycache__/util.cpython-37.pyc,, +pip/_vendor/distlib/__pycache__/version.cpython-37.pyc,, +pip/_vendor/distlib/__pycache__/wheel.cpython-37.pyc,, +pip/_vendor/distlib/_backport/__init__.py,sha256=bqS_dTOH6uW9iGgd0uzfpPjo6vZ4xpPZ7kyfZJ2vNaw,274 +pip/_vendor/distlib/_backport/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/distlib/_backport/__pycache__/misc.cpython-37.pyc,, +pip/_vendor/distlib/_backport/__pycache__/shutil.cpython-37.pyc,, +pip/_vendor/distlib/_backport/__pycache__/sysconfig.cpython-37.pyc,, +pip/_vendor/distlib/_backport/__pycache__/tarfile.cpython-37.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=LqTcNkDyV4bWcc_qDxiYJHnXaNxFs1O1bFSAg_reaI0,50868 +pip/_vendor/distlib/index.py,sha256=Dd1kIV06XIdynNpKxHMMRRIKsXuoUsG7QIzntfVtZCI,21073 +pip/_vendor/distlib/locators.py,sha256=e4UaQSzNg5iG3PfQRH6lnVMfLOwhm2sVmGGRdjdB3ik,51657 +pip/_vendor/distlib/manifest.py,sha256=nQEhYmgoreaBZzyFzwYsXxJARu3fo4EkunU163U16iE,14811 +pip/_vendor/distlib/markers.py,sha256=6Ac3cCfFBERexiESWIOXmg-apIP8l2esafNSX3KMy-8,4387 +pip/_vendor/distlib/metadata.py,sha256=Ns92dqeMxopDPQsiEWnhMtd4RagJaA58lz8O_vjCxyk,39986 +pip/_vendor/distlib/resources.py,sha256=2FGv0ZHF14KXjLIlL0R991lyQQGcewOS4mJ-5n-JVnc,10766 +pip/_vendor/distlib/scripts.py,sha256=WEqXkpRvqR6oe-QlMRYg8gEJxXRWJeWn1GPc0ihZ4N0,16585 +pip/_vendor/distlib/t32.exe,sha256=ftub1bsSPUCOnBn-eCtcarKTk0N0CBEP53BumkIxWJE,92672 +pip/_vendor/distlib/t64.exe,sha256=iChOG627LWTHY8-jzSwlo9SYU5a-0JHwQu4AqDz8I68,102400 +pip/_vendor/distlib/util.py,sha256=FnzjaibVcIg1xOtET6QPNeqTnn3LcWLCjNOficMyGKA,59494 +pip/_vendor/distlib/version.py,sha256=_n7F6juvQGAcn769E_SHa7fOcf5ERlEVymJ_EjPRwGw,23391 +pip/_vendor/distlib/w32.exe,sha256=NPYPpt7PIjVqABEu1CzabbDyHHkJpuw-_qZq_48H0j0,89088 +pip/_vendor/distlib/w64.exe,sha256=Yb-qr1OQEzL8KRGTk-XHUZDwMSljfQeZnVoTk-K4e7E,99328 +pip/_vendor/distlib/wheel.py,sha256=W9aKwi4CQL_bQFYb8IcwH-c6WK-yku5P8SY3RGPv-Mk,39506 +pip/_vendor/distro.py,sha256=dOMrjIXv-3GmEbtP-NJc057Sv19P7ZAdke-v0TBeNio,42455 +pip/_vendor/html5lib/__init__.py,sha256=Ztrn7UvF-wIFAgRBBa0ML-Gu5AffH3BPX_INJx4SaBI,1162 +pip/_vendor/html5lib/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/html5lib/__pycache__/_ihatexml.cpython-37.pyc,, +pip/_vendor/html5lib/__pycache__/_inputstream.cpython-37.pyc,, +pip/_vendor/html5lib/__pycache__/_tokenizer.cpython-37.pyc,, +pip/_vendor/html5lib/__pycache__/_utils.cpython-37.pyc,, +pip/_vendor/html5lib/__pycache__/constants.cpython-37.pyc,, +pip/_vendor/html5lib/__pycache__/html5parser.cpython-37.pyc,, +pip/_vendor/html5lib/__pycache__/serializer.cpython-37.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-37.pyc,, +pip/_vendor/html5lib/_trie/__pycache__/_base.cpython-37.pyc,, +pip/_vendor/html5lib/_trie/__pycache__/datrie.cpython-37.pyc,, +pip/_vendor/html5lib/_trie/__pycache__/py.cpython-37.pyc,, +pip/_vendor/html5lib/_trie/_base.py,sha256=uJHVhzif9S0MJXgy9F98iEev5evi_rgUk5BmEbUSp8c,930 +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-37.pyc,, +pip/_vendor/html5lib/filters/__pycache__/alphabeticalattributes.cpython-37.pyc,, +pip/_vendor/html5lib/filters/__pycache__/base.cpython-37.pyc,, +pip/_vendor/html5lib/filters/__pycache__/inject_meta_charset.cpython-37.pyc,, +pip/_vendor/html5lib/filters/__pycache__/lint.cpython-37.pyc,, +pip/_vendor/html5lib/filters/__pycache__/optionaltags.cpython-37.pyc,, +pip/_vendor/html5lib/filters/__pycache__/sanitizer.cpython-37.pyc,, +pip/_vendor/html5lib/filters/__pycache__/whitespace.cpython-37.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-37.pyc,, +pip/_vendor/html5lib/treeadapters/__pycache__/genshi.cpython-37.pyc,, +pip/_vendor/html5lib/treeadapters/__pycache__/sax.cpython-37.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-37.pyc,, +pip/_vendor/html5lib/treebuilders/__pycache__/base.cpython-37.pyc,, +pip/_vendor/html5lib/treebuilders/__pycache__/dom.cpython-37.pyc,, +pip/_vendor/html5lib/treebuilders/__pycache__/etree.cpython-37.pyc,, +pip/_vendor/html5lib/treebuilders/__pycache__/etree_lxml.cpython-37.pyc,, +pip/_vendor/html5lib/treebuilders/base.py,sha256=wQGp5yy22TNG8tJ6aREe4UUeTR7A99dEz0BXVaedWb4,14579 +pip/_vendor/html5lib/treebuilders/dom.py,sha256=SY3MsijXyzdNPc8aK5IQsupBoM8J67y56DgNtGvsb9g,8835 +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-37.pyc,, +pip/_vendor/html5lib/treewalkers/__pycache__/base.cpython-37.pyc,, +pip/_vendor/html5lib/treewalkers/__pycache__/dom.cpython-37.pyc,, +pip/_vendor/html5lib/treewalkers/__pycache__/etree.cpython-37.pyc,, +pip/_vendor/html5lib/treewalkers/__pycache__/etree_lxml.cpython-37.pyc,, +pip/_vendor/html5lib/treewalkers/__pycache__/genshi.cpython-37.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-37.pyc,, +pip/_vendor/idna/__pycache__/codec.cpython-37.pyc,, +pip/_vendor/idna/__pycache__/compat.cpython-37.pyc,, +pip/_vendor/idna/__pycache__/core.cpython-37.pyc,, +pip/_vendor/idna/__pycache__/idnadata.cpython-37.pyc,, +pip/_vendor/idna/__pycache__/intranges.cpython-37.pyc,, +pip/_vendor/idna/__pycache__/package_data.cpython-37.pyc,, +pip/_vendor/idna/__pycache__/uts46data.cpython-37.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=OwI5R_uuXU4PlOSoG8cjaMPA1hhdGGjjZ8I2MZhSPxo,11858 +pip/_vendor/idna/idnadata.py,sha256=zwxvoSsYqPHNa6xzXWHizXpDC28JJMGXRinhJ4Gkcz0,39285 +pip/_vendor/idna/intranges.py,sha256=TY1lpxZIQWEP6tNqjZkFA5hgoMWOj1OBmnUG8ihT87E,1749 +pip/_vendor/idna/package_data.py,sha256=Vt9rtr32BzO7O25rypo8nzAs3syTJhG1ojU3J-s2RFo,21 +pip/_vendor/idna/uts46data.py,sha256=czULzYN5Lr9K5MmOH-1g3CJY7QPjGeHjYmC3saJ_BHk,197803 +pip/_vendor/ipaddress.py,sha256=2OgbkeAD2rLkcXqbcvof3J5R7lRwjNLoBySyTkBtKnc,79852 +pip/_vendor/lockfile/__init__.py,sha256=Tqpz90DwKYfhPsfzVOJl84TL87pdFE5ePNHdXAxs4Tk,9371 +pip/_vendor/lockfile/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/lockfile/__pycache__/linklockfile.cpython-37.pyc,, +pip/_vendor/lockfile/__pycache__/mkdirlockfile.cpython-37.pyc,, +pip/_vendor/lockfile/__pycache__/pidlockfile.cpython-37.pyc,, +pip/_vendor/lockfile/__pycache__/sqlitelockfile.cpython-37.pyc,, +pip/_vendor/lockfile/__pycache__/symlinklockfile.cpython-37.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=y0bk2YbzK6J2e0J_dyreN6nD7yM2IezT6m_tU2h-Mdg,1677 +pip/_vendor/msgpack/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/msgpack/__pycache__/_version.cpython-37.pyc,, +pip/_vendor/msgpack/__pycache__/exceptions.cpython-37.pyc,, +pip/_vendor/msgpack/__pycache__/fallback.cpython-37.pyc,, +pip/_vendor/msgpack/_version.py,sha256=dN7wVIjbyuQIJ35B2o6gymQNDLPlj_7-uTfgCv7KErM,20 +pip/_vendor/msgpack/exceptions.py,sha256=lPkAi_u12NlFajDz4FELSHEdfU8hrR3zeTvKX8aQuz4,1056 +pip/_vendor/msgpack/fallback.py,sha256=h0ll8xnq12mI9PuQ9Qd_Ihtt08Sp8L0JqhG9KY8Vyjk,36411 +pip/_vendor/packaging/__about__.py,sha256=mH-sMIEu48PzdYakZ6Y6OBzL3TlSetzz1fQSkCXiy30,720 +pip/_vendor/packaging/__init__.py,sha256=_vNac5TrzwsrzbOFIbF-5cHqc_Y2aPT2D7zrIR06BOo,513 +pip/_vendor/packaging/__pycache__/__about__.cpython-37.pyc,, +pip/_vendor/packaging/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/packaging/__pycache__/_compat.cpython-37.pyc,, +pip/_vendor/packaging/__pycache__/_structures.cpython-37.pyc,, +pip/_vendor/packaging/__pycache__/markers.cpython-37.pyc,, +pip/_vendor/packaging/__pycache__/requirements.cpython-37.pyc,, +pip/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc,, +pip/_vendor/packaging/__pycache__/utils.cpython-37.pyc,, +pip/_vendor/packaging/__pycache__/version.cpython-37.pyc,, +pip/_vendor/packaging/_compat.py,sha256=Vi_A0rAQeHbU-a9X0tt1yQm9RqkgQbDSxzRw8WlU9kA,860 +pip/_vendor/packaging/_structures.py,sha256=DCpKtb7u94_oqgVsIJQTrTyZcb3Gz7sSGbk9vYDMME0,1418 +pip/_vendor/packaging/markers.py,sha256=ftZegBU5oEmulEKApDGEPgti2lYIchFQHAfH9tZy3_U,8221 +pip/_vendor/packaging/requirements.py,sha256=xIWdoZXVKhUHxqFP5xmnKylM7NHXQS48hUfIIX1PvY0,4439 +pip/_vendor/packaging/specifiers.py,sha256=pFp716eLYBRt0eLNsy6cnWD9dyMKq-Zag7bsLbLv4Fs,28026 +pip/_vendor/packaging/utils.py,sha256=c9obOpok2CpKDApkc2M5ma0YFnT-jtt4I6XI4F0jYiI,1580 +pip/_vendor/packaging/version.py,sha256=MKL8nbKLPLGPouIwFvwSVnYRzNpkMo5AIcsa6LGqDF8,12219 +pip/_vendor/pep517/__init__.py,sha256=GH4HshnLERtjAjkY0zHoz3f7-35UcIvr27iFWSOUazU,82 +pip/_vendor/pep517/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/pep517/__pycache__/_in_process.cpython-37.pyc,, +pip/_vendor/pep517/__pycache__/check.cpython-37.pyc,, +pip/_vendor/pep517/__pycache__/colorlog.cpython-37.pyc,, +pip/_vendor/pep517/__pycache__/compat.cpython-37.pyc,, +pip/_vendor/pep517/__pycache__/envbuild.cpython-37.pyc,, +pip/_vendor/pep517/__pycache__/wrappers.cpython-37.pyc,, +pip/_vendor/pep517/_in_process.py,sha256=iWpagFk2GhNBbvl-Ca2RagfD0ALuits4WWSM6nQMTdg,5831 +pip/_vendor/pep517/check.py,sha256=Yp2NHW71DIOCgkFb7HKJOzKmsum_s_OokRP6HnR3bTg,5761 +pip/_vendor/pep517/colorlog.py,sha256=2AJuPI_DHM5T9IDgcTwf0E8suyHAFnfsesogr0AB7RQ,4048 +pip/_vendor/pep517/compat.py,sha256=4SFG4QN-cNj8ebSa0wV0HUtEEQWwmbok2a0uk1gYEOM,631 +pip/_vendor/pep517/envbuild.py,sha256=osRsJVd7hir1w_uFXiVeeWxfJ3iYhwxsKRgNBWpqtCI,5672 +pip/_vendor/pep517/wrappers.py,sha256=RhgWm-MLxpYPgc9cZ3-A3ToN99ZzgM8-ia4FDB58koM,5018 +pip/_vendor/pkg_resources/__init__.py,sha256=ykZI7-YBIAQ7ztWf0RskP8Oy1VQU88o-16PJbIMCtLg,103915 +pip/_vendor/pkg_resources/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-37.pyc,, +pip/_vendor/pkg_resources/py31compat.py,sha256=CRk8fkiPRDLsbi5pZcKsHI__Pbmh_94L8mr9Qy9Ab2U,562 +pip/_vendor/progress/__init__.py,sha256=Hv3Y8Hr6RyM34NdZkrZQWMURjS2h5sONRHJSvZXWZgQ,3188 +pip/_vendor/progress/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/progress/__pycache__/bar.cpython-37.pyc,, +pip/_vendor/progress/__pycache__/counter.cpython-37.pyc,, +pip/_vendor/progress/__pycache__/helpers.cpython-37.pyc,, +pip/_vendor/progress/__pycache__/spinner.cpython-37.pyc,, +pip/_vendor/progress/bar.py,sha256=hlkDAEv9pRRiWqR5XL6vIAgMG4u_dBGEW_8klQhBRq0,2942 +pip/_vendor/progress/counter.py,sha256=XtBuZY4yYmr50E2A_fAzjWhm0IkwaVwxNsNVYDE7nsw,1528 +pip/_vendor/progress/helpers.py,sha256=6FsBLh_xUlKiVua-zZIutCjxth-IO8FtyUj6I2tx9fg,2952 +pip/_vendor/progress/spinner.py,sha256=m7bASI2GUbLFG-PbAefdHtrrWWlJLFhhSBbw70gp2TY,1439 +pip/_vendor/pyparsing.py,sha256=My2ZwDJCEaZkZgZyG9gL--48RLGmf9vnVCTW93rhdYI,226342 +pip/_vendor/pytoml/__init__.py,sha256=q12Xv23Tta44gtK4HGK68Gr4tKfciILidFPmPuoIqIo,92 +pip/_vendor/pytoml/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/pytoml/__pycache__/core.cpython-37.pyc,, +pip/_vendor/pytoml/__pycache__/parser.cpython-37.pyc,, +pip/_vendor/pytoml/__pycache__/writer.cpython-37.pyc,, +pip/_vendor/pytoml/core.py,sha256=9CrLLTs1PdWjEwRnYzt_i4dhHcZvGxs_GsMlYAX3iY4,509 +pip/_vendor/pytoml/parser.py,sha256=mcTzHB2GQGyK8KVwuQ0EraSz_78O36U60NqHBtgVmV0,11247 +pip/_vendor/pytoml/writer.py,sha256=-mSOVGaiGLrpj5BRR7czmquZXJGflcElHrwAd33J48A,3815 +pip/_vendor/requests/__init__.py,sha256=OrwNk1JwZGqIQ4JVGgMbfpstqey-oHS_Re_Dw6D4ciI,4209 +pip/_vendor/requests/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/__version__.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/_internal_utils.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/adapters.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/api.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/auth.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/certs.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/compat.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/cookies.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/exceptions.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/help.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/hooks.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/models.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/packages.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/sessions.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/status_codes.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/structures.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/utils.cpython-37.pyc,, +pip/_vendor/requests/__version__.py,sha256=rJ2xgNOLhjspGkNPfgXTBctqqvsf2uJMFTaE0rlVtbI,436 +pip/_vendor/requests/_internal_utils.py,sha256=Zx3PnEUccyfsB-ie11nZVAW8qClJy0gx1qNME7rgT18,1096 +pip/_vendor/requests/adapters.py,sha256=y5DISepvSsGlu3II_VUsdgKBej1dGY4b5beRrTE2tsI,21428 +pip/_vendor/requests/api.py,sha256=zub9ENcEUT2m9gwgBgqH5RIRDfrx2kwRpZ7L6hX3mcw,6261 +pip/_vendor/requests/auth.py,sha256=oRSQkBYcLkTEssudkzoR1UW1Glb1ts3p1RWusgHf1YU,10208 +pip/_vendor/requests/certs.py,sha256=nXRVq9DtGmv_1AYbwjTu9UrgAcdJv05ZvkNeaoLOZxY,465 +pip/_vendor/requests/compat.py,sha256=7EC6fZY4dJDxuBQnqUGwe13OTZ3VLGO3QfOApE5lE3I,1998 +pip/_vendor/requests/cookies.py,sha256=olUaLeNci_z1K-Bn5PeEKllSspmQqN9-s8Ug7CasaPE,18346 +pip/_vendor/requests/exceptions.py,sha256=-mLam3TAx80V09EaH3H-ZxR61eAVuLRZ8zgBBSLjK44,3197 +pip/_vendor/requests/help.py,sha256=T4K-Oo_FS9fxF8NHVR8hxMwFo71gIkRM7UddCc9vH7Y,3669 +pip/_vendor/requests/hooks.py,sha256=HXAHoC1FNTFRZX6-lNdvPM7Tst4kvGwYTN-AOKRxoRU,767 +pip/_vendor/requests/models.py,sha256=3fmmYdDW7U18SrVeZaseHuk8KPI-7vLp_435DY3ejes,34160 +pip/_vendor/requests/packages.py,sha256=njJmVifY4aSctuW3PP5EFRCxjEwMRDO6J_feG2dKWsI,695 +pip/_vendor/requests/sessions.py,sha256=71MK2HCadovka1vAx9dyDFWAuw69KgRPRBpd0HWSEAo,27829 +pip/_vendor/requests/status_codes.py,sha256=pgw-xlnxO5zHQWn3fKps2cxwQehKzPxEbdhIrMQe6Ec,4128 +pip/_vendor/requests/structures.py,sha256=zoP8qly2Jak5e89HwpqjN1z2diztI-_gaqts1raJJBc,2981 +pip/_vendor/requests/utils.py,sha256=3OxbbLUQFVdm84fdBD9nduXvhw6hIzj59mhvBomKuJI,30156 +pip/_vendor/retrying.py,sha256=k3fflf5_Mm0XcIJYhB7Tj34bqCCPhUDkYbx1NvW2FPE,9972 +pip/_vendor/six.py,sha256=A08MPb-Gi9FfInI3IW7HimXFmEH2T2IPzHgDvdhZPRA,30888 +pip/_vendor/urllib3/__init__.py,sha256=DZucS8tlzGYKmK5FIsyUViMghpCq_0_0Ouvm_Jp9GNc,2853 +pip/_vendor/urllib3/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/urllib3/__pycache__/_collections.cpython-37.pyc,, +pip/_vendor/urllib3/__pycache__/connection.cpython-37.pyc,, +pip/_vendor/urllib3/__pycache__/connectionpool.cpython-37.pyc,, +pip/_vendor/urllib3/__pycache__/exceptions.cpython-37.pyc,, +pip/_vendor/urllib3/__pycache__/fields.cpython-37.pyc,, +pip/_vendor/urllib3/__pycache__/filepost.cpython-37.pyc,, +pip/_vendor/urllib3/__pycache__/poolmanager.cpython-37.pyc,, +pip/_vendor/urllib3/__pycache__/request.cpython-37.pyc,, +pip/_vendor/urllib3/__pycache__/response.cpython-37.pyc,, +pip/_vendor/urllib3/_collections.py,sha256=iNeAU_we9L3lMGRUKKdq24Mf7o050TXP5U4Jm9AzAY4,10841 +pip/_vendor/urllib3/connection.py,sha256=My76qeWMDkV-KP1l3iChXHOE7J-ZCaUdP3sPIiLA2uE,14485 +pip/_vendor/urllib3/connectionpool.py,sha256=w20OwKdIqk6f8FIl6QGgn6jf9gZ0-tmgH7VPxnpEgkQ,35464 +pip/_vendor/urllib3/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-37.pyc,, +pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-37.pyc,, +pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-37.pyc,, +pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-37.pyc,, +pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-37.pyc,, +pip/_vendor/urllib3/contrib/_securetransport/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-37.pyc,, +pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-37.pyc,, +pip/_vendor/urllib3/contrib/_securetransport/bindings.py,sha256=x2kLSh-ASZKsun0FxtraBuLVe3oHuth4YW6yZ5Vof-w,17560 +pip/_vendor/urllib3/contrib/_securetransport/low_level.py,sha256=Umy5u-3Z957GirdapnicXVOpHaM4xdOZABJuJxfaeJA,12162 +pip/_vendor/urllib3/contrib/appengine.py,sha256=Q3BDy5C_TrI-3cSyo0ELNGlNiK2eSVptQAQMdz4PH9Q,11197 +pip/_vendor/urllib3/contrib/ntlmpool.py,sha256=Q9-rO5Rh2-IqyEd4ZicpTDfMnOlf0IPPCkjhChBCjV4,4478 +pip/_vendor/urllib3/contrib/pyopenssl.py,sha256=cM7fVZJRrdLZsprcdWe3meM_hvq8LR73UNDveIMa-20,15480 +pip/_vendor/urllib3/contrib/securetransport.py,sha256=BqXSlChN9_hjCWgyN6JdcgvBUdc37QCCX4u3_8zE_9o,30309 +pip/_vendor/urllib3/contrib/socks.py,sha256=Iom0snbHkCuZbZ7Sle2Kueha1W0jYAJ0SyCOtePLaio,6391 +pip/_vendor/urllib3/exceptions.py,sha256=rFeIfBNKC8KJ61ux-MtJyJlEC9G9ggkmCeF751JwVR4,6604 +pip/_vendor/urllib3/fields.py,sha256=D_TE_SK15YatdbhWDMN0OE3X6UCJn1RTkANINCYOobE,5943 +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-37.pyc,, +pip/_vendor/urllib3/packages/__pycache__/ordered_dict.cpython-37.pyc,, +pip/_vendor/urllib3/packages/__pycache__/six.cpython-37.pyc,, +pip/_vendor/urllib3/packages/backports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-37.pyc,, +pip/_vendor/urllib3/packages/backports/makefile.py,sha256=r1IADol_pBBq2Y1ub4CPyuS2hXuShK47nfFngZRcRhI,1461 +pip/_vendor/urllib3/packages/ordered_dict.py,sha256=VQaPONfhVMsb8B63Xg7ZOydJqIE_jzeMhVN3Pec6ogw,8935 +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-37.pyc,, +pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/_implementation.cpython-37.pyc,, +pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py,sha256=XCW0ydHg171GfOqNbvUAnRzQ0lc0twp5-dIlolgf4RM,5719 +pip/_vendor/urllib3/poolmanager.py,sha256=FHBjb7odbP2LyQRzeitgpuh1AQAPyegzmrm2b3gSZlY,16821 +pip/_vendor/urllib3/request.py,sha256=fwjlq5nQfcUa7aoncR25z6-fJAX_oNTcPksKKGjBm38,5996 +pip/_vendor/urllib3/response.py,sha256=uAuOTZSuTodzvQWIDCZghDoKmZ2bKbgIRCfaVIIZfn8,24667 +pip/_vendor/urllib3/util/__init__.py,sha256=6Ran4oAVIy40Cu_oEPWnNV9bwF5rXx6G1DUZ7oehjPY,1044 +pip/_vendor/urllib3/util/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/urllib3/util/__pycache__/connection.cpython-37.pyc,, +pip/_vendor/urllib3/util/__pycache__/queue.cpython-37.pyc,, +pip/_vendor/urllib3/util/__pycache__/request.cpython-37.pyc,, +pip/_vendor/urllib3/util/__pycache__/response.cpython-37.pyc,, +pip/_vendor/urllib3/util/__pycache__/retry.cpython-37.pyc,, +pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-37.pyc,, +pip/_vendor/urllib3/util/__pycache__/timeout.cpython-37.pyc,, +pip/_vendor/urllib3/util/__pycache__/url.cpython-37.pyc,, +pip/_vendor/urllib3/util/__pycache__/wait.cpython-37.pyc,, +pip/_vendor/urllib3/util/connection.py,sha256=8K1VXm8BHsM3QATJJGBNRa_MStkzDy1Da2IaPAaCU8c,4279 +pip/_vendor/urllib3/util/queue.py,sha256=myTX3JDHntglKQNBf3b6dasHH-uF-W59vzGSQiFdAfI,497 +pip/_vendor/urllib3/util/request.py,sha256=H5_lrHvtwl2U2BbT1UYN9HpruNc1gsNFlz2njQmhPrQ,3705 +pip/_vendor/urllib3/util/response.py,sha256=SSNL888W-MQ8t3HAi44kNGgF682p6H__ytEXzBYxV_M,2343 +pip/_vendor/urllib3/util/retry.py,sha256=tlxiEq8OU2BSenPpPjYYO1URne8A-qTEgaykam6rZPg,15104 +pip/_vendor/urllib3/util/ssl_.py,sha256=iHJopgSv8_vXfmGg3lOsTS3ldMD9zhe130huHZxQEGU,14022 +pip/_vendor/urllib3/util/timeout.py,sha256=7lHNrgL5YH2cI1j-yZnzV_J8jBlRVdmFhQaNyM1_2b8,9757 +pip/_vendor/urllib3/util/url.py,sha256=qCY_HHUXvo05wAsEERALgExtlgxLnAHSQ7ce1b-g3SM,6487 +pip/_vendor/urllib3/util/wait.py,sha256=_4vvsT1BTTpqxQYK-2kXVfGsUsVRiuc4R4F-0Bf5BPc,5468 +pip/_vendor/webencodings/__init__.py,sha256=qOBJIuPy_4ByYH6W_bNgJF-qYQ2DoU-dKsDu5yRWCXg,10579 +pip/_vendor/webencodings/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/webencodings/__pycache__/labels.cpython-37.pyc,, +pip/_vendor/webencodings/__pycache__/mklabels.cpython-37.pyc,, +pip/_vendor/webencodings/__pycache__/tests.cpython-37.pyc,, +pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-37.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.7/site-packages/pip-18.1.dist-info/WHEEL b/venv/lib/python3.7/site-packages/pip-18.1.dist-info/WHEEL new file mode 100644 index 0000000..1001235 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip-18.1.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.32.1) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/venv/lib/python3.7/site-packages/pip-18.1.dist-info/entry_points.txt b/venv/lib/python3.7/site-packages/pip-18.1.dist-info/entry_points.txt new file mode 100644 index 0000000..f5809cb --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip-18.1.dist-info/entry_points.txt @@ -0,0 +1,5 @@ +[console_scripts] +pip = pip._internal:main +pip3 = pip._internal:main +pip3.7 = pip._internal:main + diff --git a/venv/lib/python3.7/site-packages/pip-18.1.dist-info/top_level.txt b/venv/lib/python3.7/site-packages/pip-18.1.dist-info/top_level.txt new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip-18.1.dist-info/top_level.txt @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python3.7/site-packages/pip/__init__.py b/venv/lib/python3.7/site-packages/pip/__init__.py new file mode 100644 index 0000000..ae265fa --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/__init__.py @@ -0,0 +1 @@ +__version__ = "18.1" diff --git a/venv/lib/python3.7/site-packages/pip/__main__.py b/venv/lib/python3.7/site-packages/pip/__main__.py new file mode 100644 index 0000000..0c223f8 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/__main__.py @@ -0,0 +1,19 @@ +from __future__ import absolute_import + +import os +import sys + +# 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__ == '': + # __file__ is pip-*.whl/pip/__main__.py + # first dirname call strips of '/__main__.py', second strips off '/pip' + # Resulting path is the name of the wheel itself + # Add that to sys.path so we can import pip + path = os.path.dirname(os.path.dirname(__file__)) + sys.path.insert(0, path) + +from pip._internal import main as _main # isort:skip # noqa + +if __name__ == '__main__': + sys.exit(_main()) diff --git a/venv/lib/python3.7/site-packages/pip/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..12f3340da4462f8935349583b1d6313ff44a4e70 GIT binary patch literal 204 zcmZ?b<>g`kf*$Fl7*Qbo7{q}AMj*ohh>JOZL<&O`LkeRsgCE$;aE zvecsD%>2Cg_>~MrOh9E|;#Z=6K~ZK|Vo9ogSz?iXT7FInP?>&ihJLbPLA+&^WtKs? zaau}Mv6*pMkx@lSRjvULr03~}=oe%b=w{{>mn7!o=$e`*Wn`BorGo^)I6gizFS8^* YUaz3?7Kcr4eoARhsvXFc#X!se09WlcK>z>% literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/__pycache__/__main__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/__pycache__/__main__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9f17ccb8b5c1e801e49e8a22dffb5a73f6cd30fc GIT binary patch literal 458 zcmXv}yH3L}6t$hC4SfJYY+IBMVFslI7G+>(+V5c1qiom5*pfe#t8n zzrchY(JS3^-{0b0d(5Za z3dtvimchRDkL?=PFb0(@x*^12V z$oM7E3)7}t<|Jc|A?3miT0B=wYSS-yIl?^G%x(zjJF1|Oam((=v9Jx-UqGJOX#>9` zDkWbN&7w7tQCbMfq>8ddG`lSEbT?g&-zO>Eshi1KUTyR)8(W*_(Q9P&hE`h>A%@qt o$zoL{bJuMA@ZhN2n(!_wXeHP^w5saVLJx&7^uypB9wV3k0pz%Xa{vGU literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/__init__.py b/venv/lib/python3.7/site-packages/pip/_internal/__init__.py new file mode 100644 index 0000000..276124d --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/__init__.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python +from __future__ import absolute_import + +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-stder +# 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._internal.vcs import git, mercurial, subversion, bazaar # noqa +from pip._vendor.urllib3.exceptions import InsecureRequestWarning + +logger = logging.getLogger(__name__) + +# Hide the InsecureRequestWarning from urllib3 +warnings.filterwarnings("ignore", category=InsecureRequestWarning) + + +def main(args=None): + if args is None: + args = sys.argv[1:] + + # Configure our deprecation warnings to be sent through loggers + deprecation.install_warning_logger() + + 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) diff --git a/venv/lib/python3.7/site-packages/pip/_internal/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ab90e9398fa2daa3dff635eb7a9c6d8558f24754 GIT binary patch literal 1850 zcmZuxUvC>l5Z~Q9pU;l}#Yx?yX;Oz$qyUKvRf~!$1TB#W3Q3g!EvHJSvv1>`z4wRR zwNqP8UkY#ZJ2;O>Jof|eG4=_GC%ytt%&wiP1@3gSv$H$1GxPiH-7lAm2%cZo+D~pT zAoQo6Ts#F(K8H`-!w7{a#0pjo^8gQmouZ|IWSr*AG@B55zX}q zp-tT|_mW^VDw#b+ulNWh%Qm75{UT2=((ex_`RXyEPOlU?eZpVSVy_(L`-s09)xgVT zmAL9vF#^vO?MZ7V1iXKH?Og=#>U8lOV!{3btH(>;lF^H7IlkmwGWr5*#FxFxMlZ3I zc-31qdYN5`*Ss~OSJ>5f-CK`0yp8ypcP(yuO=GV@Rh!->RAo)yq1Vr`_wKyD%~^e6 zJ*;Zh@4-gZ8r0?>EL_Hkh5dBP6(HW9tYH7Hn{Q~5u zCUX2I|U)xAJ0P%B-&Mb_^AA)y&>V{-uHPAT_ayFNRUU4>?E`(TXk2C?m z=ehM*(~3Msqq;0j%d*s~gw{C_5u)FO=%rp2;{OiuZHQl!wdrDLPwd$a6T^OPU&N60 z30_5EZbJG_=)A;dxk+xiG$H30pw1usrHdaIc8`t@k3MbQ5DJZN>}fm!*(TN924nN| zDNUM!N~x_Z?F5XDi`&}~&;t|VGWF&y2ap)&OOlKNoDU?N@brhy5Kd0QUh`$e>fA?D%kA_fT zYZ&m>Ny;EU(Tbn8Iv-{J-SOSt&C^>a;aJ?cHRK;ZljHa%Jl&-AZ7Yki?RnMPw?An= z?GM^rZ8V=BC6e+aU@afiNc#RxHsaUe#5?ebCJ2OGT(Ml@5Q1ywt>CLR!F60G8z9Z@ zEqt)`o+|qO$w0#G@_kOgldpq-&OsvpEq+DM+jF?emKcGKhUi;GYC*-N$nI$DfrjYJpX6JI|a?YIdoilrL zZq76C{OPIfFaNP*82_fq^l?zQfh7Nej2TUXnam2!rm4SH)6!qNY2#~$PA}KYnMC7+ z`Cg$}(B)j{_KMA7&ue))omJqs`o9JGa5BhRk}R&lf!f;j{Gp#MoUq*w9*|}vsLL1 zf6xyEr`gr~uegwy^W8Y=gh4x1-u+nYVY<6K#lZP?D-33yTTM?`FT2ZU3%M-al zi2RIH)3_Q$G6i>;0IQ5A(yQWWo7gNp^d%17MUq#LrCM(un?u7#+BL`4F^HIf{n(8` zQ6EGdi$Eq0M96Bka4}33{S+eeSs+xtt@lV2l82qY8Dbt3--Vlr2==l0&Ha|x?8G6% zsciOkHrp>I{u_fgcCS5rxx)tX)tC3hO9$zocMVTB+Pt@!1WA3uNd1-9ws-dW+g)nZ z$q%BGi>MWD>b?2c+eUJzTpt}l>iet285xIRmd(NXd5LaJ>Aoit5{niI@dhzK5DFiueEdN)F6&_n7YiKcd-5A+uwZ+#% znzy)0%-O4YO=eyXE}=w2IiI|9??dH%^2NOmKW^yqLRM~k z{Mp^DJ9ls0+fo*+yPU)_IPep}JHbKCQqFcua^)t#5h{@yLgAz;$hHWQR0=v=(9IDA zOq#cYPS95QY=Up8SD7!?%F2o{Xkt&w2D+%CZ0&QOj!(^JMGZh_8lo6b2CzxFa-vp` z3og3l3eqP`&=(w7hXQs^1s55a zoIIz4utwMc%)uW8@4SMoMNJS*C%qgR(g(=TNq&tN|t8Xlon6So+e$cah}t z$cE7WJy)!eUW{P}r0pi@j7cp+13E*P1e3Hy74+gK$dsML368da11IULB2dQPZ-sq+ zUP2|oC9s{NS7;9M7;k6^3^rzQe?VZeaXpOTE#%u9XNHSQwEi+>myuyZ&r!vmxz{7@)So1!MI-ZCfX$d5w@2vUxZ>A?Fp=q8k0~p zZv<0xB4hIe%ulhb&<=Sk>L(Y#*=rd4OQa0W%)#0d!kLUeIZILuic|E`U!%}9fIh}I zp$VKx&0ToMbz^L!)zBtpXGzEJ-^}a-8~@8#Pamx|~tGoJ_(X6+c6(aysyf zg0xxX5+Dy(`BsAPfeDh#R2v*xOci>8l!!!>^-wAsP3N^>c|zcy-R&osN0P!Bwga+L<8nGT%qKgn zvV)^PHaixLfABgE&D^bszw0scRAvk7MpyS9T+{VMX8hh-H?Ypq2b<6yhW3&9&GM*}E(814h9$QC*e1ngQb>l-|Ts`w?bwVYInlbA> z@UIxf{&ongDdpWp>!P)ClsGY?Za%y z``BGc?!*s$nX62B+7x?H1;ODz+i=jkaS*Az zj0G4_o@USo!`KAzh-(FSR27N+z)!>?z*HWJt9(;n+XrIGaF_ zZ3&9%_Z|HP-K~2E2}S|%|#!j?45xsvsP#zZi3?? z=j;2*^Zj1T`XQCezW<=#3MV}U-)C{#_r)SMgJ4bIekIaFedJ;TZQ@nR$oYsHl(i{4 zp_>Ic^QbgwK;0 zM>Bqbe7`jKXA+WKbN9&d30u}r!QD)5_+C^7@GcKww&x1^)iUWFDQG3 zveTp1r%c-L2c#e3az+$%@yfIBZ=`d7JhRl*nOshT9^#Fj@9{`lml{XL?-0ahL8_@P zHRAMEFA4Q83C^~Jh(&F}`>#PSzNG9c%Fgjl`uiAZ%6o0*hGtu1Q81d3Q`VuZOBw0R zc`Linzyc7DkR$~P+Q4j>7G6O;wY6-@2Fh7H^btzx68*O6r$Hz;fa-wYPSDl&9o(T# z>NY5w>+pda{yva778}W47lDq9`vN~=bO@zmCLL`7Vu^Bk-QUP&M`+X5=&G*H>Yo0T z$bM3+%p$>WB7$iB|LC^%HJQwAQ)52f-i6E2IHLJIb2uj$q}=Nn%)L$MBG-@sh5()} Qz_n~G18nK**$cb>19RdBNdN!< literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/__pycache__/cache.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/__pycache__/cache.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e4b2dcf281a49b6957633b7f764b29079c09aac6 GIT binary patch literal 6844 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 Te->eY{#&$aHvUO;WpVL;qS2Xy literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/__pycache__/configuration.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/__pycache__/configuration.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..386b8e83a11ac27dfb6f65628428849ea06c1c10 GIT binary patch literal 9843 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 NGV>Y;X7Xnm{|&Ri9J~Mk literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/__pycache__/download.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/__pycache__/download.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..634d0d2d764c5c014eb4a5c54b7411820b7de54c GIT binary patch literal 20911 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 Uc_@9{duaS#Ftm31i1+OO1)a}0p8x;= literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/__pycache__/exceptions.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/__pycache__/exceptions.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fbf3d6de0660ab871caa38d64ad133cf76d53354 GIT binary patch literal 11564 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/__pycache__/pep425tags.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/__pycache__/pep425tags.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..161900bad5eb2786d13fc22f27ea809e1d18ff59 GIT binary patch literal 7299 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 qNNyd435n3P;maR=LrQwiuqjxUkef~e|r!5Kq literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/__pycache__/pyproject.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/__pycache__/pyproject.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0e0e2832341d6f05b93d4a8648f08cbdaf7a7523 GIT binary patch literal 2723 zcmb7G&5ztP6pxckCX>m2blW0Y5VE*zM|5ZVq0((t3X~Rsv|37A6||y?GO=eSyGfkd zp52{k=F;tviXJ#s9JUuEt{nLvkT^%&IPov^#It8M`=RzgB!9$yety5-dw%wlUG@h@mJTBw{0JAx$xNrO1e8JBAooC+}7 zY+oqtSkm-2gDXZ~C(AjHw?avmw?e+$WeK5NET{eD=wcpR8(rJDuzk5pM&jekTl~_F z9HkfF>t)Limh(7Y(wim8(v_>7{^p?5Q-it$aV9CxLQp@WB0_*+Sm*>Qu+!ESZ_TDnDJqfuC7o}74Ys$D>G?u;?^WV7&g z(F-I#sALunWB{ED=$bua>=#Y7;|s)Z5r5pA>SSCX(avH_mn38s-pt3p8HZS2- z2upRmG3!o1O(J_yya`^VMo>A(gM0{3-mX9k!4c8SR7(MEkO4ce^Z}5lyVJcD5izGJ z%_QEYiySDfh`{H%j8{r34lt%FF9C-thXG-&i3je1fjm1zzoHSxUC@g~pA8bC9HJ2? zv=>H095Dj>g|dGhGw?3oj$uB;fHOJZ|J)G^4%sVkm$UR3XXlSd?<3uJawm*7X-19; z9Z`8;Yt*OFCJup-X?lWS3A+$r7)VyIkL;w_8RQyVXAlEanr+3LWs2BJu%&yW+CX-f zRv`1ZGy@7i)!N9{tCqwNf-?Pb^!4pngq;MY-VmTT7GTp>n8f6|a+gYrm@q1E#w6~C zTZ+W}NO&-snW&y(A9en>>iw7&pmqXos!Ij%lQGzG%n73fy}M)#vhOFCSK61_SIXLU zpVDM>`e3T9l?8BWL%37isUO5~gTHx_gWJL$9RoIHLv^6qRT2Q=!$TZIEY0CCZpX4e zdaKS+BJ}3v@dkV zC})5p7@0;{*-*b)tVCUam`_$tqBodCZ#k>;LjZxC!#jp*zRUVFX3CmASjR8ilM2Sc zMq2Fx;1Lg@GEVu(H*GYJPN}x$A{Uv+u^i;-~{t;+yHA^oDx&ugEGzhqQO7JtPdIzeq2@jEWumvfDaZUH+IrOd` y-hZ34=}ts*#k9~a&{S*Xhd`=V64y@)_eRRdAfY$adrtUJ`6d7|=S|;o>;C~g))e*t literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/__pycache__/resolve.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/__pycache__/resolve.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3c9654d54a86bf0a927d0f5347efd3cdafeed038 GIT binary patch literal 8490 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/build_env.py b/venv/lib/python3.7/site-packages/pip/_internal/build_env.py new file mode 100644 index 0000000..673409d --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/build_env.py @@ -0,0 +1,142 @@ +"""Build Environment used for isolation during sdist building +""" + +import logging +import os +import sys +from distutils.sysconfig import get_python_lib +from sysconfig import get_paths + +from pip._vendor.pkg_resources import Requirement, VersionConflict, WorkingSet + +from pip._internal.utils.misc import call_subprocess +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.ui import open_spinner + +logger = logging.getLogger(__name__) + + +class BuildEnvironment(object): + """Creates and manages an isolated environment to install build deps + """ + + def __init__(self): + self._temp_dir = TempDirectory(kind="build-env") + self._temp_dir.create() + + @property + def path(self): + return self._temp_dir.path + + def __enter__(self): + self.save_path = os.environ.get('PATH', None) + self.save_pythonpath = os.environ.get('PYTHONPATH', None) + self.save_nousersite = os.environ.get('PYTHONNOUSERSITE', None) + + install_scheme = 'nt' if (os.name == 'nt') else 'posix_prefix' + install_dirs = get_paths(install_scheme, vars={ + 'base': self.path, + 'platbase': self.path, + }) + + scripts = install_dirs['scripts'] + if self.save_path: + os.environ['PATH'] = scripts + os.pathsep + self.save_path + else: + os.environ['PATH'] = scripts + os.pathsep + os.defpath + + # Note: prefer distutils' sysconfig to get the + # library paths so PyPy is correctly supported. + purelib = get_python_lib(plat_specific=0, prefix=self.path) + platlib = get_python_lib(plat_specific=1, prefix=self.path) + if purelib == platlib: + lib_dirs = purelib + else: + lib_dirs = purelib + os.pathsep + platlib + if self.save_pythonpath: + os.environ['PYTHONPATH'] = lib_dirs + os.pathsep + \ + self.save_pythonpath + else: + os.environ['PYTHONPATH'] = lib_dirs + + os.environ['PYTHONNOUSERSITE'] = '1' + + return self.path + + def __exit__(self, exc_type, exc_val, exc_tb): + def restore_var(varname, old_value): + if old_value is None: + os.environ.pop(varname, None) + else: + os.environ[varname] = old_value + + restore_var('PATH', self.save_path) + restore_var('PYTHONPATH', self.save_pythonpath) + restore_var('PYTHONNOUSERSITE', self.save_nousersite) + + def cleanup(self): + self._temp_dir.cleanup() + + def missing_requirements(self, reqs): + """Return a list of the requirements from reqs that are not present + """ + missing = [] + with self: + ws = WorkingSet(os.environ["PYTHONPATH"].split(os.pathsep)) + for req in reqs: + try: + if ws.find(Requirement.parse(req)) is None: + missing.append(req) + except VersionConflict: + missing.append(req) + return missing + + def install_requirements(self, finder, requirements, message): + args = [ + sys.executable, '-m', 'pip', 'install', '--ignore-installed', + '--no-user', '--prefix', self.path, '--no-warn-script-location', + ] + if logger.getEffectiveLevel() <= logging.DEBUG: + args.append('-v') + for format_control in ('no_binary', 'only_binary'): + formats = getattr(finder.format_control, format_control) + args.extend(('--' + format_control.replace('_', '-'), + ','.join(sorted(formats or {':none:'})))) + if finder.index_urls: + args.extend(['-i', finder.index_urls[0]]) + for extra_index in finder.index_urls[1:]: + args.extend(['--extra-index-url', extra_index]) + else: + args.append('--no-index') + for link in finder.find_links: + args.extend(['--find-links', link]) + for _, host, _ in finder.secure_origins: + args.extend(['--trusted-host', host]) + if finder.allow_all_prereleases: + args.append('--pre') + if finder.process_dependency_links: + args.append('--process-dependency-links') + args.append('--') + args.extend(requirements) + with open_spinner(message) as spinner: + call_subprocess(args, show_stdout=False, spinner=spinner) + + +class NoOpBuildEnvironment(BuildEnvironment): + """A no-op drop-in replacement for BuildEnvironment + """ + + def __init__(self): + pass + + def __enter__(self): + pass + + def __exit__(self, exc_type, exc_val, exc_tb): + pass + + def cleanup(self): + pass + + def install_requirements(self, finder, requirements, message): + raise NotImplementedError() diff --git a/venv/lib/python3.7/site-packages/pip/_internal/cache.py b/venv/lib/python3.7/site-packages/pip/_internal/cache.py new file mode 100644 index 0000000..33bec97 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/cache.py @@ -0,0 +1,202 @@ +"""Cache Management +""" + +import errno +import hashlib +import logging +import os + +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal.download import path_to_url +from pip._internal.models.link import Link +from pip._internal.utils.compat import expanduser +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.wheel import InvalidWheelFilename, Wheel + +logger = logging.getLogger(__name__) + + +class Cache(object): + """An abstract class - provides cache directories for data from links + + + :param cache_dir: The root of the cache. + :param format_control: An object of FormatControl class to limit + binaries being read from the cache. + :param allowed_formats: which formats of files the cache should store. + ('binary' and 'source' are the only allowed values) + """ + + def __init__(self, cache_dir, format_control, allowed_formats): + super(Cache, self).__init__() + self.cache_dir = expanduser(cache_dir) if cache_dir else 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): + """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 = [link.url_without_fragment] + if link.hash_name is not None and link.hash is not None: + key_parts.append("=".join([link.hash_name, link.hash])) + key_url = "#".join(key_parts) + + # 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 = hashlib.sha224(key_url.encode()).hexdigest() + + # 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, package_name): + can_not_cache = ( + not self.cache_dir or + not 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 + ) + 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 + + def get_path_for_link(self, link): + """Return a directory to store cached items in for link. + """ + raise NotImplementedError() + + def get(self, link, package_name): + """Returns a link to a cached item if it exists, otherwise returns the + passed link. + """ + raise NotImplementedError() + + def _link_for_candidate(self, link, candidate): + root = self.get_path_for_link(link) + path = os.path.join(root, candidate) + + return Link(path_to_url(path)) + + def cleanup(self): + pass + + +class SimpleWheelCache(Cache): + """A cache of wheels for future installs. + """ + + def __init__(self, cache_dir, format_control): + super(SimpleWheelCache, self).__init__( + cache_dir, format_control, {"binary"} + ) + + def get_path_for_link(self, link): + """Return a directory to store cached wheels for link + + Because there are M wheels for any one sdist, we provide a directory + to cache them in, and then consult that directory when looking up + cache hits. + + We only insert things into the cache if they have plausible version + numbers, so that we don't contaminate the cache with things that were + not unique. E.g. ./package might have dozens of installs done for it + and build a version of 0.0...and if we built and cached a wheel, we'd + end up using the same wheel even if the source has been edited. + + :param link: The link of the sdist for which this will cache wheels. + """ + parts = self._get_cache_path_parts(link) + + # Store wheels within the root cache_dir + return os.path.join(self.cache_dir, "wheels", *parts) + + def get(self, link, package_name): + candidates = [] + + for wheel_name in self._get_candidates(link, package_name): + try: + wheel = Wheel(wheel_name) + except InvalidWheelFilename: + continue + if not wheel.supported(): + # Built for a different python/arch/etc + continue + candidates.append((wheel.support_index_min(), wheel_name)) + + if not candidates: + return link + + return self._link_for_candidate(link, min(candidates)[1]) + + +class EphemWheelCache(SimpleWheelCache): + """A SimpleWheelCache that creates it's own temporary cache directory + """ + + def __init__(self, format_control): + self._temp_dir = TempDirectory(kind="ephem-wheel-cache") + self._temp_dir.create() + + super(EphemWheelCache, self).__init__( + self._temp_dir.path, format_control + ) + + def cleanup(self): + self._temp_dir.cleanup() + + +class WheelCache(Cache): + """Wraps EphemWheelCache and SimpleWheelCache into a single Cache + + This Cache allows for gracefully degradation, using the ephem wheel cache + when a certain link is not found in the simple wheel cache first. + """ + + def __init__(self, cache_dir, format_control): + super(WheelCache, self).__init__( + cache_dir, format_control, {'binary'} + ) + self._wheel_cache = SimpleWheelCache(cache_dir, format_control) + self._ephem_cache = EphemWheelCache(format_control) + + def get_path_for_link(self, link): + return self._wheel_cache.get_path_for_link(link) + + def get_ephem_path_for_link(self, link): + return self._ephem_cache.get_path_for_link(link) + + def get(self, link, package_name): + retval = self._wheel_cache.get(link, package_name) + if retval is link: + retval = self._ephem_cache.get(link, package_name) + return retval + + def cleanup(self): + self._wheel_cache.cleanup() + self._ephem_cache.cleanup() diff --git a/venv/lib/python3.7/site-packages/pip/_internal/cli/__init__.py b/venv/lib/python3.7/site-packages/pip/_internal/cli/__init__.py new file mode 100644 index 0000000..e589bb9 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/cli/__init__.py @@ -0,0 +1,4 @@ +"""Subpackage containing all of pip's command line interface related code +""" + +# This file intentionally does not import submodules diff --git a/venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..20bbc24c424eb2c601f4388921abb8cdbf5e178f GIT binary patch literal 281 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..863ee7bbad8648ef4ba4b2f2341849ff41bc54da GIT binary patch literal 6319 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..08bf509a3a844bb304379ce9a3c75f6eb4717f0c GIT binary patch literal 15040 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 DHXJve literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8be2d96947264e57c571c609689222e9996b0622 GIT binary patch literal 2241 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3caeba083ebdd46d3d014845bc0da43b133a2274 GIT binary patch literal 410 zcmXw#TS~(~6o!*Dy--@}gP`CB>_eSuQ7MSnOT=KENG=tEFeII{jZQAiBvrcxm*586 zQeJ(^7JPEj+J89Tx$tui%&^(43tXQ^?(-MVKSi^X#ETmq?3e=!SR_Iq+M>v7Tf&lE z!X;bAvR%eyyMilr6;}NSrKF^D#d8vS0;D7_RYgrwk zd77luLx>iZtZG=JkzyEGSZUcAC~%6PW};iog5&J)QCFs_ zW*KN`sgp4ptNOox4{GRPV23dUL#H7rhlddr#IumunFM6U2Vp@k5q4gmlg?-Q{cQE{fqMkRK)<4IKhz#0T7z eqzug>?6H&hBdc8n5l)GBUHl7ca5N-Y+`T_6XK(HR literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/cli/autocompletion.py b/venv/lib/python3.7/site-packages/pip/_internal/cli/autocompletion.py new file mode 100644 index 0000000..0a04199 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/cli/autocompletion.py @@ -0,0 +1,152 @@ +"""Logic that powers autocompletion installed by ``pip completion``. +""" + +import optparse +import os +import sys + +from pip._internal.cli.main_parser import create_main_parser +from pip._internal.commands import commands_dict, get_summaries +from pip._internal.utils.misc import get_installed_distributions + + +def autocomplete(): + """Entry Point for completion of main and subcommand options. + """ + # Don't complete if user hasn't sourced bash_completion file. + if 'PIP_AUTO_COMPLETE' not in os.environ: + return + cwords = os.environ['COMP_WORDS'].split()[1:] + cword = int(os.environ['COMP_CWORD']) + try: + current = cwords[cword - 1] + 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() + # subcommand options + if subcommand_name: + # special case: 'help' subcommand has no options + if subcommand_name == 'help': + sys.exit(1) + # special case: list locally installed dists for show and uninstall + should_list_installed = ( + subcommand_name in ['show', 'uninstall'] and + not current.startswith('-') + ) + if should_list_installed: + installed = [] + lc = current.lower() + for dist in get_installed_distributions(local_only=True): + if dist.key.startswith(lc) and dist.key not in cwords[1:]: + installed.append(dist.key) + # if there are no dists installed, fall back to option completion + if installed: + for dist in installed: + print(dist) + sys.exit(1) + + subcommand = commands_dict[subcommand_name]() + + for opt in subcommand.parser.option_list_all: + if opt.help != optparse.SUPPRESS_HELP: + for opt_str in opt._long_opts + opt._short_opts: + options.append((opt_str, opt.nargs)) + + # filter out previously specified options from available options + prev_opts = [x.split('=')[0] for x in cwords[1:cword - 1]] + options = [(x, v) for (x, v) in options if x not in prev_opts] + # filter options by current input + options = [(k, v) for k, v in options if k.startswith(current)] + # get completion type given cwords and available subcommand options + completion_type = get_path_completion_type( + cwords, cword, subcommand.parser.option_list_all, + ) + # get completion files and directories if ``completion_type`` is + # ````, ``

`` or ```` + if completion_type: + options = auto_complete_paths(current, completion_type) + options = ((opt, 0) for opt in options) + for option in options: + opt_label = option[0] + # append '=' to options which require args + if option[1] and option[0][:2] == "--": + opt_label += '=' + print(opt_label) + else: + # show main parser options only when necessary + + 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) + if current.startswith('-'): + for opt in 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) + if completion_type: + subcommands = 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): + """Get the type of path completion (``file``, ``dir``, ``path`` or None) + + :param cwords: same as the environmental variable ``COMP_WORDS`` + :param cword: same as the environmental variable ``COMP_CWORD`` + :param opts: The available options to check + :return: path completion type (``file``, ``dir``, ``path`` or None) + """ + if cword < 2 or not cwords[cword - 2].startswith('-'): + return + for opt in opts: + if opt.help == optparse.SUPPRESS_HELP: + continue + for o in str(opt).split('/'): + if cwords[cword - 2].split('=')[0] == o: + if not opt.metavar or any( + x in ('path', 'file', 'dir') + for x in opt.metavar.split('/')): + return opt.metavar + + +def auto_complete_paths(current, completion_type): + """If ``completion_type`` is ``file`` or ``path``, list all regular files + and directories starting with ``current``; otherwise only list directories + starting with ``current``. + + :param current: The word to be completed + :param completion_type: path completion type(`file`, `path` or `dir`)i + :return: A generator of regular files and/or directories + """ + directory, filename = os.path.split(current) + current_path = os.path.abspath(directory) + # Don't complete paths if they can't be accessed + if not os.access(current_path, os.R_OK): + return + filename = os.path.normcase(filename) + # list all files that start with ``filename`` + file_list = (x for x in os.listdir(current_path) + if os.path.normcase(x).startswith(filename)) + for f in file_list: + opt = os.path.join(current_path, f) + comp_file = os.path.normcase(os.path.join(directory, f)) + # complete regular files when there is not ```` after option + # complete directories when there is ````, ```` or + # ````after option + if completion_type != 'dir' and os.path.isfile(opt): + yield comp_file + elif os.path.isdir(opt): + yield os.path.join(comp_file, '') diff --git a/venv/lib/python3.7/site-packages/pip/_internal/cli/base_command.py b/venv/lib/python3.7/site-packages/pip/_internal/cli/base_command.py new file mode 100644 index 0000000..dac4b05 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/cli/base_command.py @@ -0,0 +1,278 @@ +"""Base Command class, and related routines""" +from __future__ import absolute_import + +import logging +import logging.config +import optparse +import os +import sys + +from pip._internal.cli import cmdoptions +from pip._internal.cli.parser import ( + ConfigOptionParser, UpdatingDefaultsHelpFormatter, +) +from pip._internal.cli.status_codes import ( + ERROR, PREVIOUS_BUILD_DIR_ERROR, SUCCESS, UNKNOWN_ERROR, + VIRTUALENV_NOT_FOUND, +) +from pip._internal.download import PipSession +from pip._internal.exceptions import ( + BadCommand, CommandError, InstallationError, PreviousBuildDirError, + UninstallationError, +) +from pip._internal.index import PackageFinder +from pip._internal.locations import running_under_virtualenv +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.logging import 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.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Optional # noqa: F401 + +__all__ = ['Command'] + +logger = logging.getLogger(__name__) + + +class Command(object): + name = None # type: Optional[str] + usage = None # type: Optional[str] + hidden = False # type: bool + ignore_require_venv = False # type: bool + + def __init__(self, isolated=False): + parser_kw = { + 'usage': self.usage, + 'prog': '%s %s' % (get_prog(), self.name), + 'formatter': UpdatingDefaultsHelpFormatter(), + 'add_help_option': False, + 'name': self.name, + 'description': self.__doc__, + 'isolated': isolated, + } + + self.parser = ConfigOptionParser(**parser_kw) + + # Commands should add options to this option group + optgroup_name = '%s Options' % self.name.capitalize() + self.cmd_opts = optparse.OptionGroup(self.parser, optgroup_name) + + # Add the general options + gen_opts = cmdoptions.make_option_group( + cmdoptions.general_group, + self.parser, + ) + self.parser.add_option_group(gen_opts) + + def _build_session(self, options, retries=None, timeout=None): + 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, + ) + + # 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): + # factored out for testability + return self.parser.parse_args(args) + + def main(self, args): + options, args = self.parse_args(args) + + # Set verbosity so that it can be used elsewhere. + self.verbosity = options.verbose - options.quiet + + setup_logging( + verbosity=self.verbosity, + no_color=options.no_color, + user_log_file=options.log, + ) + + # TODO: Try to get these passing down from the command? + # without resorting to os.environ to hold these. + # This also affects isolated builds and it should. + + if options.no_input: + os.environ['PIP_NO_INPUT'] = '1' + + if options.exists_action: + os.environ['PIP_EXISTS_ACTION'] = ' '.join(options.exists_action) + + if options.require_venv and not self.ignore_require_venv: + # If a venv is required check if it can really be found + if not running_under_virtualenv(): + logger.critical( + 'Could not find an activated virtualenv (required).' + ) + sys.exit(VIRTUALENV_NOT_FOUND) + + 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 + 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: + logger.critical(str(exc)) + logger.debug('Exception information:', exc_info=True) + + return ERROR + except CommandError as exc: + logger.critical('ERROR: %s', exc) + logger.debug('Exception information:', exc_info=True) + + return ERROR + except KeyboardInterrupt: + logger.critical('Operation cancelled by user') + logger.debug('Exception information:', exc_info=True) + + return ERROR + except BaseException: + logger.critical('Exception:', exc_info=True) + + 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, args, options, finder, + session, name, wheel_cache): + """ + 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, + 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, + 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): + 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, session, + platform=None, python_versions=None, + abi=None, implementation=None): + """ + Create a package finder appropriate to this requirement command. + """ + index_urls = [options.index_url] + options.extra_index_urls + if options.no_index: + logger.debug('Ignoring indexes: %s', ','.join(index_urls)) + index_urls = [] + + return PackageFinder( + find_links=options.find_links, + format_control=options.format_control, + index_urls=index_urls, + trusted_hosts=options.trusted_hosts, + allow_all_prereleases=options.pre, + process_dependency_links=options.process_dependency_links, + session=session, + platform=platform, + versions=python_versions, + abi=abi, + implementation=implementation, + prefer_binary=options.prefer_binary, + ) diff --git a/venv/lib/python3.7/site-packages/pip/_internal/cli/cmdoptions.py b/venv/lib/python3.7/site-packages/pip/_internal/cli/cmdoptions.py new file mode 100644 index 0000000..3033cd4 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/cli/cmdoptions.py @@ -0,0 +1,714 @@ +""" +shared options and groups + +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. + +""" +from __future__ import absolute_import + +import warnings +from functools import partial +from optparse import SUPPRESS_HELP, Option, OptionGroup + +from pip._internal.exceptions import CommandError +from pip._internal.locations import USER_CACHE_DIR, src_prefix +from pip._internal.models.format_control import FormatControl +from pip._internal.models.index import PyPI +from pip._internal.utils.hashes import STRONG_HASHES +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 # noqa: F401 + + +def make_option_group(group, parser): + """ + Return an OptionGroup object + group -- assumed to be dict with 'name' and 'options' keys + parser -- an optparse Parser + """ + option_group = OptionGroup(parser, group['name']) + for option in group['options']: + option_group.add_option(option()) + return option_group + + +def check_install_build_global(options, check_options=None): + """Disable wheels if per-setup.py call options are set. + + :param options: The OptionParser options to update. + :param check_options: The options to check, if not supplied defaults to + options. + """ + if check_options is None: + check_options = options + + def getname(n): + 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, + ) + + +def check_dist_restriction(options, check_target=False): + """Function for determining if custom platform options are allowed. + + :param options: The OptionParser options. + :param check_target: Whether or not to check if --target is being used. + """ + dist_restriction_set = any([ + options.python_version, + options.platform, + options.abi, + options.implementation, + ]) + + binary_only = FormatControl(set(), {':all:'}) + sdist_dependencies_allowed = ( + options.format_control != binary_only and + not options.ignore_dependencies + ) + + # Installations or downloads using dist restrictions must not combine + # source distributions and dist-specific wheels, as they are not + # gauranteed to be locally compatible. + if dist_restriction_set and sdist_dependencies_allowed: + raise CommandError( + "When restricting platform and interpreter constraints using " + "--python-version, --platform, --abi, or --implementation, " + "either --no-deps must be set, or --only-binary=:all: must be " + "set and --no-binary must not be set (or must be set to " + ":none:)." + ) + + if check_target: + if dist_restriction_set and not options.target_dir: + raise CommandError( + "Can not use any platform or abi specific options unless " + "installing via '--target'" + ) + + +########### +# options # +########### + +help_ = partial( + Option, + '-h', '--help', + dest='help', + action='help', + help='Show help.', +) # type: Any + +isolated_mode = partial( + Option, + "--isolated", + dest="isolated_mode", + action="store_true", + default=False, + help=( + "Run pip in an isolated mode, ignoring environment variables and user " + "configuration." + ), +) + +require_virtualenv = partial( + Option, + # Run only if inside a virtualenv, bail if not. + '--require-virtualenv', '--require-venv', + dest='require_venv', + action='store_true', + default=False, + help=SUPPRESS_HELP +) # type: Any + +verbose = partial( + Option, + '-v', '--verbose', + dest='verbose', + action='count', + default=0, + help='Give more output. Option is additive, and can be used up to 3 times.' +) + +no_color = partial( + Option, + '--no-color', + dest='no_color', + action='store_true', + default=False, + help="Suppress colored output", +) + +version = partial( + Option, + '-V', '--version', + dest='version', + action='store_true', + help='Show version and exit.', +) # type: Any + +quiet = partial( + Option, + '-q', '--quiet', + dest='quiet', + action='count', + default=0, + help=( + 'Give less output. Option is additive, and can be used up to 3' + ' times (corresponding to WARNING, ERROR, and CRITICAL logging' + ' levels).' + ), +) # type: Any + +progress_bar = partial( + Option, + '--progress-bar', + dest='progress_bar', + type='choice', + choices=list(BAR_TYPES.keys()), + default='on', + help=( + 'Specify type of progress to be displayed [' + + '|'.join(BAR_TYPES.keys()) + '] (default: %default)' + ), +) # type: Any + +log = partial( + Option, + "--log", "--log-file", "--local-log", + dest="log", + metavar="path", + help="Path to a verbose appending log." +) # type: Any + +no_input = partial( + Option, + # Don't ask for input + '--no-input', + dest='no_input', + action='store_true', + default=False, + help=SUPPRESS_HELP +) # type: Any + +proxy = partial( + Option, + '--proxy', + dest='proxy', + type='str', + default='', + help="Specify a proxy in the form [user:passwd@]proxy.server:port." +) # type: Any + +retries = partial( + Option, + '--retries', + dest='retries', + type='int', + default=5, + help="Maximum number of retries each connection should attempt " + "(default %default times).", +) # type: Any + +timeout = partial( + Option, + '--timeout', '--default-timeout', + metavar='sec', + dest='timeout', + type='float', + default=15, + help='Set the socket timeout (default %default seconds).', +) # type: Any + +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: Any + + +def exists_action(): + return Option( + # Option when path already exist + '--exists-action', + dest='exists_action', + type='choice', + choices=['s', 'i', 'w', 'b', 'a'], + default=[], + action='append', + metavar='action', + help="Default action when a path already exists: " + "(s)witch, (i)gnore, (w)ipe, (b)ackup, (a)bort).", + ) + + +cert = partial( + Option, + '--cert', + dest='cert', + type='str', + metavar='path', + help="Path to alternate CA bundle.", +) # type: Any + +client_cert = partial( + Option, + '--client-cert', + dest='client_cert', + type='str', + default=None, + metavar='path', + help="Path to SSL client certificate, a single file containing the " + "private key and the certificate in PEM format.", +) # type: Any + +index_url = partial( + Option, + '-i', '--index-url', '--pypi-url', + dest='index_url', + metavar='URL', + default=PyPI.simple_url, + help="Base URL of Python Package Index (default %default). " + "This should point to a repository compliant with PEP 503 " + "(the simple repository API) or a local directory laid out " + "in the same format.", +) # type: Any + + +def extra_index_url(): + return Option( + '--extra-index-url', + dest='extra_index_urls', + metavar='URL', + action='append', + default=[], + help="Extra URLs of package indexes to use in addition to " + "--index-url. Should follow the same rules as " + "--index-url.", + ) + + +no_index = partial( + Option, + '--no-index', + dest='no_index', + action='store_true', + default=False, + help='Ignore package index (only looking at --find-links URLs instead).', +) # type: Any + + +def find_links(): + return Option( + '-f', '--find-links', + dest='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.", + ) + + +def trusted_host(): + return Option( + "--trusted-host", + dest="trusted_hosts", + action="append", + metavar="HOSTNAME", + default=[], + help="Mark this host as trusted, even though it does not have valid " + "or any HTTPS.", + ) + + +# Remove after 1.5 +process_dependency_links = partial( + Option, + "--process-dependency-links", + dest="process_dependency_links", + action="store_true", + default=False, + help="Enable the processing of dependency links.", +) # type: Any + + +def constraints(): + return Option( + '-c', '--constraint', + dest='constraints', + action='append', + default=[], + metavar='file', + help='Constrain versions using the given constraints file. ' + 'This option can be used multiple times.' + ) + + +def requirements(): + return Option( + '-r', '--requirement', + dest='requirements', + action='append', + default=[], + metavar='file', + help='Install from the given requirements file. ' + 'This option can be used multiple times.' + ) + + +def editable(): + return Option( + '-e', '--editable', + dest='editables', + action='append', + default=[], + metavar='path/url', + help=('Install a project in editable mode (i.e. setuptools ' + '"develop mode") from a local project path or a VCS url.'), + ) + + +src = partial( + Option, + '--src', '--source', '--source-dir', '--source-directory', + dest='src_dir', + metavar='dir', + default=src_prefix, + help='Directory to check out editable projects into. ' + 'The default in a virtualenv is "/src". ' + 'The default for global installs is "/src".' +) # type: Any + + +def _get_format_control(values, option): + """Get a format_control object.""" + return getattr(values, option.dest) + + +def _handle_no_binary(option, opt_str, value, parser): + existing = _get_format_control(parser.values, option) + FormatControl.handle_mutual_excludes( + value, existing.no_binary, existing.only_binary, + ) + + +def _handle_only_binary(option, opt_str, value, parser): + existing = _get_format_control(parser.values, option) + FormatControl.handle_mutual_excludes( + value, existing.only_binary, existing.no_binary, + ) + + +def no_binary(): + format_control = FormatControl(set(), set()) + return Option( + "--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.", + ) + + +def only_binary(): + format_control = FormatControl(set(), set()) + return Option( + "--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.", + ) + + +platform = partial( + Option, + '--platform', + dest='platform', + metavar='platform', + default=None, + help=("Only use wheels compatible with . " + "Defaults to the platform of the running system."), +) + + +python_version = partial( + Option, + '--python-version', + dest='python_version', + metavar='python_version', + default=None, + help=("Only use wheels compatible with Python " + "interpreter version . If not specified, then the " + "current system interpreter minor version is used. A major " + "version (e.g. '2') can be specified to match all " + "minor revs of that major version. A minor version " + "(e.g. '34') can also be specified."), +) + + +implementation = partial( + Option, + '--implementation', + dest='implementation', + metavar='implementation', + default=None, + help=("Only use wheels compatible with Python " + "implementation , e.g. 'pp', 'jy', 'cp', " + " or 'ip'. If not specified, then the current " + "interpreter implementation is used. Use 'py' to force " + "implementation-agnostic wheels."), +) + + +abi = partial( + Option, + '--abi', + dest='abi', + metavar='abi', + default=None, + help=("Only use wheels compatible with Python " + "abi , e.g. 'pypy_41'. If not specified, then the " + "current interpreter abi tag is used. Generally " + "you will need to specify --implementation, " + "--platform, and --python-version when using " + "this option."), +) + + +def prefer_binary(): + return Option( + "--prefer-binary", + dest="prefer_binary", + action="store_true", + default=False, + help="Prefer older binary packages over newer source packages." + ) + + +cache_dir = partial( + Option, + "--cache-dir", + dest="cache_dir", + default=USER_CACHE_DIR, + metavar="dir", + help="Store the cache data in ." +) + +no_cache = partial( + Option, + "--no-cache-dir", + dest="cache_dir", + action="store_false", + help="Disable the cache.", +) + +no_deps = partial( + Option, + '--no-deps', '--no-dependencies', + dest='ignore_dependencies', + action='store_true', + default=False, + help="Don't install package dependencies.", +) # type: Any + +build_dir = partial( + Option, + '-b', '--build', '--build-dir', '--build-directory', + dest='build_dir', + metavar='dir', + help='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. ' + 'When passed, build directories are not cleaned in case of failures.' +) # type: Any + +ignore_requires_python = partial( + Option, + '--ignore-requires-python', + dest='ignore_requires_python', + action='store_true', + help='Ignore the Requires-Python information.' +) # type: Any + +no_build_isolation = partial( + Option, + '--no-build-isolation', + dest='build_isolation', + action='store_false', + default=True, + help='Disable isolation when building a modern source distribution. ' + 'Build dependencies specified by PEP 518 must be already installed ' + 'if this option is used.' +) # type: Any + +install_options = partial( + Option, + '--install-option', + dest='install_options', + action='append', + metavar='options', + help="Extra arguments to be supplied to the setup.py install " + "command (use like --install-option=\"--install-scripts=/usr/local/" + "bin\"). Use multiple --install-option options to pass multiple " + "options to setup.py install. If you are using an option with a " + "directory path, be sure to use absolute path.", +) # type: Any + +global_options = partial( + Option, + '--global-option', + dest='global_options', + action='append', + metavar='options', + help="Extra global options to be supplied to the setup.py " + "call before the install command.", +) # type: Any + +no_clean = partial( + Option, + '--no-clean', + action='store_true', + default=False, + help="Don't clean up build directories." +) # type: Any + +pre = partial( + Option, + '--pre', + action='store_true', + default=False, + help="Include pre-release and development versions. By default, " + "pip only finds stable versions.", +) # type: Any + +disable_pip_version_check = partial( + Option, + "--disable-pip-version-check", + dest="disable_pip_version_check", + action="store_true", + default=False, + help="Don't periodically check PyPI to determine whether a new version " + "of pip is available for download. Implied with --no-index.", +) # type: Any + + +# Deprecated, Remove later +always_unzip = partial( + Option, + '-Z', '--always-unzip', + dest='always_unzip', + action='store_true', + help=SUPPRESS_HELP, +) # type: Any + + +def _merge_hash(option, opt_str, value, parser): + """Given a value spelled "algo:digest", append the digest to a list + pointed to in a dict by the algo name.""" + if not parser.values.hashes: + parser.values.hashes = {} + 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) + if algo not in STRONG_HASHES: + parser.error('Allowed hash algorithms for %s are %s.' % + (opt_str, ', '.join(STRONG_HASHES))) + parser.values.hashes.setdefault(algo, []).append(digest) + + +hash = partial( + Option, + '--hash', + # Hash values eventually end up in InstallRequirement.hashes due to + # __dict__ copying in process_line(). + dest='hashes', + action='callback', + callback=_merge_hash, + type='string', + help="Verify that the package's archive matches this " + 'hash before installing. Example: --hash=sha256:abcdef...', +) # type: Any + + +require_hashes = partial( + Option, + '--require-hashes', + dest='require_hashes', + action='store_true', + default=False, + help='Require a hash to check each requirement against, for ' + 'repeatable installs. This option is implied when any package in a ' + 'requirements file has a --hash option.', +) # type: Any + + +########## +# groups # +########## + +general_group = { + 'name': 'General Options', + 'options': [ + help_, + isolated_mode, + require_virtualenv, + verbose, + version, + quiet, + log, + no_input, + proxy, + retries, + timeout, + skip_requirements_regex, + exists_action, + trusted_host, + cert, + client_cert, + cache_dir, + no_cache, + disable_pip_version_check, + no_color, + ] +} + +index_group = { + 'name': 'Package Index Options', + 'options': [ + index_url, + extra_index_url, + no_index, + find_links, + process_dependency_links, + ] +} diff --git a/venv/lib/python3.7/site-packages/pip/_internal/cli/main_parser.py b/venv/lib/python3.7/site-packages/pip/_internal/cli/main_parser.py new file mode 100644 index 0000000..1774a6b --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/cli/main_parser.py @@ -0,0 +1,96 @@ +"""A single place for constructing and exposing the main parser +""" + +import os +import sys + +from pip import __version__ +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, +) +from pip._internal.exceptions import CommandError +from pip._internal.utils.misc import get_prog + +__all__ = ["create_main_parser", "parse_command"] + + +def create_main_parser(): + """Creates and returns the main parser for pip's CLI + """ + + parser_kw = { + 'usage': '\n%prog [options]', + 'add_help_option': False, + 'formatter': UpdatingDefaultsHelpFormatter(), + 'name': 'global', + 'prog': get_prog(), + } + + parser = ConfigOptionParser(**parser_kw) + parser.disable_interspersed_args() + + pip_pkg_dir = os.path.abspath(os.path.join( + os.path.dirname(__file__), "..", "..", + )) + parser.version = 'pip %s from %s (python %s)' % ( + __version__, pip_pkg_dir, sys.version[:3], + ) + + # add the general options + gen_opts = cmdoptions.make_option_group(cmdoptions.general_group, parser) + parser.add_option_group(gen_opts) + + parser.main = True # so the help formatter knows + + # create command listing for description + command_summaries = get_summaries() + description = [''] + ['%-27s %s' % (i, j) for i, j in command_summaries] + parser.description = '\n'.join(description) + + return parser + + +def parse_command(args): + parser = create_main_parser() + + # Note: parser calls disable_interspersed_args(), so the result of this + # call is to split the initial args into the general options before the + # subcommand and everything else. + # For example: + # args: ['--timeout=5', 'install', '--user', 'INITools'] + # general_options: ['--timeout==5'] + # args_else: ['install', '--user', 'INITools'] + general_options, args_else = parser.parse_args(args) + + # --version + if general_options.version: + sys.stdout.write(parser.version) + sys.stdout.write(os.linesep) + sys.exit() + + # pip || pip help -> print_help() + if not args_else or (args_else[0] == 'help' and len(args_else) == 1): + parser.print_help() + sys.exit() + + # the subcommand name + cmd_name = args_else[0] + + if cmd_name not in commands_dict: + guess = get_similar_commands(cmd_name) + + msg = ['unknown command "%s"' % cmd_name] + if guess: + msg.append('maybe you meant "%s"' % guess) + + raise CommandError(' - '.join(msg)) + + # all the args without the subcommand + cmd_args = args[:] + cmd_args.remove(cmd_name) + + return cmd_name, cmd_args diff --git a/venv/lib/python3.7/site-packages/pip/_internal/cli/parser.py b/venv/lib/python3.7/site-packages/pip/_internal/cli/parser.py new file mode 100644 index 0000000..e1eaac4 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/cli/parser.py @@ -0,0 +1,261 @@ +"""Base option parser setup""" +from __future__ import absolute_import + +import logging +import optparse +import sys +import textwrap +from distutils.util import strtobool + +from pip._vendor.six import string_types + +from pip._internal.cli.status_codes import UNKNOWN_ERROR +from pip._internal.configuration import Configuration, ConfigurationError +from pip._internal.utils.compat import get_terminal_size + +logger = logging.getLogger(__name__) + + +class PrettyHelpFormatter(optparse.IndentedHelpFormatter): + """A prettier/less verbose help formatter for optparse.""" + + def __init__(self, *args, **kwargs): + # help position must be aligned with __init__.parseopts.description + kwargs['max_help_position'] = 30 + kwargs['indent_increment'] = 1 + kwargs['width'] = get_terminal_size()[0] - 2 + optparse.IndentedHelpFormatter.__init__(self, *args, **kwargs) + + def format_option_strings(self, option): + return self._format_option_strings(option, ' <%s>', ', ') + + def _format_option_strings(self, option, mvarfmt=' <%s>', 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 optsep: separator + """ + opts = [] + + if option._short_opts: + opts.append(option._short_opts[0]) + if option._long_opts: + opts.append(option._long_opts[0]) + if len(opts) > 1: + opts.insert(1, optsep) + + if option.takes_value(): + metavar = option.metavar or option.dest.lower() + opts.append(mvarfmt % metavar.lower()) + + return ''.join(opts) + + def format_heading(self, heading): + if heading == 'Options': + return '' + return heading + ':\n' + + def format_usage(self, usage): + """ + 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), " ") + return msg + + def format_description(self, description): + # leave full control over description to us + if description: + if hasattr(self.parser, 'main'): + label = 'Commands' + else: + label = 'Description' + # some doc strings have initial newlines, some don't + description = description.lstrip('\n') + # some doc strings have final newlines and spaces, some don't + description = description.rstrip() + # dedent, then reindent + description = self.indent_lines(textwrap.dedent(description), " ") + description = '%s:\n%s\n' % (label, description) + return description + else: + return '' + + def format_epilog(self, epilog): + # leave full control over epilog to us + if epilog: + return epilog + else: + return '' + + def indent_lines(self, text, indent): + new_lines = [indent + line for line in text.split('\n')] + return "\n".join(new_lines) + + +class UpdatingDefaultsHelpFormatter(PrettyHelpFormatter): + """Custom help formatter for use in ConfigOptionParser. + + This is updates the defaults before expanding them, allowing + them to show up correctly in the help listing. + """ + + def expand_default(self, option): + if self.parser is not None: + self.parser._update_defaults(self.parser.defaults) + return optparse.IndentedHelpFormatter.expand_default(self, option) + + +class CustomOptionParser(optparse.OptionParser): + + def insert_option_group(self, idx, *args, **kwargs): + """Insert an OptionGroup at a given position.""" + group = self.add_option_group(*args, **kwargs) + + self.option_groups.pop() + self.option_groups.insert(idx, group) + + return group + + @property + def option_list_all(self): + """Get a list of all options, including those in option groups.""" + res = self.option_list[:] + for i in self.option_groups: + res.extend(i.option_list) + + return res + + +class ConfigOptionParser(CustomOptionParser): + """Custom option parser which updates its defaults by checking the + configuration files and environmental variables""" + + def __init__(self, *args, **kwargs): + self.name = kwargs.pop('name') + + isolated = kwargs.pop("isolated", False) + self.config = Configuration(isolated) + + assert self.name + optparse.OptionParser.__init__(self, *args, **kwargs) + + def check_default(self, option, key, val): + try: + return option.check_value(key, val) + except optparse.OptionValueError as exc: + print("An error occurred during configuration: %s" % exc) + sys.exit(3) + + def _get_ordered_configuration_items(self): + # Configuration gives keys in an unordered manner. Order them. + override_order = ["global", self.name, ":env:"] + + # Pool the options into different groups + section_items = {name: [] for name in override_order} + for section_key, val in self.config.items(): + # ignore empty values + if not val: + logger.debug( + "Ignoring configuration key '%s' as it's value is empty.", + section_key + ) + continue + + section, key = section_key.split(".", 1) + if section in override_order: + section_items[section].append((key, val)) + + # Yield each group in their override order + for section in override_order: + for key, val in section_items[section]: + yield key, val + + def _update_defaults(self, defaults): + """Updates the given defaults with values from the config files and + the environ. Does a little special handling for certain types of + options (lists).""" + + # Accumulate complex default state. + self.values = optparse.Values(self.defaults) + late_eval = set() + # Then set the options with those values + for key, val in self._get_ordered_configuration_items(): + # '--' because configuration supports only long names + option = self.get_option('--' + key) + + # Ignore options not present in this parser. E.g. non-globals put + # in [global] by users that want them to apply to all applicable + # commands. + if option is None: + continue + + if option.action in ('store_true', 'store_false', 'count'): + try: + val = strtobool(val) + except ValueError: + error_msg = invalid_config_error_message( + option.action, key, val + ) + self.error(error_msg) + + elif option.action == 'append': + val = val.split() + val = [self.check_default(option, key, v) for v in val] + elif option.action == 'callback': + late_eval.add(option.dest) + opt_str = option.get_opt_string() + val = option.convert_value(opt_str, val) + # From take_action + args = option.callback_args or () + kwargs = option.callback_kwargs or {} + option.callback(option, opt_str, val, self, *args, **kwargs) + else: + val = self.check_default(option, key, val) + + defaults[option.dest] = val + + for key in late_eval: + defaults[key] = getattr(self.values, key) + self.values = None + return defaults + + def get_default_values(self): + """Overriding to make updating the defaults after instantiation of + the option parser possible, _update_defaults() does the dirty work.""" + if not self.process_default_values: + # Old, pre-Optik 1.5 behaviour. + return optparse.Values(self.defaults) + + # Load the configuration, or error out in case of an error + try: + self.config.load() + except ConfigurationError as err: + self.exit(UNKNOWN_ERROR, str(err)) + + defaults = self._update_defaults(self.defaults.copy()) # ours + for option in self._get_all_options(): + default = defaults.get(option.dest) + if isinstance(default, string_types): + opt_str = option.get_opt_string() + defaults[option.dest] = option.check_value(opt_str, default) + return optparse.Values(defaults) + + def error(self, msg): + self.print_usage(sys.stderr) + self.exit(UNKNOWN_ERROR, "%s\n" % msg) + + +def invalid_config_error_message(action, key, val): + """Returns a better error message when invalid configuration option + is provided.""" + if action in ('store_true', 'store_false'): + return ("{0} is not a valid value for {1} option, " + "please specify a boolean value like yes/no, " + "true/false or 1/0 instead.").format(val, key) + + return ("{0} is not a valid value for {1} option, " + "please specify a numerical value like 1/0 " + "instead.").format(val, key) diff --git a/venv/lib/python3.7/site-packages/pip/_internal/cli/status_codes.py b/venv/lib/python3.7/site-packages/pip/_internal/cli/status_codes.py new file mode 100644 index 0000000..275360a --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/cli/status_codes.py @@ -0,0 +1,8 @@ +from __future__ import absolute_import + +SUCCESS = 0 +ERROR = 1 +UNKNOWN_ERROR = 2 +VIRTUALENV_NOT_FOUND = 3 +PREVIOUS_BUILD_DIR_ERROR = 4 +NO_MATCHES_FOUND = 23 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/commands/__init__.py b/venv/lib/python3.7/site-packages/pip/_internal/commands/__init__.py new file mode 100644 index 0000000..c7d1da3 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/commands/__init__.py @@ -0,0 +1,79 @@ +""" +Package containing all pip commands +""" +from __future__ import absolute_import + +from pip._internal.commands.completion import CompletionCommand +from pip._internal.commands.configuration import ConfigurationCommand +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 + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import List, Type # noqa: F401 + from pip._internal.cli.base_command import Command # noqa: F401 + +commands_order = [ + InstallCommand, + DownloadCommand, + UninstallCommand, + FreezeCommand, + ListCommand, + ShowCommand, + CheckCommand, + ConfigurationCommand, + SearchCommand, + WheelCommand, + HashCommand, + CompletionCommand, + HelpCommand, +] # type: List[Type[Command]] + +commands_dict = {c.name: c for c in commands_order} + + +def get_summaries(ordered=True): + """Yields sorted (command name, command summary) tuples.""" + + 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) + + +def get_similar_commands(name): + """Command name auto-correct.""" + from difflib import get_close_matches + + name = name.lower() + + close_commands = get_close_matches(name, commands_dict.keys()) + + if close_commands: + 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.7/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b61a3223d6caa81518e7530a35e18755f56ca1f3 GIT binary patch literal 2509 zcmaJ@TW{1x6rQoY7dE@jCM+R$mRrkK%`Pp1iVC5s;S$s~LQQ~Tfh@-}n>CrSm$8?S z)#iyv?L+(2Kaf23xAYHGe(e)~ftU82$zB3tu{Gl}XU<&CH{Utq?@Ofuf#>&yt!IDd z3HcWrgQo<-cTnOBln_Q7!YDHYm4;(blucnu%dxaI@t>sfvmJ4D^PCL_Do)D*H#i?kyD9*?kXGY5nyX0JAr&;BI@Jn~d8|qwUOKgUnJ)q8KY?jR(5a)9?&lcc&g)MH7 z+H&`D;i2d6c-y?{M`7XxVGwRtJt3;?pbaW1y^zI)w+L{Jrjy=Q9EncC-9WY@m4Iq$ zHIi+?lOPH~LUT}7R->>PYS@ZVU8yR^YQ<)0kB(Ta9Q{q}<}PQbm9ru+z8{yS|Q?cVI(d~tR6T9b9- z8`oZ`uU{u!c@>`Ru(8>I(_87gwQ~KNt=3LwYa5lixIvh36?&rK_Yb(?f-Xp0x8B}+ zSGdIjKY_0H?Jsce=t!2RIrwZ2y+hATC_a?oT5?E+-uRjgAU~x4DPH|Sf(%)AVf%$Sk!)n|C zeyP1$HR%B3;`(|mliDthaR-j1rGez46RACHMhd`7GeN>-oaP2oS!qspaF*tM$#kze z1MUnba(&^&@#s+0tnS_BiF-Urz~dDJL1!h?qD3Qb*i>Br-4HEAYRH8f(9n5_NV-oc zAa`g0QUrKG67$eHB7mULGgQ52Fgiyz2s5DoTWXo^{Oa+MX=timCy7@4NGa|ob%o5s zh{V15B8s^yy~Jv^$RK{gz8t)qzJ`9e&0wC2zo@oY4Z;Q zoVC`6_@QTz>&a;xh*R#_zmY>2fcP8%hb&;;PC-H1$CttIUm*X(BL2YUq-KFn-=7GmHVUxq<)3akDWt63Rb7kVsXqWz<+;7VQ`M!Y^?7LHSwv1 zVz@>WvO8TKvrs?XD*OjY@%sGOfpi9!jk3{f+@^Q&{!x=?GXMTeog@%(J=tr+J*~=U zknK07prNKw^WhFfP~Y+(8}wj-{ZNA5is dig~U`$GngLELx^T(}0lq*qb$Nvrx?2{{sOqspJ3v literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/check.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/check.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..831679b5a7e0d051d527b2c82be4f824be5f0f12 GIT binary patch literal 1311 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1d3c2c4fc8321b0dfa85953261c83bb3e21e0dee GIT binary patch literal 6435 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 j%ACjdQnct+lyj@N`#mbX&RhE literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7bd0b30e0419f95a4db87e1dcb4c41da68d1b169 GIT binary patch literal 2879 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/help.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/help.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ed2280135e70483eace0f8e88fe3650196a81b50 GIT binary patch literal 1249 zcmZuw&2HQ_5GM6+b?pSGv5C>55CR0~9=viIv_XI%2(k^DUUJzKErgR>|Xz^5XT9|#JnknxMn53xQtuj3kJ(pt5>S7NM!{c@ z35~G6m(EmKG&LhRuS!`%$e)y)r-B-H`qO0cW;z9Tu#LWvvXpakdM6e*uRzt;U>Hg; zMTtdmVpA(|sGYdfNj&N%KJ}=7jQ~La2=?@6Z&^`ov$n(OX?YQyLL^$0GMaB7DD9X~ zI}D><9#^u=q8HoUm+ga3pBlfP+knN$9%ukM0ae#vD29?j`PMeK)(%FiK?h)u(AxbO zi9-j~_IW5zFfvc=Owli>b36Oomqq7v?iF5p)b89N%JACnJo#Ja-vGhR8=_liNDV}9 z{La6{SNJ3D;L9U)h1NkAoCP;~x7(Z}@14YeWn}679aBQ{d94pKRuh%;yhtV4ZMBDu zI2YxG*p(%E^jJM=4|%$pv1nB`5of8WH&Ht}jz*y#R(Ulhxu}^GX))fVlBO2Y6h((W z3d%0~c1kl~+Dog72`XK)aL&qHXs=48Vp4~dgjB@z0vhKiRxGq%R&`zqXi+LNbtiE! z=ah()Gwo&#Q%c)hW!m3D_yfrY@Pogr7;-Mtn#Idh#*4C`Osbfl#`7l?dEP!hJGpqe zpso7u=~8}kS-1QIBop!b7?>UBLe*(e9Dn<4c6#2-G863eU&`^0a%@nKtChB8Bksem z)t6upzHeF903Tq_3UFYB*ue+Z0lY)2z4sQ5Og1AphEwl=bU=Degy@hEUecyu;13A- z(4>W73oD-xTF$|7HuM{nW=#94f%_y^`tv*!rDR014^0m5B@;_|1X%it+%XSL%mZV( zr3S_Uc#Z`Mw%;+30LY@L8^}bYxrF+w|24hH$Fo$i-5^PGDL(ZP)Us|Ad`6kt%)-O} lW@49fw&`|19X*0Ocuhm40j+}1e13R9TsDs8o) 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 WuzCq554nhi6j=W|3jMyCOaBk%d8~;5 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/list.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/list.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7db88b8dcfc9f129d303effd8c92bde8610d8453 GIT binary patch literal 8922 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/search.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/search.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..98ae97cce5458d05433d37b5c68f56e318c1d318 GIT binary patch literal 4315 zcmZu!NpsxB748Nwz-(MaQ=)9k@IsfyF^5WAS?ppdvL(iLBGZaVManoX6gUkIL1Gzo zW4KI#mrxZ~rQ#)bABGoKVhI_TKjvd^9yxXZZc& zP&tXh+Amtzjz2Hc*J7f;hbnAGCGESn;lcXt&WAa8C7DtV`~{Ja^h;I zs_9Bpi|d_+rtPR1Pj#j=?L^b@OlL;Z)o3=J>&(UToq64_MVI1*&Vr`v(M$1SXHnCQ z=yH6eb4An5XeqwhxvJ@@=;ip8&MTY+#^}}H+8OV>_AwLFV&*XuGr`QM*>T0Jn0w4R zuZu-7FD^aioj1gScnO?0g|W$6m!IIKti_8Ne_N%|APc-O?x!-_0I%`66oCxHov@ps zJJsLsc`{JxKz0KKMy2md70}309Lavy>qcRakf?JzjblF%Eu)y-_}u&K!>!w&tZ#b1 z`~3dKox<6?fBW|O<|gFk?}hz`dhV9=6Gau|wfKMva&u$$Sb2&-d@O2_${?QmfW=P@iN zs-gzn)I?o0@UDN&EY@j2Pt9U#Gw@}1cYL(rt+MOxq|&A1xqZL8@Am@b9`2?pa1%cc zT#Ts!6d{k@Zkl9%m?(Gc(IAk=H`|4+^n$}{byxqE`!emhU#9&mOcV9hL~yt?-bwF5 z+f8NPvvS~h6jEYtm1I1J81;ytJQdSwfpnF_x|wxy&H$`?TDfJ)q4l> z7f0DJzJXsaS>0OghkYnXWquT`{PNe^yZeLf9x-*p4S-nSb+uc%gjy}_-tHgEE4aYx zXlfP@#^<@sEpFg%@v1RgEDb+KTzjI7?gZHm=1|1Cji$En$PLxZ5VcPEUt#nUGiM{7 zn>jx-POQwxty6wd5$wdy0EAKHjLEgkK1F0(BA%01a$A_+006lq?`73Zmel|RYh&2@ zEL18?daeu}4MGG27fKw&@H+Q;c^OxOy45bN$cyQ7FFg!Jw%e-92F@qxniwNj2ascL zH-tq^b*$hFnMem&VTa1kvST?#l2fnrLIoQgq2bkp-54g6?4;&`4&yPhXkv1m~lD8x^BgXl|PFG*zp(`&$a2SIY6y+yV$ zT;gbI?7iI}im=A{iCbKfPf0Sgjw4GTw1<(AEtr^|%|>-rkDkX+Qep*7oAmD>GIq*N z_|ZYm?y#?t6C*bShpU))lgn6mn|N2q#YX&$?K|=l&{kgQabf)cZf>rzM@@P!F;Q7! zBLg6ySPV!!ZS>{4BW1txC0fmwVXC^X<27{wwC!EvpPAjyal}j>Ly-=wI5Jq z@caEB5yi}I*xN+{0T%S-3X66x>;pd z81Iw|^Du#__W=M~-)rU$VEPlui#h63 zsgPXN{rO2>_b%lQjXgj-E92S&_UNX?vZ?(#R>x}e|1)?G(MSpaU)VVJLj%gC(7K7H z$lZHTKlwW55G#*)4Y7DGfnE8~iAn}_~kVrCDVWNOU zbT!&H!dw2cL2jIKcBUC*qYYnF^ z@P|`(Kipd1-1>m3Q%svK%-BDYbk(A9n96-r1V}@fR;~O!v8!2dlpRXHUs&aHFAbBz zMrn?~URYtWlNPg7#0zLnhT8)w(Bw3xYX2~wNDC0s4Q++f=DUYfH zst*igy(+hjS*jCs?xQDS1z$u;na4OP2OUA`h#AxTDxc+&RyxN8V#Tw1jS?vUjff!l zH}oZD&=;49kOvt234^G9=<8|{?vT}Pf&1c73D$o@)5u_4+X72%wBDk;yEDiJ$fBMk zBo_|Z0Y;N=(?So4)qp}H;E$3;8FU*cT-%gyMJlzeJFh;+X_q?2BJFV)mV`PnqX@#1nK zJxrq17rGiMu3Q`pj=DklO{I&_;_Ag=)Fwfs+PX3-zbIZ107x-TQNhp3y7c9XE0h8g z=$l685)F&eZJr@dQ*YAb>RMSZ-6X&$GFH>jd5JfHwx&r> RLgDyt)Xmv( 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 aHN~IDrHJDfLoK38Qk&88shM-ejsE~u`Qcpv literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6128dd43afc54c2afd4161f4d7b80b00306031dd GIT binary patch literal 2705 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] list + %prog [] [--editor ] edit + + %prog [] get name + %prog [] set name value + %prog [] unset name + """ + + summary = "Manage local and global configuration." + + def __init__(self, *args, **kwargs): + super(ConfigurationCommand, self).__init__(*args, **kwargs) + + self.configuration = None + + self.cmd_opts.add_option( + '--editor', + dest='editor', + action='store', + default=None, + help=( + 'Editor to use to edit the file. Uses VISUAL or EDITOR ' + 'environment variables if not provided.' + ) + ) + + self.cmd_opts.add_option( + '--global', + dest='global_file', + action='store_true', + default=False, + help='Use the system-wide configuration file only' + ) + + self.cmd_opts.add_option( + '--user', + dest='user_file', + action='store_true', + default=False, + help='Use the user configuration file only' + ) + + self.cmd_opts.add_option( + '--venv', + dest='venv_file', + action='store_true', + default=False, + help='Use the virtualenv configuration file only' + ) + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + handlers = { + "list": self.list_values, + "edit": self.open_in_editor, + "get": self.get_name, + "set": self.set_name_value, + "unset": self.unset_name + } + + # Determine action + if not args or args[0] not in handlers: + logger.error("Need an action ({}) to perform.".format( + ", ".join(sorted(handlers))) + ) + return ERROR + + action = args[0] + + # Determine which configuration files are to be loaded + # Depends on whether the command is modifying. + try: + load_only = self._determine_file( + options, need_value=(action in ["get", "set", "unset", "edit"]) + ) + except PipError as e: + logger.error(e.args[0]) + return ERROR + + # Load a new configuration + self.configuration = Configuration( + isolated=options.isolated_mode, load_only=load_only + ) + self.configuration.load() + + # Error handling happens here, not in the action-handlers. + try: + handlers[action](options, args[1:]) + except PipError as e: + logger.error(e.args[0]) + return ERROR + + return SUCCESS + + def _determine_file(self, options, need_value): + file_options = { + kinds.USER: options.user_file, + kinds.GLOBAL: options.global_file, + kinds.VENV: options.venv_file + } + + if sum(file_options.values()) == 0: + if not need_value: + return None + # Default to user, unless there's a virtualenv file. + elif os.path.exists(venv_config_file): + return kinds.VENV + else: + return kinds.USER + elif sum(file_options.values()) == 1: + # There's probably a better expression for this. + return [key for key in file_options if file_options[key]][0] + + raise PipError( + "Need exactly one file to operate upon " + "(--user, --venv, --global) to perform." + ) + + def list_values(self, options, args): + self._get_n_args(args, "list", n=0) + + for key, value in sorted(self.configuration.items()): + logger.info("%s=%r", key, value) + + def get_name(self, options, args): + key = self._get_n_args(args, "get [name]", n=1) + value = self.configuration.get_value(key) + + logger.info("%s", value) + + def set_name_value(self, options, args): + 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): + key = self._get_n_args(args, "unset [name]", n=1) + self.configuration.unset_value(key) + + self._save_configuration() + + def open_in_editor(self, options, args): + editor = self._determine_editor(options) + + fname = self.configuration.get_file_to_edit() + if fname is None: + raise PipError("Could not determine appropriate file.") + + try: + subprocess.check_call([editor, fname]) + except subprocess.CalledProcessError as e: + raise PipError( + "Editor Subprocess exited with exit code {}" + .format(e.returncode) + ) + + def _get_n_args(self, args, example, n): + """Helper to make sure the command got the right number of arguments + """ + if len(args) != n: + msg = ( + 'Got unexpected number of arguments, expected {}. ' + '(example: "{} config {}")' + ).format(n, get_prog(), example) + raise PipError(msg) + + if n == 1: + return args[0] + else: + return args + + def _save_configuration(self): + # 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 + ) + raise PipError("Internal Error.") + + def _determine_editor(self, options): + if options.editor is not None: + return options.editor + elif "VISUAL" in os.environ: + return os.environ["VISUAL"] + elif "EDITOR" in os.environ: + return os.environ["EDITOR"] + else: + raise PipError("Could not determine editor to use.") diff --git a/venv/lib/python3.7/site-packages/pip/_internal/commands/download.py b/venv/lib/python3.7/site-packages/pip/_internal/commands/download.py new file mode 100644 index 0000000..b3f3c6e --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/commands/download.py @@ -0,0 +1,174 @@ +from __future__ import absolute_import + +import logging +import os + +from pip._internal.cli import cmdoptions +from pip._internal.cli.base_command import RequirementCommand +from pip._internal.operations.prepare import RequirementPreparer +from pip._internal.req import RequirementSet +from pip._internal.req.req_tracker import RequirementTracker +from pip._internal.resolve import Resolver +from pip._internal.utils.filesystem import check_path_owner +from pip._internal.utils.misc import ensure_dir, normalize_path +from pip._internal.utils.temp_dir import TempDirectory + +logger = logging.getLogger(__name__) + + +class DownloadCommand(RequirementCommand): + """ + Download packages from: + + - PyPI (and other indexes) using requirement specifiers. + - VCS project urls. + - Local project directories. + - Local or remote source archives. + + pip also supports downloading from "requirements files", which provide + an easy way to specify a whole environment to be downloaded. + """ + name = 'download' + + usage = """ + %prog [options] [package-index-options] ... + %prog [options] -r [package-index-options] ... + %prog [options] ... + %prog [options] ... + %prog [options] ...""" + + summary = 'Download packages.' + + 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( + '-d', '--dest', '--destination-dir', '--destination-directory', + dest='download_dir', + metavar='dir', + default=os.curdir, + help=("Download packages into ."), + ) + + cmd_opts.add_option(cmdoptions.platform()) + cmd_opts.add_option(cmdoptions.python_version()) + cmd_opts.add_option(cmdoptions.implementation()) + cmd_opts.add_option(cmdoptions.abi()) + + index_opts = cmdoptions.make_option_group( + cmdoptions.index_group, + self.parser, + ) + + self.parser.insert_option_group(0, index_opts) + self.parser.insert_option_group(0, cmd_opts) + + def run(self, options, args): + options.ignore_installed = True + # editable doesn't really make sense for `pip download`, but the bowels + # of the RequirementSet code require that property. + options.editables = [] + + if options.python_version: + python_versions = [options.python_version] + else: + python_versions = None + + 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: + finder = self._build_package_finder( + options=options, + session=session, + platform=options.platform, + python_versions=python_versions, + abi=options.abi, + implementation=options.implementation, + ) + 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 + + with RequirementTracker() as req_tracker, TempDirectory( + options.build_dir, delete=build_delete, kind="download" + ) as directory: + + requirement_set = RequirementSet( + require_hashes=options.require_hashes, + ) + self.populate_requirement_set( + requirement_set, + args, + options, + finder, + session, + self.name, + None + ) + + 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, + ) + + 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, + ignore_requires_python=False, + ignore_installed=True, + isolated=options.isolated_mode, + ) + resolver.resolve(requirement_set) + + downloaded = ' '.join([ + req.name for req in requirement_set.successfully_downloaded + ]) + if downloaded: + logger.info('Successfully downloaded %s', downloaded) + + # Clean up + if not options.no_clean: + requirement_set.cleanup_files() + + return requirement_set diff --git a/venv/lib/python3.7/site-packages/pip/_internal/commands/freeze.py b/venv/lib/python3.7/site-packages/pip/_internal/commands/freeze.py new file mode 100644 index 0000000..dc9c53a --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/commands/freeze.py @@ -0,0 +1,96 @@ +from __future__ import absolute_import + +import sys + +from pip._internal.cache import WheelCache +from pip._internal.cli.base_command import Command +from pip._internal.models.format_control import FormatControl +from pip._internal.operations.freeze import freeze +from pip._internal.utils.compat import stdlib_pkgs + +DEV_PKGS = {'pip', 'setuptools', 'distribute', 'wheel'} + + +class FreezeCommand(Command): + """ + Output installed packages in requirements format. + + 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) + + self.cmd_opts.add_option( + '-r', '--requirement', + dest='requirements', + action='append', + default=[], + metavar='file', + help="Use the order in the given requirements file and its " + "comments when generating output. This option can be " + "used multiple times.") + self.cmd_opts.add_option( + '-f', '--find-links', + dest='find_links', + action='append', + default=[], + metavar='URL', + help='URL for finding packages, which will be added to the ' + 'output.') + self.cmd_opts.add_option( + '-l', '--local', + dest='local', + action='store_true', + default=False, + help='If in a virtualenv that has global access, do not output ' + 'globally-installed packages.') + self.cmd_opts.add_option( + '--user', + dest='user', + action='store_true', + default=False, + help='Only output packages installed in user-site.') + self.cmd_opts.add_option( + '--all', + dest='freeze_all', + action='store_true', + help='Do not skip these packages in the output:' + ' %s' % ', '.join(DEV_PKGS)) + self.cmd_opts.add_option( + '--exclude-editable', + dest='exclude_editable', + action='store_true', + help='Exclude editable package from output.') + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + format_control = FormatControl(set(), set()) + wheel_cache = WheelCache(options.cache_dir, format_control) + skip = set(stdlib_pkgs) + if not options.freeze_all: + skip.update(DEV_PKGS) + + freeze_kwargs = dict( + requirement=options.requirements, + find_links=options.find_links, + local_only=options.local, + user_only=options.user, + 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() diff --git a/venv/lib/python3.7/site-packages/pip/_internal/commands/hash.py b/venv/lib/python3.7/site-packages/pip/_internal/commands/hash.py new file mode 100644 index 0000000..423440e --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/commands/hash.py @@ -0,0 +1,57 @@ +from __future__ import absolute_import + +import hashlib +import logging +import sys + +from pip._internal.cli.base_command import Command +from pip._internal.cli.status_codes import ERROR +from pip._internal.utils.hashes import FAVORITE_HASH, STRONG_HASHES +from pip._internal.utils.misc import read_chunks + +logger = logging.getLogger(__name__) + + +class HashCommand(Command): + """ + Compute a hash of a local package archive. + + These can be used with --hash in a requirements file to do repeatable + installs. + + """ + name = 'hash' + usage = '%prog [options] ...' + summary = 'Compute hashes of package archives.' + ignore_require_venv = True + + def __init__(self, *args, **kw): + super(HashCommand, self).__init__(*args, **kw) + 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)) + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + 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)) + + +def _hash_of_file(path, algorithm): + """Return the hash digest of a file.""" + with open(path, 'rb') as archive: + hash = hashlib.new(algorithm) + for chunk in read_chunks(archive): + hash.update(chunk) + return hash.hexdigest() diff --git a/venv/lib/python3.7/site-packages/pip/_internal/commands/help.py b/venv/lib/python3.7/site-packages/pip/_internal/commands/help.py new file mode 100644 index 0000000..49a81cb --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/commands/help.py @@ -0,0 +1,37 @@ +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 + + +class HelpCommand(Command): + """Show help for commands""" + name = 'help' + usage = """ + %prog """ + summary = 'Show help for commands.' + ignore_require_venv = True + + def run(self, options, args): + from pip._internal.commands import commands_dict, get_similar_commands + + try: + # 'pip help' with no args is handled by pip.__init__.parseopt() + cmd_name = args[0] # the command we need help for + except IndexError: + return SUCCESS + + if cmd_name not in commands_dict: + guess = get_similar_commands(cmd_name) + + msg = ['unknown command "%s"' % cmd_name] + if guess: + msg.append('maybe you meant "%s"' % guess) + + raise CommandError(' - '.join(msg)) + + command = commands_dict[cmd_name]() + command.parser.print_help() + + return SUCCESS diff --git a/venv/lib/python3.7/site-packages/pip/_internal/commands/install.py b/venv/lib/python3.7/site-packages/pip/_internal/commands/install.py new file mode 100644 index 0000000..6fc178f --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/commands/install.py @@ -0,0 +1,535 @@ +from __future__ import absolute_import + +import errno +import logging +import operator +import os +import shutil +from optparse import SUPPRESS_HELP + +from pip._vendor import pkg_resources + +from pip._internal.cache import WheelCache +from pip._internal.cli import cmdoptions +from pip._internal.cli.base_command import RequirementCommand +from pip._internal.cli.status_codes import ERROR +from pip._internal.exceptions import ( + CommandError, InstallationError, PreviousBuildDirError, +) +from pip._internal.locations import distutils_scheme, virtualenv_no_global +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.resolve import Resolver +from pip._internal.utils.filesystem import check_path_owner +from pip._internal.utils.misc import ( + ensure_dir, get_installed_version, + protect_pip_from_modification_on_windows, +) +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.wheel import WheelBuilder + +try: + import wheel +except ImportError: + wheel = None + + +logger = logging.getLogger(__name__) + + +class InstallCommand(RequirementCommand): + """ + Install packages from: + + - PyPI (and other indexes) using requirement specifiers. + - VCS project urls. + - Local project directories. + - Local or remote source archives. + + 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] [package-index-options] ... + %prog [options] -r [package-index-options] ... + %prog [options] [-e] ... + %prog [options] [-e] ... + %prog [options] ...""" + + summary = 'Install packages.' + + 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( + '-t', '--target', + dest='target_dir', + metavar='dir', + default=None, + help='Install packages into . ' + 'By default this will not replace existing files/folders in ' + '. Use --upgrade to replace existing packages in ' + 'with new versions.' + ) + cmd_opts.add_option(cmdoptions.platform()) + cmd_opts.add_option(cmdoptions.python_version()) + cmd_opts.add_option(cmdoptions.implementation()) + cmd_opts.add_option(cmdoptions.abi()) + + cmd_opts.add_option( + '--user', + dest='use_user_site', + action='store_true', + help="Install to the Python user install directory for your " + "platform. Typically ~/.local/, or %APPDATA%\\Python on " + "Windows. (See the Python documentation for site.USER_BASE " + "for full details.)") + cmd_opts.add_option( + '--no-user', + dest='use_user_site', + action='store_false', + help=SUPPRESS_HELP) + 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( + '--prefix', + dest='prefix_path', + metavar='dir', + default=None, + help="Installation prefix where lib, bin and other top-level " + "folders are placed") + + cmd_opts.add_option(cmdoptions.build_dir()) + + cmd_opts.add_option(cmdoptions.src()) + + cmd_opts.add_option( + '-U', '--upgrade', + dest='upgrade', + action='store_true', + help='Upgrade all specified packages to the newest available ' + 'version. The handling of dependencies depends on the ' + 'upgrade-strategy used.' + ) + + cmd_opts.add_option( + '--upgrade-strategy', + dest='upgrade_strategy', + default='only-if-needed', + choices=['only-if-needed', 'eager'], + help='Determines how dependency upgrading should be handled ' + '[default: %default]. ' + '"eager" - dependencies are upgraded regardless of ' + 'whether the currently installed version satisfies the ' + 'requirements of the upgraded package(s). ' + '"only-if-needed" - are upgraded only when they do not ' + 'satisfy the requirements of the upgraded package(s).' + ) + + 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( + '-I', '--ignore-installed', + dest='ignore_installed', + action='store_true', + help='Ignore the installed packages (reinstalling instead).') + + cmd_opts.add_option(cmdoptions.ignore_requires_python()) + cmd_opts.add_option(cmdoptions.no_build_isolation()) + + cmd_opts.add_option(cmdoptions.install_options()) + cmd_opts.add_option(cmdoptions.global_options()) + + cmd_opts.add_option( + "--compile", + action="store_true", + dest="compile", + default=True, + help="Compile Python source files to bytecode", + ) + + cmd_opts.add_option( + "--no-compile", + action="store_false", + dest="compile", + help="Do not compile Python source files to bytecode", + ) + + 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( + "--no-warn-conflicts", + action="store_false", + dest="warn_about_conflicts", + default=True, + 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()) + + index_opts = cmdoptions.make_option_group( + cmdoptions.index_group, + self.parser, + ) + + self.parser.insert_option_group(0, index_opts) + self.parser.insert_option_group(0, cmd_opts) + + def run(self, options, args): + 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) + + if options.python_version: + python_versions = [options.python_version] + else: + python_versions = None + + 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") + if options.target_dir: + options.ignore_installed = True + options.target_dir = os.path.abspath(options.target_dir) + if (os.path.exists(options.target_dir) and not + os.path.isdir(options.target_dir)): + raise CommandError( + "Target path exists but is not a directory, will not " + "continue." + ) + + # Create a target directory for using with the target option + target_temp_dir.create() + install_options.append('--home=' + target_temp_dir.path) + + global_options = options.global_options or [] + + with self._build_session(options) as session: + finder = self._build_package_finder( + options=options, + session=session, + platform=options.platform, + python_versions=python_versions, + abi=options.abi, + implementation=options.implementation, + ) + 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, + ) + 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, + ) + + 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, + ) + + 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, + ) + resolver.resolve(requirement_set) + + protect_pip_from_modification_on_windows( + modifying_pip=requirement_set.has_requirement("pip") + ) + + # If caching is disabled or wheel is not installed don't + # try to build wheels. + if wheel and options.cache_dir: + # build wheels before install. + wb = WheelBuilder( + finder, preparer, wheel_cache, + build_options=[], global_options=[], + ) + # Ignore the result: a failed wheel will be + # installed from the sdist/vcs whatever. + wb.build( + requirement_set.requirements.values(), + session=session, autobuilding=True + ) + + 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() + + if options.target_dir: + self._handle_target_dir( + options.target_dir, target_temp_dir, options.upgrade + ) + return requirement_set + + def _handle_target_dir(self, target_dir, target_temp_dir, upgrade): + 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'] + + 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) + + shutil.move( + os.path.join(lib_dir, item), + target_item_dir + ) + + def _warn_about_conflicts(self, to_install): + package_set, _dep_info = check_install_conflicts(to_install) + missing, conflicting = _dep_info + + # NOTE: There is some duplication here from pip check + 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], + ) + + 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, + ) + + +def get_lib_location_guesses(*args, **kwargs): + scheme = distutils_scheme('', *args, **kwargs) + return [scheme['purelib'], scheme['platlib']] + + +def create_env_error_message(error, show_traceback, using_user_site): + """Format an error message for an EnvironmentError + + It may occur anytime during the execution of the install command. + """ + parts = [] + + # Mention the error if we are not going to show a traceback + parts.append("Could not install packages due to an EnvironmentError") + if not show_traceback: + parts.append(": ") + parts.append(str(error)) + else: + parts.append(".") + + # Spilt the error indication from a helper message (if any) + parts[-1] += "\n" + + # Suggest useful actions to the user: + # (1) using user site-packages or (2) verifying the permissions + if error.errno == errno.EACCES: + user_option_part = "Consider using the `--user` option" + permissions_part = "Check the permissions" + + if not using_user_site: + parts.extend([ + user_option_part, " or ", + permissions_part.lower(), + ]) + else: + parts.append(permissions_part) + parts.append(".\n") + + return "".join(parts).strip() + "\n" diff --git a/venv/lib/python3.7/site-packages/pip/_internal/commands/list.py b/venv/lib/python3.7/site-packages/pip/_internal/commands/list.py new file mode 100644 index 0000000..c6eeca7 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/commands/list.py @@ -0,0 +1,306 @@ +from __future__ import absolute_import + +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.exceptions import CommandError +from pip._internal.index import PackageFinder +from pip._internal.utils.misc import ( + dist_is_editable, get_installed_distributions, +) +from pip._internal.utils.packaging import get_installer + +logger = logging.getLogger(__name__) + + +class ListCommand(Command): + """ + List installed packages, including editables. + + Packages are listed in a case-insensitive sorted order. + """ + name = 'list' + 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( + '-o', '--outdated', + action='store_true', + default=False, + help='List outdated packages') + cmd_opts.add_option( + '-u', '--uptodate', + action='store_true', + default=False, + help='List uptodate packages') + cmd_opts.add_option( + '-e', '--editable', + action='store_true', + default=False, + help='List editable projects.') + cmd_opts.add_option( + '-l', '--local', + action='store_true', + default=False, + help=('If in a virtualenv that has global access, do not list ' + 'globally-installed packages.'), + ) + self.cmd_opts.add_option( + '--user', + dest='user', + action='store_true', + default=False, + help='Only output packages installed in user-site.') + + cmd_opts.add_option( + '--pre', + action='store_true', + default=False, + help=("Include pre-release and development versions. By default, " + "pip only finds stable versions."), + ) + + cmd_opts.add_option( + '--format', + action='store', + dest='list_format', + default="columns", + choices=('columns', 'freeze', 'json'), + help="Select the output format among: columns (default), freeze, " + "or json", + ) + + cmd_opts.add_option( + '--not-required', + action='store_true', + dest='not_required', + help="List packages that are not dependencies of " + "installed packages.", + ) + + cmd_opts.add_option( + '--exclude-editable', + action='store_false', + dest='include_editable', + help='Exclude editable package from output.', + ) + cmd_opts.add_option( + '--include-editable', + action='store_true', + dest='include_editable', + help='Include editable package from output.', + default=True, + ) + index_opts = cmdoptions.make_option_group( + cmdoptions.index_group, self.parser + ) + + self.parser.insert_option_group(0, index_opts) + self.parser.insert_option_group(0, cmd_opts) + + def _build_package_finder(self, options, index_urls, session): + """ + Create a package finder appropriate to this list command. + """ + return PackageFinder( + find_links=options.find_links, + index_urls=index_urls, + allow_all_prereleases=options.pre, + trusted_hosts=options.trusted_hosts, + process_dependency_links=options.process_dependency_links, + session=session, + ) + + def run(self, options, args): + if options.outdated and options.uptodate: + raise CommandError( + "Options --outdated and --uptodate cannot be combined.") + + packages = get_installed_distributions( + local_only=options.local, + user_only=options.user, + editables_only=options.editable, + include_editables=options.include_editable, + ) + + if options.outdated: + packages = self.get_outdated(packages, options) + elif options.uptodate: + packages = self.get_uptodate(packages, options) + + if options.not_required: + packages = self.get_not_required(packages, options) + + self.output_package_listing(packages, options) + + def get_outdated(self, packages, options): + 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): + 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() + 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} + + def iter_packages_latest_infos(self, packages, options): + index_urls = [options.index_url] + options.extra_index_urls + if options.no_index: + logger.debug('Ignoring indexes: %s', ','.join(index_urls)) + index_urls = [] + + dependency_links = [] + for dist in packages: + if dist.has_metadata('dependency_links.txt'): + dependency_links.extend( + dist.get_metadata_lines('dependency_links.txt'), + ) + + with self._build_session(options) as session: + finder = self._build_package_finder(options, index_urls, session) + finder.add_dependency_links(dependency_links) + + for dist in packages: + typ = 'unknown' + all_candidates = finder.find_all_candidates(dist.key) + if not options.pre: + # Remove prereleases + all_candidates = [candidate for candidate in all_candidates + if not candidate.version.is_prerelease] + + if not all_candidates: + continue + best_candidate = max(all_candidates, + key=finder._candidate_sort_key) + remote_version = best_candidate.version + if best_candidate.location.is_wheel: + typ = 'wheel' + else: + typ = 'sdist' + # This is dirty but makes the rest of the code much cleaner + dist.latest_version = remote_version + dist.latest_filetype = typ + yield dist + + def output_package_listing(self, packages, options): + packages = sorted( + packages, + key=lambda dist: dist.project_name.lower(), + ) + if options.list_format == 'columns' and packages: + data, header = format_for_columns(packages, options) + self.output_package_listing_columns(data, header) + 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) + else: + logger.info("%s==%s", dist.project_name, dist.version) + elif options.list_format == 'json': + logger.info(format_for_json(packages, options)) + + def output_package_listing_columns(self, data, header): + # insert the header first: we need to know the size of column names + if len(data) > 0: + data.insert(0, header) + + pkg_strings, sizes = tabulate(data) + + # Create and add a separator. + if len(data) > 0: + 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 + + +def format_for_columns(pkgs, options): + """ + Convert the package data into something usable + by output_package_listing_columns. + """ + running_outdated = options.outdated + # Adjust the header for the `pip list --outdated` case. + if running_outdated: + header = ["Package", "Version", "Latest", "Type"] + else: + header = ["Package", "Version"] + + data = [] + if options.verbose >= 1 or any(dist_is_editable(x) for x in pkgs): + header.append("Location") + if options.verbose >= 1: + header.append("Installer") + + for proj in pkgs: + # if we're working on the 'outdated' list, separate out the + # latest_version and type + row = [proj.project_name, proj.version] + + if running_outdated: + row.append(proj.latest_version) + row.append(proj.latest_filetype) + + if options.verbose >= 1 or dist_is_editable(proj): + row.append(proj.location) + if options.verbose >= 1: + row.append(get_installer(proj)) + + data.append(row) + + return data, header + + +def format_for_json(packages, options): + data = [] + for dist in packages: + info = { + 'name': dist.project_name, + 'version': six.text_type(dist.version), + } + if options.verbose >= 1: + info['location'] = dist.location + info['installer'] = get_installer(dist) + if options.outdated: + info['latest_version'] = six.text_type(dist.latest_version) + info['latest_filetype'] = dist.latest_filetype + data.append(info) + return json.dumps(data) diff --git a/venv/lib/python3.7/site-packages/pip/_internal/commands/search.py b/venv/lib/python3.7/site-packages/pip/_internal/commands/search.py new file mode 100644 index 0000000..c157a31 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/commands/search.py @@ -0,0 +1,135 @@ +from __future__ import absolute_import + +import logging +import sys +import textwrap +from collections import OrderedDict + +from pip._vendor import pkg_resources +from pip._vendor.packaging.version import parse as parse_version +# 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._internal.cli.base_command import Command +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.utils.compat import get_terminal_size +from pip._internal.utils.logging import indent_log + +logger = logging.getLogger(__name__) + + +class SearchCommand(Command): + """Search for PyPI packages whose name or summary contains .""" + name = 'search' + usage = """ + %prog [options] """ + summary = 'Search PyPI for packages.' + ignore_require_venv = True + + def __init__(self, *args, **kw): + super(SearchCommand, self).__init__(*args, **kw) + self.cmd_opts.add_option( + '-i', '--index', + dest='index', + metavar='URL', + default=PyPI.pypi_url, + help='Base URL of Python Package Index (default %default)') + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + if not args: + raise CommandError('Missing required argument (search query).') + query = args + pypi_hits = self.search(query, options) + hits = transform_hits(pypi_hits) + + terminal_width = None + if sys.stdout.isatty(): + terminal_width = get_terminal_size()[0] + + print_results(hits, terminal_width=terminal_width) + if pypi_hits: + return SUCCESS + return NO_MATCHES_FOUND + + def search(self, query, options): + 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 + + +def transform_hits(hits): + """ + 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() + for hit in hits: + name = hit['name'] + summary = hit['summary'] + version = hit['version'] + + if name not in packages.keys(): + packages[name] = { + 'name': name, + 'summary': summary, + 'versions': [version], + } + else: + packages[name]['versions'].append(version) + + # if this is the highest version, replace summary and score + if version == highest_version(packages[name]['versions']): + packages[name]['summary'] = summary + + return list(packages.values()) + + +def print_results(hits, name_column_width=None, terminal_width=None): + if not hits: + return + if name_column_width is None: + name_column_width = max([ + len(hit['name']) + len(highest_version(hit.get('versions', ['-']))) + for hit in hits + ]) + 4 + + installed_packages = [p.project_name for p in pkg_resources.working_set] + for hit in hits: + name = hit['name'] + summary = hit['summary'] or '' + latest = highest_version(hit.get('versions', ['-'])) + if terminal_width is not 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) + + line = '%-*s - %s' % (name_column_width, + '%s (%s)' % (name, latest), summary) + try: + logger.info(line) + if name in installed_packages: + dist = pkg_resources.get_distribution(name) + with indent_log(): + if dist.version == latest: + logger.info('INSTALLED: %s (latest)', dist.version) + else: + logger.info('INSTALLED: %s', dist.version) + logger.info('LATEST: %s', latest) + except UnicodeEncodeError: + pass + + +def highest_version(versions): + return max(versions, key=parse_version) diff --git a/venv/lib/python3.7/site-packages/pip/_internal/commands/show.py b/venv/lib/python3.7/site-packages/pip/_internal/commands/show.py new file mode 100644 index 0000000..f92c9bc --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/commands/show.py @@ -0,0 +1,168 @@ +from __future__ import absolute_import + +import logging +import os +from email.parser import FeedParser # type: ignore + +from pip._vendor import pkg_resources +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 + +logger = logging.getLogger(__name__) + + +class ShowCommand(Command): + """ + Show information about one or more installed packages. + + The output is in RFC-compliant mail header format. + """ + name = 'show' + usage = """ + %prog [options] ...""" + summary = 'Show information about installed packages.' + ignore_require_venv = True + + def __init__(self, *args, **kw): + super(ShowCommand, self).__init__(*args, **kw) + self.cmd_opts.add_option( + '-f', '--files', + dest='files', + action='store_true', + default=False, + help='Show the full list of installed files for each package.') + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + if not args: + logger.warning('ERROR: Please provide a package name or names.') + return ERROR + query = args + + results = search_packages_info(query) + if not print_results( + results, list_files=options.files, verbose=options.verbose): + return ERROR + return SUCCESS + + +def search_packages_info(query): + """ + Gather details from installed distributions. Print distribution name, + version, location, and installed files. Installed files requires a + pip generated 'installed-files.txt' in the distributions '.egg-info' + directory. + """ + installed = {} + for p in pkg_resources.working_set: + installed[canonicalize_name(p.project_name)] = p + + query_names = [canonicalize_name(name) for name in query] + + for dist in [installed[pkg] for pkg in query_names if pkg in installed]: + package = { + 'name': dist.project_name, + 'version': dist.version, + 'location': dist.location, + 'requires': [dep.project_name for dep in dist.requires()], + } + file_list = None + metadata = None + 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 = [os.path.join(dist.location, p) for p in paths] + file_list = [os.path.relpath(p, dist.location) for p in paths] + + if dist.has_metadata('METADATA'): + metadata = dist.get_metadata('METADATA') + else: + # Otherwise use pip's log for .egg-info's + if dist.has_metadata('installed-files.txt'): + paths = dist.get_metadata_lines('installed-files.txt') + paths = [os.path.join(dist.egg_info, p) for p in paths] + file_list = [os.path.relpath(p, dist.location) for p in paths] + + if dist.has_metadata('PKG-INFO'): + metadata = dist.get_metadata('PKG-INFO') + + if dist.has_metadata('entry_points.txt'): + entry_points = dist.get_metadata_lines('entry_points.txt') + package['entry_points'] = entry_points + + if dist.has_metadata('INSTALLER'): + for line in dist.get_metadata_lines('INSTALLER'): + if line.strip(): + package['installer'] = line.strip() + break + + # @todo: Should pkg_resources.Distribution have a + # `get_pkg_info` method? + feed_parser = FeedParser() + feed_parser.feed(metadata) + pkg_info_dict = feed_parser.close() + for key in ('metadata-version', 'summary', + 'home-page', 'author', 'author-email', 'license'): + package[key] = pkg_info_dict.get(key) + + # It looks like FeedParser cannot deal with repeated headers + classifiers = [] + for line in metadata.splitlines(): + if line.startswith('Classifier: '): + classifiers.append(line[len('Classifier: '):]) + package['classifiers'] = classifiers + + if file_list: + package['files'] = sorted(file_list) + yield package + + +def print_results(distributions, list_files=False, verbose=False): + """ + Print the informations from installed distributions found. + """ + results_printed = False + for i, dist in enumerate(distributions): + results_printed = True + if i > 0: + logger.info("---") + + 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)) + + if verbose: + logger.info("Metadata-Version: %s", + dist.get('metadata-version', '')) + logger.info("Installer: %s", dist.get('installer', '')) + logger.info("Classifiers:") + for classifier in dist.get('classifiers', []): + logger.info(" %s", classifier) + logger.info("Entry-points:") + for entry in dist.get('entry_points', []): + logger.info(" %s", entry.strip()) + if list_files: + logger.info("Files:") + for line in dist.get('files', []): + logger.info(" %s", line.strip()) + if "files" not in dist: + logger.info("Cannot locate installed-files.txt") + return results_printed diff --git a/venv/lib/python3.7/site-packages/pip/_internal/commands/uninstall.py b/venv/lib/python3.7/site-packages/pip/_internal/commands/uninstall.py new file mode 100644 index 0000000..0cd6f54 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/commands/uninstall.py @@ -0,0 +1,78 @@ +from __future__ import absolute_import + +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal.cli.base_command import Command +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.utils.misc import protect_pip_from_modification_on_windows + + +class UninstallCommand(Command): + """ + Uninstall packages. + + pip is able to uninstall most installed packages. Known exceptions are: + + - Pure distutils packages installed with ``python setup.py install``, which + leave behind no metadata to determine what files were installed. + - Script wrappers installed by ``python setup.py develop``. + """ + name = 'uninstall' + usage = """ + %prog [options] ... + %prog [options] -r ...""" + summary = 'Uninstall packages.' + + def __init__(self, *args, **kw): + super(UninstallCommand, self).__init__(*args, **kw) + self.cmd_opts.add_option( + '-r', '--requirement', + dest='requirements', + action='append', + default=[], + metavar='file', + help='Uninstall all the packages listed in the given requirements ' + 'file. This option can be used multiple times.', + ) + self.cmd_opts.add_option( + '-y', '--yes', + dest='yes', + action='store_true', + help="Don't ask for confirmation of uninstall deletions.") + + 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, + ) + 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 + ) + + 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() diff --git a/venv/lib/python3.7/site-packages/pip/_internal/commands/wheel.py b/venv/lib/python3.7/site-packages/pip/_internal/commands/wheel.py new file mode 100644 index 0000000..9c1f149 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/commands/wheel.py @@ -0,0 +1,183 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import logging +import os + +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.operations.prepare import RequirementPreparer +from pip._internal.req import RequirementSet +from pip._internal.req.req_tracker import RequirementTracker +from pip._internal.resolve import Resolver +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.wheel import WheelBuilder + +logger = logging.getLogger(__name__) + + +class WheelCommand(RequirementCommand): + """ + Build Wheel archives for your requirements and dependencies. + + Wheel is a built-package format, and offers the advantage of not + recompiling your software during every install. For more details, see the + wheel docs: https://wheel.readthedocs.io/en/latest/ + + Requirements: setuptools>=0.8, and wheel. + + 'pip wheel' uses the bdist_wheel setuptools extension from the wheel + package to build individual wheels. + + """ + + name = 'wheel' + usage = """ + %prog [options] ... + %prog [options] -r ... + %prog [options] [-e] ... + %prog [options] [-e] ... + %prog [options] ...""" + + summary = 'Build wheels from your requirements.' + + def __init__(self, *args, **kw): + super(WheelCommand, self).__init__(*args, **kw) + + cmd_opts = self.cmd_opts + + cmd_opts.add_option( + '-w', '--wheel-dir', + dest='wheel_dir', + metavar='dir', + default=os.curdir, + help=("Build wheels into , where the default is the " + "current working directory."), + ) + cmd_opts.add_option(cmdoptions.no_binary()) + cmd_opts.add_option(cmdoptions.only_binary()) + cmd_opts.add_option(cmdoptions.prefer_binary()) + cmd_opts.add_option( + '--build-option', + dest='build_options', + metavar='options', + action='append', + help="Extra arguments to be supplied to 'setup.py bdist_wheel'.", + ) + cmd_opts.add_option(cmdoptions.no_build_isolation()) + cmd_opts.add_option(cmdoptions.constraints()) + cmd_opts.add_option(cmdoptions.editable()) + cmd_opts.add_option(cmdoptions.requirements()) + cmd_opts.add_option(cmdoptions.src()) + cmd_opts.add_option(cmdoptions.ignore_requires_python()) + cmd_opts.add_option(cmdoptions.no_deps()) + cmd_opts.add_option(cmdoptions.build_dir()) + cmd_opts.add_option(cmdoptions.progress_bar()) + + cmd_opts.add_option( + '--global-option', + dest='global_options', + action='append', + metavar='options', + help="Extra global options to be supplied to the setup.py " + "call before the 'bdist_wheel' command.") + + cmd_opts.add_option( + '--pre', + action='store_true', + default=False, + help=("Include pre-release and development versions. By default, " + "pip only finds stable versions."), + ) + + cmd_opts.add_option(cmdoptions.no_clean()) + cmd_opts.add_option(cmdoptions.require_hashes()) + + index_opts = cmdoptions.make_option_group( + cmdoptions.index_group, + self.parser, + ) + + self.parser.insert_option_group(0, index_opts) + self.parser.insert_option_group(0, cmd_opts) + + def run(self, options, args): + cmdoptions.check_install_build_global(options) + + index_urls = [options.index_url] + options.extra_index_urls + if options.no_index: + logger.debug('Ignoring indexes: %s', ','.join(index_urls)) + index_urls = [] + + if options.build_dir: + options.build_dir = os.path.abspath(options.build_dir) + + options.src_dir = os.path.abspath(options.src_dir) + + 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) + + with RequirementTracker() as req_tracker, TempDirectory( + options.build_dir, delete=build_delete, kind="wheel" + ) as directory: + + requirement_set = RequirementSet( + require_hashes=options.require_hashes, + ) + + 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, + ) + 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, + ) + wheels_built_successfully = wb.build( + requirement_set.requirements.values(), session=session, + ) + if not wheels_built_successfully: + raise CommandError( + "Failed to build one or more wheels" + ) + except PreviousBuildDirError: + options.no_clean = True + raise + finally: + if not options.no_clean: + requirement_set.cleanup_files() + wheel_cache.cleanup() diff --git a/venv/lib/python3.7/site-packages/pip/_internal/configuration.py b/venv/lib/python3.7/site-packages/pip/_internal/configuration.py new file mode 100644 index 0000000..fe6df9b --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/configuration.py @@ -0,0 +1,387 @@ +"""Configuration management setup + +Some terminology: +- name + As written in config files. +- value + Value associated with a name +- key + Name combined with it's section (section.name) +- variant + A single word describing where the configuration key-value pair came from +""" + +import locale +import logging +import os + +from pip._vendor import six +from pip._vendor.six.moves import configparser + +from pip._internal.exceptions import ( + ConfigurationError, ConfigurationFileCouldNotBeLoaded, +) +from pip._internal.locations import ( + legacy_config_file, new_config_file, running_under_virtualenv, + site_config_files, venv_config_file, +) +from pip._internal.utils.misc import ensure_dir, enum +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import ( # noqa: F401 + Any, Dict, Iterable, List, NewType, Optional, Tuple + ) + + RawConfigParser = configparser.RawConfigParser # Shorthand + Kind = NewType("Kind", str) + +logger = logging.getLogger(__name__) + + +# NOTE: Maybe use the optionx attribute to normalize keynames. +def _normalize_name(name): + # type: (str) -> str + """Make a name consistent regardless of source (environment or file) + """ + name = name.lower().replace('_', '-') + if name.startswith('--'): + name = name[2:] # only prefer long opts + return name + + +def _disassemble_key(name): + # type: (str) -> List[str] + return name.split(".", 1) + + +# The kinds of configurations there are. +kinds = enum( + USER="user", # User Specific + GLOBAL="global", # System Wide + VENV="venv", # Virtual Environment Specific + ENV="env", # from PIP_CONFIG_FILE + ENV_VAR="env-var", # from Environment Variables +) + + +class Configuration(object): + """Handles management of configuration. + + Provides an interface to accessing and managing configuration files. + + This class converts provides an API that takes "section.key-name" style + keys and stores the value associated with it as "key-name" under the + section "section". + + This allows for a clean interface wherein the both the section and the + key-name are preserved in an easy to manage form in the configuration files + and the data stored is also nice. + """ + + def __init__(self, isolated, load_only=None): + # type: (bool, Kind) -> None + super(Configuration, self).__init__() + + _valid_load_only = [kinds.USER, kinds.GLOBAL, kinds.VENV, None] + if load_only not in _valid_load_only: + raise ConfigurationError( + "Got invalid value for load_only - should be one of {}".format( + ", ".join(map(repr, _valid_load_only[:-1])) + ) + ) + self.isolated = isolated # type: bool + self.load_only = load_only # type: Optional[Kind] + + # The order here determines the override order. + self._override_order = [ + kinds.GLOBAL, kinds.USER, kinds.VENV, kinds.ENV, kinds.ENV_VAR + ] + + self._ignore_env_names = ["version", "help"] + + # Because we keep track of where we got the data from + self._parsers = { + variant: [] for variant in self._override_order + } # type: Dict[Kind, List[Tuple[str, RawConfigParser]]] + self._config = { + variant: {} for variant in self._override_order + } # type: Dict[Kind, Dict[str, Any]] + self._modified_parsers = [] # type: List[Tuple[str, RawConfigParser]] + + def load(self): + # type: () -> None + """Loads configuration from configuration files and environment + """ + self._load_config_files() + if not self.isolated: + self._load_environment_vars() + + def get_file_to_edit(self): + # type: () -> Optional[str] + """Returns the file with highest priority in configuration + """ + assert self.load_only is not None, \ + "Need to be specified a file to be editing" + + try: + return self._get_parser_to_modify()[0] + except IndexError: + return None + + def items(self): + # type: () -> Iterable[Tuple[str, Any]] + """Returns key-value pairs like dict.items() representing the loaded + configuration + """ + return self._dictionary.items() + + def get_value(self, key): + # type: (str) -> Any + """Get a value from the configuration. + """ + try: + return self._dictionary[key] + except KeyError: + raise ConfigurationError("No such key - {}".format(key)) + + def set_value(self, key, value): + # type: (str, Any) -> None + """Modify a value in the configuration. + """ + self._ensure_have_load_only() + + fname, parser = self._get_parser_to_modify() + + if parser is not None: + section, name = _disassemble_key(key) + + # Modify the parser and the configuration + if not parser.has_section(section): + parser.add_section(section) + parser.set(section, name, value) + + self._config[self.load_only][key] = value + self._mark_as_modified(fname, parser) + + def unset_value(self, key): + # type: (str) -> None + """Unset a value in the configuration. + """ + self._ensure_have_load_only() + + if key not in self._config[self.load_only]: + raise ConfigurationError("No such key - {}".format(key)) + + fname, parser = self._get_parser_to_modify() + + 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 = six.next(section_iter) + except StopIteration: + val = None + + if val is None: + parser.remove_section(section) + + self._mark_as_modified(fname, parser) + else: + raise ConfigurationError( + "Fatal Internal error [id=1]. Please report as a bug." + ) + + del self._config[self.load_only][key] + + def save(self): + # type: () -> None + """Save the currentin-memory state. + """ + self._ensure_have_load_only() + + for fname, parser in self._modified_parsers: + logger.info("Writing to %s", fname) + + # Ensure directory exists. + ensure_dir(os.path.dirname(fname)) + + with open(fname, "w") as f: + parser.write(f) # type: ignore + + # + # Private routines + # + + def _ensure_have_load_only(self): + # type: () -> None + if self.load_only is None: + raise ConfigurationError("Needed a specific file to be modifying.") + logger.debug("Will be working with %s variant only", self.load_only) + + @property + def _dictionary(self): + # type: () -> Dict[str, Any] + """A dictionary representing the loaded configuration. + """ + # NOTE: Dictionaries are not populated if not loaded. So, conditionals + # are not needed here. + retval = {} + + for variant in self._override_order: + retval.update(self._config[variant]) + + return retval + + def _load_config_files(self): + # type: () -> None + """Loads configuration from configuration 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 " + "environment's PIP_CONFIG_FILE being os.devnull" + ) + return + + for variant, files in config_files.items(): + for fname in files: + # If there's specific variant set in `load_only`, load only + # that variant, not the others. + if self.load_only is not None and variant != self.load_only: + logger.debug( + "Skipping file '%s' (variant: %s)", fname, variant + ) + continue + + parser = self._load_file(variant, fname) + + # Keeping track of the parsers used + self._parsers[variant].append((fname, parser)) + + def _load_file(self, variant, fname): + # type: (Kind, str) -> RawConfigParser + logger.debug("For variant '%s', will try loading '%s'", variant, fname) + parser = self._construct_parser(fname) + + for section in parser.sections(): + items = parser.items(section) + self._config[variant].update(self._normalized_keys(section, items)) + + return parser + + def _construct_parser(self, fname): + # type: (str) -> RawConfigParser + parser = configparser.RawConfigParser() + # If there is no such file, don't bother reading it but create the + # parser anyway, to hold the data. + # Doing this is useful when modifying and saving files, where we don't + # need to construct a parser. + if os.path.exists(fname): + try: + parser.read(fname) + except UnicodeDecodeError: + # See https://github.com/pypa/pip/issues/4963 + raise ConfigurationFileCouldNotBeLoaded( + reason="contains invalid {} characters".format( + locale.getpreferredencoding(False) + ), + fname=fname, + ) + except configparser.Error as error: + # See https://github.com/pypa/pip/issues/4893 + raise ConfigurationFileCouldNotBeLoaded(error=error) + return parser + + def _load_environment_vars(self): + # type: () -> None + """Loads configuration from environment variables + """ + self._config[kinds.ENV_VAR].update( + self._normalized_keys(":env:", self._get_environ_vars()) + ) + + def _normalized_keys(self, section, items): + # type: (str, Iterable[Tuple[str, Any]]) -> Dict[str, Any] + """Normalizes items to construct a dictionary with normalized keys. + + This routine is where the names become keys and are made the same + regardless of source - configuration files or environment. + """ + normalized = {} + for name, val in items: + key = section + "." + _normalize_name(name) + normalized[key] = val + return normalized + + 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(): + should_be_yielded = ( + key.startswith("PIP_") and + key[4:].lower() not in self._ignore_env_names + ) + if should_be_yielded: + yield key[4:].lower(), val + + # XXX: This is patched in the tests. + def _iter_config_files(self): + # type: () -> Iterable[Tuple[Kind, List[str]]] + """Yields variant and configuration files associated with it. + + This should be treated like items of a dictionary. + """ + # SMELL: Move the conditions out of this function + + # environment variables have the lowest priority + config_file = os.environ.get('PIP_CONFIG_FILE', None) + if config_file is not None: + yield kinds.ENV, [config_file] + else: + yield kinds.ENV, [] + + # at the base we have any global configuration + yield kinds.GLOBAL, list(site_config_files) + + # per-user configuration next + should_load_user_config = not self.isolated and not ( + config_file and os.path.exists(config_file) + ) + if should_load_user_config: + # The legacy config file is overridden by the new config file + yield kinds.USER, [legacy_config_file, new_config_file] + + # finally virtualenv configuration first trumping others + if running_under_virtualenv(): + yield kinds.VENV, [venv_config_file] + + def _get_parser_to_modify(self): + # type: () -> Tuple[str, RawConfigParser] + # Determine which parser to modify + parsers = self._parsers[self.load_only] + if not parsers: + # This should not happen if everything works correctly. + raise ConfigurationError( + "Fatal Internal error [id=2]. Please report as a bug." + ) + + # Use the highest priority parser. + return parsers[-1] + + # XXX: This is patched in the tests. + def _mark_as_modified(self, fname, parser): + # type: (str, RawConfigParser) -> None + file_parser_tuple = (fname, parser) + if file_parser_tuple not in self._modified_parsers: + self._modified_parsers.append(file_parser_tuple) diff --git a/venv/lib/python3.7/site-packages/pip/_internal/download.py b/venv/lib/python3.7/site-packages/pip/_internal/download.py new file mode 100644 index 0000000..96f3b65 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/download.py @@ -0,0 +1,921 @@ +from __future__ import absolute_import + +import cgi +import email.utils +import getpass +import json +import logging +import mimetypes +import os +import platform +import re +import shutil +import sys + +from pip._vendor import requests, six, 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 +from pip._vendor.six.moves.urllib.parse import unquote as urllib_unquote +from pip._vendor.urllib3.util import IS_PYOPENSSL + +import pip +from pip._internal.exceptions import HashMismatch, InstallationError +from pip._internal.locations import write_delete_marker_file +from pip._internal.models.index import PyPI +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.logging import indent_log +from pip._internal.utils.misc import ( + ARCHIVE_EXTENSIONS, ask_path_exists, backup_dir, call_subprocess, consume, + display_path, format_size, get_installed_version, rmtree, splitext, + unpack_file, +) +from pip._internal.utils.setuptools_build import SETUPTOOLS_SHIM +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.ui import DownloadProgressProvider +from pip._internal.vcs import vcs + +try: + import ssl # noqa +except ImportError: + ssl = None + +HAS_TLS = (ssl is not None) or IS_PYOPENSSL + +__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'] + + +logger = logging.getLogger(__name__) + + +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 + + return "{data[installer][name]}/{data[installer][version]} {json}".format( + data=data, + json=json.dumps(data, separators=(",", ":"), sort_keys=True), + ) + + +class MultiDomainBasicAuth(AuthBase): + + def __init__(self, prompting=True): + self.prompting = prompting + self.passwords = {} + + def __call__(self, req): + parsed = urllib_parse.urlparse(req.url) + + # Get the netloc without any embedded credentials + netloc = parsed.netloc.rsplit("@", 1)[-1] + + # Set the url of the request to the url without any credentials + req.url = urllib_parse.urlunparse(parsed[:1] + (netloc,) + parsed[2:]) + + # Use any stored credentials that we have for this netloc + username, password = self.passwords.get(netloc, (None, None)) + + # Extract credentials embedded in the url if we have none stored + if username is None: + username, password = self.parse_credentials(parsed.netloc) + + # Get creds from netrc if we still don't have them + if username is None and password is None: + netrc_auth = get_netrc_auth(req.url) + username, password = netrc_auth if netrc_auth else (None, None) + + if username or password: + # Store the username and password + self.passwords[netloc] = (username, password) + + # Send the basic auth with this request + req = HTTPBasicAuth(username or "", password or "")(req) + + # Attach a hook to handle 401 responses + req.register_hook("response", self.handle_401) + + return req + + 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 = six.moves.input("User for %s: " % parsed.netloc) + password = getpass.getpass("Password: ") + + # Store the new username and password to use for future requests + if username or password: + self.passwords[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) + + # Send our new request + new_resp = resp.connection.send(req, **kwargs) + new_resp.history.append(resp) + + return new_resp + + def parse_credentials(self, netloc): + if "@" in netloc: + userinfo = netloc.rsplit("@", 1)[0] + if ":" in userinfo: + user, pwd = userinfo.split(":", 1) + return (urllib_unquote(user), urllib_unquote(pwd)) + return urllib_unquote(userinfo), None + return None, None + + +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 + + def __init__(self, *args, **kwargs): + retries = kwargs.pop("retries", 0) + cache = kwargs.pop("cache", None) + insecure_hosts = kwargs.pop("insecure_hosts", []) + + 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() + + # 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) + + 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.mount("https://{}/".format(host), 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): + """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): + """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): + """ + 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 we have a UNC path, prepend UNC share notation + if netloc: + netloc = '\\\\' + netloc + + path = urllib_request.url2pathname(netloc + path) + return path + + +def path_to_url(path): + """ + Convert a path to a file: URL. The path will be made absolute and have + quoted path parts. + """ + path = os.path.normpath(os.path.abspath(path)) + url = urllib_parse.urljoin('file:', urllib_request.pathname2url(path)) + return url + + +def is_archive_file(name): + """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) + + +def _get_used_vcs_backend(link): + for backend in vcs.backends: + if link.scheme in backend.schemes: + vcs_backend = backend(link.url) + return vcs_backend + + +def is_vcs_url(link): + return bool(_get_used_vcs_backend(link)) + + +def is_file_url(link): + return link.url.lower().startswith('file:') + + +def is_dir_url(link): + """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, link, content_file, hashes, progress_bar): + 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, location, download_dir=None, + session=None, hashes=None, progress_bar="on"): + 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, location, download_dir=None, hashes=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) + + +def _copy_dist_from_dir(link_path, location): + """Copy distribution files in `link_path` to `location`. + + Invoked when user requests to install a local directory. E.g.: + + pip install . + pip install ~/dev/git-repos/python-prompt-toolkit + + """ + + # Note: This is currently VERY SLOW if you have a lot of data in the + # directory, because it copies everything with `shutil.copytree`. + # What it should really do is build an sdist and install that. + # See https://github.com/pypa/pip/issues/2195 + + if os.path.isdir(location): + rmtree(location) + + # build an sdist + setup_py = 'setup.py' + sdist_args = [sys.executable] + sdist_args.append('-c') + sdist_args.append(SETUPTOOLS_SHIM % setup_py) + sdist_args.append('sdist') + sdist_args += ['--dist-dir', location] + logger.info('Running setup.py sdist for %s', link_path) + + with indent_log(): + call_subprocess(sdist_args, cwd=link_path, show_stdout=False) + + # unpack sdist into `location` + sdist = os.path.join(location, os.listdir(location)[0]) + logger.info('Unpacking sdist %s into %s', sdist, location) + unpack_file(sdist, location, content_type=None, link=None) + + +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, location, download_dir=None, + only_download=False, session=None, hashes=None, + progress_bar="on"): + """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 _download_http_url(link, session, temp_dir, hashes, progress_bar): + """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: + type, params = cgi.parse_header(content_disposition) + # We use ``or`` here because we don't want to use an "empty" value + # from the filename param. + filename = params.get('filename') or filename + ext = splitext(filename)[1] + 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): + """ 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.7/site-packages/pip/_internal/exceptions.py b/venv/lib/python3.7/site-packages/pip/_internal/exceptions.py new file mode 100644 index 0000000..f1ca6f3 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/exceptions.py @@ -0,0 +1,268 @@ +"""Exceptions used throughout package""" +from __future__ import absolute_import + +from itertools import chain, groupby, repeat + +from pip._vendor.six import iteritems + + +class PipError(Exception): + """Base pip exception""" + + +class ConfigurationError(PipError): + """General exception in configuration""" + + +class InstallationError(PipError): + """General exception during installation""" + + +class UninstallationError(PipError): + """General exception during uninstallation""" + + +class DistributionNotFound(InstallationError): + """Raised when a distribution cannot be found to satisfy a requirement""" + + +class RequirementsFileParseError(InstallationError): + """Raised when a general error occurs parsing a requirements file line.""" + + +class BestVersionAlreadyInstalled(PipError): + """Raised when the most up-to-date version of a package is already + installed.""" + + +class BadCommand(PipError): + """Raised when virtualenv or a command is not found""" + + +class CommandError(PipError): + """Raised when there is an error in command-line arguments""" + + +class PreviousBuildDirError(PipError): + """Raised when there's a previous conflicting build directory""" + + +class InvalidWheelFilename(InstallationError): + """Invalid wheel filename.""" + + +class UnsupportedWheel(InstallationError): + """Unsupported wheel.""" + + +class HashErrors(InstallationError): + """Multiple HashError instances rolled into one for reporting""" + + def __init__(self): + self.errors = [] + + def append(self, error): + self.errors.append(error) + + def __str__(self): + lines = [] + self.errors.sort(key=lambda e: e.order) + for cls, errors_of_cls in groupby(self.errors, lambda e: e.__class__): + lines.append(cls.head) + lines.extend(e.body() for e in errors_of_cls) + if lines: + return '\n'.join(lines) + + def __nonzero__(self): + return bool(self.errors) + + def __bool__(self): + return self.__nonzero__() + + +class HashError(InstallationError): + """ + A failure to verify a package against known-good hashes + + :cvar order: An int sorting hash exception classes by difficulty of + recovery (lower being harder), so the user doesn't bother fretting + about unpinned packages when he has deeper issues, like VCS + dependencies, to deal with. Also keeps error reports in a + deterministic order. + :cvar head: A section heading for display above potentially many + exceptions of this kind + :ivar req: The InstallRequirement that triggered this error. This is + pasted on after the exception is instantiated, because it's not + typically available earlier. + + """ + req = None + head = '' + + def body(self): + """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 + + """ + return ' %s' % self._requirement_name() + + def __str__(self): + return '%s\n%s' % (self.head, self.body()) + + def _requirement_name(self): + """Return a description of the requirement that triggered me. + + This default implementation returns long description of the req, with + line numbers + + """ + return str(self.req) if self.req else 'unknown package' + + +class VcsHashUnsupported(HashError): + """A hash was provided for a version-control-system-based requirement, but + we don't have a method for hashing those.""" + + order = 0 + head = ("Can't verify hashes for these requirements because we don't " + "have a way to hash version control repositories:") + + +class DirectoryUrlHashUnsupported(HashError): + """A hash was provided for a version-control-system-based requirement, but + we don't have a method for hashing those.""" + + order = 1 + head = ("Can't verify hashes for these file:// requirements because they " + "point to directories:") + + +class HashMissing(HashError): + """A hash was needed for a requirement but is absent.""" + + order = 2 + head = ('Hashes are required in --require-hashes mode, but they are ' + 'missing from some requirements. Here is a list of those ' + 'requirements along with the hashes their downloaded archives ' + 'actually had. Add lines like these to your requirements files to ' + 'prevent tampering. (If you did not enable --require-hashes ' + 'manually, note that it turns on automatically when any package ' + 'has a hash.)') + + def __init__(self, gotten_hash): + """ + :param gotten_hash: The hash of the (possibly malicious) archive we + just downloaded + """ + self.gotten_hash = gotten_hash + + def body(self): + # Dodge circular import. + from pip._internal.utils.hashes import FAVORITE_HASH + + package = None + if self.req: + # In the case of URL-based requirements, display the original URL + # seen in the requirements file rather than the package name, + # so the output can be directly copied into the requirements file. + package = (self.req.original_link if self.req.original_link + # 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) + + +class HashUnpinned(HashError): + """A requirement had a hash specified but was not pinned to a specific + version.""" + + order = 3 + head = ('In --require-hashes mode, all requirements must have their ' + 'versions pinned with ==. These do not:') + + +class HashMismatch(HashError): + """ + Distribution file hash values don't match. + + :ivar package_name: The name of the package that triggered the hash + mismatch. Feel free to write to this after the exception is raise to + improve its error message. + + """ + order = 4 + head = ('THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS ' + 'FILE. If you have updated the package versions, please update ' + 'the hashes. Otherwise, examine the package contents carefully; ' + 'someone may have tampered with them.') + + def __init__(self, allowed, gots): + """ + :param allowed: A dict of algorithm names pointing to lists of allowed + hex digests + :param gots: A dict of algorithm names pointing to hashes we + actually got from the files under suspicion + """ + self.allowed = allowed + self.gots = gots + + def body(self): + return ' %s:\n%s' % (self._requirement_name(), + self._hash_comparison()) + + def _hash_comparison(self): + """ + Return a comparison of actual and expected hash values. + + Example:: + + Expected sha256 abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde + or 123451234512345123451234512345123451234512345 + Got bcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdef + + """ + def hash_then_or(hash_name): + # 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 = [] + for hash_name, expecteds in iteritems(self.allowed): + prefix = hash_then_or(hash_name) + lines.extend((' Expected %s %s' % (next(prefix), e)) + for e in expecteds) + lines.append(' Got %s\n' % + self.gots[hash_name].hexdigest()) + prefix = ' or' + return '\n'.join(lines) + + +class UnsupportedPythonVersion(InstallationError): + """Unsupported python version according to Requires-Python package + metadata.""" + + +class ConfigurationFileCouldNotBeLoaded(ConfigurationError): + """When there are errors while loading a configuration file + """ + + def __init__(self, reason="could not be loaded", fname=None, error=None): + super(ConfigurationFileCouldNotBeLoaded, self).__init__(error) + self.reason = reason + self.fname = fname + self.error = error + + def __str__(self): + 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) + return "Configuration file {}{}".format(self.reason, message_part) diff --git a/venv/lib/python3.7/site-packages/pip/_internal/index.py b/venv/lib/python3.7/site-packages/pip/_internal/index.py new file mode 100644 index 0000000..8c2f24f --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/index.py @@ -0,0 +1,899 @@ +"""Routines related to PyPI, indexes""" +from __future__ import absolute_import + +import cgi +import itertools +import logging +import mimetypes +import os +import posixpath +import re +import sys +from collections import namedtuple + +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 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 HAS_TLS, is_url, path_to_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.index import PyPI +from pip._internal.models.link import Link +from pip._internal.pep425tags import get_supported +from pip._internal.utils.compat import ipaddress +from pip._internal.utils.deprecation import deprecated +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ( + ARCHIVE_EXTENSIONS, SUPPORTED_EXTENSIONS, normalize_path, + remove_auth_from_url, +) +from pip._internal.utils.packaging import check_requires_python +from pip._internal.wheel import Wheel, wheel_ext + +__all__ = ['FormatControl', '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", "*", "*"), +] + + +logger = logging.getLogger(__name__) + + +def _get_content_type(url, session): + """Get the Content-Type of the given url, using a HEAD request""" + scheme, netloc, path, query, fragment = urllib_parse.urlsplit(url) + if scheme not in {'http', 'https'}: + # FIXME: some warning or something? + # assertion error? + return '' + + resp = session.head(url, allow_redirects=True) + resp.raise_for_status() + + return resp.headers.get("Content-Type", "") + + +def _handle_get_page_fail(link, reason, url, meth=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): + if session is None: + raise TypeError( + "_get_html_page() missing 1 required keyword argument: 'session'" + ) + + url = link.url + url = url.split('#', 1)[0] + + # Check for VCS schemes that do not support lookup as web pages. + from pip._internal.vcs import VcsSupport + for scheme in VcsSupport.schemes: + if url.lower().startswith(scheme) and url[len(scheme)] in '+:': + logger.debug('Cannot look at %s URL %s', scheme, link) + return None + + try: + filename = link.filename + for bad_ext in ARCHIVE_EXTENSIONS: + if filename.endswith(bad_ext): + content_type = _get_content_type(url, session=session) + if content_type.lower().startswith('text/html'): + break + else: + logger.debug( + 'Skipping page %s because of Content-Type: %s', + link, + content_type, + ) + return + + logger.debug('Getting page %s', url) + + # Tack index.html onto file:// URLs that point to directories + (scheme, netloc, path, params, query, fragment) = \ + 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) + + 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. + content_type = resp.headers.get('Content-Type', 'unknown') + if not content_type.lower().startswith("text/html"): + logger.debug( + 'Skipping page %s because of Content-Type: %s', + link, + content_type, + ) + return + + inst = HTMLPage(resp.content, resp.url, resp.headers) + except requests.HTTPError as exc: + _handle_get_page_fail(link, exc, url) + except SSLError as exc: + reason = "There was a problem confirming the ssl certificate: " + reason += str(exc) + _handle_get_page_fail(link, reason, url, meth=logger.info) + except requests.ConnectionError as exc: + _handle_get_page_fail(link, "connection error: %s" % exc, url) + except requests.Timeout: + _handle_get_page_fail(link, "timed out", url) + else: + return inst + + +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, find_links, index_urls, allow_all_prereleases=False, + trusted_hosts=None, process_dependency_links=False, + session=None, format_control=None, platform=None, + versions=None, abi=None, implementation=None, + prefer_binary=False): + """Create a PackageFinder. + + :param format_control: A FormatControl object or None. Used to control + the selection of source packages / binary packages when consulting + the index and links. + :param platform: A string or None. If None, searches for packages + that are supported by the current system. Otherwise, will find + packages that can be built on the platform passed in. These + packages will only be downloaded for distribution: they will + not be built locally. + :param versions: A list of strings or None. This is passed directly + to pep425tags.py in the get_supported() method. + :param abi: A string or None. This is passed directly + to pep425tags.py in the get_supported() method. + :param implementation: A string or None. This is passed directly + to pep425tags.py in the get_supported() method. + """ + if session is None: + raise TypeError( + "PackageFinder() missing 1 required keyword argument: " + "'session'" + ) + + # Build find_links. If an argument starts with ~, it may be + # a local file relative to a home directory. So try normalizing + # it and if it exists, use the normalized version. + # This is deliberately conservative - it might be fine just to + # blindly normalize anything starting with a ~... + self.find_links = [] + for link in find_links: + if link.startswith('~'): + new_link = normalize_path(link) + if os.path.exists(new_link): + link = new_link + self.find_links.append(link) + + self.index_urls = index_urls + self.dependency_links = [] + + # These are boring links that have already been logged somehow: + self.logged_links = set() + + self.format_control = format_control or FormatControl(set(), set()) + + # Domains that we won't emit warnings for when not using HTTPS + self.secure_origins = [ + ("*", host, "*") + for host in (trusted_hosts if trusted_hosts else []) + ] + + # Do we want to allow _all_ pre-releases? + self.allow_all_prereleases = allow_all_prereleases + + # Do we process dependency links? + self.process_dependency_links = process_dependency_links + + # The Session we'll use to make requests + self.session = session + + # The valid tags to check potential found wheel candidates against + self.valid_tags = get_supported( + versions=versions, + platform=platform, + abi=abi, + impl=implementation, + ) + + # Do we prefer old, but valid, binary dist over new source dist + self.prefer_binary = prefer_binary + + # If we don't have TLS enabled, then WARN if anyplace we're looking + # relies on TLS. + if not HAS_TLS: + for link in itertools.chain(self.index_urls, self.find_links): + parsed = urllib_parse.urlparse(link) + if parsed.scheme == "https": + logger.warning( + "pip is configured with locations that require " + "TLS/SSL, however the ssl module in Python is not " + "available." + ) + break + + def get_formatted_locations(self): + lines = [] + if self.index_urls and self.index_urls != [PyPI.simple_url]: + lines.append( + "Looking in indexes: {}".format(", ".join( + remove_auth_from_url(url) for url in self.index_urls)) + ) + if self.find_links: + lines.append( + "Looking in links: {}".format(", ".join(self.find_links)) + ) + return "\n".join(lines) + + def add_dependency_links(self, links): + # FIXME: this shouldn't be global list this, it should only + # apply to requirements of the package that specifies the + # dependency_links value + # FIXME: also, we should track comes_from (i.e., use Link) + if self.process_dependency_links: + deprecated( + "Dependency Links processing has been deprecated and will be " + "removed in a future release.", + replacement="PEP 508 URL dependencies", + gone_in="18.2", + issue=4187, + ) + self.dependency_links.extend(links) + + @staticmethod + def _sort_locations(locations, expand_dir=False): + """ + 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) + 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 _candidate_sort_key(self, candidate): + """ + Function used to generate link sort key for link tuples. + The greater the return value, the more preferred it is. + If not finding wheels, then 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.valid_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 + """ + support_num = len(self.valid_tags) + build_tag = tuple() + binary_preference = 0 + if candidate.location.is_wheel: + # can raise InvalidWheelFilename + wheel = Wheel(candidate.location.filename) + if not wheel.supported(self.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(self.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) + return (binary_preference, candidate.version, build_tag, pri) + + def _validate_secure_origin(self, logger, location): + # 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 (SECURE_ORIGINS + self.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) + else secure_origin[1].decode("utf8") + ) + 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 _get_index_urls_locations(self, project_name): + """Returns the locations found via self.index_urls + + Checks the url_name on the main (first in the list) index and + use this url_name to produce all locations + """ + + def mkurl_pypi_url(url): + loc = posixpath.join( + url, + urllib_parse.quote(canonicalize_name(project_name))) + # For maximum compatibility with easy_install, ensure the path + # ends in a trailing slash. Although this isn't in the spec + # (and PyPI can handle it without the slash) some other index + # implementations might break if they relied on easy_install's + # behavior. + if not loc.endswith('/'): + loc = loc + '/' + return loc + + return [mkurl_pypi_url(url) for url in self.index_urls] + + def find_all_candidates(self, project_name): + """Find all available InstallationCandidate for project_name + + This checks index_urls, find_links and dependency_links. + All versions found are returned as an InstallationCandidate list. + + See _link_package_versions for details on which files are accepted + """ + index_locations = self._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, + ) + dep_file_loc, dep_url_loc = self._sort_locations(self.dependency_links) + + file_locations = (Link(url) for url in itertools.chain( + index_file_loc, fl_file_loc, dep_file_loc, + )) + + # We trust every url that the user has given us whether it was given + # via --index-url or --find-links + # We explicitly do not trust links that came from dependency_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), + (Link(url) for url in dep_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) + + canonical_name = canonicalize_name(project_name) + formats = self.format_control.get_allowed_formats(canonical_name) + search = Search(project_name, canonical_name, formats) + find_links_versions = self._package_versions( + # We trust every directly linked archive in find_links + (Link(url, '-f') for url in self.find_links), + search + ) + + 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(page.iter_links(), search) + ) + + dependency_versions = self._package_versions( + (Link(url) for url in self.dependency_links), search + ) + if dependency_versions: + logger.debug( + 'dependency_links found: %s', + ', '.join([ + version.location.url for version in dependency_versions + ]) + ) + + file_versions = self._package_versions(file_locations, search) + if file_versions: + file_versions.sort(reverse=True) + logger.debug( + 'Local files found: %s', + ', '.join([ + url_to_path(candidate.location.url) + for candidate in file_versions + ]) + ) + + # This is an intentional priority ordering + return ( + file_versions + find_links_versions + page_versions + + dependency_versions + ) + + def find_requirement(self, req, upgrade): + """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 + """ + all_candidates = self.find_all_candidates(req.name) + + # Filter out anything which doesn't match our specifier + compatible_versions = set( + req.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 all_candidates], + prereleases=( + self.allow_all_prereleases + if self.allow_all_prereleases else None + ), + ) + ) + applicable_candidates = [ + # Again, converting to str to deal with debundling. + c for c in all_candidates if str(c.version) in compatible_versions + ] + + if applicable_candidates: + best_candidate = max(applicable_candidates, + key=self._candidate_sort_key) + else: + best_candidate = None + + if req.satisfied_by is not None: + installed_version = parse_version(req.satisfied_by.version) + else: + installed_version = 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, + ', '.join( + sorted( + {str(c.version) for c in all_candidates}, + key=parse_version, + ) + ) + ) + + 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, + ', '.join(sorted(compatible_versions, key=parse_version)) or + "none", + ) + raise BestVersionAlreadyInstalled + + logger.debug( + 'Using version %s (newest of versions: %s)', + best_candidate.version, + ', '.join(sorted(compatible_versions, key=parse_version)) + ) + return best_candidate.location + + def _get_pages(self, locations, project_name): + """ + Yields (page, page_url) from the given locations, skipping + locations that have errors. + """ + seen = set() + for location in locations: + if location in seen: + continue + seen.add(location) + + page = self._get_page(location) + if page is None: + continue + + yield page + + _py_version_re = re.compile(r'-py([123]\.?[0-9]?)$') + + def _sort_links(self, links): + """ + Returns elements of links in order, non-egg links first, egg links + second, while eliminating duplicates + """ + eggs, no_eggs = [], [] + seen = set() + 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 _package_versions(self, links, search): + result = [] + for link in self._sort_links(links): + v = self._link_package_versions(link, search) + if v is not None: + result.append(v) + return result + + def _log_skipped_link(self, link, reason): + if link not in self.logged_links: + logger.debug('Skipping link %s; %s', link, reason) + self.logged_links.add(link) + + def _link_package_versions(self, link, search): + """Return an InstallationCandidate or None""" + version = None + if link.egg_fragment: + egg_info = link.egg_fragment + ext = link.ext + else: + egg_info, ext = link.splitext() + if not ext: + self._log_skipped_link(link, 'not a file') + return + if ext not in SUPPORTED_EXTENSIONS: + self._log_skipped_link( + link, 'unsupported archive format: %s' % ext, + ) + return + if "binary" not in search.formats and ext == wheel_ext: + self._log_skipped_link( + link, 'No binaries permitted for %s' % search.supplied, + ) + return + if "macosx10" in link.path and ext == '.zip': + self._log_skipped_link(link, 'macosx10 one') + return + if ext == wheel_ext: + try: + wheel = Wheel(link.filename) + except InvalidWheelFilename: + self._log_skipped_link(link, 'invalid wheel filename') + return + if canonicalize_name(wheel.name) != search.canonical: + self._log_skipped_link( + link, 'wrong project name (not %s)' % search.supplied) + return + + if not wheel.supported(self.valid_tags): + self._log_skipped_link( + link, 'it is not compatible with this Python') + return + + version = wheel.version + + # This should be up by the search.ok_binary check, but see issue 2700. + if "source" not in search.formats and ext != wheel_ext: + self._log_skipped_link( + link, 'No sources permitted for %s' % search.supplied, + ) + return + + if not version: + version = egg_info_matches(egg_info, search.supplied, link) + if version is None: + self._log_skipped_link( + link, 'Missing project version for %s' % search.supplied) + return + + match = self._py_version_re.search(version) + if match: + version = version[:match.start()] + py_version = match.group(1) + if py_version != sys.version[:3]: + self._log_skipped_link( + link, 'Python version is incorrect') + return + try: + support_this_python = check_requires_python(link.requires_python) + except specifiers.InvalidSpecifier: + logger.debug("Package %s has an invalid Requires-Python entry: %s", + link.filename, link.requires_python) + support_this_python = True + + if not support_this_python: + logger.debug("The package %s is incompatible with the python" + "version in use. Acceptable python versions are:%s", + link, link.requires_python) + return + logger.debug('Found link %s, version: %s', link, version) + + return InstallationCandidate(search.supplied, version, link) + + def _get_page(self, link): + return _get_html_page(link, session=self.session) + + +def egg_info_matches( + egg_info, search_name, link, + _egg_info_re=re.compile(r'([a-z0-9_.]+)-([a-z0-9_.!+-]+)', re.I)): + """Pull the version part out of a string. + + :param egg_info: The string to parse. E.g. foo-2.1 + :param search_name: The name of the package this belongs to. None to + infer the name. Note that this cannot unambiguously parse strings + like foo-2-2 which might be foo, 2-2 or foo-2, 2. + :param link: The link the string came from, for logging on failure. + """ + match = _egg_info_re.search(egg_info) + if not match: + logger.debug('Could not parse version from link: %s', link) + return None + if search_name is None: + full_match = match.group(0) + return full_match.split('-', 1)[-1] + name = match.group(0).lower() + # To match the "safe" name that pkg_resources creates: + name = name.replace('_', '-') + # project name and version must be separated by a dash + look_for = search_name.lower() + "-" + if name.startswith(look_for): + return match.group(0)[len(look_for):] + else: + return None + + +def _determine_base_url(document, page_url): + """Determine the HTML document's base URL. + + This looks for a ```` 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 + + +_CLEAN_LINK_RE = re.compile(r'[^a-z0-9$&+,/:;=?@.#%_\\|-]', re.I) + + +def _clean_link(url): + """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).""" + return _CLEAN_LINK_RE.sub(lambda match: '%%%2x' % ord(match.group(0)), url) + + +class HTMLPage(object): + """Represents one page, along with its URL""" + + def __init__(self, content, url, headers=None): + self.content = content + self.url = url + self.headers = headers + + def __str__(self): + return self.url + + def iter_links(self): + """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"): + if anchor.get("href"): + href = anchor.get("href") + url = _clean_link(urllib_parse.urljoin(base_url, href)) + pyrequire = anchor.get('data-requires-python') + pyrequire = unescape(pyrequire) if pyrequire else None + yield Link(url, self.url, requires_python=pyrequire) + + +Search = namedtuple('Search', 'supplied canonical formats') +"""Capture key aspects of a search. + +:attribute supplied: The user supplied package. +:attribute canonical: The canonical package name. +:attribute formats: The formats allowed for this package. Should be a set + with 'binary' or 'source' or both in it. +""" diff --git a/venv/lib/python3.7/site-packages/pip/_internal/locations.py b/venv/lib/python3.7/site-packages/pip/_internal/locations.py new file mode 100644 index 0000000..183aaa3 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/locations.py @@ -0,0 +1,194 @@ +"""Locations where we look for configs, install stuff, etc""" +from __future__ import absolute_import + +import os +import os.path +import platform +import site +import sys +import sysconfig +from distutils import sysconfig as distutils_sysconfig +from distutils.command.install import SCHEME_KEYS # type: ignore + +from pip._internal.utils import appdirs +from pip._internal.utils.compat import WINDOWS, expanduser + +# Application Directories +USER_CACHE_DIR = appdirs.user_cache_dir("pip") + + +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): + """ + 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) + + +def running_under_virtualenv(): + """ + Return True if we're running inside a virtualenv, False otherwise. + + """ + if hasattr(sys, 'real_prefix'): + return True + elif sys.prefix != getattr(sys, "base_prefix", sys.prefix): + return True + + return False + + +def virtualenv_no_global(): + """ + 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 + + +if running_under_virtualenv(): + src_prefix = os.path.join(sys.prefix, 'src') +else: + # FIXME: keep src in cwd for now (it is not a temporary folder) + try: + src_prefix = os.path.join(os.getcwd(), 'src') + except OSError: + # In case the current working directory has been renamed or deleted + sys.exit( + "The folder you are executing pip from can no longer be found." + ) + +# under macOS + virtualenv sys.prefix is not properly resolved +# it is something like /path/to/python/bin/.. +# Note: using realpath due to tmp dirs on OSX being symlinks +src_prefix = os.path.abspath(src_prefix) + +# FIXME doesn't account for venv linked to global site-packages + +site_packages = sysconfig.get_path("purelib") +# This is because of a bug in PyPy's sysconfig module, see +# https://bitbucket.org/pypy/pypy/issues/2506/sysconfig-returns-incorrect-paths +# for more information. +if platform.python_implementation().lower() == "pypy": + site_packages = distutils_sysconfig.get_python_lib() +try: + # Use getusersitepackages if this is present, as it ensures that the + # value is initialised properly. + user_site = site.getusersitepackages() +except AttributeError: + user_site = site.USER_SITE +user_dir = expanduser('~') +if WINDOWS: + bin_py = os.path.join(sys.prefix, 'Scripts') + bin_user = os.path.join(user_site, 'Scripts') + # buildout uses 'bin' on Windows too? + if not os.path.exists(bin_py): + bin_py = os.path.join(sys.prefix, 'bin') + bin_user = os.path.join(user_site, 'bin') + + config_basename = 'pip.ini' + + legacy_storage_dir = os.path.join(user_dir, 'pip') + legacy_config_file = os.path.join( + legacy_storage_dir, + config_basename, + ) +else: + bin_py = os.path.join(sys.prefix, 'bin') + bin_user = os.path.join(user_site, 'bin') + + config_basename = 'pip.conf' + + legacy_storage_dir = os.path.join(user_dir, '.pip') + legacy_config_file = os.path.join( + legacy_storage_dir, + config_basename, + ) + # Forcing to use /usr/local/bin for standard macOS framework installs + # Also log to ~/Library/Logs/ for use with the Console.app log viewer + if sys.platform[:6] == 'darwin' and sys.prefix[:16] == '/System/Library/': + bin_py = '/usr/local/bin' + +site_config_files = [ + os.path.join(path, config_basename) + for path in appdirs.site_config_dirs('pip') +] + +venv_config_file = os.path.join(sys.prefix, config_basename) +new_config_file = os.path.join(appdirs.user_config_dir("pip"), config_basename) + + +def distutils_scheme(dist_name, user=False, home=None, root=None, + isolated=False, prefix=None): + """ + 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} + dist_args.update(extra_dist_args) + + d = Distribution(dist_args) + d.parse_config_files() + i = d.get_command_obj('install', create=True) + # 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. + assert not (user and prefix), "user={} prefix={}".format(user, prefix) + i.user = user or i.user + if user: + i.prefix = "" + i.prefix = prefix or i.prefix + i.home = home or i.home + i.root = root or i.root + i.finalize_options() + for key in SCHEME_KEYS: + scheme[key] = getattr(i, 'install_' + key) + + # install_lib specified in setup.cfg should install *everything* + # into there (i.e. it takes precedence over both purelib and + # 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 + 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, + 'include', + 'site', + 'python' + sys.version[:3], + dist_name, + ) + + if root is not None: + path_no_drive = os.path.splitdrive( + os.path.abspath(scheme["headers"]))[1] + scheme["headers"] = os.path.join( + root, + path_no_drive[1:], + ) + + return scheme diff --git a/venv/lib/python3.7/site-packages/pip/_internal/models/__init__.py b/venv/lib/python3.7/site-packages/pip/_internal/models/__init__.py new file mode 100644 index 0000000..7855226 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/models/__init__.py @@ -0,0 +1,2 @@ +"""A package that contains models that represent entities. +""" diff --git a/venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..55cde0e48d989942b40bc7fe307d7b3b5d603899 GIT binary patch literal 269 zcmXwzO-{ow5QUv?s4DdYY`pEFb)jmZ65{UwY+zL(Sx!7nOdZD>PXpu(T!bri%Pm+j zX~mP?{Cta<_c$Jp1ncWOf4$@W(=Y$Zc(`Y$Ar~t)!e-B6GU%=!WHiOjlpv`xB#S1H zaUsdNvEb7QB1D7)fh60JgESjGO|rw8*0w3M{uVgkv&Zs_Dxzx*foct^ZR0IqQgx+@ zi>TM#`fdKc*xD|w7A;fjN5Vf6;-L7^ELgfMiEj=|-NeUI9qN+me0U<;Wz$rqq+}OL#*7?BpF72|M zTB#TK4{+o!<%&4)7dSCac3UJWMw-csV|!-ao9y;_9R&9I_QAWK1fd`HWnnIWXW)7r z0!JK6l;N0Qi-~kHH+C_4j=00!GsIoto;tC|y*DWEf58b9;L0nR(gMKBOL4NxwBUP1 z25aI~dYtBo-L)`h4)huTfnv;2OgN66b2Px5aObQYyWHj88H&AgX2f*swJ4R)A~(9v`ek7NrA+o$lf{r7A`uF;%Z-i%x{n&`Z@?fVM1>y1mNN<5DPPtE$?R!aau4z^z;@ZB$ zebT|pczX9r-NHpv3AP8o?9&6^1J^4MIR0u`1_c_Xzd1F((_s6`8`nPGQ=iuRmoeA@ z!hFy^W9A>qR1Y$!YZu`Bgnx>avnC>V}SDs|ZCsO;F+H(nOdpoWv}rk@?FPt8e} Gbe%sDi62b> literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/format_control.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/format_control.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..84979139e8075296b3232f16ab402e2c10ffdbaa GIT binary patch literal 2439 zcmai0&2Jk;6rb5$Zyd)-n>G}oqOzc(VwBpYF4h>@@7LFV`m@T| z-?TYx9u^PKO@Ki%$rCo<9nRS|Oghp%V$xO4q1$n#_akdmo`H)sc(ELXX_m%On8afx z(r}<6Iyr4F77x%(8-rpUE?LKs98#7gBpvaNCo9rFVx5YdlU2;VoR>AsbE+yAWc`R8 z^3J?mluMx1!9l6Ld4I%Ht$X zH)xLwpzCZ9?DXQO7YxH_Gu%)n2(=30)Z}53DA}w9Xy0~&FzCiAkwJ`0VPf`HgE+?~ zy_E+>%Af*tD{iJr?M7;t2YD|uDoA3JD=0{@S3!nB zmpYrl_i3^hWT~3k0AB~|iu77>d3L5W2y>X4#{<<29z%>)CJ(Z%6-m@U?S@f)`mq58 zsx(d+D~mq9G-Nf{iF4ST?gbn1wn}GrGBO6=wL^{^4awj$)6UdeaqWmAPmN{={UN$p z#V`Q|HmiCmXNN3xCVavKpE#EG&XneW1`1-#+YPsH@xjG>nu+x|4fS5JK$c85IQEQ6 zy1D|<+Q;x0)4(=+zS|n=cstBhYdh4fZk9-;O>59=MIQ{s{qg<&ot=AKIW`~P+tzn? z^YP#g+D6)X+#1Hi+fyLi{^*nS-sWh1gNU|^IL(z#!=yFHq)H4V6QslxWzFGUQ59f{ zb0HRBhoQt`e1(s%okMH$lqn+bP@{R~sX8_j)`z$HY?IIqPjHef;|P))j-CTYQL%8b zA6yReMD>MGTS8pI+F0p)ymC=FF`QFPfwDm=RUbq339nCs!1W@Ir&={}yh3NHgt+ow zI*B1dlG;Wy1 z&cxmH^$!#0n4d5X=gnqEIwz>36IY@iyR?(;>+DzOb0$69n$vZ{`d0l3+g+QuU$dX@ z9(WT^dYg_;PvvYq%|SclIB||E6VFQI$4cj2aLr|`(j z7hQU-7p5{%Vlc`_VIol5l95#AO$aqNFfgaaYrKkIjjuT6Orv8dHCt^VHfmv_W;ltBj;Hkm$;GO?M7WM<5E!*0#$VcFo~ir#1`;W=5;ZL z%9lk*Uit@Pi;-TU71f)fjz>F>qk+PMDod+x(&4)_P>#PaP=VBhATrQg#!&S=Uh}Fh zeslG!)w(@xH@xCHYJOAT36z;`mTxznzUC;86I14lpRM;*l-nCG=&&knC9Zx}e$N+_ Ki?$Zm-G2bahhzW% literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/index.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/index.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e2aee9f539347812080ef932a343b3c7182e0492 GIT binary patch literal 1173 zcmZuxPjAyO6t|r;O-nX5Hg;efa-@efgNZ*w2q8e4c9|yFDMGT+*lp9fNwD3rMZIm( zF7O?;BVWl^xbPJ?@tm$~NIdC1zh}qq&+q5kfqdQUefsGj^uq=Valv^5s$PI$ zh+%=oI3^hFAx4;Uj+n!pGbeVr%UsrA-Zv6Az;80Y_C416h&t_Ga2s{7X_SdnJhjn6 zpkgiR5iA_Vn4y?396J}NkLwzKT<1PVapMBHDE1(uXM)2dJx&IEKWF@;+WWvu$raDF z3X|~qD6G%IBxhkMi)qHV3VEV3F2f{Exl*AnLY}j-$lzW(1W6a|*ma@mJp>wQJVR&X zl3XE-X5dptyO)g_zQQ99BGAhwg9v=T_DSuxW(0QH3_;t@f$>x}E(JGkd0J+jJEox~ zC706HGCrkQo@q*rGm*jsU_{oVHE70%NR=Yf#>=@DMQWBPY|(xp;R`)9?RjRqX?&Z# z_SX8D;8f{C0$7w4<0Q*Fj&T(ied$A0c^3?D)1ovLiBgn)N56}xl-V@VJenpl>KB4> zsiN^PN*|YWx7r59bo6v;qMg?FHUdA41fP+SL|2EOx1wtvY-+|cGzS4J~Y8i}1 zmq5XY05Jq0#|IrpwqV~h0hkd`T~FO1a>Z`C7CLzk+__n^p6y{BRMkar_2AzYZlm65 zTGsMp%z?Ewr7+h7@TMl9^z$SU*C$O1(5IBvbJqERy*b_~7Xl9cw$Qzk2}VJp}T)bPB(dLUvVl(j6C5C<7qC+msfeIlNxc8}U@nU$T36dbn@=BS>w% bo9S*)HvX$QSg)}i(EbMn&dNH$Z9?!LL99F2 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/link.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/link.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3004c1e325126274fcbae309b92a2cf389518dac GIT binary patch literal 4771 zcmb_f&2tmU6`!6NeOQ(a7%&*TyAxQ0wZRhDm<=12-M}vS0v7?2N@*d(NZqo=o)6JI zvaw3eVWDa-n|~o?=azqIt~qhv6Q}%Mk0l{6m8B|U&(oXk*ZsaQ%#7a}yugbu4PF$b7gl|Wvxi1y;uW|UYZaE}I-XPl$YjS$+HMlNT^ZoB zs5*h4i029L6Mqytw>%~I?KlLvxaU9jBaBaMw}l8?5H)GL!9%LhqkaMq28mxcIjdWI z@du;DxW(<46Lp*Cc>bkP&t>A(^P<2fcz{fiz9nS`Kf(YKZeoMd`^$f=+QG6J&w_{d|r>9(4!w=^dv?< z=AY=%S>O);g~m?-KgZ8&{50@S`GUshfM4JjHGbv?!#3(?Vctq=-}R%--d7JqM+zmP zL^+E8->2HVJ3NQ{li3%n2^-= z{>2PKGb4uZ{TIWJg8?UQIZ0bMP$cfkrf@p3A0>i2N$f1PrDzQZNU_Rrbu$iya!Jqe z9sNipUW9G1?e8AlyL+GXM<7X|xoGQbd&+6W-H2auV(F+v`q6rIxU&?`x;~_FJ3C1` zj>fltsEM6s93`F~VV&Of>4SqcOZWAfr%osmk9&#dw0seOkLrk~51bF#kotb)-2e8z zvvPH{>O5-u$_c$4ry)kvPGbjdq>YvaVl8E2jqT$l5UbHm1no%1B+au(NWAq+4)o;Bt#9o0J0-|`Ys z+wx?s6$e~MRSVm-=9P|ny?1@%^7cxL_tdqOExG(W>4lf^tVgv+wT|Ce(h(2@ORJwZ z+MC_RIt}U)UQi2TE&^4fV5oL>B#NbR6t5y+OqE#C%(Fb3HcQNAy{WrIHc+97 zc-D^zNGWq0uet$%;5Xz9N1ALHv&JrqY;GcLj14BM+@jPVyw6(JtntuD^vDZTOOCIK zz1BPFEDnr#;NveAR3$Zf(+kR3)ESL${M*`Snfb_&sf7@(n3AMVP1%t%Kr(Qgh6=6= z0$3j(ii~bRxw2^k&X~ROfqI%`s2yoZ8fxu|Ku9l=yJD{OCT`FgXF=W6Tq;bnew!`4 zE>WLccLmE8ZDx#&navE@jmiLpnfGxyo!+%DTScP&7cSbKKg+RIU8+Gm}` zzPW3IGT*oN*{^ilNcSN0g1) zXyp8n(KwsSd?ksfV#zc3k!J}|#JtC2dDU!-P}~GX<}b51siPws{~*S%K7g@22adPi z;hI@(jO#E)WUqm36A}Y=ug-~k)j5Yr8lS5IE=1$Xor`qu42k2|ll3-lD66<9(gyw#Jv>hf{7Hx8s zEdBGHFroFJqei_W*|awNkYFetW&g0meTt7k)>H6vbKm6F95SAxvB_|q5ILN$=Osz0 z51ZHQE9C#E?CB0Am!$Nx8W1czM|D~^ zkE_GpxQb!G`r*X13Wossru~5}cB2 zm3g`tP=vZ}T5?@9<=uervgwCuA7=E*%5;`9cd$5} z*Dl!-5szgRt!Fiiw}h%9MbM*43Q67Dq_g9$~yNMsDYUtw{NGE1` v=Fn+".format( + self.project, self.version, self.location, + ) diff --git a/venv/lib/python3.7/site-packages/pip/_internal/models/format_control.py b/venv/lib/python3.7/site-packages/pip/_internal/models/format_control.py new file mode 100644 index 0000000..2748856 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/models/format_control.py @@ -0,0 +1,62 @@ +from pip._vendor.packaging.utils import canonicalize_name + + +class FormatControl(object): + """A helper class for controlling formats from which packages are installed. + If a field is falsy, it isn't set. If it is {':all:'}, it should match all + packages except those listed in the other field. Only one field can be set + to {':all:'} at a time. The rest of the time exact package name matches + are listed, with any given package only showing up in one field at a time. + """ + def __init__(self, no_binary=None, only_binary=None): + self.no_binary = set() if no_binary is None else no_binary + self.only_binary = set() if only_binary is None else only_binary + + def __eq__(self, other): + return self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not self.__eq__(other) + + def __repr__(self): + return "{}({}, {})".format( + self.__class__.__name__, + self.no_binary, + self.only_binary + ) + + @staticmethod + def handle_mutual_excludes(value, target, other): + new = value.split(',') + while ':all:' in new: + other.clear() + target.clear() + target.add(':all:') + del new[:new.index(':all:') + 1] + # Without a none, we want to discard everything as :all: covers it + if ':none:' not in new: + return + for name in new: + if name == ':none:': + target.clear() + continue + name = canonicalize_name(name) + other.discard(name) + target.add(name) + + def get_allowed_formats(self, canonical_name): + result = {"binary", "source"} + if canonical_name in self.only_binary: + result.discard('source') + elif canonical_name in self.no_binary: + result.discard('binary') + elif ':all:' in self.only_binary: + result.discard('source') + elif ':all:' in self.no_binary: + result.discard('binary') + return frozenset(result) + + def disallow_binaries(self): + self.handle_mutual_excludes( + ':all:', self.no_binary, self.only_binary, + ) diff --git a/venv/lib/python3.7/site-packages/pip/_internal/models/index.py b/venv/lib/python3.7/site-packages/pip/_internal/models/index.py new file mode 100644 index 0000000..870a315 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/models/index.py @@ -0,0 +1,29 @@ +from pip._vendor.six.moves.urllib import parse as urllib_parse + + +class PackageIndex(object): + """Represents a Package Index and provides easier access to endpoints + """ + + def __init__(self, url, file_storage_domain): + super(PackageIndex, self).__init__() + self.url = url + self.netloc = urllib_parse.urlsplit(url).netloc + self.simple_url = self._url_for_path('simple') + self.pypi_url = self._url_for_path('pypi') + + # This is part of a temporary hack used to block installs of PyPI + # packages which depend on external urls only necessary until PyPI can + # block such packages themselves + self.file_storage_domain = file_storage_domain + + def _url_for_path(self, path): + return urllib_parse.urljoin(self.url, path) + + +PyPI = PackageIndex( + 'https://pypi.org/', file_storage_domain='files.pythonhosted.org' +) +TestPyPI = PackageIndex( + 'https://test.pypi.org/', file_storage_domain='test-files.pythonhosted.org' +) diff --git a/venv/lib/python3.7/site-packages/pip/_internal/models/link.py b/venv/lib/python3.7/site-packages/pip/_internal/models/link.py new file mode 100644 index 0000000..5decb7c --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/models/link.py @@ -0,0 +1,141 @@ +import posixpath +import re + +from pip._vendor.six.moves.urllib import parse as urllib_parse + +from pip._internal.download import path_to_url +from pip._internal.utils.misc import splitext +from pip._internal.utils.models import KeyBasedCompareMixin +from pip._internal.wheel import wheel_ext + + +class Link(KeyBasedCompareMixin): + """Represents a parsed link from a Package Index's simple URL + """ + + def __init__(self, url, comes_from=None, requires_python=None): + """ + url: + url of the resource pointed to (href of the link) + comes_from: + instance of HTMLPage where the link was found, or string. + requires_python: + String containing the `Requires-Python` metadata field, specified + in PEP 345. This may be specified by a data-requires-python + attribute in the HTML link tag, as described in PEP 503. + """ + + # url can be a UNC windows share + if url.startswith('\\\\'): + url = path_to_url(url) + + self.url = url + self.comes_from = comes_from + self.requires_python = requires_python if requires_python else None + + super(Link, self).__init__( + key=(self.url), + defining_class=Link + ) + + def __str__(self): + if self.requires_python: + rp = ' (requires-python:%s)' % self.requires_python + else: + rp = '' + if self.comes_from: + return '%s (from %s)%s' % (self.url, self.comes_from, rp) + else: + return str(self.url) + + def __repr__(self): + return '' % self + + @property + def filename(self): + _, netloc, path, _, _ = urllib_parse.urlsplit(self.url) + name = posixpath.basename(path.rstrip('/')) or netloc + name = urllib_parse.unquote(name) + assert name, ('URL %r produced no filename' % self.url) + return name + + @property + def scheme(self): + return urllib_parse.urlsplit(self.url)[0] + + @property + def netloc(self): + return urllib_parse.urlsplit(self.url)[1] + + @property + def path(self): + return urllib_parse.unquote(urllib_parse.urlsplit(self.url)[2]) + + def splitext(self): + return splitext(posixpath.basename(self.path.rstrip('/'))) + + @property + def ext(self): + return self.splitext()[1] + + @property + def url_without_fragment(self): + scheme, netloc, path, query, fragment = urllib_parse.urlsplit(self.url) + return urllib_parse.urlunsplit((scheme, netloc, path, query, None)) + + _egg_fragment_re = re.compile(r'[#&]egg=([^&]*)') + + @property + def egg_fragment(self): + match = self._egg_fragment_re.search(self.url) + if not match: + return None + return match.group(1) + + _subdirectory_fragment_re = re.compile(r'[#&]subdirectory=([^&]*)') + + @property + def subdirectory_fragment(self): + match = self._subdirectory_fragment_re.search(self.url) + if not match: + return None + return match.group(1) + + _hash_re = re.compile( + r'(sha1|sha224|sha384|sha256|sha512|md5)=([a-f0-9]+)' + ) + + @property + def hash(self): + match = self._hash_re.search(self.url) + if match: + return match.group(2) + return None + + @property + def hash_name(self): + match = self._hash_re.search(self.url) + if match: + return match.group(1) + return None + + @property + def show_url(self): + return posixpath.basename(self.url.split('#', 1)[0].split('?', 1)[0]) + + @property + def is_wheel(self): + return self.ext == wheel_ext + + @property + def is_artifact(self): + """ + 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 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/operations/__init__.py b/venv/lib/python3.7/site-packages/pip/_internal/operations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f48c1c7077f9eb89fb3f8b4cb370b63b8de596d4 GIT binary patch literal 205 zcmZ?b<>g`kf*$Fl7!ds!M8E(ekl_Ht#VkM~g&~+hlhJP_LlH1zy z=6nm!?^n0Jd3wpR{y~k?$3f*MDB5L~C9KdAOz@OtJmie(c4}u%=$N{b)-pFlN9b#5 zJ@Z1()ZMg^`JvA&>8roNR!^H*D{L8?m(FGFu$|3^^VveUkS&Ib*;2TaT?#K{m&421 zmGBD2Ey$~)(dR2xcuiiGS7qDOmrb2oHY_XDOJ0%7E0(cdpS4$J?N#)?E?151hUB6l ze9_$I$2`0#T4L_C72Xop#JpH|&BFJ@qF90^5SPSdyl;yu;ws*EMEix+S)TmhS8~>2)oocs$xs(@no41`D%l#-!kPws`Sr7}qm3s&+xR?s{>#nH zr<*?~?bGRi=W=hHD4EG&(eWz#r^Ca_+rUKeRw^s!QPL|a?`a`bT;!_qelen1 zZiM|OeuVZBJGft1ec1lM9$CM>bHoc)@?Cz+j_krl%_;dw?X7jpOIF(J*4~}3tdha= z&g91%`4FoYI*5Z5do%9G`^+mrGAwc!XIsX%bo~I&<3C#+UioPbw@3LfJ**r(NJbr3 z(RP&$QME=Y-<9w_#Y8QTev!lyM8~Pz!K+wp>#8}6Z=~TUhay!uW(1PQQY8MZ*G4MY zj|;iBAFH)~o(gzuE!$b^eK3kXoqW1`|J8%OnCOom?5htCib-}K&-QTb<=QA2-J1pc z-bbHo?F`0S+oUuFP(Zv8q_uoRaU&S4^>$=$&>bCCw|h!r$>_rNqQ1(ra{%4K-gFzn zs(H-k4qIS8TW0D8G@Ct620TraI?4u${ue~a1RHp2fg<=C(JQQD3o#>UAN;kn5W~M5 zIR!(zW~7U_Imb+`@7+0=lve4iSi2m((xW=!Ti=E4$Sb|l8r0SAgmct@u7))lYM*K+ z?pq7GhI&%gPU`4a@AJ2eS$j_~mxsB$BOm=5yME~lN7UYM{iJkFPw4yhv@bAIQ-3d- zWvyrl_YE(3>8x9&tL{MO&U7~E48C}2_c<_DpZsxyJQ^f@z-Z>n0HF>N9rWOE#2Xpq z8&o~*2YM$Try@$Whq;o}XB2BK#rr{0%xuAy#7w}Q$-JQ0iHo2>wgbavlG8N^LqR+g zfs(~o4GH2~d7jF6IECN<3$J{7BIR&(#{^dlN- zBF-jv4TLV@rn_zuML+DmGw3DQr8!bkN$g5Xq9A)94?A;|2A~rgZZg?o@=0B#W!)@R z0||nW`*Au3J}WyG!X#GJ&?DJP`U#ogTCmGdSFX-gAq6HYRHvzy=~HgfO!X|$IvH+P zP4w-jSdbd6Q@E4+s@AMe1Wwk~!iA1gjSa>!-od^wo1AXszg@NXKMuJ^?)njgRri=@ zyUgW2C+RWHkwv!09ORM@*=F4Kky)2bemQun`xti?JR1!ch2Hu@2$M(*6o^DS=144p zDr&z)8|lKnwfaav!C!mAe!~q&or!#$tH5j%P9UrnJM#P>It;c|JlY9f5jF{b=fDl( zJ~)IZ5mado7Mfr?*_T5A@9f0T2AXG^CbSV+h~2aYQCh!2_5yWm^CIYgh{mg(q>x0; z7r^JOr*XC=;)f|sfMQKLQzy?h5uJugpJVTI3;<04=s1R`s+CA5**GPtn+-Nh80GzH zF`9AU`5wsk9lP?2{Is`$RJCM$6K$PM0xZziVX+VJQYL4v{hvL4gC4pCVYvW;?c1Dj zranRYj72HLbhK=s=w}d9);xG*_;MX59nQ96w#zBBZy5L!Tx6KBR@6{)OXs9MI|FOr zEq>yaHN$KzFdH$IJ^5@S&qm_{OhVD0oyr$)AhTd!2=uudW~73Mx%~v!7u9K~+t{Zf zLQyLu2%_pe67L>{>if{)=p+)Edb2TG0(t9EHKIH-b9@ICsRtNWpiIvq*ERX#BU9Sk z*v_0t4m@+>b2F;6aCmUIk**GKV~GpHz*RT)+6V8`bpgi%S#H6hApBjp*x2vFflg_T zhG*8^-LI^@_RNiJvs0UXIGyv;Z#J7YA6Zi$la^ShTAWdhj^chF_XHs3hh*%MAncq2 zUJ+M(i=t^#i+kK>Q>thaO>kpJ?sUFa)uTw{y(l7D!z~Z2hC@bCvQ?`%_`4A@Q{<{U zT^z~U#r-eU(<@70dYoPhy64w|E@*lbgQ_W-)$+UD%miH!V9(rss_WlnE)GXnOc9R5 zo9}i&aJwjH2}QSs%AE}$c2Erx^tVFMZ9-A1s5ugJ`%v>F?m~qAv+30m_q4G7<&@vU z=Ega{hs~Lm?yKSa1&dKMH|VT>F7-GqrXZ!ej3Hc;js{M~*%tz2LS^#XThDSaPUS;# ix27FAyhT5TANae)?$)T@2FEWz)3&{Nf6ZI=F8v48nsK)P literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e7a3e4cbf3fa38a838f83a4074370570010e250a GIT binary patch literal 6337 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 Cm+J8V literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8841e9fe59b120360ffa10c6b8fb187cbe2aab4b GIT binary patch literal 9203 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 XCg8FO#sD^9Ru>jtTWBnF7Hau literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/operations/check.py b/venv/lib/python3.7/site-packages/pip/_internal/operations/check.py new file mode 100644 index 0000000..799257a --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/operations/check.py @@ -0,0 +1,148 @@ +"""Validation of dependencies of packages +""" + +from collections import namedtuple + +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal.operations.prepare import make_abstract_dist +from pip._internal.utils.misc import get_installed_distributions +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from pip._internal.req.req_install import InstallRequirement # noqa: F401 + from typing import ( # noqa: F401 + Any, Callable, Dict, Iterator, Optional, Set, Tuple, List + ) + + # Shorthands + PackageSet = Dict[str, 'PackageDetails'] + Missing = Tuple[str, Any] + Conflicting = Tuple[str, str, Any] + + MissingDict = Dict[str, List[Missing]] + ConflictingDict = Dict[str, List[Conflicting]] + CheckResult = Tuple[MissingDict, ConflictingDict] + +PackageDetails = namedtuple('PackageDetails', ['version', 'requires']) + + +def create_package_set_from_installed(**kwargs): + # type: (**Any) -> PackageSet + """Converts a list of distributions into a PackageSet. + """ + # Default to using all packages installed on the system + if kwargs == {}: + kwargs = {"local_only": False, "skip": ()} + + package_set = {} + for dist in get_installed_distributions(**kwargs): + name = canonicalize_name(dist.project_name) + package_set[name] = PackageDetails(dist.version, dist.requires()) + return package_set + + +def check_package_set(package_set, should_ignore=None): + # type: (PackageSet, Optional[Callable[[str], bool]]) -> CheckResult + """Check if a package set is consistent + + 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() + + 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): + continue + + for req in package_set[package_name].requires: + name = canonicalize_name(req.project_name) # type: str + + # Check if it's missing + if name not in package_set: + missed = True + if req.marker is not None: + missed = req.marker.evaluate() + if missed: + missing_deps.add((name, req)) + continue + + # Check if there's a conflict + version = package_set[name].version # type: str + if not req.specifier.contains(version, prereleases=True): + conflicting_deps.add((name, version, req)) + + if missing_deps: + missing[package_name] = sorted(missing_deps, key=str) + if conflicting_deps: + conflicting[package_name] = sorted(conflicting_deps, key=str) + + return missing, conflicting + + +def check_install_conflicts(to_install): + # type: (List[InstallRequirement]) -> Tuple[PackageSet, CheckResult] + """For checking if the dependency graph would be consistent after \ + installing given requirements + """ + # Start from the current state + package_set = create_package_set_from_installed() + # Install packages + would_be_installed = _simulate_installation_of(to_install, package_set) + + # Only warn about directly-dependent packages; create a whitelist of them + whitelist = _create_whitelist(would_be_installed, package_set) + + return ( + package_set, + check_package_set( + package_set, should_ignore=lambda name: name not in whitelist + ) + ) + + +# NOTE from @pradyunsg +# This required a minor update in dependency link handling logic over at +# operations.prepare.IsSDist.dist() to get it working +def _simulate_installation_of(to_install, package_set): + # type: (List[InstallRequirement], PackageSet) -> Set[str] + """Computes the version of packages after installing to_install. + """ + + # Keep track of packages that were installed + installed = set() + + # Modify it as installing requirement_set would (assuming no errors) + for inst_req in to_install: + dist = make_abstract_dist(inst_req).dist(finder=None) + name = canonicalize_name(dist.key) + package_set[name] = PackageDetails(dist.version, dist.requires()) + + installed.add(name) + + return installed + + +def _create_whitelist(would_be_installed, package_set): + # type: (Set[str], PackageSet) -> Set[str] + packages_affected = set(would_be_installed) + + for package_name in package_set: + if package_name in packages_affected: + continue + + for req in package_set[package_name].requires: + if canonicalize_name(req.name) in packages_affected: + packages_affected.add(package_name) + break + + return packages_affected diff --git a/venv/lib/python3.7/site-packages/pip/_internal/operations/freeze.py b/venv/lib/python3.7/site-packages/pip/_internal/operations/freeze.py new file mode 100644 index 0000000..beb2feb --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/operations/freeze.py @@ -0,0 +1,264 @@ +from __future__ import absolute_import + +import collections +import logging +import os +import re + +from pip._vendor import pkg_resources, six +from pip._vendor.packaging.utils import canonicalize_name +from pip._vendor.pkg_resources import RequirementParseError + +from pip._internal.exceptions import InstallationError +from pip._internal.req.constructors import ( + install_req_from_editable, install_req_from_line, +) +from pip._internal.req.req_file import COMMENT_RE +from pip._internal.utils.deprecation import deprecated +from pip._internal.utils.misc import ( + dist_is_editable, get_installed_distributions, make_vcs_requirement_url, +) + +logger = logging.getLogger(__name__) + + +def freeze( + requirement=None, + find_links=None, local_only=None, user_only=None, skip_regex=None, + isolated=False, + wheel_cache=None, + exclude_editable=False, + skip=()): + find_links = find_links or [] + skip_match = None + + if skip_regex: + skip_match = re.compile(skip_regex).search + + dependency_links = [] + + for dist in pkg_resources.working_set: + if dist.has_metadata('dependency_links.txt'): + dependency_links.extend( + dist.get_metadata_lines('dependency_links.txt') + ) + for link in find_links: + if '#egg=' in link: + dependency_links.append(link) + for link in find_links: + yield '-f %s' % link + installations = {} + for dist in get_installed_distributions(local_only=local_only, + skip=(), + user_only=user_only): + try: + req = FrozenRequirement.from_dist( + dist, + dependency_links + ) + except RequirementParseError: + logger.warning( + "Could not parse requirement: %s", + dist.project_name + ) + continue + if exclude_editable and req.editable: + continue + installations[req.name] = req + + if requirement: + # the options that don't get turned into an InstallRequirement + # should only be emitted once, even if the same option is in multiple + # requirements files, so we need to keep track of what has been emitted + # so that we don't emit it again if it's seen again + emitted_options = set() + # keep track of which files a requirement is in so that we can + # give an accurate warning if a requirement appears multiple times. + req_files = collections.defaultdict(list) + for req_file_path in requirement: + with open(req_file_path) as req_file: + 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'))): + line = line.rstrip() + if line not in emitted_options: + emitted_options.add(line) + yield line + continue + + if line.startswith('-e') or line.startswith('--editable'): + if line.startswith('-e'): + line = line[2:].strip() + else: + line = line[len('--editable'):].strip().lstrip('=') + 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: + logger.info( + "Skipping line in requirement file [%s] because " + "it's not clear what it would install: %s", + req_file_path, line.strip(), + ) + logger.info( + " (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 that " + "package is not installed", + req_file_path, + COMMENT_RE.sub('', line).strip(), + ) + 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) + + # Warn about requirements that were included multiple times (in a + # single requirements file or in different requirements files). + for name, files in six.iteritems(req_files): + if len(files) > 1: + logger.warning("Requirement %s included multiple times [%s]", + name, ', '.join(sorted(set(files)))) + + yield( + '## The following requirements were added by ' + 'pip freeze:' + ) + for installation in sorted( + installations.values(), key=lambda x: x.name.lower()): + if canonicalize_name(installation.name) not in skip: + yield str(installation).rstrip() + + +class FrozenRequirement(object): + def __init__(self, name, req, editable, comments=()): + self.name = name + self.req = req + self.editable = editable + self.comments = comments + + _rev_re = re.compile(r'-r(\d+)$') + _date_re = re.compile(r'-(20\d\d\d\d\d\d)$') + + @classmethod + def _init_args_from_dist(cls, dist, dependency_links): + """ + Compute and return arguments (req, editable, comments) to pass to + FrozenRequirement.__init__(). + + This method is for use in FrozenRequirement.from_dist(). + """ + location = os.path.normcase(os.path.abspath(dist.location)) + comments = [] + from pip._internal.vcs import vcs, get_src_requirement + if dist_is_editable(dist) and vcs.get_backend_name(location): + editable = True + try: + req = get_src_requirement(dist, location) + except InstallationError as exc: + logger.warning( + "Error when trying to get requirement for VCS system %s, " + "falling back to uneditable format", exc + ) + req = None + if req is None: + logger.warning( + 'Could not determine repository location of %s', location + ) + comments.append( + '## !! Could not determine repository location' + ) + req = dist.as_requirement() + editable = False + else: + editable = False + req = dist.as_requirement() + specs = req.specs + assert len(specs) == 1 and specs[0][0] in ["==", "==="], \ + 'Expected 1 spec with == or ===; specs = %r; dist = %r' % \ + (specs, dist) + version = specs[0][1] + ver_match = cls._rev_re.search(version) + date_match = cls._date_re.search(version) + if ver_match or date_match: + svn_backend = vcs.get_backend('svn') + if svn_backend: + svn_location = svn_backend().get_location( + dist, + dependency_links, + ) + if not svn_location: + logger.warning( + 'Warning: cannot find svn location for %s', req, + ) + comments.append( + '## FIXME: could not find svn URL in dependency_links ' + 'for this package:' + ) + else: + deprecated( + "SVN editable detection based on dependency links " + "will be dropped in the future.", + replacement=None, + gone_in="18.2", + issue=4187, + ) + comments.append( + '# Installing as editable to satisfy requirement %s:' % + req + ) + if ver_match: + rev = ver_match.group(1) + else: + rev = '{%s}' % date_match.group(1) + editable = True + egg_name = cls.egg_name(dist) + req = make_vcs_requirement_url(svn_location, rev, egg_name) + + return (req, editable, comments) + + @classmethod + def from_dist(cls, dist, dependency_links): + args = cls._init_args_from_dist(dist, dependency_links) + return cls(dist.project_name, *args) + + @staticmethod + def egg_name(dist): + name = dist.egg_name() + match = re.search(r'-py\d\.\d$', name) + if match: + name = name[:match.start()] + return name + + def __str__(self): + req = self.req + if self.editable: + req = '-e %s' % req + return '\n'.join(list(self.comments) + [str(req)]) + '\n' diff --git a/venv/lib/python3.7/site-packages/pip/_internal/operations/prepare.py b/venv/lib/python3.7/site-packages/pip/_internal/operations/prepare.py new file mode 100644 index 0000000..104bea3 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/operations/prepare.py @@ -0,0 +1,355 @@ +"""Prepares a distribution for installation +""" + +import logging +import os + +from pip._vendor import pkg_resources, requests + +from pip._internal.build_env import BuildEnvironment +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, +) +from pip._internal.utils.compat import expanduser +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.vcs import vcs + +logger = logging.getLogger(__name__) + + +def make_abstract_dist(req): + """Factory to make an abstract dist object. + + Preconditions: Either an editable req with a source_dir, or satisfied_by or + a wheel link, or a non-editable req with a source_dir. + + :return: A concrete DistAbstraction. + """ + if req.editable: + return IsSDist(req) + elif req.link and req.link.is_wheel: + return IsWheel(req) + else: + return IsSDist(req) + + +class DistAbstraction(object): + """Abstracts out the wheel vs non-wheel Resolver.resolve() logic. + + The requirements for anything installable are as follows: + - we must be able to determine the requirement name + (or we can't correctly handle the non-upgrade case). + - we must be able to generate a list of run-time dependencies + without installing any additional packages (or we would + have to either burn time by doing temporary isolated installs + or alternatively violate pips 'don't start installing unless + all requirements are available' rule - neither of which are + desirable). + - for packages with setup requirements, we must also be able + to determine their requirements without installing additional + packages (for the same reason as run-time dependencies) + - we must be able to create a Distribution object exposing the + above metadata. + """ + + def __init__(self, req): + self.req = req + + def dist(self, finder): + """Return a setuptools Dist object.""" + raise NotImplementedError(self.dist) + + def prep_for_dist(self, finder, build_isolation): + """Ensure that we can get a Dist for this requirement.""" + raise NotImplementedError(self.dist) + + +class IsWheel(DistAbstraction): + + def dist(self, finder): + return list(pkg_resources.find_distributions( + self.req.source_dir))[0] + + def prep_for_dist(self, finder, build_isolation): + # FIXME:https://github.com/pypa/pip/issues/1112 + pass + + +class IsSDist(DistAbstraction): + + def dist(self, finder): + dist = self.req.get_dist() + # FIXME: shouldn't be globally added. + if finder and dist.has_metadata('dependency_links.txt'): + finder.add_dependency_links( + dist.get_metadata_lines('dependency_links.txt') + ) + return dist + + def prep_for_dist(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 + + 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, + "Installing build dependencies" + ) + missing = [] + if self.req.requirements_to_check: + check = self.req.requirements_to_check + missing = self.req.build_env.missing_requirements(check) + 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))) + ) + + self.req.run_egg_info() + self.req.assert_source_matches_version() + + +class Installed(DistAbstraction): + + def dist(self, finder): + return self.req.satisfied_by + + def prep_for_dist(self, finder, build_isolation): + pass + + +class RequirementPreparer(object): + """Prepares a Requirement + """ + + def __init__(self, build_dir, download_dir, src_dir, wheel_download_dir, + progress_bar, build_isolation, req_tracker): + super(RequirementPreparer, self).__init__() + + self.src_dir = src_dir + self.build_dir = build_dir + self.req_tracker = req_tracker + + # 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 + # download_dir and wheel_download_dir overlap semantically and may + # be combined if we're willing to have non-wheel archives present in + # the wheelhouse output by 'pip wheel'. + + self.progress_bar = progress_bar + + # Is build isolation allowed? + self.build_isolation = build_isolation + + @property + def _download_should_save(self): + # 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 + + def prepare_linked_requirement(self, req, session, finder, + upgrade_allowed, require_hashes): + """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) + logger.info('Processing %s', display_path(path)) + else: + logger.info('Collecting %s', req) + + with indent_log(): + # @@ if filesystem packages are not marked + # editable in a req, a non deterministic error + # occurs when the script attempts to unpack the + # build directory + 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() + + 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, + ) + raise InstallationError( + 'Could not install requirement %s because of HTTP ' + 'error %s for URL %s' % + (req, exc, req.link) + ) + abstract_dist = make_abstract_dist(req) + with self.req_tracker.track(req): + abstract_dist.prep_for_dist(finder, self.build_isolation) + if self._download_should_save: + # Make a .zip of the source_dir we already created. + if req.link.scheme in vcs.all_schemes: + req.archive(self.download_dir) + return abstract_dist + + def prepare_editable_requirement(self, req, require_hashes, use_user_site, + finder): + """Prepare an editable requirement + """ + assert req.editable, "cannot prepare a non-editable req as editable" + + logger.info('Obtaining %s', req) + + with indent_log(): + if require_hashes: + raise InstallationError( + 'The editable requirement %s cannot be installed when ' + 'requiring hashes, because there is no single file to ' + 'hash.' % req + ) + req.ensure_has_source_dir(self.src_dir) + req.update_editable(not self._download_should_save) + + abstract_dist = make_abstract_dist(req) + with self.req_tracker.track(req): + abstract_dist.prep_for_dist(finder, self.build_isolation) + + if self._download_should_save: + req.archive(self.download_dir) + req.check_if_exists(use_user_site) + + return abstract_dist + + def prepare_installed_requirement(self, req, require_hashes, skip_reason): + """Prepare an already-installed requirement + """ + assert req.satisfied_by, "req should have been satisfied but isn't" + assert skip_reason is not None, ( + "did not get skip reason skipped but req.satisfied_by " + "is set to %r" % (req.satisfied_by,) + ) + logger.info( + 'Requirement %s: %s (%s)', + skip_reason, req, req.satisfied_by.version + ) + with indent_log(): + if require_hashes: + logger.debug( + 'Since it is already installed, we are trusting this ' + 'package without checking its hash. To ensure a ' + 'completely repeatable environment, install into an ' + 'empty virtualenv.' + ) + abstract_dist = Installed(req) + + return abstract_dist diff --git a/venv/lib/python3.7/site-packages/pip/_internal/pep425tags.py b/venv/lib/python3.7/site-packages/pip/_internal/pep425tags.py new file mode 100644 index 0000000..ab1a029 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/pep425tags.py @@ -0,0 +1,317 @@ +"""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 + +logger = logging.getLogger(__name__) + +_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: + logger.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 + sys.version_info < (3, 3))) \ + and sys.version_info < (3, 3): + 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 pip._internal.utils.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 an 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() + 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() + 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.7/site-packages/pip/_internal/pyproject.py b/venv/lib/python3.7/site-packages/pip/_internal/pyproject.py new file mode 100644 index 0000000..f938a76 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/pyproject.py @@ -0,0 +1,144 @@ +from __future__ import absolute_import + +import io +import os + +from pip._vendor import pytoml, six + +from pip._internal.exceptions import InstallationError + + +def _is_list_of_str(obj): + return ( + isinstance(obj, list) and + all(isinstance(item, six.string_types) for item in obj) + ) + + +def load_pyproject_toml(use_pep517, pyproject_toml, setup_py, req_name): + """Load the pyproject.toml file. + + Parameters: + use_pep517 - Has the user requested PEP 517 processing? None + means the user hasn't explicitly specified. + pyproject_toml - Location of the project's pyproject.toml file + setup_py - Location of the project's setup.py file + req_name - The name of the requirement we're processing (for + error reporting) + + Returns: + None if we should use the legacy code path, otherwise a tuple + ( + requirements from pyproject.toml, + name of PEP 517 backend, + requirements we should check are installed after setting + up the build environment + ) + """ + has_pyproject = os.path.isfile(pyproject_toml) + has_setup = os.path.isfile(setup_py) + + if has_pyproject: + with io.open(pyproject_toml, encoding="utf-8") as f: + pp_toml = pytoml.load(f) + build_system = pp_toml.get("build-system") + else: + build_system = None + + # The following cases must use PEP 517 + # We check for use_pep517 equalling False because that + # means the user explicitly requested --no-use-pep517 + if has_pyproject and not has_setup: + if use_pep517 is False: + raise InstallationError( + "Disabling PEP 517 processing is invalid: " + "project does not have a setup.py" + ) + use_pep517 = True + elif build_system and "build-backend" in build_system: + if use_pep517 is False: + raise InstallationError( + "Disabling PEP 517 processing is invalid: " + "project specifies a build backend of {} " + "in pyproject.toml".format( + build_system["build-backend"] + ) + ) + use_pep517 = True + + # If we haven't worked out whether to use PEP 517 yet, + # and the user hasn't explicitly stated a preference, + # we do so if the project has a pyproject.toml file. + elif use_pep517 is None: + use_pep517 = has_pyproject + + # At this point, we know whether we're going to use PEP 517. + assert use_pep517 is not None + + # If we're using the legacy code path, there is nothing further + # for us to do here. + if not use_pep517: + return None + + if build_system is None: + # Either the user has a pyproject.toml with no build-system + # section, or the user has no pyproject.toml, but has opted in + # explicitly via --use-pep517. + # In the absence of any explicit backend specification, we + # assume the setuptools backend, and require wheel and a version + # of setuptools that supports that backend. + build_system = { + "requires": ["setuptools>=38.2.5", "wheel"], + "build-backend": "setuptools.build_meta", + } + + # If we're using PEP 517, we have build system information (either + # from pyproject.toml, or defaulted by the code above). + # Note that at this point, we do not know if the user has actually + # specified a backend, though. + assert build_system is not None + + # Ensure that the build-system section in pyproject.toml conforms + # to PEP 518. + error_template = ( + "{package} has a pyproject.toml file that does not comply " + "with PEP 518: {reason}" + ) + + # Specifying the build-system table but not the requires key is invalid + if "requires" not in build_system: + raise InstallationError( + error_template.format(package=req_name, reason=( + "it has a 'build-system' table but not " + "'build-system.requires' which is mandatory in the table" + )) + ) + + # Error out if requires is not a list of strings + requires = build_system["requires"] + if not _is_list_of_str(requires): + raise InstallationError(error_template.format( + package=req_name, + reason="'build-system.requires' is not a list of strings.", + )) + + backend = build_system.get("build-backend") + check = [] + if backend is None: + # If the user didn't specify a backend, we assume they want to use + # the setuptools backend. But we can't be sure they have included + # a version of setuptools which supplies the backend, or wheel + # (which is neede by the backend) in their requirements. So we + # make a note to check that those requirements are present once + # we have set up the environment. + # TODO: Review this - it's quite a lot of work to check for a very + # specific case. The problem is, that case is potentially quite + # common - projects that adopted PEP 518 early for the ability to + # specify requirements to execute setup.py, but never considered + # needing to mention the build tools themselves. The original PEP + # 518 code had a similar check (but implemented in a different + # way). + backend = "setuptools.build_meta" + check = ["setuptools>=38.2.5", "wheel"] + + return (requires, backend, check) diff --git a/venv/lib/python3.7/site-packages/pip/_internal/req/__init__.py b/venv/lib/python3.7/site-packages/pip/_internal/req/__init__.py new file mode 100644 index 0000000..b270498 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/req/__init__.py @@ -0,0 +1,69 @@ +from __future__ import absolute_import + +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 + + +__all__ = [ + "RequirementSet", "InstallRequirement", + "parse_requirements", "install_given_reqs", +] + +logger = logging.getLogger(__name__) + + +def install_given_reqs(to_install, install_options, global_options=(), + *args, **kwargs): + """ + Install everything in the given list. + + (to be called after having downloaded and unpacked the packages) + """ + + if to_install: + logger.info( + 'Installing collected packages: %s', + ', '.join([req.name for req in to_install]), + ) + + with indent_log(): + for requirement in to_install: + if requirement.conflicts_with: + logger.info( + 'Found existing installation: %s', + requirement.conflicts_with, + ) + with indent_log(): + uninstalled_pathset = requirement.uninstall( + auto_confirm=True + ) + try: + requirement.install( + install_options, + global_options, + *args, + **kwargs + ) + except Exception: + should_rollback = ( + requirement.conflicts_with and + not requirement.install_succeeded + ) + # if install did not succeed, rollback previous uninstall + if should_rollback: + uninstalled_pathset.rollback() + raise + else: + should_commit = ( + requirement.conflicts_with and + requirement.install_succeeded + ) + if should_commit: + uninstalled_pathset.commit() + requirement.remove_temporary_source() + + return to_install diff --git a/venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bd3799f85ddb6d6694b940fcbe4432393600e39d GIT binary patch literal 1573 zcmZWpPm3c(6tAjuI-SnHH4Ce_pzT31;3T7q%E~Z^s36FSI}5WLT#8OtrPDLrU74!t z%uMLHxO?;u-aJX>A_^Wn`U(6HbrL-7SJ;!UI?3#S)zs@(uU@@+@BQAZPdXhR!T9d> zhN)&i7-Bd@86IP7d6JSbVKwHYwaghiAgi%@TF>0ETk&q%$h@&v z={C}4=8t{gJ=SDCYsJpE#mTD8JC}IeWnI=`t*3b0W8?r0de7iCG{B}8PLxOs&1sU& zh1B<+;q^xUi(Kh2P4DxQB9T1fxd!#_wdDb~lKwoDic|SQO@Y);at0@8Dq>j&gVKg6 zT_C2PtPRsRS@7H*RKKIB23vMCVYXm?1ylV4q(m~%XoVSOWK|{ODabxWPw*waBpB)1 z6ZGSs7@hrQrH@w^^|F5CNLHPx_$#eGMzB|BE^B;`FWf^&)z|1gdWg48^^x<10(xc%i?FCUK?FB%7*;4bXUzw*!dPcLiwu?*BXCWjSH{z zYT5tE@DS{7?=2BP(OedO0ArKyfG@Z_*Rv##gCr01j0aVsf;3Tj=vS(5 zYY|L%5CJ@#1>sb48O*|kJ;KCko{ErJdCr0&pNG*gEUX>NhA~%z%E`O40lZp z0IuW}c`inCnJhxhM~hI7rXpors!=u@Meok(-R0e*-P1c$wp1V7S;+U!^fKFp5$B@^ zqj@sl*_6)C`yWnb$HgSJ!fMhaha}`-I)dv)6qbpmbT~hM?(f;eMIxK;zh*tRVYq1d z*8i(;xR(k@soDo-dt~|g=c0f-@-vXEA*s3|)QQM#iXK3??Xb{-Mk1dkGP^fu8yCtx z=F&JxJ{86}5=kx_aIfiFr8J4OqNjeCtrgXb@LK!RL z9-mhK*0qKmMzHql1?I8?p-Xu8&`p?X9|-as>|la# z)jaHDx8gnG!M{&PwX*v@=@J)vH3xe@UF;Ie-68|LF0>oQr*vBALUKx_1=cid<^d;T z{olr3JwB#kCE$4V9zh;qHBC~!ew1!QAq}sJXjteZRl|*~HFOP1q1`Ao&6w*i*Z6vr r+DeDZZ@}eMh}Xil%}~W|yuD1YBIWzGm#W@r6OXiU^*In!&9D6jx}v?# literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/constructors.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/constructors.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b2ee24e14e01fbc219020c21fcce2e5e8630fac5 GIT binary patch literal 6971 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 F{})&Dm#zQ+ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_install.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_install.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cb883d5e4a3c3ab75274ef1505d07c1e33df3cc2 GIT binary patch literal 22822 zcmc(HdyHIHnpfRh@9OI6cl&K$zuk$uojA^865EqFaVME^Iv%_8m?AUf>N>aE)m^Wg zd&_ng)na!XW-`lW6JXGS7?$pVo!uSr7*@mX2%%*`5YU3q@X!if5LyYO-9fM`1QJq^ z7Jk3)+`3iWsf?JvXuHlm_uTWk-}%n>KKI(_XfB4opFgzn&L6)Qi~T3w^!^gaJddCE zT`Lw-F=f?ab*pGu%-c1)Xv;NTjLS7qOvp7^Ov*J?OvyD}Oye4_W$M{tR@x?Nx%x

#_3`4kM0A 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 xexBfa!TF4;x;41&L`V(x=hU65`(GY_zYqWb literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..92de3a402d9395f11d13f0eb42d6948017932587 GIT binary patch literal 12869 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/req/constructors.py b/venv/lib/python3.7/site-packages/pip/_internal/req/constructors.py new file mode 100644 index 0000000..4c4641d --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/req/constructors.py @@ -0,0 +1,298 @@ +"""Backing implementation for InstallRequirement's various constructors + +The idea here is that these formed a major chunk of InstallRequirement's size +so, moving them and support code dedicated to them outside of that class +helps creates for better understandability for the rest of the code. + +These are meant to be used elsewhere within pip to create instances of +InstallRequirement. +""" + +import logging +import os +import re +import traceback + +from pip._vendor.packaging.markers import Marker +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, path_to_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.req.req_install import InstallRequirement +from pip._internal.utils.misc import is_installable_dir +from pip._internal.vcs import vcs +from pip._internal.wheel import Wheel + +__all__ = [ + "install_req_from_editable", "install_req_from_line", + "parse_editable" +] + +logger = logging.getLogger(__name__) +operators = Specifier._operators.keys() + + +def _strip_extras(path): + m = re.match(r'^(.+)(\[[^\]]+\])$', path) + extras = None + if m: + path_no_extras = m.group(1) + extras = m.group(2) + else: + path_no_extras = path + + return path_no_extras, extras + + +def parse_editable(editable_req): + """Parses an editable requirement into: + - a requirement name + - an URL + - extras + - editable options + Accepted requirements: + svn+http://blahblah@rev#egg=Foobar[baz]&subdirectory=version_subdir + .[some_extra] + """ + + url = editable_req + + # If a file path is specified with extras, strip off the extras. + url_no_extras, extras = _strip_extras(url) + + if os.path.isdir(url_no_extras): + if not os.path.exists(os.path.join(url_no_extras, 'setup.py')): + raise InstallationError( + "Directory %r is not installable. File 'setup.py' not found." % + url_no_extras + ) + # Treating it as code that has already been checked out + url_no_extras = path_to_url(url_no_extras) + + if url_no_extras.lower().startswith('file:'): + package_name = Link(url_no_extras).egg_fragment + if extras: + return ( + package_name, + url_no_extras, + Requirement("placeholder" + extras.lower()).extras, + ) + else: + return package_name, url_no_extras, None + + for version_control in vcs: + if url.lower().startswith('%s:' % version_control): + url = '%s+%s' % (version_control, url) + break + + if '+' not in url: + raise InstallationError( + '%s should either be a path to a local project or a VCS url ' + 'beginning with svn+, git+, hg+, or bzr+' % + 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' + 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 + ) + return package_name, url, None + + +def deduce_helpful_msg(req): + """Returns helpful msg in case requirements file does not exist, + or cannot be parsed. + + :params req: Requirements file path + """ + msg = "" + if os.path.exists(req): + msg = " It does exist." + # Try to parse and check if it is a requirements file. + try: + 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" + \ + " the packages specified within it." + except RequirementParseError: + logger.debug("Cannot parse '%s' as requirements \ + file" % (req), exc_info=1) + else: + msg += " File '%s' does not exist." % (req) + return msg + + +# ---- The actual constructors follow ---- + + +def install_req_from_editable( + editable_req, comes_from=None, isolated=False, options=None, + wheel_cache=None, constraint=False +): + 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 + return InstallRequirement( + req, comes_from, source_dir=source_dir, + editable=True, + link=Link(url), + constraint=constraint, + isolated=isolated, + options=options if options else {}, + wheel_cache=wheel_cache, + extras=extras_override or (), + ) + + +def install_req_from_line( + name, comes_from=None, isolated=False, options=None, wheel_cache=None, + constraint=False +): + """Creates an InstallRequirement from a name, which might be a + requirement, directory containing 'setup.py', filename, or URL. + """ + if is_url(name): + marker_sep = '; ' + else: + marker_sep = ';' + if marker_sep in name: + name, markers = name.split(marker_sep, 1) + markers = markers.strip() + if not markers: + markers = None + else: + markers = Marker(markers) + else: + markers = None + name = name.strip() + req = None + path = os.path.normpath(os.path.abspath(name)) + link = None + extras = None + + if is_url(name): + link = Link(name) + else: + p, extras = _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)) + + # it's a local file, dir, or url + if link: + # Handle relative file URLs + if link.scheme == 'file' and re.search(r'\.\./', link.url): + link = Link( + path_to_url(os.path.normpath(os.path.abspath(link.path)))) + # wheel file + if link.is_wheel: + wheel = Wheel(link.filename) # can raise InvalidWheelFilename + req = "%s==%s" % (wheel.name, wheel.version) + else: + # set the req to the egg fragment. when it's not there, this + # will become an 'unnamed' requirement + req = link.egg_fragment + + # a requirement specifier + else: + req = name + + if extras: + extras = Requirement("placeholder" + extras.lower()).extras + else: + extras = () + if req is not None: + try: + req = Requirement(req) + except InvalidRequirement: + if os.path.sep in req: + add_msg = "It looks like a path." + add_msg += deduce_helpful_msg(req) + elif '=' in req and not any(op in req for op in operators): + add_msg = "= is not a valid operator. Did you mean == ?" + else: + add_msg = traceback.format_exc() + raise InstallationError( + "Invalid requirement: '%s'\n%s" % (req, add_msg) + ) + + return InstallRequirement( + req, comes_from, link=link, markers=markers, + isolated=isolated, + options=options if options else {}, + wheel_cache=wheel_cache, + constraint=constraint, + extras=extras, + ) + + +def install_req_from_req( + req, comes_from=None, isolated=False, wheel_cache=None +): + try: + req = Requirement(req) + except InvalidRequirement: + raise InstallationError("Invalid requirement: '%s'" % req) + + domains_not_allowed = [ + PyPI.file_storage_domain, + TestPyPI.file_storage_domain, + ] + if req.url and comes_from.link.netloc in domains_not_allowed: + # Explicitly disallow pypi packages that depend on external urls + 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) + ) + + return InstallRequirement( + req, comes_from, isolated=isolated, wheel_cache=wheel_cache + ) diff --git a/venv/lib/python3.7/site-packages/pip/_internal/req/req_file.py b/venv/lib/python3.7/site-packages/pip/_internal/req/req_file.py new file mode 100644 index 0000000..e7acf7c --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/req/req_file.py @@ -0,0 +1,340 @@ +""" +Requirements file parsing +""" + +from __future__ import absolute_import + +import optparse +import os +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.req.constructors import ( + install_req_from_editable, install_req_from_line, +) + +__all__ = ['parse_requirements'] + +SCHEME_RE = re.compile(r'^(http|https|file):', re.I) +COMMENT_RE = re.compile(r'(^|\s)+#.*$') + +# Matches environment variable-style values in '${MY_VARIABLE_1}' with the +# variable name consisting of only uppercase letters, digits or the '_' +# (underscore). This follows the POSIX standard defined in IEEE Std 1003.1, +# 2013 Edition. +ENV_VAR_RE = re.compile(r'(?P\$\{(?P[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_binary, + cmdoptions.only_binary, + cmdoptions.pre, + cmdoptions.process_dependency_links, + cmdoptions.trusted_host, + cmdoptions.require_hashes, +] + +# options to be passed to requirements +SUPPORTED_OPTIONS_REQ = [ + cmdoptions.install_options, + cmdoptions.global_options, + cmdoptions.hash, +] + +# the 'dest' string values +SUPPORTED_OPTIONS_REQ_DEST = [o().dest for o in SUPPORTED_OPTIONS_REQ] + + +def parse_requirements(filename, finder=None, comes_from=None, options=None, + session=None, constraint=False, wheel_cache=None): + """Parse a requirements file and yield InstallRequirement instances. + + :param filename: Path or url of requirements file. + :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 + """ + if session is None: + raise TypeError( + "parse_requirements() missing 1 required keyword argument: " + "'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, + constraint=constraint) + for req in req_iter: + yield req + + +def preprocess(content, options): + """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) + 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, filename, line_number, finder=None, comes_from=None, + options=None, session=None, wheel_cache=None, + constraint=False): + """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: + # `finder.format_control` will be updated during parsing + defaults.format_control = finder.format_control + args_str, options_str = break_args_options(line) + if sys.version_info < (2, 7, 3): + # Prior to 2.7.3, shlex cannot deal with unicode entries + options_str = options_str.encode('utf8') + opts, _ = parser.parse_args(shlex.split(options_str), defaults) + + # preserve for the nested code path + line_comes_from = '%s %s (line %s)' % ( + '-c' if constraint else '-r', filename, line_number, + ) + + # yield a line requirement + if args_str: + isolated = options.isolated_mode if options else False + if options: + cmdoptions.check_install_build_global(options, 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] + yield install_req_from_line( + args_str, line_comes_from, constraint=constraint, + isolated=isolated, options=req_options, wheel_cache=wheel_cache + ) + + # 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, + 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? + parser = parse_requirements( + req_path, finder, comes_from, options, session, + constraint=nested_constraint, wheel_cache=wheel_cache + ) + for req in parser: + yield req + + # percolate hash-checking option upward + elif opts.require_hashes: + options.require_hashes = opts.require_hashes + + # set finder options + elif finder: + if opts.index_url: + finder.index_urls = [opts.index_url] + if opts.no_index is True: + finder.index_urls = [] + if opts.extra_index_urls: + finder.index_urls.extend(opts.extra_index_urls) + if opts.find_links: + # FIXME: it would be nice to keep track of the source + # of the find_links: support a find-links local path + # relative to a requirements file. + value = opts.find_links[0] + req_dir = os.path.dirname(os.path.abspath(filename)) + relative_to_reqs_file = os.path.join(req_dir, value) + if os.path.exists(relative_to_reqs_file): + value = relative_to_reqs_file + finder.find_links.append(value) + if opts.pre: + finder.allow_all_prereleases = True + if opts.process_dependency_links: + finder.process_dependency_links = True + if opts.trusted_hosts: + finder.secure_origins.extend( + ("*", host, "*") for host in opts.trusted_hosts) + + +def break_args_options(line): + """Break up the line into an args and options string. We only want to shlex + (and then optparse) the options, not the args. args can contain markers + which are corrupted by shlex. + """ + tokens = line.split(' ') + args = [] + options = tokens[:] + for token in tokens: + if token.startswith('-') or token.startswith('--'): + break + else: + args.append(token) + options.pop(0) + return ' '.join(args), ' '.join(options) + + +def build_parser(line): + """ + Return a parser for parsing requirement lines + """ + parser = optparse.OptionParser(add_help_option=False) + + option_factories = SUPPORTED_OPTIONS + SUPPORTED_OPTIONS_REQ + for option_factory in option_factories: + option = option_factory() + parser.add_option(option) + + # By default optparse sys.exits on parsing errors. We want to wrap + # that in our own exception. + def parser_exit(self, msg): + # add offending line + msg = 'Invalid requirement: %s\n%s' % (line, msg) + raise RequirementsFileParseError(msg) + parser.exit = parser_exit + + return parser + + +def join_lines(lines_enum): + """Joins a line ending in '\' with the previous line (except when following + comments). The joined line takes on the index of the first line. + """ + primary_line_number = None + new_line = [] + for line_number, line in lines_enum: + if not line.endswith('\\') or COMMENT_RE.match(line): + if COMMENT_RE.match(line): + # this ensures comments are always matched later + line = ' ' + line + if new_line: + new_line.append(line) + yield primary_line_number, ''.join(new_line) + new_line = [] + else: + yield line_number, line + else: + if not new_line: + primary_line_number = line_number + new_line.append(line.strip('\\')) + + # last line contains \ + if new_line: + yield primary_line_number, ''.join(new_line) + + # TODO: handle space after '\'. + + +def ignore_comments(lines_enum): + """ + Strips comments and filter empty lines. + """ + for line_number, line in lines_enum: + line = COMMENT_RE.sub('', line) + line = line.strip() + if line: + yield line_number, line + + +def skip_regex(lines_enum, options): + """ + 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): + """Replace all environment variables that can be retrieved via `os.getenv`. + + The only allowed format for environment variables defined in the + requirement file is `${MY_VARIABLE_1}` to ensure two things: + + 1. Strings that contain a `$` aren't accidentally (partially) expanded. + 2. Ensure consistency across platforms for requirement files. + + These points are the result of a discusssion on the `github pull + request #3514 `_. + + Valid characters in variable names follow the `POSIX standard + `_ and are limited + to uppercase letter, digits and the `_` (underscore). + """ + for line_number, line in lines_enum: + for env_var, var_name in ENV_VAR_RE.findall(line): + value = os.getenv(var_name) + if not value: + continue + + line = line.replace(env_var, value) + + yield line_number, line diff --git a/venv/lib/python3.7/site-packages/pip/_internal/req/req_install.py b/venv/lib/python3.7/site-packages/pip/_internal/req/req_install.py new file mode 100644 index 0000000..c2624fe --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/req/req_install.py @@ -0,0 +1,860 @@ +from __future__ import absolute_import + +import logging +import os +import shutil +import sys +import sysconfig +import zipfile +from distutils.util import change_root + +from pip._vendor import pkg_resources, six +from pip._vendor.packaging.requirements import Requirement +from pip._vendor.packaging.utils import canonicalize_name +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 ( + PIP_DELETE_MARKER_FILENAME, running_under_virtualenv, +) +from pip._internal.models.link import Link +from pip._internal.pyproject import load_pyproject_toml +from pip._internal.req.req_uninstall import UninstallPathSet +from pip._internal.utils.compat import native_str +from pip._internal.utils.hashes import Hashes +from pip._internal.utils.logging import indent_log +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, rmtree, +) +from pip._internal.utils.packaging import get_metadata +from pip._internal.utils.setuptools_build import SETUPTOOLS_SHIM +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.ui import open_spinner +from pip._internal.vcs import vcs +from pip._internal.wheel import move_wheel_files + +logger = logging.getLogger(__name__) + + +class InstallRequirement(object): + """ + Represents something that may be installed later on, may have information + about where to fetch the relavant requirement and also contains logic for + installing the said requirement. + """ + + def __init__(self, req, comes_from, source_dir=None, editable=False, + link=None, update=True, markers=None, + isolated=False, options=None, wheel_cache=None, + constraint=False, extras=()): + assert req is None or isinstance(req, Requirement), req + self.req = req + self.comes_from = comes_from + self.constraint = constraint + if source_dir is not None: + self.source_dir = os.path.normpath(os.path.abspath(source_dir)) + else: + self.source_dir = None + self.editable = editable + + self._wheel_cache = wheel_cache + if link is not None: + self.link = self.original_link = link + else: + self.link = self.original_link = req and req.url and Link(req.url) + + if extras: + self.extras = extras + elif req: + self.extras = { + pkg_resources.safe_extra(extra) for extra in req.extras + } + else: + self.extras = set() + if markers is not None: + self.markers = markers + else: + self.markers = req and req.marker + self._egg_info_path = None + # 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 + # 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 + # True if the editable should be updated: + self.update = update + # Set to True after successful installation + self.install_succeeded = None + # UninstallPathSet of uninstalled distribution (for possible rollback) + self.uninstalled_pathset = None + self.options = options if options else {} + # Set to True after successful preparation of this requirement + self.prepared = False + self.is_direct = False + + self.isolated = isolated + self.build_env = NoOpBuildEnvironment() + + # The static build requirements (from pyproject.toml) + self.pyproject_requires = None + + # Build requirements that we will check are available + # TODO: We don't do this for --no-build-isolation. Should we? + self.requirements_to_check = [] + + # The PEP 517 backend we should use to build the project + self.pep517_backend = None + + # Are we using PEP 517 for this requirement? + # After pyproject.toml has been loaded, the only valid values are True + # and False. Before loading, None is valid (meaning "use the default"). + # Setting an explicit value before loading pyproject.toml is supported, + # but after loading this flag should be treated as read only. + self.use_pep517 = None + + def __str__(self): + if self.req: + s = str(self.req) + if self.link: + s += ' from %s' % self.link.url + elif self.link: + s = self.link.url + else: + s = '' + if self.satisfied_by is not None: + s += ' in %s' % display_path(self.satisfied_by.location) + if self.comes_from: + if isinstance(self.comes_from, six.string_types): + comes_from = self.comes_from + else: + comes_from = self.comes_from.from_path() + if comes_from: + s += ' (from %s)' % comes_from + return s + + def __repr__(self): + return '<%s object: %s editable=%r>' % ( + self.__class__.__name__, str(self), self.editable) + + def populate_link(self, finder, upgrade, require_hashes): + """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): + if self.req is None: + return None + return native_str(pkg_resources.safe_name(self.req.name)) + + @property + def specifier(self): + return self.req.specifier + + @property + def is_pinned(self): + """Return whether I am pinned to an exact version. + + For example, some-package==1.2 is pinned; some-package>1.2 is not. + """ + specifiers = self.specifier + return (len(specifiers) == 1 and + next(iter(specifiers)).operator in {'==', '==='}) + + @property + def installed_version(self): + return get_installed_version(self.name) + + def match_markers(self, extras_requested=None): + if not extras_requested: + # Provide an extra to safely evaluate the markers + # without matching any extra + extras_requested = ('',) + if self.markers is not None: + return any( + self.markers.evaluate({'extra': extra}) + for extra in extras_requested) + else: + return True + + @property + def has_hash_options(self): + """Return whether any known-good hashes are specified as options. + + These activate --require-hashes mode; hashes specified as part of a + URL do not. + + """ + return bool(self.options.get('hashes', {})) + + def hashes(self, trust_internet=True): + """Return a hash-comparer that considers my option- and URL-based + hashes to be known-good. + + Hashes in URLs--ones embedded in the requirements file, not ones + downloaded from an index server--are almost peers with ones from + flags. They satisfy --require-hashes (whether it was implicitly or + explicitly activated) but do not activate it. md5 and sha224 are not + allowed in flags, which should nudge people toward good algos. We + always OR all hashes together, even ones from URLs. + + :param trust_internet: Whether to trust URL-based (#md5=...) hashes + downloaded from the internet, as by populate_link() + + """ + good_hashes = self.options.get('hashes', {}).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) + return Hashes(good_hashes) + + def from_path(self): + """Format a nice indicator to show where this "comes from" + """ + if self.req is None: + return None + s = str(self.req) + if self.comes_from: + if isinstance(self.comes_from, six.string_types): + comes_from = self.comes_from + else: + comes_from = self.comes_from.from_path() + if comes_from: + s += '->' + comes_from + return s + + def build_location(self, build_dir): + assert build_dir is not None + if self._temp_build_dir.path is not None: + 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 + + return self._temp_build_dir.path + if self.editable: + name = self.name.lower() + else: + name = self.name + # 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) + + def _correct_build_location(self): + """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. + """ + 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.path + old_location = self._temp_build_dir.path + self._temp_build_dir.path = 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), + ) + 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 + + def remove_temporary_source(self): + """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() + + def check_if_exists(self, use_user_site): + """Find an installed distribution that satisfies or conflicts + with this requirement, and set self.satisfied_by or + self.conflicts_with 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 + ) + if use_user_site: + if dist_in_usersite(existing_dist): + self.conflicts_with = existing_dist + 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) + ) + else: + self.conflicts_with = existing_dist + return True + + # Things valid for wheels + @property + def is_wheel(self): + return self.link and self.link.is_wheel + + def move_wheel_files(self, wheeldir, root=None, home=None, prefix=None, + warn_script_location=True, use_user_site=False, + pycompile=True): + 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): + return os.path.join( + self.source_dir, + self.link and self.link.subdirectory_fragment or '') + + @property + def setup_py(self): + assert self.source_dir, "No source dir for %s" % self + + setup_py = os.path.join(self.setup_py_dir, 'setup.py') + + # Python2 __file__ should not be unicode + if six.PY2 and isinstance(setup_py, six.text_type): + setup_py = setup_py.encode(sys.getfilesystemencoding()) + + return setup_py + + @property + def pyproject_toml(self): + assert self.source_dir, "No source dir for %s" % self + + pp_toml = os.path.join(self.setup_py_dir, 'pyproject.toml') + + # Python2 __file__ should not be unicode + if six.PY2 and isinstance(pp_toml, six.text_type): + pp_toml = pp_toml.encode(sys.getfilesystemencoding()) + + return pp_toml + + def load_pyproject_toml(self): + """Load the pyproject.toml file. + + After calling this routine, all of the attributes related to PEP 517 + processing for this requirement have been set. In particular, the + use_pep517 attribute can be used to determine whether we should + follow the PEP 517 or legacy (setup.py) code path. + """ + pep517_data = load_pyproject_toml( + self.use_pep517, + self.pyproject_toml, + self.setup_py, + str(self) + ) + + if pep517_data is None: + self.use_pep517 = False + else: + self.use_pep517 = True + requires, backend, check = pep517_data + self.requirements_to_check = check + self.pyproject_requires = requires + self.pep517_backend = Pep517HookCaller(self.setup_py_dir, backend) + + def run_egg_info(self): + assert self.source_dir + if self.name: + logger.debug( + 'Running setup.py (path:%s) egg_info for package %s', + self.setup_py, self.name, + ) + else: + logger.debug( + 'Running setup.py (path:%s) egg_info for package from %s', + self.setup_py, self.link, + ) + + with indent_log(): + script = SETUPTOOLS_SHIM % self.setup_py + base_cmd = [sys.executable, '-c', script] + 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 = [] + 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, + show_stdout=False, + command_desc='python setup.py egg_info') + + 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() + else: + metadata_name = canonicalize_name(self.metadata["Name"]) + if canonicalize_name(self.req.name) != metadata_name: + logger.warning( + 'Running setup.py (path:%s) egg_info for package %s ' + 'produced metadata for project name %s. Fix your ' + '#egg=%s fragments.', + self.setup_py, self.name, metadata_name, self.name + ) + self.req = Requirement(metadata_name) + + @property + def egg_info_path(self): + 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 + + @property + def metadata(self): + if not hasattr(self, '_metadata'): + self._metadata = get_metadata(self.get_dist()) + + return self._metadata + + def get_dist(self): + """Return a pkg_resources.Distribution built from self.egg_info_path""" + egg_info = self.egg_info_path.rstrip(os.path.sep) + base_dir = os.path.dirname(egg_info) + metadata = pkg_resources.PathMetadata(base_dir, egg_info) + dist_name = os.path.splitext(os.path.basename(egg_info))[0] + return pkg_resources.Distribution( + os.path.dirname(egg_info), + project_name=dist_name, + metadata=metadata, + ) + + def assert_source_matches_version(self): + assert self.source_dir + version = self.metadata['version'] + if self.req.specifier and version not in self.req.specifier: + logger.warning( + 'Requested %s, but installing version %s', + self, + version, + ) + else: + logger.debug( + 'Source in %s has version %s, which satisfies requirement %s', + display_path(self.source_dir), + version, + self, + ) + + # For both source distributions and editables + def ensure_has_source_dir(self, parent_dir): + """Ensure that a source_dir is set. + + This will create a temporary build dir if the name of the requirement + isn't known yet. + + :param parent_dir: The ideal pip parent_dir for the source_dir. + Generally src_dir for editables and build_dir for sdists. + :return: self.source_dir + """ + if self.source_dir is None: + self.source_dir = self.build_location(parent_dir) + return self.source_dir + + # For editable installations + def install_editable(self, install_options, + global_options=(), prefix=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( + [ + sys.executable, + '-c', + SETUPTOOLS_SHIM % self.setup_py + ] + + list(global_options) + + ['develop', '--no-deps'] + + list(install_options), + + cwd=self.setup_py_dir, + show_stdout=False, + ) + + self.install_succeeded = True + + def update_editable(self, obtain=True): + if not self.link: + logger.debug( + "Cannot update repository at %s; repository location is " + "unknown", + self.source_dir, + ) + return + assert self.editable + assert self.source_dir + 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 + vc_type, url = self.link.url.split('+', 1) + backend = vcs.get_backend(vc_type) + if backend: + vcs_backend = backend(self.link.url) + if obtain: + vcs_backend.obtain(self.source_dir) + else: + vcs_backend.export(self.source_dir) + else: + assert 0, ( + 'Unexpected version control type (in %s): %s' + % (self.link, vc_type)) + + # Top-level Actions + def uninstall(self, auto_confirm=False, verbose=False, + use_user_site=False): + """ + Uninstall the distribution currently satisfying this requirement. + + Prompts before removing or modifying files unless + ``auto_confirm`` is True. + + Refuses to delete or modify files outside of ``sys.prefix`` - + thus uninstallation within a virtual environment can only + modify that virtual environment, even if the virtualenv is + linked to global site-packages. + + """ + if not self.check_if_exists(use_user_site): + logger.warning("Skipping %s as it is not installed.", self.name) + return + dist = self.satisfied_by or self.conflicts_with + + 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. + 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 + + # TODO: Investigate if this should be kept in InstallRequirement + # Seems to be used only when VCS + downloads + def archive(self, build_dir): + assert self.source_dir + create_archive = True + archive_name = '%s-%s.zip' % (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')) + if response == 'i': + create_archive = False + elif response == 'w': + logger.warning('Deleting %s', display_path(archive_path)) + os.remove(archive_path) + elif response == 'b': + dest_file = backup_dir(archive_path) + logger.warning( + 'Backing up %s to %s', + display_path(archive_path), + display_path(dest_file), + ) + 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 + ) + 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: + dirname = os.path.join(dirpath, dirname) + name = self._clean_zip_name(dirname, dir) + zipdir = zipfile.ZipInfo(self.name + '/' + name + '/') + zipdir.external_attr = 0x1ED << 16 # 0o755 + zip.writestr(zipdir, '') + for filename in filenames: + if filename == PIP_DELETE_MARKER_FILENAME: + continue + filename = os.path.join(dirpath, filename) + name = self._clean_zip_name(filename, dir) + zip.write(filename, self.name + '/' + name) + zip.close() + logger.info('Saved %s', display_path(archive_path)) + + def install(self, install_options, global_options=None, root=None, + home=None, prefix=None, warn_script_location=True, + use_user_site=False, pycompile=True): + 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, + ) + self.install_succeeded = True + return + + # 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', []) + + if self.isolated: + global_options = global_options + ["--no-user-cfg"] + + 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, + ) + 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, + show_stdout=False, + spinner=spinner, + ) + + if not os.path.exists(record_filename): + logger.debug('Record file %s not found', record_filename) + return + self.install_succeeded = True + + def prepend_root(path): + if root is None or not os.path.isabs(path): + return path + else: + return change_root(root, path) + + 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') + + def get_install_args(self, global_options, record_filename, root, prefix, + pycompile): + install_args = [sys.executable, "-u"] + install_args.append('-c') + install_args.append(SETUPTOOLS_SHIM % self.setup_py) + 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] + + if pycompile: + install_args += ["--compile"] + else: + install_args += ["--no-compile"] + + 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)] + + return install_args diff --git a/venv/lib/python3.7/site-packages/pip/_internal/req/req_set.py b/venv/lib/python3.7/site-packages/pip/_internal/req/req_set.py new file mode 100644 index 0000000..b198317 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/req/req_set.py @@ -0,0 +1,181 @@ +from __future__ import absolute_import + +import logging +from collections import OrderedDict + +from pip._internal.exceptions import InstallationError +from pip._internal.utils.logging import indent_log +from pip._internal.wheel import Wheel + +logger = logging.getLogger(__name__) + + +class RequirementSet(object): + + def __init__(self, require_hashes=False, check_supported_wheels=True): + """Create a RequirementSet. + """ + + self.requirements = OrderedDict() + self.require_hashes = require_hashes + self.check_supported_wheels = check_supported_wheels + + # Mapping of alias: real_name + self.requirement_aliases = {} + self.unnamed_requirements = [] + self.successfully_downloaded = [] + self.reqs_to_cleanup = [] + + def __str__(self): + 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]) + + def __repr__(self): + 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)) + + def add_requirement(self, install_req, parent_req_name=None, + extras_requested=None): + """Add install_req as a requirement to install. + + :param parent_req_name: The name of the requirement that needed this + added. The name is used because when multiple unnamed requirements + resolve to the same name, we could otherwise end up with dependency + links that point outside the Requirements set. parent_req must + already be added. Note that None implies that this is a user + supplied requirement, vs an inferred one. + :param extras_requested: an iterable of extras used to evaluate the + environment markers. + :return: Additional requirements to scan. That is either [] if + 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, + ) + return [], None + + # If the wheel is not supported, raise an error. + # Should check this after filtering out based on environment markers to + # allow specifying different wheels based on the environment/OS, in a + # 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(): + raise InstallationError( + "%s is not a supported wheel on this platform." % + 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" + ) + + # 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) + return [install_req], None + + try: + existing_req = self.get_requirement(name) + except KeyError: + existing_req = None + + has_conflicting_requirement = ( + parent_req_name is None and + existing_req and + not existing_req.constraint and + existing_req.extras == install_req.extras and + existing_req.req.specifier != install_req.req.specifier + ) + if has_conflicting_requirement: + raise InstallationError( + "Double requirement given: %s (already in %s, name=%r)" + % (install_req, existing_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 + return [install_req], install_req + + # Assume there's no need to scan, and that we've already + # encountered this for scanning. + if install_req.constraint or not existing_req.constraint: + return [], existing_req + + does_not_satisfy_constraint = ( + install_req.link and + not ( + existing_req.link and + install_req.link.path == existing_req.link.path + ) + ) + if does_not_satisfy_constraint: + self.reqs_to_cleanup.append(install_req) + raise InstallationError( + "Could not satisfy constraints for '%s': " + "installation from path or url cannot be " + "constrained to a version" % name, + ) + # If we're now installing a constraint, mark the existing + # object for real installation. + existing_req.constraint = False + existing_req.extras = tuple(sorted( + set(existing_req.extras) | set(install_req.extras) + )) + logger.debug( + "Setting %s extras to: %s", + existing_req, existing_req.extras, + ) + # Return the existing requirement for addition to the parent and + # scanning again. + return [existing_req], existing_req + + def has_requirement(self, project_name): + 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 + + @property + def has_requirements(self): + return list(req for req in self.requirements.values() if not + req.constraint) or self.unnamed_requirements + + def get_requirement(self, project_name): + 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) + + def cleanup_files(self): + """Clean up files, remove builds.""" + logger.debug('Cleaning up...') + with indent_log(): + for req in self.reqs_to_cleanup: + req.remove_temporary_source() diff --git a/venv/lib/python3.7/site-packages/pip/_internal/req/req_tracker.py b/venv/lib/python3.7/site-packages/pip/_internal/req/req_tracker.py new file mode 100644 index 0000000..0a86f4c --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/req/req_tracker.py @@ -0,0 +1,76 @@ +from __future__ import absolute_import + +import contextlib +import errno +import hashlib +import logging +import os + +from pip._internal.utils.temp_dir import TempDirectory + +logger = logging.getLogger(__name__) + + +class RequirementTracker(object): + + def __init__(self): + 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) + self._entries = set() + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.cleanup() + + def _entry_path(self, link): + hashed = hashlib.sha224(link.url_without_fragment.encode()).hexdigest() + return os.path.join(self._root, hashed) + + def add(self, req): + link = req.link + info = str(req) + entry_path = self._entry_path(link) + 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())) + except IOError as e: + 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) + + def remove(self, req): + link = 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): + 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) + + @contextlib.contextmanager + def track(self, req): + self.add(req) + yield + self.remove(req) diff --git a/venv/lib/python3.7/site-packages/pip/_internal/req/req_uninstall.py b/venv/lib/python3.7/site-packages/pip/_internal/req/req_uninstall.py new file mode 100644 index 0000000..a7d8230 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/req/req_uninstall.py @@ -0,0 +1,460 @@ +from __future__ import absolute_import + +import csv +import functools +import logging +import os +import sys +import sysconfig + +from pip._vendor import pkg_resources + +from pip._internal.exceptions import UninstallationError +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, +) +from pip._internal.utils.temp_dir import TempDirectory + +logger = logging.getLogger(__name__) + + +def _script_names(dist, script_name, is_gui): + """Create the fully qualified name of the files created by + {console,gui}_scripts for the given ``dist``. + Returns the list of file names + """ + if dist_in_usersite(dist): + bin_dir = bin_user + else: + bin_dir = bin_py + exe_name = os.path.join(bin_dir, script_name) + paths_to_remove = [exe_name] + if WINDOWS: + paths_to_remove.append(exe_name + '.exe') + paths_to_remove.append(exe_name + '.exe.manifest') + if is_gui: + paths_to_remove.append(exe_name + '-script.pyw') + else: + paths_to_remove.append(exe_name + '-script.py') + return paths_to_remove + + +def _unique(fn): + @functools.wraps(fn) + def unique(*args, **kw): + seen = set() + for item in fn(*args, **kw): + if item not in seen: + seen.add(item) + yield item + return unique + + +@_unique +def uninstallation_paths(dist): + """ + Yield all the uninstallation paths for dist based on RECORD-without-.py[co] + + Yield paths to all the files in RECORD. For each .py file in RECORD, add + the .pyc and .pyo in the same directory. + + UninstallPathSet.add() takes care of the __pycache__ .py[co]. + """ + r = csv.reader(FakeFile(dist.get_metadata_lines('RECORD'))) + for row in r: + path = os.path.join(dist.location, row[0]) + yield path + if path.endswith('.py'): + dn, fn = os.path.split(path) + base = fn[:-3] + path = os.path.join(dn, base + '.pyc') + yield path + path = os.path.join(dn, base + '.pyo') + yield path + + +def compact(paths): + """Compact a path set to contain the minimal number of paths + necessary to contain all paths in the set. If /a/path/ and + /a/path/to/a/file.txt are both in the set, leave only the + shorter path.""" + + sep = os.path.sep + short_paths = set() + for path in sorted(paths, key=len): + should_add = any( + path.startswith(shortpath.rstrip("*")) and + path[len(shortpath.rstrip("*").rstrip(sep))] == sep + for shortpath in short_paths + ) + if not should_add: + short_paths.add(path) + return short_paths + + +def compress_for_output_listing(paths): + """Returns a tuple of 2 sets of which paths to display to user + + The first set contains paths that would be deleted. Files of a package + are not added and the top-level directory of the package has a '*' added + at the end - to signify that all it's contents are removed. + + The second set contains files that would have been skipped in the above + folders. + """ + + will_remove = list(paths) + will_skip = set() + + # Determine folders and files + folders = set() + files = set() + for path in will_remove: + if path.endswith(".pyc"): + continue + if path.endswith("__init__.py") or ".dist-info" in path: + folders.add(os.path.dirname(path)) + files.add(path) + + _normcased_files = set(map(os.path.normcase, files)) + + folders = compact(folders) + + # This walks the tree using os.walk to not miss extra folders + # that might get added. + for folder in folders: + for dirpath, _, dirfiles in os.walk(folder): + for fname in dirfiles: + if fname.endswith(".pyc"): + continue + + file_ = os.path.join(dirpath, fname) + if (os.path.isfile(file_) and + os.path.normcase(file_) not in _normcased_files): + # We are skipping this file. Add it to the set. + will_skip.add(file_) + + will_remove = files | { + os.path.join(folder, "*") for folder in folders + } + + return will_remove, will_skip + + +class UninstallPathSet(object): + """A set of file paths to be removed in the uninstallation of a + requirement.""" + def __init__(self, dist): + self.paths = set() + self._refuse = set() + self.pth = {} + self.dist = dist + self.save_dir = TempDirectory(kind="uninstall") + self._moved_paths = [] + + def _permitted(self, path): + """ + Return True if the given path is one we are permitted to + remove/modify, False otherwise. + + """ + return is_local(path) + + def add(self, path): + head, tail = os.path.split(path) + + # we normalize the head to resolve parent directory symlinks, but not + # the tail, since we only want to uninstall symlinks, not their targets + path = os.path.join(normalize_path(head), os.path.normcase(tail)) + + if not os.path.exists(path): + return + if self._permitted(path): + self.paths.add(path) + else: + self._refuse.add(path) + + # __pycache__ files can show up after 'installed-files.txt' is created, + # due to imports + if os.path.splitext(path)[1] == '.py' and uses_pycache: + self.add(cache_from_source(path)) + + def add_pth(self, pth_file, entry): + pth_file = normalize_path(pth_file) + if self._permitted(pth_file): + if pth_file not in self.pth: + self.pth[pth_file] = UninstallPthEntries(pth_file) + self.pth[pth_file].add(entry) + else: + self._refuse.add(pth_file) + + def _stash(self, path): + return os.path.join( + self.save_dir.path, os.path.splitdrive(path)[1].lstrip(os.path.sep) + ) + + def remove(self, auto_confirm=False, verbose=False): + """Remove paths in ``self.paths`` with confirmation (unless + ``auto_confirm`` is True).""" + + if not self.paths: + logger.info( + "Can't uninstall '%s'. No files were found to uninstall.", + self.dist.project_name, + ) + return + + dist_name_version = ( + self.dist.project_name + "-" + self.dist.version + ) + logger.info('Uninstalling %s:', dist_name_version) + + with indent_log(): + if auto_confirm or self._allowed_to_proceed(verbose): + self.save_dir.create() + + for path in sorted(compact(self.paths)): + new_path = self._stash(path) + logger.debug('Removing file or directory %s', path) + self._moved_paths.append(path) + renames(path, new_path) + for pth in self.pth.values(): + pth.remove() + + logger.info('Successfully uninstalled %s', dist_name_version) + + def _allowed_to_proceed(self, verbose): + """Display which files would be deleted and prompt for confirmation + """ + + def _display(msg, paths): + if not paths: + return + + logger.info(msg) + with indent_log(): + for path in sorted(compact(paths)): + logger.info(path) + + if not verbose: + will_remove, will_skip = compress_for_output_listing(self.paths) + else: + # In verbose mode, display all the files that are going to be + # deleted. + will_remove = list(self.paths) + will_skip = set() + + _display('Would remove:', will_remove) + _display('Would not remove (might be manually added):', will_skip) + _display('Would not remove (outside of prefix):', self._refuse) + + return ask('Proceed (y/n)? ', ('y', 'n')) == 'y' + + def rollback(self): + """Rollback the changes previously made by remove().""" + if self.save_dir.path is None: + logger.error( + "Can't roll back %s; was not uninstalled", + self.dist.project_name, + ) + return False + logger.info('Rolling back uninstall of %s', self.dist.project_name) + for path in self._moved_paths: + tmp_path = self._stash(path) + logger.debug('Replacing %s', path) + renames(tmp_path, path) + for pth in self.pth.values(): + pth.rollback() + + def commit(self): + """Remove temporary save dir: rollback will no longer be possible.""" + self.save_dir.cleanup() + self._moved_paths = [] + + @classmethod + def from_dist(cls, dist): + dist_path = normalize_path(dist.location) + if not dist_is_local(dist): + logger.info( + "Not uninstalling %s at %s, outside environment %s", + dist.key, + dist_path, + sys.prefix, + ) + return cls(dist) + + if dist_path in {p for p in {sysconfig.get_path("stdlib"), + sysconfig.get_path("platstdlib")} + if p}: + logger.info( + "Not uninstalling %s at %s, as it is in the standard library.", + dist.key, + dist_path, + ) + return cls(dist) + + paths_to_remove = cls(dist) + develop_egg_link = egg_link_path(dist) + develop_egg_link_egg_info = '{}.egg-info'.format( + pkg_resources.to_filename(dist.project_name)) + egg_info_exists = dist.egg_info and os.path.exists(dist.egg_info) + # Special case for distutils installed package + distutils_egg_info = getattr(dist._provider, 'path', None) + + # Uninstall cases order do matter as in the case of 2 installs of the + # same package, pip needs to uninstall the currently detected version + if (egg_info_exists and dist.egg_info.endswith('.egg-info') and + not dist.egg_info.endswith(develop_egg_link_egg_info)): + # if dist.egg_info.endswith(develop_egg_link_egg_info), we + # are in fact in the develop_egg_link case + paths_to_remove.add(dist.egg_info) + if dist.has_metadata('installed-files.txt'): + for installed_file in dist.get_metadata( + 'installed-files.txt').splitlines(): + path = os.path.normpath( + os.path.join(dist.egg_info, installed_file) + ) + paths_to_remove.add(path) + # FIXME: need a test for this elif block + # occurs with --single-version-externally-managed/--record outside + # of pip + elif dist.has_metadata('top_level.txt'): + if dist.has_metadata('namespace_packages.txt'): + namespaces = dist.get_metadata('namespace_packages.txt') + else: + namespaces = [] + for top_level_pkg in [ + p for p + in dist.get_metadata('top_level.txt').splitlines() + if p and p not in namespaces]: + path = os.path.join(dist.location, top_level_pkg) + paths_to_remove.add(path) + paths_to_remove.add(path + '.py') + paths_to_remove.add(path + '.pyc') + paths_to_remove.add(path + '.pyo') + + elif distutils_egg_info: + raise UninstallationError( + "Cannot uninstall {!r}. It is a distutils installed project " + "and thus we cannot accurately determine which files belong " + "to it which would lead to only a partial uninstall.".format( + dist.project_name, + ) + ) + + elif dist.location.endswith('.egg'): + # package installed by easy_install + # We cannot match on dist.egg_name because it can slightly vary + # i.e. setuptools-0.6c11-py2.6.egg vs setuptools-0.6rc11-py2.6.egg + paths_to_remove.add(dist.location) + easy_install_egg = os.path.split(dist.location)[1] + easy_install_pth = os.path.join(os.path.dirname(dist.location), + 'easy-install.pth') + paths_to_remove.add_pth(easy_install_pth, './' + easy_install_egg) + + elif egg_info_exists and dist.egg_info.endswith('.dist-info'): + for path in uninstallation_paths(dist): + paths_to_remove.add(path) + + elif develop_egg_link: + # develop egg + 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) + ) + paths_to_remove.add(develop_egg_link) + easy_install_pth = os.path.join(os.path.dirname(develop_egg_link), + 'easy-install.pth') + paths_to_remove.add_pth(easy_install_pth, dist.location) + + else: + logger.debug( + 'Not sure how to uninstall: %s - Check: %s', + dist, dist.location, + ) + + # find distutils scripts= scripts + if dist.has_metadata('scripts') and dist.metadata_isdir('scripts'): + for script in dist.metadata_listdir('scripts'): + if dist_in_usersite(dist): + bin_dir = bin_user + else: + bin_dir = bin_py + paths_to_remove.add(os.path.join(bin_dir, script)) + if WINDOWS: + paths_to_remove.add(os.path.join(bin_dir, script) + '.bat') + + # find console_scripts + _scripts_to_remove = [] + console_scripts = dist.get_entry_map(group='console_scripts') + for name in console_scripts.keys(): + _scripts_to_remove.extend(_script_names(dist, name, False)) + # find gui_scripts + gui_scripts = dist.get_entry_map(group='gui_scripts') + for name in gui_scripts.keys(): + _scripts_to_remove.extend(_script_names(dist, name, True)) + + for s in _scripts_to_remove: + paths_to_remove.add(s) + + return paths_to_remove + + +class UninstallPthEntries(object): + def __init__(self, pth_file): + 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() + self._saved_lines = None + + def add(self, entry): + entry = os.path.normcase(entry) + # On Windows, os.path.normcase converts the entry to use + # backslashes. This is correct for entries that describe absolute + # paths outside of site-packages, but all the others use forward + # slashes. + if WINDOWS and not os.path.splitdrive(entry)[0]: + entry = entry.replace('\\', '/') + self.entries.add(entry) + + def remove(self): + logger.debug('Removing pth entries from %s:', self.file) + with open(self.file, 'rb') as fh: + # windows uses '\r\n' with py3k, but uses '\n' with py2.x + lines = fh.readlines() + self._saved_lines = lines + if any(b'\r\n' in line for line in lines): + endline = '\r\n' + else: + endline = '\n' + # handle missing trailing newline + if lines and not lines[-1].endswith(endline.encode("utf-8")): + lines[-1] = lines[-1] + endline.encode("utf-8") + for entry in self.entries: + try: + logger.debug('Removing entry: %s', entry) + lines.remove((entry + endline).encode("utf-8")) + except ValueError: + pass + with open(self.file, 'wb') as fh: + fh.writelines(lines) + + def rollback(self): + if self._saved_lines is None: + logger.error( + 'Cannot roll back changes to %s, none were made', self.file + ) + return False + logger.debug('Rolling %s back to previous state', self.file) + with open(self.file, 'wb') as fh: + fh.writelines(self._saved_lines) + return True diff --git a/venv/lib/python3.7/site-packages/pip/_internal/resolve.py b/venv/lib/python3.7/site-packages/pip/_internal/resolve.py new file mode 100644 index 0000000..2d9f1c5 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/resolve.py @@ -0,0 +1,353 @@ +"""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 +from collections import defaultdict +from itertools import chain + +from pip._internal.exceptions import ( + BestVersionAlreadyInstalled, DistributionNotFound, HashError, HashErrors, + UnsupportedPythonVersion, +) +from pip._internal.req.constructors import install_req_from_req +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import dist_in_usersite, ensure_dir +from pip._internal.utils.packaging import check_dist_requires_python + +logger = logging.getLogger(__name__) + + +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, session, finder, wheel_cache, use_user_site, + ignore_dependencies, ignore_installed, ignore_requires_python, + force_reinstall, isolated, upgrade_strategy): + super(Resolver, self).__init__() + assert upgrade_strategy in self._allowed_strategies + + 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 + + self.require_hashes = None # This is set in resolve + + 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._discovered_dependencies = defaultdict(list) + + def resolve(self, requirement_set): + """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 + locations = self.finder.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 = [] + 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): + 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): + """ + 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): + """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): + """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, req_to_install): + """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.dist(self.finder) + try: + check_dist_requires_python(dist) + except UnsupportedPythonVersion as err: + if self.ignore_requires_python: + logger.warning(err.args[0]) + else: + raise + + more_reqs = [] + + def add_req(subreq, extras_requested): + sub_install_req = install_req_from_req( + str(subreq), + req_to_install, + isolated=self.isolated, + wheel_cache=self.wheel_cache, + ) + 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): + """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() + + 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.7/site-packages/pip/_internal/utils/__init__.py b/venv/lib/python3.7/site-packages/pip/_internal/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5112ad2e4a6388b2af25f0a9ed70b3b7202536ee GIT binary patch literal 200 zcmZ?b<>g`kf*$Fl7!ds!M8E(ekl_Ht#VkM~g&~+hlhJP_LlHt<8 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3f01e4b53485b2d3427c263ec595d4d867c176be GIT binary patch literal 7921 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/compat.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..21373185b39026c8239341404905a83af85123db GIT binary patch literal 5991 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..17e8cf777cdeb2605d8cef899494a4a341abbce1 GIT binary patch literal 2574 zcmaJ@%Z?jG6z!KEV|yN%Bs_wGN&*BHi5(J=C=o&#CQ%XrP80@0ETpE~RknMkUsP3l zV&iO>EWwEZmQ6;YSt7fbc)#7@8&D5(=BX0Ja zw#A#`N6f25t$4k^9&hwFZ0nB2>TK_cZ?0jMrm{CX2h5!% z-p&eA*{&96{Zxdb5T5vQoE|R1qG*It=7S)jQX23@ElNk2HY(OeTz!K&7e#F`yIm`4 zF_)5#cu_|X@lh&p>ccQX#KpX*A^>@k7M|`YJl#T{v2k)zVjWE2AXiYF(*$W6ExV4N zV{bbRw_&#&#}<0*wQ#DS!!Y^@D$3fo8TeujbANYjOSxdSt{L916E|dt4Qx>~SCASwE54ZcGY-AA2qAxA&oBM{ z6c(h863f~0>UPx@1oc2`jDB>eEFDs4FneyjZ9Vno&>V!w`v@8L1%l+IeNFeeruQcE z5GL-CjhPk9s9;8AF#}X!-OtKV7+22RIkFEbXnS+-$o|b%mHq16Qy#0bnkI}nAg50M zMEu_6QO1SVkK@pRgggnQ(yB7dlc2oYp_+CY4T48NVAAA9@f2O5eBCA)Q@OM>;5<1&!8(iWvWNyo?cUr|=7>~4O_TrG7lKLk;U>_( z319B^nr|BIlms-;f_q0;$|1pTdIb{lh!NZ+&=RK;&PbS) zW;JCGX(+J}@s9F*1+IW!P)Kod?V5{34Bm`B9WO@^sh?x9anXBsjL69$JOKw^Z2 zGRUP)5QL&T6X_&moD4Z<18lR1mYwL3P9@2pG+4Pj$_r#cuUTuLYY+!~dYB4Es2JsC zegh5yof3#Yg9nGHJqaM&M22c{RCN6JJ0weiPG`iGeF-@I z^=W7J!C0wG-spBmp&I9dPLRgkY?@J{{sxZh&N}3Anwy|7j;}Z@_=pN-@~%F7fP&Fi zIvcbdaR#5Ffy@#dM0~;{=w}sf#8efoR6@9Vd~+Js+KpcXs+Nd zY75?qia{w(>lJP;q7`{E%G6k1XLc2HN}+vM3+)Epmc8M=gRi)NF{BZs{$BfRQS*J4 z24(gg<|-G+#6r6zwsfK4_0OAxGl7n#qLaZ%suM?NaWhKqT+9(#?ZihYivQ#&lT$lt znqi&LI#^T}4K0j9C(xqysQgoKqR6EP6FozNUh(%tj_Y5P{~5m297~-dW>$l>@!LF?2MnwCK!YRHv#H9jI1jDX;X3N6ah>?>{*)M<%gIF7t_fVDP%kjqQ;M zz0R$1eu9XVbtC!7^tM^w`g;UjP3epa#F^mqhjhoq3Civ)7lz-qx->lS08C>3Q;zED z|41rR41~H2DMH&ppUD~fvZX8%$UvE`q^F!&SXnHJ=`X|=f$iT!XRwoPU z(~M$Cc^ojmFC!-W+2yP0Kox_&Oq$d2uK)*e85FYSv5Oat1-ytC@I1CKzX8$mC1q!8 z3I)%ql))*#ni&pkwfXi<{hlhES?e3BbZ#~`YZtxewezxSHyMlb;h z8{T=SJx_RQ4J}~8682{{v<38--}p)0?9zwIn@T+@LOmNTV-bN#lMo7XNnewyFJv^+ zAmEm(w%|RQzk_vAvJw^+e$p`Kd#hvzz)Zv5J`mP|!deRkpcJ0Ry7f*@2(bGPtXqS1qdcWz fy`lQA`lkPx`(}juJk7;2kuS`~m06QZIG*(ziL9x6 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d521cb8fb13792bafd2a8984bc4bcf807bcdf27c GIT binary patch literal 1558 zcmZ8h-EJH;6t+FHv(rhF{tzle5m->9j7YK}6`-I}eo7;RqNr*r6@{YF?AW_I+4;lv zB+Y7a6)w5s1(HkNfhX}TSG)pOoa0SIle4ltdu)F`{=Rek-Qr?Iz<$3!eD&7?A%Eka zOJnfy4K)1&bb<(4kdp3Gir=hY`^=5rzUM}N-xr?ne+7oE{8FYr6Q9;k?2|12Ba==dLOHwWS z#CX$4tx$qLLHEc{u=2p~XwvKGDLG*#=$PrBGQHEWGdLa)ScgG)v#saSw5rm4T;#)y zA4;Y3y5icXyc)0aTJhbwk~|;rsy4jU;GHjB-?hC|XL%mqut8>y8>y}T3Ru07C4-1$+X_|0L=b`2MX1jmi&GBL|168jR{fz@-M|WRQK@BwMqs zgN>tyBQevTKRi^Mug$F702^0>7lS5m)?5TdvG&;)!^yNAj?w8_l2=BmDlG=B$qPMj zgsnHnaNjpCije?GsGDAfj`SnSXhfI1zzb=>A{sGu2mBezi{@W6Co|^QT;`6PvlFlL z^aI1rJi$70j~M@)fyCY(F}=<^3xt18PiaS|tlqxx^qhxHdmwMHJA1J5^|ME1dQhv! zKX0sU{qjltYTdc=>VMbltEaCUnHedrrNL2dCVZ1;HDqQbE2FuCS}$?;Dj(P8Oa8Im zwms*D0sV2`G9}SxvWX3kQdI#VkRAACm!7wk$xHci?zSG#YI|c zQj-r0IS+9YR%%QT0%3&^mihp`GjyO)Xc*wtphyR$?Sg{B6<$Y1I6{E2Kl|f_I_9S4 zLPCZDNs^n1yeefBaj?r`Pq}HELh^caQR$kmKoYNB)_=^8CV4giz){*32C-$?nB&XU z4lJ*Dmg@OgMO{zZhL2LHjCD7=8#7B3hkJm!SRgTVX%8>n;uWE;a~57!(~q!sPE+7$ zV(KICz;hEN$*6@_OD2gzq7+J~u-Mc+?6A6=K8{zn>y1P3jZiLa!bfE-+Cn}?#$B%5 QWFZI=df~g_?eLxd0NDzb)c^nh literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..26f218885a6431278bc319d7443e7d2493432535 GIT binary patch literal 3335 zcmbVOTW=f36`t8$E|(N3$%^XMaZyYf6b{pfjO{wD4Wo!_yRnT_X=T+;775nNogumA zUZ|O&E(G;r3CK%}{srl=@BIP&9sAm+{DnOAoLQ2RTm=ET#LOP!C#_Pv~*Tu?_?XSZBCEkGl4Y3OUuW;)* zX*Iut`$>xyD`8jV$ykdZPDi=an=QMj#ac)hsVY1qhvGmLb)uz&O;m`4w(+=a~8quWKNY@V&-Y z_$s{XM)9@6MPY@Sgb&!B3`Zj&nI43ib;ohS6-&p7jz@`L1H;B(CC?(k!i=+MAfllH zc9F8MAI6|)oxwBA^1W=MpXZ#F7OI=in~?>=_MI z++s~~vl9=!HwtB#&cwLK9xxt9AWM&hNk0eo3{sYbsZeZ`$C(DpGo7;}R$7%zNxmoe z;xs&QAok&qz5tfR_f2q)7l6BvyJZ!Q5=pOcOXdGb9v zRVN*EqMM`O?&R+4kN0l(_(Xkjdsp7t*OT;Pc=}mqyEBSM8)zoDVB^kjyMy7l+sBV) z1R%GNS(tRjI!;ulytF+!0Eu8N)XDeM7$j zjxS-nB>Nvs@f3FG?7yq4Q_GyWd{~)QPQ0meN-5dlaNY~x{7~0s>%aKgIukW5nUk@k{u2vNW}Dw?U>odGiqQ#SD(-=qphM5ClgfLN)8jJY^V+VHZ#e zcqpR^sD)E`sKa)NLG=4p7%Rchdh>{7agSwiCNuGSj&<^rzh(x_26qNv_t>x0W~(7F zb;)IziYf}1#NEQq#9mQ5=sYvJyls-E3LXg%x8Spiv+B zbDS`I&Lov6&s`WLr0JwN6QH!jg)7nA=1Md(FjPX;ixaVt#6v(w z_qB-h|Ahol<2|@p)?k{cR5*C@TRIhM7p;dZ_hC<|qC2^Esg03qp)Oh%uQBQ}Ai%Oh{tMY6UqYe8Jh@p|vWw{|ABjx94|`g62_t6|>VZV>|A?T-_XyY& zTAI)X{Q*&tFQUi;555r)MpVo>^CV-u^3j&iW0|qNfq)tz*;7*)pmZFZFA<1i03Ax- z&GV!L4J|=)5iiA35I~qtgv^8B3EWm1)tao$adWnOxri8r2%gg!PN{6cm)7OCLDofq zg5dMTRrFleE!Pn3OPHWBHiMw32SJ+iae{Os2zJI{GFzzz0nei#kng~8C72NZ##{0R zQYef35T`S}4TWJXn=oOmR2X!gAJpp67UuS&d*}@z^s;eE`Jyj^SI5 zu?IZ^bPd=ud`leY7{F<6(S)RkjZ10L$-kj3$mK9J@zcwt$(xXT$4YQ?EO=MkkdQgc zT`Vj!C31#Lik)#RMJlpc&^^^G%F_|_SEg-XVWh!8MK_a5ch z4eT#^rXdpS)vFSyuU@g?UMTx*Kn;3gv*i>OHHN-PcHpn^ZqfYXgBM?HJ>7mBJbCc^ z$qZl6TGWCdNULmRF!U26@ar#FV20nsB-O^NCiE6^degI$sFT((ubZ%SubfK5gH znOUEAPwfRTR9S_L5is(Lw-`;E)du87CaoJo70u_{TVHH`W*qnUdEu5d!^BtV;7ek& d@a~sE|9eb`CO{jOXRTZ7cEfQhb$j*Re*wWvINJaK literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/logging.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/logging.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d969623e0cd59be3d33cb5c00445008911fd2b5f GIT binary patch literal 5368 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/misc.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/misc.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..acfab0cc9a9a4384c875e9dad917ee06714b45f7 GIT binary patch literal 23914 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/outdated.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/outdated.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..95ab0a5570ec1da181b98f715a43e2db57368a13 GIT binary patch literal 3921 zcmZu!TW=$`6&}uvq|sQC<=b9!8KiX=F4l6IAZ@eQZjZ$x@DKhq%lZ#}%pVtxk5JS2e1-L}o!X*=fawq5fswaeyRX;<)e z5-+W`tEu1ijhve-q_uY4v`a}NU2HF!b~$OLOYJ4ot|ZIpN_)k$y<|0AYpbs z>*?k?KUn|d-uh?v*7w^T+UNYS(f9~Oy@5(tZN@EFn{gZGa=61?yj@P;j06tcguo>*U6Pp#~hYiVCE=vvnq__E6^`h8_(_LrE2ec5~ChQh{- zeOi45OV*1L?4U)_FfX#ZF4UFk=*L$ z2|TN|(%x3*C&Tc=@rV6)Pu}nHvHI!z$MU^XJx<@nbChizYz^b#=A}b7Kls^UZ!kJM zqE1ubYAs|IC0ipMCu%DnX^usBYj{?8Ax2{zhBwF|%cv|?W@X1^O=hzi3)reNzW%B+ zTXUHXd6S+J%9U6Dg%5blQa;&SvrCVn=K@|-f$1&1+RH5CSu^L`F}?@|9%;E?a;U4+ z0s@*-NBids6X$|W-4~wE+}N7B6Z^cT>lZ)~XMeRPu5R=f?^`ojZa=euA4vC`6L(_J z%1h5(2GqR3&%9-@Ql`7;Cy~;jflE;vo(<#qWhvOn!G`@kyZb%6hj~?n%Nq^^0O2b! zjAW#9sWz5m9mbFzRSl{ZQ56;3!7NIJtWp=*u<&+q=XdDNm&IwUw316SM*fg1W`feP ztK(D@%lq5AI}bnEe)wtl=;MR!aOblFxk~faXr9YQ>2RYYZ&FV{J+;nAN|EW1q~&eu zuTe#an^kYpG*?B(;tpEsEmW3WX0Ef$TzA=Num*r|&2}A+HSp!L@ycs}Albc*5}}C> z7KVi%hH1`6xJ+SD3&XERQ8F8mq+V`P^9Z;@I?>N2wBt6 z#{)FZ-qF@Mn*b(LIQ|@Tbiwj>xQ(_$?Lm3p0x4L17liQh86j|IA9TT85JGAEcSBMt zIOz%96EXnh1}BjUuIMp1JPUA>d_TZ*(2Fsof{_wD$Z{R%Jm9e!Cec{{@nAGOk`Wg{ zDwF~_lh%x+NhZ#MZq(66&nwzNBU+@va7O4s8f6fbcLO!*^a5;!XWbyrf*rwg8MTaj zQGL9(fAI0{?)HUy{j+CUHBqq-A`F>khK2^&%CfLPxmtQL#+p^RF<8Gogyr zM=#Ca%k@q^$~aK%z!*Rj4ZiS|LCY#k^il*lJPT#Kpg`r{$ zj85W0#-BJ7e_(yb$U0|1-VF@XDMEFgbwn`4g*Xvn&)L-+VQan zj$^5D*+q67V0mEPTni=S9Tog`fBQ-J@MDly_~`MI0CWjWdADok%;Km~hmDXF-5b@B z@lfM#=-v$Z@;yLkZ-dEOc+0n`3Q)y=x>vP!ka+lABt(Sk0jQXAqtkFC6IHAs*U3*p z)FD=qA`y`S^y^xVaQk@J%fY(EjiJnuYN?P5M0-wVxzts`Y)ZYZsE8QC@$M&4ddQ;(eZ9*;BZ_?a+1791Jx^F6isoeWrPjPks^OV(wr3GdPJb+q7l~wVW%Us(>aaqmw?N#K59xK~T<~yEkW3+}$5p$SFv+%Ro zs*9Np1pwbcHVH}eIt|FssQf+jZoEx7LU*L;Pe~{#uuBRcCg&+CWH>TdC08xF{Im3l z@*HE17S5C*9GdLO1itnf4l(bB2>m&Nf|-*Zk=%-zFwccs#^VMP#jRIIOqSdNw6XBa zk8l0I3G`QC7P?J>2kxK^T1?{e!ANEB@&oE9g t(^%;xPhI6mg?E3JT0J28Q30x&jZ|s&gN%vX>NIq{{bRpH_-q9 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3db7299751d74078fee3b7f29fa63a16896086b2 GIT binary patch literal 2400 zcma)8TW=dh6rR~#+w09bPSYf9xvrp9WvQ`yfnFq35qcw{n5YS~SfI^jXKb&tx6X{y z#&QrMzyt6joJaoByza`q}r(_PRG&v zay*x~9apa_aV?qe%wt52Nu4en;m$c?lj_f?vq&5=2lIL2k{ZlQWS-PvUM9vSYAn0~ ze^3L+@|!Uk)P($}etid&e;~9c}Iz6+@PCZ+nXk>GsU-%wX1?ed45P z%C+&S?S!VHdD_piYVr-JP3D#UX=El`Mz8Z6_fz-ry#Nb?r`1cj%`@jF+I#KfbJBwRn|1NyRZ;| zZh;5Jp}{^FBS17@SFbF!I>6~Qtp!Z8yRfndtU$XWN|Q1%MP-Zz_8~qppwTVpiRvLz z$e%c4cpD>F%^e}t18r%4`DknH;o8>P$lmzk$?AIh@mHe@?aWK42uL6TDDyBSstvAi zi5jkSBCd0jhLl<0s$6;)aj_0%Q!|TpAT3!c-G0FRnGxyssQ7nRjQuoN=K zY-PuevoKKaGKC{)b%9A_DU35t0T33Df{^yH#W{5h4564t*Sioa@G5&3#AO(K2?W9} zc8XyvV#_GQPTx4rzKX(yp|k%hEL8RnA)jMB!8+f@{#^n2JH-5R0o+0i$Zu(E0M7u& z2wPMK4v_FM&veZd;G&=KbClk;keC~|yAJyiqXQG8(Tb=|=1HlrFgA}YMaG*j4$L3S z7wB7*8ZWe_QErdw&!$LP-O#i&`sfPxX6W(?op<#Lzv@BS3kDgcDy6fth(q0&;!UOi zIJ&c;;Yva4L4{8C^O;Y1z(H(Z-CG6GsOy|b6AG!Z%PL?_Ui>=c!(5R+u)g;2n}XD( zo3m^{L*b`ELRn2YFt0>i3DpqnoD!NV7S0k7drzIc529hQ4`C{PNfbBuBnkyvR60!0 z6kfhnw4Z{?*&e(FZ}4|OAZ!By43HK`H7+Y$!0a0A8k`^F!hnr}qQ=EdSU{)2Zw~Za z^R?A=;g|D_>qPVGuyJd-rn3=d;0XzGj<7#G)$)4kc%f< z!jGera#>OhlsAkbW=kp0hFDXtP05L}$6%>o7Kmv9VsbINp+2%A9pCQ`;fIL&K2wp% zit0MmZ7TcHrAZLQ&1nOvFy$OjToYI{B^lGL-B~`NfvZ!Z(?u&Ny{0eB7;%b;Q@W;R z$z~GquxRrt1n{)zf7{pS00(uw6(wqv=`!dzPDHObovHSg_9sb3hB3Xb{u=O$AY8*% Su^TR4fZ-aBX)oDz`}{u})s&O~ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8779cf38d64cd3c652936d0cfc61da841a5c0548 GIT binary patch literal 395 zcmYLF(MrQG6wT(#5X3iMeCdm{fo_=&l~E@m2nyFk_ zllzCKZ=~C9o1Oe_h|+u&TOg}glS~Q*+K_xf(o;o;)$qOlG00eDE(R-owzgH?cbFGs zN)%UJUKkq-(LKLR7Rxf3*UcR%FD&RH7NoRX81jE7nv`6yp4x0XSGi=Rfa|^bz>eq- DCyaT! literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..205a0fb6204181e8944c9e59840de3c9c8d789d7 GIT binary patch literal 2812 zcmai0U2oeq6eT5DmYq0hw{8u#VdDx6t+CW@*KJ*kqWfsE4MXb!tAPQ=06{kCSdP9* zQfcZqPc6`w?LQ=s`%8M=)BeJqb}uD6P3mAWL`oug@8!AY9{Pt?t4ZMcOsQ^rxA(ifKq(6B5Poo-X1unuMKL@+mRdB2X#t>b>xZ0F\BHZD% zSA^HZ+Dm(|&aJ1U?fwHcNt+g%!BC}9u7w}QSt@l8zPU2iQiu^wSzH(lUg{TU1Q}3H zAOJeB`GwbHOpS{MgyQo0D*~Z-yaBz-n|uxWI$!54=smu{H=%F5CJq@iA&`qjt1sg0 zVJO8&r}9N`)h6U;5oJQMQ4}b}^d!(MeV!;5Bpkkp03P#<1x&-jR0i?|gO(nwjW53-o09f*&5Gqtc*GVLO72qzE*`v%)Nf(@PVvT+c-$^vNrl`)wk? ziZrH{J7;Q=<`KuemP~fg zQ)L4ilr@l&hVPpy_Wi%ezt6gv4EKQf-Mv6|$7#fcRNZ*e9o@|QJF`2}8_#cz`AmI% zYfpZ$uV?WMxOS3mzng{G^)OL7h@$IX-5ySM^WhGDG&ckWIY@%2o9i%AUBtu()H>M< zS%)w_gIldbL+FNe!FDW{x^(t_|4rHHEVehII1w)Fapw=<29-9IYw%UJmd!>r2{p&}Z^E0hpdl+l zE2o?a4X2vW(AS(C5tCue9W@eO()1j!kQKvQ-~SR;E8Hfb9-Uo2i%B)>6vLLD5fp%e z$PMsM(ZAsi__quPih5PQZO81ru*LqUsO<$&E(%KzS73ql;QL73DyUV7Dkq&n!-W+F zjeZpqr@IXhNP1*(>j-!~CCBubLWJ}w(aw|{)wDaUbK8u0$8diA3FE+js2EsNJG-Xs z&VDSVj{T3)fzVw&Q97)O&MB$u%|3s+8)g~EzsXT`&LC;eoMm^}!Qrfq)IT`9j>j^b zP2+HX_DLDY%Hspqv>S$Tg&UQT);!obPbl;Q6iL&;glQo+CYAppmAJz<1#Sfs|Gf zBU)V`@)8U^hFc-Ah`mLdboSnvE#e=MJZsy%o~*&7_L{r^UD5RYIOTZ+gruN+j;1mKp_Kw>;1p&sw*d_J5%j|H$Hc?BU@#{_$H( zdh%|f_ulR4{of}KZmBZ_pZGwIRcc4FUEgxYE?Kvtm{hV2rLmWlb=2FwDvFD4?8gf# zDH;AGhDkZqj?qR+-nX=28X_YMGhQL~VvBS^o!3LlQ`#8Yn4%AUZ8c&VADEVdYm)VV zvT2l+R>DWMKqblieY}YQE%15Cj)Q93ar%FTjUQS~3zmX>NUTXE3Ipougr^o#T1rX= z8%q@pQc_viM5;-V6n^A<>H9AaY7eH)Co*a+P@}+>8P~5l7*@zT7O2Or9N7IB37}~R zE|MS8CmbP^;H=qcAJn21tq_{!irlN967=;$XpnK~Lvc1H1C~ei?%}wib2G##iU3yQ zH7^ttZhH6+Gn4r>9w3f{K2#ZPs;oR9LXyLWYI9RY(Sh@PVhAgFZ_)4{H`NQLd`7kV2@-qK#^s2L7 Y^|s2YAFsZ7x;4hLd-6@($8>xDKT7Duga7~l literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/ui.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/ui.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..39adfe57e5868c690eb82ccc6e66b485f3296584 GIT binary patch literal 11869 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 + Unix: ~/.cache/ (XDG default) + Windows: C:\Users\\AppData\Local\\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\\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): + 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 + + for a discussion of issues. + + Typical user data directories are: + macOS: ~/Library/Application Support/ + if it exists, else ~/.config/ + Unix: ~/.local/share/ # or in + $XDG_DATA_HOME, if defined + Win XP (not roaming): C:\Documents and Settings\\ ... + ...Application Data\ + Win XP (roaming): C:\Documents and Settings\\Local ... + ...Settings\Application Data\ + Win 7 (not roaming): C:\\Users\\AppData\Local\ + Win 7 (roaming): C:\\Users\\AppData\Roaming\ + + For Unix, we follow the XDG spec and support $XDG_DATA_HOME. + That means, by default "~/.local/share/". + """ + 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 + + +def user_config_dir(appname, roaming=True): + """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 + + for a discussion of issues. + + Typical user data directories are: + macOS: same as user_data_dir + Unix: ~/.config/ + Win *: same as user_data_dir + + For Unix, we follow the XDG spec and support $XDG_CONFIG_HOME. + That means, by default "~/.config/". + """ + 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) + + return path + + +# for the discussion regarding site_config_dirs locations +# see +def site_config_dirs(appname): + 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// + Unix: /etc or $XDG_CONFIG_DIRS[i]// for each value in + $XDG_CONFIG_DIRS + Win XP: C:\Documents and Settings\All Users\Application ... + ...Data\\ + Vista: (Fail! "C:\ProgramData" is a hidden *system* directory + on Vista.) + Win 7: Hidden, but writeable on Win 7: + C:\ProgramData\\ + """ + 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 = [] + + # always look in /etc directly as well + pathlist.append('/etc') + + return pathlist + + +# -- Windows support functions -- + +def _get_win_folder_from_registry(csidl_name): + """ + 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): + 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 + # . + 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 + . + + 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 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/utils/compat.py b/venv/lib/python3.7/site-packages/pip/_internal/utils/compat.py new file mode 100644 index 0000000..3114f2d --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/utils/compat.py @@ -0,0 +1,248 @@ +"""Stuff that differs in different Python versions and platform +distributions.""" +from __future__ import absolute_import, division + +import codecs +import locale +import logging +import os +import shutil +import sys + +from pip._vendor.six import text_type + +try: + import ipaddress +except ImportError: + try: + from pip._vendor import ipaddress # type: ignore + except ImportError: + import ipaddr as ipaddress # type: ignore + ipaddress.ip_address = ipaddress.IPAddress + ipaddress.ip_network = ipaddress.IPNetwork + + +__all__ = [ + "ipaddress", "uses_pycache", "console_to_str", "native_str", + "get_path_uid", "stdlib_pkgs", "WINDOWS", "samefile", "get_terminal_size", + "get_extension_suffixes", +] + + +logger = logging.getLogger(__name__) + +if sys.version_info >= (3, 4): + uses_pycache = True + from importlib.util import cache_from_source +else: + import imp + + try: + cache_from_source = imp.cache_from_source # type: ignore + except AttributeError: + # does not use __pycache__ + 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 + # 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 + codecs.register_error( + "backslashreplace_decode", + backslashreplace_decode_fn, + ) + backslashreplace_decode = "backslashreplace_decode" + + +def console_to_str(data): + """Return a string, safe for output, of subprocess output. + + We assume the data is in the locale preferred encoding. + If it won't decode properly, we warn the user but decode as + best we can. + + We also ensure that the output can be safely written to + standard output without encoding errors. + """ + + # First, get the encoding we assume. This is the preferred + # encoding for the locale, unless that is not found, or + # it is ASCII, in which case assume UTF-8 + encoding = locale.getpreferredencoding() + if (not encoding) or codecs.lookup(encoding).name == "ascii": + encoding = "utf-8" + + # Now try to decode the data - if we fail, warn the user and + # decode with replacement. + try: + s = data.decode(encoding) + except UnicodeDecodeError: + logger.warning( + "Subprocess output does not appear to be encoded as %s", + encoding, + ) + s = data.decode(encoding, errors=backslashreplace_decode) + + # Make sure we can print the output, by encoding it to the output + # encoding with replacement of unencodable characters, and then + # decoding again. + # We use stderr's encoding because it's less likely to be + # redirected and if we don't find an encoding we skip this + # step (on the assumption that output is wrapped by something + # that won't fail). + # The double getattr is to deal with the possibility that we're + # being called in a situation where sys.__stderr__ doesn't exist, + # or doesn't have an encoding attribute. Neither of these cases + # should occur in normal pip use, but there's no harm in checking + # in case people use pip in (unsupported) unusual situations. + output_encoding = getattr(getattr(sys, "__stderr__", None), + "encoding", None) + + if output_encoding: + s = s.encode(output_encoding, errors="backslashreplace") + s = s.decode(output_encoding) + + return s + + +if sys.version_info >= (3,): + def native_str(s, replace=False): + if isinstance(s, bytes): + return s.decode('utf-8', 'replace' if replace else 'strict') + return s + +else: + def native_str(s, replace=False): + # 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): + """ + Return path's uid. + + Does not follow symlinks: + https://github.com/pypa/pip/pull/935#discussion_r5307003 + + Placed this function in compat due to differences on AIX and + Jython, that should eventually go away. + + :raises OSError: When path is a symlink or can't be read. + """ + if hasattr(os, 'O_NOFOLLOW'): + fd = os.open(path, os.O_RDONLY | os.O_NOFOLLOW) + file_uid = os.fstat(fd).st_uid + os.close(fd) + else: # AIX and Jython + # WARNING: time of check vulnerability, but best we can do w/o NOFOLLOW + if not os.path.islink(path): + # older versions of Jython don't have `os.fstat` + file_uid = os.stat(path).st_uid + else: + # raise OSError for parity with os.O_NOFOLLOW above + raise OSError( + "%s is a symlink; Will not return uid for symlinks" % 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): + """ + Expand ~ and ~user constructions. + + Includes a workaround for https://bugs.python.org/issue14768 + """ + expanded = os.path.expanduser(path) + if path.startswith('~/') and expanded.startswith('//'): + expanded = expanded[1:] + return expanded + + +# packages in the stdlib that may have installation metadata, but should not be +# considered 'installed'. this theoretically could be determined based on +# dist.location (py27:`sysconfig.get_paths()['stdlib']`, +# py26:sysconfig.get_config_vars('LIBDEST')), but fear platform variation may +# make this ineffective, so hard-coding +stdlib_pkgs = {"python", "wsgiref", "argparse"} + + +# windows detection, covers cpython and ironpython +WINDOWS = (sys.platform.startswith("win") or + (sys.platform == 'cli' and os.name == 'nt')) + + +def samefile(file1, file2): + """Provide an alternative for os.path.samefile on Windows/Python2""" + if hasattr(os.path, 'samefile'): + return os.path.samefile(file1, file2) + else: + path1 = os.path.normcase(os.path.abspath(file1)) + path2 = os.path.normcase(os.path.abspath(file2)) + return path1 == path2 + + +if hasattr(shutil, 'get_terminal_size'): + def get_terminal_size(): + """ + Returns a tuple (x, y) representing the width(x) and the height(y) + in characters of the terminal window. + """ + return tuple(shutil.get_terminal_size()) +else: + def get_terminal_size(): + """ + Returns a tuple (x, y) representing the width(x) and the height(y) + in characters of the terminal window. + """ + def ioctl_GWINSZ(fd): + try: + import fcntl + import termios + import struct + cr = struct.unpack_from( + 'hh', + fcntl.ioctl(fd, termios.TIOCGWINSZ, '12345678') + ) + except Exception: + return None + if cr == (0, 0): + return None + 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 not cr: + cr = (os.environ.get('LINES', 25), os.environ.get('COLUMNS', 80)) + return int(cr[1]), int(cr[0]) diff --git a/venv/lib/python3.7/site-packages/pip/_internal/utils/deprecation.py b/venv/lib/python3.7/site-packages/pip/_internal/utils/deprecation.py new file mode 100644 index 0000000..bd744cf --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/utils/deprecation.py @@ -0,0 +1,89 @@ +""" +A module that implements tooling to enable easy warnings about deprecations. +""" +from __future__ import absolute_import + +import logging +import warnings + +from pip._vendor.packaging.version import parse + +from pip import __version__ as current_version +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Any, Optional # noqa: F401 + + +class PipDeprecationWarning(Warning): + pass + + +_original_showwarning = None # type: Any + + +# Warnings <-> Logging Integration +def _showwarning(message, category, filename, lineno, file=None, line=None): + if file is not None: + if _original_showwarning is not None: + _original_showwarning( + message, category, filename, lineno, file, line, + ) + elif issubclass(category, PipDeprecationWarning): + # We use a specially named logger which will handle all of the + # deprecation messages for pip. + logger = logging.getLogger("pip._internal.deprecations") + logger.warning(message) + else: + _original_showwarning( + message, category, filename, lineno, file, line, + ) + + +def install_warning_logger(): + # Enable our Deprecation Warnings + warnings.simplefilter("default", PipDeprecationWarning, append=True) + + global _original_showwarning + + if _original_showwarning is None: + _original_showwarning = warnings.showwarning + warnings.showwarning = _showwarning + + +def deprecated(reason, replacement, gone_in, issue=None): + # type: (str, Optional[str], Optional[str], Optional[int]) -> None + """Helper to deprecate existing functionality. + + reason: + Textual reason shown to the user about why this functionality has + been deprecated. + replacement: + Textual suggestion shown to the user about what alternative + functionality they can use. + gone_in: + The version of pip does this functionality should get removed in. + Raises errors if pip's current version is greater than or equal to + this. + issue: + Issue number on the tracker that would serve as a useful place for + users to find related discussion and provide feedback. + + Always pass replacement, gone_in and issue as keyword arguments for clarity + at the call site. + """ + + # Construct a nice message. + # This is purposely eagerly formatted as we want it to appear as if someone + # typed this entire message out. + message = "DEPRECATION: " + reason + if replacement is not None: + message += " A possible replacement is {}.".format(replacement) + if issue is not None: + url = "https://github.com/pypa/pip/issues/" + str(issue) + message += " You can find discussion regarding this at {}.".format(url) + + # Raise as an error if it has to be removed. + if gone_in is not None and parse(current_version) >= parse(gone_in): + raise PipDeprecationWarning(message) + warnings.warn(message, category=PipDeprecationWarning, stacklevel=2) diff --git a/venv/lib/python3.7/site-packages/pip/_internal/utils/encoding.py b/venv/lib/python3.7/site-packages/pip/_internal/utils/encoding.py new file mode 100644 index 0000000..56f6036 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/utils/encoding.py @@ -0,0 +1,33 @@ +import codecs +import locale +import re +import sys + +BOMS = [ + (codecs.BOM_UTF8, 'utf8'), + (codecs.BOM_UTF16, 'utf16'), + (codecs.BOM_UTF16_BE, 'utf16-be'), + (codecs.BOM_UTF16_LE, 'utf16-le'), + (codecs.BOM_UTF32, 'utf32'), + (codecs.BOM_UTF32_BE, 'utf32-be'), + (codecs.BOM_UTF32_LE, 'utf32-le'), +] + +ENCODING_RE = re.compile(br'coding[:=]\s*([-\w.]+)') + + +def auto_decode(data): + """Check a bytes string for a BOM to correctly detect the encoding + + Fallback to locale.getpreferredencoding(False) like open() on Python3""" + for bom, encoding in BOMS: + if data.startswith(bom): + return data[len(bom):].decode(encoding) + # 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') + return data.decode(encoding) + return data.decode( + locale.getpreferredencoding(False) or sys.getdefaultencoding(), + ) diff --git a/venv/lib/python3.7/site-packages/pip/_internal/utils/filesystem.py b/venv/lib/python3.7/site-packages/pip/_internal/utils/filesystem.py new file mode 100644 index 0000000..1e9cebd --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/utils/filesystem.py @@ -0,0 +1,28 @@ +import os +import os.path + +from pip._internal.utils.compat import get_path_uid + + +def check_path_owner(path): + # 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"): + return True + + previous = None + while path != previous: + if os.path.lexists(path): + # Check if path is writable by current user. + if os.geteuid() == 0: + # Special handling for root user in order to handle properly + # cases where users use sudo without -H flag. + try: + path_uid = get_path_uid(path) + except OSError: + return False + return path_uid == 0 + else: + return os.access(path, os.W_OK) + else: + previous, path = path, os.path.dirname(path) diff --git a/venv/lib/python3.7/site-packages/pip/_internal/utils/glibc.py b/venv/lib/python3.7/site-packages/pip/_internal/utils/glibc.py new file mode 100644 index 0000000..ebcfc5b --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/utils/glibc.py @@ -0,0 +1,84 @@ +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[0-9]+)\.(?P[0-9]+)", version_str) + if not m: + warnings.warn("Expected glibc version with 2 components major.minor," + " got: %s" % version_str, RuntimeWarning) + return 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.7/site-packages/pip/_internal/utils/hashes.py b/venv/lib/python3.7/site-packages/pip/_internal/utils/hashes.py new file mode 100644 index 0000000..8b909ba --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/utils/hashes.py @@ -0,0 +1,94 @@ +from __future__ import absolute_import + +import hashlib + +from pip._vendor.six import iteritems, iterkeys, itervalues + +from pip._internal.exceptions import ( + HashMismatch, HashMissing, InstallationError, +) +from pip._internal.utils.misc import read_chunks + +# The recommended hash algo of the moment. Change this whenever the state of +# the art changes; it won't hurt backward compatibility. +FAVORITE_HASH = 'sha256' + + +# Names of hashlib algorithms allowed by the --hash option and ``pip hash`` +# Currently, those are the ones at least as collision-resistant as sha256. +STRONG_HASHES = ['sha256', 'sha384', 'sha512'] + + +class Hashes(object): + """A wrapper that builds multiple hashes at once and checks them against + known-good values + + """ + def __init__(self, hashes=None): + """ + :param hashes: A dict of algorithm names pointing to lists of allowed + hex digests + """ + self._allowed = {} if hashes is None else hashes + + def check_against_chunks(self, chunks): + """Check good hashes against ones built from iterable of chunks of + data. + + Raise HashMismatch if none match. + + """ + gots = {} + for hash_name in iterkeys(self._allowed): + try: + gots[hash_name] = hashlib.new(hash_name) + except (ValueError, TypeError): + raise InstallationError('Unknown hash name: %s' % hash_name) + + for chunk in chunks: + for hash in itervalues(gots): + hash.update(chunk) + + for hash_name, got in iteritems(gots): + if got.hexdigest() in self._allowed[hash_name]: + return + self._raise(gots) + + def _raise(self, gots): + raise HashMismatch(self._allowed, gots) + + def check_against_file(self, file): + """Check good hashes against a file-like object + + Raise HashMismatch if none match. + + """ + return self.check_against_chunks(read_chunks(file)) + + def check_against_path(self, path): + with open(path, 'rb') as file: + return self.check_against_file(file) + + def __nonzero__(self): + """Return whether I know any known-good hashes.""" + return bool(self._allowed) + + def __bool__(self): + return self.__nonzero__() + + +class MissingHashes(Hashes): + """A workalike for Hashes used when we're missing a hash for a requirement + + It computes the actual hash of the requirement and raises a HashMissing + exception showing it to the user. + + """ + def __init__(self): + """Don't offer the ``hashes`` kwarg.""" + # Pass our favorite hash in to generate a "gotten hash". With the + # empty list, it will never match, so an error will always raise. + super(MissingHashes, self).__init__(hashes={FAVORITE_HASH: []}) + + def _raise(self, gots): + raise HashMissing(gots[FAVORITE_HASH].hexdigest()) diff --git a/venv/lib/python3.7/site-packages/pip/_internal/utils/logging.py b/venv/lib/python3.7/site-packages/pip/_internal/utils/logging.py new file mode 100644 index 0000000..d9b9541 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/utils/logging.py @@ -0,0 +1,225 @@ +from __future__ import absolute_import + +import contextlib +import logging +import logging.handlers +import os + +from pip._internal.utils.compat import WINDOWS +from pip._internal.utils.misc import ensure_dir + +try: + import threading +except ImportError: + import dummy_threading as threading # type: ignore + + +try: + from pip._vendor import colorama +# Lots of different errors can come from this, including SystemError and +# ImportError. +except Exception: + colorama = None + + +_log_state = threading.local() +_log_state.indentation = 0 + + +@contextlib.contextmanager +def indent_log(num=2): + """ + A context manager which will cause the log output to be indented for any + log messages emitted inside it. + """ + _log_state.indentation += num + try: + yield + finally: + _log_state.indentation -= num + + +def get_indentation(): + return getattr(_log_state, 'indentation', 0) + + +class IndentingFormatter(logging.Formatter): + + def format(self, record): + """ + Calls the standard formatter, but will indent all of the log messages + by our current indentation level. + """ + formatted = logging.Formatter.format(self, record) + formatted = "".join([ + (" " * get_indentation()) + line + for line in formatted.splitlines(True) + ]) + return formatted + + +def _color_wrap(*colors): + def wrapped(inp): + return "".join(list(colors) + [inp, colorama.Style.RESET_ALL]) + return wrapped + + +class ColorizedStreamHandler(logging.StreamHandler): + + # Don't build up a list of colors if we don't have colorama + if colorama: + COLORS = [ + # This needs to be in order from highest logging level to lowest. + (logging.ERROR, _color_wrap(colorama.Fore.RED)), + (logging.WARNING, _color_wrap(colorama.Fore.YELLOW)), + ] + else: + COLORS = [] + + def __init__(self, stream=None, no_color=None): + logging.StreamHandler.__init__(self, stream) + self._no_color = no_color + + if WINDOWS and colorama: + self.stream = colorama.AnsiToWin32(self.stream) + + def should_color(self): + # Don't colorize things if we do not have colorama or if told not to + if not colorama or self._no_color: + return False + + real_stream = ( + self.stream if not isinstance(self.stream, colorama.AnsiToWin32) + else self.stream.wrapped + ) + + # If the stream is a tty we should color it + if hasattr(real_stream, "isatty") and real_stream.isatty(): + return True + + # If we have an ANSI term we should color it + if os.environ.get("TERM") == "ANSI": + return True + + # If anything else we should not color it + return False + + def format(self, record): + msg = logging.StreamHandler.format(self, record) + + if self.should_color(): + for level, color in self.COLORS: + if record.levelno >= level: + msg = color(msg) + break + + return msg + + +class BetterRotatingFileHandler(logging.handlers.RotatingFileHandler): + + def _open(self): + ensure_dir(os.path.dirname(self.baseFilename)) + return logging.handlers.RotatingFileHandler._open(self) + + +class MaxLevelFilter(logging.Filter): + + def __init__(self, level): + self.level = level + + def filter(self, record): + return record.levelno < self.level + + +def setup_logging(verbosity, no_color, user_log_file): + """Configures and sets up all of the logging + """ + + # Determine the level to be logging at. + if verbosity >= 1: + level = "DEBUG" + elif verbosity == -1: + level = "WARNING" + elif verbosity == -2: + level = "ERROR" + elif verbosity <= -3: + level = "CRITICAL" + else: + level = "INFO" + + # The "root" logger should match the "console" level *unless* we also need + # to log to a user log file. + include_user_log = user_log_file is not None + if include_user_log: + additional_log_file = user_log_file + root_level = "DEBUG" + else: + additional_log_file = "/dev/null" + root_level = level + + # Disable any logging besides WARNING unless we have DEBUG level logging + # enabled for vendored libraries. + vendored_log_level = "WARNING" if level in ["INFO", "ERROR"] else "DEBUG" + + # Shorthands for clarity + log_streams = { + "stdout": "ext://sys.stdout", + "stderr": "ext://sys.stderr", + } + handler_classes = { + "stream": "pip._internal.utils.logging.ColorizedStreamHandler", + "file": "pip._internal.utils.logging.BetterRotatingFileHandler", + } + + logging.config.dictConfig({ + "version": 1, + "disable_existing_loggers": False, + "filters": { + "exclude_warnings": { + "()": "pip._internal.utils.logging.MaxLevelFilter", + "level": logging.WARNING, + }, + }, + "formatters": { + "indent": { + "()": IndentingFormatter, + "format": "%(message)s", + }, + }, + "handlers": { + "console": { + "level": level, + "class": handler_classes["stream"], + "no_color": no_color, + "stream": log_streams["stdout"], + "filters": ["exclude_warnings"], + "formatter": "indent", + }, + "console_errors": { + "level": "WARNING", + "class": handler_classes["stream"], + "no_color": no_color, + "stream": log_streams["stderr"], + "formatter": "indent", + }, + "user_log": { + "level": "DEBUG", + "class": handler_classes["file"], + "filename": additional_log_file, + "delay": True, + "formatter": "indent", + }, + }, + "root": { + "level": root_level, + "handlers": ["console", "console_errors"] + ( + ["user_log"] if include_user_log else [] + ), + }, + "loggers": { + "pip._vendor": { + "level": vendored_log_level + } + }, + }) diff --git a/venv/lib/python3.7/site-packages/pip/_internal/utils/misc.py b/venv/lib/python3.7/site-packages/pip/_internal/utils/misc.py new file mode 100644 index 0000000..84a421f --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/utils/misc.py @@ -0,0 +1,940 @@ +from __future__ import absolute_import + +import contextlib +import errno +import io +import locale +# we have a submodule named 'logging' which would shadow this if we used the +# regular name: +import logging as std_logging +import os +import posixpath +import re +import shutil +import stat +import subprocess +import sys +import tarfile +import zipfile +from collections import deque + +from pip._vendor import pkg_resources +# 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._vendor.six.moves import input +from pip._vendor.six.moves.urllib import parse as urllib_parse + +from pip._internal.exceptions import CommandError, InstallationError +from pip._internal.locations import ( + running_under_virtualenv, site_packages, user_site, virtualenv_no_global, + write_delete_marker_file, +) +from pip._internal.utils.compat import ( + WINDOWS, console_to_str, expanduser, stdlib_pkgs, +) + +if PY2: + from io import BytesIO as StringIO +else: + from io import StringIO + +__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', + 'get_installed_version', 'remove_auth_from_url'] + + +logger = std_logging.getLogger(__name__) + +BZ2_EXTENSIONS = ('.tar.bz2', '.tbz') +XZ_EXTENSIONS = ('.tar.xz', '.txz', '.tlz', '.tar.lz', '.tar.lzma') +ZIP_EXTENSIONS = ('.zip', '.whl') +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') + + +def import_or_raise(pkg_or_module_string, ExceptionType, *args, **kwargs): + try: + return __import__(pkg_or_module_string) + except ImportError: + raise ExceptionType(*args, **kwargs) + + +def ensure_dir(path): + """os.path.makedirs without EEXIST.""" + try: + os.makedirs(path) + except OSError as e: + if e.errno != errno.EEXIST: + raise + + +def get_prog(): + try: + prog = os.path.basename(sys.argv[0]) + if prog in ('__main__.py', '-c'): + return "%s -m pip" % sys.executable + else: + return prog + except (AttributeError, TypeError, IndexError): + pass + return 'pip' + + +# Retry every half second for up to 3 seconds +@retry(stop_max_delay=3000, wait_fixed=500) +def rmtree(dir, ignore_errors=False): + shutil.rmtree(dir, ignore_errors=ignore_errors, + onerror=rmtree_errorhandler) + + +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: + # convert to read/write + os.chmod(path, stat.S_IWRITE) + # use the original function to repeat the operation + func(path) + return + else: + raise + + +def display_path(path): + """Gives the display value for a given path, making it relative to cwd + if possible.""" + path = os.path.normcase(os.path.abspath(path)) + if sys.version_info[0] == 2: + path = path.decode(sys.getfilesystemencoding(), 'replace') + path = path.encode(sys.getdefaultencoding(), 'replace') + if path.startswith(os.getcwd() + os.path.sep): + path = '.' + path[len(os.getcwd()):] + return path + + +def backup_dir(dir, ext='.bak'): + """Figure out the name of a directory to back up the given dir to + (adding .bak, .bak2, etc)""" + n = 1 + extension = ext + while os.path.exists(dir + extension): + n += 1 + extension = ext + str(n) + return dir + extension + + +def ask_path_exists(message, options): + for action in os.environ.get('PIP_EXISTS_ACTION', '').split(): + if action in options: + return action + return ask(message, options) + + +def ask(message, options): + """Ask the message interactively, with the given possible responses""" + while 1: + if os.environ.get('PIP_NO_INPUT'): + raise Exception( + 'No input was expected ($PIP_NO_INPUT set); question: %s' % + message + ) + response = input(message) + response = response.strip().lower() + if response not in options: + print( + 'Your response (%r) was not one of the expected responses: ' + '%s' % (response, ', '.join(options)) + ) + else: + return response + + +def format_size(bytes): + if bytes > 1000 * 1000: + return '%.1fMB' % (bytes / 1000.0 / 1000) + elif bytes > 10 * 1000: + return '%ikB' % (bytes / 1000) + elif bytes > 1000: + return '%.1fkB' % (bytes / 1000.0) + else: + return '%ibytes' % bytes + + +def is_installable_dir(path): + """Is path is a directory containing setup.py or pyproject.toml? + """ + if not os.path.isdir(path): + return False + setup_py = os.path.join(path, 'setup.py') + if os.path.isfile(setup_py): + return True + pyproject_toml = os.path.join(path, 'pyproject.toml') + if os.path.isfile(pyproject_toml): + return True + return False + + +def is_svn_page(html): + """ + Returns true if the page appears to be the index page of an svn repository + """ + return (re.search(r'[^<]*Revision \d+:', html) and + re.search(r'Powered by (?:<a[^>]*?>)?Subversion', html, re.I)) + + +def file_contents(filename): + 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: + chunk = file.read(size) + if not chunk: + break + yield chunk + + +def split_leading_dir(path): + 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): + """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): + """ + Convert a path to its canonical, case-normalized, absolute version. + + """ + path = expanduser(path) + if resolve_symlinks: + path = os.path.realpath(path) + else: + path = os.path.abspath(path) + return os.path.normcase(path) + + +def splitext(path): + """Like os.path.splitext, but take off .tar too""" + base, ext = posixpath.splitext(path) + if base.lower().endswith('.tar'): + ext = base[-4:] + ext + base = base[:-4] + return base, ext + + +def renames(old, new): + """Like os.renames(), but handles renaming across devices.""" + # Implementation borrowed from os.renames(). + head, tail = os.path.split(new) + if head and tail and not os.path.exists(head): + os.makedirs(head) + + shutil.move(old, new) + + head, tail = os.path.split(old) + if head and tail: + try: + os.removedirs(head) + except OSError: + pass + + +def is_local(path): + """ + Return True if path is within sys.prefix, if we're running in a virtualenv. + + If we're not in a virtualenv, all paths are considered "local." + + """ + if not running_under_virtualenv(): + return True + return normalize_path(path).startswith(normalize_path(sys.prefix)) + + +def dist_is_local(dist): + """ + Return True if given Distribution object is installed locally + (i.e. within current virtualenv). + + Always True if we're not in a virtualenv. + + """ + return is_local(dist_location(dist)) + + +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)) + + +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)) + + +def dist_is_editable(dist): + """Is distribution an editable install?""" + for path_item in sys.path: + egg_link = os.path.join(path_item, dist.project_name + '.egg-link') + if os.path.isfile(egg_link): + return True + return False + + +def get_installed_distributions(local_only=True, + skip=stdlib_pkgs, + include_editables=True, + editables_only=False, + user_only=False): + """ + Return a list of installed Distribution objects. + + If ``local_only`` is True (default), only return installations + local to the current virtualenv, if in a virtualenv. + + ``skip`` argument is an iterable of lower-case project names to + ignore; defaults to stdlib_pkgs + + If ``include_editables`` is False, don't report editables. + + If ``editables_only`` is True , only report editables. + + If ``user_only`` is True , only report installations in the user + site directory. + + """ + if local_only: + local_test = dist_is_local + else: + def local_test(d): + return True + + if include_editables: + def editable_test(d): + return True + else: + def editable_test(d): + return not dist_is_editable(d) + + if editables_only: + def editables_only_test(d): + return dist_is_editable(d) + else: + def editables_only_test(d): + return True + + if user_only: + user_test = dist_in_usersite + else: + def user_test(d): + return True + + return [d for d in pkg_resources.working_set + if local_test(d) and + d.key not in skip and + editable_test(d) and + editables_only_test(d) and + user_test(d) + ] + + +def egg_link_path(dist): + """ + Return the path for the .egg-link file if it exists, otherwise, None. + + There's 3 scenarios: + 1) not in a virtualenv + try to find in site.USER_SITE, then site_packages + 2) in a no-global virtualenv + try to find in site_packages + 3) in a yes-global virtualenv + try to find in site_packages, then site.USER_SITE + (don't look in global location) + + For #1 and #3, there could be odd cases, where there's an egg-link in 2 + locations. + + This method will just return the first one found. + """ + 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) + else: + if user_site: + sites.append(user_site) + sites.append(site_packages) + + for site in sites: + egglink = os.path.join(site, dist.project_name) + '.egg-link' + if os.path.isfile(egglink): + return egglink + + +def dist_location(dist): + """ + Get the site-packages location of this distribution. Generally + this is dist.location, except in the case of develop-installed + packages, where dist.location is the source code location, and we + want to know where the egg-link file is. + + """ + egg_link = egg_link_path(dist) + if egg_link: + return egg_link + return 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): + """ + 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 + data = zip.read(name) + 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) + fp = open(fn, 'wb') + try: + fp.write(data) + 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): + """ + 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: + # note: python<=2.5 doesn't seem to know about pax headers, filter them + leading = has_leading_dir([ + member.name for member in tar.getmembers() + if member.name != 'pax_global_header' + ]) + for member in tar.getmembers(): + fn = member.name + if fn == 'pax_global_header': + continue + if leading: + fn = split_leading_dir(fn)[1] + path = os.path.join(location, fn) + if member.isdir(): + ensure_dir(path) + elif member.issym(): + try: + tar._extract_member(member, path) + 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) + tar.utime(member, path) + # 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, location, content_type, link): + 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 + Subversion('svn+' + link.url).unpack(location) + 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 call_subprocess(cmd, show_stdout=True, cwd=None, + on_returncode='raise', + command_desc=None, + extra_environ=None, unset_environ=None, spinner=None): + """ + Args: + unset_environ: an iterable of environment variable names to unset + prior to calling subprocess.Popen(). + """ + if unset_environ is None: + unset_environ = [] + # This function's handling of subprocess output is confusing and I + # previously broke it terribly, so as penance I will write a long comment + # explaining things. + # + # The obvious thing that affects output is the show_stdout= + # kwarg. show_stdout=True means, let the subprocess write directly to our + # stdout. Even though it is nominally the default, it is almost never used + # inside pip (and should not be used in new code without a very good + # reason); as of 2016-02-22 it is only used in a few places inside the VCS + # wrapper code. Ideally we should get rid of it entirely, because it + # creates a lot of complexity here for a rarely used feature. + # + # Most places in pip set show_stdout=False. What this means is: + # - We connect the child stdout to a pipe, which we read. + # - By default, we hide the output but show a spinner -- unless the + # subprocess exits with an error, in which case we show the output. + # - If the --verbose option was passed (= loglevel is DEBUG), then we show + # the output unconditionally. (But in this case we don't want to show + # the output a second time if it turns out that there was an error.) + # + # stderr is always merged with stdout (even if show_stdout=True). + if show_stdout: + stdout = None + else: + stdout = subprocess.PIPE + if command_desc is None: + cmd_parts = [] + for part in cmd: + if ' ' in part or '\n' in part or '"' in part or "'" in part: + part = '"%s"' % part.replace('"', '\\"') + cmd_parts.append(part) + command_desc = ' '.join(cmd_parts) + logger.debug("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=stdout, cwd=cwd, env=env, + ) + proc.stdin.close() + except Exception as exc: + logger.critical( + "Error %s while executing command %s", exc, command_desc, + ) + raise + all_output = [] + if stdout is not None: + while True: + line = console_to_str(proc.stdout.readline()) + if not line: + break + line = line.rstrip() + all_output.append(line + '\n') + if logger.getEffectiveLevel() <= std_logging.DEBUG: + # Show the line immediately + logger.debug(line) + else: + # Update the spinner + if spinner is not None: + spinner.spin() + try: + proc.wait() + finally: + if proc.stdout: + proc.stdout.close() + if spinner is not None: + if proc.returncode: + spinner.finish("error") + else: + spinner.finish("done") + if proc.returncode: + if on_returncode == 'raise': + if (logger.getEffectiveLevel() > std_logging.DEBUG and + not show_stdout): + logger.info( + 'Complete output from command %s:', command_desc, + ) + logger.info( + ''.join(all_output) + + '\n----------------------------------------' + ) + raise InstallationError( + 'Command "%s" failed with error code %s in %s' + % (command_desc, proc.returncode, cwd)) + elif on_returncode == 'warn': + 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)) + if not show_stdout: + return ''.join(all_output) + + +def read_text_file(filename): + """Return the contents of *filename*. + + Try to decode the file contents with utf-8, the preferred system encoding + (e.g., cp1252 on some Windows machines), and latin1, in that order. + Decoding a byte string with latin1 will never raise an error. In the worst + case, the returned string will contain some garbage characters. + + """ + with open(filename, 'rb') as fp: + data = fp.read() + + encodings = ['utf-8', locale.getpreferredencoding(False), 'latin1'] + for enc in encodings: + try: + data = data.decode(enc) + except UnicodeDecodeError: + continue + break + + assert type(data) != bytes # Latin1 should have worked. + return data + + +def _make_build_dir(build_dir): + os.makedirs(build_dir) + write_delete_marker_file(build_dir) + + +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) + + def readline(self): + try: + try: + return next(self._gen) + except NameError: + return self._gen.next() + except StopIteration: + return '' + + def __iter__(self): + return self._gen + + +class StreamWrapper(StringIO): + + @classmethod + def from_stream(cls, orig_stream): + cls.orig_stream = orig_stream + return cls() + + # compileall.compile_dir() needs stdout.encoding to print to stdout + @property + def encoding(self): + return self.orig_stream.encoding + + +@contextlib.contextmanager +def captured_output(stream_name): + """Return a context manager used by captured_stdout/stdin/stderr + that temporarily replaces the sys stream *stream_name* with a StringIO. + + Taken from Lib/support/__init__.py in the CPython repo. + """ + orig_stdout = getattr(sys, stream_name) + setattr(sys, stream_name, StreamWrapper.from_stream(orig_stdout)) + try: + yield getattr(sys, stream_name) + finally: + setattr(sys, stream_name, orig_stdout) + + +def captured_stdout(): + """Capture the output of sys.stdout: + + with captured_stdout() as stdout: + print('hello') + self.assertEqual(stdout.getvalue(), 'hello\n') + + Taken from Lib/support/__init__.py in the CPython repo. + """ + return captured_output('stdout') + + +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. + req = pkg_resources.Requirement.parse(dist_name) + + if working_set is None: + # We want to avoid having this cached, so we need to construct a new + # working set each time. + working_set = pkg_resources.WorkingSet() + + # Get the installed distribution from our working set + dist = working_set.find(req) + + # Check to see if we got an installed distribution or not, if we did + # we want to return it's version. + return dist.version if dist else None + + +def consume(iterator): + """Consume an iterable at C speed.""" + deque(iterator, maxlen=0) + + +# Simulates an enum +def enum(*sequential, **named): + enums = dict(zip(sequential, range(len(sequential))), **named) + reverse = {value: key for key, value in enums.items()} + enums['reverse_mapping'] = reverse + return type('Enum', (), enums) + + +def make_vcs_requirement_url(repo_url, rev, egg_project_name, subdir=None): + """ + Return the URL for a VCS requirement. + + Args: + repo_url: the remote VCS url, with any needed VCS prefix (e.g. "git+"). + """ + req = '{}@{}#egg={}'.format(repo_url, rev, egg_project_name) + if subdir: + req += '&subdirectory={}'.format(subdir) + + return req + + +def split_auth_from_netloc(netloc): + """ + Parse out and remove the auth information from a netloc. + + Returns: (netloc, (username, password)). + """ + if '@' not in netloc: + return netloc, (None, None) + + # Split from the right because that's how urllib.parse.urlsplit() + # behaves if more than one @ is present (which can be checked using + # the password attribute of urlsplit()'s return value). + auth, netloc = netloc.rsplit('@', 1) + if ':' in auth: + # Split from the left because that's how urllib.parse.urlsplit() + # behaves if more than one : is present (which again can be checked + # using the password attribute of the return value) + user_pass = tuple(auth.split(':', 1)) + else: + user_pass = auth, None + + return netloc, user_pass + + +def remove_auth_from_url(url): + # Return a copy of url with 'username:password@' removed. + # username/pass params are passed to subversion through flags + # and are not recognized in the url. + + # parsed url + purl = urllib_parse.urlsplit(url) + netloc, user_pass = split_auth_from_netloc(purl.netloc) + + # stripped url + url_pieces = ( + purl.scheme, netloc, purl.path, purl.query, purl.fragment + ) + surl = urllib_parse.urlunsplit(url_pieces) + return surl + + +def protect_pip_from_modification_on_windows(modifying_pip): + """Protection of pip.exe from modification on Windows + + On Windows, any operation modifying pip should be run as: + python -m pip ... + """ + pip_names = [ + "pip.exe", + "pip{}.exe".format(sys.version_info[0]), + "pip{}.{}.exe".format(*sys.version_info[:2]) + ] + + # See https://github.com/pypa/pip/issues/1299 for more discussion + should_show_use_python_msg = ( + modifying_pip and + WINDOWS and + os.path.basename(sys.argv[0]) in pip_names + ) + + if should_show_use_python_msg: + new_command = [ + sys.executable, "-m", "pip" + ] + sys.argv[1:] + raise CommandError( + 'To modify pip, please run the following command:\n{}' + .format(" ".join(new_command)) + ) diff --git a/venv/lib/python3.7/site-packages/pip/_internal/utils/models.py b/venv/lib/python3.7/site-packages/pip/_internal/utils/models.py new file mode 100644 index 0000000..d5cb80a --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/utils/models.py @@ -0,0 +1,40 @@ +"""Utilities for defining models +""" + +import operator + + +class KeyBasedCompareMixin(object): + """Provides comparision capabilities that is based on a key + """ + + def __init__(self, key, defining_class): + self._compare_key = key + self._defining_class = defining_class + + def __hash__(self): + return hash(self._compare_key) + + def __lt__(self, other): + return self._compare(other, operator.__lt__) + + def __le__(self, other): + return self._compare(other, operator.__le__) + + def __gt__(self, other): + return self._compare(other, operator.__gt__) + + def __ge__(self, other): + return self._compare(other, operator.__ge__) + + def __eq__(self, other): + return self._compare(other, operator.__eq__) + + def __ne__(self, other): + return self._compare(other, operator.__ne__) + + def _compare(self, other, method): + if not isinstance(other, self._defining_class): + return NotImplemented + + return method(self._compare_key, other._compare_key) diff --git a/venv/lib/python3.7/site-packages/pip/_internal/utils/outdated.py b/venv/lib/python3.7/site-packages/pip/_internal/utils/outdated.py new file mode 100644 index 0000000..5bfbfe1 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/utils/outdated.py @@ -0,0 +1,154 @@ +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.index import PackageFinder +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 + +SELFCHECK_DATE_FMT = "%Y-%m-%dT%H:%M:%SZ" + + +logger = logging.getLogger(__name__) + + +class SelfCheckState(object): + def __init__(self, cache_dir): + self.state = {} + 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): + # 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): + """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 (dist.has_metadata('INSTALLER') and + 'pip' in dist.get_metadata_lines('INSTALLER')) + except pkg_resources.DistributionNotFound: + return False + + +def pip_version_check(session, options): + """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 + finder = PackageFinder( + find_links=options.find_links, + index_urls=[options.index_url] + options.extra_index_urls, + allow_all_prereleases=False, # Explicitly set to False + trusted_hosts=options.trusted_hosts, + process_dependency_links=options.process_dependency_links, + session=session, + ) + all_candidates = finder.find_all_candidates("pip") + if not all_candidates: + return + pypi_version = str( + max(all_candidates, key=lambda c: c.version).version + ) + + # save that we've performed a check + state.save(pypi_version, current_time) + + remote_version = packaging_version.parse(pypi_version) + + # Determine if our pypi_version is older + if (pip_version < remote_version and + pip_version.base_version != remote_version.base_version and + was_installed_by_pip('pip')): + # 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.7/site-packages/pip/_internal/utils/packaging.py b/venv/lib/python3.7/site-packages/pip/_internal/utils/packaging.py new file mode 100644 index 0000000..c43142f --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/utils/packaging.py @@ -0,0 +1,75 @@ +from __future__ import absolute_import + +import logging +import sys +from email.parser import FeedParser # type: ignore + +from pip._vendor import pkg_resources +from pip._vendor.packaging import specifiers, version + +from pip._internal import exceptions +from pip._internal.utils.misc import display_path + +logger = logging.getLogger(__name__) + + +def check_requires_python(requires_python): + """ + Check if the python version in use match the `requires_python` specifier. + + Returns `True` if the version of python in use matches the requirement. + Returns `False` if the version of python in use does not matches the + requirement. + + Raises an InvalidSpecifier if `requires_python` have an invalid format. + """ + if requires_python is None: + # The package provides no information + return True + requires_python_specifier = specifiers.SpecifierSet(requires_python) + + # We only use major.minor.micro + python_version = version.parse('.'.join(map(str, sys.version_info[:3]))) + return python_version in requires_python_specifier + + +def get_metadata(dist): + if (isinstance(dist, pkg_resources.DistInfoDistribution) and + dist.has_metadata('METADATA')): + metadata = dist.get_metadata('METADATA') + elif dist.has_metadata('PKG-INFO'): + metadata = dist.get_metadata('PKG-INFO') + else: + logger.warning("No metadata found in %s", display_path(dist.location)) + metadata = '' + + feed_parser = FeedParser() + feed_parser.feed(metadata) + return feed_parser.close() + + +def check_dist_requires_python(dist): + pkg_info_dict = get_metadata(dist) + requires_python = pkg_info_dict.get('Requires-Python') + try: + if not check_requires_python(requires_python): + raise exceptions.UnsupportedPythonVersion( + "%s requires Python '%s' but the running Python is %s" % ( + dist.project_name, + requires_python, + '.'.join(map(str, sys.version_info[:3])),) + ) + except specifiers.InvalidSpecifier as e: + logger.warning( + "Package %s has an invalid Requires-Python entry %s - %s", + dist.project_name, requires_python, e, + ) + return + + +def get_installer(dist): + if dist.has_metadata('INSTALLER'): + for line in dist.get_metadata_lines('INSTALLER'): + if line.strip(): + return line.strip() + return '' diff --git a/venv/lib/python3.7/site-packages/pip/_internal/utils/setuptools_build.py b/venv/lib/python3.7/site-packages/pip/_internal/utils/setuptools_build.py new file mode 100644 index 0000000..03973e9 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/utils/setuptools_build.py @@ -0,0 +1,8 @@ +# Shim to wrap setup.py invocation with setuptools +SETUPTOOLS_SHIM = ( + "import setuptools, tokenize;__file__=%r;" + "f=getattr(tokenize, 'open', open)(__file__);" + "code=f.read().replace('\\r\\n', '\\n');" + "f.close();" + "exec(compile(code, __file__, 'exec'))" +) diff --git a/venv/lib/python3.7/site-packages/pip/_internal/utils/temp_dir.py b/venv/lib/python3.7/site-packages/pip/_internal/utils/temp_dir.py new file mode 100644 index 0000000..edc506b --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/utils/temp_dir.py @@ -0,0 +1,82 @@ +from __future__ import absolute_import + +import logging +import os.path +import tempfile + +from pip._internal.utils.misc import rmtree + +logger = logging.getLogger(__name__) + + +class TempDirectory(object): + """Helper class that owns and cleans up a temporary directory. + + This class can be used as a context manager or as an OO representation of a + temporary directory. + + Attributes: + path + Location to the created temporary directory or None + 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 + + 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. + """ + + def __init__(self, path=None, delete=None, kind="temp"): + 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 + + self.path = path + self.delete = delete + self.kind = kind + + def __repr__(self): + return "<{} {!r}>".format(self.__class__.__name__, self.path) + + def __enter__(self): + self.create() + return self + + def __exit__(self, exc, value, tb): + if self.delete: + self.cleanup() + + def create(self): + """Create a temporary directory and store it's 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)) + ) + logger.debug("Created temporary directory: {}".format(self.path)) + + def cleanup(self): + """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 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/utils/typing.py b/venv/lib/python3.7/site-packages/pip/_internal/utils/typing.py new file mode 100644 index 0000000..e085cdf --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/utils/typing.py @@ -0,0 +1,29 @@ +"""For neatly implementing static typing in pip. + +`mypy` - the static type analysis tool we use - uses the `typing` module, which +provides core functionality fundamental to mypy's functioning. + +Generally, `typing` would be imported at runtime and used in that fashion - +it acts as a no-op at runtime and does not have any run-time overhead by +design. + +As it turns out, `typing` is not vendorable - it uses separate sources for +Python 2/Python 3. Thus, this codebase can not expect it to be present. +To work around this, mypy allows the typing import to be behind a False-y +optional to prevent it from running at runtime and type-comments can be used +to remove the need for the types to be accessible directly during runtime. + +This module provides the False-y guard in a nicely named fashion so that a +curious maintainer can reach here to read this. + +In pip, all static-typing related imports should be guarded as follows: + + from pip._internal.utils.typing import MYPY_CHECK_RUNNING + + if MYPY_CHECK_RUNNING: + from typing import ... # noqa: F401 + +Ref: https://github.com/python/mypy/issues/3216 +""" + +MYPY_CHECK_RUNNING = False diff --git a/venv/lib/python3.7/site-packages/pip/_internal/utils/ui.py b/venv/lib/python3.7/site-packages/pip/_internal/utils/ui.py new file mode 100644 index 0000000..6bab904 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/utils/ui.py @@ -0,0 +1,421 @@ +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.bar import ( + Bar, ChargingBar, FillingCirclesBar, FillingSquaresBar, IncrementalBar, + ShadyBar, +) +from pip._vendor.progress.helpers import HIDE_CURSOR, SHOW_CURSOR, WritelnMixin +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 # noqa: F401 + +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 neds 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): # type: ignore + pass + + +class DownloadSilentBar(BaseDownloadProgressBar, SilentBar): # type: ignore + pass + + +class DownloadIncrementalBar(BaseDownloadProgressBar, # type: ignore + IncrementalBar): + pass + + +class DownloadChargingBar(BaseDownloadProgressBar, # type: ignore + ChargingBar): + pass + + +class DownloadShadyBar(BaseDownloadProgressBar, ShadyBar): # type: ignore + pass + + +class DownloadFillingSquaresBar(BaseDownloadProgressBar, # type: ignore + FillingSquaresBar): + pass + + +class DownloadFillingCirclesBar(BaseDownloadProgressBar, # type: ignore + FillingCirclesBar): + pass + + +class DownloadBlueEmojiProgressBar(BaseDownloadProgressBar, # type: ignore + BlueEmojiBar): + pass + + +class DownloadProgressSpinner(WindowsMixin, InterruptibleMixin, + DownloadProgressMixin, WritelnMixin, 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": (DownloadIncrementalBar, 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): + # 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): + self._min_update_interval_seconds = min_update_interval_seconds + self._last_update = 0 + + def ready(self): + now = time.time() + delta = now - self._last_update + return delta >= self._min_update_interval_seconds + + def reset(self): + self._last_update = time.time() + + +class InteractiveSpinner(object): + 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): + if self._finished: + return + if not self._rate_limiter.ready(): + return + self._write(next(self._spin_cycle)) + + def finish(self, final_status): + 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(object): + def __init__(self, message, min_update_interval_seconds=60): + 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): + if self._finished: + return + if not self._rate_limiter.ready(): + return + self._update("still running...") + + def finish(self, final_status): + if self._finished: + return + self._update("finished with status '%s'" % (final_status,)) + self._finished = True + + +@contextlib.contextmanager +def open_spinner(message): + # 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) + 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.7/site-packages/pip/_internal/vcs/__init__.py b/venv/lib/python3.7/site-packages/pip/_internal/vcs/__init__.py new file mode 100644 index 0000000..794b35d --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/vcs/__init__.py @@ -0,0 +1,509 @@ +"""Handles all VCS (version control) support""" +from __future__ import absolute_import + +import errno +import logging +import os +import shutil +import sys + +from pip._vendor.six.moves.urllib import parse as urllib_parse + +from pip._internal.exceptions import BadCommand +from pip._internal.utils.misc import ( + display_path, backup_dir, call_subprocess, rmtree, ask_path_exists, +) +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Dict, Optional, Tuple # noqa: F401 + from pip._internal.cli.base_command import Command # noqa: F401 + +__all__ = ['vcs', 'get_src_requirement'] + + +logger = logging.getLogger(__name__) + + +class RevOptions(object): + + """ + Encapsulates a VCS-specific revision to install, along with any VCS + install options. + + Instances of this class should be treated as if immutable. + """ + + def __init__(self, vcs, rev=None, extra_args=None): + """ + Args: + vcs: a VersionControl object. + rev: the name of the revision to install. + extra_args: a list of extra options. + """ + if extra_args is None: + extra_args = [] + + self.extra_args = extra_args + self.rev = rev + self.vcs = vcs + + def __repr__(self): + return '<RevOptions {}: rev={!r}>'.format(self.vcs.name, self.rev) + + @property + def arg_rev(self): + if self.rev is None: + return self.vcs.default_arg_rev + + return self.rev + + def to_args(self): + """ + Return the VCS-specific command arguments. + """ + args = [] + rev = self.arg_rev + if rev is not None: + args += self.vcs.get_base_rev_args(rev) + args += self.extra_args + + return args + + def to_display(self): + if not self.rev: + return '' + + return ' (to revision {})'.format(self.rev) + + def make_new(self, rev): + """ + Make a copy of the current instance, but with a new rev. + + Args: + rev: the name of the revision for the new object. + """ + return self.vcs.make_rev_options(rev, extra_args=self.extra_args) + + +class VcsSupport(object): + _registry = {} # type: Dict[str, Command] + schemes = ['ssh', 'git', 'hg', 'bzr', 'sftp', 'svn'] + + def __init__(self): + # Register more schemes with urlparse for various version control + # systems + urllib_parse.uses_netloc.extend(self.schemes) + # Python >= 2.7.4, 3.3 doesn't have uses_fragment + if getattr(urllib_parse, 'uses_fragment', None): + urllib_parse.uses_fragment.extend(self.schemes) + super(VcsSupport, self).__init__() + + def __iter__(self): + return self._registry.__iter__() + + @property + def backends(self): + return list(self._registry.values()) + + @property + def dirnames(self): + return [backend.dirname for backend in self.backends] + + @property + def all_schemes(self): + schemes = [] + for backend in self.backends: + schemes.extend(backend.schemes) + return schemes + + def register(self, cls): + if not hasattr(cls, 'name'): + logger.warning('Cannot register VCS %s', cls.__name__) + return + if cls.name not in self._registry: + self._registry[cls.name] = cls + logger.debug('Registered VCS backend: %s', cls.name) + + def unregister(self, cls=None, name=None): + if name in self._registry: + del self._registry[name] + elif cls in self._registry.values(): + del self._registry[cls.name] + else: + logger.warning('Cannot unregister because no class or name given') + + def get_backend_name(self, location): + """ + Return the name of the version control backend if found at given + location, e.g. vcs.get_backend_name('/path/to/vcs/checkout') + """ + for vc_type in self._registry.values(): + if vc_type.controls_location(location): + logger.debug('Determine that %s uses VCS: %s', + location, vc_type.name) + return vc_type.name + return None + + def get_backend(self, name): + name = name.lower() + if name in self._registry: + return self._registry[name] + + def get_backend_from_location(self, location): + vc_type = self.get_backend_name(location) + if vc_type: + return self.get_backend(vc_type) + return None + + +vcs = VcsSupport() + + +class VersionControl(object): + name = '' + dirname = '' + # List of supported schemes for this Version Control + schemes = () # type: Tuple[str, ...] + # Iterable of environment variable names to pass to call_subprocess(). + unset_environ = () # type: Tuple[str, ...] + default_arg_rev = None # type: Optional[str] + + def __init__(self, url=None, *args, **kwargs): + self.url = url + super(VersionControl, self).__init__(*args, **kwargs) + + def get_base_rev_args(self, rev): + """ + Return the base revision arguments for a vcs command. + + Args: + rev: the name of a revision to install. Cannot be None. + """ + raise NotImplementedError + + def make_rev_options(self, rev=None, extra_args=None): + """ + Return a RevOptions object. + + Args: + rev: the name of a revision to install. + extra_args: a list of extra options. + """ + return RevOptions(self, rev, extra_args=extra_args) + + def _is_local_repository(self, repo): + """ + posix absolute paths start with os.path.sep, + win32 ones start with drive (like c:\\folder) + """ + drive, tail = os.path.splitdrive(repo) + return repo.startswith(os.path.sep) or drive + + def export(self, location): + """ + Export the repository at the url to the destination location + i.e. only download the files, without vcs informations + """ + raise NotImplementedError + + def get_netloc_and_auth(self, netloc, scheme): + """ + Parse the repository URL's netloc, and return the new netloc to use + along with auth information. + + Args: + netloc: the original repository URL netloc. + scheme: the repository URL's scheme without the vcs prefix. + + This is mainly for the Subversion class to override, so that auth + information can be provided via the --username and --password options + instead of through the URL. For other subclasses like Git without + such an option, auth information must stay in the URL. + + Returns: (netloc, (username, password)). + """ + return netloc, (None, None) + + def get_url_rev_and_auth(self, url): + """ + Parse the repository URL to use, and return the URL, revision, + and auth info to use. + + Returns: (url, rev, (username, password)). + """ + scheme, netloc, path, query, frag = urllib_parse.urlsplit(url) + if '+' not in scheme: + raise ValueError( + "Sorry, {!r} is a malformed VCS url. " + "The format is <vcs>+<protocol>://<url>, " + "e.g. svn+http://myrepo/svn/MyApp#egg=MyApp".format(url) + ) + # Remove the vcs prefix. + scheme = scheme.split('+', 1)[1] + netloc, user_pass = self.get_netloc_and_auth(netloc, scheme) + rev = None + if '@' in path: + path, rev = path.rsplit('@', 1) + url = urllib_parse.urlunsplit((scheme, netloc, path, query, '')) + return url, rev, user_pass + + def make_rev_args(self, username, password): + """ + Return the RevOptions "extra arguments" to use in obtain(). + """ + return [] + + def get_url_rev_options(self, url): + """ + 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 + extra_args = self.make_rev_args(username, password) + rev_options = self.make_rev_options(rev, extra_args=extra_args) + + return url, rev_options + + def normalize_url(self, url): + """ + Normalize a URL for comparison by unquoting it and removing any + trailing slash. + """ + return urllib_parse.unquote(url).rstrip('/') + + def compare_urls(self, url1, url2): + """ + Compare two repo URLs for identity, ignoring incidental differences. + """ + return (self.normalize_url(url1) == self.normalize_url(url2)) + + def fetch_new(self, dest, url, rev_options): + """ + Fetch a revision from a repository, in the case that this is the + first fetch from the repository. + + Args: + dest: the directory to fetch the repository to. + rev_options: a RevOptions object. + """ + raise NotImplementedError + + def switch(self, dest, url, rev_options): + """ + Switch the repo at ``dest`` to point to ``URL``. + + Args: + rev_options: a RevOptions object. + """ + raise NotImplementedError + + def update(self, dest, url, rev_options): + """ + Update an already-existing repo to the given ``rev_options``. + + Args: + rev_options: a RevOptions object. + """ + raise NotImplementedError + + def is_commit_id_equal(self, dest, name): + """ + Return whether the id of the current commit equals the given name. + + Args: + dest: the repository directory. + name: a string name. + """ + raise NotImplementedError + + def obtain(self, dest): + """ + Install or update in editable mode the package represented by this + VersionControl object. + + Args: + dest: the repository directory in which to install or update. + """ + url, rev_options = self.get_url_rev_options(self.url) + + if not os.path.exists(dest): + self.fetch_new(dest, url, rev_options) + return + + rev_display = rev_options.to_display() + if self.is_repository_directory(dest): + existing_url = self.get_url(dest) + if self.compare_urls(existing_url, url): + logger.debug( + '%s in %s exists, and has correct URL (%s)', + self.repo_name.title(), + display_path(dest), + url, + ) + if not self.is_commit_id_equal(dest, rev_options.rev): + logger.info( + 'Updating %s %s%s', + display_path(dest), + self.repo_name, + rev_display, + ) + self.update(dest, url, rev_options) + else: + logger.info('Skipping because already up-to-date.') + return + + logger.warning( + '%s %s in %s exists with URL %s', + self.name, + self.repo_name, + display_path(dest), + existing_url, + ) + prompt = ('(s)witch, (i)gnore, (w)ipe, (b)ackup ', + ('s', 'i', 'w', 'b')) + else: + logger.warning( + 'Directory %s already exists, and is not a %s %s.', + dest, + self.name, + self.repo_name, + ) + prompt = ('(i)gnore, (w)ipe, (b)ackup ', ('i', 'w', 'b')) + + logger.warning( + 'The plan is to install the %s repository %s', + self.name, + url, + ) + response = ask_path_exists('What to do? %s' % prompt[0], prompt[1]) + + if response == 'a': + sys.exit(-1) + + if response == 'w': + logger.warning('Deleting %s', display_path(dest)) + rmtree(dest) + self.fetch_new(dest, url, rev_options) + return + + if response == 'b': + dest_dir = backup_dir(dest) + logger.warning( + 'Backing up %s to %s', display_path(dest), dest_dir, + ) + shutil.move(dest, dest_dir) + self.fetch_new(dest, url, rev_options) + return + + # Do nothing if the response is "i". + if response == 's': + logger.info( + 'Switching %s %s to %s%s', + self.repo_name, + display_path(dest), + url, + rev_display, + ) + self.switch(dest, url, rev_options) + + def unpack(self, location): + """ + Clean up current location and download the url repository + (and vcs infos) into location + """ + if os.path.exists(location): + rmtree(location) + self.obtain(location) + + def get_src_requirement(self, dist, location): + """ + Return a string representing the requirement needed to + redownload the files currently present in location, something + like: + {repository_url}@{revision}#egg={project_name}-{version_identifier} + """ + raise NotImplementedError + + def get_url(self, location): + """ + Return the url used at location + """ + raise NotImplementedError + + def get_revision(self, location): + """ + Return the current commit id of the files at the given location. + """ + raise NotImplementedError + + def run_command(self, cmd, show_stdout=True, cwd=None, + on_returncode='raise', + command_desc=None, + extra_environ=None, spinner=None): + """ + Run a VCS subcommand + This is simply a wrapper around call_subprocess that adds the VCS + command name, and checks that the VCS is available + """ + cmd = [self.name] + cmd + try: + return call_subprocess(cmd, show_stdout, cwd, + on_returncode, + command_desc, extra_environ, + unset_environ=self.unset_environ, + spinner=spinner) + 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?' % (self.name, self.name)) + else: + raise # re-raise exception if a different error occurred + + @classmethod + def is_repository_directory(cls, path): + """ + Return whether a directory path is a repository directory. + """ + logger.debug('Checking in %s for %s (%s)...', + path, cls.dirname, cls.name) + return os.path.exists(os.path.join(path, cls.dirname)) + + @classmethod + def controls_location(cls, location): + """ + Check if a location is controlled by the vcs. + 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. + """ + return cls.is_repository_directory(location) + + +def get_src_requirement(dist, location): + version_control = vcs.get_backend_from_location(location) + if version_control: + try: + return version_control().get_src_requirement(dist, + location) + except BadCommand: + logger.warning( + 'cannot determine version of editable source in %s ' + '(%s command not found in path)', + location, + version_control.name, + ) + return dist.as_requirement() + logger.warning( + 'cannot determine version of editable source in %s (is not SVN ' + 'checkout, Git clone, Mercurial clone or Bazaar branch)', + location, + ) + return dist.as_requirement() diff --git a/venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8a18f06589647df0c1b7c426e8f4d0214e26fb93 GIT binary patch literal 15566 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1266e6f8715371dfcae009d3ab5f42fb5501835c GIT binary patch literal 3829 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 It@hvk2iX0zumAu6 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/git.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/git.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..920a8b7f1eddcd0c170ecb60ba8174635a630753 GIT binary patch literal 9134 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7795061d4a2b71e0d949923d02c558cc1b35be69 GIT binary patch literal 3802 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 b?-8-oHky_lve0g!TJ0cXcI>9p`Ro4yn_#}d literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fd7aefc878286db8f9f5a6242092ec9b74cb3eb9 GIT binary patch literal 6404 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 WC<GJ`5*Dq}AXvDTYn6Uxy!jta3qXMY literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_internal/vcs/bazaar.py b/venv/lib/python3.7/site-packages/pip/_internal/vcs/bazaar.py new file mode 100644 index 0000000..3cc66c9 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/vcs/bazaar.py @@ -0,0 +1,112 @@ +from __future__ import absolute_import + +import logging +import os + +from pip._vendor.six.moves.urllib import parse as urllib_parse + +from pip._internal.download import path_to_url +from pip._internal.utils.misc import ( + display_path, make_vcs_requirement_url, rmtree, +) +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.vcs import VersionControl, vcs + +logger = logging.getLogger(__name__) + + +class Bazaar(VersionControl): + name = 'bzr' + dirname = '.bzr' + repo_name = 'branch' + schemes = ( + 'bzr', 'bzr+http', 'bzr+https', 'bzr+ssh', 'bzr+sftp', 'bzr+ftp', + 'bzr+lp', + ) + + def __init__(self, url=None, *args, **kwargs): + super(Bazaar, self).__init__(url, *args, **kwargs) + # This is only needed for python <2.7.5 + # Register lp but do not expose as a scheme to support bzr+lp. + if getattr(urllib_parse, 'uses_fragment', None): + urllib_parse.uses_fragment.extend(['lp']) + + def get_base_rev_args(self, rev): + return ['-r', rev] + + def export(self, location): + """ + Export the Bazaar repository at the url to the destination location + """ + # Remove the location to make sure Bazaar can export it correctly + if os.path.exists(location): + rmtree(location) + + with TempDirectory(kind="export") as temp_dir: + self.unpack(temp_dir.path) + + self.run_command( + ['export', location], + cwd=temp_dir.path, show_stdout=False, + ) + + def fetch_new(self, dest, url, rev_options): + rev_display = rev_options.to_display() + logger.info( + 'Checking out %s%s to %s', + url, + rev_display, + display_path(dest), + ) + cmd_args = ['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) + + def update(self, dest, url, rev_options): + cmd_args = ['pull', '-q'] + rev_options.to_args() + self.run_command(cmd_args, cwd=dest) + + def get_url_rev_and_auth(self, url): + # hotfix the URL scheme after removing bzr+ from bzr+ssh:// readd it + url, rev, user_pass = super(Bazaar, self).get_url_rev_and_auth(url) + if url.startswith('ssh://'): + url = 'bzr+' + url + return url, rev, user_pass + + def get_url(self, location): + urls = self.run_command(['info'], show_stdout=False, cwd=location) + for line in urls.splitlines(): + line = line.strip() + for x in ('checkout of branch: ', + 'parent branch: '): + if line.startswith(x): + repo = line.split(x)[1] + if self._is_local_repository(repo): + return path_to_url(repo) + return repo + return None + + def get_revision(self, location): + revision = self.run_command( + ['revno'], show_stdout=False, cwd=location, + ) + return revision.splitlines()[-1] + + def get_src_requirement(self, dist, location): + repo = self.get_url(location) + if not repo: + return None + if not repo.lower().startswith('bzr:'): + repo = 'bzr+' + repo + current_rev = self.get_revision(location) + egg_project_name = dist.egg_name().split('-', 1)[0] + return make_vcs_requirement_url(repo, current_rev, egg_project_name) + + def is_commit_id_equal(self, dest, name): + """Always assume the versions don't match""" + return False + + +vcs.register(Bazaar) diff --git a/venv/lib/python3.7/site-packages/pip/_internal/vcs/git.py b/venv/lib/python3.7/site-packages/pip/_internal/vcs/git.py new file mode 100644 index 0000000..9778539 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/vcs/git.py @@ -0,0 +1,346 @@ +from __future__ import absolute_import + +import logging +import os.path +import re + +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, make_vcs_requirement_url +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.vcs import VersionControl, vcs + +urlsplit = urllib_parse.urlsplit +urlunsplit = urllib_parse.urlunsplit + + +logger = logging.getLogger(__name__) + + +HASH_REGEX = re.compile('[a-fA-F0-9]{40}') + + +def looks_like_hash(sha): + return bool(HASH_REGEX.match(sha)) + + +class Git(VersionControl): + name = 'git' + dirname = '.git' + repo_name = 'clone' + schemes = ( + 'git', 'git+http', 'git+https', 'git+ssh', 'git+git', 'git+file', + ) + # Prevent the user's environment variables from interfering with pip: + # https://github.com/pypa/pip/issues/1130 + unset_environ = ('GIT_DIR', 'GIT_WORK_TREE') + default_arg_rev = 'HEAD' + + def __init__(self, url=None, *args, **kwargs): + + # Works around an apparent Git bug + # (see https://article.gmane.org/gmane.comp.version-control.git/146500) + if url: + scheme, netloc, path, query, fragment = urlsplit(url) + if scheme.endswith('file'): + initial_slashes = path[:-len(path.lstrip('/'))] + newpath = ( + initial_slashes + + urllib_request.url2pathname(path) + .replace('\\', '/').lstrip('/') + ) + url = urlunsplit((scheme, netloc, newpath, query, fragment)) + after_plus = scheme.find('+') + 1 + url = scheme[:after_plus] + urlunsplit( + (scheme[after_plus:], netloc, newpath, query, fragment), + ) + + super(Git, self).__init__(url, *args, **kwargs) + + def get_base_rev_args(self, rev): + return [rev] + + def get_git_version(self): + VERSION_PFX = 'git version ' + version = self.run_command(['version'], show_stdout=False) + if version.startswith(VERSION_PFX): + version = version[len(VERSION_PFX):].split()[0] + else: + version = '' + # get first 3 positions of the git version becasue + # on windows it is x.y.z.windows.t, and this parses as + # LegacyVersion which always smaller than a Version. + version = '.'.join(version.split('.')[:3]) + return parse_version(version) + + def get_branch(self, location): + """ + Return the current branch, or None if HEAD isn't at a branch + (e.g. detached HEAD). + """ + args = ['rev-parse', '--abbrev-ref', 'HEAD'] + output = self.run_command(args, show_stdout=False, cwd=location) + branch = output.strip() + + if branch == 'HEAD': + return None + + return branch + + def export(self, location): + """Export the Git repository at the url to the destination location""" + if not location.endswith('/'): + location = location + '/' + + with TempDirectory(kind="export") as temp_dir: + self.unpack(temp_dir.path) + self.run_command( + ['checkout-index', '-a', '-f', '--prefix', location], + show_stdout=False, cwd=temp_dir.path + ) + + def get_revision_sha(self, dest, rev): + """ + Return (sha_or_none, is_branch), where sha_or_none is a commit hash + if the revision names a remote branch or tag, otherwise None. + + Args: + dest: the repository directory. + rev: the revision name. + """ + # Pass rev to pre-filter the list. + output = self.run_command(['show-ref', rev], cwd=dest, + show_stdout=False, on_returncode='ignore') + refs = {} + for line in output.strip().splitlines(): + try: + sha, ref = line.split() + except ValueError: + # Include the offending line to simplify troubleshooting if + # this error ever occurs. + raise ValueError('unexpected show-ref line: {!r}'.format(line)) + + refs[ref] = sha + + branch_ref = 'refs/remotes/origin/{}'.format(rev) + tag_ref = 'refs/tags/{}'.format(rev) + + sha = refs.get(branch_ref) + if sha is not None: + return (sha, True) + + sha = refs.get(tag_ref) + + return (sha, False) + + def resolve_revision(self, dest, url, rev_options): + """ + Resolve a revision to a new RevOptions object with the SHA1 of the + branch, tag, or ref if found. + + Args: + rev_options: a RevOptions object. + """ + rev = rev_options.arg_rev + sha, is_branch = self.get_revision_sha(dest, rev) + + if sha is not None: + rev_options = rev_options.make_new(sha) + rev_options.branch_name = rev if is_branch else None + + return rev_options + + # Do not show a warning for the common case of something that has + # the form of a Git commit hash. + if not looks_like_hash(rev): + logger.warning( + "Did not find branch or tag '%s', assuming revision or ref.", + rev, + ) + + if not rev.startswith('refs/'): + return rev_options + + # If it looks like a ref, we have to fetch it explicitly. + self.run_command( + ['fetch', '-q', url] + rev_options.to_args(), + cwd=dest, + ) + # Change the revision to the SHA of the ref we fetched + sha = self.get_revision(dest, rev='FETCH_HEAD') + rev_options = rev_options.make_new(sha) + + return rev_options + + def is_commit_id_equal(self, dest, name): + """ + Return whether the current commit hash equals the given name. + + Args: + dest: the repository directory. + name: a string name. + """ + if not name: + # Then avoid an unnecessary subprocess call. + return False + + return self.get_revision(dest) == name + + def fetch_new(self, dest, url, rev_options): + rev_display = rev_options.to_display() + logger.info( + 'Cloning %s%s to %s', url, rev_display, display_path(dest), + ) + self.run_command(['clone', '-q', url, dest]) + + if rev_options.rev: + # Then a specific revision was requested. + rev_options = self.resolve_revision(dest, url, rev_options) + branch_name = getattr(rev_options, 'branch_name', None) + if branch_name is None: + # 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() + self.run_command(cmd_args, cwd=dest) + elif self.get_branch(dest) != branch_name: + # Then a specific branch was requested, and that branch + # is not yet checked out. + track_branch = 'origin/{}'.format(branch_name) + cmd_args = [ + 'checkout', '-b', branch_name, '--track', track_branch, + ] + self.run_command(cmd_args, cwd=dest) + + #: repo may contain submodules + 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() + self.run_command(cmd_args, cwd=dest) + + self.update_submodules(dest) + + def update(self, dest, url, rev_options): + # First fetch changes from the default remote + if self.get_git_version() >= parse_version('1.9.0'): + # fetch tags in addition to everything else + self.run_command(['fetch', '-q', '--tags'], cwd=dest) + else: + 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() + self.run_command(cmd_args, cwd=dest) + #: update submodules + self.update_submodules(dest) + + def get_url(self, location): + """Return URL of the first remote encountered.""" + remotes = self.run_command( + ['config', '--get-regexp', r'remote\..*\.url'], + show_stdout=False, cwd=location, + ) + remotes = remotes.splitlines() + found_remote = remotes[0] + for remote in remotes: + if remote.startswith('remote.origin.url '): + found_remote = remote + break + url = found_remote.split(' ')[1] + return url.strip() + + def get_revision(self, location, rev=None): + if rev is None: + rev = 'HEAD' + current_rev = self.run_command( + ['rev-parse', rev], show_stdout=False, cwd=location, + ) + return current_rev.strip() + + def _get_subdirectory(self, location): + """Return the relative path of setup.py to the git repo root.""" + # find the repo root + git_dir = self.run_command(['rev-parse', '--git-dir'], + show_stdout=False, 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) + + def get_src_requirement(self, dist, location): + repo = self.get_url(location) + if not repo.lower().startswith('git:'): + repo = 'git+' + repo + current_rev = self.get_revision(location) + egg_project_name = dist.egg_name().split('-', 1)[0] + subdir = self._get_subdirectory(location) + req = make_vcs_requirement_url(repo, current_rev, egg_project_name, + subdir=subdir) + + return req + + def get_url_rev_and_auth(self, url): + """ + Prefixes stub URLs like 'user@hostname:user/repo.git' with 'ssh://'. + That's required because although they use SSH they sometimes don't + work with a ssh:// scheme (e.g. GitHub). But we need a scheme for + parsing. Hence we remove it again afterwards and return it as a stub. + """ + if '://' not in url: + assert 'file:' not in url + url = url.replace('git+', 'git+ssh://') + url, rev, user_pass = super(Git, self).get_url_rev_and_auth(url) + url = url.replace('ssh://', '') + else: + url, rev, user_pass = super(Git, self).get_url_rev_and_auth(url) + + return url, rev, user_pass + + def update_submodules(self, location): + if not os.path.exists(os.path.join(location, '.gitmodules')): + return + self.run_command( + ['submodule', 'update', '--init', '--recursive', '-q'], + cwd=location, + ) + + @classmethod + def controls_location(cls, location): + if super(Git, cls).controls_location(location): + return True + try: + r = cls().run_command(['rev-parse'], + cwd=location, + show_stdout=False, + on_returncode='ignore') + return not r + except BadCommand: + logger.debug("could not determine if %s is under git control " + "because git is not available", location) + return False + + +vcs.register(Git) diff --git a/venv/lib/python3.7/site-packages/pip/_internal/vcs/mercurial.py b/venv/lib/python3.7/site-packages/pip/_internal/vcs/mercurial.py new file mode 100644 index 0000000..17cfb67 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/vcs/mercurial.py @@ -0,0 +1,101 @@ +from __future__ import absolute_import + +import logging +import os + +from pip._vendor.six.moves import configparser + +from pip._internal.download import path_to_url +from pip._internal.utils.misc import display_path, make_vcs_requirement_url +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.vcs import VersionControl, vcs + +logger = logging.getLogger(__name__) + + +class Mercurial(VersionControl): + name = 'hg' + dirname = '.hg' + repo_name = 'clone' + schemes = ('hg', 'hg+http', 'hg+https', 'hg+ssh', 'hg+static-http') + + def get_base_rev_args(self, rev): + return [rev] + + def export(self, location): + """Export the Hg repository at the url to the destination location""" + with TempDirectory(kind="export") as temp_dir: + self.unpack(temp_dir.path) + + self.run_command( + ['archive', location], show_stdout=False, cwd=temp_dir.path + ) + + def fetch_new(self, dest, url, rev_options): + rev_display = rev_options.to_display() + logger.info( + 'Cloning hg %s%s to %s', + url, + 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) + + def switch(self, dest, url, rev_options): + repo_config = os.path.join(dest, self.dirname, 'hgrc') + config = configparser.SafeConfigParser() + try: + config.read(repo_config) + config.set('paths', 'default', url) + with open(repo_config, 'w') as config_file: + config.write(config_file) + except (OSError, configparser.NoSectionError) as exc: + logger.warning( + 'Could not switch Mercurial repository to %s: %s', url, exc, + ) + else: + cmd_args = ['update', '-q'] + rev_options.to_args() + self.run_command(cmd_args, cwd=dest) + + def update(self, dest, url, rev_options): + self.run_command(['pull', '-q'], cwd=dest) + cmd_args = ['update', '-q'] + rev_options.to_args() + self.run_command(cmd_args, cwd=dest) + + def get_url(self, location): + url = self.run_command( + ['showconfig', 'paths.default'], + show_stdout=False, cwd=location).strip() + if self._is_local_repository(url): + url = path_to_url(url) + return url.strip() + + def get_revision(self, location): + current_revision = self.run_command( + ['parents', '--template={rev}'], + show_stdout=False, cwd=location).strip() + return current_revision + + def get_revision_hash(self, location): + current_rev_hash = self.run_command( + ['parents', '--template={node}'], + show_stdout=False, cwd=location).strip() + return current_rev_hash + + def get_src_requirement(self, dist, location): + repo = self.get_url(location) + if not repo.lower().startswith('hg:'): + repo = 'hg+' + repo + current_rev_hash = self.get_revision_hash(location) + egg_project_name = dist.egg_name().split('-', 1)[0] + return make_vcs_requirement_url(repo, current_rev_hash, + egg_project_name) + + def is_commit_id_equal(self, dest, name): + """Always assume the versions don't match""" + return False + + +vcs.register(Mercurial) diff --git a/venv/lib/python3.7/site-packages/pip/_internal/vcs/subversion.py b/venv/lib/python3.7/site-packages/pip/_internal/vcs/subversion.py new file mode 100644 index 0000000..6f7cb5d --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/vcs/subversion.py @@ -0,0 +1,213 @@ +from __future__ import absolute_import + +import logging +import os +import re + +from pip._internal.models.link import Link +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ( + display_path, make_vcs_requirement_url, rmtree, split_auth_from_netloc, +) +from pip._internal.vcs import VersionControl, vcs + +_svn_xml_url_re = re.compile('url="([^"]+)"') +_svn_rev_re = re.compile(r'committed-rev="(\d+)"') +_svn_info_xml_rev_re = re.compile(r'\s*revision="(\d+)"') +_svn_info_xml_url_re = re.compile(r'<url>(.*)</url>') + + +logger = logging.getLogger(__name__) + + +class Subversion(VersionControl): + name = 'svn' + dirname = '.svn' + repo_name = 'checkout' + schemes = ('svn', 'svn+ssh', 'svn+http', 'svn+https', 'svn+svn') + + def get_base_rev_args(self, rev): + return ['-r', rev] + + def export(self, location): + """Export the svn repository at the url to the destination location""" + url, rev_options = self.get_url_rev_options(self.url) + + logger.info('Exporting svn repository %s to %s', url, location) + with indent_log(): + if os.path.exists(location): + # 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'] + rev_options.to_args() + [url, location] + self.run_command(cmd_args, show_stdout=False) + + def fetch_new(self, dest, url, rev_options): + rev_display = rev_options.to_display() + logger.info( + 'Checking out %s%s to %s', + url, + rev_display, + display_path(dest), + ) + cmd_args = ['checkout', '-q'] + rev_options.to_args() + [url, dest] + self.run_command(cmd_args) + + def switch(self, dest, url, rev_options): + cmd_args = ['switch'] + rev_options.to_args() + [url, dest] + self.run_command(cmd_args) + + def update(self, dest, url, rev_options): + cmd_args = ['update'] + rev_options.to_args() + [dest] + self.run_command(cmd_args) + + def get_location(self, dist, dependency_links): + for url in dependency_links: + egg_fragment = Link(url).egg_fragment + if not egg_fragment: + continue + if '-' in egg_fragment: + # FIXME: will this work when a package has - in the name? + key = '-'.join(egg_fragment.split('-')[:-1]).lower() + else: + key = egg_fragment + if key == dist.key: + return url.split('#', 1)[0] + return None + + def get_revision(self, location): + """ + Return the maximum revision for all files under a given location + """ + # Note: taken from setuptools.command.egg_info + revision = 0 + + for base, dirs, files in os.walk(location): + if self.dirname not in dirs: + dirs[:] = [] + continue # no sense walking uncontrolled subdirs + dirs.remove(self.dirname) + entries_fn = os.path.join(base, self.dirname, 'entries') + if not os.path.exists(entries_fn): + # FIXME: should we warn? + continue + + dirurl, localrev = self._get_svn_url_rev(base) + + if base == location: + base = dirurl + '/' # save the root url + elif not dirurl or not dirurl.startswith(base): + dirs[:] = [] + continue # not part of the same svn tree, skip it + revision = max(revision, localrev) + return revision + + def get_netloc_and_auth(self, netloc, scheme): + """ + This override allows the auth information to be passed to svn via the + --username and --password options instead of via the URL. + """ + if scheme == 'ssh': + # The --username and --password options can't be used for + # svn+ssh URLs, so keep the auth information in the URL. + return super(Subversion, self).get_netloc_and_auth( + netloc, scheme) + + return split_auth_from_netloc(netloc) + + def get_url_rev_and_auth(self, url): + # hotfix the URL scheme after removing svn+ from svn+ssh:// readd it + url, rev, user_pass = super(Subversion, self).get_url_rev_and_auth(url) + if url.startswith('ssh://'): + url = 'svn+' + url + return url, rev, user_pass + + def make_rev_args(self, username, password): + extra_args = [] + if username: + extra_args += ['--username', username] + if password: + extra_args += ['--password', password] + + return extra_args + + def get_url(self, location): + # In cases where the source is in a subdirectory, not alongside + # setup.py we have to look up in the location until we find a real + # 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 + + return self._get_svn_url_rev(location)[0] + + def _get_svn_url_rev(self, location): + from pip._internal.exceptions import InstallationError + + entries_path = os.path.join(location, self.dirname, 'entries') + if os.path.exists(entries_path): + with open(entries_path) as f: + data = f.read() + else: # subversion >= 1.7 does not have the 'entries' file + data = '' + + if (data.startswith('8') or + data.startswith('9') or + data.startswith('10')): + data = list(map(str.splitlines, data.split('\n\x0c\n'))) + del data[0][0] # get rid of the '8' + url = data[0][3] + revs = [int(d[9]) for d in data if len(d) > 9 and d[9]] + [0] + elif data.startswith('<?xml'): + match = _svn_xml_url_re.search(data) + if not match: + raise ValueError('Badly formatted data: %r' % data) + url = match.group(1) # get repository URL + revs = [int(m.group(1)) for m in _svn_rev_re.finditer(data)] + [0] + else: + try: + # subversion >= 1.7 + xml = self.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: + url, revs = None, [] + + if revs: + rev = max(revs) + else: + rev = 0 + + return url, rev + + def get_src_requirement(self, dist, location): + repo = self.get_url(location) + if repo is None: + return None + repo = 'svn+' + repo + rev = self.get_revision(location) + # FIXME: why not project name? + egg_project_name = dist.egg_name().split('-', 1)[0] + return make_vcs_requirement_url(repo, rev, egg_project_name) + + def is_commit_id_equal(self, dest, name): + """Always assume the versions don't match""" + return False + + +vcs.register(Subversion) diff --git a/venv/lib/python3.7/site-packages/pip/_internal/wheel.py b/venv/lib/python3.7/site-packages/pip/_internal/wheel.py new file mode 100644 index 0000000..5ce890e --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_internal/wheel.py @@ -0,0 +1,831 @@ +""" +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 path_to_url, unpack_url +from pip._internal.exceptions import ( + InstallationError, InvalidWheelFilename, UnsupportedWheel, +) +from pip._internal.locations import ( + PIP_DELETE_MARKER_FILENAME, distutils_scheme, +) +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ( + call_subprocess, captured_stdout, ensure_dir, read_chunks, +) +from pip._internal.utils.setuptools_build import SETUPTOOLS_SHIM +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 # noqa: F401 + +wheel_ext = '.whl' + +VERSION_COMPATIBLE = (1, 0) + + +logger = logging.getLogger(__name__) + + +def rehash(path, blocksize=1 << 20): + """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) + digest = 'sha256=' + urlsafe_b64encode( + h.digest() + ).decode('latin1').rstrip('=') + return (digest, length) + + +def open_for_csv(name, mode): + if sys.version_info[0] < 3: + nl = {} + bin = 'b' + else: + nl = {'newline': ''} + bin = '' + return open(name, mode + bin, **nl) + + +def fix_script(path): + """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 + + +dist_info_re = re.compile(r"""^(?P<namever>(?P<name>.+?)(-(?P<ver>.+?))?) + \.dist-info$""", re.VERBOSE) + + +def root_is_purelib(name, wheeldir): + """ + 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): + 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: (List[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(): + scripts = sorted(scripts) + if len(scripts) == 1: + start_text = "script {} is".format(scripts[0]) + else: + start_text = "scripts {} are".format( + ", ".join(scripts[:-1]) + " and " + 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 move_wheel_files(name, req, wheeldir, user=False, home=None, root=None, + pycompile=True, scheme=None, isolated=False, prefix=None, + warn_script_location=True): + """Install a wheel""" + + 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 = [] + 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 = {} + changed = set() + generated = [] + + # 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 normpath(src, p): + return os.path.relpath(src, p).replace(os.path.sep, '/') + + 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, + } + + maker._get_script_text = _get_script_text + 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) + writer = csv.writer(record_out) + outrows = [] + for row in reader: + row[0] = installed.pop(row[0], row[0]) + if row[0] in changed: + row[1], row[2] = rehash(row[0]) + outrows.append(tuple(row)) + for f in generated: + digest, length = rehash(f) + outrows.append((normpath(f, lib_dir), digest, length)) + for f in installed: + outrows.append((installed[f], '', '')) + for row in sorted(outrows): + writer.writerow(row) + shutil.move(temp_record, record) + + +def wheel_version(source_dir): + """ + Return the Wheel-Version of an extracted wheel, if possible. + + Otherwise, return False 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 False + + +def check_compatibility(version, name): + """ + 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)), + ) + + +class Wheel(object): + """A wheel file""" + + # 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): + """ + :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 support_index_min(self, tags=None): + """ + 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): + """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)) + + +class WheelBuilder(object): + """Build wheels from a RequirementSet.""" + + def __init__(self, finder, preparer, wheel_cache, + build_options=None, global_options=None, no_clean=False): + 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 self.__build_one(req, temp_dir.path, python_tag=python_tag): + try: + wheel_name = os.listdir(temp_dir.path)[0] + wheel_path = os.path.join(output_dir, wheel_name) + shutil.move( + os.path.join(temp_dir.path, wheel_name), wheel_path + ) + logger.info('Stored in directory: %s', output_dir) + return wheel_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. + return [ + sys.executable, '-u', '-c', + SETUPTOOLS_SHIM % req.setup_py + ] + list(self.global_options) + + def __build_one(self, req, tempd, python_tag=None): + base_args = self._base_setup_args(req) + + spin_message = 'Running setup.py bdist_wheel for %s' % (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: + call_subprocess(wheel_args, cwd=req.setup_py_dir, + show_stdout=False, spinner=spinner) + return True + except Exception: + spinner.finish("error") + logger.error('Failed building wheel for %s', req.name) + return False + + 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, show_stdout=False) + return True + except Exception: + logger.error('Failed cleaning build dir for %s', req.name) + return False + + def build(self, requirements, session, autobuilding=False): + """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. + """ + from pip._internal import index + from pip._internal.models.link import Link + + building_is_possible = self._wheel_dir or ( + autobuilding and self.wheel_cache.cache_dir + ) + assert building_is_possible + + buildset = [] + format_control = self.finder.format_control + for req in requirements: + if req.constraint: + continue + if req.is_wheel: + if not autobuilding: + logger.info( + 'Skipping %s, due to already being wheel.', req.name, + ) + elif autobuilding and req.editable: + pass + elif autobuilding and not req.source_dir: + pass + elif autobuilding and req.link and not req.link.is_artifact: + # VCS checkout. Build wheel just for this run. + buildset.append((req, True)) + else: + ephem_cache = False + if autobuilding: + link = req.link + base, ext = link.splitext() + if index.egg_info_matches(base, None, link) is None: + # E.g. local directory. Build wheel just for this run. + ephem_cache = True + 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, + ) + continue + buildset.append((req, ephem_cache)) + + if not buildset: + return True + + # 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 True if all builds were successful + return len(build_failure) == 0 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/__init__.py new file mode 100644 index 0000000..a0aae81 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/__init__.py @@ -0,0 +1,110 @@ +""" +pip._vendor is for vendoring dependencies of pip to prevent needing pip to +depend on something external. + +Files inside of pip._vendor should be considered immutable and should only be +updated to versions from upstream. +""" +from __future__ import absolute_import + +import glob +import os.path +import sys + +# Downstream redistributors which have debundled our dependencies should also +# patch this value to be true. This will trigger the additional patching +# to cause things like "six" to be available as pip. +DEBUNDLED = False + +# By default, look in this directory for a bunch of .whl files which we will +# add to the beginning of sys.path before attempting to import anything. This +# is done to support downstream re-distributors like Debian and Fedora who +# wish to create their own Wheels for our dependencies to aid in debundling. +WHEEL_DIR = os.path.abspath(os.path.dirname(__file__)) + + +# Define a small helper function to alias our vendored modules to the real ones +# if the vendored ones do not exist. This idea of this was taken from +# https://github.com/kennethreitz/requests/pull/2567. +def vendored(modulename): + vendored_name = "{0}.{1}".format(__name__, modulename) + + try: + __import__(vendored_name, globals(), locals(), level=0) + except ImportError: + 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 + else: + sys.modules[vendored_name] = sys.modules[modulename] + base, head = vendored_name.rsplit(".", 1) + setattr(sys.modules[base], head, sys.modules[modulename]) + + +# If we're operating in a debundled setup, then we want to go ahead and trigger +# the aliasing of our vendored libraries as well as looking for wheels to add +# to our sys.path. This will cause all of this code to be a no-op typically +# however downstream redistributors can enable it in a consistent way across +# all platforms. +if DEBUNDLED: + # Actually look inside of WHEEL_DIR to find .whl files and add them to the + # front of our sys.path. + sys.path[:] = glob.glob(os.path.join(WHEEL_DIR, "*.whl")) + sys.path + + # Actually alias all of our vendored dependencies. + vendored("cachecontrol") + vendored("colorama") + vendored("distlib") + vendored("distro") + vendored("html5lib") + vendored("lockfile") + vendored("six") + vendored("six.moves") + vendored("six.moves.urllib") + vendored("six.moves.urllib.parse") + vendored("packaging") + vendored("packaging.version") + vendored("packaging.specifiers") + vendored("pkg_resources") + vendored("progress") + vendored("pytoml") + vendored("retrying") + vendored("requests") + vendored("requests.packages") + vendored("requests.packages.urllib3") + vendored("requests.packages.urllib3._collections") + vendored("requests.packages.urllib3.connection") + vendored("requests.packages.urllib3.connectionpool") + vendored("requests.packages.urllib3.contrib") + vendored("requests.packages.urllib3.contrib.ntlmpool") + vendored("requests.packages.urllib3.contrib.pyopenssl") + vendored("requests.packages.urllib3.exceptions") + vendored("requests.packages.urllib3.fields") + vendored("requests.packages.urllib3.filepost") + vendored("requests.packages.urllib3.packages") + vendored("requests.packages.urllib3.packages.ordered_dict") + vendored("requests.packages.urllib3.packages.six") + vendored("requests.packages.urllib3.packages.ssl_match_hostname") + vendored("requests.packages.urllib3.packages.ssl_match_hostname." + "_implementation") + vendored("requests.packages.urllib3.poolmanager") + vendored("requests.packages.urllib3.request") + vendored("requests.packages.urllib3.response") + vendored("requests.packages.urllib3.util") + vendored("requests.packages.urllib3.util.connection") + vendored("requests.packages.urllib3.util.request") + vendored("requests.packages.urllib3.util.response") + vendored("requests.packages.urllib3.util.retry") + vendored("requests.packages.urllib3.util.ssl_") + vendored("requests.packages.urllib3.util.timeout") + vendored("requests.packages.urllib3.util.url") + vendored("urllib3") diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..26b7f2e10037f317a1987806a44c026695bac8b3 GIT binary patch literal 2870 zcmbW3&u`pB6vsWb*WTS^+q9%VLTPb-H!bz14Jj(B5GqMUrK$&hsAW~jcs;YbPR1TH zGfuN^atho);=mat5*Pj@ixWsl{TDd##-0R3$)>7Tp3ivZ>*tyG-puU%PN!|a_5GRt zv!9L|#vkfo?{c8>G2G%$WEj}!85m)cqQvZ(NYyQB^{k3^uTjzIIoR&Gq_NuEX;o#L zOzomw)SJc)?0jqVI>h}E@!yHHV^#e}$TW6$&0R#C)#fQfmDs}8cji5VbZ~PUA;p$v zTXRZtTC<~hMDwWTjOH=T<C<@2&T5{}JgIp~^R(ui=G&TQG~dxYt9efIT}@B(yygYX zi<*}-FKb@WysCLkb6)eh<_*pFG;eD9nqAEW&0CtcH5WDC*IZJ>*5}6jo#MB47H592 zPEyRc7YlCysGs6==wXsU4@sk#2#*as5POn&87H8TUP=g7vbwolt38%_f+a+bR2SKh zgr_0(+wBK21uJnXVobEL{V$6V%PIEy#EV!Z-~@YdlH@Y%Q{sgw_OyhhbPT$7p5ah} z2!^vxxQO93Z@^jN<(ZJ2go)pNsd9TBl}E$AU^JH`h?9(Q`S?KuIbK~hlv8kj0=M`D z3XFCPi8hU0a|?}6OLG%RYuk|awt-D-{a_>GiIEnzAscIL{xdSvuhJR+qnp*buWQ{` zM*87XLprPOrZHC&-7_}PP7~X>v1>jvx6Ca|wkm}=XKY$~+HDIN@V5CBRwl&Fd0e<J z7PkBsx3;*N3CyuUAtba!{>!SNT{;lSB$Q<{2+}YiK~S~>J%6aXL(2Lg6{SO2q&W4k za?J|ojF*-ei_%RP&LLu@!$n48S-OJAP)a^;m+iVw87@0@x)5A_r?mT_Af-JbA^z3i zvoN~9;%>&{b%<7XJ>=a1qZk6#O-9}5Ru<eX?yfF8UmV~<+*w@bw>M;wEWkBPyI*u6 zv2H@b$dJ;TOCR({Yk7aD8mn7pZ5O7M#xe-}Y+N??26I*g^duApnl?>z8XZAZ*>cPo zG=sS6DjL`Q=ObE9M`1J~ka&_aS~ep_84r`Nba5;sjr*meDx8(gkxb~4YH5Po)&`K! z;H!9}XhGp8Y@LW=X20s^oPxGE`QH{l3px0xm4(q-ID}PF9NVw@I+=^vf0{%_qIeL4 z)5=b^HVilsEawq~rkQazghvQcHkK@b(Q_jC7;LKAH#ref6vy^z@L}~u80Fk6O?tG8 z#gzlQ`~X}-NhH-`D=r<Z16QWCthn|%s*EvOoS&$a96WjbP>G*P3W*HnZXB-7#tgPM zA?T#Jkd26B^^CoPO+s`i7R7~03Q962<Rs00c)ADM+0*!p!!m+ZhvP_23fle)Dp8kS z!!S4`fSn^61tS=*TI0pa8@=YM{f3eRj*3uuu(&+I48$x6Q%FueDHF7TNlt|2kU@Tu z;@rVs%VkW9`N{qMzp{A3noy?vy<uHF#N__iCM+Ip5LR(<@ep$=Qj<bonUZlrSUxfD zDjn=rrCV=Vi}OcIHwZ9`>SJS&%bddz!cEvUOIw{CrOO0tCvsGpOz>&d-dbL{|K;Q5 zM=Q&vUG=zd?$#9?!+!ucE8s9vn<iLoJ^6HH<x#Nw@Uv<wF6~tor`2)sui}I<+q_pF lHXph0BvL4B*wUK_ehu51b(&`#>ylMHtF|}))iz&w|8KT6gNy(G literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/appdirs.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/appdirs.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bb2e1c70c3b6547c61e8ff8ee16b070e9c523685 GIT binary patch literal 20617 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/distro.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/distro.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c83b64d4983cb28b83c361fabffd5fe02d338b00 GIT binary patch literal 36150 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 Sd-wfXO8;vXvc<<s>HiB*goM@r literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/ipaddress.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/ipaddress.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a5c647c49428c75fb56a3b26f4d09f6a16cb89c4 GIT binary patch literal 66460 zcmeIb4Rl<`btc$<XfzrP5CkdyiKd?@Q3Plb#2-NtmMB6LDbbc8S)y$jw$pClJ&;WR z-Qep6f7(sk5f#VDBpFX8@!2yon^4{)lW{VcWKQBq?3|4@&g5s4P4;Adl5}!%va`;3 zv}bls&dy|J<ITqVeYbwzPj`c$E&1ncKz4QYd-dv7-MV$_-dp$HdU9YOpTOVuJ-GP6 z|9CQ)_}}@%{N<22i%)Gel}NaWg@l`QQ>)3f)IuuBe0nv#ke2VvLdMN3^my6j<U;SQ zf|vDj%c+Il_a!PjGYPM6CGWo@nc%<oCn~9z61Q?*exV<CAJKPjs=Hocq2C+u3M=Va zy*~JIQkBLVk}E0y``jKk`$}SATP5fAs@$!-m%Tc)upKq+M@_?c&*xQ5ZqDsP+3mW9 zyxWgoJG`A<)-Bvg`G4pRxP!Rz0P5PNa_+pl-5q`<xv=Z$guBDt`AWjw>FvIgUfAP4 zu&~$NwXhG@ce{IVeUJAbuJ6b1z3x8z-Y37`;y&o^N1X@U=iCGCTT#<nUB`V0R~+}C z`!K#AavyOI;rpQbsCyXS54$7oD83(YkGOBc_aXPFdko)?x?}Efd>?kl-3fe;xRdS_ zzDM!KY4-%)c*5I*797Fv8TTZ9pY)F4_uKIMlzSS#Ps{J4_&w{s9lzf$JvoNokGYTI z_v79%?`?N73uCx)#(e@;p76#{!*TpR>(1f#97-HTiE&(c(mjVO=cJAaZ^9cZPU7lQ z?s;52FIT7V`-1y4en0I^NzK!^@{D^CS1x+fsQCnbzr%eee!mkXSn~|7JnOy-SKcLc zob*n5)5S?Q{bFMD`Nj{=Im@M5{iw5AzI>&A!(-}PeE$0MaU?U&TB%ZA-&ifx%hd{s zEczw?mQ$`c&)=$FsaD4F`Ab*Iwctk0*{FH0Q?EKpzE`Sy$JeVX-f>%rCp9~zip$K5 zQ*vG3tJS<(o|h_K{YKSasiD@_IW<O;t)Y!dd8z7p#np1%^GmC>`9^kPY<z5Taw*9o z_~SP}=kTdzkTetMSaSZK@cH!Ot-7DaMM=JL_4vA9zRq@CFZsuptE;Z(*N(4UIleTp zUOe46eRcfC)Uw;C%}ibQCvVmpYvcI4TseN}_<DK$Sh-TGmsVGgojAF8Wo2XWGB3)f zc-^bGRsVQ-U3X|~{Z?yVajCktUaA+-1g}=CS0z)tj!wLlO~q74!~HDMNMCqe`Z9<N zrex|B^ysO?og{jdp0`C=jL*J^Pi;Sv%P97towt+q#NDKuXeM7xxyikWzn8j}!GkGz z-9u0Mgw$xNm95qNjiq`kyHQy$Ev?{6YHYlfTnu34_n_og@{g^SYjt+y%)@+<dTV2> zd*8+$Tdgjkk7tlEk4mkhNuQ$=dxP}<ps6~MT;dz}$FlqgC>}$mDb%S}s3%?qP;RGg zK1#5B=)moCJ=sjxQ+HCe5#DR2-1M15Grc=;J9TZ>`x4C*`k$ExDwHov_g^Qu9Zk0e z=YV-W5&OLFSN&GLT$2&5EP1W%ri0~5y;#4s?$t&!3%wXg4qvMe!(A>_fVr(S@OL4# zcs<swVDwqRvR_>bM*lEgUn?L<Bn!z*GM^kw4ki5^_`O6-<sZK}xYGF_K&FntttZjN z!Fo!%2tr-kCwTw^MEjX$!cDIvYLocRtn~Pg)zfz~ZqKX9my^hWpf?k*0uTUVFG|0n zOS||60pF3p6BT(PZ=dMLy}}cCuRCxy@hXT#J$r|s=j<As_t}BhWk88itET0dL}LV9 z_AYzAQ{AXL)n&&oRW5tZa@BVZUp&n3wNl;Tq*ge2@%15A#c_ZA<478#-JgH=yQ3BG ztq;BX-LId;_bL(gs~=PUwk1Y;{cX75vvQwP$?rwd>hWZ(GsODVj`?c+;@bMEx8|YA zuAsqadLfGjV4PdoRj+cne#PI;r}-+C@I9>|gCKfd*T!+RwhKuD<5@`NFs6C=-ihyB zDgP~eD!*8+7geoxA`^V<yo@zbvzfS?cvaCb%$WnY0z#H7$6GLLS`gGZhq8vQILO;~ zuzq$x-tj0hHyx6RS2=+|GMd1PCqQd}8TlsY%(eXcz=n`)%o~EyNBUc@R)PIJOVy1^ zeKh5hjQPV%qQLPTTzd+i8gW>`<8^k^;y3YzZCb)dAcsktT*;`(-Avq0-`v+sH<K#~ z|41|aUXXYEN}a^@Ys0aYC1q?!Gp!!bX20G_V`{cCwYs;inip+ZYrp_akn$aTy|86^ zCT5d9XD6Fw|Jcs6_|%wqi3QAn1+*3n83+xS1u$f8556(S++KWVHA~d%DrP9>7Tf_` z?{fzM(QU0A#Y<HzBhUF*d&-r|?<(IcR|J5T^zn@Z*ExJ@#0VjI79$?S6%g!9&0Ae= z^;GLufYPyUW{XAdTCw<kR>0a4$;Q48uN_mx?2B0oKk{O(DMUrAB+1*UW~!cC$@#nL zK#yjspc|9&--c4H!RS01P5Yy`>>uI19`D*lX|+QGD_*hqL6ndlCNN2IAcozV$-=go zTY^u}gbwdstrv@neD~(SVKMvG2yh<3!*Sr$b~RHq2Uk-B8Nr0{PR;`w$5Glp%7oyG zfG4wxRisl3(P0mTEp!TiP&eqThM~i`We0HvKjQ7wgQ(kiJB`JYLwi&W?fPUhZHBk4 z<(UvvN$~t*O!zjH2x$cJT?XJ*aJ5FlYsPl-5#}SEVZAj(v@i~X*Ox|iXdeJpXZtw2 zO#8Y)_c994kLFvsVzE+M!;e<JSX`^R8w7i+P%IL`^_{+Av9?;R*NR0MYJUvXtKpwu zZj#9qlb}tKBjEfIBro72P{VA<=F&O!>63e}J1n&u$r3*HkEG%(J~b|NQ33@7Ot-er zDK7iHrPU2j*0{!@IY)ju^3(A>F!+jX2Q@KV`Plqu#-B!={s|^TrB-jT=vJ4|yH4#t zjS?TjM`l$n>GSvfwRGOAua#;mTW%>N2A1#8QhydN@7T(><Hns(EBV_ll!Rp;KId5A zDw10{vR-7qGho2#spS-8UneSK*VAn!o(z|$XTZGmKpI}CgNJP<cA-A7Wmz|6@*<06 zN<V|wUn;F&1S*h^9PsE^AdZ6@5sAt7>KlHA_o|Cmy(QtTI9y9r-{()VsSuqU{LT57 zYqOH$FD;bJI&->82fUbOvW_~e0xvU?i{qRxb4gK>TGh9;I5Ck8qTwxP(Q|4W>+7p! z&wab865=3e8tO$$CyyMNnsjcIS64&z;Gv~zrB=oQsE`g9C~-QAw;b17E^VyVbw6H^ zE{D1@N5EX4))>uxP>!@e1uo{<QW=6}0EGalW}Wh~bo+?z^bu#h1X;j!%C*Yjy5lJT zlpHh(Z@~9VsP+081?a}jL%!oyy_!?0VwBd`y^>Gq7d?_OR5gTU-7)8>vg_QcZpb?+ zN|(@YNQlk|#yb$Loyk%B03%a!$wZeNEeY$vf1)vdzi*x&?QQjkpeOUwC;H1}14Ut* zTRqaIRz83ln9yF`_t3l&ik~m97xk_0=ENbzP7I~6q7NstDf69Arjn^tE|p38bGU!W zQhP4KcG6Yw<5r%Nt_gW3GVKnACl$(I+O?Ir5H4dU-gn$%;{C7R#EGZ19%J{Kct$(& z&760j&(zSEd1rs#=e$#d?Q58HW6pD!B5Lw#csN%|HRnpTR(Bu=)ts7VXvcj_O<mPD zVQT6(+o`D`8lRfxvPiUNFhl$&kU#`Gi!V{;l$Sz!F45gUpRr!l_5T!#*;$#_vr>JB zX61R5>bw$O!ksr}B@EU-m+W!6bQ!b%Z`Zsnta%rqqVShXOP-m1p$p%z`KMMrh<o9c z^^$N9*PjR)w6x0gw1(BZw&a)9VmPO`PzQSC5~e;BZ%fcC2mFP`@uN<y%EkHCVc&BW zOSLkTiL1Bp2$YbE<%&{7V?kVm;46!`uGg;6)FkV=9NiAh5i};ZykwF)5@64d_Ou4L zXxh$&<|c2<1UF<(CS^{>SI7e9qOJ4yI2(5&NjzZIM)Qre@flq2JPXN---7-VDmf_q z?m#6+p7d&}o))fjOf7x&jGHEZsdr>Dm}Nbs4`YFQ0Xh+{22B@P6TMtJAfD40jinWE zKZ*?jN1~~QGXj<AF{SGq1=fLIy9a++F+3nd3jH!WV1^$G@tO*o+L%1z6M;n?qG_jY zqBM8w?R;Sq9`K@CM$C(_i&60|qqWy%f<e{g06U?$G~Ap;FkytJ!FZa+X`uKVQqhYx z9yQ3`xk~CniBmu>(F=-d(%*~6TLaHs2jZ<(Z-`{3$b4s%8oEABl;XyM0?z-1=aoP^ zn1ViQXVRyB>y1XG#$R^BqluYsBqGhU55RpQ656|UO!6PN&%vE(A6)+;>)3=!3|*gz z4rvzCRt;%h59vF@LrTUujn6rJYSgwVSrz*~)Y(B=1$)fxfsFrXJ?(;BR+1-GyrY@M z+%w+lI;I#9yaovl0wm@gramQVC2(@~I2x4$L4XWc#q(Ux{Yvt<PnCCL|8o`4=xW7t z4j(`4pwhK+oeBlel0!a}v;9Wx3eFFjTE4B7h8|pKsbOO>oa=GIxw|N(i`8{*)Rb1q z(XfHLEM!ttw-=KByU`Gf>=a9=2wTFZMxBa+3}BKZOfuLTf|7ZxnS=uT(c773=4z^$ zz6!PO?!-#kf2@gL%PCPjXQ2DcK=HhfJ4xoM;$0fQccF~MrUa(*+J=X1BMNG@s?VMS zIveQblIT@1*B{nk+>C%?O+{tgHDg7ghqTPcjZw<;?=O3+Zb-77bLx1P2-WpcxdNSm z4CQj!M@?J~u^Mwv*U&30%orGswrRMbU=IUQP*}Dy)b_VB74Ig-saRgeBG|{#k-geh z3ZvH}wYM^?8W+~%<F=!?4A>Z{uqf*G0~|9dsS^1dMl3H|BpFDF{sOK=#6i3Hr4+5Q zHBlhmVjMY!iEUg3Q+pC;p-Z8dIGS$!`8n=OC@kJsTLfkUiVe?)G)~C?d<VPi%LX@e z6RtxIM91-{$m19cyPl0%>d(4nA%op4uWhV3sw7_|@8G^S8=-6MNRWa@?$tI{D|1qs zW5x(TO!yoq>;a_Luy^37d{$N5%CIHz;oxR8+EtX^v-3s1yvU-H92ME9>8A$X{|;1V z$AbD%&ZQ-MYX2Sy=Mgs|{hewguqC;_j(J0lqnWshO`EG}%%D@a2JKcext!882YJw; zXAF13ve>9h`7hObZl@}H<aZB#U#VyDJBM;vU1u*;)QPJ(%+e&%o}1s%%rtvelK!97 z`|5e*(|1z!{$@`zvnS#9?gl=%y?YXOQn$01uejUH?nx}C?j&#bHha~Kc6*!IGYM=b zVcxTBGj+AVP0{BQ*IvQ)QV!VESNgFu_SQGn)=GZ40cDQmiPUc9Wv~efpEj9gdc@A( zEOC!9&_ta%b4F(QNX^tAohKvY4K%$NIXrQCk_HcB<A+C&S}YtJgT7$1zm8Q*Ores| z(XH3wI1fYJ3ueDQ>%49Lxfk9w_w2=m^Tqc)bMeyo7oVRycivX@0lrYP-Jv!gpFDwP zD`rRO4uYE#lc$bPO@w>ZrQFo`@u|tfqaRY#FRI%V@XyLLQ6mxRxDk{zC=Jn*5ez0Y zDVVB2lSvEv&7YU9x6SZ5kPOhyQXMRwp1yXJ#pq>Zx;Zmyu}Nui4Ph5{HNcZgQ0NL9 z7+m6zYsNK(c)BL11hI*_$S}DNI=l7fWqH7MhXa1JhNU;CBj5x&wo9O>HPmFP(U!|% z3j|JsDq&VEZ4YV;wMxIuz)p8ki;lWF(aO%~+0~ec0b*@~x}dO5+p8UwW@xdd);M&i zChH=<G`P%Ig?ijLq7lNZn~teE(jR%f@cyrpiZ+HfDl3)h4bkB1-Uzv#A01Gt)k5*f zQq9vy+3K^S-0C&O$s+nsGC7B&HCV)QQ-nOVT)s)BiP{+d158M(h5ontigV9CTYPT* z{EMSG|9!mt5)<wKw|XIblG3;Oq^)EzTRHYkay=Efmj-m=tHy4Nx={j!-3_&EpV*g| zja%BW(B>hR$|tk9l7*T#iyZT?e!xPX#r?sg&n*?pq|qP)R8}o6{~a=hNh^aryZLN0 z>A%!W(n^7Qly_73&NNeZ)6EQ++n#0*n1Y;thL!=%%wvgbgIEH%^bGR%<5+I)g1o<) zOyUlRdh&Mm=5)OW&u3r75&^dF5!9MR9ew^Mn%S$pVE=ky1@nn(tH$EscJ|sTpTu&I zDs6z*ezsa&=e~wt-MFlD50)o7igkZ=wX_ZkqRZUeSlYmz444rBbrJSZV$((}w`+kV zoaOZi=kd;jZ~XY=%;A7qm)9q|m7JN57oF->lvFoX?R3|&rzcfe+gh*@(oN4G1T5Pq zLHl6MM?QeQ9Cgr4CR0qNKQ!tbJ7b@AoUY5nw59I^lNc4&u2eTxU2e!=Hd6~kwz|x% zuGL%EY^r0o#$3K$E`?sw-o}v+d}vhDi|F!U2aua%A<o+@Wrx8xsy!yXwjHi@QCe*E zaYzR1RH*<@z>(g#0$ZpX9{&5D?Sa~i((Roe&4J5?OwdZNSJzuPY_|d09)4a%lI4~Y zEMBro>}X}LbCb8$+P>&lOYRcqxb7nCq27Zj*2+O&u;xLr(dw;jETW>CU&eKRO>TNO z@g}rQQ4dZ|MH6J3Xa8oSe~UDM+<Ia!*~l!ZfzSqQ`-2t?V%ujpnM)V22?Q&f>nInY z19t!C6zaL0xShl&g-`nCmzuOv`jgukP=}1Lo|l@mcLUS8HvzE?q8n!YGZ1je?#Wfl zbfzo~7)Cj;h*z^<^nMx7e=_#`Cp$fVYY6m$!eKAz$omr4{u2~#Icxy`qEfZ#yM4U- ze%yU2ac#Jn_P^AGv396!U($8URogb$=V|%`o2GgmEG(E*u&FS$`Bc(Bdh^kGfmhJ? zeIHES?g2ZSygN`QmCN2q@r|EKlCsseHDUfpwwFRs>9+yCb9#<~YYk93CPP|6gxMy4 zohHp@Je|c>Q$hH<<AXwZzz)V~Lij<+Z-Gd3pT$xBE7XwKM2^8@D~y~0QNYJ(q7bhu zrggL{{49Alz119y&06^;D4S(`M3-+k!q>lwzb*1BqeIH#@xz!~Fjg_lL<v9rDzD{3 zJj4>O3U@F#SBIU!;znKZnyqc13Ebo}gu`FwvuSLsiJ0EXLMZ@}BTKo=V?$YbNNHdZ zTVAhGbpXP``a{e}jGPP`c$znPwa=1>P|ckf&VYzy(qtcYA~yu~fhtYrQuquecc#>@ z!E_;=1!;ka<#*yaOH@!(pc|uQjg?%7X`)2~OSuB+(SHP2GIFH{lPFo5#A2@y0#j(k zy9FDEa=o+&6$>@DB()^pi-3~{DNw^pv6OZ}G0Tl+UBkN)aaNrbO6`ID!`sOwa|=YK z+44rk1!G#F^*Kx=%FD}GF2G%=of5~pNnJacbhS2d5{1N|K;nY*=RDS(*}xjCDxg6F z*WEQ`i-P`pm6`{M^AZe0APnPEt3ouWm)D?6x>CL20ojgXG2>mDHqbQWM!9xHS`Vej zl@he-);eAw$PPlgNPzN*Qsvf-(ycL05dNfok%~!|dqHLJ@3<(HEkS~Si-BBq0GB0k zOu)7P#R?47<7nOG4Z=$Fnxc#w>9qD^5M~2Q4?B^4qwmynS_vsJ>VQSpufmf6%00eQ z5A|p^%-`!8VM&g4+U&#DiYV@X7}y8{VqVwiBA00(NS6h)EY64zv#ihwF-B+cKjT!% z<B`NL4eR*vKY?GI*!GVz?kqkva@SGQu!W4*<3a`V3RaGVEb`*?gM2UYy>3pf=aBDn z^OEm#``rTUSo7MYr{62UrDsU)!IemydRW&W^5WKm{5IqtaCb?WA>_ra2iLbNhn|ID z_d!g!{g7}jK0l{s3T30lb|9LwCZ?@w4{uB$5}DkXqk)AiZ5%m)N0W_NJ#&c=tJTV7 zQT18ssx)eWaLf&`k~WJP1N8S7F`HKDaRT<!r@-n$|5;QP3oyqX#arW}lhcp5U*(vv zU5RvKceG1mrcC!fDCtM~@b*w2Y&(J_;vSvw--Q-*X=|Ro9HPf{Gia%4?cP{xgHqkw z8^FAD5gq4{(F)Rt?mmeEX6jS(FFNa05fWs!b6f)WA9cL3%VSYR0`+5-Sd0PsdX|hF zoR~ZbUD){8#KF-qU4K#69pOg~(?<x!P`q3@#>dA>{(9+fq)_+QOpcFF%({!GW@oqf zBED>E|4xl9j=5}_l%GWJW^~hR+kk~b#aQpUjOMmju|7MbeT@ULA&nKa<4Sxboj8Y2 zZ66XBE<`kFTu$x+AFeh`wBJW+zH#6XpaY_hc~hxcl&r0LOXX!)0n#v?hKT-ys0lke zoG(yQ*Dl8<jlYN+JK0=r(<HEo)7TYju%5G47tKae4v~glK&FX(F1QFBpf?bjjNLBi zi35!@e{t{YNjDw3PhE0yIjywP;^dG~P7aM@hg@gmF=rfhcS>y)>|>Egh~*)QXk>&j z0g9h_oF<Nk+^szWd)m`zw||p~%VY_OF<3s!3qQbwJynUwUGVg{;w`Pn)}Vg-UP4Y8 zS5w*=2K}ceQRAT)4BMYvV&(i})l^ssIBBO05K{htuBAzd>IifukhdUHLB0TR0nFu0 z2yDQGj~?=!5on|wfa0OYk!}qPZ<L)C0QVf)9l#XZ=|Z2+;%ch^iVIzV=hES()vp1^ zA02`GfCiP?OE)CvAmJ>lEall$CY?(*9_b9@=z|t(Q9&@hxcLP@st;Ul=G2n)6PIY% zOTws>d@!J;;}MM@st(LU%XKhQc5gOd@}g1@**>czgg(P=UMU;jNY$EU;Uh8LhL>PK zY#$Dl1Q8<Aa^Go*UU2qhafIE$B@>NTj&G{iQ9_cyNc1-j#v#~V+`^BF0g?zoQ~HY# zO*x0L!$YKmzuz7z2=V;{6ojxZgZH1C#5IWf*e6OuiHK5eYG2}ZmOJ85`laurZ}+;H z+c}t!=9;~Fhl>8NJ*5Y+l<Czs0x^e9d@@F{;Rpe!eLPgh+6MzNgKV>79~Ni|Cc}gI zjUHy@As3ADJqG9=qZ^Y&Ik+JOzS&GDSJvUICyO+;6feVoTXs(I^(eRXYj$xGRklBX zanP17;B%!X@N}gb5c~ZO8P(YHpnRgMUgCpvg;Qn_eg5A^zLiyAYHh3grSdA?FT0ao z&Ho|ZEv&)@nituSRt_?d&WZH~CwH&wVdHzX)^TF*&{D5LM)juCL`GUJBnG(uOy-&D zYdY*vk=>4<3KhatSOiU@7UH!aC{2KXf?PReN#Yi!_M~g<1!(lj0+aI6D$Kw&8en44 z3>)-Jz|pTSlk4o*rQKi;*1?@(j!8YnDB=ZnORcA%Q;)`HS?7l$9pQejbmR&$b<7*( z%mmk_1QhSEDoN4;4NC$QRfq;~01B}lD8$Zcg_td6A__E98IV8h)^ZkRSCTcil7c&* zEhkP=sZ!sjvktqj5b6B#l4jI{xzRr3EKwr#W+|~6rw7ndDw3-eFcw%Af=b@-38v>n z_j#uHix?IJa}2<M|0<kqC=9)Ky0xwN)cJE4vH4nj>f+NEFTF@tWzhpuDf1&J45dq@ zE>p^I6oN<t5n#w{ij(Snk=dcqTuD3cBQ_1A_QbXVrUng==&8Jie8y-Tx55)7QcGv_ zqNI9jkP?J)FVv`%1S%c1s3d-LHk3tPkOrDhF?-CQ<g==zLN(z~dgd|jZnc;Ec;`Cx z-VW_jWCfO8ep0jJG$<Fcra)m<V%0OfJO>EWj)fpI7X9>W4(j|?M?~9Fi;?rAS@^9g z+Np@3f{S9kh=Kk;Vj>%t!Xs!>M#_$&{-=4DlrqHD?uwwEDhM*aPPC&Ol7JcGAW^O- z1(X|1X46DM<{F1KLqA)S6>&J9_;R6ah6ke+5rv#(?WUQ+9%@kxhT-0}nFNj7Fz#A{ z^WP7$srb;pHZDO2rRGO>#N6nVbJ|Hf*UC|o1bTGK{~rAGzn97PF<E5tcbWVkl2*U8 zY|TT|4cGr+UKW50=zokq|1pz)!XyB*<jCjybj$fGfI*x9z{lcWp$Gr^3q85MT)r?+ z*o$9#3kRj-5=z@Y_U|k{HI8dshom$}@O@SxW8eWz&Cx=y(i$z~w9cqc>x}YBW3<q( zv_%VAQ?xLkv_uPo?rtz)dqhLl`1qW2*{cZIhrU25O*OM6`-8YBKp{z|-J8+@8ch$Z z&t#*Gnm`4%8Wfb}r7Kil3Svv75~y6cXA9MCpp)>ReJ7tJkc=P^5lN7Uf)f@rVc+Mm zd~-{_i;NDJNwUJly8xs?mYrb}0C-_b0ZS<fak~&t;>RtTM}bmaO{}D<%!9+Y3U7U( zgmg&MG_wvC_N9dI8%a8EvQ<jhY%nJZMkSJqZ*~Y%1WD+e{6DajO5h>EC&_Q@h_#lk z<&nmc<q)uZ7#Z^CCRByC*Mp87u{p?_<DT6BOJGATd6gXcQ@96SK5`G+UEmke{s+l7 zNFKmeev<QzgNKy1onKHn)5auhz(EDX7B@{Um^cxfA<9Rao$yOcL{68X-2`gKQS!5d zn(&jLPZY$-MJisB-)#_#IF@s`Ed(9>h(eId9v#{4V9<9bxct$nyhrWzkeI1f|0Hvt zL86r|okp1MyO4v6#b083iNo}LhSz-@AEi*|A$IUk_Xh6y`WuK{>0<GJyhj72P-JRa z2x=A_6Xq%{ph@Flg9xZWVUayl8-YPG7;OR9H2Sg`sfWim{TPbHFS0rKkkCI6n+>W& z=eBTo04#*s02YIFkxg2RURvIYB~>k>VY%WSqy!HXi@zRfPJHO3K<Czwm#d2xGg<>5 z5&l!ylxbz4(7Vz~U-51V5^dHBK!t^i#or1wBMuc+BGL}RPpAaR3tE7WS$mT*)jAVU z{}mMfozSb^5*>ipHcIDLQdOp23FTj~<SR6g8QxK~FAM7Lh2Fh8`fke!%#UvCy2krI zjhCx%0HhWEKV|YWO#T^@pJVd#OxV%xOZbOz_tR|39%OP^F5!p|(3{(q>%qUY`X?)A zWcf~`^jUmrE*7uo@_oPIOWbX;{WIil$9KOw?C!vK!QJUTfbRi!m%AI^gWfiGkGofI z`D}CdxerQyJFf3{-y->8<QcgQa}%-RwyEfC$nQj6BDf*{0P+&W4f$QjOC&esck5Vg zdvq+fy{?MowhvLz7{x8Q@SuB9;<zOj_TxE;<A&$n;vG;i+>n2(ir$8JaT2v{;USch zcx||M5P6BzhWx|GOO!U`A3<K?vmt*7d5Ow~{G-TAL^k9PyT>t~-r>ItcsD*8VP7Bw zD9_ojtKJ*R#^^T~%Yg{>2HFHuuZ)>cv|K{6l`SrnpkOxZ29YJk88Gw({0hLt{4o)b zwOK+4S(hCXCWa*<^Y2X{$}(yGbdzRupvRm8LU~A!$%TjpHncAE9I73M_B!Q%1O-G+ z?m~+=S^u}t%N6wvU=XFg>^?u7khRB<a4mr5lD;|2(JDQ4^B}a4*vZ(99gI6EnEMPt zn+bb_X8P46?bWY60wYA_;qaqRlON`;^F?c841O0I;$l8Pp;cTvthIVbHz~LV_0wt@ z@g*>vsGwMc@^Q&qhvKg;K@7O(@2e;iR7PuzvQi+n>aAIs*#;r6Yzt^R*B-Tm2rPZ{ zT4E|;kJqT+g=+_UN?m=cSHGpzXX|byZ^jX@NBZ_9LY|y)qE{J)G=_y98~95hi-7k5 zeHw$ogsL0#75AW=E;@G3{}*VJ?vekC$os#<<nv63d@3Q6EmKKg{};A1;K69+qB#rG z88b$9BAfmQCa<C{i%nEDDr^!=f*I=>?uG%Q(%AnRr}>%kr2tmRbqP;|xT5fZ;O36t z9(K|eA|>TIOGb9dcIr`#M0e{9npXZIgs_{+lQ9ILR<aTTQVc%*h#utCfu3u{;(sNG z$j^~YHA>pSlv36<_C&@$^q7Sh9uGKcGV_4bn<krJ1bQK-^g?E-+x(j(v*Z-_AIK~( zqjMpdg;P&v7Ij#LupeQWD6}OsQ5x5j!UZsH7hXaFOn{ng0*sYcFW@b=jsgGxwaBZ? zYk9SLlngmpPj1BUTg$N2=4lmj9VS?T44YLln2?gsu>G$w*|Ib{%&ryiNJ7+?v>>zc zY|t5zXDQnAkKdeW=kO6$iySi=jTt20X!IQT7R@*N{~X0a<nA^6?6P!_#oNdB5Gy+@ zpPFNqyC}eKlveF{78wiDv_C|}C0YY8!g}q1{NlcL25rQwz1l+$M{3=xPclf#Rd`aZ z;E5DEr)P6&o`SE)x7$#+a4ey2T;es7?oDuqk*|#ArC5B6g>(vXFWdk!nLSjBQG*>o zIw&8RqwK4|djuKP&z0;t;(HQtBnMP#CUg#?v63bH8%HjAtE+TJWhgxEtuU+rEadcS zu&0LoHL)TZGi&?3I+d$pL8T%85q3z{8gz#LV&vJBv&#)TK?*M&;bPB@7*|{@@CkS; zoWjBmcYWMZLj@Jco#c~{nL&nyEpd~NVcwu~h`cCG&HBH9s{9HQlF(p~S~;VnHiOh* zxsggH!ec|?ImqrDh>VS0e9bBy>6e`lr#km*I@~Yxu4k@GpT3CaVJFwAPp`3eF7In) zOQ-Je`B`>HR8&B<9K1`~#>N1~_JNZcPpPrl8WVVnE$Ju}wgzt?KvZB$`y|^V(>B$3 zFap$Qxv!x$HG{UVb#F~U-cnK9uopsYiB7(7sjsIcU+mtJ0eOc3{yRcV+1CyhQ>=4a z_TVjsy)n!U+&jUjaBegnowp9YtjGE@8@C(f*)XQqlC+vLoKC{ucNx_I>@gbT_iFRD z^=ZTf3{$a4G28kGx!#9YZEi(%C}Ks0U@6rlT9dkltyY?CjQ;nt)ej;uv*HJM0gVgs zltLI@WP>?R6FpesqIhV!rM5S0n>j1^IfsvE14*&e!j|;A<G;v9AF%LA!Eh@KAGJq@ zZFx)L*(y@TCBA1T-pKbT?f}li5Pia`UvdU@DvT#_2YGFrL2oY5l-jd(Sgn#)S~W74 z1Go{p8Adn0n{}yFCL@Nx_`4JpO5E*xH31(Ay8JJa0S1fqCuDo&n>9l<=YLlFeWilZ z*P7x*20_gK&87+mkPhFi=Mh&KK>?t+)&^zQni3{}k#zr)s;_cT-jwqHM%7RmZhwkx zAMGuD9)NnmTf@piYcs=Vi`@yl1xoPQfdEEtvXIDi0YaH)9E`0X#@!1(PuDVRhk-ay zMh_W+AD=uG@+>pO>0j2V_=Nc1Mrx;H$%wpSOg9vUvrDTRt|wO~M@OB<BM<N$-5fjU z-P^@UcrxxH%zF42^6UuuHGP~O&Rwd4-`nYkml;5ZT4rVg0hSeaf?LQSv>g<DAP%|k z1Mqu^!TM_hUU+2M>JMDQ*$4USTz>L6tYRZh*PEB0MtOK4Zn^$bC{Lg7w!wGcv)+EO zV<S%?>i+EP@u{iEaJBEU3u`CFRUvHX?B~<AKNOlnUF|=tlEoNYUl;Ff&CeRIAHA&z z_LFRAq>Hen+JFZklqn{15`i6$O2lhXA0gpq=`x~B;JL?z{VnDAf!#_&8zS#=j4>{} zC4kxBiq*r`<VaHiyOYY-n!lK-O5{n}g0FgYFTz-J-xR$KL2-*4ZjF7|wCmEQ#xC6B zW?qDWKZHXcL_t?;OsROa*f6J&93de@hpsQPPHke=!Sl6A`I0U$H`=e{oDx<aB{si| zT&qv<2*v8MvRe2_-WECYhnTA~;jV$v>QH)arD_xSOvcvV*0vZ4EOK$2!2^j$WD^h) zL;;^6aI17_Du8dL#V))eRhrJE;2Wv_A>Y^^Sx{q@+hvt32bWe^zCVnNT~^b6+p>y# z6uDE-@*Jf$(f-c(k8xKOzbQH52m$|DeP8{~_#fnbS)zJMKaLlk<FOXNNUSN`G*=t* zVKtypHC7oE2t&C<hgGmPi#!m3ibY}+;%e030IRocX?cj{%_20FxDu<(h7SuVBn|pQ z_o!Wk*SwN!|HGLU<!mkF4OL(kw3o_FG{%ITMNwE1Qb4Tp1QTT<fcmrp(v4E3ZtH=; zj%u<OM4A+rB={f0fD=LL&{3}<ZsG7)3Ve|dKZ6#`jlpupdCXz{N#+j+3(n>=%}!O@ zl8&SbO(t|O7TWj$BuC4{Q5wQhHMnRT)mmP}5VAFs5*(Yb!t`T`dPE&F9LKv1AI9#H zKG4gKca7_3<ZZHs&uC&gayYc4f&60?fjgS>SnLV5l52K{r|`UfD)P*@?b73qt3E|; zZ{8&~0grX;6TI{3Fvk`Je_h%(VcUl4Vvq3Qdp;I<CK#nN_tzsc49=OZUBc2Gd6(*1 zm-Yo9cfwBo0XVkOv(W20EsUY1ks}#LbP^)#5E)*LwqPRS-vH4R8Bv{bkqIpnvJ$+8 z`$q2SpgnC3X{ult?Am8Z_$j+49#Vu~*?_><N-RP$$%fjz*62GHe?B6bp{_t-A+(+P zFwpU3TB;`-zpZOICUh1qfz}@~1P4tpC{QRu4G4ntA@WtFPKO;DO@aLBHRiC{^Fevn z4opSq7RFRq2J3Xm#{$pTgJ{6P!1<DXohl~5NPtkJM&y0Rc*lBW5?x>sA<D=A>>X7v z{vE)iMIej5B^Og-wYyqAjPmo=<%PZkRuKKS_+g+5aSayE+-;*SmAgR*3-S(#b`Vst zB91efmF%Ek&jdo_S^S0qj|cIv1bhvkzH@tI2PI|WRzV!a8ANoa!MI@`=A(EDVMYSc z)hGhtX2UX21-d-7sK@AR`HKg$Aauz{y_en$aQ#nXhj0&KStahmbAj>bpghbqbFx$T zIUTMfSNd0g(IrxQ72-j&s8`{JN4Hq<>*Y*}=}Usu;G%LzK>!K5+5%yOBh_pfW2s@m zW4OPI&s!`R5q>aGi;-|5_B#=Q^piYkhY}!3wgz2v1_InIhPWfr+F(l5Ejd>i+o!q# zx55bP*}jTeB}9?Lq22$Yv}R+)MQwV+w99c+2ojo&mn%Hbj4|RD;iW7bj=o8L6$N05 z4f<sJqUx!5H#9)V^5W<ygj!^P>hN2FGRj&VF>?{*guVecqV7QYwI&Erz-6e~w1NQY zDTclqsjV?$im$5}<tVB#H6cFqooHh;Kh>#gx;zv+0@G-RY>zrJD08841ZM(tP*Jej zS;tN*Kv*^*PDjU<?O?E0=`WGYMsAJw%yFK3!M2kyi&aGG6byzK7D|v|jx6d8Zbd3_ z1Q6==0JjFeg|?Yt8q3VE#H!FwDK^&XdO&xnw$V=cZ1H?!ZwM_6CeX{-^JO7xjDRC0 zMzYbH_D`0)#sS?f?Qq7)VxwH0amE|t9qu3EISH5$;(8+U8x0k`6s4^`(Hx2!f)cDg z13Ie&E78Dykv|VJp~QvaVg)c5ZEGtZK)W>%<k3w35k7l}$)iYGIo{>+)#}x-j!9=C z%6*Az#!-|{>?=U-g6R|_FC}s1k;gB{XE>ff<g`IZXT#hmj9PbST54Al%3gNE=acxs zwE!ze3L&VVM#U<U!YcBlUPUtg2o##wJ;bV!MC3!pNW_|<_T`}tr5Bs5?oIlxVbu`d z)@78z(QTC7tin^<gL1u~T_|_=n#nVXv)JwDY9Ok_-^Ti==s#p-3=buraBNV6mKw!E z48t2oOCf~B(40$-eq)HVx?Y&HIu|h4v_|u&qv9;aNgX(ETMuU~;)$E!Xo@z0$RPd{ zxf9)eSv}gTnP4^I=K+lN#qz~-L%`@p&169{J&9PRbC%wVh(TVH1<W?uITr5#+>j9q zW6T><VkYBf#9&DqA04hbGDq)8_3(E4Vg;=&6Fwnzv35k4ovw5*T1*qVSXE}p(tr)o zJt0=}jeQ-6pM*!aZ|c{0yO{wN7VI1jhNVbP0xBU(Iw2P9#CjEt6K@yM7K!pGAat*R z7#O|L|AM^#yG(wM3FuIG=VlE*_kxhr9Apv?VB0)GnMk8Zl?EX`?27L|8|01%4R$|= zyPPCQSCdtcqpPW_Bn-*M7cL=~rxBzy*Uz3)+u~mb+d(F54JYs*bTJCTN8+B-0ipP- zaM7$BbuRfE;FOe*7OJ}xs!(5!V(E*X=e%&?oHIFfa>|(;J1LFOKAoZ0Lr9=}&?=N` zMcYKRP2O2r_<fX~BXmis6MgWBjP8ks>xrn<awvWdpV|kJ+`^ffdcP{9Si7SI0+41v z7p4}IRG%TAUV#M*+#+ey@?Pb4COcVR<qZkf&XL?}OV4jrZ#wm!idgx9e`i2e&DtBn zE)j1`L?UQGIj6B2_ryh7S%Yam1266*PG3MShLboW5pc2E(RUGkM5aV41u<3y+a^B7 zwnZZkMSw}*3ovPj1GxnsIQ@y&RbxU?*bwFb7Y$)Wwq&{qiY^*m#AxyVHR{<!EcbsC z_utQEV-ZBNWBZe~XZL6%7GvGWsVy{8uQT`2%vQgdz|cW|DAe4jU0bNoeNFUV=rYj- ziV{xX;`vJ#?7R<6v(Ag&J!d(WSen~FDg+d;)JLehr7u(^+4DIh6mM8{Y^HcWP|!TG z*$k%;Un1;?WHQ5}&<j;_U(owh7wDNb359~E`pPjm?fC15o~;;&B(!jP^7KTgS_7B? z^oZ{*%6m5h%^v_DYZf#)5WlD$L!_en0?xk<fWs*Y-kayWF}uoE(Tstsh(2oDOy}@0 ze~l;>22upOa2RvxSb6>W^f3uUQ(8UddzYbT@}Z@`R+zp!({{H5fZ<vVkzEc6-we8c z2<YCl(B;yiTtnuyIebt{XV7wm;j*HR+HCy67D2kPh%*J=K!}plc~ha9^a-ghCO3V6 z(&g3aVrlgif>OwJUyNMaBAwybh0XcN0G=?W2rzV`Vj~rW#(wMQ2qedU$}ypu><bVk z2<I1;x!F~&L=ZH@-JC!y_dwBR=Jg=@8LDzK)N28te>Z}9QEQ)QP4@-1pX&lPs3Z{k zcoD}0nZAa)uyyD~hN8Vr#$wwF{H8)LH}K<vVcNJE@ctOU`-c(WwJjK?8n74-qx8J} z9_i@f^*NLYd2)S$KYy9YuP_mhFFMvL7q9<`xnE`SStfx-<k$G~Uo!c1CcnW%>^()k z_-+3D9VT~}$mTRf2cH~ntAL}g!LMuQaB@e&0{Q=jIj)dC*8-V{{vR<%4Dtzy5bKxb zPpUJ-7WiLbF4kzuo$Ez_6y;o2z+tola5u~0_du?<&{xP6GV-s7x!gN*<GFnPM1G`z zzg#Al!B@ZfNS#Zl&i;|{Jd025XOKkQ(r}`78Xn~tFS{e*_UwT-xtF6-eW4HE@Gqxt zIsMA%Q|@lN+=n}PFT2oRrZbvyP8;wBm3tcQZ9`sM)Q}%SUfk4>-;TU-R2x=qY70A* ziy9o!9<UB-yO4L>hs0TJw|fvg`@{Z^qS1|8w0hIJ?Wk85!&+h~yg>s6<9p7HD&ujk z^x-PdD|eukn$ftS3*pc-3;Q!lIu}i#SwhvY?L;Hw_#HvhR(^b9a%%d-%*j)yU;ip@ zz5X{${+h}E&Ezkb{27zikjOE@B34HT1WE8Ye8lpZhL^_DJ-LaWtp7<o@hg^sGeQ<Y z^WN#P&4MXf_8Sid?(P-*P^Qo;y}oO0-1jx%DODMhkRh;3z@CSRK0`4}ANmQ|0>*#5 zrv$7zG-r2vY20VRnk~zIO*082YZ2-8in(KH8>HrUNvu<61i}XuLPxcdgz>_lJeTuz zYy>E+mC}JmL(~Y$GZlLjN(5{Q1iR<QWG_RXX*R<3Bcikkw#ZP>#H+D35JaQ4N1PD` zPIL}VP9MClr*;4A<0r5l>CbqmCPW<{G+~95e_+Vr{Kqgz60t}{ouIM1#H4`EL*mY) zOa5gQZRR!J64D|G=?mmb?mwBzf0cMcR8I8K${xqXA{O9anjwCnfmLqB#H8>u5!4|i z5tQWyVl!F80eSj38k`;Aa(gTVn^H*YvUN9xy9i&TtV(YU*TuCSfe7G80c9+NQb_Ju zpcJOY?Q}BHz%e&az|z7~A7q0qwq6%U(tI@i5@LQ=Qt(yj1x?5a64^Lz3PWI#0UngY z2m2P-h1j5K!XF1#Fi{K&o$N$yA}r)k3AV6wUG~IgbtCj_$A$P3a1HHHg(cdlZAJLe z4q?LP6x$Tuet~XBSENo#HW7@3py~3VS{u9dHKSC+KAE?+Ucc2!j>(A`jos&UkUpG3 z$b)8-Dfb~?1sBUfkpc2}$jAApD%8w8##jaY+kqScOP1E*hXP}wnpc$PWzRw5q5l&s zlU4P$(l8Z^p`!oeEMO6E5KA3RwXg|5rP~nxX+vrvAUe)49V7zUZ9jsB#BV{v??onp zhET!jC|V;yq)LT=*y#mr0%B(Trx1@$N3qoRfTl!A*$c>`gpc37dvQJyb{KrOFIpP= z1$mVD1kkm=sg04Fv=b<l3ZQQ1RMab{1O{uVjIBWh?KobB#;$!IK;YO37tNkmmHs#P zRu~c^rLOzJ#uyrs9;!+dCUTzfV2Dr;g<OANe2nz%L!q8E_MRsW>c=SoLFQHm)-@h} zjyu~1MsE2sj!g+}D`b3~L)~~}4sm5@UpD0|T`Bn`Ag|wEl*H-vUL>;AwvywGsW}{D zdU>M?yU-DIptO2izipH;;ix~A7<!Rr`G3kc9(axugt0b9&N%23P7w;X9lAbINZ;k# zUS;welg}VAbh%F;#vzojaxMKEXdRyz{|BD>OHPaf$RuQ9hzSeMZ$N01R6fJt>-4@s za1*sl#wik-hjwm|qaXleZtO?KP2Pn+Gh+{Mb$2ts@$^&RGi2u~+xUIbP%8eWCXXQ^ zA~BSffeKUIsvIk5#s~cu`@qoPwxg|@x9uhXAc~sF3O&9V3Du>;5u-U+_imH_AJA>f zW)UD+d}{oRBWWf+G(v}P%k01*{BFh-B`MF5s9^K&j&cRZmLhe=A}K%gq}mn1xW5av zsO9+#bAoSFFhFvl$xA0K?^pUBV{j!zjz4n<tFqLXNjJtU=cX2}aAcCP$3*8;J2Pe< z4URlz++UiPNN`8ImwZ5{s9*li;>JF{5!i)Tp!sx&#J0cFq7h58OPqVPD@fp(0aW7Z zerx}CCzi3&1Eq3xdX|bCJy||PmD`E+JdO2yR%zmC#`+R;^Efn)o2TFkuo3$_uY!Q~ z>}8tWOOqd$tGXDy<{Ez#mWo4bI<b@{rm}%J0>6Bid4o~IGH(OPnaJ~8$UCAYx*T8H z*KxWsjI%(aP38AO(7Dda*)B~D)z*%ggfo{`aR|Ol+#IHH(<i|$uVj5JNq;YO4bT#L zfk4&6MX>?^cUD_b3ou>Q1nEAHS|WNMGJk$Qk{N?=*+gT+A{+#G+us1wXf8%Z>C6Se zb}`wz1e6y>;C0qW0;eb+>7Chj<I?Yc2uZ64R7oF*Xqv;8fNco9@d%qFTxgzl0Q<pv zX0iP9xC!iZ1QagxNMu42Z0GQ)J&HuhP0IBXXbHspuJm5)?t}7SD!&SvCvI##jqg<C zMwojYo;wmQUBanTmCDslc&v7cC8kJaTIh2NNa?1O%!y@8oxUw@u+TtFj8C0#rp8Xh z5nx`R+8Bt$N{3=a$cg~^zo1tbS7oYU0*T9F5<h9u|2ru91ffZgB(iV<Rtgrb59Uc7 zvfV-u3`%!Lv?bg$1D8f#Embmv1Cevlp5a?bU9sh3<%UR!t-X+PMCTVuP`+nFui0j> zR~uf>BX-?1+jxS>43k+VCz-HbghY7$z0=R0pMUz&Grr3UePB}>JYJ*j-({)4WWqlC zf6nBSOn!>Vmzn%H6E4m|NB#fC93igMNq@!MB9j16l0%adqO|x)j7sewenGF3%3!w{ zYj}EJDg&<roXxbS@L=IkVJP=NuCI`h@@$CxV^wGIsWp+b>uh+I#6ph;4?H(3+LB)6 zgOen(!ATOhE@w$7&5eo;h<rb;n-e7p$ZvOtrJe!g&506&?gLl>clne#8^>QTZUUku zSu0h_>o`*$@lk9{KNucr83f(}K;cVx4#yD}Z+N8@*o=e%*%4p)IfqY;V})rf!6N(v zP$S61Mc`WO3Kn6S1NVF0&A|QsS*3P>q=~?`P&rW9kb=1;ru`kL8+7TMT*rAE2+5Jf zA*X%xQ`EkViMx3Qdog84v!$QIjIjFS_H{#3fnec~T@KACwW$qYqiO5nI)s(Tb<65F z<<(m-ld%G!xHCXTQ%4jXg#mBuLDC=%&cNvoM|c_|d2?@Sa&lsF^2F&=C$Ipjcbc?{ zgJRaIP=-ltN9-8giWLaI1I%CN!%*=~dKk9b(ube6N2j860D?}|IlA3p83SfA_6!Q> z{OLUsk#<W;Iu6m&`G6bp8L*+T^F3s+BnG{li!Gcz+>y57rq7KF72lI6=?mlbgUpdP z^tl8p`g@u=PJ6SmokhNtUcAmw*l2@r^PHIhUG%Avejnz%it4dl^eRd5JQ9vQlcB{M zIrk8>ItOqfIh6@PL5AxZqZeTUGWG)2q{VWjggrKkav^V>U}uoi?j39(JKCABwz4XE z{zuqoz7q$i42K)1Zb#_1ZJIJGph6F3)+#W>&xScRJyP7bx%cL`(@_F&x^P&bs`d6a zR_Z7|+ub#GC%W++!X2>Bc}CNKCLfD94h=Go8P|f&a1-tR$1TwM8oR?l1G8ePi9n82 zju<28QBMf>4F36*9JoBVh*21mK~6V57r-$X&u`J4-ViixZ;2!9=@fgr3kmqy!Q0?w z8CFD0=2JRas$yt0>sm(12*3g1g#VwB{E&flCeav;!CLPccMy|sqIwz!T=`^jFt)m& z8QNO-RVFWQ{6oC)@0d3xuru2EjkdewqwKWUi65}EQPZNgic`<7rqpgT<4;OcwiVZ9 zL)o-slf7EmIQlf(LhMOE572lZ)*7{w+qp3v=IB2Sa4WJeXi!#kq}I&qjj=?t)kRk& zV}CX^adJXl+rjoMr9d_uSe_ZEnIVf2VQ$U+qtM{(iGj<uWeX6a)SqnpSQm(e_Kic6 zpd%scNXIa>@t-nAs3xNvxyPpLiIXBz1j{Rkz2Mf)@OE}l6Ur{2;(p{m4uNW43{;_J zZ2?$n3Hbglz-r%i{+eJGLD^89#(ZaLYHB=Gv4P5VyGeZy?BVY0Ker&swGno+Nxfxw z{9qS&M5fytY0(taMFpzZG)<kxfn4pVGAtHNqFlNMRJf1*%OR-jjUh^48MSFZR`N$m zV&X=r+9D^dRlDPyxS=g_zO$n|MG@rPYz!9`6;nO;h{ROyFJ!Uv-CxLyn6iZ1_K!s3 zEIzfXNCFuOt8Zc<t)r<!B}xejd*CXXx|W={4}P@|yWq0>Es{|`^4JBJd;xhQJq;jl zq^Ci52dKwR{{miU)oE-7nyz>|YL}I;Q%@~3qSz!AkjhFEB25og4*D1*itswSn!|S= z7fpF0kJ6turKzkGA*f$=HF);c6&zv<)?zPM3O-lC)2as4ihU0^^ZgW&Sa0vu0p##O z4hGA`L3sxbw-s?pwI^lY(EfBE>+e?2XpcJMOLodHfC@c@E}QdGh4mJ8oFgjCvpRfT z81rA`H4dTJe7AaJD>zWC`>*lV7n!^p3077rN&K@+o@YWx$5`{<BGQcDdP1AiA}oM} z2Ph<maBw<<0w_c9A?9&ME&LZD;Q7m?C9gB9Ze`a!sF*Qz?h3n3xf0gja1Aj*uzOUn z(~MFf1fBdLJlBOlGwkV~v(>WrQ*@BUKincHGDE^NdrfuiIecnQBB@IZY})<ufMb78 z6PvOKh_;{SzuYRIi7MIvereO`$F#y0(uNKP$e49KGNV*5<)f%p#gS|vXCQwB`PP75 zZ;IZvjnZm-4Bmz!ud_FU$RyAkZfY>v{a{9kMB#o#g55{DMa@{WThgUHb#`gL?NVYL z(a}uzs?+SS?&33>b@4cASCQQX1KYY-FkQr1O>IgzKKz&LA<>#W<RNkFA-2`i?R}JJ zj$|JB$8YvihK{&|)(a-hC7@eJPZ+yyP7Eg)hF<W8!J?ERRvP;e{Op2BKaX2Uh`371 z>www!3LG95LTQ>MbC!+h^1}DyR@S~S)fnQE5e#s7J+gw@Nkp0+pG2`KR0GQWEQ$pn z=+cB=L!msIAhQQ5x5oZxBPcrtj<au2gI>d1yEN!u;?}lEgM{M>pdt;@mLhLZbH3QU zIlqouJ0s0`umgO|=0Jy)UDk8bs8E!3BAOg#q9Uq)mOqILK1U;DX-8C#6Nn4A_8Xi& zJCVtya{FP;1{1ejI-7#M8_rEpiz#l}KUQ-VpBm{;u&ytpy$sgzoUH6TXSdgCM`6o` zbr}wVc%bBA)`=!xooHeeD$4vTP;A!BwkQE)?0}uO8D<?iPR(E0L%nOW&IhzRT}@;g zKB=vg105cMSs*CXhpg&i41-VKQ^UBcs2_7m=M{P^6fI)R3{b4BIu~_{Iyj>P9BYd< z8GB~p^d!zlog8Ceu;3|;kg>AHdP%+`AvwmZZ`Z6dc~bG6m#q6H5H4VWnt*>m%fa+O z-%HydVTT?gvmy+PGAIKJ^J?;gWL(H}<V73I^8H|jev=FjOghN?d{D7Ix6>86aOQ5O z71N`cAypUjzClfOvOi$8ZfBYq$-}nsY@$hL(O<)&`Lp#w=#LXhYh2lh+CrsN`=l+3 zY3jlK#NDAL;^l!Y)9pv=7-pacCL~|M9WZ7=>rfg21;XuVralE$sorDS6|{+O<MAwV zKh&yjWs8IW&gHtAbK&T^!g_Dw*LJ{fm~Dp6dl&<9Q7ORWU~TT9-cY+<8X4Qe;e7q7 zapwb%nrQ?Z5rd%W+v<-c)XOF}!!~r$Glm^UR|0H4u4V%8G+u_bq0ofe_#M=Wi#*O? zJ+v|4oE>vsEU%T}M+u#Mx3)~gYqnjOI3AfN?QIB^#H@?GKs6B23rz42X(5;^_({M( zvd+*1j4DD`d_)++roys1$PvF|RpGp=>xe$$l(c7;Y@XjJqxbXz#?}qCBXpz^u0kj$ zCE!wo$a^8-Q4JBa^we9Z9e5szh)7^gX&H>NTt80Wu|P>1X37Dz$~Z4(q3;+&4seX( zzp{3eVe#1|X_u?)J~R!Ymm}^%U5mYC9Cgoz#yVQ5R*p41A25?x7Rp>xMnUj^TPDX( zjmpLqj~BL^{i^C%Wsw)j(VUTLfn5O(>Y9(LX0<7#&EA*_{ZDuSwzOGTT~+N>BO*s- z#d;rWlz|0%LU-k5o(L^Z<2eB`eXwECUxGg=-+~b&KxqcuHj-FdzV<z-`FMcK(4LgJ z7uu7G^<zt0QkFRyDeFzC;7TxeHrtl!Ts}~TywMv|VPXa#aA0B^T$~wZ5Y-l!SaXm~ zh=B<BAsmMmI--;^Rx7P|mSpCLKd^Gp$7{$>7)FI?0PC&TTj1-szKTP{L&z~NBD>gr zG<L!q6yiY;gN;!x!~z~C?7fWTT*>ai_L@lcA|OyAQ9I~M%)Q1$gccq=8j|M4f{uc` z+G+n~=DvUgF{=Z){wZGl_e?~6)J@DE#eycXZ{koPO`#svBq<8|g=9X>*nf-xIE<@< z*olXo33lanLO95$vdLk57}pxV@XWB@sneL;S^Q6<J?HQd3luD^FejrK^h&n655H38 zS0Pb-1i#a=6Od~BQlJ&Yi0IMf;D8#0UHQI6{LVs%(HKBbwXvCL@QDcfHjdp<8DnzO z%B|)Pk?SJ={1I+_l%s<W?9O?rsZwYd2xI3=?PlO?zf0iJr%^0!(;;~EFL)zRC$i#@ zFu^fVJ~eFCKE9Dkkz79yZ_2+%SbyT9{Uhq0#i#Z|NQ@NW!QKGY5gB~LUJVu&&=cZ2 zi*HEc&<etG?M@OYI7g%?gA`97?UghqDR@a-$xGTVX+hEfNe3m}Ch5?f<mJJI97^N2 z=o`1=8wWmtPul^v08#=N6sx_;#^A)vX)Hf_AZ8l<h%d`Q!LXca^iNL84g8pnjaZ{k z3Q4j2M35htI5{~sF{8$HvQbd70IQokjhBgJFg`YMavYI?&0R<fhzX+ZPRyKA&(7e5 zr%#Pd=$|JV+xYXu#267rm7g4+LfMH4q<p@Aa@w?Gx-lGDQn|ch@oMzy+w-G^I8F%S z<w#9>ne;HpFiA5>G7*f)$~6pc2u~nt;y7*G_&%ZtHG>d3)jtr5ZvXP>TuPpbpb&Ko zXYr~12oi%rZW7AnRJ&u9o5e8q5lsRYDsO-;R-#fKL>|g!$!|j*E?1HtLLRPHlHZQ} zgQ9FElHyD-cPCWWJM@8`bfntt?vavoq}uE5ll*RX2*|YG9C17oI8)6;x%^95qVDNT zWu6glfv?S(st9NW&Qx;1d23hTQ8oAExu?!wC@n65o3ToCf|?&8yYE28Ixd~Hw!F%5 zNu5Y6)~XEI12?6=bxIPxTzf$oCdBwO1<dSN#3?DOjN*b7{>M0Mk2CpUB-+kht<5B% zYM~c0EQw4s8q$4{6HU~=+UtnN3J3m1GhO_R_(UEb8S#IY;)r+hH*(XE^~L81)?P3H zq}7-5AVR1=$ny;P1p6<93WTk3*8h3>AvIHXGp{D@;P95)J+NDzgpN1?yXEhN9}-B0 z_#yQ+VO<vTL&~|i+u4t1jUN(fz)lgQ`ur1c0yzsk0gr39SA#3qVsQ%yG}x=#*b807 zzjFtgxVi^D;u}Kk%-zo2JX_DX1y!15<e;o0xBC#<s&8+i_LU}DveE~c-f;(M)fPP6 z?7N-2_7%j$Hzoe(X6|-gzc+^y9Z=iten4W|-o&SpwMsMZ7EUE@=bL%dR&j?^P1aIQ zAck_EZo+;L<@%fbDEDc1d#oIfV#+uBcQZ6&p;>SXD~V5~{AqVsmlFt>zH&4wS9P0k zN3<G$;qC~^22j^6P1W*U+Lo$45^s&F`8IavZujF;xK&3waPw%ruZh(d;T#=65`^}h ziQ5BBXn<f1C~$o>`5dl%Ds}BCzz_GEg`EkOxjBv}`}-4EonfnU&!=DJ)3WE#zmf+O z{$%SI<>o-7cQ*b?9gZ#{z>IYOi+Z$$IJ0)8jPe-^%oU9b8zO<ITcM{rn=OcmV(2l= zsouBnM6q4`>A>U0O!{Vwp=hWvT^-oIlAQJbPY{BJ12-T9KY||+{Bp$79Kp-9&7au& ziHW^3unyeW8mU7!{Ri-T`Ku5iM8s)4WE_f6(NYyL{o1^V<YnS>#2_n&XJ-$`U6YiY zH2$nta_Mz=7$qcBr*&|m5`(RzG%giL8ygdse66q9@*~Hs=N=S4(kQfB?CUfbL@5$_ z$I<gQ;UopcRy&|rl(E5s(%`R713b#i|2gJ_d0J)e5|b(tc#=MI{-sOjFBQ){_n!Gn z>X^YEi7A6y=q8*3aiA@nrj%FUpz=!j2|oW{`Fy^J81gI#|9~Ihg&bpu(9O^PkNSS; zrn=wC*H*-n2nX8vZ<Vt0T=7a7XSlNlSa!4qRE|a0J-4I(%a7yPf5X-16UZpfs(e}< z7Yz$+Y|;%w8aW8*Z@7o@A7g*zGMVHaY~iU$g}F>#<VD5?LnK3y5lv1>nR|NZwLs}o z-Bq4iwDwNnNz{kh7=fPOEN47$u<A({J3BdY0p&;5K1$XUGI6jmxSAUFJh54(?U}Vx zBQ@aDSP8}Z*50F2Bdn%DS9(g1g5$N0iJH2o@q%KlliO@)X0{U<_2e7mpQxKb#hkT{ z4!ymTswS)j0hyt0rCeDDR<}7QqH+@_ls<|vB?vthFW@iYviMf<OXP!{eG<j=IPgiF z-oz(S=+0;ljNmbOicej9`r@S*mA~K<7}P))g5Ax(j|;7Q09ctMak*s}qj&}`XX>22 zA?&7WCqd(c0kp!juyfI}&wZ%fvd^59E)3`4Aq(O4HqL{;-E;FDv@ww-@(hme$s+1; zFMMTF{_|jRGB~>u8z2&I^Gq{~Et4KO?ee8&4?Je!OM7h}>tJ2i_F)NxundI!43<{L zSVqKTvgka3(0>^y*>gFG`s5o-e5#rIt`uSfpf$Mv8Qzsx&Pai{+0vH;ao51S)@qE< zAVIB3QWdC7m<B4~&cS!7t(d}YoYR4QzSYu_@$Z*7u2@N62VBR&A#f43s8NHi9VaSD zXsv_e2aQ^r-cd@;d+?yrBtwe|!Y@wNdJ>_1fu4<6xroq6l?sc&vk1hS*F1!aL;IQ4 zQ?ItMbOpb09|6<U>p{G2gO;EmVigBx5026AZ$x)}6wQGyA6kBQ1I=ZHbl(yXxaNEU zyvkO@5>P1280AxFmUWxs*wUP{Ah)n&MY<8(g)nao)z_J|h}RT)Km~}$U?=>)VDd1M z79;2NdGL9blXzvmKtm)`rB}bdwQCU(`igE9YBNvPa*!pg5v`qV*Rgxj+TLDpTlf;o z^pts&YAdVW(4iuXU~Fc>(%1k&FN3w0I8VpWi^O&;2l7uJJc5M*CTs}5z;6bf#8x*J z5FWOgPwB9U@5M}x*EnydGuH;nSNyImAi=as!o+9TSZwGs4!JHoVh)<+Szfym-=l2M zVfO|P&WtNwL&_-_#zI<J25IQKi_^BmO*mgVicvA1!iXW>?kWsGmA=7#!gG4=C_XjZ z0K1<ba*)8LRGSOQz1EdW!10ih7LMd}jTV<v06`sff@zGo$vAvrI)up4;aNr%uML!q z({;wDCU06p56HD*ytRWP`6v?c13dup2$__&^BmdTiSNShF|>`47L`xvXj<6Xop?a4 zF-hfo9`OflagGE&D<Y8h<B9*Cn8_EzC-k`TsspyE$=$^X*}8@*&(KqRue_Y$To5qg zGrS<oqRX7DZrgFoC*R@!7hKazoZ{0C@G6lPO5?-KOWSDR^GUXC2${s73KY#5vX6Fo zD)1KPMSDvvIJw5ziSd2-!3j}M!dPGzL__G}vEiSr9FVJYC{u^zLZyqVIhJ4!(*VLh z-JQW`0pxnhz{w0#rk7syQ2&Y_JyZ{@9}`K87ha|j>D@l%V0JaHY?#aytY&?Up9Uwd zHfdBWU4}0U<4TAiwo_y!O?4FQI-s{iSdPUviOw1bPiRZ`7IeZ@aMKCF)&0l_uI^Mm z9>CLt!c&c*NrfOX$`Q0wBhKq;*ol(A5JJgQ7A4WZ)vD_i1y=C&cF8lV(GPikbi++F zpC`@xf}+|J>>S@JzP7T1@ic$FpUICi5sZDAIby7AS{Y9;@=OYMDb2Lw?k92eGwj4J zWD;;}CPgnmuT0Tl9|QrMIj%!B0fRT`m_=nyP|LEBGEfF^K@Hp#U7X?a3^ofUo?xW3 zt8-RdoqO-w)wvTta38MDQzuT(Ad+y{)meEt3*`O%oZtTe?QisrmDgv+O8$BY#Nc~y zrPZsLGEY$m?esigT$dT^qs`os9=M+;pb49>&ojVk9(;p*p8dbV8@^~TGw^ht8GGYB zoqr?r8tv&kGp0SAN0VFgb)E_NI{QNe`~QOu`1_b!V(!nG{1lTfGZCDpNTH}S$*=N( zCXBb@<vf6A{~0Jk?GZeny_|vgU~90$3V-L}Lb<T7Fb-qby}3Q&=gcSA6#GXqa2B81 zPa|pHLUA+S2tQ}|JU`&>lFgEB$eT@+A>_>_%68-*boWb{VfQT{<_AO<z9qkCtL_T? zqW!-{e=R>pT;_-5>6`5jodMzLXd7n9M0D4Pl2`j$r5B`NvHAwOP0!33+sWXZGx3|Y zf)LxxKQ6td@HF;S$4}18OizHlgFp4;sS`7&$EQx8nm&DEV&=rusmYlWGvk4Yq^e;n z_AK@l+M31w4xPici7`v(;`gnNg~^Z}lur6seJjL&%nM^F!NJ~a7i<6j1>XCA!-Vue zC1m4dyZ`q|8u#H>Vt7;UY6GXvHXB?{WqNT>$%sjq#`o)8{Z2eCoNgC;2k4j+|IHF} z<yvi9cAu`*-_{2RDBnccobLiEI)DAO1yx^zUYizFFbnDIwMjZjEV;Kw^|xnO_6P&W zj!v<&WGlDkQ2lw7i~w9F(tpO)AsEDn+y{s1BQaPT*TfKCZDLk|Swpmqgz?EWC5`)F zcbDpai+A>#cfzHb4)fvhH8t5D<1Gn0PYd{AeX5n8>9<~_c#Y(=MTx*%$d~}0E{($$ z2sx!1&}+^ZkUVgs+$tDKAI94PTe66j!hlq~4{A8jtu1E$JR)8xT_crvK@qz+)Ig-5 z-Ge%Q(en^;jbUF@pn04_%-Gsfr%s*@j1u32xV-3w2|#a7%n+@7)XYtr2dny_IoYU` zp=d?4Yv?!a%B<HRYI=hJ)%wNL6Q{%BsJo~b?{z|o1(EfXJu$(PP)>}^gjPS}L_Az1 zh_>J_+u~^fEUQin*l<&^F{jsmPFTov?lDhKkrU?7!_T=lIt^*~)k<GRrJwn=;VW zp(4UmX0uQc0b%pgu_<g`B=4Yo;}P=?9UP*=J8TC@$oM&jkC-7+cGt%byy<43_0A^) zF@R+l_wAG;BfGU@8#X&&K>WE+gkVIk)i8`U3t2&)OsO|kxLuiQeA}EUAo@_?3U!|b zWrX+#D?kgk&V~R(|GzL`?iq2R4LaX`M+eAu&gNkHV}R+MAuz?cg^p1e2xXaM4l)XZ zV33u96W1_LQpdg{m1dc<(CY%PdK#Zoi-zo#VHl?2LP6^Rv-pJ;fR3vRWT^Na8nycf zRu!+w9Q)1kk(t)%tvV2rGcO1F;0d3H289~qQ{gW5EAy-D@>f6h)sLkaB~VoEG}q{i zd#!#kvQV9TFM$hfjaXr4aEM9-4{3~{%0;M{)k;j`x$Xc4(0d4E1@LY9*D@z_w(-Z8 zB&0i*d=KZPy3{zsX~@Ir?H8X9@0)Z4xqX&^$GNvSI1N$Fmf*TjsgJS(Di#EA+7Li< z5D}oeRZp29VX#Zs#HsQW*^+66e!>|s#bg6f_Ie|=h&Evsw#lIgXRm)4aKXZqbmsj% z$ll-ZWEC8iI5PM^am>@cU?I<dT$V=YLR?Vz$8RFRIebL(cJE=4VffuR?$6Y#)4`Bv zD1@-C^LStw1c&+bF*~3Jh8P5HKx1%X;}U_SDQy7GNvOt!`|%}kiY4b>t$TeP{V%5+ zoEq}_^T^&G<ojynoAv54&NudB(;~8N*;4axd*Kv_dnTOZwa+p6EE7uqa!^R<ERbUu zu#N|UjPb@elPM+~(@-Le2hDANha&O;WOUq<LpttBzAz|}PZ<4Vps-EUkxM9M|5)K! zd}=Qv33RJ(X8aSxLNU=Jw;^w|szdH>px_?=X*9$tJ=r{V@*F<3KSctq3<$`#aa@!j zs!9+c#l~0JVq6q4uoi?OToi%-Mdp^6++q^*qk4_kzQ|<DQBhtd&X3@cP*fDUKS6nq zs3_R2vQbfVUZSGRSg*RyDmJ@TkPyZLI=lf<QT_p2&6hCBhBy<7-?kZ%9-W8KJkK z6`O<%@$=CcEt8qg{0RFX#_;GvEEY<nH{XO<DAKXx_vl!EhmP@?&$45(agT1bg+PgP z?He2d<#TKqMb3l@ff8xU{f0mh7;VDrb2Ir1_Jt}0O6Y~(s1PW>!Y0U6F(FVwji3qe zH#!8$uSFUpB2Yk0q(Ry*r8D<Q^=F)-Y#Jhl^sqBe?EgA${Z^zo41p4dkBP7mX%Df8 zWVtqsM6q2fsp=4Nh~<eDE~P?WL1QY6xzKHje_dL_TfZAZ7KW+`wF3&Jd&-908}cyU z8*T^%tS$}Vt=|tdMC_M>@u8YhpGh}Ax;@SZ$zt_2MuZ^*x}T0lcH!e}78ev40_};% zh5;v(QA`C2*uOM#XYr{`A_@2&9Umrd;=}03Z#?l#V!zS<((S`2_WK;;(sfX}t;LBk zMsXZI6XC)LHk$^AnHdRf0m4-h-nERXa*x<BMlgs!9FE^&&{qPu1P{#4E{98XjtvtO z5B5*dxX6=ww#KSo#^3Bclksp9AT2DHZ^G<y)<NID1p>#w`YRTiB^pY`1ZesHW#E`E zV@>H|9H9NV-wfk`U{+D6jB8Z5jV}h-3YCs))C{&L)J}b9reT(yiiceZZetpb&vr{T ze{?op>sF%8%#1nlkS-Bn*$D-Bp|SV<gmj5j6bkSH5QId11){mHBQD5{9{(^=>TYyl z3cra)7v>el=)(LC26}cgql=Ek1EUK9jFyN?b(*;7Jtv9FLiPJm82Q&W5NSw^`fqSM z?K+(Su%D*l{l~^-4uNm56;_D`?m#V<k2(<=EDMAnJJtE6O01sXoF&*KJ907(BZ0J4 z#APNl`khRnfeX;%)WV)N(0&@lO$U!YeJeWc0L3>T7K*hzidG(Ln;H)11~v{i35LSk zZ)!9Yx@)Nu2Sir*2!DQ=$r6*-m~@ij#bo*oiiYxK@=Q<SO$o<FLy@qjI^u~4^^s^O zsZFDyn7Q39_EW^*hkdJ^MPe*#c*qvmVg$&zox1rb-PCBt4lf_1;z~ON&!Ge&-y#T_ z1cx8NVUJ{?(~ZwOjl;5V!V~n2(0rEaAo*1&eG$s21Q!p9NF%`qEP979nUoX?dHi23 zuXs+ehz(h21>h&T<gLR!td7W2N)_yjeROOwd2wSAbMV*;aFE0c5k`KA-li6_?QE0n z3`XSq47#j>q4>-lX2Lin#%x$5fM4R(&ofEeL=*yFz|R@DW+~loFO@Dh!)H6$NKJku z&|fVggMcelG6;oj${<&hRVbMdca~cm$-lJ@P-|I7<+Y{MM-_>PZW$15!aJnO+M%O$ zKw1sDsCGH>UF0g>f06?%qIdx(*NbFj1~+0cAmMNFap7tfm8+l&LHHY@jZ!zu`vats zoM6^D6!`;E0qz|l1`f^~%0HJYh+wmXOZJaQbQYi5uOczB5~9&Cz(_0#4z41a0@82< zoXw-&pq9&diJr4b{2SDWm^Vm=CEX$EPDvk-beE*NCEX+GUP<?%_H7cA=RveK=k5po zzeUB&nF(U%^eua*#%E^{x2Ta@UIuG7i�mv$GRq<r-Pu!S?_pBML9z{EnZVY2+a9 z;Lgl+qfhVpOim$W&G`7l>?E#F<AGpZX0)1u{G8xJs4cg=B+s90WN-nmQ`I4ZVz_d$ z(L1eP(C9rSnG^C#-kWaZaF4mEMsCLDP)uK&v$=CNcV6Z2>;;uWeHT>C=*$J&Mt!Fn zfW;DX6XWykk(P)vzC_iLfI4X^`rgKb{$C-|6=2ykZoEMBK7vOjh)#zPI{6G0ox#6+ z+UIkaF%RP@#(X;E6U*TtUR>U&gKH`l{S@2s5R+cs!XZ-H79RJ6<`QpP8G3QH`sNY2 z@x1R>{Z=n*ik9FpA}$`SG&llv*bf!1a@bERFK5aw-l}^wb?{Gvx8B0qdZ7y})$xeK zOC;qu&sGi&_eXf;D@=|M7P3~K=Fhh?nPYOE$umse!9>hNWjSBq&+lMzmC1D`-^t_? zOun1Rhnc+0<VTr^`~3yxo@BycMPhvC4=^WO#nZeY14dYO8k|<{u{HRGu6k!MK#AHb zNMMnl#%V-2fh-HBLxkXlPkRcwTJAa0HIYG%Qdol!oux0g4Z+aUxokc+Gz#a%^iXCf zlY1opNbcd>&fE~rrDu9FH<6pk?H&49;=s`3Ncrz2d><LUKJ?<SKjdW7a`mmlA4{AV Mdf)Izh93I=07rC7I{*Lx literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/pyparsing.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/pyparsing.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..631ec7baad702bc1b88aa6885eedbfabb5f02d16 GIT binary patch literal 203064 zcmeFad3+qlbtgVI1_Ka0#Y>db1P=fb0G^^K3Zg}Vq(qy7WRkLENb+caYJdX_X29+S z34jA10%cK-<tR?pb{r=Go!GGxCr)hVuyZ-F<6Ms8BtAQr?RYoQ=Gb5EtTxAfzpwfn z03u~8yZgrv_)K?Kb#<MuUcGu(9bK`akig$tZyb7Tr;|?n83X=b84vg1XMd$7kx+@j zgh~!3RcbJ$(t~N0QQ1mnFoS!plAXv6HYF1hmmkc_y?L-%?uEgE+*<})<lZ{iD)$wG zE9Blb*e3UtgDd5}YH$_qO_kLXs|Qyn6Eh6uD{Cg!4z5im9!^w^Ou}3@Ua&rpOz>ac z-k{&UHc?GIl9<_oxaP|Gi4B7r<b46p8wWSa*WKRNe;0h+Tv-uGxk9J(a$?ync)w|I zvwVG2fBjt2I-$Rp+O<?}3{q?kQrzQ}kR9BtbJJJVs#d5rwNkB8tJNB{R;^PvsP$@t z+Nd_E&FV(AMct%sR<|faZB^}Ro7%2+sGX`qb*e6PtGZ2fs~**>cB$QJkJ_vDsr~A9 zbwJ&r4yrrVA$6DPQ+KPw>J{o9bwnLi{py%Hu1=_X)qU!udZl`mI;HMc1L^_wpnA1B zt<I>k>LK+S^{{$Gy;cpXN7ZBMarHV?R8Odq8dAebDN~K8QFTt0)tDMr6*Zx%s-`B@ zd1WbEIiuylE#^&T^VrSvNtIPoPo*{`25&KMQJGB%H8q|ZG)&{Ulr@PITL;_CZG+p* z9fLb@?=U;fF7sCNHnSVw_n5urE_1iJXS8K-Z*>T%_aXKE!Q0gZb@6gyuwyhaxEJG* ztsEFUFnv@_FWhl8aV+upfx&|_>&(3icbbRH1Lnc`)YYVn6-VN(@d8TzEj<#?r7pfp zkHK@P^Y3~%VfLvRHG4T>-mWgqCyyoOlk>^JyH#Dyp|r#ICe-WI8!ji*8_ZYCrw8vb zGh;{aJGvn;*stC=c+5Pe-h}7lX1{q1_Y>w0^(4N(SIsZnr!GsrnX!}1^=fkPmB{TW zwGFv#Ghc<=P9gkewFBWD<|%~lNBC*gfpCX}2N1rZx)AO%2k`y@gr8B}2zSf(4<h^) z^&JR*ht%%X2)|WzBHStA)8@v7Gv;abgnCxJ0_{1g-liVJ{UP<8>VDi`qn=aWh5N(m z?drR6e?)zc`Y*V@R=q<#jQikoNx;~<)c0Oa4nB(9->q&%?zc+rk0JbhYA?cj&Bsu? z#}R&yT8r>n^Kpb<hw%5Sn-IQ9!bOCCK;4M&jS_ysd}6R<K4Csq9KxF)R2%VTqr4eL zctN!x+-5$3oD{-W)e3}Hn8OI02)|cZ2wReV1mPc2w<CPJghvtnVbz0hkA%-5{62LX z!naAdjPU!_N`zNRcnskmQTq|zFX3^7KcGH{@CPMaLHI}2dW6@T6_h`L@Q<m@2yd2f z72yx5O$cw2a1G%fSGy73E#XOoe?sj-c$b9FBm7}?2f}wq*h2Ux)d7SLNZ3aBr_@e_ zcS_GX2!BMiBHU^^D1Qp!kE(Wr+a-Jf;g6{;2yc<_MTCD^twDH=gr^by8MPhZ?ULUN z!au9lA-v9<L4LCc|D3uR;hQCV3E_{cPaymW3D*(+d36iIx0rRLpF{W;)Io#~O8E5% z|DyUOgnvmO;|=B;<`aW&MC>oCt%%(!xx5MCPpV#odnNoN!oQ+!K==j;&m;V+>Qe}R z%A7|jml6K7+K2EydH)o`zou3pyvlqE@868@XVeCSH%RztgnwPFMtHS^uOR#zY7fGD zB>W7*zo`s_4XNc@)NiSCfbs7DjPF*zqfP+E--_ow>T~KSo}X2}t3HqSZ&Sag9>V=Q z)$gmbxId@<Kz#xC??T$W>PzaiNc(p6Wpyv&z8i7-)K}C5;=V_HRaFu9UzDpRaes&T zy7|PyJJm^Gf_Ir!d42%T-)q+7c>vGvHYeqI6wlvho|oqlJio^rHSbk_sNSjm=-Kqb z_p3ive{wm2_#ZIOsXv`hBIave%nu^w>k{(~FJ{5~0rLlsCd>u=#?+swOUNU2G%<M9 zeA>KfKBK-lpWKizuWkU28ho$$g!-@ZN%KwWzaftwQh$Dx@18d2%=emCj|y%?>|Zce zJr8{M!|J~)6K#8+`b%{N_xG#6QbV}^i27^w1nwVDf1_;NKWKhX{SVd$W&9|f|3B~f z$JF1dzr*_vslQjR#{I|DKd95V|AhKSHIDm-F;WTh!^NLOzwTH6q|T#Xf6BZE(De~{ z^O535z5B<|l7B|cpHcrZpBzc4|EX$7`_tx65B`k#X7tGmSe5=4+lUePSM=P^O6<QO z_TRnO|3K`|MbqLd?>$?-@J`f$eg1KzDd8FGg!%D>{MCg19x+&R20x+xS^bO3>Ng`9 z#HQ72P?Mj>)9v_WR0W}5FyDvgEPCS?<tc}!Uow9jqug(vz?&xInUWIoS5eMmsli_! z{G|CS=C9&iGgmy^3-c*_^(pflo?Gy1UAWKu)WWB)qK+H*enn8PHq`6a5VKO1(5Iha z8xdMHpTu=_kZKK5{kpta>$P?rVtzwnZa~a$UIp~xi}i^8Es5RWrQ3*@-)_v+{OzFE zHsSqe&Cd@0j(oM*`|3u-ehy#Fq1CTczm1%?JexA#WRBwLCiLwS>bK{UE77~0AG{Mz zxjHZWu2++rk;CWBx8fTa2lMks6KWn`-|{Sa2IG7W-v8dc><dFVnD@?nYVh~XKR|fv zc<Q+p>kFpBb31xbKW)R)7lSd_j?z+tUqb$0LaH6=i@5IO>@$B9`F<I*;;rVFr9SMH z4#a&0_fGRGm|I_6<||jea)YnB@YNrhU%+>_qQzfjJ~A7>h*tk0LR}0E{*n1d3xABz zZCuIC-yi!E33Yp+KaGXHCZQf#^GPLreemn};_ImO2hFdKeS>s}<neV$*DL9=XA+$U zl8Hp=FPamH!sN_k$+FAUQDdT}rYfe<WAs-_wr$!*sj7?#(>YgDw&BzaWsa1qro@`l z=J1qb8vduFR%v1a*%a=6IsXcUv*%DoV+G5snNg}Zrd2ID<qN3N<fK(A4WDBzhb<G4 zXbx+y>&cK^o|r`A{EBuLF4(<>gX|rvq{>dYRxMSGiaEV&rZhYpWY}%gEJ-zGn?`NK zu*}h^O36aLla^`Q_zJlg50{;DVKuvrnc7rA)v6tiQ8i7)N>$8~g(@R_(XeN#PHEa0 zLC(^ntesyi7B^9HhR-oFQV0fxb@jVjk5mDTzED;iD5FvyvP#wr>p1L<o^!6`uqp=Y z&W=H49cyaXk*vHD4OO<xVW%=<l&i*rGZ^b?Z=rCXX_*GQ*+3CY$?sXXX|&&GRw}h_ z<KdcBQCr)MPSm(mok0ssQ@R~BU{%q)38T<|slCrGRi+#aNv(Rg+vqDPP;r1R^YGU8 zxvp+wXsTRsjHyY~l5IY92^p)oZakbSV}MH)JaZ&ZT{==#bB0+lC(Np28->nOmpX3i z=zEa0vX1NM-eM8?7mJ7IjM^kVc2K!d0EiuY9*$eLf!;uoXeAn3nsRDA=%EXy<;ai~ z!U{wOqU+G1Lcze_h*g^~Cd-q(#S11jMpkbKrhv4X<*<ho>Ry>VSF-gt+x#iycRu>6 z6!e^AE8S?^EgyI4Z@Y}!jP~w!T$y7ua%;QJ_Z)`=A2p1PWH^a7I!31?={DMX4!3vf z5_@Gl&qyEW*IixSg!9I{HswrCp{w<9qKJ#=F2DUTFfe)!8;^EKR7bbb(annh2p_g~ zJg)QA;DtHFxr0Fzm>|Tm0KZEBb?2ur@<>)vrJ;(6DadjOflOzcm60CIj7kY}zh=!8 z1l)~kX~MKMq%f5?T>&7dK)pjCsN;1V0aVxk^0P>H>XN|EY15vnI5wbWXbiIfWjj+= z6>uP<>?I0-EYfie;1_uV5F7@U8Ukny4-?>(QR0NEnl=HfQnnpb7t?Q8aE~=3sHRjc zcvZMaoWfS&I|qX_1a#}yIs`QjWuL<gsQ}9D+JvAfb^&HCdT)Zm2RuL+cV;Hb!=(!5 z`UP{EU3&4HSv4+Nz<%ssbK22!+_Dc9fN&7DN`jEez;u!v<6=*ihE1cBC6tD0z`Z_( zxLB@K0PS|o(6#ZQQQ%-JpiV=lVRQpw5_uQ~V@+qcw~NJ{pQ^EAyh$k)m>4q2hXCf9 zkV#)C6z(-0sqGo3Bono#(9`%=cum<ZYb58R!iEu?^Ds($>;YgvO9Es=C15)LW9h$% zn(Y`hwAu<0y#_sWd%22u6iI05H69|mMfa%Mu#aJg>&@vBS0I}Jf39{B@GQL?V&#g) zcN+gkagGm#K0@?r-;YWnKRbx_D$K46a~(ccvP#3iq{c;HkDgJh23#9mSv1~dg+1J> z8_rzV9lEM|Rpq3d1eTXIcX1x4E)AMi?E&llnq~T3{6N+8BO=w~^wj7ZNd2&2d(6_l z`?>O+C|kDU#l5bh?*WU?dIjj%+0l0#%X|dA3t<BI7$Rljt?|*C0r}NH*Z}&G2;Dzz z)G!0tIFLBC;c^L>MsSBA6AsHI2AE5VLR$qX1PhZuOMnDy)A6vz04C`ia|Cq+_~jG? zww)ZAszmzPu+L#l=mF7WWA2Z$`O2)6Cotyf6mWsxU#Q&!BVle*bMzK7<1DCEBY6_= z1kz4j3NS)Zr<&7^lDR7VUYO19?cLkEXZD6Y2aPl4q_KB59(M0OwEs@yp|kz7w?0@x z5%&+@I|X{c=$mvVhDYx~!Is@?qfdrSfbgi<TQ!}-&x1Lf80bp6Y0DhJEw9jtPI<z_ zbN2M9+VD6dPjc}F0>X3K{aF9;ct6NA;1R^MJYXr180r|XpPL2@xGQ~Vew8^xKn){2 z@OBIRfMk21=A5j$P5pYr-HharAyBy4;}et4j9WNS<5Fd+qcd*PiJEn>gxm`E*3Q=Y zYn7>qs++x+bHHu#OKLg=*g1|mH1k0ai;FlRKHNeGlWx;MO+s!CwK!6pahn6^cJmKZ zD>DyNhfO?9YHHF=Jz%+O1Zs|Asve&nHsy`GR^mL8<#-k75}&o{$RN>5FYMEq-d86| zPN@=R)hekxKy=qh=#0>pVVV^Z>jSRa`f5S6df|6BodzKf^8bQ)uO{Kc@3N<{H=1^H zXU5BuXKQY={(>FVq91iv<<Crk`UW0yvuA7LX4P$zTfaw3S#I{>bLdPr1EjCqCSIkp z`Ji(sglNNU7MiCzHDS9sP5!tAeLpx<cH9<_n*EiUZJsTS;zf1lfl0H<=M}?eoSBLV zxZq0RriW`4cMa!43BV2v=uI<sm7X8>oxT6m@hULcjN3X~o2ugV5z8vgxGRSzCu2FS zR6~_mk1^s5NbGZdSu0`_+0AiDe_+IIQ?-lLVGO)<2YSa8@N7C~PD}Gz&N&kmKaW*o zr3<B4xtR)p(QV>Yx{D9GyK;Q2*4);K(zwZnp#8Sn!q6jLpiTA=1j!=~px#|A;Rh}A zLb*0&9|sZau8Tzl;I7FNNwKmzRjC{^ho(l42#w-qq~2LUQEpRh@(3}gyT+%qk^Qi# zOae1@CP2KL^R}CxoT?7X;H{aI{Y9*qt$Nw_pt035CqPq3f7|YAtTq);8<D|k@uIln zatnYu^z<oq)Jl6aK1?~=Dpf~Kx7ij7SHM<3>Rwz0;%3;Cso^zm#Z<LCTvO;}ZVTMj zsmaLbt>E%-#3#hu6+rcXGa#7?@SVG|W|c?F*g>8J(FC01HceG!rDejA@-*;;5W8** zk`orCgPWOWKX+?DZUkzLUGfg65s;<3su8U}p9bn3#@1c_7|7$-kDvVnE>5DJaFX*W ztF4|mlbFdnsd{2Qc_xubIBCev2DL=QNiudJ<75|dS0UZInwm>GO)52?oJ-YH3wdy` zGUPTU69_fe!9h5acqE~~HR#HfZb0G3tlDG`mL6{`IN@YBi|*|N_1dK=PV^#(9jv|} zfgjR63qq!Bf>NF7HBRCaF7()bBbn?}xU0gSp9|7(X8_uDq*SihdVMbWSskx(sE%7! z&FbbFST#uUNs-<#N>x};G;>MW=h63iXX7RJN&mV52u9XeTpeAe&~oMo)<;LbBQ0Dv zdV70~!@WV~?&|4@3W+T&ieAUe=5}s-Ox<=@Fkl?G9DZl;v$x}-k`4x}o=^~;vD+y` zBeMw42|jN?(yr{lZ0fNoiyuFq;^jZ^*OhY9z$9)O^9&1W()nP*n#Ri)#&%)uT>y;j zx=^xqjnpbwXzg7S=XMS6nJnHpd*|5hi~B~@tbJhL1#9oLGdr;xf1}l1XLn&Ui&3?) zzEpZ{zhmg!_|(uSBjxAqa(4v~iT$pd@2iw1hE(bBkD+86zr^f@;uHq3w~ugMu@B=x zrx@rexCPMV%%2zn6GSGPn?`bXjRzo+QFU{A9FSnfcGrxW4wxkz1Bu2ESY0U3Z37(^ zoy03Kt*bVOm5DPljl0rr8Zb#(#ThI_hKQXdJ!Z`?pRCmT-FURu;F8D|l9^O0olmu; z)+O`FwxsoD#LgbDrzXJ6se;Ut?FTR_x);PE_j86bMHUlk1bTG_d!dRkfoU>Pnhqd< z<Hz4Heo|09@pxe_Sx>$OLhbV@#qmxKNWCz^sovdgaz@uu>dUIW(A+m_R!QR?{#oY2 z>@o@K8Qh*Hj09z65#UeI!(lwA<Q$mRDh<|XW+6c_DyRH(J0LJwPtB(wR$cd4YA!vO zsV5dv^>jT0)Q~ve{xHxA;c#}>aeKHlX&O7h$LTh}&B6W+8*FajNQ#!c%^P<(pb1O8 zv)P@8``SB#8nLQr{0J)cW?azvHK<dfP5}dcUN59jTKa|L&KHt*`F&wMjpT09Zs-hY z_AfCz-3_xh7cs^~Q|cLkLchmm*J2Z9j5-G9GFKij`f4^{Bx_GrKwhM0%ODKB>D!fc zGi-+2%6(nYo|zb`Re-9UTJW5eH*OkH4Ha`+A{F^KD<~QlnM`s`a$Ry&(s~Et2nE3( z$L=2d>{eXN1avME(76Ea1t1iPAg4HU9D4w@%@>Q@vlNSXQPeB|Jhv8$=ch^){U%bK z0CKE%BIi%B2zFLJDPgy;d(Yl|`)@yR$H6-XTaO&=KX&{?X=oUe?fJ)$$_?SkA3fIE z-hvB8ZyjORNsJ}Oo2*m=6r<ibOm42Fg^MHsg>}%C@`iFaQboeG4CQY#Z#|T;&PgNw z9=>}Jm#}l7kg}G_0T8id%&f|(CJ{O1R9-bh^wFdWss;Bv)h}>whS~*GFp#=HH4MbG zs5CnG2J04NJ9~$0`%Rw&*ZW{u**KL!MG6<h0=0<E4)$RlJ#PzY9vJ3a;~(#=Z$ExE z=UpAka4}H_P9M)(TQJuWMTnDdO;uYl%Mg;dR2}oKnC4upr$-o{5qyvuu)ZI;036f6 zs&0D19(6O5M4KyEr-1qCW=htmO{fK5V8r?%d}CeZ<-NGL8FEe=x}1Piu9lr*@%NC# zUWH2{nFG4RFO|bJmz=#(uxo4s11_unYM3L%Ki&gWvmSvurt}zpXxbP6V=O(NK}RQN ze>_+)v2c-pU%~P|Oh%q3X&}WQ`}p$6OvuXz%}Mr^Ft?;a!8XMRG8A52sj8VY*xz5M zl_9q{SGvIU+OIP59tGoYN*DswkqT&aaOJSChJ;{hC}2@&QpD)WG<2i&!)P1;J3S0c zkOGUjVHsIj6pRqS#vdWMz;hxu+rCs!#*@c7G=QN2b|@fbJY}sXiHA;2i~(PtVQgwV zXLUP(mRM{WX^%R9r!dyZ)<Ic336UfQB0KxfHnweg5exZ?#?Xu~4#+M9cPjGNgB6au z4zM{ib5s*gj5M$<7y^IEW8?;H7mi{>CfJrW<bW7#%3n$zQsxrX0ME-Q0WdL?B-xg! zhjmIu(7FpZH>XRtP9iYSm6LaR&dBUx8hPio1*E@_oIqml=l5AKp(hprK})d+a)rHG zEPfNo>^58yIZ_ecFExAfQos;?7A%=u6@r<y5dk6&%q(wUaZitA)^mAI4a~Ohu#HX- z%p^mN9SYKwPIlIz9gstyrMPziqKOW4BiR+!hj8giN_!fixv5wLnkg3l9!cyBE{S9+ zIlFnus!PIHwTTo22Xc=>xaC#^)C~$FEwxOUKuK7CQRqJ*jh;HoAt9aah4kUAeZj<G zEt~L@g8T5m-om~H{iTu{6LUbX)_#=&c>_YIo+gp45w4Qwk@Qu)3rb&QpJryCI!-P) zkwhG(1PBG=Fuq)cpv0qoG_w-I(DB%|hRI~}2RYc{sUpnBl3`DpU`bXWA|$O5ZZ531 zpe3>j3}65WtukzGW~^2QLyN2IBwh$if-PW;o7Ne<^5$7ljv}_6eDVOk0d1||Hz(N$ zCi)lTFH}e(lS_gQ2HdVm&KgS$d+f8=;By>g4A$X6B}r~NNxdJXj9bI&N|pwkf=UT` z=}KE~Lvl9_p`@E3zF!7N0GLQpET%9$d>C08EF~H8<vbc7=zRnaU9Hx;aI?Ob7t;JL zGpr2*^gh5)i>w1$@@;W%V||#HpXBAIc=<VAex8@GBjrg584?q}gP$y@`D7+tXlc#o zSLU&sC=`bABKTvi?!iw|#>g5Wfvv50R~o=X5;PjFdCoZt%q1<qnIsJm;|gohv+#E` z4Re=#ew_&a+r#t}J$%b3UKic4KoCZd>Gj}tua`v50y(9>d^y%k7+@q>kDX*@b@gJi zHUJdf*-mm~)U?{WVsg=T5X9{ePkDcOP0=$U91Y0zCL5MZ;eT}keuGb$gN|+2bMTOH zX|BDOJJphdl)Z?B0M;*wcL~ThcGwzljv%4Lj?=4fi12p@_<oN@_j|(Z{37>Ao<t(? z31IyKAZ<xtCJ1H$r-J|UYck1~1i;(y^=y@LgdTxevIL_ma|DjdV7pXpY@^9e(m>5o zN67CKh=xbNt5tUa)7B<IwneD&GWfoV(wxf7OKBbJ2PJQ>b*Y!wx*crYpN@g!0rVv@ z9l?=t9zCR2klkYWkSXg^y%55R^c4bMZ^%zw64K%fn$`!2NN+I+LfqBa(Gv=<yD;`( zGNZ9vm9XBkw@CJ&gGfCihkz=M^a~hq!zD`IAeNr04wZ(-xw4JRka#*NCi!U~nQf#6 zlS6v@rF17d<d&d2(+%B8g5VzfYy+1#wj)zQtO~NYV<U(4p~>n*vf0519jChxG-`u9 zxA#J+Ql=DY&M3#V3BcQjpcx!U=wyIvX<F!au&K4gBOn@BG5-4TlYP4E#}Xbl2JE%f z0*{`=<}4Y<J_Wcc`i6qM$Rv`*fD6igb_okeBxl=~6}W`kDkPUb-edLB#Gg;@-L!00 zhm0LI);cmqmR><+ExRL9t*y)Eg=(Qy#UknBrH}?2sF%j2)<TZqUY3)?1J=T1J{?0K zY~DTi+1<E=FriX_gS6&E11<m&0vAmxk9$rv13n7whN4V2Px?iXzyl*AK<LA1<i$VU zgZ?8CPEv0~cH`mLropuXfgrR~YH|;Db$gc@!@DA#Wh_&0ID#ydf4m1ZAP0!#Xg#@! z1dvd|zk)a)mXhU$g26=MmH@1iiDL2YNCmbnUx6Tfj2vT6^y4R65xs|0sD)7E;4dI+ z?rJlns4c0|k{bdceqIr&$BT4?CeD|hVx$S#5v)QT+Ph$N=*i|+C8;Z+cUjh_k-V{I znla9Lw2wsUvvs+C2~rOLuQWih0PwG|4596QJzkmswanyC;>95rmd8UL91{Lpj2*@= z_~UNv9{lY0AZ-ZIfaXViRu!1A*nOz9nH|wgt0Z9BV_6{%y1rmrB_nJrSPlX13$z}> zy@eJ;xVM_Eu%?0~5uV#<O@#YOS`^{FidIFqucl=Y?rY4o)_crVgX_%IgEyFK2G>`& zBeVgbjR<X`?GaL~qx})?H_!$N_w}?x!hJJsk#N5ec0#a7Lfy8|DhV++(J~45n`xbd z`z^Fk!rh>i67E}Rsf2qwt(9=!MvEofx6^6~_Z_rc!hI*~k6^uooI7a2gqTiRG2z~& zV9A90t*}pmH4{?YMvErIbknK{_a4|S!LkW&dTHH+m|e7R!hJWboN(VmODEj-(%K34 zeTww;6V`T&Q|Tl|Ocr5mnV=mB){ye(56Bm(76t(mv>&yur7?k+GTHnSCIk)K$!YyA zrr{n>)&q1S7{>w8No5m*I+`F9I{Pm{e$eS<-8C1`Xgy@UND|5xr<u@8^yu!#yRm9X zT^`-@I0y<)X-ZQL@?pTkiG0`F=Y2#97es_s=xJO#F*Q!>yqOI3k-j*twUt7;GoUv; z-9#auecFZ1m0hNBx6$blrX;N+8F#kNKnJ#+%8VVmIs*E{BYwi$ZGJ(Ez6X=eIrr^k zph`3C5fXcwVM5aoq=P5FoCwCtfTCvDAg?_Q4G8Ml*&eT0<b@Qd`;!garhx-sMq<rp zqm}e_!s{we3>kE+9zk@gU!nN+WY3*<-nnbf-d+3lV3!hn1m-=MZ?@A3&>gAXO;p?! zHjY*Cb|T;xL34A5-EQnKbmC4E9nxuc;V;NevT7%2dSKfX*%IlOx|#sg<=%8iCv`0M zzE^h@tHwW_srL;4!h`-rnRh_GM!m?67fGY5)~lu_COf+zumUloo7T9qlF8?{P;0cZ zd#ORXi<dongU5Y)pwp_WYIt=++xbn0eA4*NZ@o^jx1-@bTQ9GWZ}4hS>zU%LHDyLp zENVT|oPgjpOcZNAUq7m=c&%3T0ODp28T<5(k!|gP9vx=jA!E<ppb9+(XEmbGQ4%?D zHjsmm;tS}Gb_76ofO#qE3E%`eNigA{W-ylpRhxy}g9-+zfwS0~UP59wrxjtznt|3l z<Xbny7I!jiD1`u3`avddg4P5<6j~}kV^AJ~UL-<Uh{sA5H;37V{2HhT>o@V`IG1!0 z&IzxpK%s|Lq<9BB(m4z%U!cKi>I)5L83>oV1K}K}0&BV<^y(YpTp=a2YAe5#bJ4 z@FD~{Fq(ki3?V0n?s$-~THueAP1T#_O&)JXoE(|<5}U6lN9D<Bo@c%Va4-|&&9F*- zT|Fh&jQu?dT{@Por}`4eBjvOpkM}#R5bg?B6JP04S16EvPMeb(Nh8JQrTp}0VkAAD zdoF3ePReh?o3F7<)HIF!J0*7IJj=>CtLn*x)zBV+7y_~$lviEvta4UTAVIP+jHmFc zj<{m7dSC`$@xA^6R^8j7nX<-N>#Re`1?2mf)=(jsFi+2RS~#%-CxlAXqOcpR-$MVp zYa1X!M!peDupk4$yPF!)V%46S;EHE20xS=7)-`;gAqjd}0IT&4?|k5E1HE3=h6iWC zzJvgo8jee(X1sL)jSybA^$9koK=~uk6IKVIOoX;{Gs88iT0mP-7y@oHGuDrVlcW^n z8Pk9}7>fc_>$AL&18IGZ7fz=}$S2Y35b}@WfkMCNKlf<`2&oIn))WcdRT3_UU~oHP znYJ~#F0~%-Q%JWyIeSBNE4K7LC}0UwhD%&PhVTdg$l54CE4v~N{a6Ol<o&o~f<P~Z zKL8CdMow=C{WsKK;0{Lia@hgPLB0Yc!PbXcFBU5bH{5lM0`?wnrO;X>HYL6*bzY>B z8nQ^~2h!;a4ITDEp^pO(?ZL^z?`6L+>s(^CyP@5|_A8=%5PXQehl~Zs9b9_|A5H5^ zc(#6@m#^|diqzW=F17EmxKH`M5M#9^3#meKO=@=Ia`hNy`}xOxNiYO&MF4my<q#e3 zMu!p^C!O?s;wmH~qu|gpuAc0}Jmdh(Wva)JKIuSfOonWL^Lh-}i7D`QXFLxKFTR^^ z$O(!iP%3enQ05gUPk~T9Q*8Ey+-Mbc^#b(L7j7DzX?+o~dZK)tPtslNBsY6;oT^ro zTz6&l_B}an{V5a4`jLh_w_y;up9WQ`_tQVjUL;H;0MT3ULtiFysdj<&Mg19k7VK!b z0&piNtH5XQ5CiE?h)6agcozU&Pu}glN89fM^d-j=)*-SZ?!Za_xd<ULMGHiPvc&oe zO?B9pz72f@nN^y0r^&?h>(I;13kC6ja0042nYrwAUp)=Qo&9sU>0YO$4jWU1+VQRl zzx-S?uz$YZjQ`wtW+U<k7H{fHoPW#1iSu>*s=&e+i81K;-K{55TC)R0<kYny1Xzpx z4;2Knst17s<7TyzWs@)@fl8q}BMMP^0JH3A+if<nSs+q0WpFXZf~r0(8B9QH7Yf~4 z@ly%va$9OZ&QPR-qL}R_$E<HkN)V<~P_Kr<j+pB$F}7616<*0tacrrgl8{l&r-{2D zdrhqYHd}{rUZ32)c+Lc$2V=}h&Yz4i2VBroVx0U*Vc&4h`qP!QY^)S?ay-$6T`Ycv zwPJQ)18!=VuVJbHc_DSYZ~z!4r7uNIS%1y~IU$zj@sV;u-xiC%$#Rh_v52mb*RcXw zXxLiNHLdvfTl*qqL2Nrzt5u3cxZUsyYg`ia`&enQzHMlpo55IGFV;S4uOLaW_}OL4 z)bC?u5)VoXIrnv$q`p-0sdUH?bMOx1`p>w%SPd||z6M~i_&Y%@8V5H_6RSzuuL<#) zR}*UQuGhGf5@@a15iD}40XNSkjhi!eSH^7ur=A;sy>z_5%Cg4GfJ3wN7C-$QYf36M zfn~gqnq40UM!$qbm1TwP^|(Bp0Fw#`>vH}|!q+4OkfaBKPdKtnzR&*z>u%dz@(O0q zCST1@!<9@KZ{3xd9;?1^-kw1wUu2z`YbG&!+v55Pa<C(duCMWj-2N3`MKkrEnKzaM zHdlZC1-}eT(1ryyOcXQ`iKU4zu~#zqOnN0$fUJA{GLl+K4OH~yUZiKf;@28I12Y~- zgM*C=YmMK;x6&~M=@|L?%YF&ymkrC5u&7)5(N57KAY?BjuVN)59+`d3X)&(U;yY68 zzNM8x(1bWMV3lFt@0pD5?VW~N1zu3iTa(w^@q2Ig^-g#70)m88;4JV5I21_8P-j@c z-vn(*&908Mg>SFB6^|_23Jpr%ZabhX9f0LB&B^JK{w~rWZCT_GzkYw+O&VFYN$8oL z#m%C=7Zskx4DBTkl-tY(3V1EuKI<<rlK&KGoHnKM8z*1J+P3UsGW*;a2$xNPug<QJ z@fHFTO$Z=7)fyiZqxuGX0J0&t9}xT3faw8V2rUG(?6p#>jZ-eI-2}j{mI7=PM#eCd zz{SEp0C8KJ<pEgT43|Se+)FoKkUK&0g`f-44eK|se+*_xjS{;&fS>(#T<S@?pkxO> zeE_x`qVoOtt)L63;+=--V9MGHx)bYOJu?Ez^ZYso>Vft2dd$@)5qda5%9QW1Gf3Iz zpil_%LuJSD?0pAX$a+#g&t<V|&tk8T<NfYL9aIwDFs7;Agl(EgbxR+|0vvSZX|ea= z#3mM?(KYQZ%n8^$Yh|dBvZy);L)<d}xEmbw5-cXWLj5S3ph1@rVryuB8hDRU&=!^b zm$=iOgHrwkw5Q9%dZ_v@P1e8-oD&-p4lfF+)`D6=j}`<g)DSSLL^)bD1WJ)Qx?7uu zK>L8wbicHqgfJU43gtjD0DB%3OpgJg28P-ZJ|>B)=^lcwqg5$|?D1-?3Zo2BO$o|3 zI>j29DhCi}mpr{QXn%;sN>D9ncu<+3deYZYEl4YdYap}j$r|(tz>=0ZuIm|v-5?Jn zr98v~V&e#U6?7|v9iDZJ9zib~zqdG@f*b-Jq;5mhCV<m1#q=QcdSepuu@?&=$cH3% zTW=SNVnWoZJFtPn&6HlxGT+@HJDYDb|2r_>><l%68uWj5gWI{!*tZw_^)4{*g@3wR zbA$KshBpyb@U^mra|&5<w8a^C&9rvYt+<YIQIoL9pi5b1r8Hz#jJVf`Sb|BAiFhyR zI@?bjIePq*NK%&Uf%unTM?pUc-^V2nM~)l~yT;?LM??^;)iyDOmr>;?!<mSvszIBQ zI*^c;>Glga1w=q66u3Rqx)g8%n2;b=!);zZp0@_hed6N@PB9N+<AWaoAnA$g0wBNB zVnwr+9?)x8i@lXjTYAW)+<2`tNM3J8vt<4)5@Im&(GHBxivnqnAvHK;AYnM)uKlg> z*xV*>!VBMQwnvZfD6MIzSp?H0t)Yg+=^`}kLcG<n!|o8i!T>lnT;8oe<|W{X$&R)w zuh|3d!z(v84)g6%Tc}^*?YLQyj#^LgZL3!g!CQ@6?=-6QA6z?cM$$xk20Tmb{=oxS z1)e}F{>c%@!OAP2oLv<o1o7e0DkK|`5jg-@^HyPv!%hY(93;uwN~cr?1rh*&PfW!q zT+zuSrsXm~$23(ECF1!*D=xt-K_EQH#-4&#Bj({*Ir@uam;sQdM!&Bie*`W}Ea1}t z7)*#VRAg0aOo)O+-<V4*+@Wyr`F93R3FzVo^V7r2V8d~(3{nISOXFvMxmr?C%o2Q2 zCJ>UB_FI*$GB@upYyczlyhj0kS#jhQ6Px-u@UADJ{<@d#_N3Mx?r)IpE&atg_)DO> z6X2<^gM;OxBNiQs`(7k3f92tz27T`t#(9cMX@F5M9Rv^>ri1kj!0tW(sNVOlCR@J& z?9to+>`6)nYV?Byd$58Qz@!9I5=z(8ClF38KuI3V#)F!m1p5&}u7LfRMQm=a305b$ zI>^6zay&!!Cd6P_uphg@dffc5KXGn}PMnifXp54_fU7LpERhZaH5lm5YwZZEC(Dyk zK_>+dF`(uO(F;pd6eDmQq*@xDUuIe%D2*e&O-RVaE2FNRG*K^_k>*P*h)L3?TH8^Q z_$z44>OhDkommlCR6BX0J_||C<tZkwb9Q&L+p9~hQ%e#Ky$y?9q~L3lHz=%QdCH2~ zhh#sxIi0CydC3~`SBTb(WpCwxPimbGnig6X_CJ_J__Ke@r@!MR&K$5>@zF`n4}yN8 zjb^_PYsELzy66~pn9LvHbkKOtpCsaCkKB$_>EDrUFycoP{KEkKQwQ3EY+zYf#B(5{ zOOVzBLZp|Bj-LoF{QExwq`D}54N7KkIe?{Lj1B=gDQP1ehfEL6dk(q)CETib3R7r) ztOQbLa1?{+A~L!rZKjiUGU-HVlFCN`ct=!NSoIg1#|?lRmVa%yT?Dk<#{T{LL-mjW zaHcfm>Rb_|_(Ry+jRu)k8^GmpLLq*ML~8^5=?s>JKaYnDp(;4Y>qwnIvXp><sUT{4 zaY*{;c3l+R3QR%~%4b^m5Xa$pc_347JsJ>(=h`lgT4Hdp9Hi+^5J2<z>OQaub%hPJ z7NKjkJ$glvod?WF6gJ@D0!ok|tT9D#5(?z{{WSp&9zM`7*t==V|ISC9M-Lt9+4H#O z0db?FvFqav;K%a3y+TJvFAcZ+qGHX~P`cFCp`oG;kXf<E)tF(c%J|rbQ5m;YNO8z3 z{e~};Jzg0Z8?PuEj@|7_NP<w)Uubc{k_WT8wLZ)?3D?a$--tX{0c^(!wjxwmQJ_#E zjyiQdF@9ZuIyEDl>c9}fq`){5aWn;<ny{X|Bj}-iI?@!wj{r_J>nO^Y2vWmVUYg-a zBZv9%(%d#{4O%eA7Lb9K$h0PB<LpNHHa7DD+3yHGn1Kvc?+2jKl7O$3En1U>4R}QM z3^0+;K~sn74JoKM9AhIzy#cBX<giiJBl^M8e7^D38>$)RB2x04HU)nfH666TykRZ; z8d~%=b_RaSC^=B<R4hj1EuoS_#`+_CrWa^YY#=y!5TuvmhT>>kcbUbl!2?Z9X(gM3 zUIR57HZPXbf>71P2jf9dVqIk=rd$sa2XH&-&qnYd?!FB35AoJl_s@#0xa=hxAeypM ztO>>9+gUFyD&u~!fdlI$3hKdx1R&POehwE}!CO_jc!9xo@|on*NnddGjJzWWJ(m)3 z8olo1>nV=<TzY!HNcFoxL_@|8nLRkPeF+fQS@KhzEO7i`XbB*#jwv>sKTJ0r8I(hd z`#aDb#S}`-(}T|#yh_8H4`8e-7mDZr@zQB)Sy|m_qL$El1qthkE86>vr;;!ILq{_u zTyizBv(SAe61rLB@osh%?uprsC@n)}AnD2|uxO_+0XkrxHRC5$*^dX&(_!mHZw;G_ zn`yZVNm816JCGu#wfVw46o|eneSXz>>hYws9?x6wJ!bhQdCP>tGdFvIFe(6#HZ-G7 zi<<E@eDfYQgTMqmz^-dH1UZUMkQ5EghOgqoP%y8V93f8qGrpz9ifH_}xv5F+Pkr4j zoOA*uFo8+Ivu>L_laDLmkPD(m1Bz4l!dlOZ2)HN^m#%&%+d#BR%`Rwh;YSS!ZGXN- zI3SBPw&cqIl-UCWW0_Jr@qo_P#KmSX_34XXGrh!6NKK?hlirvjPddWZkvZoXbFh(( zlZ`gtQu>du-g>sJN#)av>Znr%V1uk=x=9_$oS{D@B339j@{TDtlJc#k@|`<C62LAB zv;Q+l8?Fq?ED5v*`7kTQu7KpTQJ=xHaA76*$2&wDy2HqGqJVrs+&W#BN^xe3C;hD0 zKj#KsNIp87f~lsT1Iyt|;3Tp;ae>U-fIg7l@f#_PnNL=8&<emkCM%9D-EYRX(nd^) zr}_M8UK+42h3X&mn+MTx<D|t@i6MAjp#DPgab){Z=D55*h!})@#Lpd_*Qik|xr;Jq z0C8-3(1FwugpzDZI1S`7^Z@~+tah01w?mYLrIRQP9g?PK3aV6iTF6{Yfapz~hr;Uu z)Trudb~yYhwE{JI3xM853Y{I&I_`>M$vz{Bm#2s#*njBI_u~flQ|2UGNKHA`N{mxu zCmM+RX*QGFzXVjr$X4WJqpFeTDdDuQMjS087<3Lk2VP*9xrkl`0Y(S_ptW>q9ti@X z#%C;YrzIPIpUJ(*zcA_IkmD#@en`<FAA-;(@N?}`%h%pvUOyclaNiblv+ar+A2TX8 zukswx={N8PqYQFI;fH)`6z<&7MlUm=i$z+50m2@-M=Wm1=NGvbn3<3(!2OX(!~!p6 zv0Zi0g)B(Z+4M2stNi;mHXg69Pn-Z49YJ2b(Z!&HiuBR|^4X<5e9$rB=8q-Ciq$d^ ztzisVG&Wh{uO5382uP#>viFaDqkEvp)e9U=9qRS7h^1WADESDI!AKSj&10_D*_Z%k z39p=~XYjMzagpVEa|Bgkjo{i)1;WxwwtB_#7KQEjMD&wA{6z0;i#&UM4T(O7l6)dG zj-Pb%qa=mD5(AsR2wtLA^e6pX6KxH<6rF3Voy1C92kis6I0=gzYN*6lL41vYJP9?S zo&f<LA>@+t0Ri8YEqw}E1S1ul!CE}9{5+P$A7>L-GuND;{|EW*K~omNw+6K381Jy5 zfvM6iv5|>y{TD&50PUpZPtFFYU3OA-!n`GBr-MnUt#@e313S7)9k6TZIAlE9>D$5V z??QA3?O42Me!p8Hwb7C!hG|Z>vA65-&|r^kk56uImT}CY6ZIIvo!4kC{Fw|p@iyzI zhK4g4rmNoyzYTu%y~g|X?m(^QLe?QG97nJX#%G>*-WIp?8pCSqMwm^3cOrhzc%p>J z?)|eZ;9(2sOFoIgg?9|Xm|Y8e9Iyf&=4G^qjqQdZ4*Y5yG6GA7L*i{y%YKblo_SyZ zng<pf<&<aXy&zVq2Bbx~17GT4@P#RtJhQz+Mmvn>Ag-YW8Uln(2E|&D;l1r}$L;+E zn1QP{v4U(^G-mKzul8!HSg2!hA{1hXy0@ZN;g`#!mK!uCiEJcGZpVCE1?o)BN71Op zr5<TVg?DbroZ3m~&1m{Wwq#$!i@)|U9V`{@h%R4VcZB#;e;$TIYlj$RnL)#8TgAQv zqP;AITiX#EDVf2)V9C^&rglArP3uy#+pePqK@YQc*&X}v6A><m;q~5zkm`~`+s8;? ze~A%__nY|4+v+t|kA&~v`W*wpcjt>%D{!_6ecQ}~uPyG=dpdd^vc7_xu!ISnD6FyK zNLAM&sSA~X*ny;<54vM5Tp*-!sn+I2OAq@rXg<=1+pmKN_!}G8u3+II-=Ln99X@oj zU|p6R%Pw$9%Icl|7zA!b{K)l~JrcmLzw+pVXlPhO8nFaHZ?q5mV=zLAFJ$uDQHOBL zWN}Lu?qsb^?2gYP&g+h)cq;PE-?JlHkuZ_rzEtl?8x%2FuM>e8A^kSA;Mb3z{UFLw zFd4+wAm_j=h<-!3Ad}e8{4(g8fs?W!F_*7r?1L&hm&PxTA1v+Xzzb2i@n-9l_2gW$ z@W#{DYw&#<Z<_59Y%qrC=U6o%oCDV-tzbK$nn$zPR^+BXArAGlg~f*eiiNor@L*cR zp5+_$LcIwbzF)<6Eem-FJPXjOOVvImCFWs+k-3@~B~LyF`#wpda(MrR#qZBwMonA2 z{QgPjgm5b?^I-Ew>$~%p!4qtnYjv8PLcN7XP;)D!zIoKQRW;XFr~>b!%`ETyWo&<R zYYJg&RCb}Io}+K)u9n%S0|@Cn#?x8EM|GFsgUgaz4fq=GHRyVr&H_Cu7AiPYgw*<O zWXzJf^qkblG69A=+&KlJN>7t4DBVpKf*HWc&!5eozZ;Hlgx1h5hTI@}kPt-B1_!!q zPfF{U=$RPd09hLdrD7qp#9lZ9j3eCN3^_kLq7wqxlC2G$8vA?U*%WyCbj~^8W=@_x ze*X)}z88{*XH$K<;9`u}AtI*a?65>uN%AzZ`OHf0;t*CF1AY|myV^8b$-ym|1ON7I zLMRf&+jQ$rF(@67yUpAIVP|G4H&v}z?P#G}2-CVNp^oF6!k(&fQh(4y=b#ui%@f$h z^e~RK5#zSNb?(ucnxPYOjn1W;1c`Mc;lFe4o<-#naATWEZUl#hcl@V-)WETYT_Bz$ zoLVDxHhJMarNoY~0M2eJzR-F%)V$$#xfQXixLJ<#+oewe)<BMB;wL!Z5FWrE6@>&* zK-dYWfKKc57U7xFg)w=iuq}hT)y>@aQ`LY>0AWzUZYLEEi_d%eugFyM*Fqq<%D6bB z&|@k!ey1kyBDm-UZk;gJATns=5b2ZwL=&e6t#~5>Y=dkl$V3Acvq(HZQ=ayTu($OL zq=AnB)ztyog3z)SthZ_3y37mFVhmPh3r*CrM;gcz#HDx!7-?GU$@msFWS+q!@{^g8 zEp?(9!SsvHcTLM`T~ANF8T6M-?TE8EIqimrlZZ1bn=&!DFAOqN<&hDb^8rl-`m4qn z5m5Ytnss^foZ}sH1I-T6et>GO9IWQ+Ieh!O9ow!JSt=-TImn{ZYJUvwOCD1_!G#YE z{0HzIY_q66n);tpyO@>l?AX>p{}q9<D7h&(-7D@2gQOxIo)y8`EurvEIc}tLQN~@J z?a?@>V+P&klbim%Zs<JxCgD>&Hq_it%)9@Aw<SdS(x@5reZfRhNgPkWlfy#kY*6+1 zh9y=v4IB6@$Re&@wRf+vXV0FVy?cB1;m_E%ckiB~4YlPuL8dn4r8>K~g9=tqlk!YO zRjdIh!F6JX)Nu$KF-F4ULRd#h8*!7z?+rBCIArV%-4!qrJ%`9h{bEgv4vBob=V<VL zK)c}tCJbZ^4xgKa@)2rikuAAK0a_yPRV0Rc0%BJ&EK4FM>pygEn%6jq;{zHHPLtR4 zqr^8GkvOqln`(=ZHc)OWu+Pmj0gkg+z0X80F-)w(Khja8r~2`;hfqA|C`cE9Ei((k zW!9S)dgv57l6L=(AP&@~^+_kAJbG&(8&F%h>DhV?>{$y~w}~_tWSq=P)1i2RJppV0 z>Zx^!deaCj3xsW(tLKGk`cOS@y+_jLK{G+QOyy9roaKG~6O4!CEI+TAxc5o8ISj*c z^<7RuHE9}9Q-8X?bNT7l!xk1_dNpgFD*!_lSSC{3%A7zc`Sl`Ih#InN)Upt*$w*Gu z`206s>>Jdw08vAb7AsBjLMtdfQX_@ZeL(yH5FIO*MyohXtUT<Sn{X<SPNH5Y_{_re zq&X<iruHw?NS=pu`H^AzAQ!u+ns@3D5^K@`_7A=p1I}a<KY?Q8qS>eZ;dG{V##&H6 zQPlPhsZ(XR#fNJW>=8r~MQzH`w~v{9olGDQ4?+2AmY#E<hzlLzWCTusA}_dI52rsT zcF+U{0u<#J7Q;~2;zQ}L1Fd#u$iF3#%!@OeVwLiIsszqbbgmK4DiLohd>43E2{D+} znT#Cq0Gyzilbp|#Ifa{KN{t{LhI}-(Nyesq4(T8Ri*J(~(2h9ce?3u-CR%2<$LL`? z(^-lfF6^*(*gX)k9WsP8rYLq1`6C29F&QemD&!f*tC<Q3WRPpDtDCye=#)Wf`Ibm6 zS4#yR-Ju>oBu_hR?Js177Wljw*=WBQnvbCm@n{gz!e<9sC*m_V4Ko-`vkOh$A~d<R z3q#;$6=vQ!Hv{6wBfC=rr*u}|WHGYM_%xsTki4;b4<l}r74Jrh1iY$dplwLc`|E+t z>3m}&ek8G1fs9^<r!~Oy`%}G*HjAuk(7`@5i2WC(zc`oyolJ^y1Qg{DKnvn+Nnfd^ z^p8=jgtMC*XQoF09Io7nlCTy<Pr(b!GP|+r`zq|PqmobNyt9Lsz)UJQT-P_;2Z4y} zBgO&1U*I@;J3|)D{bn$6{4#ojqU1#4UZeA&OXnPC^3bkbJZTZ<(a7PoIHqpbzFppN zxV!W>y*z4boA>Nx6R}lUTB8yN>w<2L+0-mc?|}mJQ!XY3M{xcX-k#7$(KRrFVFSre zbzyb7!4HVHj?NC?L-`s$)4Dq1*iPd6`utCC^GHPh@VU;|p=6ybChF3Q*d;)b%qoT+ z+efM;qtrdr-8oVnGKRZV_uk#`F1%;=?go_W;Yr=4ofpf>Id}K|h^f^w2ou?NbO!^> zx<Ht=D9Y#<YD|S>ofNa7TDU#hG0cGC1r;QBAKmnLL(Xu?#do1h4*Nehr>m@mP+EuH zdLJiiZi&g-kGSvgu}tEI2F9JvDVT&v8%nWz5#T0|n>(_oa0kl*45*tmQ8j7MQ54*R zfN?hh6HKz}d`)M)M{VG<35#t>-<&-D1vDQHiGe4+;)hsWy*uTGn;2w~%ZV^`u+Ju) z7>M8pSb3;=&|eddFTu`pQ{pjHwFsRY@Lr%_<oUNkqZVK_Diovmq_U1d_zngw(&VZ+ z@r8ve8W-~|(iCAQ3Ufr1#e|diXDC{GcJZX}aB)xfA#}g#ww9})dpze&4TzP!09P$u zFMO1}KzbKU=*&9cS27%1Q;T{c{314t?2Uf>JmsjyQy27LWppc~0e^tR))#PDTBF2m zlOcj(18tg$#ZR(&TwkFdp^sTP?W+oKD1&rMSBfjBK0S<^dT2rjneI8)2NY$jk0XV6 zmeQ8-veQ@+cEpuEMU;MR;#&#N*?w1MVBqXo?e|0uq{+Z17az`on&4gb8fUxqH#%4q z-{QZ?1fmJ`0Y3d2FaM2~zvty2c=<<O{s|ZQ>4D+vEKZY!X3)Pd`hW65M-JA%@$&Dy z?BrZ!tE?oS#2DZO2C0i<35TBRyw%LhH~4}|{+bk^#;PcNYS;ej7~I0kO}tR`NBcCU zf`=v<$i~-fZ}P&dgS^lwu*J39B95?*@p3OO_wn-c%w;-$5oX$U#4)XX4iEXASnr$H zb>y2{SLAQNApw9<%_Pg`5CX$2lg58C#Vh{v8TrrV_ZQaZ*X7&tYw}IFX7j7^d8RM4 z;AvaFrEoXmcNBW^8*yI&x61-)C=lZ;F6;!fPapthc#6*JGI#~IL|Z^QV)Ei?e--^# zT}M|>Dzy=;R>gB=aC`>YRn)P8KQ4TCHNBCOJ5$P_2%m?f9r)lZ5`Df454e!6h2DP9 zK|Rk=!j=bMP8a_|1n>c(J&+ze+Z$F7SQ*ZO7|=%rdRb8ns85{PqxT{MuoyigL<5Kj zIi`=a3-cZ_dHfG33SnK52}Pzf4yF`E5|SCwlRH@25D&UV9eBL7Pv!Wz!38W&^6rI= z91cc4b?Ky*n)oNHMwigJ7d;r9G>)9?OYRHVw_uC0a9G9qW$A9RsjA~2YSVwI@9dGI zhvz&i3VUjF6yD;%OxJD;#P|CI4!~i0qs091vF}j-LK)^%aia`>Btq`K&wK-&BfNVI z1|M|4Gee(*)2A__nBZGq>t2Q|)WekR3JCZ=2bjTG6i-M7vbf4n2IY@h&*CvMM`U{3 zg}C1!HX;H}6yQbP2VLHS^@-ZT;E{rpNw0@j;ZIrg>N2IKCBRT1%LAL20~RH}{~r<s zKK@^ZL~fTuaD<>dD~JamNg%Xd#n&N<7VtZT7hen(!$JUjgvJ2)G~Nt>531%#;6q|V z5=V5dk)?ADu$2Io`k*1vl$EeP=@U$Nsx4<{1J5g*P6An+so)bvr#~jAoJabtVNpz8 zLndR`8I*&(679zxmeVp5_K2IKgN^>vZjQ{#{?m;;bP_%Bb@q@@m}#0*=OM%itVi)G zv>rW(07SLW9p<Wna~|R54$q)j@SLVfD}BOJrImN;>%vYniEXN^DFd^)`*|w7F`M_S zK#kd^P8?_@XIZ&f*<on08OKeI_2LPMFxAtJG&#&T{0@SEhE}*6i{5f^hR8m0(D7de zgP*j{po0QYG)F&x050NQyP#+4wF~yGWR@}<v>`n(o0m2KRnKPVLIQnFLAI{;9IH*W zG}y$yn!}No#RtR9BTyCY)@ep(AbV+4l5;l)ZI~M7+7xNU-$YvRFk2zm6y@;FUq60A z+D2Ou)EdW$tqxRi469TIGvE*)Ca5?X!Rl(Lks79PR7YbcZ}BS_<Q1vn-$ttVT2>J? zl0Q6?hD+RwpR58RtxC<_+i|Sc0|RQ15~Cep84OL0Qfm^+CyoAKc!<pydO^Rzfy}~C z<<VSfN_=j6t81@kJe|~gzJ~dK28I4ZP_vX}BOD-sCIs^M;eEp9hUE%;XhO=i?&*|o z*@0=D9!)+2Ed*Qv_6lbw^PDkg9%QW(@Yl~%EJ$+Qpqf?Ta`G8i={YIrAf#~3Jd;o@ zRCUIg7p>1G)e8FFtY@^39@U1u7|_W`>Y41*iKmlKr=Ctfoq0Mtl9OXC^U!fvJ(ru= z=wz>?)Ec?2ollMB=F@XIaLc#AHmM1=NuSZSNlyL>CgfaBd)cLiKoLJ6r1b-_nao9Z zEt|`BYt0+k`p8gYHRlrUCM(uO+<{=h5vzJ&An0@!(W?P(?8e0GO+`%0iDC(!pJpN) zMDLVfK~5*6#{p{R@xk+)Z@~tLz0Mzp$o3HnNYYl7ssgcsnJA}CwtzgvgoM9Km3<bd z27L(L7sesSaTq06zKOPBEPy_T^$PL)zu{cv=l>lS?fVjIMFqYP99^9>jvAf;xix{4 zkU?D5s%|rn&oOz9j=O>~9RMOuN<k1g7nvyyGu#y;76ex`WyN7>jc55<l)-FZ=j2e8 z1Pn7a<Aj(cyC_yd0FM4#mJZpDEO-_xP0>{HSqR0^Xf#+WO6UXbr12RZgeFy_{L1g{ z602MA%W;OF@RV|fB%Pa+R@fFtqG5_#3UL4}-*AIQCbPG^Xd9fN=h@y^C4^OsNcrO! zH{-VfKYIa}>37c<S3u=m5xXDlEBkGbldIGfG_?;6mQ&7YdG`(t-HhLa&DoQQ>i*eY zIvc-=c}Ykh2-DK;SwIYCCE$cmafM#3#-2<(jF{J_9`Q=Lk{M50&#}}jw?DZ%0DgUm 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�yt|u># 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 bf4OD`vK@PJnXc|!mfuWQHplGlWEB2CiXjwV literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/retrying.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/retrying.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1026d5fd53fbc7fcac7cb5050186963c57ecd0d4 GIT binary patch literal 8098 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/six.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/six.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..89ab4b6f8b62d2c073ae45974128dbf4aca9c748 GIT binary patch literal 25003 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 KzM*7#hW;O$K(}WA literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/appdirs.py b/venv/lib/python3.7/site-packages/pip/_vendor/appdirs.py new file mode 100644 index 0000000..2bd3911 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/appdirs.py @@ -0,0 +1,604 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2005-2010 ActiveState Software Inc. +# Copyright (c) 2013 Eddy Petrișor + +"""Utilities for determining application-specific dirs. + +See <http://github.com/ActiveState/appdirs> for details and usage. +""" +# Dev Notes: +# - MSDN on where to store app data files: +# http://support.microsoft.com/default.aspx?scid=kb;en-us;310294#XSLTH3194121123120121120120 +# - 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__)) + + +import sys +import os + +PY3 = sys.version_info[0] == 3 + +if PY3: + unicode = str + +if sys.platform.startswith('java'): + import platform + os_name = platform.java_ver()[3][0] + if os_name.startswith('Windows'): # "Windows XP", "Windows 7", etc. + system = 'win32' + elif os_name.startswith('Mac'): # "Mac OS X", etc. + system = 'darwin' + else: # "Linux", "SunOS", "FreeBSD", etc. + # Setting this to "linux2" is not ideal, but only Windows or Mac + # are actually checked for and the rest of the module expects + # *sys.platform* style strings. + system = 'linux2' +else: + system = sys.platform + + + +def user_data_dir(appname=None, appauthor=None, version=None, roaming=False): + 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. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "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: + Mac OS X: ~/Library/Application Support/<AppName> + 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> + Win 7 (not roaming): C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName> + Win 7 (roaming): C:\Users\<username>\AppData\Roaming\<AppAuthor>\<AppName> + + For Unix, we follow the XDG spec and support $XDG_DATA_HOME. + That means, by default "~/.local/share/<AppName>". + """ + if system == "win32": + if appauthor is None: + appauthor = appname + const = roaming and "CSIDL_APPDATA" or "CSIDL_LOCAL_APPDATA" + path = os.path.normpath(_get_win_folder(const)) + if appname: + if appauthor is not False: + path = os.path.join(path, appauthor, appname) + else: + path = os.path.join(path, appname) + elif system == 'darwin': + path = os.path.expanduser('~/Library/Application Support/') + if appname: + path = os.path.join(path, appname) + else: + path = os.getenv('XDG_DATA_HOME', os.path.expanduser("~/.local/share")) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +def site_data_dir(appname=None, appauthor=None, version=None, multipath=False): + r"""Return full path to the user-shared data dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "multipath" is an optional parameter only applicable to *nix + which indicates that the entire list of data dirs should be + returned. By default, the first item from XDG_DATA_DIRS is + returned, or '/usr/local/share/<AppName>', + if XDG_DATA_DIRS is not set + + Typical site data directories are: + Mac OS X: /Library/Application Support/<AppName> + Unix: /usr/local/share/<AppName> or /usr/share/<AppName> + Win XP: C:\Documents and Settings\All Users\Application Data\<AppAuthor>\<AppName> + Vista: (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.) + Win 7: C:\ProgramData\<AppAuthor>\<AppName> # Hidden, but writeable on Win 7. + + For Unix, this is using the $XDG_DATA_DIRS[0] default. + + WARNING: Do not use this on Windows. See the Vista-Fail note above for why. + """ + if system == "win32": + if appauthor is None: + appauthor = appname + path = os.path.normpath(_get_win_folder("CSIDL_COMMON_APPDATA")) + if appname: + if appauthor is not False: + path = os.path.join(path, appauthor, appname) + else: + path = os.path.join(path, appname) + elif system == 'darwin': + path = os.path.expanduser('/Library/Application Support') + if appname: + path = os.path.join(path, appname) + else: + # XDG default for $XDG_DATA_DIRS + # only first, if multipath is False + path = os.getenv('XDG_DATA_DIRS', + os.pathsep.join(['/usr/local/share', '/usr/share'])) + pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)] + if appname: + if version: + appname = os.path.join(appname, version) + pathlist = [os.sep.join([x, appname]) for x in pathlist] + + if multipath: + path = os.pathsep.join(pathlist) + else: + path = pathlist[0] + return path + + if appname and version: + path = os.path.join(path, version) + return path + + +def user_config_dir(appname=None, appauthor=None, version=None, roaming=False): + r"""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. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "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 config directories are: + Mac OS X: same as user_data_dir + Unix: ~/.config/<AppName> # or in $XDG_CONFIG_HOME, if defined + 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 system in ["win32", "darwin"]: + path = user_data_dir(appname, appauthor, None, roaming) + else: + path = os.getenv('XDG_CONFIG_HOME', os.path.expanduser("~/.config")) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +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. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "multipath" is an optional parameter only applicable to *nix + which indicates that the entire list of config dirs should be + returned. By default, the first item from XDG_CONFIG_DIRS is + returned, or '/etc/xdg/<AppName>', if XDG_CONFIG_DIRS is not set + + Typical site config directories are: + Mac OS X: same as site_data_dir + Unix: /etc/xdg/<AppName> or $XDG_CONFIG_DIRS[i]/<AppName> for each value in + $XDG_CONFIG_DIRS + Win *: same as site_data_dir + Vista: (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.) + + For Unix, this is using the $XDG_CONFIG_DIRS[0] default, if multipath=False + + WARNING: Do not use this on Windows. See the Vista-Fail note above for why. + """ + if system in ["win32", "darwin"]: + path = site_data_dir(appname, appauthor) + if appname and version: + path = os.path.join(path, version) + else: + # XDG default for $XDG_CONFIG_DIRS + # 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)] + if appname: + if version: + appname = os.path.join(appname, version) + pathlist = [os.sep.join([x, appname]) for x in pathlist] + + if multipath: + path = os.pathsep.join(pathlist) + else: + path = pathlist[0] + return path + + +def user_cache_dir(appname=None, appauthor=None, version=None, opinion=True): + r"""Return full path to the user-specific cache dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "opinion" (boolean) can be False to disable the appending of + "Cache" to the base app data dir for Windows. See + discussion below. + + Typical user cache directories are: + Mac OS X: ~/Library/Caches/<AppName> + Unix: ~/.cache/<AppName> (XDG default) + Win XP: C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>\Cache + Vista: C:\Users\<username>\AppData\Local\<AppAuthor>\<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` above). 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. + This can be disabled with the `opinion=False` option. + """ + if system == "win32": + if appauthor is None: + appauthor = appname + path = os.path.normpath(_get_win_folder("CSIDL_LOCAL_APPDATA")) + if appname: + if appauthor is not False: + path = os.path.join(path, appauthor, appname) + else: + path = os.path.join(path, appname) + if opinion: + path = os.path.join(path, "Cache") + elif system == 'darwin': + path = os.path.expanduser('~/Library/Caches') + if appname: + path = os.path.join(path, appname) + else: + path = os.getenv('XDG_CACHE_HOME', os.path.expanduser('~/.cache')) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +def user_state_dir(appname=None, appauthor=None, version=None, roaming=False): + r"""Return full path to the user-specific state dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "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 state directories are: + Mac OS X: same as user_data_dir + Unix: ~/.local/state/<AppName> # or in $XDG_STATE_HOME, if defined + Win *: same as user_data_dir + + For Unix, we follow this Debian proposal <https://wiki.debian.org/XDGBaseDirectorySpecification#state> + to extend the XDG spec and support $XDG_STATE_HOME. + + That means, by default "~/.local/state/<AppName>". + """ + if system in ["win32", "darwin"]: + path = user_data_dir(appname, appauthor, None, roaming) + else: + path = os.getenv('XDG_STATE_HOME', os.path.expanduser("~/.local/state")) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +def user_log_dir(appname=None, appauthor=None, version=None, opinion=True): + r"""Return full path to the user-specific log dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "opinion" (boolean) can be False to disable the appending of + "Logs" to the base app data dir for Windows, and "log" to the + base cache dir for Unix. See discussion below. + + Typical user log directories are: + Mac OS X: ~/Library/Logs/<AppName> + Unix: ~/.cache/<AppName>/log # or under $XDG_CACHE_HOME if defined + Win XP: C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>\Logs + Vista: C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName>\Logs + + On Windows the only suggestion in the MSDN docs is that local settings + go in the `CSIDL_LOCAL_APPDATA` directory. (Note: I'm interested in + examples of what some windows apps use for a logs dir.) + + OPINION: This function appends "Logs" to the `CSIDL_LOCAL_APPDATA` + value for Windows and appends "log" to the user cache dir for Unix. + This can be disabled with the `opinion=False` option. + """ + if system == "darwin": + path = os.path.join( + os.path.expanduser('~/Library/Logs'), + appname) + elif system == "win32": + path = user_data_dir(appname, appauthor, version) + version = False + if opinion: + path = os.path.join(path, "Logs") + else: + path = user_cache_dir(appname, appauthor, version) + version = False + if opinion: + path = os.path.join(path, "log") + if appname and version: + path = os.path.join(path, version) + return path + + +class AppDirs(object): + """Convenience wrapper for getting application dirs.""" + def __init__(self, appname=None, appauthor=None, version=None, + roaming=False, multipath=False): + self.appname = appname + self.appauthor = appauthor + self.version = version + self.roaming = roaming + self.multipath = multipath + + @property + def user_data_dir(self): + return user_data_dir(self.appname, self.appauthor, + version=self.version, roaming=self.roaming) + + @property + def site_data_dir(self): + return site_data_dir(self.appname, self.appauthor, + version=self.version, multipath=self.multipath) + + @property + def user_config_dir(self): + return user_config_dir(self.appname, self.appauthor, + version=self.version, roaming=self.roaming) + + @property + def site_config_dir(self): + return site_config_dir(self.appname, self.appauthor, + version=self.version, multipath=self.multipath) + + @property + def user_cache_dir(self): + return user_cache_dir(self.appname, self.appauthor, + version=self.version) + + @property + def user_state_dir(self): + return user_state_dir(self.appname, self.appauthor, + version=self.version) + + @property + def user_log_dir(self): + return user_log_dir(self.appname, self.appauthor, + version=self.version) + + +#---- internal support stuff + +def _get_win_folder_from_registry(csidl_name): + """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. + """ + if PY3: + import winreg as _winreg + else: + 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" + ) + dir, type = _winreg.QueryValueEx(key, shell_folder_name) + return dir + + +def _get_win_folder_with_pywin32(csidl_name): + from win32com.shell import shellcon, shell + dir = shell.SHGetFolderPath(0, getattr(shellcon, csidl_name), 0, 0) + # Try to make this a unicode path because SHGetFolderPath does + # not return unicode strings when there is unicode data in the + # path. + try: + dir = unicode(dir) + + # 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 dir: + if ord(c) > 255: + has_high_char = True + break + if has_high_char: + try: + import win32api + dir = win32api.GetShortPathName(dir) + except ImportError: + pass + except UnicodeError: + pass + return dir + + +def _get_win_folder_with_ctypes(csidl_name): + import ctypes + + 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 + +def _get_win_folder_with_jna(csidl_name): + import array + from com.sun import jna + from com.sun.jna.platform import win32 + + buf_size = win32.WinDef.MAX_PATH * 2 + buf = array.zeros('c', buf_size) + shell = win32.Shell32.INSTANCE + shell.SHGetFolderPath(None, getattr(win32.ShlObj, csidl_name), None, win32.ShlObj.SHGFP_TYPE_CURRENT, buf) + dir = jna.Native.toString(buf.tostring()).rstrip("\0") + + # 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 dir: + if ord(c) > 255: + has_high_char = True + break + if has_high_char: + buf = array.zeros('c', buf_size) + kernel = win32.Kernel32.INSTANCE + if kernel.GetShortPathName(dir, buf, buf_size): + dir = jna.Native.toString(buf.tostring()).rstrip("\0") + + return dir + +if system == "win32": + try: + from ctypes import windll + _get_win_folder = _get_win_folder_with_ctypes + except ImportError: + try: + import com.sun.jna + _get_win_folder = _get_win_folder_with_jna + except ImportError: + _get_win_folder = _get_win_folder_from_registry + + +#---- self test code + +if __name__ == "__main__": + appname = "MyApp" + appauthor = "MyCompany" + + props = ("user_data_dir", + "user_config_dir", + "user_cache_dir", + "user_state_dir", + "user_log_dir", + "site_data_dir", + "site_config_dir") + + print("-- app dirs %s --" % __version__) + + print("-- app dirs (with optional 'version')") + dirs = AppDirs(appname, appauthor, version="1.0") + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) + + print("\n-- app dirs (without optional 'version')") + dirs = AppDirs(appname, appauthor) + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) + + print("\n-- app dirs (without optional 'appauthor')") + dirs = AppDirs(appname) + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) + + print("\n-- app dirs (with disabled 'appauthor')") + dirs = AppDirs(appname, appauthor=False) + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__init__.py new file mode 100644 index 0000000..8fdee66 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__init__.py @@ -0,0 +1,11 @@ +"""CacheControl import Interface. + +Make it easy to import from cachecontrol without long namespaces. +""" +__author__ = "Eric Larson" +__email__ = "eric@ionrock.org" +__version__ = "0.12.5" + +from .wrapper import CacheControl +from .adapter import CacheControlAdapter +from .controller import CacheController diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6be5e8c1034742c9bc1ed1520aa34c9cb0a5b38c GIT binary patch literal 558 zcmYjN&2AGh5Z=w-CfigX^~lB79J)?h6{v)&mZ}FN-~y)=lI5(O#KeCZJDYZ&ffwPG z_R5J@=!x0TN*Qa$-#7A%znPE6$9aPG>&@avktWHXj=We8!3}zNk3l45BGNJyy|O3z zWnT=$P!G(o9Ht54ksg_>%=S3bV>2lyh{xZO*`!(A@oFvaoQ>c#QN}xn<dcmOmb{Wh zo`2yRNmL|~hes0K%abKIL#nQ}dam86xOUq}w6iN>xskzRhfw6r(LJb&eC80GZC*<x zH_BOX)uwQ;YDV+o?7X=Aiz6npw4EL*LVj|{Zw2?L4b!g<(^|sUS>9%h30E=J=8W+z z$^pa^#-!m&BRpcPmJslBB-swQ_Y$C6Wt;K;ouS{c{COzs3j<92PGE}HK0MXbgQ|Iy zwB|sUP7CZw&6-wco?SIpKj*uPrD($2iyF=!Vq@lLD@(squl%X9A#$xxFW)WJo9$xN pCHIcftZ+aNmr5B^Rz=1N|JaT{7$>$`UU!N@r)QAvPj8w|(|<uMsks0E literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9b492579c0fe038cf80a19398d2a9da075d15510 GIT binary patch literal 1561 zcmZ`(OOM+&5GE;El4aTJrbUrHkh*CP@gb|UL0cp!f+m}yIRr-0-CTqMg4SegIeL|( zoy2fXn`84IyvP0}UVG|a=&3W5b{hl;0g@kw56yh@jUEh#A%XViXQ#g(^a%MI7Z=R| z@Dp_P0tQYvEl7ehD`?3QMiD!OQ@V+3v0L;?FYzqy6@D2cfyG|YFT*4R?DOC?Nd~;n zLzp8z;1SG2KITI{dQFp&IN%4*nABo)M&LX>Cesi8fv=O<l$t<_Kh{EN1^C0GY`zpn zb){up+~--Ng#>f|VLsP(3l?5cFBaB3x-S>&QdIiaOe!Jg_#!q69iu#guCBwN$)0Mq za?U9wn(f_l@(OLe9YG5x;18WmJqc716DXk{i;XCZk6+5Gh3P%~`N5N4%<x!Ck(H0K ziWfqfFyp+#;FiB^&3_R&glGPhaU=6hrbWETWc;))xR5F?m+}0YCcU%0v%2;C_EWx9 z-{0QIZ(rzbc?;U2icjJuZ*Jz5(pgd5{O*U-<+Jta0*$t(8&UCE#&aZU-Vzn3^O7Gn zFU=5KUpHyzc7)-3Fc2EifXV|vmmD!z;GX5^9so@=J%ijp_CX78TwsXp9bk&?=-%ZH za0S}1*zGV`^>#G%c9_rJ>}2YgfpsetI$J0cLQe9m$hW{%e<{{7S2~|>{iW8;-8kL` z2o#{HFEL%x#Q_~N{;^OhuPf6l>vg3~*hPx8kK1qjZ<#XVXRTI@tKgzdKs$`^wZTH@ z6gS|-D_~G)C6v)I3xJvkM)?U?F3CXwp);18&jDz129nv46$OGAcitcsWY5k~I_}Ik zYgufso-D=W$#0J*x}IqHasqmoSYJUM?ot%Z)R9QJi9k4M)@j#-4XPK{SOK10$#+8t zFa$hu4Ib!{>d_IEU%+~f{$fKGFa17&Me8>v)~1m`1W*L8n0B!ccXZX;dpoxBp$Bbx z!O};|IhBue$mtmrNEHBLh-|4iv#o!G^5b7_hqGF@LGsDn8`FXH$C7Cra9Mr|PFUf| zj{%ucn>#5~Q&&nDzpH)Y$n1Hy%hL;E4=SkAAS)Lmmsjxx7w^8yj$3AV^)+m(F${!y z)N>-obFMfe8ZvnUF9vCfr_vNleJlgC4WOzHyNa^HOD1nw4z07D&JH_;S*0e|-h0g6 zu}V(9djFxeZb8l6F9+gl^N#vx`9eXqY+kruWu-{dw_?ZtjI;_5ek^OgF2p@lf<meT U7BP@Eh&yruFNgv!{3xLR0YwIlssI20 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..abddab57cb7dec1688f4074ffcae64561c375545 GIT binary patch literal 3044 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 USpfYoR{{M10&UiYjHPY;2OiB6G5`Po literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..009e067ed0c5a53ddd85a0f1e1c0cf5565661285 GIT binary patch literal 1774 zcma)7OK;Oa5Z<*N$8nps6j6kD$Ok}*M3eGXC4@=~LX}X&O9DkmmgC*DZvA4{2{g(H zdPM49phy0aublV`oS0eHNgAQTT08q1?|d`!jlEf~+XULT%iRw*bV7dOqHG3CHlWLU zAQ<ToMwu4UNb6{nJSR+N#vx$_*T3o=1J)I0!rJ5ptShYghBT~U*M7Up9pCdoCfz;m zXU>zC+fFYLP7tLbk9eE~@lK&3n+|F--t+ol<^<C5oNQNckJ-}eaVLmZBOWE<z+r)( z1xf6QgQoop(2)ksjTec(@8hCu8ca5z%Ud8g=}>S&LnjVNM=#)ai~=?SW)|$5tOmgC zyte5{zJ<7byapSN6#5o)iDApgSMmieg%@ZW5S(u(*>>p_XU~L4L_^CB$-`c*@AHEn zL{#Cu-?Ej8VBlrEHSk2MmxPQ9*@|{s{_WIVAFl7MeY)FYL;2wDK-~G94Wl(^J8|o6 zD-F`sAeNaIhO74<c6ayt-5uOi-5v0lC8DLm?I&?2lCW4b(}P^!;TfWq${#wck3DR{ ziLb*EHXP6LQXnlFx~RY)Ob~fx;DvpzJS&8SySn6A9VUM<2Pgj>)WV!LF*j?+WIW^< zUz#$tH1VuB^wA+~IF6k|M^2KbE^W}l3Z`hvk%}KClAnjo(v`)@{pzgUsOFaI#$Lo- zH@96kN?1R{`Mm3X?0aExB5HW?9Ey1q7@a9^lvxa&z!cy_qOdee$4Bk@urY3^wgFu> zL5%5bGmYto6bKH~20|OmWK|d|%wjb~a0+~#%WF@eh7`fur;>r}*uq;^Kp?|M#HAye zE(AE!O1A3)6>}qmqRS2DWnQC5QeF$<Aak)or<_xifEcMW_Y&TZ;V0Ch!{srOW~p!r z5h^M~3osdxJ@Os!FmkLFb*Bl;jSB7w1Vzgk<Ldk>D3(dAPpr<;AM>OP-aIjQv_jD^ z{jQDZNDJsOrQ{uO=M{NP-j^JLnpj34h$c7tDa3?N*NMR5n?;3eaG+13F@<ZkPR6+K zdxn8Hx&pW;BHK5`wG!dK(dlWDo)s&k=XFGd^^G~Q>2PThucD~%n^zT>6S0T_D^OfO zF~jpoJxwTn4)iWUKcTp70L2Y~yX}UVS6!DSKGaXG`252kqM(~u{6kbNDDA0ujxW!x SM@0cXM&>9V3_7nbE&c)KT39mx literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/compat.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9a486bb004c461d6d891a0bf1fe8201f3cdb7eaa GIT binary patch literal 765 zcmZ`#&59F25bmCz&1`lOgQo@e;7N$EGtr>S!XhFFdRZ0?sEsg8dOFE$dZyd%p18>~ z?2GsW-h7Zb34-7&c(UeaV^*++uCA)@t8c37MX%RIVAuDiAHP}%{iu=~^B{N*NB;!3 z9waEi9A%hbjNYOAzJr*x?5Yt))mNi-gML7{^&YK#s9D@0F0hYUHrcW*?h?0UR@ye- z%Q~cUOZ$4uwz=1!I~@++&$^_0tK-|Y!{G-F+ID!%Cq0<t5GLuv+}|4}yF+>nBeCA1 zq5BKoiiWuC6pCMpG(U&fe>It0ykT03T(c@qbu^O^<wCP$I4FJK@^l)=SZStUji@|$ zok^k0OQnP=J-}<M?9hvpE;%drWPOuBrZR|DEKh_A6#G;#Z8QkcWjtp(XoSarG(T51 zh?Aq;rhh5q;V$}r$-<;uIhEYuZo`dS1;Y~Zl!}Cv`-WYa$gCxV=W)iGciGygFG%%4 zq;|heC{?<O4GUMX3TJ{ROzALNg!GY&PB*8QqtD}6ve8e+EA{xwY_bv9JP#)!jBuRh z+Qgh6KRKB$mc?{l73<UPC!{f5Fe-AR1P`gmWNZStF1@o%Bn4;BFbtv}fV1!b_wilZ Q!am%6x6Q4;br0%)03yxMtpET3 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4bf269cec8706d8cb79affaa4d32649b64425e7d GIT binary patch literal 7644 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 N(eNW`uGzX(`9F3+7wG^1 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..893722fc99334ba4805dc29aca356fcbfcbfec6c GIT binary patch literal 2162 zcmZ`)&2Aev5GJ`RX}y+R_b+wQAZ2rkfW%4@v_*ilaGWMZFYdts(h3C#YRR?MUhS&n zO0op?WFPww_OY+D*P@5KLQkFHO15KcDR9W;42R!0oT2tMHbMgJ&(Hh6{j)~M-}td= zK1_C@TMj}IMN=}QJxa-sL^0)^5#?!i>h(P3ACOMt9axbLEn9oDLffByj_`ZcJecf4 zw|gKo=}|>`Oi|eDJoS9#tHv4WHB?izU~H;Dt-;t*AE<TJKBK)rZKzFHSyLgLwpD)o zQl@ENM#ry{RKGQHG}1;+C?O$-b}$4jpH|CUntYroE_poSdH+a91)mO*XuzilSQT1x zJ<(=X43g}S8!Z)2vLffwx$2MOSeu7jf`{oqXS^85g2!+wPb`np+-k4~kLXLE=xAJM zI4WAggY{wnd$e;F<yoP#!ty+>{8Zj|LZ^KJ9%NCNqz^tUz}9?Z@{<G(065@-0}XA` z8RB#ZDmKgQZw3yKw3d%8>>ui3UmIH?kX+^CK7e*EY?OoZ2SRjs3VhMu$mlpZ;TCvX zhbGGlJXS_gq5w1SnQ=RiDxX3uu5j*D#PEi(;mDxBgl@M%6y%gFh@cA!k}ViWPZ797 zy5I2)nwGak&1DJ!u_?FfRq?32SFc&cz2lX>)oENZunktLe-VQT|L?3jGRZ_1x;v4k z8|Nv6)pm!2ZuHeiJexl|dOUp^tGWH=>BKxaDdxk+&<?Zio9-wXJxVf*;du1*xBbEK zxPOR?u8WDzRBpPFj0PI-+T>{$FKU^IJEK_{2$5t-A;cC&s0o75fHvv;ZcPw&R>lzq z3LC~3yNmB9Fj<gusLc!d2P-H<m!2|+E!#H@&~;e3CB&gFF0)FAvbFr~c%}t5rJu>6 zHUUgsY$~yin)S=QLVOAf7M}#N7Sj0_^;nmlg@~XKUBeMwJGei<WY%7gBXR@}z;SRu zd{VIE&~Qrd_bbWRFJu-t3-40<{dKLPj^1m?9c1WmmzytERrAW2+?36#EIZUOyh&>l zf@(!P5|!1L;KqIgf>1`=Y?C$_qXCZo{C+*p>)YR>iUD#|IZTj-xrO%wGkVT0$OXKf z3abHRRRNyC3^2H_3?O_HnU3}U;BHocpMdQ$Z<=(gHNR7f(Q(_aPn(BJaOY5zm^c8B zoqG$0@BprVLCgaf8y9dV3rr^{)usz~>ErWQ!EH=UQt0x2eH~s8k-_9yrJE;*Md>S9 z$Q$=!Zh_TzNY4Ey(Kh@7xQO|79YMrV&u$l7VCXN|QALlL;R~i%H6Eb;CgbPtG4}S~ zVZ~V#8{vw5D6EXNxQv1M4Acf+x$6|oZCtp60-0PDl(`F^ub|sa5Cr&bc|KdRyjREa z>O8!I5FZb$R;c1oh+(eADbCwM{63cHQqvMb<&hAk4QCj9Wv&pq7&{o(pgE9O@CF|i uOhtz;2z?ebf_Cs>upS0Z2QPNXlDvAgo7JC>Q`C7YgXa}OsNZEI+unbCUKlX| literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7714175c55e117c5859c688fd4d119b0c275696b GIT binary patch literal 4682 zcmb7ITW=f372X@k6-CLiqFkN06T3o7!6GeRVnj6xJB|~lwdKZ^k(Ma1SaOEqTFYH# zW~d860RiOpsqs_$QWSyp*q>3L4+UEE2kc`D6!24@`qHO<XO^Ty!D&$fb9Qb!bLN~g z-}#mw&CQi9{C;(=`SX9Av8=ySWBl__xrL&hLvV}RvDL_*cEd*7iJh+7aJyc^>lPXX zo5tL@*ey1S-BP23w%73aSzh49XLe(Tm$?7TYLq{<_zW*Uvv^s|9=eSR+OxcZc12Xs zo<n<%&!atW+Vg0i;R|RlnD!ZNKenoiFQJpQQFXI&JC)r~^H7UyrWZ;jOtmtp26|9+ zGM{>N)Wsx{T*NvYyuBP=V#}N@H`(&f*z&#g<p=A_kJ+aWHd_v@j~_j$+(A)G5JS6H z*47LA$U3lx_RxCMf;#p_)sY2^X2rg4CFw49ESNnqk2e0jCCSeJ-mCXyw1bZNPAKc` zH0DC8dbd+=t@VNr2OmDYynD6H2kL{XJMzk&9&|6`x0Td4>%FMA8YN1HalCr{Mzgcs zZ*EbiDZ!3Ncq;3yu+<T*G|@7R>mAXTk<w91)q49`MeOw=DT1)Ag`B0skb5n=V#^Ai zEt^{S(UT5h&bx?;wzU1i8CoygBkRaMB;(_>o+P7Wek+WzbttnUS#_(MTUYmcv8dXa z!?ihgE@;<maqNdcr$I-AFu(%(m9e)i&!XN!nf$2#7K-{Vgs>>^8V<L)gHUq0%RM|j z6Jl1Qz)R51&*nY~mAE%P{*)`}c;;wydJ{=b_&z$zZ1j61bYCVcWIJITakjR%$96-R zM9CJ*wWWc+U|gt{jGEN1JAxU@PZkOJ)4tMOk!V#bPkJ{oPYTsb6D3%rSWl)q5f_~4 zG-dE>x;x%Vu{hcmY;Eo8<mHamz4dw>Q)5+&gl^YTxmEAzZd{k`){QGyuU%B4rK2=i zy<WRsyT*1qLJGDkSRw?UETdC~K!~GOq~m?2!u=_Y(j6h$m20e%_N8Ko&f4U~!P{$V zm)R=2@aV(|9wQvZ1>;==yr)Fm&iwHaPkX*Jvf~@%P2=vF!Ru3=s*PrRyT>AP*#`f7 z(xWgkmLG37a*txWk?ycC*~h_m$DJp<u<>y7?mFA-zyXi%J$!QiW0-z7+*d40T5+EX zrqZrpUrhU4rxQcuaiXHFBx>(NgHTVau^Xy98aQjxIASA?5DAx9lIl~dU;?&gY1_=3 z#6uov2%T|Ijw~!+gXtuJ&}rMw_l-eD7fQW9F>z_|?zD-gCr&I)*MW+;8@Euwg$L9f z*$2+hkvE6-Qvw0!$hK+3H6!lO<<|Dhc$C{iH^Lj3K_KC5WTlZ6ffnTStTZ|pK+>oy zUq>$nC&y}>$p`rOAdRI_NQ^oHbNNo6z7Y0$@%{=HQ}Ym(U3NSGTiN#Q1!wTuv;oZA zjcPITgCGgJA_%f_5Oh=CkEvb>f-n1FoR1g<jqdUttb1Z#LURM7k}#57qKXi{<Inmt zrtj4#_7)}`qZkm(;jTe24<;*Qvkw#TakzhnaD4E<_}|p0LkwY)#|oiOn9z*|v@5p8 zIHD;^XtsH`-3OS7JdP%=CUhrVjjJD_5?Kd8RJhpMF3AmTYTS9-I<ya5?P!CtU)$Ov zck{w8F!J2u#jl+MPZx&Xp*_UgH!WVm)4ypA9h_ta&L3$dXRyUf!d)Z;B*T66l6J4! zW*{r}`c1&mV6H`HUL7T`YEhD<q)USGlcaY{hBYaoS~w1xd?xK8zeB>f=GZ?Jc{fo; zq2W1Yd)_{e@bK-yJ15Lto4y$v*y0>5_b!R|AhJ>r@U#^Kc|aU*bG+AiO#1-E<W}GF z97#Q|j)d=H<kgYD3y27iCSJm`$bGVBR=Jxy`8MV6!4FP^#>xtE$I1$T{L8*jS}_nJ z79v5lqlA(R@-piQ8KomMpQL)iU^4KJQ4}R%ZMAWCpM%r{NVC}1&>CZTAH$$HbW<~D zd-s%)=`KY{q=Vo-t!2R79=v{1<=S}0Bo1k7DtG7=^0o%FJO#rza5SLi(55W^JBlWE zLtex<_9q9Q4iz^K5YjM@4fjNBd|O03#Ox6RD%*o|Q<_c(!j!&rGNUiy3^(8iovk;> zSkA^^J<pN1`#J?BjX;i&WKCdm<CSGqW0U;ZjkY?PHIZ;Ai{d^Q8=p`<^K`ctpE9+9 zq{qkFd-h;yO8XIDZd6OB;#U%blHVgicOu8OS4HtMMn6SSq>%4=j_>-Oq}~?F<VSSw z7K&PjI33B{a5AF&MD~f`cV@xU46#RS8$yrRJ`1}oW|jM)(hpJ|wIh)CKaA<vXC^Iz z#2{5CDI1+~OvA!hf<5kEVr^KNHN)06OA|&bt&W#6m!z-89Bo2~SzD%EGx&e7s%y0? zwJYW&a42}T)sKmSgt&L1N|Ue|i<}ycxW*@d<aW9TcA-+nQ@}G33*8}Y47)=W98k!K zA`1MDiyaZC=&g0rK@`WKp?M-%ee$>t@KN<IM6-TxbMq(lJHSh<6?}60^T`TWAl{pP zb+pW?6fyJ^bp>kI67@vrT_LyeIg;wMMPCcxm-R&5!($ww_h8>ztJk}D^}`!xizkUu ze6%ES%Q)&r#D8!SSmnyK)sD=w&C5R_C|>@V#9v7K6(YI>&qk{xeof*xBz{Zc8xsG5 zm|QlB%MyyYY=1+A(vwM3&UR5Q5)b463Dj4Rc94>|yY0#q>L;#(OX(n)t($os=9Scs zc!8dBgZi}lf|8fRJxX(6Ij%0ERWM1<B)V;14Tm21jW544Z<Jn?@X1%uJ}(XnL-#G~ z&^ag$U0P}A9ocVL2PGQQGs6-uowK-q=wOCF^oPZ5TmI2#<_`Tgt%DhE>(Yy|o`tLo zXO8S6CnCl)v+*i?Gtg&p<zOzR=mu3W7e&He)=M%}^wsCKRh=`5Fe?I1bYErf8Qh_; z44V4^vO(C7b&wAVCFk&-BovcG`%Iz*-q824+YR?1q9pT`mTlALZ+`aRZt%&2&8)c9 zrJiaz&jlXQ@8b;IFe(z8GAd>+K83T{R$odm;2_)*2IR8EHeTx_La88*+UB$TTXS~@ z>Zuh7%Pu;;?Kw**6_f>(MdWdM`pD_?_7ZYB)d%NJ0?MhxJ_#|xax$R_F*3p^<r%;o z<vMu-{jWmcU!s4U=a!~+`ycpwnHK!-_*=!4pVImUe`h`C9oIiEsh1M+LhiaXG_zUJ z4Wqc$*HNs@2YF7Ij7N#)<*eyC)eMQEuj{OsHlN~4(U4TbPYkr1^-rACBnI=v?%#wv fL5_b&#xj3___psXISY>GmJ7bOaAD!>!rA`-h{0Im literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..db97d42b75a98f891457777c0455b5f4a5d7dfcb GIT binary patch literal 4246 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 KF>86YXa5^(jH~1T literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aa57466cbace17aa393768d7f93b181185b5c1c2 GIT binary patch literal 666 zcmYjP%Z}496t(m23yRnvu}8{c@W2SrAcSDbx*NKxkSaI!Gyx~EY_|iEyMiTr1F+<m zyk*5Nu;MzM5xv$uI`@&A<C|PeCPM`F_5S+Z_W+^aKDe<I$SZLD0DvKe1*-89W6uK- z)ZsD&p0b!FU+^+w;aikve=s!X*xjAcqU5u-F{%}>8I^`BNDtmrh3QN4MUg?Pw*k24 zGjM$YV6n^$`i%D2CUR=<KCy|#Hn5?MY;048za{(3q8|YZZ1yw2sORAg2O-fskKL&7 zB39hcjdnxLRYgVBapeXj->OQRs&LcdpiywODg@Qq-RYmAYr$7FH)YFomzKuJ=Y({b zCmL8Dst}YaSQ>J1-EJF`4_u@<42b&yD)RN%L*l`&(@p4M6^B<Te`}Xs=YAn|3*x_9 zB2~4chLast<gyivD^2Q>6p!TUygPq?dUbZmI{ox)ryhSaU406+X~=@eN}g1WHdKg{ zC(qX9hwXaflfAEYykV^(y}0X3lPg7~<m#dP<i@k3FXm<IdjM!O#2F5bP8N*uI8all v<>`De_m;<M0&%|$HS(-qj_>L3bOg5{=du@d%eI2Q^nZ)?Z7?%N`2YC_>I$X} literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/_cmd.py b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/_cmd.py new file mode 100644 index 0000000..f1e0ad9 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/_cmd.py @@ -0,0 +1,57 @@ +import logging + +from pip._vendor import requests + +from pip._vendor.cachecontrol.adapter import CacheControlAdapter +from pip._vendor.cachecontrol.cache import DictCache +from pip._vendor.cachecontrol.controller import logger + +from argparse import ArgumentParser + + +def setup_logging(): + logger.setLevel(logging.DEBUG) + handler = logging.StreamHandler() + logger.addHandler(handler) + + +def get_session(): + adapter = CacheControlAdapter( + DictCache(), cache_etags=True, serializer=None, heuristic=None + ) + sess = requests.Session() + sess.mount("http://", adapter) + sess.mount("https://", adapter) + + sess.cache_controller = adapter.controller + return sess + + +def get_args(): + parser = ArgumentParser() + parser.add_argument("url", help="The URL to try and cache") + return parser.parse_args() + + +def main(args=None): + args = get_args() + sess = get_session() + + # Make a request to get a response + resp = sess.get(args.url) + + # Turn on logging + setup_logging() + + # try setting the cache + sess.cache_controller.cache_response(resp.request, resp.raw) + + # Now try to get it + if sess.cache_controller.cached_request(resp.request): + print("Cached!") + else: + print("Not cached :(") + + +if __name__ == "__main__": + main() diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/adapter.py b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/adapter.py new file mode 100644 index 0000000..780eb28 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/adapter.py @@ -0,0 +1,133 @@ +import types +import functools +import zlib + +from pip._vendor.requests.adapters import HTTPAdapter + +from .controller import CacheController +from .cache import DictCache +from .filewrapper import CallbackFileWrapper + + +class CacheControlAdapter(HTTPAdapter): + invalidating_methods = {"PUT", "DELETE"} + + def __init__( + self, + cache=None, + cache_etags=True, + controller_class=None, + serializer=None, + heuristic=None, + cacheable_methods=None, + *args, + **kw + ): + super(CacheControlAdapter, self).__init__(*args, **kw) + self.cache = cache or DictCache() + self.heuristic = heuristic + self.cacheable_methods = cacheable_methods or ("GET",) + + controller_factory = controller_class or CacheController + self.controller = controller_factory( + self.cache, cache_etags=cache_etags, serializer=serializer + ) + + def send(self, request, cacheable_methods=None, **kw): + """ + Send a request. Use the request information to see if it + exists in the cache and cache the response if we need to and can. + """ + cacheable = cacheable_methods or self.cacheable_methods + if request.method in cacheable: + try: + cached_response = self.controller.cached_request(request) + except zlib.error: + cached_response = None + if cached_response: + return self.build_response(request, cached_response, from_cache=True) + + # check for etags and add headers if appropriate + request.headers.update(self.controller.conditional_headers(request)) + + resp = super(CacheControlAdapter, self).send(request, **kw) + + return resp + + def build_response( + self, request, response, from_cache=False, cacheable_methods=None + ): + """ + Build a response by making a request or using the cache. + + This will end up calling send and returning a potentially + cached response + """ + cacheable = cacheable_methods or self.cacheable_methods + if not from_cache and request.method in cacheable: + # Check for any heuristics that might update headers + # before trying to cache. + if self.heuristic: + response = self.heuristic.apply(response) + + # apply any expiration heuristics + if response.status == 304: + # We must have sent an ETag request. This could mean + # that we've been expired already or that we simply + # have an etag. In either case, we want to try and + # update the cache if that is the case. + cached_response = self.controller.update_cached_response( + request, response + ) + + if cached_response is not response: + from_cache = True + + # We are done with the server response, read a + # possible response body (compliant servers will + # not return one, but we cannot be 100% sure) and + # release the connection back to the pool. + response.read(decode_content=False) + response.release_conn() + + response = cached_response + + # We always cache the 301 responses + elif response.status == 301: + self.controller.cache_response(request, response) + else: + # Wrap the response file with a wrapper that will cache the + # response when the stream has been consumed. + response._fp = CallbackFileWrapper( + response._fp, + functools.partial( + self.controller.cache_response, request, response + ), + ) + if response.chunked: + super_update_chunk_length = response._update_chunk_length + + def _update_chunk_length(self): + super_update_chunk_length() + if self.chunk_left == 0: + self._fp._close() + + response._update_chunk_length = types.MethodType( + _update_chunk_length, response + ) + + resp = super(CacheControlAdapter, self).build_response(request, response) + + # See if we should invalidate the cache. + if request.method in self.invalidating_methods and resp.ok: + cache_url = self.controller.cache_url(request.url) + self.cache.delete(cache_url) + + # Give the request a from_cache attr to let people use it + resp.from_cache = from_cache + + return resp + + def close(self): + self.cache.close() + super(CacheControlAdapter, self).close() diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/cache.py b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/cache.py new file mode 100644 index 0000000..94e0773 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/cache.py @@ -0,0 +1,39 @@ +""" +The cache object API for implementing caches. The default is a thread +safe in-memory dictionary. +""" +from threading import Lock + + +class BaseCache(object): + + def get(self, key): + raise NotImplementedError() + + def set(self, key, value): + raise NotImplementedError() + + def delete(self, key): + raise NotImplementedError() + + def close(self): + pass + + +class DictCache(BaseCache): + + def __init__(self, init_dict=None): + self.lock = Lock() + self.data = init_dict or {} + + def get(self, key): + return self.data.get(key, None) + + def set(self, key, value): + with self.lock: + self.data.update({key: value}) + + def delete(self, key): + with self.lock: + if key in self.data: + self.data.pop(key) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__init__.py new file mode 100644 index 0000000..0e1658f --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__init__.py @@ -0,0 +1,2 @@ +from .file_cache import FileCache # noqa +from .redis_cache import RedisCache # noqa diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3c303f2fe86119f2e242f79f934c5a764dbd6568 GIT binary patch literal 302 zcmXv}O-jTt6i(Vfoa&rFFVMx9(LrTEL=;@Q(80wZgtkei(fpBQsusL~7x7Bny7CIH ze5v}ud++;sgqO?7BtwArz4GB6=4TZDNPt{G`F&^%F)We7D~uygWTMhl3Ov0-`REJ7 zN{;*SwUGR(s2UC;yX8#yLEYq|KC2<4RSaExy5Dgz|8r7sK9JjjF|_YDVx4G<z)4#; zQX9#*^F%eII<$1rEgomj^O|-3WZt@?m(ZyhV6DlLSYf9^`%p+ZJw7d)r%kzz=1{cd mni)riJ1V1tGxAq>LaERqP<mir`|UGj*hcd6_%k2x-NiqJoKtiF literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c3c5626cd9b37f3ce4588865ab04d3be5f76c0cf GIT binary patch literal 3236 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 X$ln3tQ4d~cRp<<6HK;dUqrUfF%jNe0 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..13896334be9cb01028f53e35676f847f6e0782cb GIT binary patch literal 1558 zcmaJ>Pmj|^6rVq~;|&R$3Is)!=v3ko31SLr0SQqANVJz63RSD9$ntt78-rtqnQ?ZB zj8us|_Csur{Yt*}#8>Ev_r^&#U7?ONGtcwp`S*VB&phe(y9CCcUmg7Z8z<y%{MZf; zgvT(=eOM%sG$(U9p%i77vpJhEC-a=oy@^N3b0R(IpAhLQ?*pIsGI&9TosVEmhO`M~ zw#-ac7EVsAve{gLy!RwA>S>bBREjsZ1H5U`AAz9Agi11Dl1g?$CR}pq!S2b6GLW4U z3Rt1sgOfmZ<ptO~vM2knhtdZh_M7g{N@k`-VH*hCaXy7<Fbp-VNet}3f{wv6FD;8= z$QsY6e5wPu@fXn{Z2$ZbEp)a74$(5v(X`B^(k7bEqV(HE{9yIq_3fj(Q@JwV-(BiE z$96Tp4dbwgUPg;-aVsl~P4fKKclQovZ>obsJajW&szR1JN?kO{!s;?_KTM>NK<qT5 z#k(eq<E+SR9Pgp`juKs6I%7H7>eF4i7*t2M2SQC=lT%vLHEjtqN3r3D$_|<Cz>S8# zQSTh%c0nwC0Twjhf?nJK1=Degb%O(U44MOc2tv)x<t=E<)=)jgjhb6_%Gcye@}4`L zS5xcP{4`jT4-{^3tg+U?&c;EbtVSkHP}#I7j~X9N)N#YJ!Zv+dLU3cFAbHXZJx4^N z!;Qa8@=7%wb-c*5GUti);m$rxgDED|qXX8Xt6h2k^Z9TNz+lU4?K<Q?Aq}L;!NW~d zoipdbFT)?Mz}!ali=C*p)+q%w4ooP<*2VP(2*=l3>@|5tUJc$u6+>bfCYF-7y<eeo z!5g;v=|`0>lor!ci!@h>&Wb|;btvpi2}raNSs@Z36Pp}BOOC`ZMv0@$&bneV(xkG` zz~79AyiJ9NW*U9}A8w8B(5}HP<7$Hs=xVUT&#C{Vhct0IdU${1{twPVR7M$rjj2-f zMJ&oP2O>8`QHnw-DQpSsN^l)%on0J_UC4*DEeOo<Sy7{lVDdE_wh3V890Vo4347Rg zMKV`$+;ro3Udk#*xfjQ8t0ZqV8s8GvCK^l1g-2s<^;KNXke%du$_E8DoWVK`S;#}) z?Z6sn)QpD#qD?DXX+YCh0ImTh*Wu+DZC;I0y7OwZ9~#5we(^cfCVbcuc!c3L*s49K H_#XcRLS9+P literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py new file mode 100644 index 0000000..1ba0080 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py @@ -0,0 +1,146 @@ +import hashlib +import os +from textwrap import dedent + +from ..cache import BaseCache +from ..controller import CacheController + +try: + FileNotFoundError +except NameError: + # py2.X + FileNotFoundError = (IOError, OSError) + + +def _secure_open_write(filename, fmode): + # We only want to write to this file, so open it in write only mode + flags = os.O_WRONLY + + # os.O_CREAT | os.O_EXCL will fail if the file already exists, so we only + # will open *new* files. + # We specify this because we want to ensure that the mode we pass is the + # mode of the file. + flags |= os.O_CREAT | os.O_EXCL + + # Do not follow symlinks to prevent someone from making a symlink that + # we follow and insecurely open a cache file. + if hasattr(os, "O_NOFOLLOW"): + flags |= os.O_NOFOLLOW + + # On Windows we'll mark this file as binary + if hasattr(os, "O_BINARY"): + flags |= os.O_BINARY + + # Before we open our file, we want to delete any existing file that is + # there + try: + os.remove(filename) + except (IOError, OSError): + # The file must not exist already, so we can just skip ahead to opening + pass + + # Open our file, the use of os.O_CREAT | os.O_EXCL will ensure that if a + # race condition happens between the os.remove and this line, that an + # error will be raised. Because we utilize a lockfile this should only + # happen if someone is attempting to attack us. + fd = os.open(filename, flags, fmode) + try: + return os.fdopen(fd, "wb") + + except: + # An error occurred wrapping our FD in a file object + os.close(fd) + raise + + +class FileCache(BaseCache): + + def __init__( + self, + directory, + forever=False, + filemode=0o0600, + dirmode=0o0700, + use_dir_lock=None, + lock_class=None, + ): + + if use_dir_lock is not None and lock_class is not None: + 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 + except ImportError: + notice = dedent( + """ + NOTE: In order to use the FileCache you must have + lockfile installed. You can install it via pip: + pip install lockfile + """ + ) + raise ImportError(notice) + + else: + if use_dir_lock: + lock_class = MkdirLockFile + + elif lock_class is None: + lock_class = LockFile + + self.directory = directory + self.forever = forever + self.filemode = filemode + self.dirmode = dirmode + self.lock_class = lock_class + + @staticmethod + def encode(x): + return hashlib.sha224(x.encode()).hexdigest() + + def _fn(self, name): + # NOTE: This method should not change as some may depend on it. + # See: https://github.com/ionrock/cachecontrol/issues/63 + hashed = self.encode(name) + parts = list(hashed[:5]) + [hashed] + return os.path.join(self.directory, *parts) + + def get(self, key): + name = self._fn(key) + try: + with open(name, "rb") as fh: + return fh.read() + + except FileNotFoundError: + return None + + def set(self, key, value): + name = self._fn(key) + + # Make sure the directory exists + try: + os.makedirs(os.path.dirname(name), self.dirmode) + except (IOError, OSError): + pass + + with self.lock_class(name) as lock: + # Write our actual file + with _secure_open_write(lock.path, self.filemode) as fh: + fh.write(value) + + def delete(self, key): + name = self._fn(key) + if not self.forever: + try: + os.remove(name) + except FileNotFoundError: + pass + + +def url_to_file_path(url, filecache): + """Return the file cache path based on the URL. + + This does not ensure the file exists! + """ + key = CacheController.cache_url(url) + return filecache._fn(key) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py new file mode 100644 index 0000000..ed705ce --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py @@ -0,0 +1,33 @@ +from __future__ import division + +from datetime import datetime +from pip._vendor.cachecontrol.cache import BaseCache + + +class RedisCache(BaseCache): + + def __init__(self, conn): + self.conn = conn + + def get(self, key): + return self.conn.get(key) + + def set(self, key, value, expires=None): + if not expires: + self.conn.set(key, value) + else: + expires = expires - datetime.utcnow() + self.conn.setex(key, int(expires.total_seconds()), value) + + def delete(self, key): + self.conn.delete(key) + + def clear(self): + """Helper for clearing all the keys in a database. Use with + caution!""" + for key in self.conn.keys(): + self.conn.delete(key) + + def close(self): + """Redis uses connection pooling, no need to close the connection.""" + pass diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/compat.py b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/compat.py new file mode 100644 index 0000000..33b5aed --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/compat.py @@ -0,0 +1,29 @@ +try: + from urllib.parse import urljoin +except ImportError: + from urlparse import urljoin + + +try: + import cPickle as pickle +except ImportError: + import pickle + + +# Handle the case where the requests module has been patched to not have +# urllib3 bundled as part of its source. +try: + from pip._vendor.requests.packages.urllib3.response import HTTPResponse +except ImportError: + from pip._vendor.urllib3.response import HTTPResponse + +try: + from pip._vendor.requests.packages.urllib3.util import is_fp_closed +except ImportError: + from pip._vendor.urllib3.util import is_fp_closed + +# Replicate some six behaviour +try: + text_type = unicode +except NameError: + text_type = str diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/controller.py b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/controller.py new file mode 100644 index 0000000..1b2b943 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/controller.py @@ -0,0 +1,367 @@ +""" +The httplib2 algorithms ported for use with requests. +""" +import logging +import re +import calendar +import time +from email.utils import parsedate_tz + +from pip._vendor.requests.structures import CaseInsensitiveDict + +from .cache import DictCache +from .serialize import Serializer + + +logger = logging.getLogger(__name__) + +URI = re.compile(r"^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?") + + +def parse_uri(uri): + """Parses a URI using the regex given in Appendix B of RFC 3986. + + (scheme, authority, path, query, fragment) = parse_uri(uri) + """ + groups = URI.match(uri).groups() + return (groups[1], groups[3], groups[4], groups[6], groups[8]) + + +class CacheController(object): + """An interface to see if request should cached or not. + """ + + def __init__( + self, cache=None, cache_etags=True, serializer=None, status_codes=None + ): + self.cache = cache or DictCache() + self.cache_etags = cache_etags + self.serializer = serializer or Serializer() + self.cacheable_status_codes = status_codes or (200, 203, 300, 301) + + @classmethod + def _urlnorm(cls, uri): + """Normalize the URL to create a safe key for the cache""" + (scheme, authority, path, query, fragment) = parse_uri(uri) + if not scheme or not authority: + raise Exception("Only absolute URIs are allowed. uri = %s" % uri) + + scheme = scheme.lower() + authority = authority.lower() + + if not path: + path = "/" + + # Could do syntax based normalization of the URI before + # computing the digest. See Section 6.2.2 of Std 66. + request_uri = query and "?".join([path, query]) or path + defrag_uri = scheme + "://" + authority + request_uri + + return defrag_uri + + @classmethod + def cache_url(cls, uri): + return cls._urlnorm(uri) + + def parse_cache_control(self, headers): + known_directives = { + # https://tools.ietf.org/html/rfc7234#section-5.2 + "max-age": (int, True), + "max-stale": (int, False), + "min-fresh": (int, True), + "no-cache": (None, False), + "no-store": (None, False), + "no-transform": (None, False), + "only-if-cached": (None, False), + "must-revalidate": (None, False), + "public": (None, False), + "private": (None, False), + "proxy-revalidate": (None, False), + "s-maxage": (int, True), + } + + cc_headers = headers.get("cache-control", headers.get("Cache-Control", "")) + + retval = {} + + for cc_directive in cc_headers.split(","): + if not cc_directive.strip(): + continue + + parts = cc_directive.split("=", 1) + directive = parts[0].strip() + + try: + typ, required = known_directives[directive] + except KeyError: + logger.debug("Ignoring unknown cache-control directive: %s", directive) + continue + + if not typ or not required: + retval[directive] = None + if typ: + try: + retval[directive] = typ(parts[1].strip()) + except IndexError: + if required: + logger.debug( + "Missing value for cache-control " "directive: %s", + directive, + ) + except ValueError: + logger.debug( + "Invalid value for cache-control directive " "%s, must be %s", + directive, + typ.__name__, + ) + + return retval + + def cached_request(self, request): + """ + Return a cached response if it exists in the cache, otherwise + return False. + """ + cache_url = self.cache_url(request.url) + logger.debug('Looking up "%s" in the cache', cache_url) + cc = self.parse_cache_control(request.headers) + + # Bail out if the request insists on fresh data + if "no-cache" in cc: + logger.debug('Request header has "no-cache", cache bypassed') + return False + + if "max-age" in cc and cc["max-age"] == 0: + logger.debug('Request header has "max_age" as 0, cache bypassed') + return False + + # Request allows serving from the cache, let's see if we find something + cache_data = self.cache.get(cache_url) + if cache_data is None: + logger.debug("No cache entry available") + return False + + # Check whether it can be deserialized + resp = self.serializer.loads(request, cache_data) + if not resp: + logger.warning("Cache entry deserialization failed, entry ignored") + return False + + # If we have a cached 301, return it immediately. We don't + # need to test our response for other headers b/c it is + # intrinsically "cacheable" as it is Permanent. + # See: + # https://tools.ietf.org/html/rfc7231#section-6.4.2 + # + # Client can try to refresh the value by repeating the request + # with cache busting headers as usual (ie no-cache). + if resp.status == 301: + msg = ( + 'Returning cached "301 Moved Permanently" response ' + "(ignoring date and etag information)" + ) + logger.debug(msg) + return resp + + headers = CaseInsensitiveDict(resp.headers) + if not headers or "date" not in headers: + if "etag" not in headers: + # Without date or etag, the cached response can never be used + # and should be deleted. + logger.debug("Purging cached response: no date or etag") + self.cache.delete(cache_url) + logger.debug("Ignoring cached response: no date") + return False + + now = time.time() + date = calendar.timegm(parsedate_tz(headers["date"])) + current_age = max(0, now - date) + logger.debug("Current age based on date: %i", current_age) + + # TODO: There is an assumption that the result will be a + # urllib3 response object. This may not be best since we + # could probably avoid instantiating or constructing the + # response until we know we need it. + resp_cc = self.parse_cache_control(headers) + + # determine freshness + freshness_lifetime = 0 + + # Check the max-age pragma in the cache control header + if "max-age" in resp_cc: + freshness_lifetime = resp_cc["max-age"] + logger.debug("Freshness lifetime from max-age: %i", freshness_lifetime) + + # If there isn't a max-age, check for an expires header + elif "expires" in headers: + expires = parsedate_tz(headers["expires"]) + if expires is not None: + expire_time = calendar.timegm(expires) - date + freshness_lifetime = max(0, expire_time) + logger.debug("Freshness lifetime from expires: %i", freshness_lifetime) + + # Determine if we are setting freshness limit in the + # request. Note, this overrides what was in the response. + if "max-age" in cc: + freshness_lifetime = cc["max-age"] + logger.debug( + "Freshness lifetime from request max-age: %i", freshness_lifetime + ) + + if "min-fresh" in cc: + min_fresh = cc["min-fresh"] + # adjust our current age by our min fresh + current_age += min_fresh + logger.debug("Adjusted current age from min-fresh: %i", current_age) + + # Return entry if it is fresh enough + if freshness_lifetime > current_age: + logger.debug('The response is "fresh", returning cached response') + logger.debug("%i > %i", freshness_lifetime, current_age) + return resp + + # we're not fresh. If we don't have an Etag, clear it out + if "etag" not in headers: + logger.debug('The cached response is "stale" with no etag, purging') + self.cache.delete(cache_url) + + # return the original handler + return False + + def conditional_headers(self, request): + cache_url = self.cache_url(request.url) + resp = self.serializer.loads(request, self.cache.get(cache_url)) + new_headers = {} + + if resp: + headers = CaseInsensitiveDict(resp.headers) + + if "etag" in headers: + new_headers["If-None-Match"] = headers["ETag"] + + if "last-modified" in headers: + new_headers["If-Modified-Since"] = headers["Last-Modified"] + + return new_headers + + def cache_response(self, request, response, body=None, status_codes=None): + """ + Algorithm for caching requests. + + This assumes a requests Response object. + """ + # From httplib2: Don't cache 206's since we aren't going to + # handle byte range requests + cacheable_status_codes = status_codes or self.cacheable_status_codes + if response.status not in cacheable_status_codes: + logger.debug( + "Status code %s not in %s", response.status, cacheable_status_codes + ) + return + + response_headers = CaseInsensitiveDict(response.headers) + + # If we've been given a body, our response has a Content-Length, that + # Content-Length is valid then we can check to see if the body we've + # been given matches the expected size, and if it doesn't we'll just + # skip trying to cache it. + if ( + body is not None + and "content-length" in response_headers + and response_headers["content-length"].isdigit() + and int(response_headers["content-length"]) != len(body) + ): + return + + cc_req = self.parse_cache_control(request.headers) + cc = self.parse_cache_control(response_headers) + + cache_url = self.cache_url(request.url) + logger.debug('Updating cache with response from "%s"', cache_url) + + # Delete it from the cache if we happen to have it stored there + no_store = False + if "no-store" in cc: + no_store = True + logger.debug('Response header has "no-store"') + if "no-store" in cc_req: + no_store = True + logger.debug('Request header has "no-store"') + if no_store and self.cache.get(cache_url): + logger.debug('Purging existing cache entry to honor "no-store"') + self.cache.delete(cache_url) + if no_store: + 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") + self.cache.set( + cache_url, self.serializer.dumps(request, response, body=body) + ) + + # Add to the cache any 301s. We do this before looking that + # the Date headers. + elif response.status == 301: + logger.debug("Caching permanant redirect") + self.cache.set(cache_url, self.serializer.dumps(request, response)) + + # Add to the cache if the response headers demand it. If there + # is no date header then we can't do anything about expiring + # the cache. + elif "date" in response_headers: + # cache when there is a max-age > 0 + if "max-age" in cc and cc["max-age"] > 0: + logger.debug("Caching b/c date exists and max-age > 0") + self.cache.set( + cache_url, self.serializer.dumps(request, response, body=body) + ) + + # If the request can expire, it means we should cache it + # in the meantime. + elif "expires" in response_headers: + if response_headers["expires"]: + logger.debug("Caching b/c of expires header") + self.cache.set( + cache_url, self.serializer.dumps(request, response, body=body) + ) + + def update_cached_response(self, request, response): + """On a 304 we will get a new set of headers that we want to + update our cached value with, assuming we have one. + + This should only ever be called when we've sent an ETag and + gotten a 304 as the response. + """ + cache_url = self.cache_url(request.url) + + cached_response = self.serializer.loads(request, self.cache.get(cache_url)) + + if not cached_response: + # we didn't have a cached response + return response + + # Lets update our headers with the headers from the new request: + # http://tools.ietf.org/html/draft-ietf-httpbis-p4-conditional-26#section-4.1 + # + # The server isn't supposed to send headers that would make + # the cached body invalid. But... just in case, we'll be sure + # to strip out ones we know that might be problmatic due to + # typical assumptions. + excluded_headers = ["content-length"] + + cached_response.headers.update( + dict( + (k, v) + for k, v in response.headers.items() + if k.lower() not in excluded_headers + ) + ) + + # we want a 200 b/c we have content via the cache + cached_response.status = 200 + + # update our cache + self.cache.set(cache_url, self.serializer.dumps(request, cached_response)) + + return cached_response diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/filewrapper.py b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/filewrapper.py new file mode 100644 index 0000000..30ed4c5 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/filewrapper.py @@ -0,0 +1,80 @@ +from io import BytesIO + + +class CallbackFileWrapper(object): + """ + Small wrapper around a fp object which will tee everything read into a + buffer, and when that file is closed it will execute a callback with the + contents of that buffer. + + All attributes are proxied to the underlying file object. + + This class uses members with a double underscore (__) leading prefix so as + not to accidentally shadow an attribute. + """ + + def __init__(self, fp, callback): + self.__buf = BytesIO() + self.__fp = fp + self.__callback = callback + + def __getattr__(self, name): + # The vaguaries of garbage collection means that self.__fp is + # not always set. By using __getattribute__ and the private + # name[0] allows looking up the attribute value and raising an + # AttributeError when it doesn't exist. This stop thigns from + # infinitely recursing calls to getattr in the case where + # self.__fp hasn't been set. + # + # [0] https://docs.python.org/2/reference/expressions.html#atom-identifiers + fp = self.__getattribute__("_CallbackFileWrapper__fp") + return getattr(fp, name) + + def __is_fp_closed(self): + try: + return self.__fp.fp is None + + except AttributeError: + pass + + try: + return self.__fp.closed + + except AttributeError: + pass + + # We just don't cache it then. + # TODO: Add some logging here... + return False + + def _close(self): + if self.__callback: + self.__callback(self.__buf.getvalue()) + + # We assign this to None here, because otherwise we can get into + # really tricky problems where the CPython interpreter dead locks + # because the callback is holding a reference to something which + # has a __del__ method. Setting this to None breaks the cycle + # and allows the garbage collector to do it's thing normally. + self.__callback = None + + def read(self, amt=None): + data = self.__fp.read(amt) + self.__buf.write(data) + if self.__is_fp_closed(): + self._close() + + return data + + def _safe_read(self, amt): + data = self.__fp._safe_read(amt) + if amt == 2 and data == b"\r\n": + # urllib executes this read to toss the CRLF at the end + # of the chunk. + return data + + self.__buf.write(data) + if self.__is_fp_closed(): + self._close() + + return data diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/heuristics.py b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/heuristics.py new file mode 100644 index 0000000..6c0e979 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/heuristics.py @@ -0,0 +1,135 @@ +import calendar +import time + +from email.utils import formatdate, parsedate, parsedate_tz + +from datetime import datetime, timedelta + +TIME_FMT = "%a, %d %b %Y %H:%M:%S GMT" + + +def expire_after(delta, date=None): + date = date or datetime.utcnow() + return date + delta + + +def datetime_to_header(dt): + return formatdate(calendar.timegm(dt.timetuple())) + + +class BaseHeuristic(object): + + def warning(self, response): + """ + Return a valid 1xx warning header value describing the cache + adjustments. + + The response is provided too allow warnings like 113 + http://tools.ietf.org/html/rfc7234#section-5.5.4 where we need + to explicitly say response is over 24 hours old. + """ + return '110 - "Response is Stale"' + + def update_headers(self, response): + """Update the response headers with any new headers. + + NOTE: This SHOULD always include some Warning header to + signify that the response was cached by the client, not + by way of the provided headers. + """ + return {} + + def apply(self, response): + updated_headers = self.update_headers(response) + + if updated_headers: + response.headers.update(updated_headers) + warning_header_value = self.warning(response) + if warning_header_value is not None: + response.headers.update({"Warning": warning_header_value}) + + return response + + +class OneDayCache(BaseHeuristic): + """ + Cache the response by providing an expires 1 day in the + future. + """ + + def update_headers(self, response): + headers = {} + + if "expires" not in response.headers: + date = parsedate(response.headers["date"]) + expires = expire_after(timedelta(days=1), date=datetime(*date[:6])) + headers["expires"] = datetime_to_header(expires) + headers["cache-control"] = "public" + return headers + + +class ExpiresAfter(BaseHeuristic): + """ + Cache **all** requests for a defined time period. + """ + + def __init__(self, **kw): + self.delta = timedelta(**kw) + + def update_headers(self, response): + expires = expire_after(self.delta) + return {"expires": datetime_to_header(expires), "cache-control": "public"} + + def warning(self, response): + tmpl = "110 - Automatically cached for %s. Response might be stale" + return tmpl % self.delta + + +class LastModified(BaseHeuristic): + """ + If there is no Expires header already, fall back on Last-Modified + using the heuristic from + http://tools.ietf.org/html/rfc7234#section-4.2.2 + to calculate a reasonable value. + + Firefox also does something like this per + https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching_FAQ + http://lxr.mozilla.org/mozilla-release/source/netwerk/protocol/http/nsHttpResponseHead.cpp#397 + Unlike mozilla we limit this to 24-hr. + """ + cacheable_by_default_statuses = { + 200, 203, 204, 206, 300, 301, 404, 405, 410, 414, 501 + } + + def update_headers(self, resp): + headers = resp.headers + + if "expires" in headers: + return {} + + if "cache-control" in headers and headers["cache-control"] != "public": + return {} + + if resp.status not in self.cacheable_by_default_statuses: + return {} + + if "date" not in headers or "last-modified" not in headers: + return {} + + date = calendar.timegm(parsedate_tz(headers["date"])) + last_modified = parsedate(headers["last-modified"]) + if date is None or last_modified is None: + return {} + + now = time.time() + current_age = max(0, now - date) + delta = date - calendar.timegm(last_modified) + freshness_lifetime = max(0, min(delta / 10, 24 * 3600)) + if freshness_lifetime <= current_age: + return {} + + expires = date + freshness_lifetime + return {"expires": time.strftime(TIME_FMT, time.gmtime(expires))} + + def warning(self, resp): + return None diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/serialize.py b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/serialize.py new file mode 100644 index 0000000..ec43ff2 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/serialize.py @@ -0,0 +1,186 @@ +import base64 +import io +import json +import zlib + +from pip._vendor import msgpack +from pip._vendor.requests.structures import CaseInsensitiveDict + +from .compat import HTTPResponse, pickle, text_type + + +def _b64_decode_bytes(b): + return base64.b64decode(b.encode("ascii")) + + +def _b64_decode_str(s): + return _b64_decode_bytes(s).decode("utf8") + + +class Serializer(object): + + def dumps(self, request, response, body=None): + response_headers = CaseInsensitiveDict(response.headers) + + if body is None: + body = response.read(decode_content=False) + + # NOTE: 99% sure this is dead code. I'm only leaving it + # here b/c I don't have a test yet to prove + # it. Basically, before using + # `cachecontrol.filewrapper.CallbackFileWrapper`, + # this made an effort to reset the file handle. The + # `CallbackFileWrapper` short circuits this code by + # setting the body as the content is consumed, the + # result being a `body` argument is *always* passed + # into cache_response, and in turn, + # `Serializer.dump`. + response._fp = io.BytesIO(body) + + # NOTE: This is all a bit weird, but it's really important that on + # Python 2.x these objects are unicode and not str, even when + # they contain only ascii. The problem here is that msgpack + # understands the difference between unicode and bytes and we + # have it set to differentiate between them, however Python 2 + # doesn't know the difference. Forcing these to unicode will be + # enough to have msgpack know the difference. + data = { + u"response": { + u"body": body, + u"headers": dict( + (text_type(k), text_type(v)) for k, v in response.headers.items() + ), + u"status": response.status, + u"version": response.version, + u"reason": text_type(response.reason), + u"strict": response.strict, + u"decode_content": response.decode_content, + } + } + + # Construct our vary headers + data[u"vary"] = {} + if u"vary" in response_headers: + varied_headers = response_headers[u"vary"].split(",") + for header in varied_headers: + header = text_type(header).strip() + header_value = request.headers.get(header, None) + if header_value is not None: + header_value = text_type(header_value) + data[u"vary"][header] = header_value + + return b",".join([b"cc=4", msgpack.dumps(data, use_bin_type=True)]) + + def loads(self, request, data): + # Short circuit if we've been given an empty set of data + if not data: + return + + # Determine what version of the serializer the data was serialized + # with + try: + ver, data = data.split(b",", 1) + except ValueError: + ver = b"cc=0" + + # Make sure that our "ver" is actually a version and isn't a false + # positive from a , being in the data stream. + if ver[:3] != b"cc=": + data = ver + data + ver = b"cc=0" + + # Get the version number out of the cc=N + ver = ver.split(b"=", 1)[-1].decode("ascii") + + # Dispatch to the actual load method for the given version + try: + return getattr(self, "_loads_v{}".format(ver))(request, data) + + except AttributeError: + # This is a version we don't have a loads function for, so we'll + # just treat it as a miss and return None + return + + def prepare_response(self, request, cached): + """Verify our vary headers match and construct a real urllib3 + HTTPResponse object. + """ + # Special case the '*' Vary value as it means we cannot actually + # determine if the cached response is suitable for this request. + if "*" in cached.get("vary", {}): + return + + # Ensure that the Vary headers for the cached response match our + # request + for header, value in cached.get("vary", {}).items(): + if request.headers.get(header, None) != value: + return + + body_raw = cached["response"].pop("body") + + headers = CaseInsensitiveDict(data=cached["response"]["headers"]) + if headers.get("transfer-encoding", "") == "chunked": + headers.pop("transfer-encoding") + + cached["response"]["headers"] = headers + + try: + body = io.BytesIO(body_raw) + except TypeError: + # This can happen if cachecontrol serialized to v1 format (pickle) + # using Python 2. A Python 2 str(byte string) will be unpickled as + # a Python 3 str (unicode string), which will cause the above to + # fail with: + # + # TypeError: 'str' does not support the buffer interface + body = io.BytesIO(body_raw.encode("utf8")) + + return HTTPResponse(body=body, preload_content=False, **cached["response"]) + + def _loads_v0(self, request, data): + # The original legacy cache data. This doesn't contain enough + # information to construct everything we need, so we'll treat this as + # a miss. + return + + def _loads_v1(self, request, data): + try: + cached = pickle.loads(data) + except ValueError: + return + + return self.prepare_response(request, cached) + + def _loads_v2(self, request, data): + try: + cached = json.loads(zlib.decompress(data).decode("utf8")) + except (ValueError, zlib.error): + return + + # We need to decode the items that we've base64 encoded + cached["response"]["body"] = _b64_decode_bytes(cached["response"]["body"]) + cached["response"]["headers"] = dict( + (_b64_decode_str(k), _b64_decode_str(v)) + for k, v in cached["response"]["headers"].items() + ) + cached["response"]["reason"] = _b64_decode_str(cached["response"]["reason"]) + cached["vary"] = dict( + (_b64_decode_str(k), _b64_decode_str(v) if v is not None else v) + for k, v in cached["vary"].items() + ) + + return self.prepare_response(request, cached) + + def _loads_v3(self, request, data): + # Due to Python 2 encoding issues, it's impossible to know for sure + # exactly how to load v3 entries, thus we'll treat these as a miss so + # that they get rewritten out as v4 entries. + return + + def _loads_v4(self, request, data): + try: + cached = msgpack.loads(data, encoding="utf-8") + except ValueError: + return + + return self.prepare_response(request, cached) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/wrapper.py b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/wrapper.py new file mode 100644 index 0000000..265bfc8 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/wrapper.py @@ -0,0 +1,29 @@ +from .adapter import CacheControlAdapter +from .cache import DictCache + + +def CacheControl( + sess, + cache=None, + cache_etags=True, + serializer=None, + heuristic=None, + controller_class=None, + adapter_class=None, + cacheable_methods=None, +): + + cache = cache or DictCache() + adapter_class = adapter_class or CacheControlAdapter + adapter = adapter_class( + cache, + cache_etags=cache_etags, + serializer=serializer, + heuristic=heuristic, + controller_class=controller_class, + cacheable_methods=cacheable_methods, + ) + sess.mount("http://", adapter) + sess.mount("https://", adapter) + + return sess diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/certifi/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/certifi/__init__.py new file mode 100644 index 0000000..aa329fb --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/certifi/__init__.py @@ -0,0 +1,3 @@ +from .core import where, old_where + +__version__ = "2018.08.24" diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/certifi/__main__.py b/venv/lib/python3.7/site-packages/pip/_vendor/certifi/__main__.py new file mode 100644 index 0000000..ae2aff5 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/certifi/__main__.py @@ -0,0 +1,2 @@ +from pip._vendor.certifi import where +print(where()) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ae561b8f36283f23e86f1aa42a0aff6520073892 GIT binary patch literal 285 zcmXv}OHRWu5Vf6vpr{f{Bu<b;<22>dN{Av3zy?+kl9j|xV~CwFNmIxfxCmFumK9fE z#kdkrnm3;}n$P`oIw6S9^Xz$z{@W%0U>Mw?wP#3@NLmp?6KYt(D3L7jr1wYy|A(R+ zu<>A5Dp2EbT}iPIhe;gGmtnLF<BNyDAN{-r1#T*MNaKkRy@FQPR){YGhfZ+x`^Fp4 zecCDBr@#vwh;7`IJfAmWHLPBu-J*~~d$s5xe(weoAvTsj@kTc@ZQCxbs@dgrR=#et ojVtaAw^>;O&lPmK&|C;@btgpFe2hmork2}E-MVL5cjGDh1LXcp{Qv*} literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/certifi/__pycache__/__main__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/certifi/__pycache__/__main__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bee84afa71c90d979d4abce9823530c050da69ff GIT binary patch literal 268 zcmZ?b<>g`kf*$Fl7*inq7{q}ACLqHBh>N9wL<&O+V-7<uV-zDJLn>1$V>3fDkd?v| z%%I8q5-880$#{#kJR`Lz)lZZ8mT*C4fnI!BYF<iykzR6YQAuW6W)aA|TdV~|nRz8E z8H!keJTURAP#-8(mRORiUzS*;pO&AKl3G-(pPQkdY*-L)S!J1JP;Q)-QdMkbTvlXM zQBsv_00ilI`XTy2TXZw?ic1o6a&%42lQObPlhQ$gU<|chA8NgRe0*+VW?p=}UP0w8 W4x8Nkl+v73J4T=@ia`$JVFUp3K1mt? literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9f816254ad0a10181012abfc568fc8440a0d65b9 GIT binary patch literal 1220 zcmZ`&&2H2%5Vn)-ZZ;}VRYFMg;v;+LrnKUx5<&<NNE|98ijY=FRyOwTx=rF>JG*oR zT*?vNp*`{>yhE;>cm+<(WPgefjO6je8GB~F`R4JJD-i+tvORqJ)F<Qzeyk(_;}I<T z0+b*FBB<~(I-t$&4ZP<>_#*gBL?Hb$e-Mb4Xn!VymgtBO_O|SZ?ulof$xyb=$Qh+X zc&|t=n!k=xX`C9Vet8;wT1yliO_XK17F8yhk*+d@Wo{ywDy&PgEOAN~EYs=2&?A;6 z_)@==c|ZCIX_CVf^-3rhk6_tNP?A9EWZ(%p@S8;Z`o>dP8VS!y@wh5PCf_8cP{nxu zHDVw~5PBw)6J}*v8Rbsdu<>G$<xqkj6YKkZ_A--+m29XXW5Z5$W#FEfs#G?Ql}1mM zfIm*Nv2<8hj<$8WWR=C&QlqWiv1(jM!Hm|<_M5ARy`T;`FOpnxUPqiSAOd@X^LJH} zE&p^l7dqwq8!;UyxKY3IxHM`CCC1al#3P+S4mQpwaeBMt2lIpD-P!&~%<bL%so8t) z=J_tjxQLJ9Qk6SP<ah4e8%|ED;TR8_#iz0m+QiFF#;G<E+G#upd=()_BMh4Fbx*J# zNUJC4a1)dx$MoED{ssNGu!9dkvkRn&cQ}tO+uLi^p0;&RCT>!9gfdt%f-+JWf)X5S zRrF|0N0+6W5F*sA8MH%Q$A}o3&<)RAgMFP89<Gzxf)7W|f#c4*@F;Qq8CfLr{l9FO zBuEEY0A+JMm7>p9^aikb6aH2YIaBBvOA3}`3T_~Kms7BGSyQMg1@vn{p;QZrG^v1E zfB83KA(Q{ao2e{=v{p%hGuzv}eZP-fnk{G!c%s$xsKMk9>>2_!0Cv|^Yy&tJ&j<~u z=eIqBaA6nnL=~L(x~2^Wri%(kuHIS=7!2-mw*H8Qw~dc}E#PS3{uw@euweT`eAObg P0vgiL-|U3#up83f{RB)C literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/certifi/cacert.pem b/venv/lib/python3.7/site-packages/pip/_vendor/certifi/cacert.pem new file mode 100644 index 0000000..85de024 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/certifi/cacert.pem @@ -0,0 +1,4300 @@ + +# Issuer: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA +# Subject: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA +# Label: "GlobalSign Root CA" +# Serial: 4835703278459707669005204 +# MD5 Fingerprint: 3e:45:52:15:09:51:92:e1:b7:5d:37:9f:b1:87:29:8a +# SHA1 Fingerprint: b1:bc:96:8b:d4:f4:9d:62:2a:a8:9a:81:f2:15:01:52:a4:1d:82:9c +# SHA256 Fingerprint: eb:d4:10:40:e4:bb:3e:c7:42:c9:e3:81:d3:1e:f2:a4:1a:48:b6:68:5c:96:e7:ce:f3:c1:df:6c:d4:33:1c:99 +-----BEGIN CERTIFICATE----- +MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG +A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv +b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw +MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i +YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT +aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ +jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp +xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp +1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG +snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ +U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8 +9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B +AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz +yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE +38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP +AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad +DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME +HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2 +# Label: "GlobalSign Root CA - R2" +# Serial: 4835703278459682885658125 +# MD5 Fingerprint: 94:14:77:7e:3e:5e:fd:8f:30:bd:41:b0:cf:e7:d0:30 +# SHA1 Fingerprint: 75:e0:ab:b6:13:85:12:27:1c:04:f8:5f:dd:de:38:e4:b7:24:2e:fe +# SHA256 Fingerprint: ca:42:dd:41:74:5f:d0:b8:1e:b9:02:36:2c:f9:d8:bf:71:9d:a1:bd:1b:1e:fc:94:6f:5b:4c:99:f4:2c:1b:9e +-----BEGIN CERTIFICATE----- +MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1 +MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL +v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8 +eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq +tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd +C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa +zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB +mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH +V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n +bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG +3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs +J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO +291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS +ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd +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" +# Serial: 946069240 +# MD5 Fingerprint: ee:29:31:bc:32:7e:9a:e6:e8:b5:f7:51:b4:34:71:90 +# SHA1 Fingerprint: 50:30:06:09:1d:97:d4:f5:ae:39:f7:cb:e7:92:7d:7d:65:2d:34:31 +# SHA256 Fingerprint: 6d:c4:71:72:e0:1c:bc:b0:bf:62:58:0d:89:5f:e2:b8:ac:9a:d4:f8:73:80:1e:0c:10:b9:c8:37:d2:1e:b1:77 +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML +RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp +bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 +IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3 +MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 +LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp +YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG +A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq +K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe +sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX +MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT +XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ +HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH +4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub +j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo +U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf +zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b +u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+ +bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er +fF6adulZkMV8gzURZVE= +-----END CERTIFICATE----- + +# Issuer: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust +# Subject: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust +# Label: "Baltimore CyberTrust Root" +# Serial: 33554617 +# MD5 Fingerprint: ac:b6:94:a5:9c:17:e0:d7:91:52:9b:b1:97:06:a6:e4 +# SHA1 Fingerprint: d4:de:20:d0:5e:66:fc:53:fe:1a:50:88:2c:78:db:28:52:ca:e4:74 +# SHA256 Fingerprint: 16:af:57:a9:f6:76:b0:ab:12:60:95:aa:5e:ba:de:f2:2a:b3:11:19:d6:44:ac:95:cd:4b:93:db:f3:f2:6a:eb +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ +RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD +VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX +DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y +ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy +VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr +mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr +IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK +mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu +XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy +dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye +jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1 +BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3 +DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92 +9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx +jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0 +Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz +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" +# Serial: 1164660820 +# MD5 Fingerprint: d6:a5:c3:ed:5d:dd:3e:00:c1:3d:87:92:1f:1d:3f:e4 +# SHA1 Fingerprint: b3:1e:b1:b7:40:e3:6c:84:02:da:dc:37:d4:4d:f5:d4:67:49:52:f9 +# SHA256 Fingerprint: 73:c1:76:43:4f:1b:c6:d5:ad:f4:5b:0e:76:e7:27:28:7c:8d:e5:76:16:c1:e6:e6:14:1a:2b:2c:bc:7d:8e:4c +-----BEGIN CERTIFICATE----- +MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 +Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW +KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl +cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw +NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw +NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy +ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV +BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo +Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4 +4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9 +KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI +rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi +94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB +sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi +gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo +kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE +vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA +A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t +O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua +AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP +9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/ +eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m +0vdXcDazv/wor3ElhVsT/h5/WrQ8 +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Global CA O=GeoTrust Inc. +# Subject: CN=GeoTrust Global CA O=GeoTrust Inc. +# Label: "GeoTrust Global CA" +# Serial: 144470 +# MD5 Fingerprint: f7:75:ab:29:fb:51:4e:b7:77:5e:ff:05:3c:99:8e:f5 +# SHA1 Fingerprint: de:28:f4:a4:ff:e5:b9:2f:a3:c5:03:d1:a3:49:a7:f9:96:2a:82:12 +# SHA256 Fingerprint: ff:85:6a:2d:25:1d:cd:88:d3:66:56:f4:50:12:67:98:cf:ab:aa:de:40:79:9c:72:2d:e4:d2:b5:db:36:a7:3a +-----BEGIN CERTIFICATE----- +MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i +YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG +EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg +R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9 +9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq +fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv +iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU +1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+ +bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW +MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA +ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l +uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn +Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS +tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF +PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un +hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV +5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw== +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Universal CA O=GeoTrust Inc. +# Subject: CN=GeoTrust Universal CA O=GeoTrust Inc. +# Label: "GeoTrust Universal CA" +# Serial: 1 +# MD5 Fingerprint: 92:65:58:8b:a2:1a:31:72:73:68:5c:b4:a5:7a:07:48 +# SHA1 Fingerprint: e6:21:f3:35:43:79:05:9a:4b:68:30:9d:8a:2f:74:22:15:87:ec:79 +# SHA256 Fingerprint: a0:45:9b:9f:63:b2:25:59:f5:fa:5d:4c:6d:b3:f9:f7:2f:f1:93:42:03:35:78:f0:73:bf:1d:1b:46:cb:b9:12 +-----BEGIN CERTIFICATE----- +MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEW +MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVy +c2FsIENBMB4XDTA0MDMwNDA1MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UE +BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xHjAcBgNVBAMTFUdlb1RydXN0 +IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKYV +VaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9tJPi8 +cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTT +QjOgNB0eRXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFh +F7em6fgemdtzbvQKoiFs7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2v +c7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d8Lsrlh/eezJS/R27tQahsiFepdaVaH/w +mZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7VqnJNk22CDtucvc+081xd +VHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3CgaRr0BHdCX +teGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZ +f9hBZ3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfRe +Bi9Fi1jUIxaS5BZuKGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+ +nhutxx9z3SxPGWX9f5NAEC7S8O08ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB +/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0XG0D08DYj3rWMB8GA1UdIwQY +MBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG +9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc +aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fX +IwjhmF7DWgh2qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzyn +ANXH/KttgCJwpQzgXQQpAvvLoJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0z +uzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsKxr2EoyNB3tZ3b4XUhRxQ4K5RirqN +Pnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxFKyDuSN/n3QmOGKja +QI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2DFKW +koRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9 +ER/frslKxfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQt +DF4JbAiXfKM9fJP/P6EUp8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/Sfuvm +bJxPgWp6ZKy7PtXny3YuxadIwVyQD8vIP/rmMuGNG2+k5o7Y+SlIis5z/iw= +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Universal CA 2 O=GeoTrust Inc. +# Subject: CN=GeoTrust Universal CA 2 O=GeoTrust Inc. +# Label: "GeoTrust Universal CA 2" +# Serial: 1 +# MD5 Fingerprint: 34:fc:b8:d0:36:db:9e:14:b3:c2:f2:db:8f:e4:94:c7 +# SHA1 Fingerprint: 37:9a:19:7b:41:85:45:35:0c:a6:03:69:f3:3c:2e:af:47:4f:20:79 +# SHA256 Fingerprint: a0:23:4f:3b:c8:52:7c:a5:62:8e:ec:81:ad:5d:69:89:5d:a5:68:0d:c9:1d:1c:b8:47:7f:33:f8:78:b9:5b:0b +-----BEGIN CERTIFICATE----- +MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEW +MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVy +c2FsIENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYD +VQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1 +c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0DE81 +WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUG +FF+3Qs17j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdq +XbboW0W63MOhBW9Wjo8QJqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxL +se4YuU6W3Nx2/zu+z18DwPw76L5GG//aQMJS9/7jOvdqdzXQ2o3rXhhqMcceujwb +KNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2WP0+GfPtDCapkzj4T8Fd +IgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP20gaXT73 +y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRt +hAAnZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgoc +QIgfksILAAX/8sgCSqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4 +Lt1ZrtmhN79UNdxzMk+MBB4zsslG8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAfBgNV +HSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8EBAMCAYYwDQYJ +KoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z +dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQ +L1EuxBRa3ugZ4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgr +Fg5fNuH8KrUwJM/gYwx7WBr+mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSo +ag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpqA1Ihn0CoZ1Dy81of398j9tx4TuaY +T1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpgY+RdM4kX2TGq2tbz +GDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiPpm8m +1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJV +OCiNUW7dFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH +6aLcr34YEoP9VhdBLtUpgn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwX +QMAJKOSLakhT2+zNVVXxxvjpoixMptEmX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS +-----END CERTIFICATE----- + +# Issuer: CN=Visa eCommerce Root O=VISA OU=Visa International Service Association +# Subject: CN=Visa eCommerce Root O=VISA OU=Visa International Service Association +# Label: "Visa eCommerce Root" +# Serial: 25952180776285836048024890241505565794 +# MD5 Fingerprint: fc:11:b8:d8:08:93:30:00:6d:23:f9:7e:eb:52:1e:02 +# SHA1 Fingerprint: 70:17:9b:86:8c:00:a4:fa:60:91:52:22:3f:9f:3e:32:bd:e0:05:62 +# SHA256 Fingerprint: 69:fa:c9:bd:55:fb:0a:c7:8d:53:bb:ee:5c:f1:d5:97:98:9f:d0:aa:ab:20:a2:51:51:bd:f1:73:3e:e7:d1:22 +-----BEGIN CERTIFICATE----- +MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBr +MQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRl +cm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv +bW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2WhcNMjIwNjI0MDAxNjEyWjBrMQsw +CQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5h +dGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1l +cmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h +2mCxlCfLF9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4E +lpF7sDPwsRROEW+1QK8bRaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdV +ZqW1LS7YgFmypw23RuwhY/81q6UCzyr0TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq +299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI/k4+oKsGGelT84ATB+0t +vz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzsGHxBvfaL +dXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUF +AAOCAQEAX/FBfXxcCLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcR +zCSs00Rsca4BIGsDoo8Ytyk6feUWYFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3 +LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pzzkWKsKZJ/0x9nXGIxHYdkFsd +7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBuYQa7FkKMcPcw +++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt +398znM/jra6O1I7mT1GvFpLgXPYHDw== +-----END CERTIFICATE----- + +# Issuer: CN=AAA Certificate Services O=Comodo CA Limited +# Subject: CN=AAA Certificate Services O=Comodo CA Limited +# Label: "Comodo AAA Services root" +# Serial: 1 +# MD5 Fingerprint: 49:79:04:b0:eb:87:19:ac:47:b0:bc:11:51:9b:74:d0 +# SHA1 Fingerprint: d1:eb:23:a4:6d:17:d6:8f:d9:25:64:c2:f1:f1:60:17:64:d8:e3:49 +# SHA256 Fingerprint: d7:a7:a0:fb:5d:7e:27:31:d7:71:e9:48:4e:bc:de:f7:1d:5f:0c:3e:0a:29:48:78:2b:c8:3e:e0:ea:69:9e:f4 +-----BEGIN CERTIFICATE----- +MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb +MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow +GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj +YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM +GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua +BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe +3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4 +YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR +rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm +ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU +oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v +QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t +b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF +AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q +GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz +Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2 +G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi +l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 +smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root Certification Authority O=QuoVadis Limited OU=Root Certification Authority +# Subject: CN=QuoVadis Root Certification Authority O=QuoVadis Limited OU=Root Certification Authority +# Label: "QuoVadis Root CA" +# Serial: 985026699 +# MD5 Fingerprint: 27:de:36:fe:72:b7:00:03:00:9d:f4:f0:1e:6c:04:24 +# SHA1 Fingerprint: de:3f:40:bd:50:93:d3:9b:6c:60:f6:da:bc:07:62:01:00:89:76:c9 +# SHA256 Fingerprint: a4:5e:de:3b:bb:f0:9c:8a:e1:5c:72:ef:c0:72:68:d6:93:a2:1c:99:6f:d5:1e:67:ca:07:94:60:fd:6d:88:73 +-----BEGIN CERTIFICATE----- +MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz +MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw +IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR +dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp +li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D +rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ +WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug +F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU +xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC +Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv +dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw +ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl +IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh +c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy +ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh +Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI +KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T +KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq +y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p +dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD +VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL +MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk +fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8 +7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R +cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y +mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW +xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK +SnQ2+Q== +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 2 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 2 O=QuoVadis Limited +# Label: "QuoVadis Root CA 2" +# Serial: 1289 +# MD5 Fingerprint: 5e:39:7b:dd:f8:ba:ec:82:e9:ac:62:ba:0c:54:00:2b +# SHA1 Fingerprint: ca:3a:fb:cf:12:40:36:4b:44:b2:16:20:88:80:48:39:19:93:7c:f7 +# SHA256 Fingerprint: 85:a0:dd:7d:d7:20:ad:b7:ff:05:f8:3d:54:2b:20:9d:c7:ff:45:28:f7:d6:77:b1:83:89:fe:a5:e5:c4:9e:86 +-----BEGIN CERTIFICATE----- +MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa +GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg +Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J +WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB +rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp ++ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1 +ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i +Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz +PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og +/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH +oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI +yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud +EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2 +A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL +MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT +ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f +BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn +g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl +fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K +WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha +B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc +hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR +TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD +mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z +ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y +4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza +8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 3" +# Serial: 1478 +# MD5 Fingerprint: 31:85:3c:62:94:97:63:b9:aa:fd:89:4e:af:6f:e0:cf +# SHA1 Fingerprint: 1f:49:14:f7:d8:74:95:1d:dd:ae:02:c0:be:fd:3a:2d:82:75:51:85 +# SHA256 Fingerprint: 18:f1:fc:7f:20:5d:f8:ad:dd:eb:7f:e0:07:dd:57:e3:af:37:5a:9c:4d:8d:73:54:6b:f4:f1:fe:d1:e1:8d:35 +-----BEGIN CERTIFICATE----- +MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM +V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB +4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr +H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd +8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv +vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT +mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe +btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc +T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt +WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ +c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A +4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD +VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG +CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0 +aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 +aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu +dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw +czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G +A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg +Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0 +7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem +d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd ++LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B +4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN +t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x +DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57 +k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s +zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j +Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT +mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK +4SVhM7JZG+Ju1zdXtg2pEto= +-----END CERTIFICATE----- + +# Issuer: O=SECOM Trust.net OU=Security Communication RootCA1 +# Subject: O=SECOM Trust.net OU=Security Communication RootCA1 +# Label: "Security Communication Root CA" +# Serial: 0 +# MD5 Fingerprint: f1:bc:63:6a:54:e0:b5:27:f5:cd:e7:1a:e3:4d:6e:4a +# SHA1 Fingerprint: 36:b1:2b:49:f9:81:9e:d7:4c:9e:bc:38:0f:c6:56:8f:5d:ac:b2:f7 +# SHA256 Fingerprint: e7:5e:72:ed:9f:56:0e:ec:6e:b4:80:00:73:a4:3f:c3:ad:19:19:5a:39:22:82:01:78:95:97:4a:99:02:6b:6c +-----BEGIN CERTIFICATE----- +MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY +MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t +dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5 +WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD +VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8 +9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ +DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9 +Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N +QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ +xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G +A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T +AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG +kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr +Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5 +Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU +JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot +RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw== +-----END CERTIFICATE----- + +# Issuer: CN=Sonera Class2 CA O=Sonera +# Subject: CN=Sonera Class2 CA O=Sonera +# Label: "Sonera Class 2 Root CA" +# Serial: 29 +# MD5 Fingerprint: a3:ec:75:0f:2e:88:df:fa:48:01:4e:0b:5c:48:6f:fb +# SHA1 Fingerprint: 37:f7:6d:e6:07:7c:90:c5:b1:3e:93:1a:b7:41:10:b4:f2:e4:9a:27 +# SHA256 Fingerprint: 79:08:b4:03:14:c1:38:10:0b:51:8d:07:35:80:7f:fb:fc:f8:51:8a:00:95:33:71:05:ba:38:6b:15:3d:d9:27 +-----BEGIN CERTIFICATE----- +MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP +MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx +MDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV +BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o +Z6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt +5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s +3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej +vOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu +8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw +DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG +MA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil +zqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/ +3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD +FNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6 +Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2 +ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M +-----END CERTIFICATE----- + +# Issuer: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com +# Subject: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com +# Label: "XRamp Global CA Root" +# Serial: 107108908803651509692980124233745014957 +# MD5 Fingerprint: a1:0b:44:b3:ca:10:d8:00:6e:9d:0f:d8:0f:92:0a:d1 +# SHA1 Fingerprint: b8:01:86:d1:eb:9c:86:a5:41:04:cf:30:54:f3:4c:52:b7:e5:58:c6 +# SHA256 Fingerprint: ce:cd:dc:90:50:99:d8:da:df:c5:b1:d2:09:b7:37:cb:e2:c1:8c:fb:2c:10:c0:ff:0b:cf:0d:32:86:fc:1a:a2 +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB +gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk +MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY +UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx +NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3 +dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy +dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6 +38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP +KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q +DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4 +qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa +JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi +PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P +BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs +jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0 +eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD +ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR +vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt +qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa +IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy +i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ +O+7ETPTsJ3xCwnR8gooJybQDJbw= +-----END CERTIFICATE----- + +# Issuer: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority +# Subject: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority +# Label: "Go Daddy Class 2 CA" +# Serial: 0 +# MD5 Fingerprint: 91:de:06:25:ab:da:fd:32:17:0c:bb:25:17:2a:84:67 +# SHA1 Fingerprint: 27:96:ba:e6:3f:18:01:e2:77:26:1b:a0:d7:77:70:02:8f:20:ee:e4 +# SHA256 Fingerprint: c3:84:6b:f2:4b:9e:93:ca:64:27:4c:0e:c6:7c:1e:cc:5e:02:4f:fc:ac:d2:d7:40:19:35:0e:81:fe:54:6a:e4 +-----BEGIN CERTIFICATE----- +MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh +MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE +YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3 +MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo +ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg +MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN +ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA +PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w +wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi +EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY +avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+ +YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE +sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h +/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5 +IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD +ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy +OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P +TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ +HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER +dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf +ReYNnyicsbkqWletNw+vHX/bvZ8= +-----END CERTIFICATE----- + +# Issuer: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority +# Subject: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority +# Label: "Starfield Class 2 CA" +# Serial: 0 +# MD5 Fingerprint: 32:4a:4b:bb:c8:63:69:9b:be:74:9a:c6:dd:1d:46:24 +# SHA1 Fingerprint: ad:7e:1c:28:b0:64:ef:8f:60:03:40:20:14:c3:d0:e3:37:0e:b5:8a +# SHA256 Fingerprint: 14:65:fa:20:53:97:b8:76:fa:a6:f0:a9:95:8e:55:90:e4:0f:cc:7f:aa:4f:b7:c2:c8:67:75:21:fb:5f:b6:58 +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl +MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp +U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw +NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE +ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp +ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3 +DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf +8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN ++lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0 +X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa +K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA +1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G +A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR +zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0 +YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD +bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w +DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3 +L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D +eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl +xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp +VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY +WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q= +-----END CERTIFICATE----- + +# Issuer: O=Government Root Certification Authority +# Subject: O=Government Root Certification Authority +# Label: "Taiwan GRCA" +# Serial: 42023070807708724159991140556527066870 +# MD5 Fingerprint: 37:85:44:53:32:45:1f:20:f0:f3:95:e1:25:c4:43:4e +# SHA1 Fingerprint: f4:8b:11:bf:de:ab:be:94:54:20:71:e6:41:de:6b:be:88:2b:40:b9 +# SHA256 Fingerprint: 76:00:29:5e:ef:e8:5b:9e:1f:d6:24:db:76:06:2a:aa:ae:59:81:8a:54:d2:77:4c:d4:c0:b2:c0:11:31:e1:b3 +-----BEGIN CERTIFICATE----- +MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/ +MQswCQYDVQQGEwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5MB4XDTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1ow +PzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dvdmVybm1lbnQgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +AJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qNw8XR +IePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1q +gQdW8or5BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKy +yhwOeYHWtXBiCAEuTk8O1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAts +F/tnyMKtsc2AtJfcdgEWFelq16TheEfOhtX7MfP6Mb40qij7cEwdScevLJ1tZqa2 +jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wovJ5pGfaENda1UhhXcSTvx +ls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7Q3hub/FC +VGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHK +YS1tB6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoH +EgKXTiCQ8P8NHuJBO9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThN +Xo+EHWbNxWCWtFJaBYmOlXqYwZE8lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1Ud +DgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNVHRMEBTADAQH/MDkGBGcqBwAE +MTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg209yewDL7MTqK +UWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ +TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyf +qzvS/3WXy6TjZwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaK +ZEk9GhiHkASfQlK3T8v+R0F2Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFE +JPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlUD7gsL0u8qV1bYH+Mh6XgUmMqvtg7 +hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6QzDxARvBMB1uUO07+1 +EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+HbkZ6Mm +nD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WX +udpVBrkk7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44Vbnz +ssQwmSNOXfJIoRIM3BKQCZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDe +LMDDav7v3Aun+kbfYNucpllQdSNpc5Oy+fwC00fmcc4QAu4njIT/rEUNE1yDMuAl +pYYsfPQS +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root CA" +# Serial: 17154717934120587862167794914071425081 +# MD5 Fingerprint: 87:ce:0b:7b:2a:0e:49:00:e1:58:71:9b:37:a8:93:72 +# SHA1 Fingerprint: 05:63:b8:63:0d:62:d7:5a:bb:c8:ab:1e:4b:df:b5:a8:99:b2:4d:43 +# SHA256 Fingerprint: 3e:90:99:b5:01:5e:8f:48:6c:00:bc:ea:9d:11:1e:e7:21:fa:ba:35:5a:89:bc:f1:df:69:56:1e:3d:c6:32:5c +-----BEGIN CERTIFICATE----- +MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c +JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP +mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+ +wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4 +VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/ +AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB +AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun +pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC +dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf +fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm +NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx +H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe ++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root CA" +# Serial: 10944719598952040374951832963794454346 +# MD5 Fingerprint: 79:e4:a9:84:0d:7d:3a:96:d7:c0:4f:e2:43:4c:89:2e +# SHA1 Fingerprint: a8:98:5d:3a:65:e5:e5:c4:b2:d7:d6:6d:40:c6:dd:2f:b1:9c:54:36 +# SHA256 Fingerprint: 43:48:a0:e9:44:4c:78:cb:26:5e:05:8d:5e:89:44:b4:d8:4f:96:62:bd:26:db:25:7f:89:34:a4:43:c7:01:61 +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert High Assurance EV Root CA" +# Serial: 3553400076410547919724730734378100087 +# MD5 Fingerprint: d4:74:de:57:5c:39:b2:d3:9c:85:83:c5:c0:65:49:8a +# SHA1 Fingerprint: 5f:b7:ee:06:33:e2:59:db:ad:0c:4c:9a:e6:d3:8f:1a:61:c7:dc:25 +# SHA256 Fingerprint: 74:31:e5:f4:c3:c1:ce:46:90:77:4f:0b:61:e0:54:40:88:3b:a9:a0:1e:d0:0b:a6:ab:d7:80:6e:d3:b1:18:cf +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug +RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm ++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW +PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM +xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB +Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 +hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg +EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA +FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec +nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z +eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF +hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 +Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +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" +# Serial: 91299735575339953335919266965803778155 +# MD5 Fingerprint: 41:03:52:dc:0f:f7:50:1b:16:f0:02:8e:ba:6f:45:c5 +# SHA1 Fingerprint: da:c9:02:4f:54:d8:f6:df:94:93:5f:b1:73:26:38:ca:6a:d7:7c:13 +# SHA256 Fingerprint: 06:87:26:03:31:a7:24:03:d9:09:f1:05:e6:9b:cf:0d:32:e1:bd:24:93:ff:c6:d9:20:6d:11:bc:d6:77:07:39 +-----BEGIN CERTIFICATE----- +MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/ +MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT +DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow +PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD +Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O +rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq +OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b +xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw +7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD +aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG +SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69 +ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr +AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz +R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5 +JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo +Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ +-----END CERTIFICATE----- + +# Issuer: CN=SwissSign Gold CA - G2 O=SwissSign AG +# Subject: CN=SwissSign Gold CA - G2 O=SwissSign AG +# Label: "SwissSign Gold CA - G2" +# Serial: 13492815561806991280 +# MD5 Fingerprint: 24:77:d9:a8:91:d1:3b:fa:88:2d:c2:ff:f8:cd:33:93 +# SHA1 Fingerprint: d8:c5:38:8a:b7:30:1b:1b:6e:d4:7a:e6:45:25:3a:6f:9f:1a:27:61 +# SHA256 Fingerprint: 62:dd:0b:e9:b9:f5:0a:16:3e:a0:f8:e7:5c:05:3b:1e:ca:57:ea:55:c8:68:8f:64:7c:68:81:f2:c8:35:7b:95 +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +# Issuer: CN=SwissSign Silver CA - G2 O=SwissSign AG +# Subject: CN=SwissSign Silver CA - G2 O=SwissSign AG +# Label: "SwissSign Silver CA - G2" +# Serial: 5700383053117599563 +# MD5 Fingerprint: e0:06:a1:c9:7d:cf:c9:fc:0d:c0:56:75:96:d8:62:13 +# SHA1 Fingerprint: 9b:aa:e5:9f:56:ee:21:cb:43:5a:be:25:93:df:a7:f0:40:d1:1d:cb +# SHA256 Fingerprint: be:6c:4d:a2:bb:b9:ba:59:b6:f3:93:97:68:37:42:46:c3:c0:05:99:3f:a9:8f:02:0d:1d:ed:be:d4:8a:81:d5 +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc. +# Subject: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc. +# Label: "GeoTrust Primary Certification Authority" +# Serial: 32798226551256963324313806436981982369 +# MD5 Fingerprint: 02:26:c3:01:5e:08:30:37:43:a9:d0:7d:cf:37:e6:bf +# SHA1 Fingerprint: 32:3c:11:8e:1b:f7:b8:b6:52:54:e2:e2:10:0d:d6:02:90:37:f0:96 +# SHA256 Fingerprint: 37:d5:10:06:c5:12:ea:ab:62:64:21:f1:ec:8c:92:01:3f:c5:f8:2a:e9:8e:e5:33:eb:46:19:b8:de:b4:d0:6c +-----BEGIN CERTIFICATE----- +MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY +MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo +R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx +MjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK +Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9 +AWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA +ZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0 +7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W +kBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI +mO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ +KoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1 +6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl +4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K +oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj +UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU +AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= +-----END CERTIFICATE----- + +# Issuer: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only +# Subject: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only +# Label: "thawte Primary Root CA" +# Serial: 69529181992039203566298953787712940909 +# MD5 Fingerprint: 8c:ca:dc:0b:22:ce:f5:be:72:ac:41:1a:11:a8:d8:12 +# SHA1 Fingerprint: 91:c6:d6:ee:3e:8a:c8:63:84:e5:48:c2:99:29:5c:75:6c:81:7b:81 +# SHA256 Fingerprint: 8d:72:2f:81:a9:c1:13:c0:79:1d:f1:36:a2:96:6d:b2:6c:95:0a:97:1d:b4:6b:41:99:f4:ea:54:b7:8b:fb:9f +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB +qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf +Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw +MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV +BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw +NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j +LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG +A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs +W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta +3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk +6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6 +Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J +NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP +r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU +DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz +YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX +xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2 +/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/ +LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7 +jVaMaA== +-----END CERTIFICATE----- + +# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only +# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only +# Label: "VeriSign Class 3 Public Primary Certification Authority - G5" +# Serial: 33037644167568058970164719475676101450 +# MD5 Fingerprint: cb:17:e4:31:67:3e:e2:09:fe:45:57:93:f3:0a:fa:1c +# SHA1 Fingerprint: 4e:b6:d5:78:49:9b:1c:cf:5f:58:1e:ad:56:be:3d:9b:67:44:a5:e5 +# SHA256 Fingerprint: 9a:cf:ab:7e:43:c8:d8:80:d0:6b:26:2a:94:de:ee:e4:b4:65:99:89:c3:d0:ca:f1:9b:af:64:05:e4:1a:b7:df +-----BEGIN CERTIFICATE----- +MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB +yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL +ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp +U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW +ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL +MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW +ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp +U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y +aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1 +nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex +t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz +SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG +BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+ +rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/ +NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E +BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH +BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy +aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv +MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE +p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y +5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK +WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ +4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N +hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq +-----END CERTIFICATE----- + +# Issuer: CN=SecureTrust CA O=SecureTrust Corporation +# Subject: CN=SecureTrust CA O=SecureTrust Corporation +# Label: "SecureTrust CA" +# Serial: 17199774589125277788362757014266862032 +# MD5 Fingerprint: dc:32:c3:a7:6d:25:57:c7:68:09:9d:ea:2d:a9:a2:d1 +# SHA1 Fingerprint: 87:82:c6:c3:04:35:3b:cf:d2:96:92:d2:59:3e:7d:44:d9:34:ff:11 +# SHA256 Fingerprint: f1:c1:b5:0a:e5:a2:0d:d8:03:0e:c9:f6:bc:24:82:3d:d3:67:b5:25:57:59:b4:e7:1b:61:fc:e9:f7:37:5d:73 +-----BEGIN CERTIFICATE----- +MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz +MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv +cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz +Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO +0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao +wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj +7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS +8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT +BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg +JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3 +6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/ +3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm +D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS +CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR +3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= +-----END CERTIFICATE----- + +# Issuer: CN=Secure Global CA O=SecureTrust Corporation +# Subject: CN=Secure Global CA O=SecureTrust Corporation +# Label: "Secure Global CA" +# Serial: 9751836167731051554232119481456978597 +# MD5 Fingerprint: cf:f4:27:0d:d4:ed:dc:65:16:49:6d:3d:da:bf:6e:de +# SHA1 Fingerprint: 3a:44:73:5a:e5:81:90:1f:24:86:61:46:1e:3b:9c:c4:5f:f5:3a:1b +# SHA256 Fingerprint: 42:00:f5:04:3a:c8:59:0e:bb:52:7d:20:9e:d1:50:30:29:fb:cb:d4:1c:a1:b5:06:ec:27:f1:5a:de:7d:ac:69 +-----BEGIN CERTIFICATE----- +MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx +MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg +Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ +iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa +/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ +jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI +HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7 +sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w +gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw +KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG +AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L +URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO +H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm +I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY +iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc +f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW +-----END CERTIFICATE----- + +# Issuer: CN=COMODO Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO Certification Authority O=COMODO CA Limited +# Label: "COMODO Certification Authority" +# Serial: 104350513648249232941998508985834464573 +# MD5 Fingerprint: 5c:48:dc:f7:42:72:ec:56:94:6d:1c:cc:71:35:80:75 +# SHA1 Fingerprint: 66:31:bf:9e:f7:4f:9e:b6:c9:d5:a6:0c:ba:6a:be:d1:f7:bd:ef:7b +# SHA256 Fingerprint: 0c:2c:d6:3d:f7:80:6f:a3:99:ed:e8:09:11:6b:57:5b:f8:79:89:f0:65:18:f9:80:8c:86:05:03:17:8b:af:66 +-----BEGIN CERTIFICATE----- +MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB +gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV +BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw +MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl +YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P +RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3 +UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI +2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8 +Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp ++2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+ +DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O +nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW +/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g +PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u +QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY +SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv +IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ +RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4 +zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd +BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB +ZQ== +-----END CERTIFICATE----- + +# Issuer: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C. +# Subject: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C. +# Label: "Network Solutions Certificate Authority" +# Serial: 116697915152937497490437556386812487904 +# MD5 Fingerprint: d3:f3:a6:16:c0:fa:6b:1d:59:b1:2d:96:4d:0e:11:2e +# SHA1 Fingerprint: 74:f8:a3:c3:ef:e7:b3:90:06:4b:83:90:3c:21:64:60:20:e5:df:ce +# SHA256 Fingerprint: 15:f0:ba:00:a3:ac:7a:f3:ac:88:4c:07:2b:10:11:a0:77:bd:77:c0:97:f4:01:64:b2:f8:59:8a:bd:83:86:0c +-----BEGIN CERTIFICATE----- +MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi +MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu +MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp +dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV +UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO +ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz +c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP +OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl +mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF +BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4 +qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw +gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu +bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp +dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8 +6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/ +h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH +/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv +wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN +pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey +-----END CERTIFICATE----- + +# Issuer: CN=COMODO ECC Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO ECC Certification Authority O=COMODO CA Limited +# Label: "COMODO ECC Certification Authority" +# Serial: 41578283867086692638256921589707938090 +# MD5 Fingerprint: 7c:62:ff:74:9d:31:53:5e:68:4a:d5:78:aa:1e:bf:23 +# SHA1 Fingerprint: 9f:74:4e:9f:2b:4d:ba:ec:0f:31:2c:50:b6:56:3b:8e:2d:93:c3:11 +# SHA256 Fingerprint: 17:93:92:7a:06:14:54:97:89:ad:ce:2f:8f:34:f7:f0:b6:6d:0f:3a:e3:a3:b8:4d:21:ec:15:db:ba:4f:ad:c7 +-----BEGIN CERTIFICATE----- +MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT +IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw +MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy +ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N +T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR +FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J +cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW +BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm +fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv +GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= +-----END CERTIFICATE----- + +# Issuer: CN=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed +# Subject: CN=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed +# Label: "OISTE WISeKey Global Root GA CA" +# Serial: 86718877871133159090080555911823548314 +# MD5 Fingerprint: bc:6c:51:33:a7:e9:d3:66:63:54:15:72:1b:21:92:93 +# SHA1 Fingerprint: 59:22:a1:e1:5a:ea:16:35:21:f8:98:39:6a:46:46:b0:44:1b:0f:a9 +# SHA256 Fingerprint: 41:c9:23:86:6a:b4:ca:d6:b7:ad:57:80:81:58:2e:02:07:97:a6:cb:df:4f:ff:78:ce:83:96:b3:89:37:d7:f5 +-----BEGIN CERTIFICATE----- +MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCB +ijELMAkGA1UEBhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHly +aWdodCAoYykgMjAwNTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl +ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQSBDQTAeFw0w +NTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYDVQQGEwJDSDEQMA4G +A1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIwIAYD +VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBX +SVNlS2V5IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAy0+zAJs9Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxR +VVuuk+g3/ytr6dTqvirdqFEr12bDYVxgAsj1znJ7O7jyTmUIms2kahnBAbtzptf2 +w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbDd50kc3vkDIzh2TbhmYsF +mQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ/yxViJGg +4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t9 +4B3RLoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQw +EAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOx +SPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vImMMkQyh2I+3QZH4VFvbBsUfk2 +ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4+vg1YFkCExh8 +vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa +hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZi +Fj4A4xylNoEYokxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ +/L7fCg0= +-----END CERTIFICATE----- + +# Issuer: CN=Certigna O=Dhimyotis +# Subject: CN=Certigna O=Dhimyotis +# Label: "Certigna" +# Serial: 18364802974209362175 +# MD5 Fingerprint: ab:57:a6:5b:7d:42:82:19:b5:d8:58:26:28:5e:fd:ff +# SHA1 Fingerprint: b1:2e:13:63:45:86:a4:6f:1a:b2:60:68:37:58:2d:c4:ac:fd:94:97 +# SHA256 Fingerprint: e3:b6:a2:db:2e:d7:ce:48:84:2f:7a:c5:32:41:c7:b7:1d:54:14:4b:fb:40:c1:1f:3f:1d:0b:42:f5:ee:a1:2d +-----BEGIN CERTIFICATE----- +MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV +BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X +DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ +BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4 +QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny +gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw +zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q +130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2 +JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw +ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT +AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj +AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG +9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h +bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc +fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu +HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w +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" +# Serial: 4835703278459682877484360 +# MD5 Fingerprint: 72:e4:4a:87:e3:69:40:80:77:ea:bc:e3:f4:ff:f0:e1 +# SHA1 Fingerprint: 5f:43:e5:b1:bf:f8:78:8c:ac:1c:c7:ca:4a:9a:c6:22:2b:cc:34:c6 +# SHA256 Fingerprint: 96:0a:df:00:63:e9:63:56:75:0c:29:65:dd:0a:08:67:da:0b:9c:bd:6e:77:71:4a:ea:fb:23:49:ab:39:3d:a3 +-----BEGIN CERTIFICATE----- +MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYG +A1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2Jh +bCBSb290MB4XDTA2MTIxNTA4MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UE +ChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBS +b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+Mi8vRRQZhP/8NN5 +7CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW0ozS +J8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2y +HLtgwEZLAfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iP +t3sMpTjr3kfb1V05/Iin89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNz +FtApD0mpSPCzqrdsxacwOUBdrsTiXSZT8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAY +XSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/ +MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2MDSgMqAw +hi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3Js +MB8GA1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUA +A4IBAQBW7wojoFROlZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMj +Wqd8BfP9IjsO0QbE2zZMcwSO5bAi5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUx +XOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2hO0j9n0Hq0V+09+zv+mKts2o +omcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+TX3EJIrduPuoc +A06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW +WL1WMRJOEcgh4LMRkWXbtKaIOM5V +-----END CERTIFICATE----- + +# Issuer: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority +# Subject: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority +# Label: "ePKI Root Certification Authority" +# Serial: 28956088682735189655030529057352760477 +# MD5 Fingerprint: 1b:2e:00:ca:26:06:90:3d:ad:fe:6f:15:68:d3:6b:b3 +# SHA1 Fingerprint: 67:65:0d:f1:7e:8e:7e:5b:82:40:a4:f4:56:4b:cf:e2:3d:69:c6:f0 +# SHA256 Fingerprint: c0:a6:f4:dc:63:a2:4b:fd:cf:54:ef:2a:6a:08:2a:0a:72:de:35:80:3e:2f:f5:ff:52:7a:e5:d8:72:06:df:d5 +-----BEGIN CERTIFICATE----- +MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe +MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 +ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe +Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw +IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL +SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH +SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh +ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X +DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1 +TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ +fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA +sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU +WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS +nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH +dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip +NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC +AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF +MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH +ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB +uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl +PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP +JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/ +gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2 +j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6 +5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB +o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS +/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z +Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE +W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D +hNQ+IIX3Sj0rnP0qCglN6oH4EZw= +-----END CERTIFICATE----- + +# Issuer: O=certSIGN OU=certSIGN ROOT CA +# Subject: O=certSIGN OU=certSIGN ROOT CA +# Label: "certSIGN ROOT CA" +# Serial: 35210227249154 +# MD5 Fingerprint: 18:98:c0:d6:e9:3a:fc:f9:b0:f5:0c:f7:4b:01:44:17 +# SHA1 Fingerprint: fa:b7:ee:36:97:26:62:fb:2d:b0:2a:f6:bf:03:fd:e8:7c:4b:2f:9b +# SHA256 Fingerprint: ea:a9:62:c4:fa:4a:6b:af:eb:e4:15:19:6d:35:1c:cd:88:8d:4f:53:f3:fa:8a:e6:d7:c4:66:a9:4e:60:42:bb +-----BEGIN CERTIFICATE----- +MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT +AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD +QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP +MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do +0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ +UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d +RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ +OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv +JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C +AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O +BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ +LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY +MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ +44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I +Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw +i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN +9u6wWk5JRFRYX0KD +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only +# Subject: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only +# Label: "GeoTrust Primary Certification Authority - G3" +# Serial: 28809105769928564313984085209975885599 +# MD5 Fingerprint: b5:e8:34:36:c9:10:44:58:48:70:6d:2e:83:d4:b8:05 +# SHA1 Fingerprint: 03:9e:ed:b8:0b:e7:a0:3c:69:53:89:3b:20:d2:d9:32:3a:4c:2a:fd +# SHA256 Fingerprint: b4:78:b8:12:25:0d:f8:78:63:5c:2a:a7:ec:7d:15:5e:aa:62:5e:e8:29:16:e2:cd:29:43:61:88:6c:d1:fb:d4 +-----BEGIN CERTIFICATE----- +MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCB +mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT +MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s +eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv +cml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIzNTk1OVowgZgxCzAJ +BgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg +MjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0 +BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz ++uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5jK/BGvESyiaHAKAxJcCGVn2TAppMSAmUm +hsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdEc5IiaacDiGydY8hS2pgn +5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3CIShwiP/W +JmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exAL +DmKudlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZC +huOl1UcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw +HQYDVR0OBBYEFMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IB +AQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9cr5HqQ6XErhK8WTTOd8lNNTB +zU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbEAp7aDHdlDkQN +kv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD +AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUH +SJsMC8tJP33st/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2G +spki4cErx5z481+oghLrGREt +-----END CERTIFICATE----- + +# Issuer: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only +# Subject: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only +# Label: "thawte Primary Root CA - G2" +# Serial: 71758320672825410020661621085256472406 +# MD5 Fingerprint: 74:9d:ea:60:24:c4:fd:22:53:3e:cc:3a:72:d9:29:4f +# SHA1 Fingerprint: aa:db:bc:22:23:8f:c4:01:a1:27:bb:38:dd:f4:1d:db:08:9e:f0:12 +# SHA256 Fingerprint: a4:31:0d:50:af:18:a6:44:71:90:37:2a:86:af:af:8b:95:1f:fb:43:1d:83:7f:1e:56:88:b4:59:71:ed:15:57 +-----BEGIN CERTIFICATE----- +MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMp +IDIwMDcgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAi +BgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMjAeFw0wNzExMDUwMDAw +MDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh +d3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBGb3Ig +YXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9v +dCBDQSAtIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/ +BebfowJPDQfGAFG6DAJSLSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6 +papu+7qzcMBniKI11KOasf2twu8x+qi58/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUmtgAMADna3+FGO6Lts6K +DPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUNG4k8VIZ3 +KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41ox +XZ3Krr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg== +-----END CERTIFICATE----- + +# Issuer: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only +# Subject: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only +# Label: "thawte Primary Root CA - G3" +# Serial: 127614157056681299805556476275995414779 +# MD5 Fingerprint: fb:1b:5d:43:8a:94:cd:44:c6:76:f2:43:4b:47:e7:31 +# SHA1 Fingerprint: f1:8b:53:8d:1b:e9:03:b6:a6:f0:56:43:5b:17:15:89:ca:f3:6b:f2 +# SHA256 Fingerprint: 4b:03:f4:58:07:ad:70:f2:1b:fc:2c:ae:71:c9:fd:e4:60:4c:06:4c:f5:ff:b6:86:ba:e5:db:aa:d7:fd:d3:4c +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCB +rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf +Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw +MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV +BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0wODA0MDIwMDAwMDBa +Fw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3Rl +LCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9u +MTgwNgYDVQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXpl +ZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEcz +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr8nLPvb2FvdeHsbnndm +gcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2AtP0LMqmsywCPLLEHd5N/8 +YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC+BsUa0Lf +b1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS9 +9irY7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2S +zhkGcuYMXDhpxwTWvGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUk +OQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV +HQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJKoZIhvcNAQELBQADggEBABpA +2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweKA3rD6z8KLFIW +oCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu +t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7c +KUGRIjxpp7sC8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fM +m7v/OeZWYdMKp8RcTGB7BXcmer/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZu +MdRAGmI0Nj81Aa6sY6A= +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only +# Subject: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only +# Label: "GeoTrust Primary Certification Authority - G2" +# Serial: 80682863203381065782177908751794619243 +# MD5 Fingerprint: 01:5e:d8:6b:bd:6f:3d:8e:a1:31:f8:12:e0:98:73:6a +# SHA1 Fingerprint: 8d:17:84:d5:37:f3:03:7d:ec:70:fe:57:8b:51:9a:99:e6:10:d7:b0 +# SHA256 Fingerprint: 5e:db:7a:c4:3b:82:a0:6a:87:61:e8:d7:be:49:79:eb:f2:61:1f:7d:d7:9b:f9:1c:1c:6b:56:6a:21:9e:d7:66 +-----BEGIN CERTIFICATE----- +MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL +MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj +KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2 +MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV +BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw +NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV +BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH +MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL +So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal +tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG +CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT +qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz +rD6ogRLQy7rQkgu2npaqBA+K +-----END CERTIFICATE----- + +# Issuer: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only +# Subject: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only +# Label: "VeriSign Universal Root Certification Authority" +# Serial: 85209574734084581917763752644031726877 +# MD5 Fingerprint: 8e:ad:b5:01:aa:4d:81:e4:8c:1d:d1:e1:14:00:95:19 +# SHA1 Fingerprint: 36:79:ca:35:66:87:72:30:4d:30:a5:fb:87:3b:0f:a7:7b:b7:0d:54 +# SHA256 Fingerprint: 23:99:56:11:27:a5:71:25:de:8c:ef:ea:61:0d:df:2f:a0:78:b5:c8:06:7f:4e:82:82:90:bf:b8:60:e8:4b:3c +-----BEGIN CERTIFICATE----- +MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB +vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL +ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp +U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W +ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe +Fw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJVUzEX +MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0 +IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9y +IGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNh +bCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj1mCOkdeQmIN65lgZOIzF +9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGPMiJhgsWH +H26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+H +LL729fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN +/BMReYTtXlT2NJ8IAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPT +rJ9VAMf2CGqUuV/c4DPxhGD5WycRtPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1Ud +EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0GCCsGAQUFBwEMBGEwX6FdoFsw +WTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgs +exkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud +DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4 +sAPmLGd75JR3Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+ +seQxIcaBlVZaDrHC1LGmWazxY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz +4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTxP/jgdFcrGJ2BtMQo2pSXpXDrrB2+ +BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR +lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3 +7M2CYfE45k+XmCpajQ== +-----END CERTIFICATE----- + +# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only +# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only +# Label: "VeriSign Class 3 Public Primary Certification Authority - G4" +# Serial: 63143484348153506665311985501458640051 +# MD5 Fingerprint: 3a:52:e1:e7:fd:6f:3a:e3:6f:f3:6f:99:1b:f9:22:41 +# SHA1 Fingerprint: 22:d5:d8:df:8f:02:31:d1:8d:f7:9d:b7:cf:8a:2d:64:c9:3f:6c:3a +# SHA256 Fingerprint: 69:dd:d7:ea:90:bb:57:c9:3e:13:5d:c8:5e:a6:fc:d5:48:0b:60:32:39:bd:c4:54:fc:75:8b:2a:26:cf:7f:79 +-----BEGIN CERTIFICATE----- +MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjEL +MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW +ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2ln +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp +U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y +aXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjELMAkG +A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJp +U2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwg +SW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2ln +biBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8Utpkmw4tXNherJI9/gHm +GUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGzrl0Bp3ve +fLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJ +aW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYj +aHR0cDovL2xvZ28udmVyaXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMW +kf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMDA2gAMGUCMGYhDBgmYFo4e1ZC +4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIxAJw9SDkjOVga +FRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA== +-----END CERTIFICATE----- + +# Issuer: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services) +# Subject: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services) +# Label: "NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny" +# Serial: 80544274841616 +# MD5 Fingerprint: c5:a1:b7:ff:73:dd:d6:d7:34:32:18:df:fc:3c:ad:88 +# SHA1 Fingerprint: 06:08:3f:59:3f:15:a1:04:a0:69:a4:6b:a9:03:d0:06:b7:97:09:91 +# SHA256 Fingerprint: 6c:61:da:c3:a2:de:f0:31:50:6b:e0:36:d2:a6:fe:40:19:94:fb:d1:3d:f9:c8:d4:66:59:92:74:c4:46:ec:98 +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG +EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3 +MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl +cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR +dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB +pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM +b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm +aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz +IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT +lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz +AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5 +VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG +ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2 +BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG +AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M +U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh +bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C ++C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC +bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F +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" +# Serial: 1000 +# MD5 Fingerprint: a8:0d:6f:39:78:b9:43:6d:77:42:6d:98:5a:cc:23:ca +# SHA1 Fingerprint: d6:da:a8:20:8d:09:d2:15:4d:24:b5:2f:cb:34:6e:b2:58:b2:8a:58 +# SHA256 Fingerprint: f9:e6:7d:33:6c:51:00:2a:c0:54:c6:32:02:2d:66:dd:a2:e7:e3:ff:f1:0a:d0:61:ed:31:d8:bb:b4:10:cf:b2 +-----BEGIN CERTIFICATE----- +MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx +FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg +Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG +A1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr +b25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ +jVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn +PzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh +ZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9 +nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h +q5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED +MA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC +mEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3 +7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB +oiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs +EhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO +fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi +AmvZWg== +-----END CERTIFICATE----- + +# Issuer: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. +# Subject: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. +# Label: "SecureSign RootCA11" +# Serial: 1 +# MD5 Fingerprint: b7:52:74:e2:92:b4:80:93:f2:75:e4:cc:d7:f2:ea:26 +# SHA1 Fingerprint: 3b:c4:9f:48:f8:f3:73:a0:9c:1e:bd:f8:5b:b1:c3:65:c7:d8:11:b3 +# SHA256 Fingerprint: bf:0f:ee:fb:9e:3a:58:1a:d5:f9:e9:db:75:89:98:57:43:d2:61:08:5c:4d:31:4f:6f:5d:72:59:aa:42:16:12 +-----BEGIN CERTIFICATE----- +MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDEr +MCkGA1UEChMiSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoG +A1UEAxMTU2VjdXJlU2lnbiBSb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0 +MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSswKQYDVQQKEyJKYXBhbiBDZXJ0aWZp +Y2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1cmVTaWduIFJvb3RD +QTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvLTJsz +i1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8 +h9uuywGOwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOV +MdrAG/LuYpmGYz+/3ZMqg6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9 +UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rPO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni +8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitAbpSACW22s293bzUIUPsC +h8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZXt94wDgYD +VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB +AKChOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xm +KbabfSVSSUOrTC4rbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQ +X5Ucv+2rIrVls4W6ng+4reV6G4pQOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWr +QbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01y8hSyn+B/tlr0/cR7SXf+Of5 +pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061lgeLKBObjBmN +QSdJQO7e5iNEOdyhIta6A/I= +-----END CERTIFICATE----- + +# Issuer: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. +# Subject: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. +# Label: "Microsec e-Szigno Root CA 2009" +# Serial: 14014712776195784473 +# MD5 Fingerprint: f8:49:f4:03:bc:44:2d:83:be:48:69:7d:29:64:fc:b1 +# SHA1 Fingerprint: 89:df:74:fe:5c:f4:0f:4a:80:f9:e3:37:7d:54:da:91:e1:01:31:8e +# SHA256 Fingerprint: 3c:5f:81:fe:a5:fa:b8:2c:64:bf:a2:ea:ec:af:cd:e8:e0:77:fc:86:20:a7:ca:e5:37:16:3d:f3:6e:db:f3:78 +-----BEGIN CERTIFICATE----- +MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD +VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0 +ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G +CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y +OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx +FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp +Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o +dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP +kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc +cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U +fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7 +N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC +xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1 ++rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM +Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG +SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h +mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk +ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 +tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c +2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t +HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 +# Label: "GlobalSign Root CA - R3" +# Serial: 4835703278459759426209954 +# MD5 Fingerprint: c5:df:b8:49:ca:05:13:55:ee:2d:ba:1a:c3:3e:b0:28 +# SHA1 Fingerprint: d6:9b:56:11:48:f0:1c:77:c5:45:78:c1:09:26:df:5b:85:69:76:ad +# SHA256 Fingerprint: cb:b5:22:d7:b7:f1:27:ad:6a:01:13:86:5b:df:1c:d4:10:2e:7d:07:59:af:63:5a:7c:f4:72:0d:c9:63:c5:3b +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 +MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 +RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT +gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm +KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd +QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ +XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o +LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU +RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp +jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK +6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX +mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs +Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH +WD9f +-----END CERTIFICATE----- + +# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Label: "Autoridad de Certificacion Firmaprofesional CIF A62634068" +# Serial: 6047274297262753887 +# MD5 Fingerprint: 73:3a:74:7a:ec:bb:a3:96:a6:c2:e4:e2:c8:9b:c0:c3 +# SHA1 Fingerprint: ae:c5:fb:3f:c8:e1:bf:c4:e5:4f:03:07:5a:9a:e8:00:b7:f7:b6:fa +# SHA256 Fingerprint: 04:04:80:28:bf:1f:28:64:d4:8f:9a:d4:d8:32:94:36:6a:82:88:56:55:3f:3b:14:30:3f:90:14:7f:5d:40:ef +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE +BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h +cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy +MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg +Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 +thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM +cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG +L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i +NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h +X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b +m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy +Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja +EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T +KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF +6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh +OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD +VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD +VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp +cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv +ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl +AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF +661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9 +am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1 +ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481 +PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS +3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k +SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF +3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM +ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g +StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz +Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB +jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V +-----END CERTIFICATE----- + +# Issuer: CN=Izenpe.com O=IZENPE S.A. +# Subject: CN=Izenpe.com O=IZENPE S.A. +# Label: "Izenpe.com" +# Serial: 917563065490389241595536686991402621 +# MD5 Fingerprint: a6:b0:cd:85:80:da:5c:50:34:a3:39:90:2f:55:67:73 +# SHA1 Fingerprint: 2f:78:3d:25:52:18:a7:4a:65:39:71:b5:2c:a2:9c:45:15:6f:e9:19 +# SHA256 Fingerprint: 25:30:cc:8e:98:32:15:02:ba:d9:6f:9b:1f:ba:1b:09:9e:2d:29:9e:0f:45:48:bb:91:4f:36:3b:c0:d4:53:1f +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +# Issuer: CN=Chambers of Commerce Root - 2008 O=AC Camerfirma S.A. +# Subject: CN=Chambers of Commerce Root - 2008 O=AC Camerfirma S.A. +# Label: "Chambers of Commerce Root - 2008" +# Serial: 11806822484801597146 +# MD5 Fingerprint: 5e:80:9e:84:5a:0e:65:0b:17:02:f3:55:18:2a:3e:d7 +# SHA1 Fingerprint: 78:6a:74:ac:76:ab:14:7f:9c:6a:30:50:ba:9e:a8:7e:fe:9a:ce:3c +# SHA256 Fingerprint: 06:3e:4a:fa:c4:91:df:d3:32:f3:08:9b:85:42:e9:46:17:d8:93:d7:fe:94:4e:10:a7:93:7e:e2:9d:96:93:c0 +-----BEGIN CERTIFICATE----- +MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD +VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 +IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 +MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xKTAnBgNVBAMTIENoYW1iZXJz +IG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEyMjk1MFoXDTM4MDcz +MTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBj +dXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIw +EAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEp +MCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW9 +28sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKAXuFixrYp4YFs8r/lfTJq +VKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorjh40G072Q +DuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR +5gN/ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfL +ZEFHcpOrUMPrCXZkNNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05a +Sd+pZgvMPMZ4fKecHePOjlO+Bd5gD2vlGts/4+EhySnB8esHnFIbAURRPHsl18Tl +UlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331lubKgdaX8ZSD6e2wsWsSaR6s ++12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ0wlf2eOKNcx5 +Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj +ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAx +hduub+84Mxh2EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNV +HQ4EFgQU+SSsD7K1+HnA+mCIG8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1 ++HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpN +YWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29t +L2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVy +ZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAt +IDIwMDiCCQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRV +HSAAMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20w +DQYJKoZIhvcNAQEFBQADggIBAJASryI1wqM58C7e6bXpeHxIvj99RZJe6dqxGfwW +PJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH3qLPaYRgM+gQDROpI9CF +5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbURWpGqOt1 +glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaH +FoI6M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2 +pSB7+R5KBWIBpih1YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MD +xvbxrN8y8NmBGuScvfaAFPDRLLmF9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QG +tjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcKzBIKinmwPQN/aUv0NCB9szTq +jktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvGnrDQWzilm1De +fhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg +OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZ +d0jQ +-----END CERTIFICATE----- + +# Issuer: CN=Global Chambersign Root - 2008 O=AC Camerfirma S.A. +# Subject: CN=Global Chambersign Root - 2008 O=AC Camerfirma S.A. +# Label: "Global Chambersign Root - 2008" +# Serial: 14541511773111788494 +# MD5 Fingerprint: 9e:80:ff:78:01:0c:2e:c1:36:bd:fe:96:90:6e:08:f3 +# SHA1 Fingerprint: 4a:bd:ee:ec:95:0d:35:9c:89:ae:c7:52:a1:2c:5b:29:f6:d6:aa:0c +# SHA256 Fingerprint: 13:63:35:43:93:34:a7:69:80:16:a0:d3:24:de:72:28:4e:07:9d:7b:52:20:bb:8f:bd:74:78:16:ee:be:ba:ca +-----BEGIN CERTIFICATE----- +MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD +VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 +IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 +MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD +aGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMxNDBaFw0zODA3MzEx +MjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3Vy +cmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAG +A1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAl +BgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZI +hvcNAQEBBQADggIPADCCAgoCggIBAMDfVtPkOpt2RbQT2//BthmLN0EYlVJH6xed +KYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXfXjaOcNFccUMd2drvXNL7 +G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0ZJJ0YPP2 +zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4 +ddPB/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyG +HoiMvvKRhI9lNNgATH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2 +Id3UwD2ln58fQ1DJu7xsepeY7s2MH/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3V +yJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfeOx2YItaswTXbo6Al/3K1dh3e +beksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSFHTynyQbehP9r +6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh +wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsog +zCtLkykPAgMBAAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQW +BBS5CcqcHtvTbDprru1U8VuTBjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDpr +ru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UEBhMCRVUxQzBBBgNVBAcTOk1hZHJp +ZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJmaXJtYS5jb20vYWRk +cmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJmaXJt +YSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiC +CQDJzdPp1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCow +KAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZI +hvcNAQEFBQADggIBAICIf3DekijZBZRG/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZ +UohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6ReAJ3spED8IXDneRRXoz +X1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/sdZ7LoR/x +fxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVz +a2Mg9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yyd +Yhz2rXzdpjEetrHHfoUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMd +SqlapskD7+3056huirRXhOukP9DuqqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9O +AP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETrP3iZ8ntxPjzxmKfFGBI/5rso +M0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVqc5iJWzouE4ge +v8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z +09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B +-----END CERTIFICATE----- + +# Issuer: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. +# Subject: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. +# Label: "Go Daddy Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: 80:3a:bc:22:c1:e6:fb:8d:9b:3b:27:4a:32:1b:9a:01 +# SHA1 Fingerprint: 47:be:ab:c9:22:ea:e8:0e:78:78:34:62:a7:9f:45:c2:54:fd:e6:8b +# SHA256 Fingerprint: 45:14:0b:32:47:eb:9c:c8:c5:b4:f0:d7:b5:30:91:f7:32:92:08:9e:6e:5a:63:e2:74:9d:d3:ac:a9:19:8e:da +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT +EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp +ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz +NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH +EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE +AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD +E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH +/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy +DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh +GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR +tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA +AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX +WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu +9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr +gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo +2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI +4uJEvlz36hz1 +-----END CERTIFICATE----- + +# Issuer: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Subject: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Label: "Starfield Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: d6:39:81:c6:52:7e:96:69:fc:fc:ca:66:ed:05:f2:96 +# SHA1 Fingerprint: b5:1c:06:7c:ee:2b:0c:3d:f8:55:ab:2d:92:f4:fe:39:d4:e7:0f:0e +# SHA256 Fingerprint: 2c:e1:cb:0b:f9:d2:f9:e1:02:99:3f:be:21:51:52:c3:b2:dd:0c:ab:de:1c:68:e5:31:9b:83:91:54:db:b7:f5 +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs +ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw +MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 +b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj +aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp +Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg +nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1 +HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N +Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN +dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0 +HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G +CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU +sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3 +4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg +8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K +pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1 +mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 +-----END CERTIFICATE----- + +# Issuer: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Subject: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Label: "Starfield Services Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: 17:35:74:af:7b:61:1c:eb:f4:f9:3c:e2:ee:40:f9:a2 +# SHA1 Fingerprint: 92:5a:8f:8d:2c:6d:04:e0:66:5f:59:6a:ff:22:d8:63:e8:25:6f:3f +# SHA256 Fingerprint: 56:8d:69:05:a2:c8:87:08:a4:b3:02:51:90:ed:cf:ed:b1:97:4a:60:6a:13:c6:e5:29:0f:cb:2a:e6:3e:da:b5 +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs +ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 +MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD +VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy +ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy +dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p +OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 +8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K +Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe +hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk +6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q +AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI +bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB +ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z +qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd +iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn +0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN +sSi6 +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Commercial O=AffirmTrust +# Subject: CN=AffirmTrust Commercial O=AffirmTrust +# Label: "AffirmTrust Commercial" +# Serial: 8608355977964138876 +# MD5 Fingerprint: 82:92:ba:5b:ef:cd:8a:6f:a6:3d:55:f9:84:f6:d6:b7 +# SHA1 Fingerprint: f9:b5:b6:32:45:5f:9c:be:ec:57:5f:80:dc:e9:6e:2c:c7:b2:78:b7 +# SHA256 Fingerprint: 03:76:ab:1d:54:c5:f9:80:3c:e4:b2:e2:01:a0:ee:7e:ef:7b:57:b6:36:e8:a9:3c:9b:8d:48:60:c9:6f:5f:a7 +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP +Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr +ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL +MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1 +yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr +VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/ +nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG +XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj +vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt +Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g +N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC +nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Networking O=AffirmTrust +# Subject: CN=AffirmTrust Networking O=AffirmTrust +# Label: "AffirmTrust Networking" +# Serial: 8957382827206547757 +# MD5 Fingerprint: 42:65:ca:be:01:9a:9a:4c:a9:8c:41:49:cd:c0:d5:7f +# SHA1 Fingerprint: 29:36:21:02:8b:20:ed:02:f5:66:c5:32:d1:d6:ed:90:9f:45:00:2f +# SHA256 Fingerprint: 0a:81:ec:5a:92:97:77:f1:45:90:4a:f3:8d:5d:50:9f:66:b5:e2:c5:8f:cd:b5:31:05:8b:0e:17:f3:f0:b4:1b +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y +YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua +kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL +QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp +6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG +yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i +QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO +tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu +QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ +Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u +olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48 +x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Premium O=AffirmTrust +# Subject: CN=AffirmTrust Premium O=AffirmTrust +# Label: "AffirmTrust Premium" +# Serial: 7893706540734352110 +# MD5 Fingerprint: c4:5d:0e:48:b6:ac:28:30:4e:0a:bc:f9:38:16:87:57 +# SHA1 Fingerprint: d8:a6:33:2c:e0:03:6f:b1:85:f6:63:4f:7d:6a:06:65:26:32:28:27 +# SHA256 Fingerprint: 70:a7:3f:7f:37:6b:60:07:42:48:90:45:34:b1:14:82:d5:bf:0e:69:8e:cc:49:8d:f5:25:77:eb:f2:e9:3b:9a +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz +dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG +A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U +cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf +qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ +JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ ++jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS +s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5 +HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7 +70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG +V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S +qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S +5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia +C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX +OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE +FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2 +KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg +Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B +8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ +MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc +0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ +u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF +u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH +YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8 +GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO +RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e +KeC2uAloGRwYQw== +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Premium ECC O=AffirmTrust +# Subject: CN=AffirmTrust Premium ECC O=AffirmTrust +# Label: "AffirmTrust Premium ECC" +# Serial: 8401224907861490260 +# MD5 Fingerprint: 64:b0:09:55:cf:b1:d5:99:e2:be:13:ab:a6:5d:ea:4d +# SHA1 Fingerprint: b8:23:6b:00:2f:1d:16:86:53:01:55:6c:11:a4:37:ca:eb:ff:c3:bb +# SHA256 Fingerprint: bd:71:fd:f6:da:97:e4:cf:62:d1:64:7a:dd:25:81:b0:7d:79:ad:f8:39:7e:b4:ec:ba:9c:5e:84:88:82:14:23 +-----BEGIN CERTIFICATE----- +MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC +VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ +cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ +BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt +VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D +0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9 +ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G +A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs +aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I +flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ== +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Network CA" +# Serial: 279744 +# MD5 Fingerprint: d5:e9:81:40:c5:18:69:fc:46:2c:89:75:62:0f:aa:78 +# SHA1 Fingerprint: 07:e0:32:e0:20:b7:2c:3f:19:2f:06:28:a2:59:3a:19:a7:0f:06:9e +# SHA256 Fingerprint: 5c:58:46:8d:55:f5:8e:49:7e:74:39:82:d2:b5:00:10:b6:d1:65:37:4a:cf:83:a7:d4:a3:2d:b7:68:c4:40:8e +-----BEGIN CERTIFICATE----- +MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM +MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D +ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU +cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3 +WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg +Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw +IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH +UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM +TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU +BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM +kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x +AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV +HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y +sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL +I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8 +J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY +VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI +03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= +-----END CERTIFICATE----- + +# Issuer: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA +# Subject: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA +# Label: "TWCA Root Certification Authority" +# Serial: 1 +# MD5 Fingerprint: aa:08:8f:f6:f9:7b:b7:f2:b1:a7:1e:9b:ea:ea:bd:79 +# SHA1 Fingerprint: cf:9e:87:6d:d3:eb:fc:42:26:97:a3:b5:a3:7a:a0:76:a9:06:23:48 +# SHA256 Fingerprint: bf:d8:8f:e1:10:1c:41:ae:3e:80:1b:f8:be:56:35:0e:e9:ba:d1:a6:b9:bd:51:5e:dc:5c:6d:5b:87:11:ac:44 +-----BEGIN CERTIFICATE----- +MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES +MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU +V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz +WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO +LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE +AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH +K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX +RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z +rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx +3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq +hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC +MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls +XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D +lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn +aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ +YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== +-----END CERTIFICATE----- + +# Issuer: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 +# Subject: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 +# Label: "Security Communication RootCA2" +# Serial: 0 +# MD5 Fingerprint: 6c:39:7d:a4:0e:55:59:b2:3f:d6:41:b1:12:50:de:43 +# SHA1 Fingerprint: 5f:3b:8c:f2:f8:10:b3:7d:78:b4:ce:ec:19:19:c3:73:34:b9:c7:74 +# SHA256 Fingerprint: 51:3b:2c:ec:b8:10:d4:cd:e5:dd:85:39:1a:df:c6:c2:dd:60:d8:7b:b7:36:d2:b5:21:48:4a:a4:7a:0e:be:f6 +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl +MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe +U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX +DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy +dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj +YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV +OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr +zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM +VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ +hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO +ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw +awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs +OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF +coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc +okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8 +t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy +1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/ +SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 +-----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" +# Serial: 0 +# MD5 Fingerprint: 73:9f:4c:4b:73:5b:79:e9:fa:ba:1c:ef:6e:cb:d5:c9 +# SHA1 Fingerprint: fe:45:65:9b:79:03:5b:98:a1:61:b5:51:2e:ac:da:58:09:48:22:4d +# SHA256 Fingerprint: bc:10:4f:15:a4:8b:e7:09:dc:a5:42:a7:e1:d4:b9:df:6f:05:45:27:e8:02:ea:a9:2d:59:54:44:25:8a:fe:71 +-----BEGIN CERTIFICATE----- +MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix +RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p +YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw +NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK +EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl +cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz +dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ +fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns +bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD +75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP +FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV +HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp +5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu +b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA +A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p +6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 +TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7 +dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys +Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI +l7WdmplNsDz4SgCbZN2fOUvRJ9e4 +-----END CERTIFICATE----- + +# Issuer: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 +# Subject: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 +# Label: "Actalis Authentication Root CA" +# Serial: 6271844772424770508 +# MD5 Fingerprint: 69:c1:0d:4f:07:a3:1b:c3:fe:56:3d:04:bc:11:f6:a6 +# SHA1 Fingerprint: f3:73:b3:87:06:5a:28:84:8a:f2:f3:4a:ce:19:2b:dd:c7:8e:9c:ac +# SHA256 Fingerprint: 55:92:60:84:ec:96:3a:64:b9:6e:2a:be:01:ce:0b:a8:6a:64:fb:fe:bc:c7:aa:b5:af:c1:55:b3:7f:d7:60:66 +-----BEGIN CERTIFICATE----- +MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE +BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w +MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 +IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC +SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1 +ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv +UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX +4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9 +KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/ +gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb +rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ +51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F +be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe +KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F +v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn +fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7 +jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz +ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt +ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL +e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70 +jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz +WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V +SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j +pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX +X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok +fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R +K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU +ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU +LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT +LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== +-----END CERTIFICATE----- + +# Issuer: O=Trustis Limited OU=Trustis FPS Root CA +# Subject: O=Trustis Limited OU=Trustis FPS Root CA +# Label: "Trustis FPS Root CA" +# Serial: 36053640375399034304724988975563710553 +# MD5 Fingerprint: 30:c9:e7:1e:6b:e6:14:eb:65:b2:16:69:20:31:67:4d +# SHA1 Fingerprint: 3b:c0:38:0b:33:c3:f6:a6:0c:86:15:22:93:d9:df:f5:4b:81:c0:04 +# SHA256 Fingerprint: c1:b4:82:99:ab:a5:20:8f:e9:63:0a:ce:55:ca:68:a0:3e:da:5a:51:9c:88:02:a0:d3:a6:73:be:8f:8e:55:7d +-----BEGIN CERTIFICATE----- +MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBF +MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQL +ExNUcnVzdGlzIEZQUyBSb290IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTEx +MzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1RydXN0aXMgTGltaXRlZDEc +MBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQRUN+ +AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihH +iTHcDnlkH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjj +vSkCqPoc4Vu5g6hBSLwacY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA +0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zto3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlB +OrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEAAaNTMFEwDwYDVR0TAQH/ +BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAdBgNVHQ4E +FgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01 +GX2cGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmW +zaD+vkAMXBJV+JOCyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP4 +1BIy+Q7DsdwyhEQsb8tGD+pmQQ9P8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZE +f1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHVl/9D7S3B2l0pKoU/rGXuhg8F +jZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN +ZetX2fNXlrtIzYE= +-----END CERTIFICATE----- + +# Issuer: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 +# Subject: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 +# Label: "Buypass Class 2 Root CA" +# Serial: 2 +# MD5 Fingerprint: 46:a7:d2:fe:45:fb:64:5a:a8:59:90:9b:78:44:9b:29 +# SHA1 Fingerprint: 49:0a:75:74:de:87:0a:47:fe:58:ee:f6:c7:6b:eb:c6:0b:12:40:99 +# SHA256 Fingerprint: 9a:11:40:25:19:7c:5b:b9:5d:94:e6:3d:55:cd:43:79:08:47:b6:46:b2:3c:df:11:ad:a4:a0:0e:ff:15:fb:48 +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr +6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV +L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91 +1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx +MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ +QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB +arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr +Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi +FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS +P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN +9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz +uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h +9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s +A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t +OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo ++fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7 +KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2 +DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us +H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ +I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7 +5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h +3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz +Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA= +-----END CERTIFICATE----- + +# Issuer: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 +# Subject: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 +# Label: "Buypass Class 3 Root CA" +# Serial: 2 +# MD5 Fingerprint: 3d:3b:18:9e:2c:64:5a:e8:d5:88:ce:0e:f9:37:c2:ec +# SHA1 Fingerprint: da:fa:f7:fa:66:84:ec:06:8f:14:50:bd:c7:c2:81:a5:bc:a9:64:57 +# SHA256 Fingerprint: ed:f7:eb:bc:a2:7a:2a:38:4d:38:7b:7d:40:10:c6:66:e2:ed:b4:84:3e:4c:29:b4:ae:1d:5b:93:32:e6:b2:4d +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y +ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E +N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9 +tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX +0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c +/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X +KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY +zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS +O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D +34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP +K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3 +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv +Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj +QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV +cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS +IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2 +HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa +O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv +033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u +dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE +kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41 +3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD +u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq +4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc= +-----END CERTIFICATE----- + +# Issuer: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Subject: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Label: "T-TeleSec GlobalRoot Class 3" +# Serial: 1 +# MD5 Fingerprint: ca:fb:40:a8:4e:39:92:8a:1d:fe:8e:2f:c4:27:ea:ef +# SHA1 Fingerprint: 55:a6:72:3e:cb:f2:ec:cd:c3:23:74:70:19:9d:2a:be:11:e3:81:d1 +# SHA256 Fingerprint: fd:73:da:d3:1c:64:4f:f1:b4:3b:ef:0c:cd:da:96:71:0b:9c:d9:87:5e:ca:7e:31:70:7a:f3:e9:6d:52:2b:bd +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN +8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/ +RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4 +hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5 +ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM +EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1 +A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy +WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ +1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30 +6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT +91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml +e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p +TpPDpFQUWw== +-----END CERTIFICATE----- + +# Issuer: CN=EE Certification Centre Root CA O=AS Sertifitseerimiskeskus +# Subject: CN=EE Certification Centre Root CA O=AS Sertifitseerimiskeskus +# Label: "EE Certification Centre Root CA" +# Serial: 112324828676200291871926431888494945866 +# MD5 Fingerprint: 43:5e:88:d4:7d:1a:4a:7e:fd:84:2e:52:eb:01:d4:6f +# SHA1 Fingerprint: c9:a8:b9:e7:55:80:5e:58:e3:53:77:a7:25:eb:af:c3:7b:27:cc:d7 +# SHA256 Fingerprint: 3e:84:ba:43:42:90:85:16:e7:75:73:c0:99:2f:09:79:ca:08:4e:46:85:68:1f:f1:95:cc:ba:8a:22:9b:8a:76 +-----BEGIN CERTIFICATE----- +MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1 +MQswCQYDVQQGEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1 +czEoMCYGA1UEAwwfRUUgQ2VydGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYG +CSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIwMTAxMDMwMTAxMDMwWhgPMjAzMDEy +MTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNl +ZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBS +b290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUy +euuOF0+W2Ap7kaJjbMeMTC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvO +bntl8jixwKIy72KyaOBhU8E2lf/slLo2rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIw +WFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw93X2PaRka9ZP585ArQ/d +MtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtNP2MbRMNE +1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYD +VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/ +zQas8fElyalL1BSZMEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYB +BQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEF +BQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+RjxY6hUFaTlrg4wCQiZrxTFGGV +v9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqMlIpPnTX/dqQG +E5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u +uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIW +iAYLtqZLICjU3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/v +GVCJYMzpJJUPwssd8m92kMfMdcGWxZ0= +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH +# Subject: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH +# Label: "D-TRUST Root Class 3 CA 2 2009" +# Serial: 623603 +# MD5 Fingerprint: cd:e0:25:69:8d:47:ac:9c:89:35:90:f7:fd:51:3d:2f +# SHA1 Fingerprint: 58:e8:ab:b0:36:15:33:fb:80:f7:9b:1b:6d:29:d3:ff:8d:5f:00:f0 +# SHA256 Fingerprint: 49:e7:a4:42:ac:f0:ea:62:87:05:00:54:b5:25:64:b6:50:e4:f4:9e:42:e3:48:d6:aa:38:e0:39:e9:57:b1:c1 +-----BEGIN CERTIFICATE----- +MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha +ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM +HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03 +UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42 +tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R +ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM +lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp +/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G +A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G +A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj +dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy +MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl +cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js +L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL +BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni +acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 +o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K +zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8 +PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y +Johw1+qRzT65ysCQblrGXnRl11z+o+I= +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH +# Subject: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH +# Label: "D-TRUST Root Class 3 CA 2 EV 2009" +# Serial: 623604 +# MD5 Fingerprint: aa:c6:43:2c:5e:2d:cd:c4:34:c0:50:4f:11:02:4f:b6 +# SHA1 Fingerprint: 96:c9:1b:0b:95:b4:10:98:42:fa:d0:d8:22:79:fe:60:fa:b9:16:83 +# SHA256 Fingerprint: ee:c5:49:6b:98:8c:e9:86:25:b9:34:09:2e:ec:29:08:be:d0:b0:f3:16:c2:d4:73:0c:84:ea:f1:f3:d3:48:81 +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw +NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV +BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn +ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0 +3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z +qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR +p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8 +HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw +ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea +HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw +Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh +c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E +RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt +dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku +Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp +3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 +nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF +CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na +xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX +KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1 +-----END CERTIFICATE----- + +# Issuer: CN=CA Disig Root R2 O=Disig a.s. +# Subject: CN=CA Disig Root R2 O=Disig a.s. +# Label: "CA Disig Root R2" +# Serial: 10572350602393338211 +# MD5 Fingerprint: 26:01:fb:d8:27:a7:17:9a:45:54:38:1a:43:01:3b:03 +# SHA1 Fingerprint: b5:61:eb:ea:a4:de:e4:25:4b:69:1a:98:a5:57:47:c2:34:c7:d9:71 +# SHA256 Fingerprint: e2:3d:4a:03:6d:7b:70:e9:f5:95:b1:42:20:79:d2:b9:1e:df:bb:1f:b6:51:a0:63:3e:aa:8a:9d:c5:f8:07:03 +-----BEGIN CERTIFICATE----- +MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV +BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu +MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy +MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx +EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw +ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe +NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH +PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I +x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe +QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR +yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO +QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912 +H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ +QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD +i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs +nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1 +rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI +hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM +tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf +GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb +lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka ++elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal +TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i +nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3 +gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr +G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os +zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x +L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL +-----END CERTIFICATE----- + +# Issuer: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV +# Subject: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV +# Label: "ACCVRAIZ1" +# Serial: 6828503384748696800 +# MD5 Fingerprint: d0:a0:5a:ee:05:b6:09:94:21:a1:7d:f1:b2:29:82:02 +# SHA1 Fingerprint: 93:05:7a:88:15:c6:4f:ce:88:2f:fa:91:16:52:28:78:bc:53:64:17 +# SHA256 Fingerprint: 9a:6e:c0:12:e1:a7:da:9d:be:34:19:4d:47:8a:d7:c0:db:18:22:fb:07:1d:f1:29:81:49:6e:d1:04:38:41:13 +-----BEGIN CERTIFICATE----- +MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE +AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw +CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ +BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND +VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb +qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY +HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo +G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA +lHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr +IA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/ +0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH +k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47 +4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO +m3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa +cXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl +uUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI +KwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls +ZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG +AQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 +VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT +VfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG +CCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA +cgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA +QwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA +7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA +cgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA +QwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA +czAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu +aHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt +aW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud +DwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF +BQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp +D70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU +JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m +AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD +vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms +tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH +7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h +I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA +h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF +d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H +pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7 +-----END CERTIFICATE----- + +# Issuer: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA +# Subject: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA +# Label: "TWCA Global Root CA" +# Serial: 3262 +# MD5 Fingerprint: f9:03:7e:cf:e6:9e:3c:73:7a:2a:90:07:69:ff:2b:96 +# SHA1 Fingerprint: 9c:bb:48:53:f6:a4:f6:d3:52:a4:e8:32:52:55:60:13:f5:ad:af:65 +# SHA256 Fingerprint: 59:76:90:07:f7:68:5d:0f:cd:50:87:2f:9f:95:d5:75:5a:5b:2b:45:7d:81:f3:69:2b:61:0a:98:67:2f:0e:1b +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx +EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT +VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5 +NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT +B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF +10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz +0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh +MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH +zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc +46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2 +yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi +laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP +oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA +BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE +qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm +4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL +1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn +LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF +H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo +RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+ +nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh +15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW +6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW +nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j +wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz +aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy +KwbQBM0= +-----END CERTIFICATE----- + +# Issuer: CN=TeliaSonera Root CA v1 O=TeliaSonera +# Subject: CN=TeliaSonera Root CA v1 O=TeliaSonera +# Label: "TeliaSonera Root CA v1" +# Serial: 199041966741090107964904287217786801558 +# MD5 Fingerprint: 37:41:49:1b:18:56:9a:26:f5:ad:c2:66:fb:40:a5:4c +# SHA1 Fingerprint: 43:13:bb:96:f1:d5:86:9b:c1:4e:6a:92:f6:cf:f6:34:69:87:82:37 +# SHA256 Fingerprint: dd:69:36:fe:21:f8:f0:77:c1:23:a1:a5:21:c1:22:24:f7:22:55:b7:3e:03:a7:26:06:93:e8:a2:4b:0f:a3:89 +-----BEGIN CERTIFICATE----- +MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw +NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv +b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD +VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2 +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F +VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1 +7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X +Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+ +/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs +81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm +dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe +Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu +sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4 +pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs +slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ +arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD +VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG +9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl +dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx +0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj +TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed +Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7 +Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI +OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7 +vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW +t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn +HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx +SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= +-----END CERTIFICATE----- + +# Issuer: CN=E-Tugra Certification Authority O=E-Tu\u011fra EBG Bili\u015fim Teknolojileri ve Hizmetleri A.\u015e. OU=E-Tugra Sertifikasyon Merkezi +# Subject: CN=E-Tugra Certification Authority O=E-Tu\u011fra EBG Bili\u015fim Teknolojileri ve Hizmetleri A.\u015e. OU=E-Tugra Sertifikasyon Merkezi +# Label: "E-Tugra Certification Authority" +# Serial: 7667447206703254355 +# MD5 Fingerprint: b8:a1:03:63:b0:bd:21:71:70:8a:6f:13:3a:bb:79:49 +# SHA1 Fingerprint: 51:c6:e7:08:49:06:6e:f3:92:d4:5c:a0:0d:6d:a3:62:8f:c3:52:39 +# SHA256 Fingerprint: b0:bf:d5:2b:b0:d7:d9:bd:92:bf:5d:4d:c1:3d:a2:55:c0:2c:54:2f:37:83:65:ea:89:39:11:f5:5e:55:f2:3c +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV +BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC +aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV +BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1 +Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz +MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+ +BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp +em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN +ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY +B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH +D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF +Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo +q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D +k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH +fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut +dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM +ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8 +zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn +rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX +U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6 +Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5 +XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF +Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR +HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY +GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c +77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3 ++GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK +vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6 +FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl +yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P +AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD +y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d +NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA== +-----END CERTIFICATE----- + +# Issuer: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Subject: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Label: "T-TeleSec GlobalRoot Class 2" +# Serial: 1 +# MD5 Fingerprint: 2b:9b:9e:e4:7b:6c:1f:00:72:1a:cc:c1:77:79:df:6a +# SHA1 Fingerprint: 59:0d:2d:7d:88:4f:40:2e:61:7e:a5:62:32:17:65:cf:17:d8:94:e9 +# SHA256 Fingerprint: 91:e2:f5:78:8d:58:10:eb:a7:ba:58:73:7d:e1:54:8a:8e:ca:cd:01:45:98:bc:0b:14:3e:04:1b:17:05:25:52 +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd +AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC +FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi +1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq +jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ +wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/ +WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy +NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC +uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw +IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6 +g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN +9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP +BSeOE6Fuwg== +-----END CERTIFICATE----- + +# Issuer: CN=Atos TrustedRoot 2011 O=Atos +# Subject: CN=Atos TrustedRoot 2011 O=Atos +# Label: "Atos TrustedRoot 2011" +# Serial: 6643877497813316402 +# MD5 Fingerprint: ae:b9:c4:32:4b:ac:7f:5d:66:cc:77:94:bb:2a:77:56 +# SHA1 Fingerprint: 2b:b1:f5:3e:55:0c:1d:c5:f1:d4:e6:b7:6a:46:4b:55:06:02:ac:21 +# SHA256 Fingerprint: f3:56:be:a2:44:b7:a9:1e:b3:5d:53:ca:9a:d7:86:4a:ce:01:8e:2d:35:d5:f8:f9:6d:df:68:a6:f4:1a:a4:74 +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE +AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG +EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM +FUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC +REUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp +Nb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM +VD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+ +SZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ +4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L +cp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi +eowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG +A1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3 +DQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j +vZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP +DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc +maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D +lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv +KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 1 G3" +# Serial: 687049649626669250736271037606554624078720034195 +# MD5 Fingerprint: a4:bc:5b:3f:fe:37:9a:fa:64:f0:e2:fa:05:3d:0b:ab +# SHA1 Fingerprint: 1b:8e:ea:57:96:29:1a:c9:39:ea:b8:0a:81:1a:73:73:c0:93:79:67 +# SHA256 Fingerprint: 8a:86:6f:d1:b2:76:b5:7e:57:8e:92:1c:65:82:8a:2b:ed:58:e9:f2:f2:88:05:41:34:b7:f1:f4:bf:c9:cc:74 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00 +MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV +wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe +rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341 +68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh +4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp +UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o +abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc +3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G +KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt +hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO +Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt +zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD +ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC +MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2 +cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN +qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5 +YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv +b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2 +8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k +NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj +ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp +q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt +nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 2 G3" +# Serial: 390156079458959257446133169266079962026824725800 +# MD5 Fingerprint: af:0c:86:6e:bf:40:2d:7f:0b:3e:12:50:ba:12:3d:06 +# SHA1 Fingerprint: 09:3c:61:f3:8b:8b:dc:7d:55:df:75:38:02:05:00:e1:25:f5:c8:36 +# SHA256 Fingerprint: 8f:e4:fb:0a:f9:3a:4d:0d:67:db:0b:eb:b2:3e:37:c7:1b:f3:25:dc:bc:dd:24:0e:a0:4d:af:58:b4:7e:18:40 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00 +MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf +qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW +n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym +c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+ +O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1 +o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j +IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq +IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz +8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh +vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l +7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG +cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD +ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 +AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC +roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga +W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n +lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE ++V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV +csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd +dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg +KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM +HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4 +WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 3 G3" +# Serial: 268090761170461462463995952157327242137089239581 +# MD5 Fingerprint: df:7d:b9:ad:54:6f:68:a1:df:89:57:03:97:43:b0:d7 +# SHA1 Fingerprint: 48:12:bd:92:3c:a8:c4:39:06:e7:30:6d:27:96:e6:a4:cf:22:2e:7d +# SHA256 Fingerprint: 88:ef:81:de:20:2e:b0:18:45:2e:43:f8:64:72:5c:ea:5f:bd:1f:c2:d9:d2:05:73:07:09:c5:d8:b8:69:0f:46 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00 +MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR +/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu +FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR +U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c +ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR +FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k +A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw +eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl +sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp +VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q +A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ +ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD +ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px +KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI +FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv +oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg +u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP +0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf +3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl +8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+ +DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN +PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ +ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0 +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root G2" +# Serial: 15385348160840213938643033620894905419 +# MD5 Fingerprint: 92:38:b9:f8:63:24:82:65:2c:57:33:e6:fe:81:8f:9d +# SHA1 Fingerprint: a1:4b:48:d9:43:ee:0a:0e:40:90:4f:3c:e0:a4:c0:91:93:51:5d:3f +# SHA256 Fingerprint: 7d:05:eb:b6:82:33:9f:8c:94:51:ee:09:4e:eb:fe:fa:79:53:a1:14:ed:b2:f4:49:49:45:2f:ab:7d:2f:c1:85 +-----BEGIN CERTIFICATE----- +MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA +n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc +biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp +EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA +bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu +YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB +AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW +BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI +QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I +0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni +lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9 +B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv +ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo +IhNzbM8m9Yop5w== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root G3" +# Serial: 15459312981008553731928384953135426796 +# MD5 Fingerprint: 7c:7f:65:31:0c:81:df:8d:ba:3e:99:e2:5c:ad:6e:fb +# SHA1 Fingerprint: f5:17:a2:4f:9a:48:c6:c9:f8:a2:00:26:9f:dc:0f:48:2c:ab:30:89 +# SHA256 Fingerprint: 7e:37:cb:8b:4c:47:09:0c:ab:36:55:1b:a6:f4:5d:b8:40:68:0f:ba:16:6a:95:2d:b1:00:71:7f:43:05:3f:c2 +-----BEGIN CERTIFICATE----- +MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg +RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf +Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q +RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD +AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY +JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv +6pZjamVFkpUBtA== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root G2" +# Serial: 4293743540046975378534879503202253541 +# MD5 Fingerprint: e4:a6:8a:c8:54:ac:52:42:46:0a:fd:72:48:1b:2a:44 +# SHA1 Fingerprint: df:3c:24:f9:bf:d6:66:76:1b:26:80:73:fe:06:d1:cc:8d:4f:82:a4 +# SHA256 Fingerprint: cb:3c:cb:b7:60:31:e5:e0:13:8f:8d:d3:9a:23:f9:de:47:ff:c3:5e:43:c1:14:4c:ea:27:d4:6a:5a:b1:cb:5f +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root G3" +# Serial: 7089244469030293291760083333884364146 +# MD5 Fingerprint: f5:5d:a4:50:a5:fb:28:7e:1e:0f:0d:cc:96:57:56:ca +# SHA1 Fingerprint: 7e:04:de:89:6a:3e:66:6d:00:e6:87:d3:3f:fa:d9:3b:e8:3d:34:9e +# SHA256 Fingerprint: 31:ad:66:48:f8:10:41:38:c7:38:f3:9e:a4:32:01:33:39:3e:3a:18:cc:02:29:6e:f9:7c:2a:c9:ef:67:31:d0 +-----BEGIN CERTIFICATE----- +MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe +Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw +EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x +IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG +fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO +Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd +BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx +AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ +oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 +sycX +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Trusted Root G4" +# Serial: 7451500558977370777930084869016614236 +# MD5 Fingerprint: 78:f2:fc:aa:60:1f:2f:b4:eb:c9:37:ba:53:2e:75:49 +# SHA1 Fingerprint: dd:fb:16:cd:49:31:c9:73:a2:03:7d:3f:c8:3a:4d:7d:77:5d:05:e4 +# SHA256 Fingerprint: 55:2f:7b:dc:f1:a7:af:9e:6c:e6:72:01:7f:4f:12:ab:f7:72:40:c7:8e:76:1a:c2:03:d1:d9:d2:0a:c8:99:88 +-----BEGIN CERTIFICATE----- +MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg +RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y +ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If +xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV +ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO +DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ +jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/ +CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi +EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM +fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY +uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK +chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t +9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD +ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2 +SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd ++SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc +fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa +sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N +cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N +0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie +4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI +r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1 +/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm +gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+ +-----END CERTIFICATE----- + +# Issuer: CN=COMODO RSA Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO RSA Certification Authority O=COMODO CA Limited +# Label: "COMODO RSA Certification Authority" +# Serial: 101909084537582093308941363524873193117 +# MD5 Fingerprint: 1b:31:b0:71:40:36:cc:14:36:91:ad:c4:3e:fd:ec:18 +# SHA1 Fingerprint: af:e5:d2:44:a8:d1:19:42:30:ff:47:9f:e2:f8:97:bb:cd:7a:8c:b4 +# SHA256 Fingerprint: 52:f0:e1:c4:e5:8e:c6:29:29:1b:60:31:7f:07:46:71:b8:5d:7e:a8:0d:5b:07:27:34:63:53:4b:32:b4:02:34 +-----BEGIN CERTIFICATE----- +MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB +hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV +BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5 +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT +EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR +6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X +pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC +9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV +/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf +Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z ++pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w +qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah +SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC +u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf +Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq +crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E +FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB +/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl +wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM +4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV +2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna +FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ +CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK +boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke +jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL +S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb +QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl +0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB +NVOFBkpdn627G190 +-----END CERTIFICATE----- + +# Issuer: CN=USERTrust RSA Certification Authority O=The USERTRUST Network +# Subject: CN=USERTrust RSA Certification Authority O=The USERTRUST Network +# Label: "USERTrust RSA Certification Authority" +# Serial: 2645093764781058787591871645665788717 +# MD5 Fingerprint: 1b:fe:69:d1:91:b7:19:33:a3:72:a8:0f:e1:55:e5:b5 +# SHA1 Fingerprint: 2b:8f:1b:57:33:0d:bb:a2:d0:7a:6c:51:f7:0e:e9:0d:da:b9:ad:8e +# SHA256 Fingerprint: e7:93:c9:b0:2f:d8:aa:13:e2:1c:31:22:8a:cc:b0:81:19:64:3b:74:9c:89:89:64:b1:74:6d:46:c3:d4:cb:d2 +-----BEGIN CERTIFICATE----- +MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB +iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl +cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV +BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw +MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV +BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B +3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY +tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ +Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 +VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT +79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 +c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT +Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l +c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee +UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE +Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd +BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G +A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF +Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO +VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 +ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs +8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR +iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze +Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ +XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ +qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB +VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB +L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG +jjxDah2nGN59PRbxYvnKkKj9 +-----END CERTIFICATE----- + +# Issuer: CN=USERTrust ECC Certification Authority O=The USERTRUST Network +# Subject: CN=USERTrust ECC Certification Authority O=The USERTRUST Network +# Label: "USERTrust ECC Certification Authority" +# Serial: 123013823720199481456569720443997572134 +# MD5 Fingerprint: fa:68:bc:d9:b5:7f:ad:fd:c9:1d:06:83:28:cc:24:c1 +# SHA1 Fingerprint: d1:cb:ca:5d:b2:d5:2a:7f:69:3b:67:4d:e5:f0:5a:1d:0c:95:7d:f0 +# SHA256 Fingerprint: 4f:f4:60:d5:4b:9c:86:da:bf:bc:fc:57:12:e0:40:0d:2b:ed:3f:bc:4d:4f:bd:aa:86:e0:6a:dc:d2:a9:ad:7a +-----BEGIN CERTIFICATE----- +MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl +eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT +JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT +Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg +VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo +I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng +o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G +A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB +zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW +RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 +# Label: "GlobalSign ECC Root CA - R4" +# Serial: 14367148294922964480859022125800977897474 +# MD5 Fingerprint: 20:f0:27:68:d1:7e:a0:9d:0e:e6:2a:ca:df:5c:89:8e +# SHA1 Fingerprint: 69:69:56:2e:40:80:f4:24:a1:e7:19:9f:14:ba:f3:ee:58:ab:6a:bb +# SHA256 Fingerprint: be:c9:49:11:c2:95:56:76:db:6c:0a:55:09:86:d7:6e:3b:a0:05:66:7c:44:2c:97:62:b4:fb:b7:73:de:22:8c +-----BEGIN CERTIFICATE----- +MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk +MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH +bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX +DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD +QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ +FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F +uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX +kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs +ewv4n4Q= +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 +# Label: "GlobalSign ECC Root CA - R5" +# Serial: 32785792099990507226680698011560947931244 +# MD5 Fingerprint: 9f:ad:3b:1c:02:1e:8a:ba:17:74:38:81:0c:a2:bc:08 +# SHA1 Fingerprint: 1f:24:c6:30:cd:a4:18:ef:20:69:ff:ad:4f:dd:5f:46:3a:1b:69:aa +# SHA256 Fingerprint: 17:9f:bc:14:8a:3d:d0:0f:d2:4e:a1:34:58:cc:43:bf:a7:f5:9c:81:82:d7:83:a5:13:f6:eb:ec:10:0c:89:24 +-----BEGIN CERTIFICATE----- +MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk +MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH +bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX +DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD +QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc +8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke +hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI +KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg +515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO +xwy8p2Fp8fc74SrL+SvzZpA3 +-----END CERTIFICATE----- + +# Issuer: CN=Staat der Nederlanden Root CA - G3 O=Staat der Nederlanden +# Subject: CN=Staat der Nederlanden Root CA - G3 O=Staat der Nederlanden +# Label: "Staat der Nederlanden Root CA - G3" +# Serial: 10003001 +# MD5 Fingerprint: 0b:46:67:07:db:10:2f:19:8c:35:50:60:d1:0b:f4:37 +# SHA1 Fingerprint: d8:eb:6b:41:51:92:59:e0:f3:e7:85:00:c0:3d:b6:88:97:c9:ee:fc +# SHA256 Fingerprint: 3c:4f:b0:b9:5a:b8:b3:00:32:f4:32:b8:6f:53:5f:e1:72:c1:85:d0:fd:39:86:58:37:cf:36:18:7f:a6:f4:28 +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloX +DTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl +ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv +b3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4yolQP +cPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WW +IkYFsO2tx1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqX +xz8ecAgwoNzFs21v0IJyEavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFy +KJLZWyNtZrVtB0LrpjPOktvA9mxjeM3KTj215VKb8b475lRgsGYeCasH/lSJEULR +9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUurmkVLoR9BvUhTFXFkC4az +5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU51nus6+N8 +6U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7 +Ngzp07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHP +bMk7ccHViLVlvMDoFxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXt +BznaqB16nzaeErAMZRKQFWDZJkBE41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTt +XUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMBAAGjQjBAMA8GA1UdEwEB/wQF +MAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleuyjWcLhL75Lpd +INyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD +U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwp +LiniyMMB8jPqKqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8 +Ipf3YF3qKS9Ysr1YvY2WTxB1v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixp +gZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA8KCWAg8zxXHzniN9lLf9OtMJgwYh +/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b8KKaa8MFSu1BYBQw +0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0rmj1A +fsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq +4BZ+Extq1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR +1VmiiXTTn74eS9fGbbeIJG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/ +QFH1T/U67cjF68IeHRaVesd+QnGTbksVtzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM +94B7IWcnMFk= +-----END CERTIFICATE----- + +# Issuer: CN=Staat der Nederlanden EV Root CA O=Staat der Nederlanden +# Subject: CN=Staat der Nederlanden EV Root CA O=Staat der Nederlanden +# Label: "Staat der Nederlanden EV Root CA" +# Serial: 10000013 +# MD5 Fingerprint: fc:06:af:7b:e8:1a:f1:9a:b4:e8:d2:70:1f:c0:f5:ba +# SHA1 Fingerprint: 76:e2:7e:c1:4f:db:82:c1:c0:a6:75:b5:05:be:3d:29:b4:ed:db:bb +# SHA256 Fingerprint: 4d:24:91:41:4c:fe:95:67:46:ec:4c:ef:a6:cf:6f:72:e2:8a:13:29:43:2f:9d:8a:90:7a:c4:cb:5d:ad:c1:5a +-----BEGIN CERTIFICATE----- +MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0y +MjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIg +TmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBS +b290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkkSzrS +M4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nC +UiY4iKTWO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3d +Z//BYY1jTw+bbRcwJu+r0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46p +rfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13l +pJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gVXJrm0w912fxBmJc+qiXb +j5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr08C+eKxC +KFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS +/ZbV0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0X +cgOPvZuM5l5Tnrmd74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH +1vI4gnPah1vlPNOePqc7nvQDs/nxfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrP +px9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwaivsnuL8wbqg7 +MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI +eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u +2dfOWBfoqSmuc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHS +v4ilf0X8rLiltTMMgsT7B/Zq5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTC +wPTxGfARKbalGAKb12NMcIxHowNDXLldRqANb/9Zjr7dn3LDWyvfjFvO5QxGbJKy +CqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tNf1zuacpzEPuKqf2e +vTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi5Dp6 +Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIa +Gl6I6lD4WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeL +eG9QgkRQP2YGiqtDhFZKDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8 +FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGyeUN51q1veieQA6TqJIc/2b3Z6fJfUEkc +7uzXLg== +-----END CERTIFICATE----- + +# Issuer: CN=IdenTrust Commercial Root CA 1 O=IdenTrust +# Subject: CN=IdenTrust Commercial Root CA 1 O=IdenTrust +# Label: "IdenTrust Commercial Root CA 1" +# Serial: 13298821034946342390520003877796839426 +# MD5 Fingerprint: b3:3e:77:73:75:ee:a0:d3:e3:7e:49:63:49:59:bb:c7 +# SHA1 Fingerprint: df:71:7e:aa:4a:d9:4e:c9:55:84:99:60:2d:48:de:5f:bc:f0:3a:25 +# SHA256 Fingerprint: 5d:56:49:9b:e4:d2:e0:8b:cf:ca:d0:8a:3e:38:72:3d:50:50:3b:de:70:69:48:e4:2f:55:60:30:19:e5:28:ae +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu +VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw +MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw +JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT +3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU ++ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp +S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1 +bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi +T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL +vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK +Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK +dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT +c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv +l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N +iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD +ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH +6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt +LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93 +nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3 ++wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK +W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT +AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq +l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG +4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ +mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A +7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H +-----END CERTIFICATE----- + +# Issuer: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust +# Subject: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust +# Label: "IdenTrust Public Sector Root CA 1" +# Serial: 13298821034946342390521976156843933698 +# MD5 Fingerprint: 37:06:a5:b0:fc:89:9d:ba:f4:6b:8c:1a:64:cd:d5:ba +# SHA1 Fingerprint: ba:29:41:60:77:98:3f:f4:f3:ef:f2:31:05:3b:2e:ea:6d:4d:45:fd +# SHA256 Fingerprint: 30:d0:89:5a:9a:44:8a:26:20:91:63:55:22:d1:f5:20:10:b5:86:7a:ca:e1:2c:78:ef:95:8f:d4:f4:38:9f:2f +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu +VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN +MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0 +MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7 +ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy +RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS +bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF +/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R +3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw +EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy +9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V +GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ +2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV +WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD +W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN +AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj +t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV +DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9 +TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G +lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW +mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df +WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5 ++bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ +tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA +GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv +8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only +# Subject: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only +# Label: "Entrust Root Certification Authority - G2" +# Serial: 1246989352 +# MD5 Fingerprint: 4b:e2:c9:91:96:65:0c:f4:0e:5a:93:92:a0:0a:fe:b2 +# SHA1 Fingerprint: 8c:f4:27:fd:79:0c:3a:d1:66:06:8d:e8:1e:57:ef:bb:93:22:72:d4 +# SHA256 Fingerprint: 43:df:57:74:b0:3e:7f:ef:5f:e4:0d:93:1a:7b:ed:f1:bb:2e:6b:42:73:8c:4e:6d:38:41:10:3d:3a:a7:f3:39 +-----BEGIN CERTIFICATE----- +MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 +cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs +IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz +dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy +NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu +dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt +dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 +aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T +RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN +cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW +wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1 +U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0 +jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN +BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/ +jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ +Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v +1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R +nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH +VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only +# Subject: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only +# Label: "Entrust Root Certification Authority - EC1" +# Serial: 51543124481930649114116133369 +# MD5 Fingerprint: b6:7e:1d:f0:58:c5:49:6c:24:3b:3d:ed:98:18:ed:bc +# SHA1 Fingerprint: 20:d8:06:40:df:9b:25:f5:12:25:3a:11:ea:f7:59:8a:eb:14:b5:47 +# SHA256 Fingerprint: 02:ed:0e:b2:8c:14:da:45:16:5c:56:67:91:70:0d:64:51:d7:fb:56:f0:b2:ab:1d:3b:8e:b0:70:e5:6e:df:f5 +-----BEGIN CERTIFICATE----- +MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG +A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3 +d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu +dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq +RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy +MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD +VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 +L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g +Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi +A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt +ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH +Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O +BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC +R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX +hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G +-----END CERTIFICATE----- + +# Issuer: CN=CFCA EV ROOT O=China Financial Certification Authority +# Subject: CN=CFCA EV ROOT O=China Financial Certification Authority +# Label: "CFCA EV ROOT" +# Serial: 407555286 +# MD5 Fingerprint: 74:e1:b6:ed:26:7a:7a:44:30:33:94:ab:7b:27:81:30 +# SHA1 Fingerprint: e2:b8:29:4b:55:84:ab:6b:58:c2:90:46:6c:ac:3f:b8:39:8f:84:83 +# SHA256 Fingerprint: 5c:c3:d7:8e:4e:1d:5e:45:54:7a:04:e6:87:3e:64:f9:0c:f9:53:6d:1c:cc:2e:f8:00:f3:55:c4:c5:fd:70:fd +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD +TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y +aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx +MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j +aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP +T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03 +sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL +TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5 +/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp +7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz +EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt +hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP +a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot +aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg +TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV +PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv +cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL +tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd +BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB +ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT +ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL +jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS +ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy +P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19 +xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d +Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN +5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe +/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z +AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ +5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su +-----END CERTIFICATE----- + +# Issuer: CN=Certinomis - Root CA O=Certinomis OU=0002 433998903 +# Subject: CN=Certinomis - Root CA O=Certinomis OU=0002 433998903 +# Label: "Certinomis - Root CA" +# Serial: 1 +# MD5 Fingerprint: 14:0a:fd:8d:a8:28:b5:38:69:db:56:7e:61:22:03:3f +# SHA1 Fingerprint: 9d:70:bb:01:a5:a4:a0:18:11:2e:f7:1c:01:b9:32:c5:34:e7:88:a8 +# SHA256 Fingerprint: 2a:99:f5:bc:11:74:b7:3c:bb:1d:62:08:84:e0:1c:34:e5:1c:cb:39:78:da:12:5f:0e:33:26:88:83:bf:41:58 +-----BEGIN CERTIFICATE----- +MIIFkjCCA3qgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJGUjET +MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxHTAb +BgNVBAMTFENlcnRpbm9taXMgLSBSb290IENBMB4XDTEzMTAyMTA5MTcxOFoXDTMz +MTAyMTA5MTcxOFowWjELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMx +FzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMR0wGwYDVQQDExRDZXJ0aW5vbWlzIC0g +Um9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANTMCQosP5L2 +fxSeC5yaah1AMGT9qt8OHgZbn1CF6s2Nq0Nn3rD6foCWnoR4kkjW4znuzuRZWJfl +LieY6pOod5tK8O90gC3rMB+12ceAnGInkYjwSond3IjmFPnVAy//ldu9n+ws+hQV +WZUKxkd8aRi5pwP5ynapz8dvtF4F/u7BUrJ1Mofs7SlmO/NKFoL21prbcpjp3vDF +TKWrteoB4owuZH9kb/2jJZOLyKIOSY008B/sWEUuNKqEUL3nskoTuLAPrjhdsKkb +5nPJWqHZZkCqqU2mNAKthH6yI8H7KsZn9DS2sJVqM09xRLWtwHkziOC/7aOgFLSc +CbAK42C++PhmiM1b8XcF4LVzbsF9Ri6OSyemzTUK/eVNfaoqoynHWmgE6OXWk6Ri +wsXm9E/G+Z8ajYJJGYrKWUM66A0ywfRMEwNvbqY/kXPLynNvEiCL7sCCeN5LLsJJ +wx3tFvYk9CcbXFcx3FXuqB5vbKziRcxXV4p1VxngtViZSTYxPDMBbRZKzbgqg4SG +m/lg0h9tkQPTYKbVPZrdd5A9NaSfD171UkRpucC63M9933zZxKyGIjK8e2uR73r4 +F2iw4lNVYC2vPsKD2NkJK/DAZNuHi5HMkesE/Xa0lZrmFAYb1TQdvtj/dBxThZng +WVJKYe2InmtJiUZ+IFrZ50rlau7SZRFDAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTvkUz1pcMw6C8I6tNxIqSSaHh0 +2TAfBgNVHSMEGDAWgBTvkUz1pcMw6C8I6tNxIqSSaHh02TANBgkqhkiG9w0BAQsF +AAOCAgEAfj1U2iJdGlg+O1QnurrMyOMaauo++RLrVl89UM7g6kgmJs95Vn6RHJk/ +0KGRHCwPT5iVWVO90CLYiF2cN/z7ZMF4jIuaYAnq1fohX9B0ZedQxb8uuQsLrbWw +F6YSjNRieOpWauwK0kDDPAUwPk2Ut59KA9N9J0u2/kTO+hkzGm2kQtHdzMjI1xZS +g081lLMSVX3l4kLr5JyTCcBMWwerx20RoFAXlCOotQqSD7J6wWAsOMwaplv/8gzj +qh8c3LigkyfeY+N/IZ865Z764BNqdeuWXGKRlI5nU7aJ+BIJy29SWwNyhlCVCNSN +h4YVH5Uk2KRvms6knZtt0rJ2BobGVgjF6wnaNsIbW0G+YSrjcOa4pvi2WsS9Iff/ +ql+hbHY5ZtbqTFXhADObE5hjyW/QASAJN1LnDE8+zbz1X5YnpyACleAu6AdBBR8V +btaw5BngDwKTACdyxYvRVB9dSsNAl35VpnzBMwQUAR1JIGkLGZOdblgi90AMRgwj +Y/M50n92Uaf0yKHxDHYiI0ZSKS3io0EHVmmY0gUJvGnHWmHNj4FgFU2A3ZDifcRQ +8ow7bkrHxuaAKzyBvBGAFhAn1/DNP3nMcyrDflOR1m749fPH0FFNjkulW+YZFzvW +gQncItzujrnEj1PhZ7szuIgVRs/taTX/dQ1G885x4cVrhkIGuUE= +-----END CERTIFICATE----- + +# Issuer: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed +# Subject: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed +# Label: "OISTE WISeKey Global Root GB CA" +# Serial: 157768595616588414422159278966750757568 +# MD5 Fingerprint: a4:eb:b9:61:28:2e:b7:2f:98:b0:35:26:90:99:51:1d +# SHA1 Fingerprint: 0f:f9:40:76:18:d3:d7:6a:4b:98:f0:a8:35:9e:0c:fd:27:ac:cc:ed +# SHA256 Fingerprint: 6b:9c:08:e8:6e:b0:f7:67:cf:ad:65:cd:98:b6:21:49:e5:49:4a:67:f5:84:5e:7b:d1:ed:01:9f:27:b8:6b:d6 +-----BEGIN CERTIFICATE----- +MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt +MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg +Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i +YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x +CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG +b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh +bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3 +HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx +WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX +1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk +u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P +99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r +M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB +BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh +cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5 +gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO +ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf +aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic +Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= +-----END CERTIFICATE----- + +# Issuer: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. +# Subject: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. +# Label: "SZAFIR ROOT CA2" +# Serial: 357043034767186914217277344587386743377558296292 +# MD5 Fingerprint: 11:64:c1:89:b0:24:b1:8c:b1:07:7e:89:9e:51:9e:99 +# SHA1 Fingerprint: e2:52:fa:95:3f:ed:db:24:60:bd:6e:28:f3:9c:cc:cf:5e:b3:3f:de +# SHA256 Fingerprint: a1:33:9d:33:28:1a:0b:56:e5:57:d3:d3:2b:1c:e7:f9:36:7e:b0:94:bd:5f:a7:2a:7e:50:04:c8:de:d7:ca:fe +-----BEGIN CERTIFICATE----- +MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL +BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6 +ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw +NzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L +cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYDVQQDDA9TWkFGSVIg +Uk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5QqEvN +QLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT +3PSQ1hNKDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw +3gAeqDRHu5rr/gsUvTaE2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr6 +3fE9biCloBK0TXC5ztdyO4mTp4CEHCdJckm1/zuVnsHMyAHs6A6KCpbns6aH5db5 +BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwiieDhZNRnvDF5YTy7ykHN +XGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsF +AAOCAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw +8PRBEew/R40/cof5O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOG +nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP +oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy +d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg +LvWpCz/UXeHPhJ/iGcJfitYgHuNztw== +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Network CA 2" +# Serial: 44979900017204383099463764357512596969 +# MD5 Fingerprint: 6d:46:9e:d9:25:6d:08:23:5b:5e:74:7d:1e:27:db:f2 +# SHA1 Fingerprint: d3:dd:48:3e:2b:bf:4c:05:e8:af:10:f5:fa:76:26:cf:d3:dc:30:92 +# SHA256 Fingerprint: b6:76:f2:ed:da:e8:77:5c:d3:6c:b0:f6:3c:d1:d4:60:39:61:f4:9e:62:65:ba:01:3a:2f:03:07:b6:d0:b8:04 +-----BEGIN CERTIFICATE----- +MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB +gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu +QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG +A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz +OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ +VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3 +b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA +DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn +0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB +OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE +fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E +Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m +o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i +sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW +OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez +Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS +adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n +3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ +F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf +CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29 +XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm +djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/ +WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb +AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq +P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko +b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj +XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P +5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi +DrW5viSP +-----END CERTIFICATE----- + +# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions RootCA 2015" +# Serial: 0 +# MD5 Fingerprint: ca:ff:e2:db:03:d9:cb:4b:e9:0f:ad:84:fd:7b:18:ce +# SHA1 Fingerprint: 01:0c:06:95:a6:98:19:14:ff:bf:5f:c6:b0:b6:95:ea:29:e9:12:a6 +# SHA256 Fingerprint: a0:40:92:9a:02:ce:53:b4:ac:f4:f2:ff:c6:98:1c:e4:49:6f:75:5e:6d:45:fe:0b:2a:69:2b:cd:52:52:3f:36 +-----BEGIN CERTIFICATE----- +MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix +DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k +IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT +N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v +dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG +A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh +ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx +QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA +4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0 +AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10 +4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C +ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV +9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD +gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6 +Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq +NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko +LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc +Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd +ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I +XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI +M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot +9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V +Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea +j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh +X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ +l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf +bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4 +pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK +e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0 +vm9qp/UsQu0yrbYhnr68 +-----END CERTIFICATE----- + +# Issuer: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions ECC RootCA 2015" +# Serial: 0 +# MD5 Fingerprint: 81:e5:b4:17:eb:c2:f5:e1:4b:0d:41:7b:49:92:fe:ef +# SHA1 Fingerprint: 9f:f1:71:8d:92:d5:9a:f3:7d:74:97:b4:bc:6f:84:68:0b:ba:b6:66 +# SHA256 Fingerprint: 44:b5:45:aa:8a:25:e6:5a:73:ca:15:dc:27:fc:36:d2:4c:1c:b9:95:3a:06:65:39:b1:15:82:dc:48:7b:48:33 +-----BEGIN CERTIFICATE----- +MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN +BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl +bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv +b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ +BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj +YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5 +MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0 +dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg +QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa +jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi +C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep +lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof +TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR +-----END CERTIFICATE----- + +# Issuer: CN=ISRG Root X1 O=Internet Security Research Group +# Subject: CN=ISRG Root X1 O=Internet Security Research Group +# Label: "ISRG Root X1" +# Serial: 172886928669790476064670243504169061120 +# MD5 Fingerprint: 0c:d2:f9:e0:da:17:73:e9:ed:86:4d:a5:e3:70:e7:4e +# SHA1 Fingerprint: ca:bd:2a:79:a1:07:6a:31:f2:1d:25:36:35:cb:03:9d:43:29:a5:e8 +# SHA256 Fingerprint: 96:bc:ec:06:26:49:76:f3:74:60:77:9a:cf:28:c5:a7:cf:e8:a3:c0:aa:e1:1a:8f:fc:ee:05:c0:bd:df:08:c6 +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 +WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu +ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc +h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ +0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U +A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW +T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH +B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC +B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv +KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn +OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn +jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw +qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI +rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq +hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ +3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK +NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 +ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur +TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC +jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc +oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq +4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA +mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d +emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- + +# Issuer: O=FNMT-RCM OU=AC RAIZ FNMT-RCM +# Subject: O=FNMT-RCM OU=AC RAIZ FNMT-RCM +# Label: "AC RAIZ FNMT-RCM" +# Serial: 485876308206448804701554682760554759 +# MD5 Fingerprint: e2:09:04:b4:d3:bd:d1:a0:14:fd:1a:d2:47:c4:57:1d +# SHA1 Fingerprint: ec:50:35:07:b2:15:c4:95:62:19:e2:a8:9a:5b:42:99:2c:4c:2c:20 +# SHA256 Fingerprint: eb:c5:57:0c:29:01:8c:4d:67:b1:aa:12:7b:af:12:f7:03:b4:61:1e:bc:17:b7:da:b5:57:38:94:17:9b:93:fa +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx +CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ +WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ +BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG +Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/ +yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf +BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz +WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF +tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z +374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC +IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL +mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7 +wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS +MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2 +ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet +UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H +YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3 +LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD +nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1 +RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM +LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf +77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N +JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm +fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp +6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp +1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B +9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok +RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv +uu8wd+RU4riEmViAqhOLUTpPSPaLtrM= +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 1 O=Amazon +# Subject: CN=Amazon Root CA 1 O=Amazon +# Label: "Amazon Root CA 1" +# Serial: 143266978916655856878034712317230054538369994 +# MD5 Fingerprint: 43:c6:bf:ae:ec:fe:ad:2f:18:c6:88:68:30:fc:c8:e6 +# SHA1 Fingerprint: 8d:a7:f9:65:ec:5e:fc:37:91:0f:1c:6e:59:fd:c1:cc:6a:6e:de:16 +# SHA256 Fingerprint: 8e:cd:e6:88:4f:3d:87:b1:12:5b:a3:1a:c3:fc:b1:3d:70:16:de:7f:57:cc:90:4f:e1:cb:97:c6:ae:98:19:6e +-----BEGIN CERTIFICATE----- +MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj +ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM +9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw +IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6 +VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L +93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm +jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA +A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI +U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs +N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv +o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU +5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy +rqXRfboQnoZsG4q5WTP468SQvvG5 +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 2 O=Amazon +# Subject: CN=Amazon Root CA 2 O=Amazon +# Label: "Amazon Root CA 2" +# Serial: 143266982885963551818349160658925006970653239 +# MD5 Fingerprint: c8:e5:8d:ce:a8:42:e2:7a:c0:2a:5c:7c:9e:26:bf:66 +# SHA1 Fingerprint: 5a:8c:ef:45:d7:a6:98:59:76:7a:8c:8b:44:96:b5:78:cf:47:4b:1a +# SHA256 Fingerprint: 1b:a5:b2:aa:8c:65:40:1a:82:96:01:18:f8:0b:ec:4f:62:30:4d:83:ce:c4:71:3a:19:c3:9c:01:1e:a4:6d:b4 +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK +gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ +W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg +1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K +8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r +2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me +z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR +8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj +mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz +7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6 ++XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI +0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB +Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm +UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2 +LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY ++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS +k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl +7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm +btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl +urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+ +fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63 +n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE +76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H +9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT +4PsJYGw= +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 3 O=Amazon +# Subject: CN=Amazon Root CA 3 O=Amazon +# Label: "Amazon Root CA 3" +# Serial: 143266986699090766294700635381230934788665930 +# MD5 Fingerprint: a0:d4:ef:0b:f7:b5:d8:49:95:2a:ec:f5:c4:fc:81:87 +# SHA1 Fingerprint: 0d:44:dd:8c:3c:8c:1a:1a:58:75:64:81:e9:0f:2e:2a:ff:b3:d2:6e +# SHA256 Fingerprint: 18:ce:6c:fe:7b:f1:4e:60:b2:e3:47:b8:df:e8:68:cb:31:d0:2e:bb:3a:da:27:15:69:f5:03:43:b4:6d:b3:a4 +-----BEGIN CERTIFICATE----- +MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl +ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr +ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr +BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM +YyRIHN8wfdVoOw== +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 4 O=Amazon +# Subject: CN=Amazon Root CA 4 O=Amazon +# Label: "Amazon Root CA 4" +# Serial: 143266989758080763974105200630763877849284878 +# MD5 Fingerprint: 89:bc:27:d5:eb:17:8d:06:6a:69:d5:fd:89:47:b4:cd +# SHA1 Fingerprint: f6:10:84:07:d6:f8:bb:67:98:0c:c2:e2:44:c2:eb:ae:1c:ef:63:be +# SHA256 Fingerprint: e3:5d:28:41:9e:d0:20:25:cf:a6:90:38:cd:62:39:62:45:8d:a5:c6:95:fb:de:a3:c2:2b:0b:fb:25:89:70:92 +-----BEGIN CERTIFICATE----- +MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi +9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk +M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB +MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw +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" +# Serial: 1 +# MD5 Fingerprint: dc:00:81:dc:69:2f:3e:2f:b0:3b:f6:3d:5a:91:8e:49 +# SHA1 Fingerprint: 31:43:64:9b:ec:ce:27:ec:ed:3a:3f:0b:8f:0d:e4:e8:91:dd:ee:ca +# SHA256 Fingerprint: 46:ed:c3:68:90:46:d5:3a:45:3f:b3:10:4a:b8:0d:ca:ec:65:8b:26:60:ea:16:29:dd:7e:86:79:90:64:87:16 +-----BEGIN CERTIFICATE----- +MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx +GDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp +bXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w +KwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24gTWVya2V6aSAtIEthbXUgU00xNjA0 +BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRpZmlrYXNpIC0gU3Vy +dW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYDVQQG +EwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXll +IEJpbGltc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklU +QUsxLTArBgNVBAsTJEthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBT +TTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11IFNNIFNTTCBLb2sgU2VydGlmaWthc2kg +LSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr3UwM6q7 +a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y86Ij5iySr +LqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INr +N3wcwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2X +YacQuFWQfw4tJzh03+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/ +iSIzL+aFCr2lqBs23tPcLG07xxO9WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4f +AJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQUZT/HiobGPN08VFw1+DrtUgxH +V8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh +AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPf +IPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4 +lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c +8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf +lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM= +-----END CERTIFICATE----- + +# Issuer: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD. +# Subject: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD. +# Label: "GDCA TrustAUTH R5 ROOT" +# Serial: 9009899650740120186 +# MD5 Fingerprint: 63:cc:d9:3d:34:35:5c:6f:53:a3:e2:08:70:48:1f:b4 +# SHA1 Fingerprint: 0f:36:38:5b:81:1a:25:c3:9b:31:4e:83:ca:e9:34:66:70:cc:74:b4 +# SHA256 Fingerprint: bf:ff:8f:d0:44:33:48:7d:6a:8a:a6:0c:1a:29:76:7a:9f:c2:bb:b0:5e:42:0f:71:3a:13:b9:92:89:1d:38:93 +-----BEGIN CERTIFICATE----- +MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE +BhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ +IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0 +MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVowYjELMAkGA1UEBhMCQ04xMjAwBgNV +BAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8w +HQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJj +Dp6L3TQsAlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBj +TnnEt1u9ol2x8kECK62pOqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+u +KU49tm7srsHwJ5uu4/Ts765/94Y9cnrrpftZTqfrlYwiOXnhLQiPzLyRuEH3FMEj +qcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ9Cy5WmYqsBebnh52nUpm +MUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQxXABZG12 +ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloP +zgsMR6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3Gk +L30SgLdTMEZeS1SZD2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeC +jGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4oR24qoAATILnsn8JuLwwoC8N9VKejveSswoA +HQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx9hoh49pwBiFYFIeFd3mqgnkC +AwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlRMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg +p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZm +DRd9FBUb1Ov9H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5 +COmSdI31R9KrO9b7eGZONn356ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ry +L3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd+PwyvzeG5LuOmCd+uh8W4XAR8gPf +JWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQHtZa37dG/OaG+svg +IHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBDF8Io +2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV +09tL7ECQ8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQ +XR4EzzffHqhmsYzmIGrv/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrq +T8p+ck0LcIymSLumoRT2+1hEmRSuqguTaaApJUqlyyvdimYHFngVV3Eb7PVHhPOe +MTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g== +-----END CERTIFICATE----- + +# Issuer: CN=TrustCor RootCert CA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Subject: CN=TrustCor RootCert CA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Label: "TrustCor RootCert CA-1" +# Serial: 15752444095811006489 +# MD5 Fingerprint: 6e:85:f1:dc:1a:00:d3:22:d5:b2:b2:ac:6b:37:05:45 +# SHA1 Fingerprint: ff:bd:cd:e7:82:c8:43:5e:3c:6f:26:86:5c:ca:a8:3a:45:5b:c3:0a +# SHA256 Fingerprint: d4:0e:9c:86:cd:8f:e4:68:c1:77:69:59:f4:9e:a7:74:fa:54:86:84:b6:c4:06:f3:90:92:61:f4:dc:e2:57:5c +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIJANqb7HHzA7AZMA0GCSqGSIb3DQEBCwUAMIGkMQswCQYD +VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk +MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U +cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29y +IFJvb3RDZXJ0IENBLTEwHhcNMTYwMjA0MTIzMjE2WhcNMjkxMjMxMTcyMzE2WjCB +pDELMAkGA1UEBhMCUEExDzANBgNVBAgMBlBhbmFtYTEUMBIGA1UEBwwLUGFuYW1h +IENpdHkxJDAiBgNVBAoMG1RydXN0Q29yIFN5c3RlbXMgUy4gZGUgUi5MLjEnMCUG +A1UECwweVHJ1c3RDb3IgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYDVQQDDBZU +cnVzdENvciBSb290Q2VydCBDQS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAv463leLCJhJrMxnHQFgKq1mqjQCj/IDHUHuO1CAmujIS2CNUSSUQIpid +RtLByZ5OGy4sDjjzGiVoHKZaBeYei0i/mJZ0PmnK6bV4pQa81QBeCQryJ3pS/C3V +seq0iWEk8xoT26nPUu0MJLq5nux+AHT6k61sKZKuUbS701e/s/OojZz0JEsq1pme +9J7+wH5COucLlVPat2gOkEz7cD+PSiyU8ybdY2mplNgQTsVHCJCZGxdNuWxu72CV +EY4hgLW9oHPY0LJ3xEXqWib7ZnZ2+AYfYW0PVcWDtxBWcgYHpfOxGgMFZA6dWorW +hnAbJN7+KIor0Gqw/Hqi3LJ5DotlDwIDAQABo2MwYTAdBgNVHQ4EFgQU7mtJPHo/ +DeOxCbeKyKsZn3MzUOcwHwYDVR0jBBgwFoAU7mtJPHo/DeOxCbeKyKsZn3MzUOcw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD +ggEBACUY1JGPE+6PHh0RU9otRCkZoB5rMZ5NDp6tPVxBb5UrJKF5mDo4Nvu7Zp5I +/5CQ7z3UuJu0h3U/IJvOcs+hVcFNZKIZBqEHMwwLKeXx6quj7LUKdJDHfXLy11yf +ke+Ri7fc7Waiz45mO7yfOgLgJ90WmMCV1Aqk5IGadZQ1nJBfiDcGrVmVCrDRZ9MZ +yonnMlo2HD6CqFqTvsbQZJG2z9m2GM/bftJlo6bEjhcxwft+dtvTheNYsnd6djts +L1Ac59v2Z3kf9YKVmgenFK+P3CghZwnS1k1aHBkcjndcw5QkPTJrS37UeJSDvjdN +zl/HHk484IkzlQsPpTLWPFp5LBk= +-----END CERTIFICATE----- + +# Issuer: CN=TrustCor RootCert CA-2 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Subject: CN=TrustCor RootCert CA-2 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Label: "TrustCor RootCert CA-2" +# Serial: 2711694510199101698 +# MD5 Fingerprint: a2:e1:f8:18:0b:ba:45:d5:c7:41:2a:bb:37:52:45:64 +# SHA1 Fingerprint: b8:be:6d:cb:56:f1:55:b9:63:d4:12:ca:4e:06:34:c7:94:b2:1c:c0 +# SHA256 Fingerprint: 07:53:e9:40:37:8c:1b:d5:e3:83:6e:39:5d:ae:a5:cb:83:9e:50:46:f1:bd:0e:ae:19:51:cf:10:fe:c7:c9:65 +-----BEGIN CERTIFICATE----- +MIIGLzCCBBegAwIBAgIIJaHfyjPLWQIwDQYJKoZIhvcNAQELBQAwgaQxCzAJBgNV +BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw +IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy +dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEfMB0GA1UEAwwWVHJ1c3RDb3Ig +Um9vdENlcnQgQ0EtMjAeFw0xNjAyMDQxMjMyMjNaFw0zNDEyMzExNzI2MzlaMIGk +MQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEg +Q2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYD +VQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRy +dXN0Q29yIFJvb3RDZXJ0IENBLTIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCnIG7CKqJiJJWQdsg4foDSq8GbZQWU9MEKENUCrO2fk8eHyLAnK0IMPQo+ +QVqedd2NyuCb7GgypGmSaIwLgQ5WoD4a3SwlFIIvl9NkRvRUqdw6VC0xK5mC8tkq +1+9xALgxpL56JAfDQiDyitSSBBtlVkxs1Pu2YVpHI7TYabS3OtB0PAx1oYxOdqHp +2yqlO/rOsP9+aij9JxzIsekp8VduZLTQwRVtDr4uDkbIXvRR/u8OYzo7cbrPb1nK +DOObXUm4TOJXsZiKQlecdu/vvdFoqNL0Cbt3Nb4lggjEFixEIFapRBF37120Hape +az6LMvYHL1cEksr1/p3C6eizjkxLAjHZ5DxIgif3GIJ2SDpxsROhOdUuxTTCHWKF +3wP+TfSvPd9cW436cOGlfifHhi5qjxLGhF5DUVCcGZt45vz27Ud+ez1m7xMTiF88 +oWP7+ayHNZ/zgp6kPwqcMWmLmaSISo5uZk3vFsQPeSghYA2FFn3XVDjxklb9tTNM +g9zXEJ9L/cb4Qr26fHMC4P99zVvh1Kxhe1fVSntb1IVYJ12/+CtgrKAmrhQhJ8Z3 +mjOAPF5GP/fDsaOGM8boXg25NSyqRsGFAnWAoOsk+xWq5Gd/bnc/9ASKL3x74xdh +8N0JqSDIvgmk0H5Ew7IwSjiqqewYmgeCK9u4nBit2uBGF6zPXQIDAQABo2MwYTAd +BgNVHQ4EFgQU2f4hQG6UnrybPZx9mCAZ5YwwYrIwHwYDVR0jBBgwFoAU2f4hQG6U +nrybPZx9mCAZ5YwwYrIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYw +DQYJKoZIhvcNAQELBQADggIBAJ5Fngw7tu/hOsh80QA9z+LqBrWyOrsGS2h60COX +dKcs8AjYeVrXWoSK2BKaG9l9XE1wxaX5q+WjiYndAfrs3fnpkpfbsEZC89NiqpX+ +MWcUaViQCqoL7jcjx1BRtPV+nuN79+TMQjItSQzL/0kMmx40/W5ulop5A7Zv2wnL +/V9lFDfhOPXzYRZY5LVtDQsEGz9QLX+zx3oaFoBg+Iof6Rsqxvm6ARppv9JYx1RX +CI/hOWB3S6xZhBqI8d3LT3jX5+EzLfzuQfogsL7L9ziUwOHQhQ+77Sxzq+3+knYa +ZH9bDTMJBzN7Bj8RpFxwPIXAz+OQqIN3+tvmxYxoZxBnpVIt8MSZj3+/0WvitUfW +2dCFmU2Umw9Lje4AWkcdEQOsQRivh7dvDDqPys/cA8GiCcjl/YBeyGBCARsaU1q7 +N6a3vLqE6R5sGtRk2tRD/pOLS/IseRYQ1JMLiI+h2IYURpFHmygk71dSTlxCnKr3 +Sewn6EAes6aJInKc9Q0ztFijMDvd1GpUk74aTfOTlPf8hAs/hCBcNANExdqtvArB +As8e5ZTZ845b2EzwnexhF7sUMlQMAimTHpKG9n/v55IFDlndmQguLvqcAFLTxWYp +5KeXRKQOKIETNcX2b2TmQcTVL8w0RSXPQQCWPUouwpaYT05KnJe32x+SMsj/D1Fu +1uwJ +-----END CERTIFICATE----- + +# Issuer: CN=TrustCor ECA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Subject: CN=TrustCor ECA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Label: "TrustCor ECA-1" +# Serial: 9548242946988625984 +# MD5 Fingerprint: 27:92:23:1d:0a:f5:40:7c:e9:e6:6b:9d:d8:f5:e7:6c +# SHA1 Fingerprint: 58:d1:df:95:95:67:6b:63:c0:f0:5b:1c:17:4d:8b:84:0b:c8:78:bd +# SHA256 Fingerprint: 5a:88:5d:b1:9c:01:d9:12:c5:75:93:88:93:8c:af:bb:df:03:1a:b2:d4:8e:91:ee:15:58:9b:42:97:1d:03:9c +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIJAISCLF8cYtBAMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYD +VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk +MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U +cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxFzAVBgNVBAMMDlRydXN0Q29y +IEVDQS0xMB4XDTE2MDIwNDEyMzIzM1oXDTI5MTIzMTE3MjgwN1owgZwxCzAJBgNV +BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw +IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy +dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEXMBUGA1UEAwwOVHJ1c3RDb3Ig +RUNBLTEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPj+ARtZ+odnbb +3w9U73NjKYKtR8aja+3+XzP4Q1HpGjORMRegdMTUpwHmspI+ap3tDvl0mEDTPwOA +BoJA6LHip1GnHYMma6ve+heRK9jGrB6xnhkB1Zem6g23xFUfJ3zSCNV2HykVh0A5 +3ThFEXXQmqc04L/NyFIduUd+Dbi7xgz2c1cWWn5DkR9VOsZtRASqnKmcp0yJF4Ou +owReUoCLHhIlERnXDH19MURB6tuvsBzvgdAsxZohmz3tQjtQJvLsznFhBmIhVE5/ +wZ0+fyCMgMsq2JdiyIMzkX2woloPV+g7zPIlstR8L+xNxqE6FXrntl019fZISjZF +ZtS6mFjBAgMBAAGjYzBhMB0GA1UdDgQWBBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAf +BgNVHSMEGDAWgBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAPBgNVHRMBAf8EBTADAQH/ +MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEABT41XBVwm8nHc2Fv +civUwo/yQ10CzsSUuZQRg2dd4mdsdXa/uwyqNsatR5Nj3B5+1t4u/ukZMjgDfxT2 +AHMsWbEhBuH7rBiVDKP/mZb3Kyeb1STMHd3BOuCYRLDE5D53sXOpZCz2HAF8P11F +hcCF5yWPldwX8zyfGm6wyuMdKulMY/okYWLW2n62HGz1Ah3UKt1VkOsqEUc8Ll50 +soIipX1TH0XsJ5F95yIW6MBoNtjG8U+ARDL54dHRHareqKucBK+tIA5kmE2la8BI +WJZpTdwHjFGTot+fDz2LYLSCjaoITmJF4PkL0uDgPFveXHEnJcLmA4GLEFPjx1Wi +tJ/X5g== +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com Root Certification Authority RSA O=SSL Corporation +# Subject: CN=SSL.com Root Certification Authority RSA O=SSL Corporation +# Label: "SSL.com Root Certification Authority RSA" +# Serial: 8875640296558310041 +# MD5 Fingerprint: 86:69:12:c0:70:f1:ec:ac:ac:c2:d5:bc:a5:5b:a1:29 +# SHA1 Fingerprint: b7:ab:33:08:d1:ea:44:77:ba:14:80:12:5a:6f:bd:a9:36:49:0c:bb +# SHA256 Fingerprint: 85:66:6a:56:2e:e0:be:5c:e9:25:c1:d8:89:0a:6f:76:a8:7e:c1:6d:4d:7d:5f:29:ea:74:19:cf:20:12:3b:69 +-----BEGIN CERTIFICATE----- +MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE +BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK +DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz +OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv +bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN +AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R +xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX +qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC +C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3 +6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh +/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF +YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E +JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc +US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8 +ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm ++Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi +M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G +A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV +cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc +Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs +PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/ +q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0 +cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr +a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I +H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y +K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu +nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf +oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY +Ic2wBlX7Jz9TkHCpBB5XJ7k= +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com Root Certification Authority ECC O=SSL Corporation +# Subject: CN=SSL.com Root Certification Authority ECC O=SSL Corporation +# Label: "SSL.com Root Certification Authority ECC" +# Serial: 8495723813297216424 +# MD5 Fingerprint: 2e:da:e4:39:7f:9c:8f:37:d1:70:9f:26:17:51:3a:8e +# SHA1 Fingerprint: c3:19:7c:39:24:e6:54:af:1b:c4:ab:20:95:7a:e2:c3:0e:13:02:6a +# SHA256 Fingerprint: 34:17:bb:06:cc:60:07:da:1b:96:1c:92:0b:8a:b4:ce:3f:ad:82:0e:4a:a3:0b:9a:cb:c4:a7:4e:bd:ce:bc:65 +-----BEGIN CERTIFICATE----- +MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz +WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0 +b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS +b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB +BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI +7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg +CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud +EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD +VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T +kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+ +gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation +# Subject: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation +# Label: "SSL.com EV Root Certification Authority RSA R2" +# Serial: 6248227494352943350 +# MD5 Fingerprint: e1:1e:31:58:1a:ae:54:53:02:f6:17:6a:11:7b:4d:95 +# SHA1 Fingerprint: 74:3a:f0:52:9b:d0:32:a0:f4:4a:83:cd:d4:ba:a9:7b:7c:2e:c4:9a +# SHA256 Fingerprint: 2e:7b:f1:6c:c2:24:85:a7:bb:e2:aa:86:96:75:07:61:b0:ae:39:be:3b:2f:e9:d0:cc:6d:4e:f7:34:91:42:5c +-----BEGIN CERTIFICATE----- +MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV +BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE +CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy +MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G +A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD +DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq +M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf +OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa +4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9 +HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR +aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA +b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ +Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV +PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO +pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu +UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY +MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV +HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4 +9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW +s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5 +Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg +cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM +79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz +/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt +ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm +Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK +QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ +w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi +S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07 +mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation +# Subject: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation +# Label: "SSL.com EV Root Certification Authority ECC" +# Serial: 3182246526754555285 +# MD5 Fingerprint: 59:53:22:65:83:42:01:54:c0:ce:42:b9:5a:7c:f2:90 +# SHA1 Fingerprint: 4c:dd:51:a3:d1:f5:20:32:14:b0:c6:c5:32:23:03:91:c7:46:42:6d +# SHA256 Fingerprint: 22:a2:c1:f7:bd:ed:70:4c:c1:e7:01:b5:f4:08:c3:10:88:0f:e9:56:b5:de:2a:4a:44:f9:9c:87:3a:25:a7:c8 +-----BEGIN CERTIFICATE----- +MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx +NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv +bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA +VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku +WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP +MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX +5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ +ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg +h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg== +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6 +# Label: "GlobalSign Root CA - R6" +# Serial: 1417766617973444989252670301619537 +# MD5 Fingerprint: 4f:dd:07:e4:d4:22:64:39:1e:0c:37:42:ea:d1:c6:ae +# SHA1 Fingerprint: 80:94:64:0e:b5:a7:a1:ca:11:9c:1f:dd:d5:9f:81:02:63:a7:fb:d1 +# SHA256 Fingerprint: 2c:ab:ea:fe:37:d0:6c:a2:2a:ba:73:91:c0:03:3d:25:98:29:52:c4:53:64:73:49:76:3a:3a:b5:ad:6c:cf:69 +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg +MB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh +bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQx +MjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjET +MBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQssgrRI +xutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1k +ZguSgMpE3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxD +aNc9PIrFsmbVkJq3MQbFvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJw +LnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqMPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw +1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+azayOeSsJDa38O+2HBNX +k7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05OWgtH8wY2 +SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/h +bguyCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4n +WUx2OVvq+aWh2IMP0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpY +rZxCRXluDocZXFSxZba/jJvcE+kNb7gu3GduyYsRtYQUigAZcIN5kZeR1Bonvzce +MgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNVHSMEGDAWgBSu +bAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN +nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGt +Ixg93eFyRJa0lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr61 +55wsTLxDKZmOMNOsIeDjHfrYBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLj +vUYAGm0CuiVdjaExUd1URhxN25mW7xocBFymFe944Hn+Xds+qkxV/ZoVqW/hpvvf +cDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr3TsTjxKM4kEaSHpz +oHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB10jZp +nOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfs +pA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+v +JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R +8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4 +5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA= +-----END CERTIFICATE----- + +# Issuer: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed +# Subject: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed +# Label: "OISTE WISeKey Global Root GC CA" +# Serial: 44084345621038548146064804565436152554 +# MD5 Fingerprint: a9:d6:b9:2d:2f:93:64:f8:a5:69:ca:91:e9:68:07:23 +# SHA1 Fingerprint: e0:11:84:5e:34:de:be:88:81:b9:9c:f6:16:26:d1:96:1f:c3:b9:31 +# SHA256 Fingerprint: 85:60:f9:1c:36:24:da:ba:95:70:b5:fe:a0:db:e3:6f:f1:1a:83:23:be:94:86:85:4f:b3:f3:4a:55:71:19:8d +-----BEGIN CERTIFICATE----- +MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQsw +CQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91 +bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwg +Um9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRaFw00MjA1MDkwOTU4MzNaMG0xCzAJ +BgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBGb3Vu +ZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2JhbCBS +b290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4ni +eUqjFqdrVCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4W +p2OQ0jnUsYd4XxiWD1AbNTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7T +rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV +57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg +Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 +-----END CERTIFICATE----- diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/certifi/core.py b/venv/lib/python3.7/site-packages/pip/_vendor/certifi/core.py new file mode 100644 index 0000000..eab9d1d --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/certifi/core.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +certifi.py +~~~~~~~~~~ + +This module returns the installation location of cacert.pem. +""" +import os +import warnings + + +class DeprecatedBundleWarning(DeprecationWarning): + """ + The weak security bundle is being deprecated. Please bother your service + provider to get them to stop using cross-signed roots. + """ + + +def where(): + f = os.path.dirname(__file__) + + return os.path.join(f, 'cacert.pem') + + +def old_where(): + warnings.warn( + "The weak security bundle has been removed. certifi.old_where() is now an alias " + "of certifi.where(). Please update your code to use certifi.where() instead. " + "certifi.old_where() will be removed in 2018.", + DeprecatedBundleWarning + ) + return where() + +if __name__ == '__main__': + print(where()) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__init__.py new file mode 100644 index 0000000..0f9f820 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__init__.py @@ -0,0 +1,39 @@ +######################## BEGIN LICENSE BLOCK ######################## +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + + +from .compat import PY2, PY3 +from .universaldetector import UniversalDetector +from .version import __version__, VERSION + + +def detect(byte_str): + """ + Detect the encoding of the given byte string. + + :param byte_str: The byte sequence to examine. + :type byte_str: ``bytes`` or ``bytearray`` + """ + if not isinstance(byte_str, bytearray): + if not isinstance(byte_str, bytes): + raise TypeError('Expected object of type bytes or bytearray, got: ' + '{0}'.format(type(byte_str))) + else: + byte_str = bytearray(byte_str) + detector = UniversalDetector() + detector.feed(byte_str) + return detector.close() diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..289b573fe234fe92e33194cf999db6ef5df9797a GIT binary patch literal 852 zcmYjQPjAyO6t|N!$pS+w96;jYBbC@vHvX+b2mzDeG7uX`R7hzWyKP1iXO3Ie(p@M= zKEx_cd?jBw@fA4n?6km>-qU;b`@Q$G{rq%uGe98UZuUQ1cM<xjgSA-TJOQm9f}x1w z4CT0sbE|7%9b1{5J6*^4cGk$<uA6&Z4`PQlzM`&A-6PcUeqn&OEM>obzpKq&3#;ba zBAqZ%#o2QvSt7ZBgiBGR*HT_Yk@DUhyg7RL>M+r0Et*XO^ciUN0*pj+B=N$k+QzfM zyCrRkFC5vJqXk~#1^$8yUt%4dBk3;CIiBMSZ;qB2Bk=qs0*2P?dq6;HDnyPLVMW4e zS_}yvn0N?m3(}uTMk*;_V<#|>P8o|hHyaUbbaWYV3<c^`b~=Vij7Uz{S)8W@+o@r4 zTGl!LP^8z>psLp+T&#jvh<MuT8O-eN!C47c#VFzZ6L1W-b)8CsG~PgNlOdNK^0|H9 z+E77Sr9~xUAfh(@rl^MLrZ$eD#DNf8D0jd`9!uqDcEW)xR?dJisv1egD+Vv*YmBC> ze7btKA4oJI^Y>|3igXf77EWRj4tPf4DZ_jeCU?qcf3|<p{<Jrsv+DldMC_i)S>6U2 z7U6MNrscLFm}T4d9`r{a$NiyRGzt?@P%gq`6bon>Mp0U%GKzM}sd8%$H}pVkfk9q? z1MK1}mJc?-;u@?S!VS0y&&yZ}Jwn0;qnhLO{H@PXpVwOrpwN>h;6oroQIb5+;y UALX2mGxk`wsdVlZzKpl*KXt?J<NyEw literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..616233dc62582994f3d428e7897bb0010efd93af GIT binary patch literal 27187 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cadb3f164846e1e545de8009d0d78bd1f80a22fe GIT binary patch literal 1128 zcmah|%Wl&^6rJ%aZj`jpiiZR%SVf|Bp%hdJAxMfUBvO#V%0e1Bo=IXDJ7#7QNYq^_ zb;C!LCBI~e6)S#$75CZ=4I7wfW{&TT@8jI#cC%S0u)f^tzx(bH@&g~1%K`8VwmyV| z6HX;bX-FwzOIoQN+9kH7le(c>Vn=#uEv!*;M7YbnQ^Gw#7k23LT935+pA<s1XmPze zktS)+jOdIa)f4888ux_)&t_-LlWf>CkrCY}9wnIo>&<pD+&@gTQAvMdl5zGti{wlv z8hp+6%cFhP>$2|a!xyh&NbqOb7f3$@AV^3#39U0Spqz5+)DLapaGN`)WI;n0a9J^6 z?~FJk#ENT09aC53#aKNqyfHRzeGd*p3_T$W>)iSZPGcKq0nf}e-h#kgJ0a&jdN_fY z^tiQFxO$QcrGRr%_>3i4Vi;2xP`PMZi%TAuP8H6fxW-qyXA!nP7picT(82%<juvtN z_ZnldjI?I#8~LS!TqRRrGMGjx7>p$sN(bpEi0|j@V1Dp^_tV~h&-J6dse16)%+p<1 z!z_3k<Vn7rWZFbhZtp+tk3LNLLo}9~O-07XDu`irT$rE_4CUnjck-F?q1?N$H3CA{ zX`T9XzI93C&a&OV_(V=S_!_p$Dez<+7Y@Fq*1^)EssUGtt78Kmiw4#J46rOpMGGw2 zf`eG|8!P!%|MUNxwGN6-i+`o{Wt0sk(NJu!q+D%r>2LWsT`Z2VqRv=4<`apy!Pv)1 zBr8wJS>XeRpb0ZmS0Sp}f}?0&j58Kef<BOmWnE3gNJ1&1I{-AQ$)^pk;gmMi*+$yG zXuq0}LVk+PN?kBtBhu<CE45c#DQCJOwMu;+MA0Bclx7+FvXTmw!|<O}?LEDX#o+iG IwEWq>0gvevZ~y=R literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/chardistribution.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/chardistribution.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a421897f9240119233d60508a7fa846c41f60ef1 GIT binary patch literal 6314 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 W;yn8IZA@$ajKpGMlz-!iss94uoDfU^ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4a33642cf7c85da82aa88f93d75e224779005589 GIT binary patch literal 2235 zcmb_d&2Jk;6rb6h-K-ruEg}7YRw6}3;EL8QEtE>o7Frr{z(s9JC97y;d&XNk>yON= zL+WlMq(<rmZX7r!M=t$G_z(7mIQ7Jx6Tdg>Bn85avESP_Z)RuS$M3!Uyjm?Yj2}+5 zAN{((*zYvi8v?>jkbNIaF~t)$;7!g+_7ZR4H+{}lnDUj_W=d%PncoyDxX)_gOO97+ zJg<ChM(y4(zMr;Ijd}If<CeLvQ&MZw!KVE|x6!coz%*-e#hRX4c+R?9dCK1|HGL=J zhV7^+bf7{tx6PjMW(YY_B`43RvYOv!%}7;L70=RhCRno!n~vm*v&&b^XfiG=XmmVx zDP#2XXJp@lkg}9#?3vg1GOqZK<hGYF>BkIQDB^))IM{E%vH7GmjAgf%q}sfsBWqzE z*vVKMLyqN<l)Ygul`@}~txnq8&~i8#<a1*e2%9g;wzjE^C)!$BC~ICWtWLTnpyPO6 zlCqPuuq=OJe?F~`O>YB1t#7nUy*o;jHnu)^T<=^O%WKnX{fpmS?y9N%=<<g7U^AT# zE@H&P`f7dL8=vnDZQ4qb^B-PqKVF-(V^TVj8+xclrrtrCluq5#>NKW^6;@psKQR#u zIs>vKFuuq`{HCY=9o`FjUUvu&G$_mz5DK+zfbE5O$J=EHF+wi=%?lapi`(qmvs*ml z=5)qqt4M_mG91wNm46k7Nq_zHL*Nl_g)SMQVM3g`Y8(LP%p4{~1_Gnui7AnSFrSA- z9?U!@HP2L>ZWelOs<aOk!ORh2N5S3&SrQmufWs9oc!cL7pPoF#b$8vq-((K?ehXxm z!QdgYCo{Ig$?sxD9+1@c04v_8`Oda{A=atvjE3Ew(!-9<E0i7hB8RO3ipp7Dn0jFE z60W#Jce(QRLT9Pq)3*+>^ws134};C?xHylfA||c)zbrh4P1g>w@Guzd9kpMr1R)|9 z&hH^?Zc^X?nc<d~d3JF<%Dg_eZ_;xIu-WBXe&*YAnER>U7i*rmnNd9hPW=#JC+!@x z5g_PEzz`sdl=m@#EW(~h`D@%nv<q*QinrFIhm<h9UlWZx4s#BEwX%blc@383qN}ws zl>9upbN4~xw)}FnNNj*AOm!YM?ykzOzHrdYL+O+?Q2;V(KS?!I#w_9hbCQ_L@<FPP zL-!fTo&{qLmL6c~@iG8PoT`)f0(b<Po;U;qWaNJGspC-PxbXfA0ZuZi#gz9w1Zhce zgp6iBW^XItRry<<t3$E*2)hHM;+_ln_4O;6-w*9K(9Z2dN?=yn^*AH_PI;GYiP=g( zE1>yI><ZL`mx(oIu4Do!^$~Qje#M1b*q@Y-`>9I8M*L#sx9QT0KW@ZNmq^^c5yN0N zrqy@s@^F+c7nMFehAI9BrL_Dh=Cw)@R?3h$LF^4;)D~XJVwjBLSerahx;=>v)tAG$ zAsp9&q6jHHdC7Hhy2Rxy7f$>~(x^lpfb2Oi<`N{38i8NYStx}^k-mr@2hmyxK0R|t z>i*sysBz5G_lCLyzBgql2O~8}NUlh^K4~SzifiMpvE>ok9zIp+lfo}@$q=lHO0Ld6 zJRO}RQXaq$t;cmq*C44HmqC{LXv7!7O1TnMqG-u=-$pIS1C1}9EefGJ>p4ZcHS{%b Z`wk8-Bsw~eJ}Dfyewxmwiz>Y0{{{4{>+Apk literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/charsetprober.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/charsetprober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a4ad560f95031cebb08020ae625152e968863286 GIT binary patch literal 3445 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3ad5a12de8c720d812bcd9f93d29f04883e0f430 GIT binary patch literal 2892 zcma)8%Wm676djU!(6X$iNsA^(AJa_{p^4-+XoCbrn`gUeoWeG`5DE|!XC%>~NM&Xu z$F8$VmR)z9Ec;8`c9mb~s^<<x$+Fd;Bg~NVI`_^w_YQS`YpcOf{<zxzt=3}fZ|an# zf|t9f`WhO+gp;ry6Rz+QXYBS|hyBDvMO0rgQI+0HuU8Sy9&6X$Vl~@&>!58rdGm1? zjp9`9nb63Hrpn^s<u0mzh(@xWBUsNBPR}C~uNdGgc&{pIqK<w|_+kUkx@d?^Jbk$# znqun}d+GEVq6O3M<rg1hB2I_a*xYdVC(hB}DEGJ~C-}JVh?|Vhq>2YeJmmc&OlbLR zD$_{vL8dS^36+VXX%Z@qQ48GRKW55;Nq`i)%t&$}aX5orN=7oCNqwEih9AaB!Us|c zZbqS*ug<uHRoILS7Fw)Tx58N%Ct*L4*Ljx8Vi$IY+{9zq;rlSRx*-~c=}>A|)TiM3 zp@!isrC~l%au#P(J>MCo<kB1)j+S0qbR~I+dUJ^d=oI!>t=c2e!fb$PBbC&KC=Ic6 zYO)(8C3hMYXm9`C?tTGr2WN<ZsjUwMDmLOp5oczEgA@OW9EQoNG8T%oT$F2Z2c(32 z7ACRaP)YJh27lUCL{OtZv{ZZ)YTlO;bO@Q6co0j`DLi}psB~-YS1RHNaYF8acj9UF z<VytDT?w4C?pXkwQ%__BlM(Slc;uFrhGGP>Lh5*!LM$70R+`Y9hXTX2I?Z?n425HA z9V1K@!O0ItF@iFJ0#TNl5TY3(np`{!SB5$%jwLoy;anm^M1~bH9*?DnDPLeHrdWlv z`VfZU=2<v8R4MqJ)<?U$Pj*XY3&Bqj`z}tQQL@zjtSP>lrk3JmdM;11?kMN6QpDJq zvlXN*As?2xZAp^PqhyL8BWBOTmAm*rWn)r7BUltHAP?;jghR%p9lJGhar053r-%9g zRd1s?aZXr(8yBr(TURi=d#3WbYHDw2yne!7`)`<on;BQ1yQA!dyOGy|F_Iw3TR}8c zDj@L#C|LF>^nygD`DQV1Lp!f0*>H%9Gv63W^E2M1%Kacn!?6s4yhgJasUpXvX}ftv z%Vdzddi)nt7vSzczjr4po*`Jevru&hS%OpR?s(LVzM2HLk8dArAKn~@WBu*Tnfm&< zIUaAL4Abs@cM?x-#3{T;k{jRL>W`jI`$HPEHJHg%WU5O}BfPrBC2U=uU*es~5jh&C zu?d1(L|+pPb87Qn(>cC+{+rM#cSJ-Q6?&2iRsn)A?0{GX?_k&2X?uzU%B%JsQ$F6? zj=~qSAi%Pq-ly&snjcWL71uewyvDrcaiKnaXBX;^&^ciT(EbXd;0k-;qURX*z<cVd zZGm1;vGX40T~roSX@woDTwxzz^dt7dv;8XOX&s{IgjLu<MbvKLm==M))%BfxGfG0O z14ADi8$x-j43T0mZx$;CxJNUUZ(8=}>*<K?nyTVqDX|=>OVq7VQ>Xcgr73r!ykUdU z!sQJcoffPhkK)KOm^V`S+yr*&J_hwgG|X!`O=x<-ZBgsAoa0Z{5WC#DqAaOvl_jr; znL<;iaB!`T`6Xn6O%Z%90-^*-^9#0@x_+_7{F*H*ek>x4{&ZP|ps>x}yh6E#kRmSE zM^=8>!rT8L1v|k!3HDC8_2qxLwPxS{_03Q42V)uz-|e6J3~v0oaK&AlcqP(KdsA&< zZQcmzzM3X<&oqPJ*)&Y%w@y6>L>2{sBK>VzsjKw%F*TpkUVoypiB#sunm!dqi&#>W zTc4w9N>%^EisSpf=eJNjJJ+tN4T7r5bUM~Wj@PpO0shU|`E{VV|6Sqo_vDHu6TaK@ F{sm`@4VwS} literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/compat.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1861365eaad970e718d3c692576a3514a8d96ee6 GIT binary patch literal 363 zcmXwyK~BRk5JjChY169RAjF0X&_!`+1*j52hy_c8L^ni8Q4&wuw25umZfJT2F2a?( zWz{RN!Y<-l^JeCc^!+#-_L0@+dG^i%gudPKFW(Liwv+=!)T>a80IfahZ;-s8IQD4} zV+bHD{I~;Q+-0ZM@$Cge1i{e_;x6@G(I`CF6!bju57>6;SuCDLJ%d%N%%B0OO3sp! z72M#Lx2eO-9<?;xEh}?Q!9-cAAaPbt!%io<6=1@w)u6tR9JpAAA5MfUn^Xg7Qb`J4 zQJYTc70IteGT+bFlaE<J_v&WW$mve+>xtEpkp&T@7?(`xw5rC}x7lj5&6dtQR?+~Y pT#|g1N(!3fycVgx6s?KwYEHKm+@IO+)rm!f`(9vQ<aPYN{tK5yVp{+J literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/cp949prober.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/cp949prober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eb346e5158001d7ab8bfe2e31989eafdb349f4ca GIT binary patch literal 1135 zcmah|OK%e~5VrS`Y)jHYc?bk2I7QHIp#>BP@n~9cC@B?z%L>Wbtes?GceB_|AW?6r z)C)hN9QjLo<-}j$#EiFr^a2yv{ybjKjKBG^Q?D-*u&+0}@1Io(`GK3cIRKu+P`fa3 z!f8TM8c>SZO03ilY=iB@N!`FT*hwmBHK<bZl5m$-jtQ>_cV-73uXaeo`$-{GgBCaT z-nI7M?8ZvVxI5DEFnf`O$wb8p4%b>k9%ucI4z*~9(ICzQc(1ibiH>(BTC@hC><E1* zhg~7zWTkc3+-|Z?o3&r>?!Ag2#UHcJklF?yNI*FWtP|3soO0{f3vA(Vn>)v3MgteH zsTpwPgg7L?nybYH6TeIs;RDcc#o##9J(x7n^oY!?Q|lWXYFj%q*fUpGW(3yi5jpkn zgcAr#4;o8_t46tyvI3V2kFhw5HDeM3N*8@gk>P=<R9d*d$`|-zArdwfvT&tPLIV$u z5=jr%CB~v8REn|h<d^ny8IOTUe;i7`H%z#Y%1;M=bU$a!Y4gM8=dB)}sz+O6`QVG5 zrkh~>%zx|WalRgBN{30Z{_t^k@Nv}bqtgsF78xH(KZ0Ixq5UX_7UZTQ8~H?fQ12ZW z3IU-jblLXk^vVK}8}kRBV-#6!;XTwIr@)kTP`KurTme^u${H*Nm(wb2iyD>zB(N+@ z#a-|yB#c<o>x&r|Kl*>x%KlJ_F#A_pFA1~$DC`S=A?3M8&Oc~)*kP=Wv0|CAbjU{u z;u>S0MqyH(7}^RCXars8iM#}1<z<+P`dLdOktCoIq+(uJ9Wk<CgmfE#LPdGB=G7eI zL#<sjjatx8DXFzmV$ftQ((<on1X!%5-7~t%rb=u`Q30<4IifsG=)aYe$aKSdQa<nL NEi48VP^0E&{|4FG6Se>V literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/enums.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/enums.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0346c4532355376f9ff4214406344a62db720c42 GIT binary patch literal 2626 zcmbVOS#R4$5T-7QV(c95V+wSE9;kpuN)xn2+@P=y+F>kHhDaBUP=KPiYl${RD!Zgp z3+Pkw*gw*L(BHz>KIt#?o>@tD96LtR6=t-v9PZA}@eP~n>$(Etm%GCse^wRccNA8m z2$L-!F$PAJzOtjx9L>K{XrAR>7W#RR3$zGwQOX67OH>6}m2wf}GSxuVq+9~ILUoXJ zDXSpgplcwnNx4kdZKZm1#`Q)RlK7A$V@8Z9od}qD3Gp~1sbCZ&9;c&moF-DmAA6j# zgiJmE*c-8$u5Ws2GLHEsX?qcAhF&C9$mi6HYQvSdHJW%qSo7maRrleBXCnu*Eg<nB zFsAf#aQ8gT^$RrLFVaH4M2mfumcUju)6Hm_CU)W_Y-Z~OhBFQXVPG}kY|5EnQG)g} zLW9FY#z7<k)dlfL8U-he3oj&KKl78A6CW%dG7>~Jx!W8}Q08dSJP*vOmNU(DBX7c7 zH`85r64Nxq`I_rKPrY#Yr0lvh_EBa3pl7%ZyJebL#jsne=@WD3iQ9bU7{4lf4K|kS zkElN7!3h{wKk<0|Fb*kLSD%dQ{+Cnt(d^OD{TB}p=}dh6@Pt43DVa^~!x%+%r#=m) z_ksv67KZn}`eryjPKP60l;obUh{n9W3{)MxBWlxAj`z}l1Tw8q%;8V2UI+-@d<)ec z1ABWw`emy2HCpahSdo>QN?&I>Q=1Aa!~6!-AYhg3X2*+0DWu7E5GIVzj@~tBkT&u? zawuOE<OP$#@}|@9lq50n<W7UZ!78ZjWlRTyMJ#y%%;#8DbII`1^V`Ti0%ld$cnSVF zl%c}Q$WS5MXgx74!!}&o+}rP%+osXZK3J_ey++$~%&yhwWZKilegic#b+_9y8dg@e zx|Z8|x|<amolaI>zLXVU={)F***czg6WARfu>njgF2b?mT24N{5SaI=l(l^x4})m5 zsFj^}b^BSZOyPBQsXjR7#<^pmKCX0PrENGy%Q3B;Oxx}rSZ&vIGS%uj?w)a_EAGO! z1n6RB;_Cl*z@F!igNQ90V7<2kq$kK^vB{e_@s55d*-oS9WF@25>-I9$bnLe|08_Gh z$pN@}!2y`kTd4L0u<J^bX;h`<SIWy=zp^aF4VyhrS>&@$aLmGB9LIF_!}V?n&or?= zcmxr}^P!FjfK?d3fc%nJ3&494#Hk>01pNSE`3(on(QqI07YF_$wSWZHCd~m@<Y$|k zoFyrb#3sNxBLG{Nf^hO{cK867qnHN(=s_e8M|i98Td<8xt!geS_@Q_$&9K<AjS)*+ z&~(o?_!f`HgjNc(PcJ*CcKHpfs$ZG!nq}-X9P@i4(+;eTxodQuW$N-@+wa<d8Sw0e zA9_Me81zcYKZ9dmvr#q$i3%UXg9ktYmsTJRsF3IQ#0NSX=))}_@d>c&vS9(#;A1Vj z(^|!_weaNW?6>Qa;JlHZyN;Z}Gjv223djd8cNq+9NQ#g(PZNeG36>xbF+La&=-lTS zgyBnK_;|o<X+)<9)ar<YOvtZ~h_t$v)9ZE!bay|FL;$T3K1DpxNFe`~-TGg+_xvAZ ze<S+~*`L6yYURo}RRD^NZNT?-rgz}aZ31xbW~%*cui5QnrM9^PKviCzePwvC@ESmi z@Te=ehCYf<tg5zXBWgT6f-el&TqTfm1T&5WE#oM)uR0*p9xpyJzQgV$Pbn5|S8m?| G0{$Q0s)IWK literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9e35c39bd3826d622720f60fad918fa1446de1ce GIT binary patch literal 2613 zcma)7OLH4V5T4mxtya=Xc0^(lLW;$lM3E>s#Um6239*tmiRF}K2(<+@$UCElv%8XK zR*tPwPEL_a;KY%GbL5g=z%SVw#VIH5oammFlmw?JW@~zSr+XgV{dLb*<#LfgdvbRB zyLf?+Kk;YQEMTrcSKk8Rgwv2j)Tb1ABQzq@H#KjDR+RH|k?q@2-p}hfD|DiQUx<o+ zF)I0`$n{-HZV;a1_9Mb=K@Uy8%=0Z$bDmS!zDCpXwO(7cL~>USwuOX=>a_vy$K6)a zPQ-dU==Eb!Gt<hQcHAAcyW)C3OoU8b)Ss!P?o?4Ps#$62rq5dIY<*+3aVM>=wKi5R zuB=>Z9-q5)_xRlH&G}pacbqqL3^w%*5J7y(iEnV~n|$Fh=}>NR>ruhCG>-;5eoojt z&z(o)kotMx3%sa#hnKkfi1-Cw<`o!=kBLS661ZhCU2Le}6_<>EFM80ndVS@+BJf5^ zD6j1;2LmoV74$?Tmc90HC<ov+uQQMy7l{ZGaFZuu&;mw%pm%%F6H;s+c%rTP;ejVb zFzCkpaeF%yo=`!1C_GrMdi_q~DX}|(<#?79pc?iC_Xe?-4D?ogF5;x$Iq;I6P_TM- z&;>1R28MPTAvmH7P3Y<fNJ0`iA&16}F`=CP1PJSr31Q}h>{v-|$G$@3D)8n}K5>%5 zA$<xO^Z(-fA9YKh`@>x3z9K7wY%-TsG8xB{7BpSd^n|9>2|0S>DM2hlFpMU^u@nOE zSVyC-b~4SW(NIWPg8QcqWBs_FFqRfF=Q0&Z7bFtx1R&pBYc^U9)>>P?duQ$XT4Ob} zAv_}H5}hFPNE}pkZe6{56?J6+f9=~Fn~keYiAkC+v>}3f0`_LXU=%0m36_Oba27!B zD3PSq7gKm$%#+k+3R5V}NeD|)Gg3>5u%qt>W)&C<!nRV3{YL(l^`Y$VfpUGXE$f{@ z$c0q(s8<g@9J0&f%R3hzT<Y+#`uNhGT-i^?(M4$8xV}{%_J`;DF&q?z=Rf*nyLW%I z-Ni}W*&diWkafHzT)7Uw0&GH-Ul<<93fT5OboDk6LaWrKE?tBVDRz7MjnDi$BQDJR z9$*c@hS)-vYHT%unPKb5z-aC-WBgai_opAy302<i5{Hpl6Pn3)m+p}yhdPIVNM>s+ z<TZ7sNZ6_sWEnQrk(Z~DgTe`+%A%8+p@`*4oIZtQ2}sS5XOKs|8kKJ$e-;T^the|K z7*z#AXa#JxsG+^!0v#_Mvs%Y-ZZevV{Tg&-1A*%!XeoeJ-vI`FygqV%Zt6}k!{T-% z8n{>|s4+fw?7){b|KGXV?AM>`%z(M}(wWCYJJWjodFU&&Qx-XG!E*#1Z8n?TXE**B zpM3V$mtD}%?Z3TH>52r>DehqP3dA}r(M}}bddnEUbIcd7>d%W>4i;k9QTP>@{a+>& zfcE5}vHv696!^(Qb7IQs#N453c^AebV`4m|53Pxnm^;>eLvnzl$pCs5*~xL^Q@}Gr zIOe!{pUR&TdnXUDbYP~?BCrFlE5f=eNJ?5_9=T7kq?O^63XBUg-Fsx$zK1@8l{Kq* zT_R?lLx;CUBU7FOJ}t&#KgkM)L@=ef#^&b6W`<}qFtwW-TWq}{-_+8qwAgD~EtpH4 z>l<G;SJ~QDdOGtHzBJixEXtnnEG;}(oaIJNgEMuu4-zPCiA-sbC6qfWrC7YOe0c$0 zt0M$&!6s@M2%$yDnj&OP5k4Dos7M|7kYcYG<5R~1i92ADxLCe12cUcx8H)yd6e903 zwmWKvQ%RmNJ_s1o<x1yl>Oc*HCm=bH@1Qjvl6R4u2a=Yjbu|!S2+QWlH!A=-_wn_3 z54yr4=;SP;vgnpv%e5R^*Oz9kl9s30msL!ONt#xtZ#cSU=2t9vX->qWNa<%sVzj0) p6e@rhY5vUU$3;IXSrwaK?nPNjozF8*e1R8L_&B-X<CFBX^$$aocgz3) literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1f3f5bacfa97b77a0f28e6bb66569ac867c87b36 GIT binary patch literal 7074 zcmeHLS#Q%o5VmtTcY1M2pb7yG1Sz;p1qcZt+7c0Zq9jiilI3PMJ#d`JP7CBW@Dun0 z{3EolJozv1#LUKa9OJYysv4=p)~<I>&x~h3Tiz%XvH~36?jC$BmIUD!67Erh#Tyvb z&$u8Efrz@$5fxDsNKA=Q@gxo-L2&ku1ad=05_n<5)#W}2rwHmLh{We4Njlu2EJ5Jp zlF^L%{usP<dqt5*N=eZec#~*~q)CQkze`G*<dh6r@%Yh`XA@ZSy8!RJYgk@Eo@YOd zKH!mO?B_w&JbyoL!ul`U3-sdcH%gY|l^o5G0?pDKDLPfjlR2dT))!X=tL0^M!8%xp zNwnv0`21b3q4gSehnu;3^*p$?&egr6Uw)Ad>bg3-H`+C&NamF}S|AIwNax5RS>nAk zPi`m+pdDT{|2_R{H>Tj#(+STTGa9dtlcQ^g{>FN_{a9IqJ+MR<praP)61hok@wji0 z+YO;~#};9amqeD|)mlf#25t1UK7A|z*F=d8LofjWrZ-_2(~V%N>0kGo+X?si+DTa1 zF_+~1H=CS|I4i_e7sBQ{k9Q|;ObHsZB%O~$gKSMHzuPER)>bPlwTXag(UQb+EnTxL zwXYrMl;wv+TWj^ZCd*lfxQ?jUI?_y4r-nl(46Q?1TGx!jQ|-{fWenu}Fs?*;Ik=pf zdNLmVTuIfg0i5&xn@xf_tHCsCP|8HwsCEVrW{`W|*e_RBDwXo)-tg=8a!_>C0{^(N zqoAlA29{yGe~cxPS=s|`4?yh^FW_n(mGLba>Cs(l<x%I%R?~oy{~Wzb+335=#=nI= zDBb$N(py?j!;jp{1l0g|L?@$wsyPurJzR@ksY|k$A!fuE#tcelP>Np}Q|bdBHg4CM zwB0qSX6%)2vLrQ5JC=$6wwP2?)Xkj+OE#M8^(ISJ>-Bw5e&1}UyH%D1X`{&&P^q?F zS9hv=YIA*Kr^<3D*;RM<-&S{60lsJPb9Qr&`^t|<FupUQ0zMW;lD}MSeHe2Eq|X%! z$HQ@5p<Xbm?fRH2AbqY-814%799KUC^9epkoPHZ}&pbYZza;XRX3FiZPN-?gog=xm z+EZT+UY@LcUTc$q^?dEjtbFMYIxBD-8gf(a9rwz|2K-^s_42b92S=Yy4-S#Zhk8a0 z(lurL=R#;-rdG@9JnemD=~taDIo0XwdvJH_3rzWV;^DG*UtAV%!TBJbh{Z(rOgl1^ V-WTt|cr-zdQq-BGu?*62+dsX%jc)(| literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..354aec004b9011daee9ba83c1ba27f5ac080d061 GIT binary patch literal 2421 zcmai0&2Jk;6rb6ztR2Tm)32l;lu8uIh}MBZp;CotolsgePL#MptU$xsGjZ10UAwd6 zkXY`?LA`L`Pe=|NxbgSQfeWWz_yf4Wd$YFXAU@WanfKm&yf?pjA9=K}P$cmE@J93N zpUQ;%hRo!1fcOkr_APXra2k_@1~jn(iz08ucH#t%q3zgByudTG6VD}n;2YYF3rR63 z8rqBJlTuKk<T2rM+&?AU7tY8I7I<NgREn=DsHs@Gv?IICC~fblPzhby3R?$JDhyYl z`r1}MR?(vqC29wu+!G2{3kfsJwJx7*8*c*X>gMy>)18edQ!;AyRn$!%reS=NMHx(9 zF_X1!s>HFHk(Z5}?QOBG?TyW6Eii2Q*<&i(0YZ>~auQgt$UfziTc>_t8`|a$(2j7q z%e_-FqJamrxi!#pyugd6B=Gq>FTq%NMH~_o0fhxUZ*=FkY9S=};fRW{WgkMPh@wL> zvd*k?m{hiMM!+*yc_RYjobt_B7?QIhuHXa?r}fIbcC&s@NLheGw9i<SMv5`%0xNx# z6<P*HmL<|d{wklrj)e%`0QS$}+)^utZYtKU6q!%}t&@p(AI1V>tvJjw#(pM$sA^9} zNARrGqfl1&yD=9st0o84*84qne{jFE{@vYuKFIFfJ(3?Bt3k33UpuWfs=cUpJ4!PZ z#_{csK5iZy_M2@Kn#PVq%Db}K0*~NARYkwm>Gh0X-07Xjc`)@Bw9L3VEz=_P;Wx-% zKS%n`1c`r!{7u+?5%MAF*g5zUXdQ{?8(`%kQV>soxm?PJODI~#?lN|`;yq{?Mi~L4 z2A5_Y{*Hn1f-UF*waErf;W@4Pz=J)vpYE7*$EtE2Q$@OjsKA@BG)%-g9$-O7tij5x zzS%|pt5*9@!(N!eOaGT*KMvD&KWq#1*NM^#m`@h8j76{ty$~JC-18pX`1p5&Ivv4p zgM9PrOABzf&g>x_TC3!ozO;wn`W^Ssl69Ez&gM9TLC1$y7+U9$n^dtg4*^lyAuq~i z?E<XjAT3{zE`k&!aQ4zUdFc!-Zh_>NA;k151XSk|w;$lRe0CYRp>qy75U4A&JZQ*Q zfOXtnA=qCh-{T3h>;Gl;Mfpnt`kb*o%jmlbmR>uwex!2UoPGVA<n-CfIqF|MbdaCi z2P9X)Gu-;%=B;cE{_-eTJBZX81Z`KYg=(z{$rI*Y1JFdGTfP1hzRC><UU)H~?O3F; z1ae(WAulqBIwd5g9_?=K?r!gDFYdP6LTZ<bX1^`3;6c~0!-v#feY?T7Hno@U)ZUZE z9`gR@+t2G8>`6nrdyR*?4Sl%{ZrSQfDN-20O+m3PGDsIWYa&QH`$BNJVALB^bYWw& zu~}<8sXx|>?XF@X?e^OTjE5@JWpidX-H*6PTS71IeX+gUs6B76#uvMrz&zWixF#mG zk3fKpQqu^+WSsU))$!39hB%l&nnsg+2h8{cnn}WhE?Y|`o0K7+IEKO=^Glg7!R!k4 z=n5@bWvfg}An~oi(rnn_)u!Qw2xBwe{}vGNn&gavKcY`thO(6L{gIWYbH_j=--X3F zLUs}!SM2<La3xdN7>xV6G|uCO`}?)<fUlrsnDU9a!r;cNp%+nwG6JOo6AEMSU@YnK zevEX9u^0U?&Sy;GHHl99;D=Ck)X9vmAe6>(y)dp3EfL31i>8o6Ml)H{Bup$=Z$rz_ zGksc`D>?Y{Z<>r-uavbb(teT|AI!aVF=>wTS{?=xbFE&^U)s1*lK*pI${$oStRFMg vE-!#yr`Jl=abEE}I5LCMh@~=5^;2teyU|wdKgbdJ6zhgDcnO|={ImZ8)Ok)- literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..49a8671529d9a10c0f39a677b689724f31aa6388 GIT binary patch literal 12071 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8282b10fdd828ac2041fbf96d4c8f21c011085cd GIT binary patch literal 1136 zcmah|O>fgc5Z(1x+>*3a1qcKuI7Om$p?s(kLeRA0P*P9>7Yk|ScsGfu?S$QRAW?6r z)C)hN9Qi+-eC5Pn;Ka<jf%F1v?e5zddv@l{^KPTDOkjMu)qVfnBjg7j=EDK-9H!cX zg%eIwlF^V-#8zr$c4!-Hr%vXEuE9>~Wwo$I$xFgr?wu0u2|BYwpVvC1>Hnk<s!7Z1 z?IP95?nH~$Ad(%S-^gKCNbsz;hCIpp9UW=Wj^aU*3$WhYf7d!V+Dnv{Nw?6+Fn^Ip z=|m+8oGZr3I&Ic|y|@1=hAaLI`vR$l00apsC!uvldX!Uco%*3I9By;xl+0-80ya4V z_RfeyLd>~VUNP~j3}Y++2ksagr@9A=CYqj*nRRY`1*f*PGlMg8wKpTM*G|Z}j~-4S zC_QX0m98pALQ0^Wls;ogo@mA-29z$^mSRH%Q<=n8l-Kw|{VYNPrb3pk6iR5|!BHaZ z!M?;;oJLA9_Kp0~!AK@!ATt<8GUyFcE~E;wK@i^`v7PD8hpkWBJw8>Bx5x6qXFbif zVD$6gZ7@nk8%eHol%^Yxo^%JtMYoSeGuc?=d?<q$+Q)?sL=hj$k!j-QXd->c_byC@ zfY24XOno}Nx<KUSyx>cWBC9R@4h!ZKn6eJ19(=ZOa3oj2)}*oyo59tx3dgdJc>oJ6 zk228&i?U!L*7U~Wm5VR^_uA4s7)lZ4|GL&sqr6{4eX+4{<)td;FEo8@F=oeDxy)EL z<VA|O&e+EyN-K}yt@MFM5Qd(}H3%!$VJRCIJ&i@0f=G~xd14L3$bwPQ9RLa?<<q)X zcZ?0iwwiS>%CEX4k)U$Dk{C2ui>&(Fi~!3u)7S;QRTA_diUK{NK27MqnN-Mh!+%<p P_v|(%gA%Ay^Vq)uR0S3@ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9456d6c70869a21d6fc6af9b15cda0f4628cd6ee GIT binary patch literal 27191 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 X>M)>t$I`jOBlQbE(rB?_#)|nr&&$<Q literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..830b34c6facba07e7b46b2f85097b0f33f8440c5 GIT binary patch literal 1136 zcmah|OK;Oa5Z?7GZb=`i0D<5FCnC|hP#&s;5Hzj0kb;z;N*2<}@oo}>?S$QRN}}FU zsTY1kIr4kB`O1mEz=@f41L+0U+TCww?Ae)bKJTrpEE5=CZgt;(_Xzochxu>-ynw0p zVc~?+lw>rd6tR_BnH|~&+o_Yep=+>{dRZ;3QSyp#mwTs#dxFmF(C4)_Y4|@Wglf?8 zdaFovvNzG9If!Ii=(lp%6%srf%^^?nep^Rcw4!*B<N~ZW58gF9NBfD=GU*mN8RjqZ zD4nQ8fpgV3S-ZtrZ}tyf$8g1;VP7Ei2!J3V<s`JuNRM*Lty4d=g~M&`oRS$0UBD)1 zz}^{gNQgPt$}1**m0^qp;J_V&<5c%y(L~b|GPBODui(_Sc4ly9uJ&dG_Sy+K_tC=% z1f_?KrP5W!NJt5^lhS7_$rH_(#DLO8+fr<(U@DW?it-v?sGmhhz*NZ6l|l&(JUB|E zJ=m8Ri_=Ic#=enXIvB}h3}go5NCv%O%7s)xHVEPeBepx;{jhz!)8kY1WM?cNe%8}$ z8%945I>9IzZ6>+WQJQW(e%c*;EV_L(n#sl@=R+C9&^|77Ac|NYk4zJ{Mic2nzIS0N z1ca{AW$M%E)deEA<^^A36j^QJcUUl|z?5}3_29G3&XHUNTZ76vYz9}$8XU_y<^e3Q zJj%p9uqX=_Voh%>Ub*<vf3GdQPLv!+`M<99(<tv3QD2|{=2u>-a{fZY#};FDjFrob zWkX)1i0h1fDx$RV7~V=Bcm!eSiCl-Uas!rf<)WvtNK+6AQZY|#1u?Q<lynDxLP`0w z?$sS*L$R%8-HY<8E=eS)+^8f5P1Yi-{x&1Pa@{m`L2s1=J&2+}kEl-*`fnx`GTrc> QRpmXujme+{>eM{eZ(N=hp#T5? literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c57910dc8754bd59ed9c2ce0a90b964450eebe83 GIT binary patch literal 19115 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 SiUq?h_%EO0B#4(F{{I0oS%*vj literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c7c35689a507dfd07aa29d88c32b232c889d7ad2 GIT binary patch literal 1144 zcmah|OK;Oa5Z?7GZk4o9R3si3I1!1~eeh5vgrF(vg%qT4vXEAecas>_j@exY67`l! zz3?N-k-y|CC;kE_X6y#i3#_%f-_F=Gv)_C^Y_(PijIVe4?@N!6A9z>{2fz!M`Un<I zIF%%&A*F~dX{B~(SJ;+L>V|HG9qFZwutCW&;V$>i2=@e?+o8`JJ<|4nQV7+i<;`v( zO>#IjqBDwAPnfrA+!qQw8=WyvvSH6eMs%Zilw<;|w~r6^_ILM=5^Yq{FHADdUS^S; z>O_Ngz4o$Rmv!G9y?Px(l0U<~MEVf`K|;z&Xq}S*<&;}zerOAa+uS)La~isUtEvHe z=foi)R^2F@b%MIc81H}scZ`lxKZL~)Lr=-vy0E^1)7ZwD!<o6pn-ka@r{uy%4<`_n zp0rm=R~NZZ3YaIQ&sdTrhB1W!m5a8OxMG9pRAD#DO}@kci;#kuP^GJc76zDbw2%YX zR~U<Bq%~vT$*&^FRWboSgGr=<!B}#kbdZjMcsFMUvx5&ipZ5oRrl0Ij)ZP~}OLt%l zv*2BjC;3*AX%k7g_4sLj^s(p<(O6A35g8w=AchWdVS-^FTa;Ig+|H-Uhl20J)CdS& zqpQ@Xv(05Hw-;Bw!YT6F!4L7uoB~(YN$J(!sWq^*scOPj;d)tzW7)(?fCrXEsdxYu zZNWmU*{v%%m*4t--bM!{sKvh$`!dRgMKlyBf<@A+7hSy3_OZ`cAY<h!W9gU|5^<BU zPemkaPsLs71DBu<Gga3iuDStB*}80OETjabARCLyT8NQ|N>29xXw;QYn_knYY^b>P zw0}uJ-6@3}l^eCrpwmXA^<P)1u)J1vcS&@$4n2sXL6j)cD)iq<YE(7Ee^y`b`CTjq KWzeM6WBmq*%M~a9 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..415c1f6f6828fcbc67a0fa0e403bf7a7e50159e2 GIT binary patch literal 2978 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 W_kn~z_s#3U0p7rxym4%5Xa5Hj!K}Cd literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/jisfreq.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/jisfreq.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9a8f27e8ee69e1be1564d317d56bb1aa0ecf5498 GIT binary patch literal 22143 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 V!M(avEgar~-={^zjukuB{{X1m+?@ab literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7cdae3ea499668d33b2c4f454a2c443534e406bd GIT binary patch literal 38022 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 ba=FAa>3?(jf%2{VvBCZ6y?OVUyC3-<TYgc$ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0adf4576dc33a82f1bc571fbf817a211c779dc17 GIT binary patch literal 23636 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 F{x5`Dzt8{x literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langcyrillicmodel.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langcyrillicmodel.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ef3e8110b84b73c1354bb2df30bd1cb2adf75492 GIT binary patch literal 29092 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≻x?BZTN& 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1c36ffa6c619a0e08e5296b40c887af7095d87fc GIT binary patch literal 23594 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 EAAYPL6951J literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ea3164c9b57e48c71a8ab5526fe96d8bd709f6f8 GIT binary patch literal 22223 zcmeI4S(jXO6~(JNO%fqd1BynR$3zXC!GKW&GC|M`5TenDmX)rX?jk*u)s@a53Ln6a zpgi#AC-B`z=Xoe+!J(XR00$gvZx{X+XZ`Q>-tJ0wnq^q*wa+>God4OUZ^K*mZQOWu zZSd#gH=Mrjo;TNOk1BZj&$<D*eem!6%LmY`ovJlQPK{)>Y@|8bT+<wDUe#RtiM6Lj zo9phaZC$^mHd3qg|20r{2Bb9f|M^Vu=rhAAqe{Hn|A)q}85;Eeu2ExE;D0~fKRB4z zf4|_E;BLWvg7*m;f>VM6f;mB3a9nVgpe}f~;HcoD;5~vn1^WeO1ZM>&1RcSoV159_ z7wYen?wx{L1n&^MQE*srhv0U>Zb3`%0l`}Zdj&TMb_n(fW(B(hZxReX!&?6~!99W_ zg42R`38n{-yI=nSNj@w1oZ$0<F9@~>-X{2>;7fup3%(-ws^DvauM55*_@>}nf_nvT z5sV9N6dV$~Qt&~+w*?;-d`B=N=n1|n_@3bVf>#T=f*%ML1WmyY1wRs;6Py=J2|g<L zvEV0ylY$Asqk{VdmjoXXJSMnV@KeFh1exIHf?o(O2>OEUf;R~E2!1KhZ+idjf~|u0 z3SK36o#3^CR|sAvc#Ys!f?EYI75rN8F~M&HzZJY*uubr|;CF)G3;rPZqu@co6M`oN ze-ivz@E5^f1y2c{BUmqZf#CUqHG)yWiv`aWTrU_AY!*CEFebQ0uvYLQ!3M!~f{lWg z2(A^}Ab6o*lVF|TYQa^4zYV~@_Wg$xen_F#*isv8q~q2)pR5cISMJ~qdd(iuD6>zC zIW#l44Hl{nEeQj{P*(w01Gt*Xu?qv7vlv?|&)5&<CGi$m@J1Mzr(il%Lx?yO2$8J( z)xrjxF5JpHTWp2}+p-vgW=K*jhzSvs%VlBv<qg@?jMF*fR$MaZuthI9Sa^tn8P!lA zL}Es`ya)4Zw#vIWhoSSPF2K;G43dN4ms~C@Ax46a;V^q+6d|TL4!P8ET%}+}=&El( zF83r9EGA??$Q6f7!RiVyZonl2vyWUIE^$O|k*vfhBr9;W@T8C99Jk_#<h(NlZW<)1 ztKk=x(lIKx>H<@OnX)0K%XXx6p2A%$2^XRYLxM{jk%JXi(U}#CT}6_zm77alEtSh1 zkXv9O&$ExfEO8FNIaP8n#>1!vmXffG#Yl1;4X5CDJu0vedLie`0M;c3^JFC95Dpod zsxC6;4czMuSZK-2Lz$8a$(f}>3NUsi2lJT-11s(g;!5FgKC?wmvFT#48II#a&{4_i z5XJmFDmnM!p~E?BQB8?mr4V|#74yi!+-Be;p@V`MeqljU9ELVR{FY!iN9<8JqJTIs z!q96Aj4~q^#8fSznmUB5sRF%JQ{s>##P1>**I+=%IRwzbypTh5X0`>h4hg20mksfL z!89kK0K<9e5L98|eiY2O8ji@pimT|#GUf%pWkYWt#2(76s0J}Na0g+E*^vu~Vfb~9 zFtAG1VzDP9!DWhh@e(JYH@5=`^HK*R$CA#mxI?PpR;h5<V&(-~#UYEE6^l7jig^R3 z*mM~0FcfIRf+ZmgM=Y*Z7qeQ48z8|iIgaBc9hzATkfWCzj1Du7V@ZJEJU4V(*(&em zc2K}fS>|595jwnNDi==TkVB-Z<ao_2wBcijtoYchVHW&`&^}VR+=3sc8kj=>F?S(n zotHEV5{FzZgcL3d<24^Awc4<A_QAW@O65}3Vjah(7e+6P>QY$vxCp&aD)a`f2C$em z>w-8HI%f-Eo<kRqgaJ5r0Ud?vti%)~Hq9Gh4Rn@-YG@-|B=dNVSZPYwv{LU<#N3Y! z0?Q3~*OHWu9OA%ANJ2*{9L|)~<l-FnL+4#sD8&#LGkS}4ORf&_p-Q9pkCuON+{>>} zE(^L;=v*=Iq;)=`7Xrwcr557$OexM$T_oe7uuwQ>s8$dC5N#oJ!8yP=+j4G^2A8c3 zZ<Sc;5M>A08{$e<xpSqq%O|!Ee|1Ya3D>B^c+!l+5~iFNS5qCAFURS;Ras!6REMj% z1$wVI=AEl=6^@wu4S9U1a;8v7g<$~eG6jYYbk2nk-3l=Nhr!}7-yjv@gKAkuZzaFp zrECYgq&ia7R4%udLh3@PFQ+)?$8#lA17l}1w#sE?b-4qET?meHZ;)F^4R9_LQaKMr zXKxMz3#O5T!b*kw_b;3YZ=sM15u4>gxEi`}H5XDR$t|SBmpK>ARDW&QX2MU#3pr=z z*N{|ScQ_rG_NNzyQVoUTkTw_{sT|c+%lQ6mFc)l)Dk09pg+hof)f=kS!|;g~Z^{NN z89GuM<Vq-*aZ`R%*e}HxKrgv4G_`$d-Bpp}8pB@KS6lK>rod7|shZgq-l)3QVbBp; zLNBicNeI!cMuuOr;Ek%ixta?|!Xey2F1$hE%4A{tuq0LPM-JvThk!d$C(eB%cM1<N zKIBrpNO+PQjA|~!3~hLG&LP#@QOi+C?ZRqi0dlvZEl3y;3YR&|U1*5!;;jS=$1c&4 zl6ZR;hUkM);YkXxl!Tmhsr^!t@T(De!;}!RP-qK<XLDG5lGWoJA7()6M@yC8DCbgN z6E~oZq0R+KZb%!F6bnOBl40j~5|_o-@CLc}qnAyY>|6-ZtwzTE!bz}-ElbeBm;$3M z9L%A6Q*Q(@Q?7J|Exe_64h9{f3t_4d1|V78%(i^G-21tJeQp&B;Sf|^U;sKsky{mv z#j(ZxsHU8A7j!V}Gnpyw4Fl*+b%ZM8Qw%ZHRF3L!*mAt#P5BuOXYrMq!okAF;Dx9X zk~5>tlGI(SOSP?(>Hoi5>pbgkkoppXX}(Dp=-{J9l45S7P&~d^T%sDruV@%dFD1M} zeAt44?;vFhUFt^`I&vjJ7s3@iNowcZg;?B-Ff}FoTG2rpEIdgeFo%ZR@$7=Q5(@*u zYO67{{nfa5?#|&8DAuKZ`tC^G1@V7}PF}PBu_vB<;PKn;xU}JXYqmLeetz4Iox6AU z)*i}Ece3+a*Y-9|Of@?7?p%GY)66>cnMS*}solvYvSv0rkqzQ*r*)xsefMI!HPM)^ zx98?t-PS@@?=-rtx!!eWv#eduW+$gx^HcTdtlP~xy$u>UpLOfAjhU>se!4L`d9E>; z9o@R7xB28<N3}qG|DnCd>nD!Yj~zd7@Ob^m-n)C74jtTg{NTy@;k`%itRFdc;Naoj zwI^G%QvYY!BXiAc`ct*eXY}_73ZA+!-tM#(8r^Jsq0t#XGdDeOFh4#sH9oPUUEgzQ z&;8ra?>f`GG=I~sh0e|k-Agmu2Y)7K$4`v6TkUPF+4*i`dV1ULn@>-jJ$HIiN&j14 z$OfnCjLSwd>yFF7l<zg86>e-_?5)3LK+jEQx9TsHoY&v|IJSB0!P?m9$kYG)8%OGy A^8f$< literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cda433991379c79495a14fa411f5be1566e23fa6 GIT binary patch literal 23625 zcmdU%ca&Xa6~!mX5JHJkRX{_RL<|#x0isA(K&pamM8`?yk&H}c#ygV)V($%m!(KoE zr3hB+z4vbH-Dknx>)RX1Pxt!n_042lCb-z^oU`}Y-#O>KH~i=E^XG5h)A{G3y;hvN z<j|g;?<=|apKUwAv7LV>?$m*yp8lSpS^cwyX7|r-^|WRW%^B()+Gc3((6%p~+dro@ z>!!-Qn<~9S+nwFBX#0gdvwC{k|LpWvouF%I|KmT!v;Q-lid7fyw*M~sIWq?Bzsah1 zD)8SQZ{N1#*Ip<%T(DTMk6@{w^V#*ZZ!b7VuuO1(V3A-y!Ty3i!6AZ^1P2TD6&xs7 zE?6QsR&b)=2!Xx<%@=CxGivW5*i*2xKp#|lFTsw2-2~eSZY9w7t36jRU!a4v=Lv2t zI6<H<XL}ogF4W##u&dxW!O?=91Uqz~cE0v2BzdLaRf1OwE)iTRc#Yt-g3AP#3$75n zPVjocm4d4TR|~EYyg_iS;5xw@1#c3(S@0IYTLo_uTrYUL;2nZ@3f?7nx8Oa3_X^%8 zc)#ESf)5HlBsf*@VZlcP9~FE|@NvN>1fLXqN^qv&(}K?kJ}dZ~;PZkn2)-!zlHkjN zuL!;>_?lp&;Ol~K2)-#eOmI)Zw*+ShzAgBU;JbqF3GOKPzTgLf9}4a&_>thpf}aT5 zf}aZREclt=c)?u+KNtK$aD(6|!QBMM2!1K}mEhNcdkJnKxQF03g1ZaO68u(hvfy`u zTMEt=oGv&=ut0E{;NF7Y3;rPZqhJrgDS|r)ZX@`U;Ln1;2=*2nDY%{BuN}DY4}iY5 z{v+7M-=UPumdmV75GlmWM4GhrCo~O0Kj)eLBUo)C)42lu@u=nrwi9eG*g>$PV7@@# zh)N%KwUc0H!7hSb1-l7eDbOFI>ed2%w3R;YYEQvl0{z{s^r=?*mi(7P=zCD@BiL84 zpJ0E%0fGYsw-+2FSSVN|(D$l3SfF1|wODY7pii(waHwFZ;4s0R1j_`63yu)z`&U1o zepZ!!N0ok!)zJd|n5tt1#|iZFt4<J{DA4b%((kA`NuZxlrJq5iUs-jkK);zvzoY65 z!6O7`3Z5s>&#%&-j7q=IN<X?vzqd-ivg$s9`wH$SxWAxZ@BqQNf(Hs7Bp47}CKwc~ z5Udmo30i{l1giwA1rHNEL~y=fM6gCMDi{-t3mz({1QUWu!CJvO!Fs_3f(r#31eXXN zE_k`%k%C7F9xZr`;IV?o2_7$ag5ZgQCkdV`c#7buf~N^C5<Fe-48b!6&k{Ua@EpN& z1uqjkU+@CK3k4SoUL$z1;K72I3U(K~Nbm~5Rf1OuUM;v>Fx-K*KZ@5Xy;P|`lq;0J zPVjocm4cTDt`=M)c!S_t!F7T+3f?4mv*0a)UcsCWEbQ5-<J<{u`W7#pk!b%JaoL<% z_MXZF7DtCyFu+Cx>q%j22ah*Ox-bn%7%(Kd>$N$ABiFV#@G_pt(>wLJEE7?zA1q5Z z>u96HH3oukw8fpy12GyKO(|l_(!tEu`UPtP?#DSDP5pk;Y>S5&D2PaFw~Rf|#la#) zS2D1ej)*)OZDwQKF4AeXg)`r<Ae_R+zLBzE5NsKQooRDK8Z0iBc(m{<P2XI@s#({} za-n8jjN3&TC#mh=Y9Xm5JSnWBnBHqO@8;K{ZR%<B8~DX;-KOl}h&C@x&1syZ#Jc9G zu%gDeT}0Dt3+HZKJZ@~s3Pkqf5D<=F9R=$&-mng_S+4-$DAwAXbO!yfDy>?o#rm}p zJC|73a4G5He%y3(t~SkHE>tprtzC7RgqM!qs71<QJt?W9()7)>nK^s2OSku{T{X6J zYT$e2UH}$J)VQCC<`rs>IL)^3<3d41>Pefy1BHYd5t333)}tYDWbkOD)MDo5bee5p zI?emV^j<o?FGzww4B^NfW+Mu#nYo{zjB89i^=MtRm6mobAP!N>aylfO$u*~JNzLP$ zfbC+1|Et8)Gc!v^WQjKqA`HAtNn!#6mX337J*TT(mG!+FOPioZM2Ah|*ce2IQ^cGY z9e3_Fnwby46Lj$;o0lSX3pO@~WphU+h@9G#4yP=Q*ijcNgk+j+;le;cM9LoQ<_Q8y zIyQ%mTBJ60%@I$!=F#Ha7`Kbm23_cyB@EQ8V{=EbV5}eeHnSYUI-E(P=1HTidHND- z`w}swTDLB7Kew?UDLR}>tk?IXu&!}?v$bb(o5fiDPd0BhWy@wAlQKBBA~MS%h{6CD zB#tm}>ZzzXVp6A3gZ=+UjK+nCykLM?w?VKaz242Kb#z3H4qV(zn<Z1fmHnpP79HKX zum=lrA!;QZo5NCbRBHvn!MI=4Vz=hB+s$XjC0^qY5%C&?w{!~Y2*NCHa8o*5Ljti? zL@XFfbEaB}I}C9HdP5Q^$2Q><tF7XuwX06)YH^pifvqeF!YKszi`q<o6Kg-2TB3FW zPs$NX3%Z8H5vvAUYv6|r?zIbI2uBdLgVz%7t!29<x^-a>JG+e)9I+cLZLo}nfja`C z0~P}!o+PpXZ$#u?-Uu-+yo&)fyEtVQY7lfdvXzfR<dj|p;)t-07zi;E9<QyL*eW2F z@kzKJhhQ04B3MU!D3-uNP%FIwyQN27khS=}n1J;j*12XKEC%SP5z)b2c#_)I6R{Cn zvXLVb+=bI|$=H{+FeMFBh_Esd1Ci2(&IY9k5I3{du`g|mMvWU_TGBDIS-0^9y*v)f zYo!_;;bMY!ae;^^B$3wIm%c;M8!3C()CO@9O8_Lcf^ZsJ!V+0RS{kT!!4O9pZGHnu zq$a2}_u>*!7;qd2M}QwPP$RN^7n0~;857t;xE9m%T8W5StwHEWV+;r)kL%Q@b4Rox zVK>CCA;G|=!N$AzA$All)G#PTZYvSgYM-=(J)(m&-k^h-9hrb7MTcpyB?7Ckcj}H> z7qjTF527S-Er>|NCG4A1*22YKE|x*!h_9YI&|$!nutZGnT1kwAsHDSy2py4Kn7{<7 zqml%J+K6}KY7Fj(ly|8ifn}<AoF`)sboL7?v!y4a4P88ht~SEn5+*2hlvuu8u#Dk| zTa~tijS2Ac8_fg79u`w$AY4i{SRz(%jj2dOOj?R~*Yi#3emqXZmJ9^z2#HgsLWcyG zsL=)yQP?+I(Tg)3Q6uGz_*&Qx;IQ<<Qp3+tNrKpsb+l1Khhz(mSk+POr07Z#SPp@% zbQ0I%NvDXB)DlQ&^Sh)(%`WI1;ZkaYMNG{d@zpbHFpD@0f?%p3oKho=$Of!Xig<(3 z(82N=I%=VdF=|s=ajRM#_Kb!Y))53z?aUzwD_#qN6p5`Mh)ke^hzJ9skT?z2&W0cm zBSB}efe(NVSSF~gAqfKr_mVb89<o_twxlZ!X)zNJVc;4m_N7{k#*;Y5leHbS1XiA) z1kr0rX^+r#k@C33P629;{I0)4NHB23^daej4XaX$OR#>ocHd}oia~8}NJvW&kC#~P z;>Z$!J2OkIj*kKZBCK4Csa)d?B-H5mA4e=$`w;V4;ttx(B5{PIR%a`EBVrc(kig<X z%{tOjR4a)$B8}H-UC`AU&`ac7MQ=>s#W^vcH^v|>MT|j&6%n%#!Pc&Y#8GJiY9Wb% z;*DtIAqYCcxg?=h5;F^?u0b#XQLywPaTK~zjb5T~aT+W`nkWG-C6>`jtZSCQmYxhr zX+g$_$j;PiQzi&W^iG|P>HVK$o7&1OZ$OkDat)x38g0}tjflr-!xT2!kPz`&$traC z(H6DR<A{l(4WbkwCPG)Lne{B_sJWwCa9g)x>uPUM>%tq+Tk>;_j*yrLD7}k8h?|L$ zcuT6WDtk~PVrFXG9yVOMAnZq5se^}jyfzA}T3x)0E+&YSHWMDLB*8B_Afk;FiKBR< z<mcWXYW>2Vl!vGh@kSRl9&e6pg#_n_knm-2EexVoVzCNw5Tr3nq`2@}M73%3qT})A zC_0=1rCvJtxJ$ZHZR#C%VW5b31A>l-NK4|V;XI|tF3lZ06yL<=w#{LAlKF`2jD(a3 zF}mhjx8rhyaBfbq4_y$Yw2Q%!V6bIIF=<>QSg#P0(pp_eN^P~Z@QXC2B8`aD22N{h zu#M5Gi@&k(x-Xw~!!hS<*#4BW&s==uk;|4ZUfRFi$!kYf4OYX0ql@Nl+<E2d!D?V~ zY+$S!YE=Vk2FEw<JYKa{wuV}xD_fm>vKqc%<E<ty93NgeI5IFkHZeRoyskA+4NeY^ zZQS+zR%?8qHM(kKcw+UyNNaMkRc+i+mJ_YXfziP=t&Q_W21i$|9bDDgu;cpS(V?;R z6N?XBx@^fAi?-=sa9YP?bm_pRc~0mwo-=l)COLg@ynjKbLE1WgmrcZJoi|P&8)}X8 z?{=f-Cg#TK?)MERm#^rl-mCvtJ;7fd);C@auN$0f^{pGM`pz30=?pQ^w`O(U%0tHo zmTy@8kR|I6J8x*i#NmgntCn6cxna$c&OfV0`_AbbA0A&kJUTHsI5M($*%2#NpTBm+ zDi!_jz`9mv>8ejR8EQ@T=^CqVzW*AHe8~8P8|NL>3D=Iaj@E}iv7iIJyY}wU`>3AY N*|To`-@Jc|{{<(bF|7aq literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0b5db8959245654f353822d6a1f1abcf8ae89388 GIT binary patch literal 22202 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 W=D4VTi*oGZvG=ydHg0(MzkdTWHO$}u literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4da78ddfd892ff2ed3d50de0d03321875e7366dd GIT binary patch literal 22225 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2268d5e8ef7b94b7161448ccf21b40e7860c5fbf GIT binary patch literal 2935 zcmc&$&2Jk;6rY*>@OraO-IAs)DPI><Bc*OBrL9!a1osOmO#)6qS_KBjGj^P;*Y4~% zZH#jvk$ORbKcPKx;g8_Y*c;-2@&|C~iT7sH*bZ%>;=qjN?VEXTX5ReXhy7`x;1g&+ z%&e_Gn<C_QoE$bv$Q(?PZx|th2pW+#4Jk#QMXYUw7VuVR3p;cK30>iYIpKyLtmQ>6 z^o18rh<q3bKP*W1fA2Z@`hC=DPriO1-R}Sb!59iY%zWvXfzqQLwF8g`pm9|8y7Rmo zb|20g&N6O%%^i`W#FrBzJphYF=g5z*xg&Cv1V7OR2`9xwc<c@lfhg<|QIK@k3X5X0 zN=nD}A=pTXriIFSO;x2{R-HAeU?D)R6*sH8rscj3TKh1_KEx#1w~#nUTqHRp9+1+U z!qtCGaHD!PG3UKn#YkVIhi_Ac3=epz9=;?~Hr$K!hNld<q2BPK;l0DPSL+>~R|hK& z8^Vk&SpXtQNFm$VW74343byBkmav4qM?zaV!V&Hs*`=Wid`@_V&xyS7LGFnO5x_V9 znAjxr!S97MSg7e%d@=KP9qq)1U%VAZ@;(qvG#!v#_JlnJp&$doEko@AdE#Via2{PO zxv7)%x>BhCwxu5Dt+=H*Pm4UNC7RbEzIYwjBrWiUk`H*j(~GrKsiR~fHH4g<$fyC| zJkJz4|Cv1NmAk671u<COs;P3L6A7u3a(lg8zu4v1`qwrtJiOEp{p90ITk69{y5GJ4 ztr?eB%H39XwiPG37Dcm{udJ<a_STxXXa?VsvFNBWnkA$zM+S|qiT?B5Z8Zsxs38a# z)`U({7kdBXC}`)OKk;wqRdD0GKs4e7-fB|KrVMu4e&P(sQ&Y_WH@0YU1;DeGR_>}} zuqO>}e{t(`UYTFvi}&xTA}lFPI&~aKiK-LG!*9j`Ir&`F1SY}IC17bl`zOY1H5iW> zimo<>Vr~m+jOqKIRhMS3UcG#6_M*At#rLHF!Uj&`ajh*Q*q@+<g!RviT{^1uk9Vip zgI;o@7uDisuhx{^k=w@I@m!;BYymY)IUMGdYrsIrk^y~6cj%+#0li7SzPrO9yxAGD zV`(-Z8<w`gP1Y#_EB3$^bd#w$?QFQ<#@sUO-|z;u15&}RK#p7oT}+4v#jjA72Mn#u zp{9_O{B)+#iXg`M!<Js>GHyn#WSvJ+!&;Iac!*a3%#}{X<VG<A&`j=igp9J7$X6ET zt5p*an3}1(xU|CW-AY{!@ePMzltBI=Uvf-{q~6-LmLOIst*1V^;voHO%)TQLl-dm` zg@#j-X&{99&^<Fe_%eEe`mBF^%)7Yb(5q+_4ukb7Fn|Y?jtvF~7BRXsAhlud0`>z) zh)tr-3AV%Hv$!g(GpG-LXaHGfikt>7&5#{7V1j|>GHL?vPMI}8Ik(vSZt9mizxDTS zVAz|M{f=N%A1r+|*IfPa*FVp#{&52^c@G2%EmZFSNv)*UHmH@X3@%4^pi%%(ow(5w zGOo*`5KT5A;D_Sx;g|!k0%|ja%VpD$dmgndkM?KAz#89Mn!o~y$pZz_=e*q!y$Jb$ z^9Q|Jlu1kxGHIWBP??~%>TPuzpYSFUEYIo#AW%><*VbheaXz#ga_J3JGBpCr^0zP& zWIP(Uo)g%C?M<43y;wS)77p??tAeKJq>hYx?IZ*46l_eb`!{bZjFHruuU3#$fmFUk zvV>FQs!Qr^P*G=*yoCfW9U7K#XjbZ7&mR8?swE+ifCkKFHa*g<BK<FYI&V+>1(iEi A`Tzg` literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c592862ffdb34a11689522eb3282345538aa9107 GIT binary patch literal 2240 zcma)7UvC>l5Z}FjIXh=3P5M`bVn791qH&=rs8T`DB(#xQr%GIqPN3D<yLQe!-?@A1 zkXY^u3F-@c2m6sXJ_4U(UwP_RK$T!-?U+PrB-Y-&nVsF4+1dHcJ}8xn1lq6Hn?F1& z5%L!@C(QxkYv}oH7&zfHAw3#WinNtjJv+2}PUukbkZ_wj$AmkA9@(MG-Ca`kUQ^gs zrMk4f7s*|rp31B#WYy9EQgPbZRgn@pcoMbt;#3%}1zY9~?PJTogF%pxauQmchBjY% zMcUNZEQF4sUG5$Gp({MT!2M%#M8gH33%qD(pD*&@n1lsh;$`?2UlE6di{Rz5zWij6 zsQAI55@-AzR*Ds9Zx<R-y=58q2*IyC>-i@@D5B_y99dm!L^=J<glt5Z%?XSSx46}@ zfO0tj7wkF&X)%e?4r|AW67n^wt$Nzc2Yn%>3!L^Di_=&!rZ4e0S2Au6RGg(ON~7d( zD5Ng5G7d3ic~2Kv66K1uAnXurCl^UudZ?1>0%I)@=8XML{ywPnWxNk}P}`4Wt(_%Y z$h_9utF=DuvwOpP-P=FiY4c(J`JH|F*?}7NZbR#&wMMNU_ix2%uA(Hlb@z+r-t$4T zgOjGSeUb7^*3do|s@7{Fl?&B339!~blm+nSW9YdL1EDL_gWvGIw+DOe<mfF-C~Wwh z$NN4oC-ELz6A+F_*OoVMob!%c1KyeP9PZ>){H?lN03B6NqBqlUyHbF|auFvGATq!e zR02fsQ^u(!9F}po0K+ZlIj$nK42LP2K78k#BN_E)&Vy%KM;+*dB0od2LvB#ajn#Ul zwtD?U^hBxz-;^?wGhe1o%stV;EYvKGdg3msGdXGvKRm~g)9e4IKXL{1o@3v~G#*49 zaqpDv^X~Oz?Hos#>39_;4i-e@;7@b2^ay?%<i|f=0&2R}*dEc5b&X8uOM7H1r|Ukq zWE~{lc!2}%x<2&6$eKWDQpN5fAT4-GUX;z+60GGgTRt<p1hX&$x|b*9r85GA!ps=Z z3wB`s0=MtucV)ba+{l@Ld!TVT1Kx1^D#7sz`2}~(<lhs};LJ2wM#Dw0eF=2GF?%mh z2vXxK6V!h7xg+14_y+t%$N;xKeE()%f&UafmAzP1pekgt5~)fP$`;5>0!vJx*Z)AP zUem6GixApQL~62F7gKSd7(f;Z3>H@HZtm=C?`SW{IvuDVE*H%~N3McMUc><broH-h zgFV^Q-gKw-wi>(0``>Oqt8cKahIV%w-|RH>YDYlD8Au5!YAO#JMmQMwXs0a%hk|A* zeqm#?vAN#Zsz20AolG&2W`oWi<B^JV+33mAcFaZE5_)C#(e_Sb{aJ%G9_?%b^LV4` z8W?IH4-bAxO=C#>S@|;-d`xSGE*NOc@gY9|kG_PSufc$YXBm*{17dyZ7z)Sf%!+lD z7Ok=s01t9&c>Np*;nB`O2O(!t7%K-{BN@}l49wQFntTL;w<AcRD1<%*E*;)H$LiTQ zVW9}{kwDzTBT;0mm+?V@bimk)L6poS3ykrs#h9tVrgCW?G7BCWb$IIbF;K=AU79@^ zEs-R!Z645*GH5CwA{V#hSQ&lWvC3ZH2TtJl@0x;Ihv%$x<{6L}CGCoI(92D(nXEL6 Y|Fbcr(1P~wPY?9f4K#xp9MEO^UoY7sYXATM literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3edd80c5b414348c6d2338da61ba3d7ade802179 GIT binary patch literal 1131 zcmZ8fOK;Oa5Z?7858G*J$^i+9dyrc9L7|ZlLJ3e&L{yPhNEXs6@j9u~bz*j%v_v@| zrBW~OAK=JeT5;pVU*N>-#!aiPHREr_Yt78}O`}qA5S(uhyPtj+5&ENo>tg|U2`0XR zqljXL5*%Qxu)&PP3`~tpW+irDYizMXQVfb3+pLt7gR;g2<|J<5YFuPqQVA*=m)J_O z8mwwuX7`e{U=5=KL>=m0BI-tXZU$BAwNb6|7egC0EUV4a4sS=<0UwRiBR=Xz9J0>I z@tggdsD1dhy^P$~C(Xm7W#}C=c6PUSma+Q$?!!&kJgPsbFGHsh_xF~Ox_kU_5r)vu z@+h*@5s$z{D8Lj22DPqG4^xAhm*v2`LKX@v7{!*W?;FkbtpQr0q5nomy-Q#wn0N&) zLm8f-xiK(inBwn1e`d~6W`WsY1+XGm39Jm}%u&BIL&Tk-AKp)-h=qzq3n+3~XV@pb zm}S6NMcQJVMx47)LzW1MhjB&-S9Q4>hTF;&l!L`UTs6hZ%BhW!#Z)sdq|GA{Wi>-u zB4R!6!AGc7CM0AXAqe?}{$2Pfk0+fh@+Tec_eP9HT=>bUA8x0lKCKV7&UbrsDxU66 z_|8Q(O}60lhyJmj#_2{p6j_I{jlE~x)3b56uaerxBpT8Y_e0nR8fAXc4Mkrq#iF&% z^b22sZXSb)``{3+8Wz6&IL7qB9VIrenW*6w2nECpJ4r-{bO=dCbj%d?2>Cqju*DZ$ zL{{>F!-z4UaUIHOSHrxjuxdbaT>~Jr%2>y(+PbW&5rD;8-E(zCI^(RjzZgd=BONh_ zMV?S9NjDmYgM4Bwne_Tywchz9C7`}^#`BC)Q@UXaOP*(xw9@Iqp63ZAv;HYN&ofGM a-R{j~3#8_frRNK3UZ~|4YF-cDdCdO`-y6#S literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4a0d3146e7ae4ace62a3dcbe9961b52ea82c5b67 GIT binary patch literal 15686 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ba1635f52b0f370f986b6ff326e4e77f5f59ed11 GIT binary patch literal 2993 zcmZ`*&vP5M6$bVPxuhssl2tpZ5)U(zv}N0bZqn4_PFgvZWmy@S@|bix!$}825+J$K za!F&ClEqRdYbKW-dTmeAF_#>A=pWEO1Gly(U)r2|X}^b+EGwz7gSYsN4|wl=5BKNi ziwx-xtDP@aZZP&ws+=beg?q@!&mkm}JYqxM;+)D(<P6=GJM>!K&~N#iZ8GUf@0dwX z@t1BZC;bMi=3a43t#UKJK4|NPN}uRaN9n3-7OA1#O_g46r>Z~Fho(fGVcc(|XfaC- z^?ah@uG$XwR1^+IBiY4TuM>fzlyo2zYjMe1j^r&@IxSDSEnj*7as5ly<1#OU<3cNM z%LQ3H4qAaK$T?X$W-ocGi1NHF+wz>eCKrxbt0WiY68`gFGLN;&ILflQ*#Njm-9Jp# zrPI8+2LvI;v3}2{f35ZZ{3l9Ztv#%F&w<k4J<G}GD5NaqGxpLsaZVX$Gn9opb0EE$ z3+YP+nX@u)Wng8&%HoWj%+Wl_0FKwICF3WPvC=w+rA;727>B74CMSj?sUlMlTJ0;H zC}~O}ZV#0hTV0qr5w(+4jI>nR%!@=l7v0e$hGr7<rK7YRQR79W3(c9L=xG{BWnZgA zrB%;(iHds0&o&HR?>G0xcCdwl5M6AU2=NvB&x_hvhx<@?ZNIH+y-@@dNo_c&b$>P% zcc*uEZy$WzlhfoEAMfjrUZm6EZKQr&Yu3i$_=7M`05AIBlRKTk-lWr~Mw`XHiseYx z2%l7GE$L7RD6>O<I6l+`+|v({lVu3T%RJ}c;}_qwa)rV_Jipv7SvMv6zt-(9QMs&J zX>}`|K2N<9|CB9fnk8N5CCR`_XcoG3>#zQc6<#5;YEcLHS)J-7D$SGdA<R-=r6QgT zMK^PxP$jxdz1K)AkXVGMa(zAf-K3_sNUV^c<vu}9N)R|d&b~mWcc$-Lb#ANYONVwa zb)6P@8)C+GnJ$yu<qfLAA6IZBdn~7JN@qH-=2vw!ZLHrRK^$}jG(&g+lls??6S8Xt zkbyIO?<#<AZg2@FDaYcxg~E4np16{q0`oc2AZo|`NxQGAUWSsUS(L`bwO;|120cW6 z6Y7;VbiPBEu8<PhBc0L0jA2m(lP)k>hOhG(03Jamx9DQ+^@4?0*pc(%Z>c-uFZl!Z zyT5+n9JxmxSj0n*Kl4*>*WY8hH3L2E=A?UvIpCC;k2UgW|A%c4&e{XC7B2M^&w9W% zyK~83&ii4%{!MlSmI6ZTG;^_AF20qmOV+(x_-;R1OS7EMRuC!fz+FDYDzN>+^N)U; zoz=%Gd5m(>`Q7rK^GB`+sL|fn_PnfivT(|df*B!Qv~BlLS~|HdbF=&`ICVM0T-=xV zUi>3F>c$>BTZcyFX%uGMIQ8tvn=}%2+-EhYo9lZ@jfDcshsi)hDg_CeMKUVzV8)PQ z*dA+gce6Ows;eZ0C^V)zd|_>Q`ri9Vr8|myq3x>ts`7sF)5?LW4BGpu(yknYajf+8 z?*ALrQPJq2603eY4KX+wjC9(aq?L34&l?Otj##YvR%VFb?}ZWYf#)G(%oxRB>I3k2 zf>2;%XhDG=lm<U&asZQG->EmB?rd9jFmsL19zWUM5RI+YhNX&(Tr7ReVR*(S6t+y^ z!A5gqy}4E2L=?O)HtIXiHXn(n8{4A!=;=n|(a!b*QzkyTIJjATveVdVZv6%uJlc8M zTz}SlV{k4S_4~M7U#iZeZ-R$A&*~4vRukbWgT7kd*!=9u+4Y^Kc)U?9SZXst2O$~r zw0@Vs^3d?E@ohlUMDA8Erg(wvTO4D&o>KBLMkeIGj2H2F;KCwba)VqEv4L`lVgxvH z!C63Qi5DGeE%N|90luRBJKUj~GkyCilA_IClM{JA>Bf3}9R*2VPJZR=dHQonKE_jL z7anH)imj5bc;t1fjQ9XG-}dCPx^(w^%=4)aR-LQ&f4}_o=HI8sYkC#S_mPplSu;1% z!*SS!$&5!yNcJXRDB-A2gO|Vl_gXcdMG_lRY{Uu9HEInoGZ~6ARVUK}*WbEW{bTgb zkP}*j;ZBQA1veO=H2uL<_jB2fs?NiD^%^~B>?=ax<v}l+Nu=<&DGBj>(vGqoP0?Ie zN&JMwZ4$()Hq@B_p&##~^e_uKmeKD}FM-6vCwr81RTK$vaSl+ujhi-P5<QcN*(U=X z!hTM<Tq>6GrF>Acfx2GJoB2!64NY1$K6zteJyDZa*)X1kb{p<41Z`%5PqSnGnj&CA J6H0v9{U6EW+%o_G literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1f15fda3a9031133519a72efb55e94b28cac02f1 GIT binary patch literal 1621 zcmaJ>+iu%77$zkjWLvUj$4RqecWbPzbAZzp7=|JNmK9rz0X9&8C?LoZBdZ~0my+Ei zaIajTH+zI#BtUQWO1$0GUSU_`PdaJS0i(bV|4HJ1_{2lct0T33|7!eFdI<dm%JnKK z;fdP$9|~d=V}>{;7=vsvi`&H3vdv1oOv=1MD!fXn+#wFHks7a)y7re?gS*7#9`UqZ zW=-BAE$$Ov>lN1K9n#Tqm2L1Y>1x?wn|zCGX}QMk@NKe<(J_kaapN6|8x*f>@<r?p zQP2Aus}y@!c8(^Y7}DZcOy{%T#B@xBvfde{S;FYyc|q6ywW}h#FVbvxZ?JoGE>gzQ z=-D);OxAyyrjLY?H+~I^G#lIw@SlazZA;_nm_Ir=Fz;w(FwjcRlD_`L!(&0|sR?MC zWA{IrR9M%XbU0^8DAF)9p_}UrZ<|$Bt<lrr!QRej5~k)LRlbQG{7lD!zPYx#M!jiA z$DA{oi_<ip=%`4w?`GL+DgRmt6cHRFV!cNvIL5K{&LQ@DR6?Yr`fkhC@bGB(Nw*^y z1S}wrA{2s;<sTFjsK86KvM#MFgi&D^r4?3K)>zS4)#zxfX{>8(XmmAt8k-thE1bAX z6!=AZh2Fx~Ix$`<TD-NiY-!nE;>(StwY0A+jF#w?f7xAP&=dPgk$H(OHzA`KK|#-d z8uhkhIiJs{5FM4abb=tw(jo{1lp>%mQ3j|0Q~?}-8UXxEq5<FnKm$Y*pshewXPS|@ z@WIpqQ#+?cz=3qZ+9@mate{ye%YrIruOv%3Whc^`=%KE|<R+UYX%w>Hwz<1V^ZDmi zMV49+L@dnnAovsgbJm}UbP*P`zX(PDWXfVH@;;yRqup8X_~P-aoj3a@@kM^HzYu$8 z#RcC{E6Mt!{w$r{PqVxT8M{AtIG&u&#|aqq4i+lyspv=QAB<_y&&N@oz>jDudoVi} zT~+fvwQ~T3n^pz?=P6gPtL!E0XrGJg*s(6QKO@?M>#_98FrqBvGzerpfM(7a$Zin4 zR;@4|eX{h{U5F@SYM|e$95nQ>_y**=05J9M)y^#i4%Yhf-j}iib*YJbQj&lW*;0iX zmnl>eMYdU(CDHm?(G&iE?#L#*kiZ>bqHnk)JKz~#Ukk>2!!PN9w@|l$aRA+93v7lN z#;VEY8p}FMAffd2%jPC9k-$`4^T+lW37R9FA5@g;?~l;099rdK7k_8_*tbAZkNq#F C3bVQZ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5005bf323e10f096699513d4d7fd7870c8454b9d GIT binary patch literal 2447 zcmZuzTW=dh6rP#Ac<tDZo3v>H2&EF0ute)Zp-`zpv`N|qH5bLM5Ef`yd&bT>yK8rL z9TLlZN>E>T=ue0r`4jyi^U70RdE^Dona#z4?s{g<Tz1Ym-?{losZ=2F{QhC<r*~yS z{=~`oV*~LWwB#4)1Q9eO5p7b6Gz(c|H7!G1p&dC*$Iy1@M!9Cr&`#(@`DWhGZdizB znln+cS)}9{5jo)<6X8jEWHn17UnkYVDFrrFsuwnfVH!L+Oy$b1uj(@0R{fS#urs&P z7eU;ur+z9o{Pu1TOITg3f4^Q|4U$v^tzjDU<HxZd9wtEod-J%r(vMSlkWMX^aGBRP z_{P@i+KVdFMdWdQwJx4rZWy&es*A@uqmpePBxzDXn(PhfP(cMd_L`QVEnx#~OGh}u zJtjxA=>lz320AD5qHs)_o|q9u81rw4O_~LOpri{ZSf+0q;lKw+<clr&61tS6bWD!e z37f!XYNhrO%(;`gM+C-P>X|V=CMN|vAqd<}H>)$+NrnTdR30wT9_K+Eq?{|fSh={C zZySJl5-Bvkz9FVy<v!v%g6|#NtF$v%FP62VWFk{Q-A-iKficf{JM@!;^FPSnNo}Bl zeXv|@-&eIxKNM0WwP?52{(Qh6jvn^z{d&J6M#+Qw`|68>bQIl#ryJKAwLvhr6U0gC zhvA*CzHaUA4O?AYG>z}eSoBq`4Zb2|T1$FCGB6HvcW|g?K+@aL6658xObgV5cVzq` z!};zx4(|v2Bl!9%;A7IWGU(5NwH01(U{$k7K_mg<s*(-YaA^*^dF=4SXV4Oan1D>9 z%B9us8Vs+9g7#m*^B#1-ob+gBPiFY&BB~C+^Vp9d9t_uv-6hZK@aa9ggF#2w=;jp1 z>CfNK7zGu`lx=G7dw<}^U}(eQ{p_?C`f+#YcO|;(InQa#&-dF#9yo+9m4jv!eE}-J zr3cL5PLJSSB|rc5nt}4{#2V8vTOt$s+8TrF_nbYZwqeIT$q5L9o(C;IW)mAiqtKgy zfGBR0R~2)%1ZO+2TE4P63#%1#cV$9e+hZmeth^gTNG~Da*M#*5$GMYvGqcC`A_UcM zxNA=s#l7p<UN#4A*=dkeSU2I+A_2<DsQ-OuPMH&M_Hy@C<p%;XxMwmjBf|}leqoQj zrRu5SadQGlA$_tqK{=N8Y@DC#2rD<hZn@3Tt=q{m{Ibwk-VM@a2;{z6_S5ASq*~ZJ z1^9_VZ#zY+oMKuy{Rf`v2N2p|P^qm@#;OSGx)4J~<q(spROpx5S=-s!+R<*<?{=lq zj*zWkSE1jj1?<qc+TGl0@QpR?W?yP|y-~-x_jK#!<|<!rXs6zIywlM0UGV4jP$?P1 z2>uO>b%8@N$)=g-+Z`!|DjD`h6rEpPYpks_);FK&*=|4OGVTw%yIlCGugm7ne%uL! zjN4Mr)t_(eG*(_Vc;orb8cbfSRvi;P+CxY{Mx|*0@pYCIQCaPwG#qg-(RCSOpMn_Q zKuaD#N9c80G0CP3>Bcq`_LzRkbb-2bj?KZDMOt8GR;EQb?Xl79R9K>J7vYGuz-GeZ zV<5n=<b;B|qRTTwvDAdd5zDfJZ7@=pX)=hc$UmrBnS!8`sfirMjxL_1c{BU3UU<Qe z&=RZ=#ON?unv(M>s!(L0uwW+Q91O;zz8Ho`7dd}5^uuh&<YkixwFe#vH7Pxu@)d;A z2(C+K6{Ic05GvIL<dAnvRy7F~%h@N;67)=u7IQ@#U+<R5$eY!&o{d^(SuXQ`g$}Og zGQ%3riL$>FrWQhJ!(uX3`m$>1_6F@ZJ;=(R3s)vkCr#aSWIT)#<Kre8vQls%Z6-I$ Vs=Y@UBHv<NF#;FC_}N>r{skT;P;>wQ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..de3bd4a933fb7d60cd03fb224374e23441714c3c GIT binary patch literal 5837 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/utf8prober.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/utf8prober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..726599e6b1ac5326db67eba06a9f9c9fd4a086e2 GIT binary patch literal 1978 zcmah~Pfr_16rb6DUYj)_h}2fCs;E^Hxe7RGlm?`#G=Kw0!AAC?N>;0py)!m8yNj7! zQ?Selq+F_;`T^kBOFl|Jz?@q3#Hl^^)c0nAn5tD*nm2FW{Cn>=@BMbQSS%3ue*Ccg z-7ld1j)R-e0_7WM$tDO+I1Nceo0Ot%ghpgG&B$t6dTfSv<TM?vTVXD8n=U0AgxlOX zC)^SA%xva)u0cxf6@}wUR2A3uTCyS19eL0evScU^wO-t9q^(paZ@U%j^<tq%uzYUq zfZt4BPvIfE{>vrS*k;?c^~$RNPQLxjYc26X5u`~uX&Rh1&DW$uxxvkIw`pnJ;x_2E zaJa*B=j4nwbD+CCuXUFf_|!Q8_dQ;OzVMn@q&WqlOsfK3p9Rp(uKRT*!1(aP9-Y9J zd=4TdDIJqD<HERv$<$1(GZ-_Q6OhiBT;$Ns2^>wUC0E(Wa3G}2!B*um){A>7W73A9 zbkLR$G$bsERFTEQh(&D{0H}$wrAR~y_*jVuJJ9DD3&K{CF!nR~D=80T?+8FHAGKt; za}aVNlXA3I4xS9y@@TpL_=l$*K1#lPdL+L%PDjyW__}e~FAsWyg<hPbtuS18_Po8f zKWul=s2e*HF+Y%Hbb*VsJWM-F1O2#*gA<ttj~_rwTo8m#(*kwqX#O35i#HMeJAj|S zuDbw^N#D$%<OrjsfitRCcz(&2c#p<TdZ=NZ%PE|qvY2(#XqrJWivpKDf|ek-nTMm< z3I8;vcbvl)Uc((&DxAW*8P$;uaW5?CbFZ(;?zp{3dHRt=%Hmcep5T511TjYMP24uQ z=6^3$SsedypBuK~?y%Jr&nE7gME+(z(0;%oj0c+z?k7-=`(wIJzHgrzfI7LLW8;#Z znqxCH`sThNAEj2`#w6Y$hmN-9z`6=n_l`9WR!DR>p>PR+?b|rANPmhO&xt|U)S>e& z6hq&Gokdvt28v?(5-l_PmV9$_9<Bhe&FU38EH$Cb>K9gpSRAJeGBgzuBT#mwUa!?9 z7NK&gHJ@!)l#?w`&X(W6vHP;NTU}>czOozsi@LAoyYM=}P)ZR)5BVI5SSJtEq-Ll5 zdd07-`CHWuHLcek#GM`&aUj%OW3yKG*LHp8Z`La?c(q=#bjm5WeUb{eTPhkr7F<`a z_El%cyA-iHLhxnqIr$g_fnxEXxzxIq({#@8pp0B&G&7MlxbHSy5FHF$KjR`OoSs6d z^nt(kiF`0dU61F<GC8H(9MkuKea4W<x|pnL_wB}SqkC`vSh>QYxaPP&S4u{PMzL0{ zu(iz>b+%Klt%4OROF6?h?Cpzxq`kZkbFZK!`j?|anML<Mm~j6tmL(5)537VRRbVVS z;KLAgkFmpHE6ir(LpW6Pi!Nd10_gy6rYCX^C+?y648?sAz?2yi1|kfBO>c3B+R=QV zsQ@YWQ)mgA0CmH2JlnH8%bnMhQY{r!@w!4Yij#=7vIWp^qLVGlzPap?b<#xH4^0!e ma-w#SB#|cajHPZp$$UaTl>1c{^4A}sGstKjorP5JtiJ(lv%?1f literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5d5fa76bf960e2b445387341c1f3c39e5394ee94 GIT binary patch literal 447 zcmXv~yH3L}6iwQcq99flmOIj+aiKf}La0J8uoQ_Rh6*WiVka?8Y|C~6%{TB7Ff#Ku zS@{D-CfrbtbdP;}ujF&j<@UDkSiJ5=kKgwET8V#j?PX$1?^q(v+#&AVrS4mYbl%;0 zmvm>&z^gy~`;2KQ1SxY0^o41oLGXMDMu298%vrJoMU7&#Vmt+tQK+cWOmN_35m5yq zfjGm8P~#^`6!6SU#yDtdN*Tx{U{0WItfxSik;L%=r&I^Ne}+qw33Ucnn8Rg`c{>Js z1oI&Jmy@)>EDvH)4E(w`4o1OY;|9}#*Yv}Xh&T+JtuS00v!bW1bJO%6uJ2|yx6=<t zZP*xE`jJQ~R$)U?g%wIfPV7FY$WXj5!_)foY4ki!NUe{@l{$DabuqF?Il4!Z$syy~ r;5;85okZE9jMCL(TlRNOghJ~r(b|knpxHeC3;1GXLVK3Hj_3XYO-zk? literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/big5freq.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/big5freq.py new file mode 100644 index 0000000..38f3251 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/big5freq.py @@ -0,0 +1,386 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# Big5 frequency table +# by Taiwan's Mandarin Promotion Council +# <http://www.edu.tw:81/mandr/> +# +# 128 --> 0.42261 +# 256 --> 0.57851 +# 512 --> 0.74851 +# 1024 --> 0.89384 +# 2048 --> 0.97583 +# +# Ideal Distribution Ratio = 0.74851/(1-0.74851) =2.98 +# Random Distribution Ration = 512/(5401-512)=0.105 +# +# Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR + +BIG5_TYPICAL_DISTRIBUTION_RATIO = 0.75 + +#Char to FreqOrder table +BIG5_TABLE_SIZE = 5376 + +BIG5_CHAR_TO_FREQ_ORDER = ( + 1,1801,1506, 255,1431, 198, 9, 82, 6,5008, 177, 202,3681,1256,2821, 110, # 16 +3814, 33,3274, 261, 76, 44,2114, 16,2946,2187,1176, 659,3971, 26,3451,2653, # 32 +1198,3972,3350,4202, 410,2215, 302, 590, 361,1964, 8, 204, 58,4510,5009,1932, # 48 + 63,5010,5011, 317,1614, 75, 222, 159,4203,2417,1480,5012,3555,3091, 224,2822, # 64 +3682, 3, 10,3973,1471, 29,2787,1135,2866,1940, 873, 130,3275,1123, 312,5013, # 80 +4511,2052, 507, 252, 682,5014, 142,1915, 124, 206,2947, 34,3556,3204, 64, 604, # 96 +5015,2501,1977,1978, 155,1991, 645, 641,1606,5016,3452, 337, 72, 406,5017, 80, # 112 + 630, 238,3205,1509, 263, 939,1092,2654, 756,1440,1094,3453, 449, 69,2987, 591, # 128 + 179,2096, 471, 115,2035,1844, 60, 50,2988, 134, 806,1869, 734,2036,3454, 180, # 144 + 995,1607, 156, 537,2907, 688,5018, 319,1305, 779,2145, 514,2379, 298,4512, 359, # 160 +2502, 90,2716,1338, 663, 11, 906,1099,2553, 20,2441, 182, 532,1716,5019, 732, # 176 +1376,4204,1311,1420,3206, 25,2317,1056, 113, 399, 382,1950, 242,3455,2474, 529, # 192 +3276, 475,1447,3683,5020, 117, 21, 656, 810,1297,2300,2334,3557,5021, 126,4205, # 208 + 706, 456, 150, 613,4513, 71,1118,2037,4206, 145,3092, 85, 835, 486,2115,1246, # 224 +1426, 428, 727,1285,1015, 800, 106, 623, 303,1281,5022,2128,2359, 347,3815, 221, # 240 +3558,3135,5023,1956,1153,4207, 83, 296,1199,3093, 192, 624, 93,5024, 822,1898, # 256 +2823,3136, 795,2065, 991,1554,1542,1592, 27, 43,2867, 859, 139,1456, 860,4514, # 272 + 437, 712,3974, 164,2397,3137, 695, 211,3037,2097, 195,3975,1608,3559,3560,3684, # 288 +3976, 234, 811,2989,2098,3977,2233,1441,3561,1615,2380, 668,2077,1638, 305, 228, # 304 +1664,4515, 467, 415,5025, 262,2099,1593, 239, 108, 300, 200,1033, 512,1247,2078, # 320 +5026,5027,2176,3207,3685,2682, 593, 845,1062,3277, 88,1723,2038,3978,1951, 212, # 336 + 266, 152, 149, 468,1899,4208,4516, 77, 187,5028,3038, 37, 5,2990,5029,3979, # 352 +5030,5031, 39,2524,4517,2908,3208,2079, 55, 148, 74,4518, 545, 483,1474,1029, # 368 +1665, 217,1870,1531,3138,1104,2655,4209, 24, 172,3562, 900,3980,3563,3564,4519, # 384 + 32,1408,2824,1312, 329, 487,2360,2251,2717, 784,2683, 4,3039,3351,1427,1789, # 400 + 188, 109, 499,5032,3686,1717,1790, 888,1217,3040,4520,5033,3565,5034,3352,1520, # 416 +3687,3981, 196,1034, 775,5035,5036, 929,1816, 249, 439, 38,5037,1063,5038, 794, # 432 +3982,1435,2301, 46, 178,3278,2066,5039,2381,5040, 214,1709,4521, 804, 35, 707, # 448 + 324,3688,1601,2554, 140, 459,4210,5041,5042,1365, 839, 272, 978,2262,2580,3456, # 464 +2129,1363,3689,1423, 697, 100,3094, 48, 70,1231, 495,3139,2196,5043,1294,5044, # 480 +2080, 462, 586,1042,3279, 853, 256, 988, 185,2382,3457,1698, 434,1084,5045,3458, # 496 + 314,2625,2788,4522,2335,2336, 569,2285, 637,1817,2525, 757,1162,1879,1616,3459, # 512 + 287,1577,2116, 768,4523,1671,2868,3566,2526,1321,3816, 909,2418,5046,4211, 933, # 528 +3817,4212,2053,2361,1222,4524, 765,2419,1322, 786,4525,5047,1920,1462,1677,2909, # 544 +1699,5048,4526,1424,2442,3140,3690,2600,3353,1775,1941,3460,3983,4213, 309,1369, # 560 +1130,2825, 364,2234,1653,1299,3984,3567,3985,3986,2656, 525,1085,3041, 902,2001, # 576 +1475, 964,4527, 421,1845,1415,1057,2286, 940,1364,3141, 376,4528,4529,1381, 7, # 592 +2527, 983,2383, 336,1710,2684,1846, 321,3461, 559,1131,3042,2752,1809,1132,1313, # 608 + 265,1481,1858,5049, 352,1203,2826,3280, 167,1089, 420,2827, 776, 792,1724,3568, # 624 +4214,2443,3281,5050,4215,5051, 446, 229, 333,2753, 901,3818,1200,1557,4530,2657, # 640 +1921, 395,2754,2685,3819,4216,1836, 125, 916,3209,2626,4531,5052,5053,3820,5054, # 656 +5055,5056,4532,3142,3691,1133,2555,1757,3462,1510,2318,1409,3569,5057,2146, 438, # 672 +2601,2910,2384,3354,1068, 958,3043, 461, 311,2869,2686,4217,1916,3210,4218,1979, # 688 + 383, 750,2755,2627,4219, 274, 539, 385,1278,1442,5058,1154,1965, 384, 561, 210, # 704 + 98,1295,2556,3570,5059,1711,2420,1482,3463,3987,2911,1257, 129,5060,3821, 642, # 720 + 523,2789,2790,2658,5061, 141,2235,1333, 68, 176, 441, 876, 907,4220, 603,2602, # 736 + 710, 171,3464, 404, 549, 18,3143,2398,1410,3692,1666,5062,3571,4533,2912,4534, # 752 +5063,2991, 368,5064, 146, 366, 99, 871,3693,1543, 748, 807,1586,1185, 22,2263, # 768 + 379,3822,3211,5065,3212, 505,1942,2628,1992,1382,2319,5066, 380,2362, 218, 702, # 784 +1818,1248,3465,3044,3572,3355,3282,5067,2992,3694, 930,3283,3823,5068, 59,5069, # 800 + 585, 601,4221, 497,3466,1112,1314,4535,1802,5070,1223,1472,2177,5071, 749,1837, # 816 + 690,1900,3824,1773,3988,1476, 429,1043,1791,2236,2117, 917,4222, 447,1086,1629, # 832 +5072, 556,5073,5074,2021,1654, 844,1090, 105, 550, 966,1758,2828,1008,1783, 686, # 848 +1095,5075,2287, 793,1602,5076,3573,2603,4536,4223,2948,2302,4537,3825, 980,2503, # 864 + 544, 353, 527,4538, 908,2687,2913,5077, 381,2629,1943,1348,5078,1341,1252, 560, # 880 +3095,5079,3467,2870,5080,2054, 973, 886,2081, 143,4539,5081,5082, 157,3989, 496, # 896 +4224, 57, 840, 540,2039,4540,4541,3468,2118,1445, 970,2264,1748,1966,2082,4225, # 912 +3144,1234,1776,3284,2829,3695, 773,1206,2130,1066,2040,1326,3990,1738,1725,4226, # 928 + 279,3145, 51,1544,2604, 423,1578,2131,2067, 173,4542,1880,5083,5084,1583, 264, # 944 + 610,3696,4543,2444, 280, 154,5085,5086,5087,1739, 338,1282,3096, 693,2871,1411, # 960 +1074,3826,2445,5088,4544,5089,5090,1240, 952,2399,5091,2914,1538,2688, 685,1483, # 976 +4227,2475,1436, 953,4228,2055,4545, 671,2400, 79,4229,2446,3285, 608, 567,2689, # 992 +3469,4230,4231,1691, 393,1261,1792,2401,5092,4546,5093,5094,5095,5096,1383,1672, # 1008 +3827,3213,1464, 522,1119, 661,1150, 216, 675,4547,3991,1432,3574, 609,4548,2690, # 1024 +2402,5097,5098,5099,4232,3045, 0,5100,2476, 315, 231,2447, 301,3356,4549,2385, # 1040 +5101, 233,4233,3697,1819,4550,4551,5102, 96,1777,1315,2083,5103, 257,5104,1810, # 1056 +3698,2718,1139,1820,4234,2022,1124,2164,2791,1778,2659,5105,3097, 363,1655,3214, # 1072 +5106,2993,5107,5108,5109,3992,1567,3993, 718, 103,3215, 849,1443, 341,3357,2949, # 1088 +1484,5110,1712, 127, 67, 339,4235,2403, 679,1412, 821,5111,5112, 834, 738, 351, # 1104 +2994,2147, 846, 235,1497,1881, 418,1993,3828,2719, 186,1100,2148,2756,3575,1545, # 1120 +1355,2950,2872,1377, 583,3994,4236,2581,2995,5113,1298,3699,1078,2557,3700,2363, # 1136 + 78,3829,3830, 267,1289,2100,2002,1594,4237, 348, 369,1274,2197,2178,1838,4552, # 1152 +1821,2830,3701,2757,2288,2003,4553,2951,2758, 144,3358, 882,4554,3995,2759,3470, # 1168 +4555,2915,5114,4238,1726, 320,5115,3996,3046, 788,2996,5116,2831,1774,1327,2873, # 1184 +3997,2832,5117,1306,4556,2004,1700,3831,3576,2364,2660, 787,2023, 506, 824,3702, # 1200 + 534, 323,4557,1044,3359,2024,1901, 946,3471,5118,1779,1500,1678,5119,1882,4558, # 1216 + 165, 243,4559,3703,2528, 123, 683,4239, 764,4560, 36,3998,1793, 589,2916, 816, # 1232 + 626,1667,3047,2237,1639,1555,1622,3832,3999,5120,4000,2874,1370,1228,1933, 891, # 1248 +2084,2917, 304,4240,5121, 292,2997,2720,3577, 691,2101,4241,1115,4561, 118, 662, # 1264 +5122, 611,1156, 854,2386,1316,2875, 2, 386, 515,2918,5123,5124,3286, 868,2238, # 1280 +1486, 855,2661, 785,2216,3048,5125,1040,3216,3578,5126,3146, 448,5127,1525,5128, # 1296 +2165,4562,5129,3833,5130,4242,2833,3579,3147, 503, 818,4001,3148,1568, 814, 676, # 1312 +1444, 306,1749,5131,3834,1416,1030, 197,1428, 805,2834,1501,4563,5132,5133,5134, # 1328 +1994,5135,4564,5136,5137,2198, 13,2792,3704,2998,3149,1229,1917,5138,3835,2132, # 1344 +5139,4243,4565,2404,3580,5140,2217,1511,1727,1120,5141,5142, 646,3836,2448, 307, # 1360 +5143,5144,1595,3217,5145,5146,5147,3705,1113,1356,4002,1465,2529,2530,5148, 519, # 1376 +5149, 128,2133, 92,2289,1980,5150,4003,1512, 342,3150,2199,5151,2793,2218,1981, # 1392 +3360,4244, 290,1656,1317, 789, 827,2365,5152,3837,4566, 562, 581,4004,5153, 401, # 1408 +4567,2252, 94,4568,5154,1399,2794,5155,1463,2025,4569,3218,1944,5156, 828,1105, # 1424 +4245,1262,1394,5157,4246, 605,4570,5158,1784,2876,5159,2835, 819,2102, 578,2200, # 1440 +2952,5160,1502, 436,3287,4247,3288,2836,4005,2919,3472,3473,5161,2721,2320,5162, # 1456 +5163,2337,2068, 23,4571, 193, 826,3838,2103, 699,1630,4248,3098, 390,1794,1064, # 1472 +3581,5164,1579,3099,3100,1400,5165,4249,1839,1640,2877,5166,4572,4573, 137,4250, # 1488 + 598,3101,1967, 780, 104, 974,2953,5167, 278, 899, 253, 402, 572, 504, 493,1339, # 1504 +5168,4006,1275,4574,2582,2558,5169,3706,3049,3102,2253, 565,1334,2722, 863, 41, # 1520 +5170,5171,4575,5172,1657,2338, 19, 463,2760,4251, 606,5173,2999,3289,1087,2085, # 1536 +1323,2662,3000,5174,1631,1623,1750,4252,2691,5175,2878, 791,2723,2663,2339, 232, # 1552 +2421,5176,3001,1498,5177,2664,2630, 755,1366,3707,3290,3151,2026,1609, 119,1918, # 1568 +3474, 862,1026,4253,5178,4007,3839,4576,4008,4577,2265,1952,2477,5179,1125, 817, # 1584 +4254,4255,4009,1513,1766,2041,1487,4256,3050,3291,2837,3840,3152,5180,5181,1507, # 1600 +5182,2692, 733, 40,1632,1106,2879, 345,4257, 841,2531, 230,4578,3002,1847,3292, # 1616 +3475,5183,1263, 986,3476,5184, 735, 879, 254,1137, 857, 622,1300,1180,1388,1562, # 1632 +4010,4011,2954, 967,2761,2665,1349, 592,2134,1692,3361,3003,1995,4258,1679,4012, # 1648 +1902,2188,5185, 739,3708,2724,1296,1290,5186,4259,2201,2202,1922,1563,2605,2559, # 1664 +1871,2762,3004,5187, 435,5188, 343,1108, 596, 17,1751,4579,2239,3477,3709,5189, # 1680 +4580, 294,3582,2955,1693, 477, 979, 281,2042,3583, 643,2043,3710,2631,2795,2266, # 1696 +1031,2340,2135,2303,3584,4581, 367,1249,2560,5190,3585,5191,4582,1283,3362,2005, # 1712 + 240,1762,3363,4583,4584, 836,1069,3153, 474,5192,2149,2532, 268,3586,5193,3219, # 1728 +1521,1284,5194,1658,1546,4260,5195,3587,3588,5196,4261,3364,2693,1685,4262, 961, # 1744 +1673,2632, 190,2006,2203,3841,4585,4586,5197, 570,2504,3711,1490,5198,4587,2633, # 1760 +3293,1957,4588, 584,1514, 396,1045,1945,5199,4589,1968,2449,5200,5201,4590,4013, # 1776 + 619,5202,3154,3294, 215,2007,2796,2561,3220,4591,3221,4592, 763,4263,3842,4593, # 1792 +5203,5204,1958,1767,2956,3365,3712,1174, 452,1477,4594,3366,3155,5205,2838,1253, # 1808 +2387,2189,1091,2290,4264, 492,5206, 638,1169,1825,2136,1752,4014, 648, 926,1021, # 1824 +1324,4595, 520,4596, 997, 847,1007, 892,4597,3843,2267,1872,3713,2405,1785,4598, # 1840 +1953,2957,3103,3222,1728,4265,2044,3714,4599,2008,1701,3156,1551, 30,2268,4266, # 1856 +5207,2027,4600,3589,5208, 501,5209,4267, 594,3478,2166,1822,3590,3479,3591,3223, # 1872 + 829,2839,4268,5210,1680,3157,1225,4269,5211,3295,4601,4270,3158,2341,5212,4602, # 1888 +4271,5213,4015,4016,5214,1848,2388,2606,3367,5215,4603, 374,4017, 652,4272,4273, # 1904 + 375,1140, 798,5216,5217,5218,2366,4604,2269, 546,1659, 138,3051,2450,4605,5219, # 1920 +2254, 612,1849, 910, 796,3844,1740,1371, 825,3845,3846,5220,2920,2562,5221, 692, # 1936 + 444,3052,2634, 801,4606,4274,5222,1491, 244,1053,3053,4275,4276, 340,5223,4018, # 1952 +1041,3005, 293,1168, 87,1357,5224,1539, 959,5225,2240, 721, 694,4277,3847, 219, # 1968 +1478, 644,1417,3368,2666,1413,1401,1335,1389,4019,5226,5227,3006,2367,3159,1826, # 1984 + 730,1515, 184,2840, 66,4607,5228,1660,2958, 246,3369, 378,1457, 226,3480, 975, # 2000 +4020,2959,1264,3592, 674, 696,5229, 163,5230,1141,2422,2167, 713,3593,3370,4608, # 2016 +4021,5231,5232,1186, 15,5233,1079,1070,5234,1522,3224,3594, 276,1050,2725, 758, # 2032 +1126, 653,2960,3296,5235,2342, 889,3595,4022,3104,3007, 903,1250,4609,4023,3481, # 2048 +3596,1342,1681,1718, 766,3297, 286, 89,2961,3715,5236,1713,5237,2607,3371,3008, # 2064 +5238,2962,2219,3225,2880,5239,4610,2505,2533, 181, 387,1075,4024, 731,2190,3372, # 2080 +5240,3298, 310, 313,3482,2304, 770,4278, 54,3054, 189,4611,3105,3848,4025,5241, # 2096 +1230,1617,1850, 355,3597,4279,4612,3373, 111,4280,3716,1350,3160,3483,3055,4281, # 2112 +2150,3299,3598,5242,2797,4026,4027,3009, 722,2009,5243,1071, 247,1207,2343,2478, # 2128 +1378,4613,2010, 864,1437,1214,4614, 373,3849,1142,2220, 667,4615, 442,2763,2563, # 2144 +3850,4028,1969,4282,3300,1840, 837, 170,1107, 934,1336,1883,5244,5245,2119,4283, # 2160 +2841, 743,1569,5246,4616,4284, 582,2389,1418,3484,5247,1803,5248, 357,1395,1729, # 2176 +3717,3301,2423,1564,2241,5249,3106,3851,1633,4617,1114,2086,4285,1532,5250, 482, # 2192 +2451,4618,5251,5252,1492, 833,1466,5253,2726,3599,1641,2842,5254,1526,1272,3718, # 2208 +4286,1686,1795, 416,2564,1903,1954,1804,5255,3852,2798,3853,1159,2321,5256,2881, # 2224 +4619,1610,1584,3056,2424,2764, 443,3302,1163,3161,5257,5258,4029,5259,4287,2506, # 2240 +3057,4620,4030,3162,2104,1647,3600,2011,1873,4288,5260,4289, 431,3485,5261, 250, # 2256 + 97, 81,4290,5262,1648,1851,1558, 160, 848,5263, 866, 740,1694,5264,2204,2843, # 2272 +3226,4291,4621,3719,1687, 950,2479, 426, 469,3227,3720,3721,4031,5265,5266,1188, # 2288 + 424,1996, 861,3601,4292,3854,2205,2694, 168,1235,3602,4293,5267,2087,1674,4622, # 2304 +3374,3303, 220,2565,1009,5268,3855, 670,3010, 332,1208, 717,5269,5270,3603,2452, # 2320 +4032,3375,5271, 513,5272,1209,2882,3376,3163,4623,1080,5273,5274,5275,5276,2534, # 2336 +3722,3604, 815,1587,4033,4034,5277,3605,3486,3856,1254,4624,1328,3058,1390,4035, # 2352 +1741,4036,3857,4037,5278, 236,3858,2453,3304,5279,5280,3723,3859,1273,3860,4625, # 2368 +5281, 308,5282,4626, 245,4627,1852,2480,1307,2583, 430, 715,2137,2454,5283, 270, # 2384 + 199,2883,4038,5284,3606,2727,1753, 761,1754, 725,1661,1841,4628,3487,3724,5285, # 2400 +5286, 587, 14,3305, 227,2608, 326, 480,2270, 943,2765,3607, 291, 650,1884,5287, # 2416 +1702,1226, 102,1547, 62,3488, 904,4629,3489,1164,4294,5288,5289,1224,1548,2766, # 2432 + 391, 498,1493,5290,1386,1419,5291,2056,1177,4630, 813, 880,1081,2368, 566,1145, # 2448 +4631,2291,1001,1035,2566,2609,2242, 394,1286,5292,5293,2069,5294, 86,1494,1730, # 2464 +4039, 491,1588, 745, 897,2963, 843,3377,4040,2767,2884,3306,1768, 998,2221,2070, # 2480 + 397,1827,1195,1970,3725,3011,3378, 284,5295,3861,2507,2138,2120,1904,5296,4041, # 2496 +2151,4042,4295,1036,3490,1905, 114,2567,4296, 209,1527,5297,5298,2964,2844,2635, # 2512 +2390,2728,3164, 812,2568,5299,3307,5300,1559, 737,1885,3726,1210, 885, 28,2695, # 2528 +3608,3862,5301,4297,1004,1780,4632,5302, 346,1982,2222,2696,4633,3863,1742, 797, # 2544 +1642,4043,1934,1072,1384,2152, 896,4044,3308,3727,3228,2885,3609,5303,2569,1959, # 2560 +4634,2455,1786,5304,5305,5306,4045,4298,1005,1308,3728,4299,2729,4635,4636,1528, # 2576 +2610, 161,1178,4300,1983, 987,4637,1101,4301, 631,4046,1157,3229,2425,1343,1241, # 2592 +1016,2243,2570, 372, 877,2344,2508,1160, 555,1935, 911,4047,5307, 466,1170, 169, # 2608 +1051,2921,2697,3729,2481,3012,1182,2012,2571,1251,2636,5308, 992,2345,3491,1540, # 2624 +2730,1201,2071,2406,1997,2482,5309,4638, 528,1923,2191,1503,1874,1570,2369,3379, # 2640 +3309,5310, 557,1073,5311,1828,3492,2088,2271,3165,3059,3107, 767,3108,2799,4639, # 2656 +1006,4302,4640,2346,1267,2179,3730,3230, 778,4048,3231,2731,1597,2667,5312,4641, # 2672 +5313,3493,5314,5315,5316,3310,2698,1433,3311, 131, 95,1504,4049, 723,4303,3166, # 2688 +1842,3610,2768,2192,4050,2028,2105,3731,5317,3013,4051,1218,5318,3380,3232,4052, # 2704 +4304,2584, 248,1634,3864, 912,5319,2845,3732,3060,3865, 654, 53,5320,3014,5321, # 2720 +1688,4642, 777,3494,1032,4053,1425,5322, 191, 820,2121,2846, 971,4643, 931,3233, # 2736 + 135, 664, 783,3866,1998, 772,2922,1936,4054,3867,4644,2923,3234, 282,2732, 640, # 2752 +1372,3495,1127, 922, 325,3381,5323,5324, 711,2045,5325,5326,4055,2223,2800,1937, # 2768 +4056,3382,2224,2255,3868,2305,5327,4645,3869,1258,3312,4057,3235,2139,2965,4058, # 2784 +4059,5328,2225, 258,3236,4646, 101,1227,5329,3313,1755,5330,1391,3314,5331,2924, # 2800 +2057, 893,5332,5333,5334,1402,4305,2347,5335,5336,3237,3611,5337,5338, 878,1325, # 2816 +1781,2801,4647, 259,1385,2585, 744,1183,2272,4648,5339,4060,2509,5340, 684,1024, # 2832 +4306,5341, 472,3612,3496,1165,3315,4061,4062, 322,2153, 881, 455,1695,1152,1340, # 2848 + 660, 554,2154,4649,1058,4650,4307, 830,1065,3383,4063,4651,1924,5342,1703,1919, # 2864 +5343, 932,2273, 122,5344,4652, 947, 677,5345,3870,2637, 297,1906,1925,2274,4653, # 2880 +2322,3316,5346,5347,4308,5348,4309, 84,4310, 112, 989,5349, 547,1059,4064, 701, # 2896 +3613,1019,5350,4311,5351,3497, 942, 639, 457,2306,2456, 993,2966, 407, 851, 494, # 2912 +4654,3384, 927,5352,1237,5353,2426,3385, 573,4312, 680, 921,2925,1279,1875, 285, # 2928 + 790,1448,1984, 719,2168,5354,5355,4655,4065,4066,1649,5356,1541, 563,5357,1077, # 2944 +5358,3386,3061,3498, 511,3015,4067,4068,3733,4069,1268,2572,3387,3238,4656,4657, # 2960 +5359, 535,1048,1276,1189,2926,2029,3167,1438,1373,2847,2967,1134,2013,5360,4313, # 2976 +1238,2586,3109,1259,5361, 700,5362,2968,3168,3734,4314,5363,4315,1146,1876,1907, # 2992 +4658,2611,4070, 781,2427, 132,1589, 203, 147, 273,2802,2407, 898,1787,2155,4071, # 3008 +4072,5364,3871,2803,5365,5366,4659,4660,5367,3239,5368,1635,3872, 965,5369,1805, # 3024 +2699,1516,3614,1121,1082,1329,3317,4073,1449,3873, 65,1128,2848,2927,2769,1590, # 3040 +3874,5370,5371, 12,2668, 45, 976,2587,3169,4661, 517,2535,1013,1037,3240,5372, # 3056 +3875,2849,5373,3876,5374,3499,5375,2612, 614,1999,2323,3877,3110,2733,2638,5376, # 3072 +2588,4316, 599,1269,5377,1811,3735,5378,2700,3111, 759,1060, 489,1806,3388,3318, # 3088 +1358,5379,5380,2391,1387,1215,2639,2256, 490,5381,5382,4317,1759,2392,2348,5383, # 3104 +4662,3878,1908,4074,2640,1807,3241,4663,3500,3319,2770,2349, 874,5384,5385,3501, # 3120 +3736,1859, 91,2928,3737,3062,3879,4664,5386,3170,4075,2669,5387,3502,1202,1403, # 3136 +3880,2969,2536,1517,2510,4665,3503,2511,5388,4666,5389,2701,1886,1495,1731,4076, # 3152 +2370,4667,5390,2030,5391,5392,4077,2702,1216, 237,2589,4318,2324,4078,3881,4668, # 3168 +4669,2703,3615,3504, 445,4670,5393,5394,5395,5396,2771, 61,4079,3738,1823,4080, # 3184 +5397, 687,2046, 935, 925, 405,2670, 703,1096,1860,2734,4671,4081,1877,1367,2704, # 3200 +3389, 918,2106,1782,2483, 334,3320,1611,1093,4672, 564,3171,3505,3739,3390, 945, # 3216 +2641,2058,4673,5398,1926, 872,4319,5399,3506,2705,3112, 349,4320,3740,4082,4674, # 3232 +3882,4321,3741,2156,4083,4675,4676,4322,4677,2408,2047, 782,4084, 400, 251,4323, # 3248 +1624,5400,5401, 277,3742, 299,1265, 476,1191,3883,2122,4324,4325,1109, 205,5402, # 3264 +2590,1000,2157,3616,1861,5403,5404,5405,4678,5406,4679,2573, 107,2484,2158,4085, # 3280 +3507,3172,5407,1533, 541,1301, 158, 753,4326,2886,3617,5408,1696, 370,1088,4327, # 3296 +4680,3618, 579, 327, 440, 162,2244, 269,1938,1374,3508, 968,3063, 56,1396,3113, # 3312 +2107,3321,3391,5409,1927,2159,4681,3016,5410,3619,5411,5412,3743,4682,2485,5413, # 3328 +2804,5414,1650,4683,5415,2613,5416,5417,4086,2671,3392,1149,3393,4087,3884,4088, # 3344 +5418,1076, 49,5419, 951,3242,3322,3323, 450,2850, 920,5420,1812,2805,2371,4328, # 3360 +1909,1138,2372,3885,3509,5421,3243,4684,1910,1147,1518,2428,4685,3886,5422,4686, # 3376 +2393,2614, 260,1796,3244,5423,5424,3887,3324, 708,5425,3620,1704,5426,3621,1351, # 3392 +1618,3394,3017,1887, 944,4329,3395,4330,3064,3396,4331,5427,3744, 422, 413,1714, # 3408 +3325, 500,2059,2350,4332,2486,5428,1344,1911, 954,5429,1668,5430,5431,4089,2409, # 3424 +4333,3622,3888,4334,5432,2307,1318,2512,3114, 133,3115,2887,4687, 629, 31,2851, # 3440 +2706,3889,4688, 850, 949,4689,4090,2970,1732,2089,4335,1496,1853,5433,4091, 620, # 3456 +3245, 981,1242,3745,3397,1619,3746,1643,3326,2140,2457,1971,1719,3510,2169,5434, # 3472 +3246,5435,5436,3398,1829,5437,1277,4690,1565,2048,5438,1636,3623,3116,5439, 869, # 3488 +2852, 655,3890,3891,3117,4092,3018,3892,1310,3624,4691,5440,5441,5442,1733, 558, # 3504 +4692,3747, 335,1549,3065,1756,4336,3748,1946,3511,1830,1291,1192, 470,2735,2108, # 3520 +2806, 913,1054,4093,5443,1027,5444,3066,4094,4693, 982,2672,3399,3173,3512,3247, # 3536 +3248,1947,2807,5445, 571,4694,5446,1831,5447,3625,2591,1523,2429,5448,2090, 984, # 3552 +4695,3749,1960,5449,3750, 852, 923,2808,3513,3751, 969,1519, 999,2049,2325,1705, # 3568 +5450,3118, 615,1662, 151, 597,4095,2410,2326,1049, 275,4696,3752,4337, 568,3753, # 3584 +3626,2487,4338,3754,5451,2430,2275, 409,3249,5452,1566,2888,3514,1002, 769,2853, # 3600 + 194,2091,3174,3755,2226,3327,4339, 628,1505,5453,5454,1763,2180,3019,4096, 521, # 3616 +1161,2592,1788,2206,2411,4697,4097,1625,4340,4341, 412, 42,3119, 464,5455,2642, # 3632 +4698,3400,1760,1571,2889,3515,2537,1219,2207,3893,2643,2141,2373,4699,4700,3328, # 3648 +1651,3401,3627,5456,5457,3628,2488,3516,5458,3756,5459,5460,2276,2092, 460,5461, # 3664 +4701,5462,3020, 962, 588,3629, 289,3250,2644,1116, 52,5463,3067,1797,5464,5465, # 3680 +5466,1467,5467,1598,1143,3757,4342,1985,1734,1067,4702,1280,3402, 465,4703,1572, # 3696 + 510,5468,1928,2245,1813,1644,3630,5469,4704,3758,5470,5471,2673,1573,1534,5472, # 3712 +5473, 536,1808,1761,3517,3894,3175,2645,5474,5475,5476,4705,3518,2929,1912,2809, # 3728 +5477,3329,1122, 377,3251,5478, 360,5479,5480,4343,1529, 551,5481,2060,3759,1769, # 3744 +2431,5482,2930,4344,3330,3120,2327,2109,2031,4706,1404, 136,1468,1479, 672,1171, # 3760 +3252,2308, 271,3176,5483,2772,5484,2050, 678,2736, 865,1948,4707,5485,2014,4098, # 3776 +2971,5486,2737,2227,1397,3068,3760,4708,4709,1735,2931,3403,3631,5487,3895, 509, # 3792 +2854,2458,2890,3896,5488,5489,3177,3178,4710,4345,2538,4711,2309,1166,1010, 552, # 3808 + 681,1888,5490,5491,2972,2973,4099,1287,1596,1862,3179, 358, 453, 736, 175, 478, # 3824 +1117, 905,1167,1097,5492,1854,1530,5493,1706,5494,2181,3519,2292,3761,3520,3632, # 3840 +4346,2093,4347,5495,3404,1193,2489,4348,1458,2193,2208,1863,1889,1421,3331,2932, # 3856 +3069,2182,3521, 595,2123,5496,4100,5497,5498,4349,1707,2646, 223,3762,1359, 751, # 3872 +3121, 183,3522,5499,2810,3021, 419,2374, 633, 704,3897,2394, 241,5500,5501,5502, # 3888 + 838,3022,3763,2277,2773,2459,3898,1939,2051,4101,1309,3122,2246,1181,5503,1136, # 3904 +2209,3899,2375,1446,4350,2310,4712,5504,5505,4351,1055,2615, 484,3764,5506,4102, # 3920 + 625,4352,2278,3405,1499,4353,4103,5507,4104,4354,3253,2279,2280,3523,5508,5509, # 3936 +2774, 808,2616,3765,3406,4105,4355,3123,2539, 526,3407,3900,4356, 955,5510,1620, # 3952 +4357,2647,2432,5511,1429,3766,1669,1832, 994, 928,5512,3633,1260,5513,5514,5515, # 3968 +1949,2293, 741,2933,1626,4358,2738,2460, 867,1184, 362,3408,1392,5516,5517,4106, # 3984 +4359,1770,1736,3254,2934,4713,4714,1929,2707,1459,1158,5518,3070,3409,2891,1292, # 4000 +1930,2513,2855,3767,1986,1187,2072,2015,2617,4360,5519,2574,2514,2170,3768,2490, # 4016 +3332,5520,3769,4715,5521,5522, 666,1003,3023,1022,3634,4361,5523,4716,1814,2257, # 4032 + 574,3901,1603, 295,1535, 705,3902,4362, 283, 858, 417,5524,5525,3255,4717,4718, # 4048 +3071,1220,1890,1046,2281,2461,4107,1393,1599, 689,2575, 388,4363,5526,2491, 802, # 4064 +5527,2811,3903,2061,1405,2258,5528,4719,3904,2110,1052,1345,3256,1585,5529, 809, # 4080 +5530,5531,5532, 575,2739,3524, 956,1552,1469,1144,2328,5533,2329,1560,2462,3635, # 4096 +3257,4108, 616,2210,4364,3180,2183,2294,5534,1833,5535,3525,4720,5536,1319,3770, # 4112 +3771,1211,3636,1023,3258,1293,2812,5537,5538,5539,3905, 607,2311,3906, 762,2892, # 4128 +1439,4365,1360,4721,1485,3072,5540,4722,1038,4366,1450,2062,2648,4367,1379,4723, # 4144 +2593,5541,5542,4368,1352,1414,2330,2935,1172,5543,5544,3907,3908,4724,1798,1451, # 4160 +5545,5546,5547,5548,2936,4109,4110,2492,2351, 411,4111,4112,3637,3333,3124,4725, # 4176 +1561,2674,1452,4113,1375,5549,5550, 47,2974, 316,5551,1406,1591,2937,3181,5552, # 4192 +1025,2142,3125,3182, 354,2740, 884,2228,4369,2412, 508,3772, 726,3638, 996,2433, # 4208 +3639, 729,5553, 392,2194,1453,4114,4726,3773,5554,5555,2463,3640,2618,1675,2813, # 4224 + 919,2352,2975,2353,1270,4727,4115, 73,5556,5557, 647,5558,3259,2856,2259,1550, # 4240 +1346,3024,5559,1332, 883,3526,5560,5561,5562,5563,3334,2775,5564,1212, 831,1347, # 4256 +4370,4728,2331,3909,1864,3073, 720,3910,4729,4730,3911,5565,4371,5566,5567,4731, # 4272 +5568,5569,1799,4732,3774,2619,4733,3641,1645,2376,4734,5570,2938, 669,2211,2675, # 4288 +2434,5571,2893,5572,5573,1028,3260,5574,4372,2413,5575,2260,1353,5576,5577,4735, # 4304 +3183, 518,5578,4116,5579,4373,1961,5580,2143,4374,5581,5582,3025,2354,2355,3912, # 4320 + 516,1834,1454,4117,2708,4375,4736,2229,2620,1972,1129,3642,5583,2776,5584,2976, # 4336 +1422, 577,1470,3026,1524,3410,5585,5586, 432,4376,3074,3527,5587,2594,1455,2515, # 4352 +2230,1973,1175,5588,1020,2741,4118,3528,4737,5589,2742,5590,1743,1361,3075,3529, # 4368 +2649,4119,4377,4738,2295, 895, 924,4378,2171, 331,2247,3076, 166,1627,3077,1098, # 4384 +5591,1232,2894,2231,3411,4739, 657, 403,1196,2377, 542,3775,3412,1600,4379,3530, # 4400 +5592,4740,2777,3261, 576, 530,1362,4741,4742,2540,2676,3776,4120,5593, 842,3913, # 4416 +5594,2814,2032,1014,4121, 213,2709,3413, 665, 621,4380,5595,3777,2939,2435,5596, # 4432 +2436,3335,3643,3414,4743,4381,2541,4382,4744,3644,1682,4383,3531,1380,5597, 724, # 4448 +2282, 600,1670,5598,1337,1233,4745,3126,2248,5599,1621,4746,5600, 651,4384,5601, # 4464 +1612,4385,2621,5602,2857,5603,2743,2312,3078,5604, 716,2464,3079, 174,1255,2710, # 4480 +4122,3645, 548,1320,1398, 728,4123,1574,5605,1891,1197,3080,4124,5606,3081,3082, # 4496 +3778,3646,3779, 747,5607, 635,4386,4747,5608,5609,5610,4387,5611,5612,4748,5613, # 4512 +3415,4749,2437, 451,5614,3780,2542,2073,4388,2744,4389,4125,5615,1764,4750,5616, # 4528 +4390, 350,4751,2283,2395,2493,5617,4391,4126,2249,1434,4127, 488,4752, 458,4392, # 4544 +4128,3781, 771,1330,2396,3914,2576,3184,2160,2414,1553,2677,3185,4393,5618,2494, # 4560 +2895,2622,1720,2711,4394,3416,4753,5619,2543,4395,5620,3262,4396,2778,5621,2016, # 4576 +2745,5622,1155,1017,3782,3915,5623,3336,2313, 201,1865,4397,1430,5624,4129,5625, # 4592 +5626,5627,5628,5629,4398,1604,5630, 414,1866, 371,2595,4754,4755,3532,2017,3127, # 4608 +4756,1708, 960,4399, 887, 389,2172,1536,1663,1721,5631,2232,4130,2356,2940,1580, # 4624 +5632,5633,1744,4757,2544,4758,4759,5634,4760,5635,2074,5636,4761,3647,3417,2896, # 4640 +4400,5637,4401,2650,3418,2815, 673,2712,2465, 709,3533,4131,3648,4402,5638,1148, # 4656 + 502, 634,5639,5640,1204,4762,3649,1575,4763,2623,3783,5641,3784,3128, 948,3263, # 4672 + 121,1745,3916,1110,5642,4403,3083,2516,3027,4132,3785,1151,1771,3917,1488,4133, # 4688 +1987,5643,2438,3534,5644,5645,2094,5646,4404,3918,1213,1407,2816, 531,2746,2545, # 4704 +3264,1011,1537,4764,2779,4405,3129,1061,5647,3786,3787,1867,2897,5648,2018, 120, # 4720 +4406,4407,2063,3650,3265,2314,3919,2678,3419,1955,4765,4134,5649,3535,1047,2713, # 4736 +1266,5650,1368,4766,2858, 649,3420,3920,2546,2747,1102,2859,2679,5651,5652,2000, # 4752 +5653,1111,3651,2977,5654,2495,3921,3652,2817,1855,3421,3788,5655,5656,3422,2415, # 4768 +2898,3337,3266,3653,5657,2577,5658,3654,2818,4135,1460, 856,5659,3655,5660,2899, # 4784 +2978,5661,2900,3922,5662,4408, 632,2517, 875,3923,1697,3924,2296,5663,5664,4767, # 4800 +3028,1239, 580,4768,4409,5665, 914, 936,2075,1190,4136,1039,2124,5666,5667,5668, # 4816 +5669,3423,1473,5670,1354,4410,3925,4769,2173,3084,4137, 915,3338,4411,4412,3339, # 4832 +1605,1835,5671,2748, 398,3656,4413,3926,4138, 328,1913,2860,4139,3927,1331,4414, # 4848 +3029, 937,4415,5672,3657,4140,4141,3424,2161,4770,3425, 524, 742, 538,3085,1012, # 4864 +5673,5674,3928,2466,5675, 658,1103, 225,3929,5676,5677,4771,5678,4772,5679,3267, # 4880 +1243,5680,4142, 963,2250,4773,5681,2714,3658,3186,5682,5683,2596,2332,5684,4774, # 4896 +5685,5686,5687,3536, 957,3426,2547,2033,1931,2941,2467, 870,2019,3659,1746,2780, # 4912 +2781,2439,2468,5688,3930,5689,3789,3130,3790,3537,3427,3791,5690,1179,3086,5691, # 4928 +3187,2378,4416,3792,2548,3188,3131,2749,4143,5692,3428,1556,2549,2297, 977,2901, # 4944 +2034,4144,1205,3429,5693,1765,3430,3189,2125,1271, 714,1689,4775,3538,5694,2333, # 4960 +3931, 533,4417,3660,2184, 617,5695,2469,3340,3539,2315,5696,5697,3190,5698,5699, # 4976 +3932,1988, 618, 427,2651,3540,3431,5700,5701,1244,1690,5702,2819,4418,4776,5703, # 4992 +3541,4777,5704,2284,1576, 473,3661,4419,3432, 972,5705,3662,5706,3087,5707,5708, # 5008 +4778,4779,5709,3793,4145,4146,5710, 153,4780, 356,5711,1892,2902,4420,2144, 408, # 5024 + 803,2357,5712,3933,5713,4421,1646,2578,2518,4781,4782,3934,5714,3935,4422,5715, # 5040 +2416,3433, 752,5716,5717,1962,3341,2979,5718, 746,3030,2470,4783,4423,3794, 698, # 5056 +4784,1893,4424,3663,2550,4785,3664,3936,5719,3191,3434,5720,1824,1302,4147,2715, # 5072 +3937,1974,4425,5721,4426,3192, 823,1303,1288,1236,2861,3542,4148,3435, 774,3938, # 5088 +5722,1581,4786,1304,2862,3939,4787,5723,2440,2162,1083,3268,4427,4149,4428, 344, # 5104 +1173, 288,2316, 454,1683,5724,5725,1461,4788,4150,2597,5726,5727,4789, 985, 894, # 5120 +5728,3436,3193,5729,1914,2942,3795,1989,5730,2111,1975,5731,4151,5732,2579,1194, # 5136 + 425,5733,4790,3194,1245,3796,4429,5734,5735,2863,5736, 636,4791,1856,3940, 760, # 5152 +1800,5737,4430,2212,1508,4792,4152,1894,1684,2298,5738,5739,4793,4431,4432,2213, # 5168 + 479,5740,5741, 832,5742,4153,2496,5743,2980,2497,3797, 990,3132, 627,1815,2652, # 5184 +4433,1582,4434,2126,2112,3543,4794,5744, 799,4435,3195,5745,4795,2113,1737,3031, # 5200 +1018, 543, 754,4436,3342,1676,4796,4797,4154,4798,1489,5746,3544,5747,2624,2903, # 5216 +4155,5748,5749,2981,5750,5751,5752,5753,3196,4799,4800,2185,1722,5754,3269,3270, # 5232 +1843,3665,1715, 481, 365,1976,1857,5755,5756,1963,2498,4801,5757,2127,3666,3271, # 5248 + 433,1895,2064,2076,5758, 602,2750,5759,5760,5761,5762,5763,3032,1628,3437,5764, # 5264 +3197,4802,4156,2904,4803,2519,5765,2551,2782,5766,5767,5768,3343,4804,2905,5769, # 5280 +4805,5770,2864,4806,4807,1221,2982,4157,2520,5771,5772,5773,1868,1990,5774,5775, # 5296 +5776,1896,5777,5778,4808,1897,4158, 318,5779,2095,4159,4437,5780,5781, 485,5782, # 5312 + 938,3941, 553,2680, 116,5783,3942,3667,5784,3545,2681,2783,3438,3344,2820,5785, # 5328 +3668,2943,4160,1747,2944,2983,5786,5787, 207,5788,4809,5789,4810,2521,5790,3033, # 5344 + 890,3669,3943,5791,1878,3798,3439,5792,2186,2358,3440,1652,5793,5794,5795, 941, # 5360 +2299, 208,3546,4161,2020, 330,4438,3944,2906,2499,3799,4439,4811,5796,5797,5798, # 5376 +) + diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/big5prober.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/big5prober.py new file mode 100644 index 0000000..98f9970 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/big5prober.py @@ -0,0 +1,47 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import Big5DistributionAnalysis +from .mbcssm import BIG5_SM_MODEL + + +class Big5Prober(MultiByteCharSetProber): + def __init__(self): + super(Big5Prober, self).__init__() + self.coding_sm = CodingStateMachine(BIG5_SM_MODEL) + self.distribution_analyzer = Big5DistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "Big5" + + @property + def language(self): + return "Chinese" diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/chardistribution.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/chardistribution.py new file mode 100644 index 0000000..c0395f4 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/chardistribution.py @@ -0,0 +1,233 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .euctwfreq import (EUCTW_CHAR_TO_FREQ_ORDER, EUCTW_TABLE_SIZE, + EUCTW_TYPICAL_DISTRIBUTION_RATIO) +from .euckrfreq import (EUCKR_CHAR_TO_FREQ_ORDER, EUCKR_TABLE_SIZE, + EUCKR_TYPICAL_DISTRIBUTION_RATIO) +from .gb2312freq import (GB2312_CHAR_TO_FREQ_ORDER, GB2312_TABLE_SIZE, + GB2312_TYPICAL_DISTRIBUTION_RATIO) +from .big5freq import (BIG5_CHAR_TO_FREQ_ORDER, BIG5_TABLE_SIZE, + BIG5_TYPICAL_DISTRIBUTION_RATIO) +from .jisfreq import (JIS_CHAR_TO_FREQ_ORDER, JIS_TABLE_SIZE, + JIS_TYPICAL_DISTRIBUTION_RATIO) + + +class CharDistributionAnalysis(object): + ENOUGH_DATA_THRESHOLD = 1024 + SURE_YES = 0.99 + SURE_NO = 0.01 + MINIMUM_DATA_THRESHOLD = 3 + + def __init__(self): + # Mapping table to get frequency order from char order (get from + # GetOrder()) + self._char_to_freq_order = None + self._table_size = None # Size of above table + # This is a constant value which varies from language to language, + # used in calculating confidence. See + # http://www.mozilla.org/projects/intl/UniversalCharsetDetection.html + # for further detail. + self.typical_distribution_ratio = None + self._done = None + self._total_chars = None + self._freq_chars = None + self.reset() + + def reset(self): + """reset analyser, clear any state""" + # If this flag is set to True, detection is done and conclusion has + # been made + self._done = False + self._total_chars = 0 # Total characters encountered + # The number of characters whose frequency order is less than 512 + self._freq_chars = 0 + + def feed(self, char, char_len): + """feed a character with known length""" + if char_len == 2: + # we only care about 2-bytes character in our distribution analysis + order = self.get_order(char) + else: + order = -1 + if order >= 0: + self._total_chars += 1 + # order is valid + if order < self._table_size: + if 512 > self._char_to_freq_order[order]: + self._freq_chars += 1 + + def get_confidence(self): + """return confidence based on existing data""" + # if we didn't receive any character in our consideration range, + # return negative answer + if self._total_chars <= 0 or self._freq_chars <= self.MINIMUM_DATA_THRESHOLD: + return self.SURE_NO + + if self._total_chars != self._freq_chars: + r = (self._freq_chars / ((self._total_chars - self._freq_chars) + * self.typical_distribution_ratio)) + if r < self.SURE_YES: + return r + + # normalize confidence (we don't want to be 100% sure) + return self.SURE_YES + + def got_enough_data(self): + # It is not necessary to receive all data to draw conclusion. + # For charset detection, certain amount of data is enough + return self._total_chars > self.ENOUGH_DATA_THRESHOLD + + def get_order(self, byte_str): + # We do not handle characters based on the original encoding string, + # but convert this encoding string to a number, here called order. + # This allows multiple encodings of a language to share one frequency + # table. + return -1 + + +class EUCTWDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(EUCTWDistributionAnalysis, self).__init__() + self._char_to_freq_order = EUCTW_CHAR_TO_FREQ_ORDER + self._table_size = EUCTW_TABLE_SIZE + self.typical_distribution_ratio = EUCTW_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for euc-TW encoding, we are interested + # first byte range: 0xc4 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char = byte_str[0] + if first_char >= 0xC4: + return 94 * (first_char - 0xC4) + byte_str[1] - 0xA1 + else: + return -1 + + +class EUCKRDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(EUCKRDistributionAnalysis, self).__init__() + self._char_to_freq_order = EUCKR_CHAR_TO_FREQ_ORDER + self._table_size = EUCKR_TABLE_SIZE + self.typical_distribution_ratio = EUCKR_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for euc-KR encoding, we are interested + # first byte range: 0xb0 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char = byte_str[0] + if first_char >= 0xB0: + return 94 * (first_char - 0xB0) + byte_str[1] - 0xA1 + else: + return -1 + + +class GB2312DistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(GB2312DistributionAnalysis, self).__init__() + self._char_to_freq_order = GB2312_CHAR_TO_FREQ_ORDER + self._table_size = GB2312_TABLE_SIZE + self.typical_distribution_ratio = GB2312_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for GB2312 encoding, we are interested + # first byte range: 0xb0 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char, second_char = byte_str[0], byte_str[1] + if (first_char >= 0xB0) and (second_char >= 0xA1): + return 94 * (first_char - 0xB0) + second_char - 0xA1 + else: + return -1 + + +class Big5DistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(Big5DistributionAnalysis, self).__init__() + self._char_to_freq_order = BIG5_CHAR_TO_FREQ_ORDER + self._table_size = BIG5_TABLE_SIZE + self.typical_distribution_ratio = BIG5_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for big5 encoding, we are interested + # first byte range: 0xa4 -- 0xfe + # second byte range: 0x40 -- 0x7e , 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char, second_char = byte_str[0], byte_str[1] + if first_char >= 0xA4: + if second_char >= 0xA1: + return 157 * (first_char - 0xA4) + second_char - 0xA1 + 63 + else: + return 157 * (first_char - 0xA4) + second_char - 0x40 + else: + return -1 + + +class SJISDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(SJISDistributionAnalysis, self).__init__() + self._char_to_freq_order = JIS_CHAR_TO_FREQ_ORDER + self._table_size = JIS_TABLE_SIZE + self.typical_distribution_ratio = JIS_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for sjis encoding, we are interested + # first byte range: 0x81 -- 0x9f , 0xe0 -- 0xfe + # second byte range: 0x40 -- 0x7e, 0x81 -- oxfe + # no validation needed here. State machine has done that + first_char, second_char = byte_str[0], byte_str[1] + if (first_char >= 0x81) and (first_char <= 0x9F): + order = 188 * (first_char - 0x81) + elif (first_char >= 0xE0) and (first_char <= 0xEF): + order = 188 * (first_char - 0xE0 + 31) + else: + return -1 + order = order + second_char - 0x40 + if second_char > 0x7F: + order = -1 + return order + + +class EUCJPDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(EUCJPDistributionAnalysis, self).__init__() + self._char_to_freq_order = JIS_CHAR_TO_FREQ_ORDER + self._table_size = JIS_TABLE_SIZE + self.typical_distribution_ratio = JIS_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for euc-JP encoding, we are interested + # first byte range: 0xa0 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + char = byte_str[0] + if char >= 0xA0: + return 94 * (char - 0xA1) + byte_str[1] - 0xa1 + else: + return -1 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/charsetgroupprober.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/charsetgroupprober.py new file mode 100644 index 0000000..8b3738e --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/charsetgroupprober.py @@ -0,0 +1,106 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import ProbingState +from .charsetprober import CharSetProber + + +class CharSetGroupProber(CharSetProber): + def __init__(self, lang_filter=None): + super(CharSetGroupProber, self).__init__(lang_filter=lang_filter) + self._active_num = 0 + self.probers = [] + self._best_guess_prober = None + + def reset(self): + super(CharSetGroupProber, self).reset() + self._active_num = 0 + for prober in self.probers: + if prober: + prober.reset() + prober.active = True + self._active_num += 1 + self._best_guess_prober = None + + @property + def charset_name(self): + if not self._best_guess_prober: + self.get_confidence() + if not self._best_guess_prober: + return None + return self._best_guess_prober.charset_name + + @property + def language(self): + if not self._best_guess_prober: + self.get_confidence() + if not self._best_guess_prober: + return None + return self._best_guess_prober.language + + def feed(self, byte_str): + for prober in self.probers: + if not prober: + continue + if not prober.active: + continue + state = prober.feed(byte_str) + if not state: + continue + if state == ProbingState.FOUND_IT: + self._best_guess_prober = prober + return self.state + elif state == ProbingState.NOT_ME: + prober.active = False + self._active_num -= 1 + if self._active_num <= 0: + self._state = ProbingState.NOT_ME + return self.state + return self.state + + def get_confidence(self): + state = self.state + if state == ProbingState.FOUND_IT: + return 0.99 + elif state == ProbingState.NOT_ME: + return 0.01 + best_conf = 0.0 + self._best_guess_prober = None + for prober in self.probers: + if not prober: + continue + if not prober.active: + self.logger.debug('%s not active', prober.charset_name) + continue + conf = prober.get_confidence() + self.logger.debug('%s %s confidence = %s', prober.charset_name, prober.language, conf) + if best_conf < conf: + best_conf = conf + self._best_guess_prober = prober + if not self._best_guess_prober: + return 0.0 + return best_conf diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/charsetprober.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/charsetprober.py new file mode 100644 index 0000000..eac4e59 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/charsetprober.py @@ -0,0 +1,145 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +import logging +import re + +from .enums import ProbingState + + +class CharSetProber(object): + + SHORTCUT_THRESHOLD = 0.95 + + def __init__(self, lang_filter=None): + self._state = None + self.lang_filter = lang_filter + self.logger = logging.getLogger(__name__) + + def reset(self): + self._state = ProbingState.DETECTING + + @property + def charset_name(self): + return None + + def feed(self, buf): + pass + + @property + def state(self): + return self._state + + def get_confidence(self): + return 0.0 + + @staticmethod + def filter_high_byte_only(buf): + buf = re.sub(b'([\x00-\x7F])+', b' ', buf) + return buf + + @staticmethod + def filter_international_words(buf): + """ + We define three types of bytes: + alphabet: english alphabets [a-zA-Z] + international: international characters [\x80-\xFF] + marker: everything else [^a-zA-Z\x80-\xFF] + + The input buffer can be thought to contain a series of words delimited + by markers. This function works to filter all words that contain at + least one international character. All contiguous sequences of markers + are replaced by a single space ascii character. + + This filter applies to all scripts which do not use English characters. + """ + filtered = bytearray() + + # This regex expression filters out only words that have at-least one + # international character. The word may include one marker character at + # the end. + words = re.findall(b'[a-zA-Z]*[\x80-\xFF]+[a-zA-Z]*[^a-zA-Z\x80-\xFF]?', + buf) + + for word in words: + filtered.extend(word[:-1]) + + # If the last character in the word is a marker, replace it with a + # space as markers shouldn't affect our analysis (they are used + # similarly across all languages and may thus have similar + # frequencies). + last_char = word[-1:] + if not last_char.isalpha() and last_char < b'\x80': + last_char = b' ' + filtered.extend(last_char) + + return filtered + + @staticmethod + def filter_with_english_letters(buf): + """ + Returns a copy of ``buf`` that retains only the sequences of English + alphabet and high byte characters that are not between <> characters. + Also retains English alphabet and high byte characters immediately + before occurrences of >. + + This filter can be applied to all scripts which contain both English + characters and extended ASCII characters, but is currently only used by + ``Latin1Prober``. + """ + filtered = bytearray() + in_tag = False + prev = 0 + + for curr in range(len(buf)): + # Slice here to get bytes instead of an int with Python 3 + buf_char = buf[curr:curr + 1] + # Check if we're coming out of or entering an HTML tag + if buf_char == b'>': + in_tag = False + elif buf_char == b'<': + in_tag = True + + # If current character is not extended-ASCII and not alphabetic... + if buf_char < b'\x80' and not buf_char.isalpha(): + # ...and we're not in a tag + if curr > prev and not in_tag: + # Keep everything after last non-extended-ASCII, + # non-alphabetic character + filtered.extend(buf[prev:curr]) + # Output a space to delimit stretch we kept + filtered.extend(b' ') + prev = curr + 1 + + # If we're not in a tag... + if not in_tag: + # Keep everything after last non-extended-ASCII, non-alphabetic + # character + filtered.extend(buf[prev:]) + + return filtered diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/cli/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/cli/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/cli/__init__.py @@ -0,0 +1 @@ + diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/cli/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/cli/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..27d6a781bd0645908c43b143bc6986b091dbe5b8 GIT binary patch literal 204 zcmZ?b<>g`kf*$Fl7)Bud7{q}Akbnaa7qb9~6oz01O-8?!3`HPe1o5j>zo00yEU_e2 zzbvsxKP^8eCAFwnKQ}`^*{~qqvdS{cpxihurK;G>xU9&iqNFO<00`3a^h5LuG7EGw z^NLFnb8>V|&66^+OOw(;f?yn9mYSE6U!<R$kyw<HTB4tvlc^scpP83g5+AQuP<e~P SCO1E&G$+*#<eXw4W&i*>IX0vK literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..99368283b6d21c3759ab3d80342d1e4825be9c24 GIT binary patch literal 2693 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 KbT7JJbN>g#5g`Ep literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/cli/chardetect.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/cli/chardetect.py new file mode 100644 index 0000000..c61136b --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/cli/chardetect.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python +""" +Script which takes one or more file paths and reports on their detected +encodings + +Example:: + + % chardetect somefile someotherfile + somefile: windows-1252 with confidence 0.5 + someotherfile: ascii with confidence 1.0 + +If no paths are provided, it takes its input from stdin. + +""" + +from __future__ import absolute_import, print_function, unicode_literals + +import argparse +import sys + +from pip._vendor.chardet import __version__ +from pip._vendor.chardet.compat import PY2 +from pip._vendor.chardet.universaldetector import UniversalDetector + + +def description_of(lines, name='stdin'): + """ + Return a string describing the probable encoding of a file or + list of strings. + + :param lines: The lines to get the encoding of. + :type lines: Iterable of bytes + :param name: Name of file or collection of lines + :type name: str + """ + u = UniversalDetector() + for line in lines: + line = bytearray(line) + u.feed(line) + # shortcut out of the loop to save reading further - particularly useful if we read a BOM. + if u.done: + break + u.close() + result = u.result + if PY2: + name = name.decode(sys.getfilesystemencoding(), 'ignore') + if result['encoding']: + return '{0}: {1} with confidence {2}'.format(name, result['encoding'], + result['confidence']) + else: + return '{0}: no result'.format(name) + + +def main(argv=None): + """ + Handles command line arguments and gets things started. + + :param argv: List of arguments, as if specified on the command-line. + If None, ``sys.argv[1:]`` is used instead. + :type argv: list of str + """ + # Get command line arguments + parser = argparse.ArgumentParser( + description="Takes one or more file paths and reports their detected \ + encodings") + parser.add_argument('input', + help='File whose encoding we would like to determine. \ + (default: stdin)', + type=argparse.FileType('rb'), nargs='*', + default=[sys.stdin if PY2 else sys.stdin.buffer]) + parser.add_argument('--version', action='version', + version='%(prog)s {0}'.format(__version__)) + args = parser.parse_args(argv) + + for f in args.input: + if f.isatty(): + print("You are running chardetect interactively. Press " + + "CTRL-D twice at the start of a blank line to signal the " + + "end of your input. If you want help, run chardetect " + + "--help\n", file=sys.stderr) + print(description_of(f, f.name)) + + +if __name__ == '__main__': + main() diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/codingstatemachine.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/codingstatemachine.py new file mode 100644 index 0000000..68fba44 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/codingstatemachine.py @@ -0,0 +1,88 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +import logging + +from .enums import MachineState + + +class CodingStateMachine(object): + """ + A state machine to verify a byte sequence for a particular encoding. For + each byte the detector receives, it will feed that byte to every active + state machine available, one byte at a time. The state machine changes its + state based on its previous state and the byte it receives. There are 3 + states in a state machine that are of interest to an auto-detector: + + START state: This is the state to start with, or a legal byte sequence + (i.e. a valid code point) for character has been identified. + + ME state: This indicates that the state machine identified a byte sequence + that is specific to the charset it is designed for and that + there is no other possible encoding which can contain this byte + sequence. This will to lead to an immediate positive answer for + the detector. + + ERROR state: This indicates the state machine identified an illegal byte + sequence for that encoding. This will lead to an immediate + negative answer for this encoding. Detector will exclude this + encoding from consideration from here on. + """ + def __init__(self, sm): + self._model = sm + self._curr_byte_pos = 0 + self._curr_char_len = 0 + self._curr_state = None + self.logger = logging.getLogger(__name__) + self.reset() + + def reset(self): + self._curr_state = MachineState.START + + def next_state(self, c): + # for each byte we get its class + # if it is first byte, we also get byte length + byte_class = self._model['class_table'][c] + if self._curr_state == MachineState.START: + self._curr_byte_pos = 0 + self._curr_char_len = self._model['char_len_table'][byte_class] + # from byte's class and state_table, we get its next state + curr_state = (self._curr_state * self._model['class_factor'] + + byte_class) + self._curr_state = self._model['state_table'][curr_state] + self._curr_byte_pos += 1 + return self._curr_state + + def get_current_charlen(self): + return self._curr_char_len + + def get_coding_state_machine(self): + return self._model['name'] + + @property + def language(self): + return self._model['language'] diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/compat.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/compat.py new file mode 100644 index 0000000..ddd7468 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/compat.py @@ -0,0 +1,34 @@ +######################## BEGIN LICENSE BLOCK ######################## +# Contributor(s): +# Dan Blanchard +# Ian Cordasco +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +import sys + + +if sys.version_info < (3, 0): + PY2 = True + PY3 = False + base_str = (str, unicode) + text_type = unicode +else: + PY2 = False + PY3 = True + base_str = (bytes, str) + text_type = str diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/cp949prober.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/cp949prober.py new file mode 100644 index 0000000..efd793a --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/cp949prober.py @@ -0,0 +1,49 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .chardistribution import EUCKRDistributionAnalysis +from .codingstatemachine import CodingStateMachine +from .mbcharsetprober import MultiByteCharSetProber +from .mbcssm import CP949_SM_MODEL + + +class CP949Prober(MultiByteCharSetProber): + def __init__(self): + super(CP949Prober, self).__init__() + self.coding_sm = CodingStateMachine(CP949_SM_MODEL) + # NOTE: CP949 is a superset of EUC-KR, so the distribution should be + # not different. + self.distribution_analyzer = EUCKRDistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "CP949" + + @property + def language(self): + return "Korean" diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/enums.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/enums.py new file mode 100644 index 0000000..0451207 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/enums.py @@ -0,0 +1,76 @@ +""" +All of the Enums that are used throughout the chardet package. + +:author: Dan Blanchard (dan.blanchard@gmail.com) +""" + + +class InputState(object): + """ + This enum represents the different states a universal detector can be in. + """ + PURE_ASCII = 0 + ESC_ASCII = 1 + HIGH_BYTE = 2 + + +class LanguageFilter(object): + """ + This enum represents the different language filters we can apply to a + ``UniversalDetector``. + """ + CHINESE_SIMPLIFIED = 0x01 + CHINESE_TRADITIONAL = 0x02 + JAPANESE = 0x04 + KOREAN = 0x08 + NON_CJK = 0x10 + ALL = 0x1F + CHINESE = CHINESE_SIMPLIFIED | CHINESE_TRADITIONAL + CJK = CHINESE | JAPANESE | KOREAN + + +class ProbingState(object): + """ + This enum represents the different states a prober can be in. + """ + DETECTING = 0 + FOUND_IT = 1 + NOT_ME = 2 + + +class MachineState(object): + """ + This enum represents the different states a state machine can be in. + """ + START = 0 + ERROR = 1 + ITS_ME = 2 + + +class SequenceLikelihood(object): + """ + This enum represents the likelihood of a character following the previous one. + """ + NEGATIVE = 0 + UNLIKELY = 1 + LIKELY = 2 + POSITIVE = 3 + + @classmethod + def get_num_categories(cls): + """:returns: The number of likelihood categories in the enum.""" + return 4 + + +class CharacterCategory(object): + """ + This enum represents the different categories language models for + ``SingleByteCharsetProber`` put characters into. + + Anything less than CONTROL is considered a letter. + """ + UNDEFINED = 255 + LINE_BREAK = 254 + SYMBOL = 253 + DIGIT = 252 + CONTROL = 251 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/escprober.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/escprober.py new file mode 100644 index 0000000..c70493f --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/escprober.py @@ -0,0 +1,101 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .codingstatemachine import CodingStateMachine +from .enums import LanguageFilter, ProbingState, MachineState +from .escsm import (HZ_SM_MODEL, ISO2022CN_SM_MODEL, ISO2022JP_SM_MODEL, + ISO2022KR_SM_MODEL) + + +class EscCharSetProber(CharSetProber): + """ + This CharSetProber uses a "code scheme" approach for detecting encodings, + whereby easily recognizable escape or shift sequences are relied on to + identify these encodings. + """ + + def __init__(self, lang_filter=None): + super(EscCharSetProber, self).__init__(lang_filter=lang_filter) + self.coding_sm = [] + if self.lang_filter & LanguageFilter.CHINESE_SIMPLIFIED: + self.coding_sm.append(CodingStateMachine(HZ_SM_MODEL)) + self.coding_sm.append(CodingStateMachine(ISO2022CN_SM_MODEL)) + if self.lang_filter & LanguageFilter.JAPANESE: + self.coding_sm.append(CodingStateMachine(ISO2022JP_SM_MODEL)) + if self.lang_filter & LanguageFilter.KOREAN: + self.coding_sm.append(CodingStateMachine(ISO2022KR_SM_MODEL)) + self.active_sm_count = None + self._detected_charset = None + self._detected_language = None + self._state = None + self.reset() + + def reset(self): + super(EscCharSetProber, self).reset() + for coding_sm in self.coding_sm: + if not coding_sm: + continue + coding_sm.active = True + coding_sm.reset() + self.active_sm_count = len(self.coding_sm) + self._detected_charset = None + self._detected_language = None + + @property + def charset_name(self): + return self._detected_charset + + @property + def language(self): + return self._detected_language + + def get_confidence(self): + if self._detected_charset: + return 0.99 + else: + return 0.00 + + def feed(self, byte_str): + for c in byte_str: + for coding_sm in self.coding_sm: + if not coding_sm or not coding_sm.active: + continue + coding_state = coding_sm.next_state(c) + if coding_state == MachineState.ERROR: + coding_sm.active = False + self.active_sm_count -= 1 + if self.active_sm_count <= 0: + self._state = ProbingState.NOT_ME + return self.state + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + self._detected_charset = coding_sm.get_coding_state_machine() + self._detected_language = coding_sm.language + return self.state + + return self.state diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/escsm.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/escsm.py new file mode 100644 index 0000000..0069523 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/escsm.py @@ -0,0 +1,246 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import MachineState + +HZ_CLS = ( +1,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,0,0, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,0,0,0,0, # 20 - 27 +0,0,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +0,0,0,0,0,0,0,0, # 40 - 47 +0,0,0,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,4,0,5,2,0, # 78 - 7f +1,1,1,1,1,1,1,1, # 80 - 87 +1,1,1,1,1,1,1,1, # 88 - 8f +1,1,1,1,1,1,1,1, # 90 - 97 +1,1,1,1,1,1,1,1, # 98 - 9f +1,1,1,1,1,1,1,1, # a0 - a7 +1,1,1,1,1,1,1,1, # a8 - af +1,1,1,1,1,1,1,1, # b0 - b7 +1,1,1,1,1,1,1,1, # b8 - bf +1,1,1,1,1,1,1,1, # c0 - c7 +1,1,1,1,1,1,1,1, # c8 - cf +1,1,1,1,1,1,1,1, # d0 - d7 +1,1,1,1,1,1,1,1, # d8 - df +1,1,1,1,1,1,1,1, # e0 - e7 +1,1,1,1,1,1,1,1, # e8 - ef +1,1,1,1,1,1,1,1, # f0 - f7 +1,1,1,1,1,1,1,1, # f8 - ff +) + +HZ_ST = ( +MachineState.START,MachineState.ERROR, 3,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,# 00-07 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 08-0f +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START, 4,MachineState.ERROR,# 10-17 + 5,MachineState.ERROR, 6,MachineState.ERROR, 5, 5, 4,MachineState.ERROR,# 18-1f + 4,MachineState.ERROR, 4, 4, 4,MachineState.ERROR, 4,MachineState.ERROR,# 20-27 + 4,MachineState.ITS_ME,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 28-2f +) + +HZ_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0) + +HZ_SM_MODEL = {'class_table': HZ_CLS, + 'class_factor': 6, + 'state_table': HZ_ST, + 'char_len_table': HZ_CHAR_LEN_TABLE, + 'name': "HZ-GB-2312", + 'language': 'Chinese'} + +ISO2022CN_CLS = ( +2,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,0,0, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,0,0,0,0, # 20 - 27 +0,3,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +0,0,0,4,0,0,0,0, # 40 - 47 +0,0,0,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,0,0,0,0,0, # 78 - 7f +2,2,2,2,2,2,2,2, # 80 - 87 +2,2,2,2,2,2,2,2, # 88 - 8f +2,2,2,2,2,2,2,2, # 90 - 97 +2,2,2,2,2,2,2,2, # 98 - 9f +2,2,2,2,2,2,2,2, # a0 - a7 +2,2,2,2,2,2,2,2, # a8 - af +2,2,2,2,2,2,2,2, # b0 - b7 +2,2,2,2,2,2,2,2, # b8 - bf +2,2,2,2,2,2,2,2, # c0 - c7 +2,2,2,2,2,2,2,2, # c8 - cf +2,2,2,2,2,2,2,2, # d0 - d7 +2,2,2,2,2,2,2,2, # d8 - df +2,2,2,2,2,2,2,2, # e0 - e7 +2,2,2,2,2,2,2,2, # e8 - ef +2,2,2,2,2,2,2,2, # f0 - f7 +2,2,2,2,2,2,2,2, # f8 - ff +) + +ISO2022CN_ST = ( +MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 00-07 +MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 08-0f +MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 10-17 +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,# 18-1f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 20-27 + 5, 6,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 28-2f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 30-37 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,# 38-3f +) + +ISO2022CN_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0, 0, 0, 0) + +ISO2022CN_SM_MODEL = {'class_table': ISO2022CN_CLS, + 'class_factor': 9, + 'state_table': ISO2022CN_ST, + 'char_len_table': ISO2022CN_CHAR_LEN_TABLE, + 'name': "ISO-2022-CN", + 'language': 'Chinese'} + +ISO2022JP_CLS = ( +2,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,2,2, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,7,0,0,0, # 20 - 27 +3,0,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +6,0,4,0,8,0,0,0, # 40 - 47 +0,9,5,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,0,0,0,0,0, # 78 - 7f +2,2,2,2,2,2,2,2, # 80 - 87 +2,2,2,2,2,2,2,2, # 88 - 8f +2,2,2,2,2,2,2,2, # 90 - 97 +2,2,2,2,2,2,2,2, # 98 - 9f +2,2,2,2,2,2,2,2, # a0 - a7 +2,2,2,2,2,2,2,2, # a8 - af +2,2,2,2,2,2,2,2, # b0 - b7 +2,2,2,2,2,2,2,2, # b8 - bf +2,2,2,2,2,2,2,2, # c0 - c7 +2,2,2,2,2,2,2,2, # c8 - cf +2,2,2,2,2,2,2,2, # d0 - d7 +2,2,2,2,2,2,2,2, # d8 - df +2,2,2,2,2,2,2,2, # e0 - e7 +2,2,2,2,2,2,2,2, # e8 - ef +2,2,2,2,2,2,2,2, # f0 - f7 +2,2,2,2,2,2,2,2, # f8 - ff +) + +ISO2022JP_ST = ( +MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 00-07 +MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 08-0f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 10-17 +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,# 18-1f +MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,MachineState.ERROR,# 20-27 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 6,MachineState.ITS_ME,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,# 28-2f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,# 30-37 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 38-3f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,MachineState.START,# 40-47 +) + +ISO2022JP_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + +ISO2022JP_SM_MODEL = {'class_table': ISO2022JP_CLS, + 'class_factor': 10, + 'state_table': ISO2022JP_ST, + 'char_len_table': ISO2022JP_CHAR_LEN_TABLE, + 'name': "ISO-2022-JP", + 'language': 'Japanese'} + +ISO2022KR_CLS = ( +2,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,0,0, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,3,0,0,0, # 20 - 27 +0,4,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +0,0,0,5,0,0,0,0, # 40 - 47 +0,0,0,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,0,0,0,0,0, # 78 - 7f +2,2,2,2,2,2,2,2, # 80 - 87 +2,2,2,2,2,2,2,2, # 88 - 8f +2,2,2,2,2,2,2,2, # 90 - 97 +2,2,2,2,2,2,2,2, # 98 - 9f +2,2,2,2,2,2,2,2, # a0 - a7 +2,2,2,2,2,2,2,2, # a8 - af +2,2,2,2,2,2,2,2, # b0 - b7 +2,2,2,2,2,2,2,2, # b8 - bf +2,2,2,2,2,2,2,2, # c0 - c7 +2,2,2,2,2,2,2,2, # c8 - cf +2,2,2,2,2,2,2,2, # d0 - d7 +2,2,2,2,2,2,2,2, # d8 - df +2,2,2,2,2,2,2,2, # e0 - e7 +2,2,2,2,2,2,2,2, # e8 - ef +2,2,2,2,2,2,2,2, # f0 - f7 +2,2,2,2,2,2,2,2, # f8 - ff +) + +ISO2022KR_ST = ( +MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,# 00-07 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 08-0f +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,MachineState.ERROR,# 10-17 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 18-1f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 20-27 +) + +ISO2022KR_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0) + +ISO2022KR_SM_MODEL = {'class_table': ISO2022KR_CLS, + 'class_factor': 6, + 'state_table': ISO2022KR_ST, + 'char_len_table': ISO2022KR_CHAR_LEN_TABLE, + 'name': "ISO-2022-KR", + 'language': 'Korean'} + + diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/eucjpprober.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/eucjpprober.py new file mode 100644 index 0000000..20ce8f7 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/eucjpprober.py @@ -0,0 +1,92 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import ProbingState, MachineState +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import EUCJPDistributionAnalysis +from .jpcntx import EUCJPContextAnalysis +from .mbcssm import EUCJP_SM_MODEL + + +class EUCJPProber(MultiByteCharSetProber): + def __init__(self): + super(EUCJPProber, self).__init__() + self.coding_sm = CodingStateMachine(EUCJP_SM_MODEL) + self.distribution_analyzer = EUCJPDistributionAnalysis() + self.context_analyzer = EUCJPContextAnalysis() + self.reset() + + def reset(self): + super(EUCJPProber, self).reset() + self.context_analyzer.reset() + + @property + def charset_name(self): + return "EUC-JP" + + @property + def language(self): + return "Japanese" + + def feed(self, byte_str): + for i in range(len(byte_str)): + # PY3K: byte_str is a byte array, so byte_str[i] is an int, not a byte + coding_state = self.coding_sm.next_state(byte_str[i]) + if coding_state == MachineState.ERROR: + self.logger.debug('%s %s prober hit error at byte %s', + self.charset_name, self.language, i) + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + char_len = self.coding_sm.get_current_charlen() + if i == 0: + self._last_char[1] = byte_str[0] + self.context_analyzer.feed(self._last_char, char_len) + self.distribution_analyzer.feed(self._last_char, char_len) + else: + self.context_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + self.distribution_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + + self._last_char[0] = byte_str[-1] + + if self.state == ProbingState.DETECTING: + if (self.context_analyzer.got_enough_data() and + (self.get_confidence() > self.SHORTCUT_THRESHOLD)): + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + context_conf = self.context_analyzer.get_confidence() + distrib_conf = self.distribution_analyzer.get_confidence() + return max(context_conf, distrib_conf) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/euckrfreq.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/euckrfreq.py new file mode 100644 index 0000000..b68078c --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/euckrfreq.py @@ -0,0 +1,195 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# Sampling from about 20M text materials include literature and computer technology + +# 128 --> 0.79 +# 256 --> 0.92 +# 512 --> 0.986 +# 1024 --> 0.99944 +# 2048 --> 0.99999 +# +# Idea Distribution Ratio = 0.98653 / (1-0.98653) = 73.24 +# Random Distribution Ration = 512 / (2350-512) = 0.279. +# +# Typical Distribution Ratio + +EUCKR_TYPICAL_DISTRIBUTION_RATIO = 6.0 + +EUCKR_TABLE_SIZE = 2352 + +# Char to FreqOrder table , +EUCKR_CHAR_TO_FREQ_ORDER = ( + 13, 130, 120,1396, 481,1719,1720, 328, 609, 212,1721, 707, 400, 299,1722, 87, +1397,1723, 104, 536,1117,1203,1724,1267, 685,1268, 508,1725,1726,1727,1728,1398, +1399,1729,1730,1731, 141, 621, 326,1057, 368,1732, 267, 488, 20,1733,1269,1734, + 945,1400,1735, 47, 904,1270,1736,1737, 773, 248,1738, 409, 313, 786, 429,1739, + 116, 987, 813,1401, 683, 75,1204, 145,1740,1741,1742,1743, 16, 847, 667, 622, + 708,1744,1745,1746, 966, 787, 304, 129,1747, 60, 820, 123, 676,1748,1749,1750, +1751, 617,1752, 626,1753,1754,1755,1756, 653,1757,1758,1759,1760,1761,1762, 856, + 344,1763,1764,1765,1766, 89, 401, 418, 806, 905, 848,1767,1768,1769, 946,1205, + 709,1770,1118,1771, 241,1772,1773,1774,1271,1775, 569,1776, 999,1777,1778,1779, +1780, 337, 751,1058, 28, 628, 254,1781, 177, 906, 270, 349, 891,1079,1782, 19, +1783, 379,1784, 315,1785, 629, 754,1402, 559,1786, 636, 203,1206,1787, 710, 567, +1788, 935, 814,1789,1790,1207, 766, 528,1791,1792,1208,1793,1794,1795,1796,1797, +1403,1798,1799, 533,1059,1404,1405,1156,1406, 936, 884,1080,1800, 351,1801,1802, +1803,1804,1805, 801,1806,1807,1808,1119,1809,1157, 714, 474,1407,1810, 298, 899, + 885,1811,1120, 802,1158,1812, 892,1813,1814,1408, 659,1815,1816,1121,1817,1818, +1819,1820,1821,1822, 319,1823, 594, 545,1824, 815, 937,1209,1825,1826, 573,1409, +1022,1827,1210,1828,1829,1830,1831,1832,1833, 556, 722, 807,1122,1060,1834, 697, +1835, 900, 557, 715,1836,1410, 540,1411, 752,1159, 294, 597,1211, 976, 803, 770, +1412,1837,1838, 39, 794,1413, 358,1839, 371, 925,1840, 453, 661, 788, 531, 723, + 544,1023,1081, 869, 91,1841, 392, 430, 790, 602,1414, 677,1082, 457,1415,1416, +1842,1843, 475, 327,1024,1417, 795, 121,1844, 733, 403,1418,1845,1846,1847, 300, + 119, 711,1212, 627,1848,1272, 207,1849,1850, 796,1213, 382,1851, 519,1852,1083, + 893,1853,1854,1855, 367, 809, 487, 671,1856, 663,1857,1858, 956, 471, 306, 857, +1859,1860,1160,1084,1861,1862,1863,1864,1865,1061,1866,1867,1868,1869,1870,1871, + 282, 96, 574,1872, 502,1085,1873,1214,1874, 907,1875,1876, 827, 977,1419,1420, +1421, 268,1877,1422,1878,1879,1880, 308,1881, 2, 537,1882,1883,1215,1884,1885, + 127, 791,1886,1273,1423,1887, 34, 336, 404, 643,1888, 571, 654, 894, 840,1889, + 0, 886,1274, 122, 575, 260, 908, 938,1890,1275, 410, 316,1891,1892, 100,1893, +1894,1123, 48,1161,1124,1025,1895, 633, 901,1276,1896,1897, 115, 816,1898, 317, +1899, 694,1900, 909, 734,1424, 572, 866,1425, 691, 85, 524,1010, 543, 394, 841, +1901,1902,1903,1026,1904,1905,1906,1907,1908,1909, 30, 451, 651, 988, 310,1910, +1911,1426, 810,1216, 93,1912,1913,1277,1217,1914, 858, 759, 45, 58, 181, 610, + 269,1915,1916, 131,1062, 551, 443,1000, 821,1427, 957, 895,1086,1917,1918, 375, +1919, 359,1920, 687,1921, 822,1922, 293,1923,1924, 40, 662, 118, 692, 29, 939, + 887, 640, 482, 174,1925, 69,1162, 728,1428, 910,1926,1278,1218,1279, 386, 870, + 217, 854,1163, 823,1927,1928,1929,1930, 834,1931, 78,1932, 859,1933,1063,1934, +1935,1936,1937, 438,1164, 208, 595,1938,1939,1940,1941,1219,1125,1942, 280, 888, +1429,1430,1220,1431,1943,1944,1945,1946,1947,1280, 150, 510,1432,1948,1949,1950, +1951,1952,1953,1954,1011,1087,1955,1433,1043,1956, 881,1957, 614, 958,1064,1065, +1221,1958, 638,1001, 860, 967, 896,1434, 989, 492, 553,1281,1165,1959,1282,1002, +1283,1222,1960,1961,1962,1963, 36, 383, 228, 753, 247, 454,1964, 876, 678,1965, +1966,1284, 126, 464, 490, 835, 136, 672, 529, 940,1088,1435, 473,1967,1968, 467, + 50, 390, 227, 587, 279, 378, 598, 792, 968, 240, 151, 160, 849, 882,1126,1285, + 639,1044, 133, 140, 288, 360, 811, 563,1027, 561, 142, 523,1969,1970,1971, 7, + 103, 296, 439, 407, 506, 634, 990,1972,1973,1974,1975, 645,1976,1977,1978,1979, +1980,1981, 236,1982,1436,1983,1984,1089, 192, 828, 618, 518,1166, 333,1127,1985, + 818,1223,1986,1987,1988,1989,1990,1991,1992,1993, 342,1128,1286, 746, 842,1994, +1995, 560, 223,1287, 98, 8, 189, 650, 978,1288,1996,1437,1997, 17, 345, 250, + 423, 277, 234, 512, 226, 97, 289, 42, 167,1998, 201,1999,2000, 843, 836, 824, + 532, 338, 783,1090, 182, 576, 436,1438,1439, 527, 500,2001, 947, 889,2002,2003, +2004,2005, 262, 600, 314, 447,2006, 547,2007, 693, 738,1129,2008, 71,1440, 745, + 619, 688,2009, 829,2010,2011, 147,2012, 33, 948,2013,2014, 74, 224,2015, 61, + 191, 918, 399, 637,2016,1028,1130, 257, 902,2017,2018,2019,2020,2021,2022,2023, +2024,2025,2026, 837,2027,2028,2029,2030, 179, 874, 591, 52, 724, 246,2031,2032, +2033,2034,1167, 969,2035,1289, 630, 605, 911,1091,1168,2036,2037,2038,1441, 912, +2039, 623,2040,2041, 253,1169,1290,2042,1442, 146, 620, 611, 577, 433,2043,1224, + 719,1170, 959, 440, 437, 534, 84, 388, 480,1131, 159, 220, 198, 679,2044,1012, + 819,1066,1443, 113,1225, 194, 318,1003,1029,2045,2046,2047,2048,1067,2049,2050, +2051,2052,2053, 59, 913, 112,2054, 632,2055, 455, 144, 739,1291,2056, 273, 681, + 499,2057, 448,2058,2059, 760,2060,2061, 970, 384, 169, 245,1132,2062,2063, 414, +1444,2064,2065, 41, 235,2066, 157, 252, 877, 568, 919, 789, 580,2067, 725,2068, +2069,1292,2070,2071,1445,2072,1446,2073,2074, 55, 588, 66,1447, 271,1092,2075, +1226,2076, 960,1013, 372,2077,2078,2079,2080,2081,1293,2082,2083,2084,2085, 850, +2086,2087,2088,2089,2090, 186,2091,1068, 180,2092,2093,2094, 109,1227, 522, 606, +2095, 867,1448,1093, 991,1171, 926, 353,1133,2096, 581,2097,2098,2099,1294,1449, +1450,2100, 596,1172,1014,1228,2101,1451,1295,1173,1229,2102,2103,1296,1134,1452, + 949,1135,2104,2105,1094,1453,1454,1455,2106,1095,2107,2108,2109,2110,2111,2112, +2113,2114,2115,2116,2117, 804,2118,2119,1230,1231, 805,1456, 405,1136,2120,2121, +2122,2123,2124, 720, 701,1297, 992,1457, 927,1004,2125,2126,2127,2128,2129,2130, + 22, 417,2131, 303,2132, 385,2133, 971, 520, 513,2134,1174, 73,1096, 231, 274, + 962,1458, 673,2135,1459,2136, 152,1137,2137,2138,2139,2140,1005,1138,1460,1139, +2141,2142,2143,2144, 11, 374, 844,2145, 154,1232, 46,1461,2146, 838, 830, 721, +1233, 106,2147, 90, 428, 462, 578, 566,1175, 352,2148,2149, 538,1234, 124,1298, +2150,1462, 761, 565,2151, 686,2152, 649,2153, 72, 173,2154, 460, 415,2155,1463, +2156,1235, 305,2157,2158,2159,2160,2161,2162, 579,2163,2164,2165,2166,2167, 747, +2168,2169,2170,2171,1464, 669,2172,2173,2174,2175,2176,1465,2177, 23, 530, 285, +2178, 335, 729,2179, 397,2180,2181,2182,1030,2183,2184, 698,2185,2186, 325,2187, +2188, 369,2189, 799,1097,1015, 348,2190,1069, 680,2191, 851,1466,2192,2193, 10, +2194, 613, 424,2195, 979, 108, 449, 589, 27, 172, 81,1031, 80, 774, 281, 350, +1032, 525, 301, 582,1176,2196, 674,1045,2197,2198,1467, 730, 762,2199,2200,2201, +2202,1468,2203, 993,2204,2205, 266,1070, 963,1140,2206,2207,2208, 664,1098, 972, +2209,2210,2211,1177,1469,1470, 871,2212,2213,2214,2215,2216,1471,2217,2218,2219, +2220,2221,2222,2223,2224,2225,2226,2227,1472,1236,2228,2229,2230,2231,2232,2233, +2234,2235,1299,2236,2237, 200,2238, 477, 373,2239,2240, 731, 825, 777,2241,2242, +2243, 521, 486, 548,2244,2245,2246,1473,1300, 53, 549, 137, 875, 76, 158,2247, +1301,1474, 469, 396,1016, 278, 712,2248, 321, 442, 503, 767, 744, 941,1237,1178, +1475,2249, 82, 178,1141,1179, 973,2250,1302,2251, 297,2252,2253, 570,2254,2255, +2256, 18, 450, 206,2257, 290, 292,1142,2258, 511, 162, 99, 346, 164, 735,2259, +1476,1477, 4, 554, 343, 798,1099,2260,1100,2261, 43, 171,1303, 139, 215,2262, +2263, 717, 775,2264,1033, 322, 216,2265, 831,2266, 149,2267,1304,2268,2269, 702, +1238, 135, 845, 347, 309,2270, 484,2271, 878, 655, 238,1006,1478,2272, 67,2273, + 295,2274,2275, 461,2276, 478, 942, 412,2277,1034,2278,2279,2280, 265,2281, 541, +2282,2283,2284,2285,2286, 70, 852,1071,2287,2288,2289,2290, 21, 56, 509, 117, + 432,2291,2292, 331, 980, 552,1101, 148, 284, 105, 393,1180,1239, 755,2293, 187, +2294,1046,1479,2295, 340,2296, 63,1047, 230,2297,2298,1305, 763,1306, 101, 800, + 808, 494,2299,2300,2301, 903,2302, 37,1072, 14, 5,2303, 79, 675,2304, 312, +2305,2306,2307,2308,2309,1480, 6,1307,2310,2311,2312, 1, 470, 35, 24, 229, +2313, 695, 210, 86, 778, 15, 784, 592, 779, 32, 77, 855, 964,2314, 259,2315, + 501, 380,2316,2317, 83, 981, 153, 689,1308,1481,1482,1483,2318,2319, 716,1484, +2320,2321,2322,2323,2324,2325,1485,2326,2327, 128, 57, 68, 261,1048, 211, 170, +1240, 31,2328, 51, 435, 742,2329,2330,2331, 635,2332, 264, 456,2333,2334,2335, + 425,2336,1486, 143, 507, 263, 943,2337, 363, 920,1487, 256,1488,1102, 243, 601, +1489,2338,2339,2340,2341,2342,2343,2344, 861,2345,2346,2347,2348,2349,2350, 395, +2351,1490,1491, 62, 535, 166, 225,2352,2353, 668, 419,1241, 138, 604, 928,2354, +1181,2355,1492,1493,2356,2357,2358,1143,2359, 696,2360, 387, 307,1309, 682, 476, +2361,2362, 332, 12, 222, 156,2363, 232,2364, 641, 276, 656, 517,1494,1495,1035, + 416, 736,1496,2365,1017, 586,2366,2367,2368,1497,2369, 242,2370,2371,2372,1498, +2373, 965, 713,2374,2375,2376,2377, 740, 982,1499, 944,1500,1007,2378,2379,1310, +1501,2380,2381,2382, 785, 329,2383,2384,1502,2385,2386,2387, 932,2388,1503,2389, +2390,2391,2392,1242,2393,2394,2395,2396,2397, 994, 950,2398,2399,2400,2401,1504, +1311,2402,2403,2404,2405,1049, 749,2406,2407, 853, 718,1144,1312,2408,1182,1505, +2409,2410, 255, 516, 479, 564, 550, 214,1506,1507,1313, 413, 239, 444, 339,1145, +1036,1508,1509,1314,1037,1510,1315,2411,1511,2412,2413,2414, 176, 703, 497, 624, + 593, 921, 302,2415, 341, 165,1103,1512,2416,1513,2417,2418,2419, 376,2420, 700, +2421,2422,2423, 258, 768,1316,2424,1183,2425, 995, 608,2426,2427,2428,2429, 221, +2430,2431,2432,2433,2434,2435,2436,2437, 195, 323, 726, 188, 897, 983,1317, 377, + 644,1050, 879,2438, 452,2439,2440,2441,2442,2443,2444, 914,2445,2446,2447,2448, + 915, 489,2449,1514,1184,2450,2451, 515, 64, 427, 495,2452, 583,2453, 483, 485, +1038, 562, 213,1515, 748, 666,2454,2455,2456,2457, 334,2458, 780, 996,1008, 705, +1243,2459,2460,2461,2462,2463, 114,2464, 493,1146, 366, 163,1516, 961,1104,2465, + 291,2466,1318,1105,2467,1517, 365,2468, 355, 951,1244,2469,1319,2470, 631,2471, +2472, 218,1320, 364, 320, 756,1518,1519,1321,1520,1322,2473,2474,2475,2476, 997, +2477,2478,2479,2480, 665,1185,2481, 916,1521,2482,2483,2484, 584, 684,2485,2486, + 797,2487,1051,1186,2488,2489,2490,1522,2491,2492, 370,2493,1039,1187, 65,2494, + 434, 205, 463,1188,2495, 125, 812, 391, 402, 826, 699, 286, 398, 155, 781, 771, + 585,2496, 590, 505,1073,2497, 599, 244, 219, 917,1018, 952, 646,1523,2498,1323, +2499,2500, 49, 984, 354, 741,2501, 625,2502,1324,2503,1019, 190, 357, 757, 491, + 95, 782, 868,2504,2505,2506,2507,2508,2509, 134,1524,1074, 422,1525, 898,2510, + 161,2511,2512,2513,2514, 769,2515,1526,2516,2517, 411,1325,2518, 472,1527,2519, +2520,2521,2522,2523,2524, 985,2525,2526,2527,2528,2529,2530, 764,2531,1245,2532, +2533, 25, 204, 311,2534, 496,2535,1052,2536,2537,2538,2539,2540,2541,2542, 199, + 704, 504, 468, 758, 657,1528, 196, 44, 839,1246, 272, 750,2543, 765, 862,2544, +2545,1326,2546, 132, 615, 933,2547, 732,2548,2549,2550,1189,1529,2551, 283,1247, +1053, 607, 929,2552,2553,2554, 930, 183, 872, 616,1040,1147,2555,1148,1020, 441, + 249,1075,2556,2557,2558, 466, 743,2559,2560,2561, 92, 514, 426, 420, 526,2562, +2563,2564,2565,2566,2567,2568, 185,2569,2570,2571,2572, 776,1530, 658,2573, 362, +2574, 361, 922,1076, 793,2575,2576,2577,2578,2579,2580,1531, 251,2581,2582,2583, +2584,1532, 54, 612, 237,1327,2585,2586, 275, 408, 647, 111,2587,1533,1106, 465, + 3, 458, 9, 38,2588, 107, 110, 890, 209, 26, 737, 498,2589,1534,2590, 431, + 202, 88,1535, 356, 287,1107, 660,1149,2591, 381,1536, 986,1150, 445,1248,1151, + 974,2592,2593, 846,2594, 446, 953, 184,1249,1250, 727,2595, 923, 193, 883,2596, +2597,2598, 102, 324, 539, 817,2599, 421,1041,2600, 832,2601, 94, 175, 197, 406, +2602, 459,2603,2604,2605,2606,2607, 330, 555,2608,2609,2610, 706,1108, 389,2611, +2612,2613,2614, 233,2615, 833, 558, 931, 954,1251,2616,2617,1537, 546,2618,2619, +1009,2620,2621,2622,1538, 690,1328,2623, 955,2624,1539,2625,2626, 772,2627,2628, +2629,2630,2631, 924, 648, 863, 603,2632,2633, 934,1540, 864, 865,2634, 642,1042, + 670,1190,2635,2636,2637,2638, 168,2639, 652, 873, 542,1054,1541,2640,2641,2642, # 512, 256 +) + diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/euckrprober.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/euckrprober.py new file mode 100644 index 0000000..345a060 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/euckrprober.py @@ -0,0 +1,47 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import EUCKRDistributionAnalysis +from .mbcssm import EUCKR_SM_MODEL + + +class EUCKRProber(MultiByteCharSetProber): + def __init__(self): + super(EUCKRProber, self).__init__() + self.coding_sm = CodingStateMachine(EUCKR_SM_MODEL) + self.distribution_analyzer = EUCKRDistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "EUC-KR" + + @property + def language(self): + return "Korean" diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/euctwfreq.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/euctwfreq.py new file mode 100644 index 0000000..ed7a995 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/euctwfreq.py @@ -0,0 +1,387 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# EUCTW frequency table +# Converted from big5 work +# by Taiwan's Mandarin Promotion Council +# <http:#www.edu.tw:81/mandr/> + +# 128 --> 0.42261 +# 256 --> 0.57851 +# 512 --> 0.74851 +# 1024 --> 0.89384 +# 2048 --> 0.97583 +# +# Idea Distribution Ratio = 0.74851/(1-0.74851) =2.98 +# Random Distribution Ration = 512/(5401-512)=0.105 +# +# Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR + +EUCTW_TYPICAL_DISTRIBUTION_RATIO = 0.75 + +# Char to FreqOrder table , +EUCTW_TABLE_SIZE = 5376 + +EUCTW_CHAR_TO_FREQ_ORDER = ( + 1,1800,1506, 255,1431, 198, 9, 82, 6,7310, 177, 202,3615,1256,2808, 110, # 2742 +3735, 33,3241, 261, 76, 44,2113, 16,2931,2184,1176, 659,3868, 26,3404,2643, # 2758 +1198,3869,3313,4060, 410,2211, 302, 590, 361,1963, 8, 204, 58,4296,7311,1931, # 2774 + 63,7312,7313, 317,1614, 75, 222, 159,4061,2412,1480,7314,3500,3068, 224,2809, # 2790 +3616, 3, 10,3870,1471, 29,2774,1135,2852,1939, 873, 130,3242,1123, 312,7315, # 2806 +4297,2051, 507, 252, 682,7316, 142,1914, 124, 206,2932, 34,3501,3173, 64, 604, # 2822 +7317,2494,1976,1977, 155,1990, 645, 641,1606,7318,3405, 337, 72, 406,7319, 80, # 2838 + 630, 238,3174,1509, 263, 939,1092,2644, 756,1440,1094,3406, 449, 69,2969, 591, # 2854 + 179,2095, 471, 115,2034,1843, 60, 50,2970, 134, 806,1868, 734,2035,3407, 180, # 2870 + 995,1607, 156, 537,2893, 688,7320, 319,1305, 779,2144, 514,2374, 298,4298, 359, # 2886 +2495, 90,2707,1338, 663, 11, 906,1099,2545, 20,2436, 182, 532,1716,7321, 732, # 2902 +1376,4062,1311,1420,3175, 25,2312,1056, 113, 399, 382,1949, 242,3408,2467, 529, # 2918 +3243, 475,1447,3617,7322, 117, 21, 656, 810,1297,2295,2329,3502,7323, 126,4063, # 2934 + 706, 456, 150, 613,4299, 71,1118,2036,4064, 145,3069, 85, 835, 486,2114,1246, # 2950 +1426, 428, 727,1285,1015, 800, 106, 623, 303,1281,7324,2127,2354, 347,3736, 221, # 2966 +3503,3110,7325,1955,1153,4065, 83, 296,1199,3070, 192, 624, 93,7326, 822,1897, # 2982 +2810,3111, 795,2064, 991,1554,1542,1592, 27, 43,2853, 859, 139,1456, 860,4300, # 2998 + 437, 712,3871, 164,2392,3112, 695, 211,3017,2096, 195,3872,1608,3504,3505,3618, # 3014 +3873, 234, 811,2971,2097,3874,2229,1441,3506,1615,2375, 668,2076,1638, 305, 228, # 3030 +1664,4301, 467, 415,7327, 262,2098,1593, 239, 108, 300, 200,1033, 512,1247,2077, # 3046 +7328,7329,2173,3176,3619,2673, 593, 845,1062,3244, 88,1723,2037,3875,1950, 212, # 3062 + 266, 152, 149, 468,1898,4066,4302, 77, 187,7330,3018, 37, 5,2972,7331,3876, # 3078 +7332,7333, 39,2517,4303,2894,3177,2078, 55, 148, 74,4304, 545, 483,1474,1029, # 3094 +1665, 217,1869,1531,3113,1104,2645,4067, 24, 172,3507, 900,3877,3508,3509,4305, # 3110 + 32,1408,2811,1312, 329, 487,2355,2247,2708, 784,2674, 4,3019,3314,1427,1788, # 3126 + 188, 109, 499,7334,3620,1717,1789, 888,1217,3020,4306,7335,3510,7336,3315,1520, # 3142 +3621,3878, 196,1034, 775,7337,7338, 929,1815, 249, 439, 38,7339,1063,7340, 794, # 3158 +3879,1435,2296, 46, 178,3245,2065,7341,2376,7342, 214,1709,4307, 804, 35, 707, # 3174 + 324,3622,1601,2546, 140, 459,4068,7343,7344,1365, 839, 272, 978,2257,2572,3409, # 3190 +2128,1363,3623,1423, 697, 100,3071, 48, 70,1231, 495,3114,2193,7345,1294,7346, # 3206 +2079, 462, 586,1042,3246, 853, 256, 988, 185,2377,3410,1698, 434,1084,7347,3411, # 3222 + 314,2615,2775,4308,2330,2331, 569,2280, 637,1816,2518, 757,1162,1878,1616,3412, # 3238 + 287,1577,2115, 768,4309,1671,2854,3511,2519,1321,3737, 909,2413,7348,4069, 933, # 3254 +3738,7349,2052,2356,1222,4310, 765,2414,1322, 786,4311,7350,1919,1462,1677,2895, # 3270 +1699,7351,4312,1424,2437,3115,3624,2590,3316,1774,1940,3413,3880,4070, 309,1369, # 3286 +1130,2812, 364,2230,1653,1299,3881,3512,3882,3883,2646, 525,1085,3021, 902,2000, # 3302 +1475, 964,4313, 421,1844,1415,1057,2281, 940,1364,3116, 376,4314,4315,1381, 7, # 3318 +2520, 983,2378, 336,1710,2675,1845, 321,3414, 559,1131,3022,2742,1808,1132,1313, # 3334 + 265,1481,1857,7352, 352,1203,2813,3247, 167,1089, 420,2814, 776, 792,1724,3513, # 3350 +4071,2438,3248,7353,4072,7354, 446, 229, 333,2743, 901,3739,1200,1557,4316,2647, # 3366 +1920, 395,2744,2676,3740,4073,1835, 125, 916,3178,2616,4317,7355,7356,3741,7357, # 3382 +7358,7359,4318,3117,3625,1133,2547,1757,3415,1510,2313,1409,3514,7360,2145, 438, # 3398 +2591,2896,2379,3317,1068, 958,3023, 461, 311,2855,2677,4074,1915,3179,4075,1978, # 3414 + 383, 750,2745,2617,4076, 274, 539, 385,1278,1442,7361,1154,1964, 384, 561, 210, # 3430 + 98,1295,2548,3515,7362,1711,2415,1482,3416,3884,2897,1257, 129,7363,3742, 642, # 3446 + 523,2776,2777,2648,7364, 141,2231,1333, 68, 176, 441, 876, 907,4077, 603,2592, # 3462 + 710, 171,3417, 404, 549, 18,3118,2393,1410,3626,1666,7365,3516,4319,2898,4320, # 3478 +7366,2973, 368,7367, 146, 366, 99, 871,3627,1543, 748, 807,1586,1185, 22,2258, # 3494 + 379,3743,3180,7368,3181, 505,1941,2618,1991,1382,2314,7369, 380,2357, 218, 702, # 3510 +1817,1248,3418,3024,3517,3318,3249,7370,2974,3628, 930,3250,3744,7371, 59,7372, # 3526 + 585, 601,4078, 497,3419,1112,1314,4321,1801,7373,1223,1472,2174,7374, 749,1836, # 3542 + 690,1899,3745,1772,3885,1476, 429,1043,1790,2232,2116, 917,4079, 447,1086,1629, # 3558 +7375, 556,7376,7377,2020,1654, 844,1090, 105, 550, 966,1758,2815,1008,1782, 686, # 3574 +1095,7378,2282, 793,1602,7379,3518,2593,4322,4080,2933,2297,4323,3746, 980,2496, # 3590 + 544, 353, 527,4324, 908,2678,2899,7380, 381,2619,1942,1348,7381,1341,1252, 560, # 3606 +3072,7382,3420,2856,7383,2053, 973, 886,2080, 143,4325,7384,7385, 157,3886, 496, # 3622 +4081, 57, 840, 540,2038,4326,4327,3421,2117,1445, 970,2259,1748,1965,2081,4082, # 3638 +3119,1234,1775,3251,2816,3629, 773,1206,2129,1066,2039,1326,3887,1738,1725,4083, # 3654 + 279,3120, 51,1544,2594, 423,1578,2130,2066, 173,4328,1879,7386,7387,1583, 264, # 3670 + 610,3630,4329,2439, 280, 154,7388,7389,7390,1739, 338,1282,3073, 693,2857,1411, # 3686 +1074,3747,2440,7391,4330,7392,7393,1240, 952,2394,7394,2900,1538,2679, 685,1483, # 3702 +4084,2468,1436, 953,4085,2054,4331, 671,2395, 79,4086,2441,3252, 608, 567,2680, # 3718 +3422,4087,4088,1691, 393,1261,1791,2396,7395,4332,7396,7397,7398,7399,1383,1672, # 3734 +3748,3182,1464, 522,1119, 661,1150, 216, 675,4333,3888,1432,3519, 609,4334,2681, # 3750 +2397,7400,7401,7402,4089,3025, 0,7403,2469, 315, 231,2442, 301,3319,4335,2380, # 3766 +7404, 233,4090,3631,1818,4336,4337,7405, 96,1776,1315,2082,7406, 257,7407,1809, # 3782 +3632,2709,1139,1819,4091,2021,1124,2163,2778,1777,2649,7408,3074, 363,1655,3183, # 3798 +7409,2975,7410,7411,7412,3889,1567,3890, 718, 103,3184, 849,1443, 341,3320,2934, # 3814 +1484,7413,1712, 127, 67, 339,4092,2398, 679,1412, 821,7414,7415, 834, 738, 351, # 3830 +2976,2146, 846, 235,1497,1880, 418,1992,3749,2710, 186,1100,2147,2746,3520,1545, # 3846 +1355,2935,2858,1377, 583,3891,4093,2573,2977,7416,1298,3633,1078,2549,3634,2358, # 3862 + 78,3750,3751, 267,1289,2099,2001,1594,4094, 348, 369,1274,2194,2175,1837,4338, # 3878 +1820,2817,3635,2747,2283,2002,4339,2936,2748, 144,3321, 882,4340,3892,2749,3423, # 3894 +4341,2901,7417,4095,1726, 320,7418,3893,3026, 788,2978,7419,2818,1773,1327,2859, # 3910 +3894,2819,7420,1306,4342,2003,1700,3752,3521,2359,2650, 787,2022, 506, 824,3636, # 3926 + 534, 323,4343,1044,3322,2023,1900, 946,3424,7421,1778,1500,1678,7422,1881,4344, # 3942 + 165, 243,4345,3637,2521, 123, 683,4096, 764,4346, 36,3895,1792, 589,2902, 816, # 3958 + 626,1667,3027,2233,1639,1555,1622,3753,3896,7423,3897,2860,1370,1228,1932, 891, # 3974 +2083,2903, 304,4097,7424, 292,2979,2711,3522, 691,2100,4098,1115,4347, 118, 662, # 3990 +7425, 611,1156, 854,2381,1316,2861, 2, 386, 515,2904,7426,7427,3253, 868,2234, # 4006 +1486, 855,2651, 785,2212,3028,7428,1040,3185,3523,7429,3121, 448,7430,1525,7431, # 4022 +2164,4348,7432,3754,7433,4099,2820,3524,3122, 503, 818,3898,3123,1568, 814, 676, # 4038 +1444, 306,1749,7434,3755,1416,1030, 197,1428, 805,2821,1501,4349,7435,7436,7437, # 4054 +1993,7438,4350,7439,7440,2195, 13,2779,3638,2980,3124,1229,1916,7441,3756,2131, # 4070 +7442,4100,4351,2399,3525,7443,2213,1511,1727,1120,7444,7445, 646,3757,2443, 307, # 4086 +7446,7447,1595,3186,7448,7449,7450,3639,1113,1356,3899,1465,2522,2523,7451, 519, # 4102 +7452, 128,2132, 92,2284,1979,7453,3900,1512, 342,3125,2196,7454,2780,2214,1980, # 4118 +3323,7455, 290,1656,1317, 789, 827,2360,7456,3758,4352, 562, 581,3901,7457, 401, # 4134 +4353,2248, 94,4354,1399,2781,7458,1463,2024,4355,3187,1943,7459, 828,1105,4101, # 4150 +1262,1394,7460,4102, 605,4356,7461,1783,2862,7462,2822, 819,2101, 578,2197,2937, # 4166 +7463,1502, 436,3254,4103,3255,2823,3902,2905,3425,3426,7464,2712,2315,7465,7466, # 4182 +2332,2067, 23,4357, 193, 826,3759,2102, 699,1630,4104,3075, 390,1793,1064,3526, # 4198 +7467,1579,3076,3077,1400,7468,4105,1838,1640,2863,7469,4358,4359, 137,4106, 598, # 4214 +3078,1966, 780, 104, 974,2938,7470, 278, 899, 253, 402, 572, 504, 493,1339,7471, # 4230 +3903,1275,4360,2574,2550,7472,3640,3029,3079,2249, 565,1334,2713, 863, 41,7473, # 4246 +7474,4361,7475,1657,2333, 19, 463,2750,4107, 606,7476,2981,3256,1087,2084,1323, # 4262 +2652,2982,7477,1631,1623,1750,4108,2682,7478,2864, 791,2714,2653,2334, 232,2416, # 4278 +7479,2983,1498,7480,2654,2620, 755,1366,3641,3257,3126,2025,1609, 119,1917,3427, # 4294 + 862,1026,4109,7481,3904,3760,4362,3905,4363,2260,1951,2470,7482,1125, 817,4110, # 4310 +4111,3906,1513,1766,2040,1487,4112,3030,3258,2824,3761,3127,7483,7484,1507,7485, # 4326 +2683, 733, 40,1632,1106,2865, 345,4113, 841,2524, 230,4364,2984,1846,3259,3428, # 4342 +7486,1263, 986,3429,7487, 735, 879, 254,1137, 857, 622,1300,1180,1388,1562,3907, # 4358 +3908,2939, 967,2751,2655,1349, 592,2133,1692,3324,2985,1994,4114,1679,3909,1901, # 4374 +2185,7488, 739,3642,2715,1296,1290,7489,4115,2198,2199,1921,1563,2595,2551,1870, # 4390 +2752,2986,7490, 435,7491, 343,1108, 596, 17,1751,4365,2235,3430,3643,7492,4366, # 4406 + 294,3527,2940,1693, 477, 979, 281,2041,3528, 643,2042,3644,2621,2782,2261,1031, # 4422 +2335,2134,2298,3529,4367, 367,1249,2552,7493,3530,7494,4368,1283,3325,2004, 240, # 4438 +1762,3326,4369,4370, 836,1069,3128, 474,7495,2148,2525, 268,3531,7496,3188,1521, # 4454 +1284,7497,1658,1546,4116,7498,3532,3533,7499,4117,3327,2684,1685,4118, 961,1673, # 4470 +2622, 190,2005,2200,3762,4371,4372,7500, 570,2497,3645,1490,7501,4373,2623,3260, # 4486 +1956,4374, 584,1514, 396,1045,1944,7502,4375,1967,2444,7503,7504,4376,3910, 619, # 4502 +7505,3129,3261, 215,2006,2783,2553,3189,4377,3190,4378, 763,4119,3763,4379,7506, # 4518 +7507,1957,1767,2941,3328,3646,1174, 452,1477,4380,3329,3130,7508,2825,1253,2382, # 4534 +2186,1091,2285,4120, 492,7509, 638,1169,1824,2135,1752,3911, 648, 926,1021,1324, # 4550 +4381, 520,4382, 997, 847,1007, 892,4383,3764,2262,1871,3647,7510,2400,1784,4384, # 4566 +1952,2942,3080,3191,1728,4121,2043,3648,4385,2007,1701,3131,1551, 30,2263,4122, # 4582 +7511,2026,4386,3534,7512, 501,7513,4123, 594,3431,2165,1821,3535,3432,3536,3192, # 4598 + 829,2826,4124,7514,1680,3132,1225,4125,7515,3262,4387,4126,3133,2336,7516,4388, # 4614 +4127,7517,3912,3913,7518,1847,2383,2596,3330,7519,4389, 374,3914, 652,4128,4129, # 4630 + 375,1140, 798,7520,7521,7522,2361,4390,2264, 546,1659, 138,3031,2445,4391,7523, # 4646 +2250, 612,1848, 910, 796,3765,1740,1371, 825,3766,3767,7524,2906,2554,7525, 692, # 4662 + 444,3032,2624, 801,4392,4130,7526,1491, 244,1053,3033,4131,4132, 340,7527,3915, # 4678 +1041,2987, 293,1168, 87,1357,7528,1539, 959,7529,2236, 721, 694,4133,3768, 219, # 4694 +1478, 644,1417,3331,2656,1413,1401,1335,1389,3916,7530,7531,2988,2362,3134,1825, # 4710 + 730,1515, 184,2827, 66,4393,7532,1660,2943, 246,3332, 378,1457, 226,3433, 975, # 4726 +3917,2944,1264,3537, 674, 696,7533, 163,7534,1141,2417,2166, 713,3538,3333,4394, # 4742 +3918,7535,7536,1186, 15,7537,1079,1070,7538,1522,3193,3539, 276,1050,2716, 758, # 4758 +1126, 653,2945,3263,7539,2337, 889,3540,3919,3081,2989, 903,1250,4395,3920,3434, # 4774 +3541,1342,1681,1718, 766,3264, 286, 89,2946,3649,7540,1713,7541,2597,3334,2990, # 4790 +7542,2947,2215,3194,2866,7543,4396,2498,2526, 181, 387,1075,3921, 731,2187,3335, # 4806 +7544,3265, 310, 313,3435,2299, 770,4134, 54,3034, 189,4397,3082,3769,3922,7545, # 4822 +1230,1617,1849, 355,3542,4135,4398,3336, 111,4136,3650,1350,3135,3436,3035,4137, # 4838 +2149,3266,3543,7546,2784,3923,3924,2991, 722,2008,7547,1071, 247,1207,2338,2471, # 4854 +1378,4399,2009, 864,1437,1214,4400, 373,3770,1142,2216, 667,4401, 442,2753,2555, # 4870 +3771,3925,1968,4138,3267,1839, 837, 170,1107, 934,1336,1882,7548,7549,2118,4139, # 4886 +2828, 743,1569,7550,4402,4140, 582,2384,1418,3437,7551,1802,7552, 357,1395,1729, # 4902 +3651,3268,2418,1564,2237,7553,3083,3772,1633,4403,1114,2085,4141,1532,7554, 482, # 4918 +2446,4404,7555,7556,1492, 833,1466,7557,2717,3544,1641,2829,7558,1526,1272,3652, # 4934 +4142,1686,1794, 416,2556,1902,1953,1803,7559,3773,2785,3774,1159,2316,7560,2867, # 4950 +4405,1610,1584,3036,2419,2754, 443,3269,1163,3136,7561,7562,3926,7563,4143,2499, # 4966 +3037,4406,3927,3137,2103,1647,3545,2010,1872,4144,7564,4145, 431,3438,7565, 250, # 4982 + 97, 81,4146,7566,1648,1850,1558, 160, 848,7567, 866, 740,1694,7568,2201,2830, # 4998 +3195,4147,4407,3653,1687, 950,2472, 426, 469,3196,3654,3655,3928,7569,7570,1188, # 5014 + 424,1995, 861,3546,4148,3775,2202,2685, 168,1235,3547,4149,7571,2086,1674,4408, # 5030 +3337,3270, 220,2557,1009,7572,3776, 670,2992, 332,1208, 717,7573,7574,3548,2447, # 5046 +3929,3338,7575, 513,7576,1209,2868,3339,3138,4409,1080,7577,7578,7579,7580,2527, # 5062 +3656,3549, 815,1587,3930,3931,7581,3550,3439,3777,1254,4410,1328,3038,1390,3932, # 5078 +1741,3933,3778,3934,7582, 236,3779,2448,3271,7583,7584,3657,3780,1273,3781,4411, # 5094 +7585, 308,7586,4412, 245,4413,1851,2473,1307,2575, 430, 715,2136,2449,7587, 270, # 5110 + 199,2869,3935,7588,3551,2718,1753, 761,1754, 725,1661,1840,4414,3440,3658,7589, # 5126 +7590, 587, 14,3272, 227,2598, 326, 480,2265, 943,2755,3552, 291, 650,1883,7591, # 5142 +1702,1226, 102,1547, 62,3441, 904,4415,3442,1164,4150,7592,7593,1224,1548,2756, # 5158 + 391, 498,1493,7594,1386,1419,7595,2055,1177,4416, 813, 880,1081,2363, 566,1145, # 5174 +4417,2286,1001,1035,2558,2599,2238, 394,1286,7596,7597,2068,7598, 86,1494,1730, # 5190 +3936, 491,1588, 745, 897,2948, 843,3340,3937,2757,2870,3273,1768, 998,2217,2069, # 5206 + 397,1826,1195,1969,3659,2993,3341, 284,7599,3782,2500,2137,2119,1903,7600,3938, # 5222 +2150,3939,4151,1036,3443,1904, 114,2559,4152, 209,1527,7601,7602,2949,2831,2625, # 5238 +2385,2719,3139, 812,2560,7603,3274,7604,1559, 737,1884,3660,1210, 885, 28,2686, # 5254 +3553,3783,7605,4153,1004,1779,4418,7606, 346,1981,2218,2687,4419,3784,1742, 797, # 5270 +1642,3940,1933,1072,1384,2151, 896,3941,3275,3661,3197,2871,3554,7607,2561,1958, # 5286 +4420,2450,1785,7608,7609,7610,3942,4154,1005,1308,3662,4155,2720,4421,4422,1528, # 5302 +2600, 161,1178,4156,1982, 987,4423,1101,4157, 631,3943,1157,3198,2420,1343,1241, # 5318 +1016,2239,2562, 372, 877,2339,2501,1160, 555,1934, 911,3944,7611, 466,1170, 169, # 5334 +1051,2907,2688,3663,2474,2994,1182,2011,2563,1251,2626,7612, 992,2340,3444,1540, # 5350 +2721,1201,2070,2401,1996,2475,7613,4424, 528,1922,2188,1503,1873,1570,2364,3342, # 5366 +3276,7614, 557,1073,7615,1827,3445,2087,2266,3140,3039,3084, 767,3085,2786,4425, # 5382 +1006,4158,4426,2341,1267,2176,3664,3199, 778,3945,3200,2722,1597,2657,7616,4427, # 5398 +7617,3446,7618,7619,7620,3277,2689,1433,3278, 131, 95,1504,3946, 723,4159,3141, # 5414 +1841,3555,2758,2189,3947,2027,2104,3665,7621,2995,3948,1218,7622,3343,3201,3949, # 5430 +4160,2576, 248,1634,3785, 912,7623,2832,3666,3040,3786, 654, 53,7624,2996,7625, # 5446 +1688,4428, 777,3447,1032,3950,1425,7626, 191, 820,2120,2833, 971,4429, 931,3202, # 5462 + 135, 664, 783,3787,1997, 772,2908,1935,3951,3788,4430,2909,3203, 282,2723, 640, # 5478 +1372,3448,1127, 922, 325,3344,7627,7628, 711,2044,7629,7630,3952,2219,2787,1936, # 5494 +3953,3345,2220,2251,3789,2300,7631,4431,3790,1258,3279,3954,3204,2138,2950,3955, # 5510 +3956,7632,2221, 258,3205,4432, 101,1227,7633,3280,1755,7634,1391,3281,7635,2910, # 5526 +2056, 893,7636,7637,7638,1402,4161,2342,7639,7640,3206,3556,7641,7642, 878,1325, # 5542 +1780,2788,4433, 259,1385,2577, 744,1183,2267,4434,7643,3957,2502,7644, 684,1024, # 5558 +4162,7645, 472,3557,3449,1165,3282,3958,3959, 322,2152, 881, 455,1695,1152,1340, # 5574 + 660, 554,2153,4435,1058,4436,4163, 830,1065,3346,3960,4437,1923,7646,1703,1918, # 5590 +7647, 932,2268, 122,7648,4438, 947, 677,7649,3791,2627, 297,1905,1924,2269,4439, # 5606 +2317,3283,7650,7651,4164,7652,4165, 84,4166, 112, 989,7653, 547,1059,3961, 701, # 5622 +3558,1019,7654,4167,7655,3450, 942, 639, 457,2301,2451, 993,2951, 407, 851, 494, # 5638 +4440,3347, 927,7656,1237,7657,2421,3348, 573,4168, 680, 921,2911,1279,1874, 285, # 5654 + 790,1448,1983, 719,2167,7658,7659,4441,3962,3963,1649,7660,1541, 563,7661,1077, # 5670 +7662,3349,3041,3451, 511,2997,3964,3965,3667,3966,1268,2564,3350,3207,4442,4443, # 5686 +7663, 535,1048,1276,1189,2912,2028,3142,1438,1373,2834,2952,1134,2012,7664,4169, # 5702 +1238,2578,3086,1259,7665, 700,7666,2953,3143,3668,4170,7667,4171,1146,1875,1906, # 5718 +4444,2601,3967, 781,2422, 132,1589, 203, 147, 273,2789,2402, 898,1786,2154,3968, # 5734 +3969,7668,3792,2790,7669,7670,4445,4446,7671,3208,7672,1635,3793, 965,7673,1804, # 5750 +2690,1516,3559,1121,1082,1329,3284,3970,1449,3794, 65,1128,2835,2913,2759,1590, # 5766 +3795,7674,7675, 12,2658, 45, 976,2579,3144,4447, 517,2528,1013,1037,3209,7676, # 5782 +3796,2836,7677,3797,7678,3452,7679,2602, 614,1998,2318,3798,3087,2724,2628,7680, # 5798 +2580,4172, 599,1269,7681,1810,3669,7682,2691,3088, 759,1060, 489,1805,3351,3285, # 5814 +1358,7683,7684,2386,1387,1215,2629,2252, 490,7685,7686,4173,1759,2387,2343,7687, # 5830 +4448,3799,1907,3971,2630,1806,3210,4449,3453,3286,2760,2344, 874,7688,7689,3454, # 5846 +3670,1858, 91,2914,3671,3042,3800,4450,7690,3145,3972,2659,7691,3455,1202,1403, # 5862 +3801,2954,2529,1517,2503,4451,3456,2504,7692,4452,7693,2692,1885,1495,1731,3973, # 5878 +2365,4453,7694,2029,7695,7696,3974,2693,1216, 237,2581,4174,2319,3975,3802,4454, # 5894 +4455,2694,3560,3457, 445,4456,7697,7698,7699,7700,2761, 61,3976,3672,1822,3977, # 5910 +7701, 687,2045, 935, 925, 405,2660, 703,1096,1859,2725,4457,3978,1876,1367,2695, # 5926 +3352, 918,2105,1781,2476, 334,3287,1611,1093,4458, 564,3146,3458,3673,3353, 945, # 5942 +2631,2057,4459,7702,1925, 872,4175,7703,3459,2696,3089, 349,4176,3674,3979,4460, # 5958 +3803,4177,3675,2155,3980,4461,4462,4178,4463,2403,2046, 782,3981, 400, 251,4179, # 5974 +1624,7704,7705, 277,3676, 299,1265, 476,1191,3804,2121,4180,4181,1109, 205,7706, # 5990 +2582,1000,2156,3561,1860,7707,7708,7709,4464,7710,4465,2565, 107,2477,2157,3982, # 6006 +3460,3147,7711,1533, 541,1301, 158, 753,4182,2872,3562,7712,1696, 370,1088,4183, # 6022 +4466,3563, 579, 327, 440, 162,2240, 269,1937,1374,3461, 968,3043, 56,1396,3090, # 6038 +2106,3288,3354,7713,1926,2158,4467,2998,7714,3564,7715,7716,3677,4468,2478,7717, # 6054 +2791,7718,1650,4469,7719,2603,7720,7721,3983,2661,3355,1149,3356,3984,3805,3985, # 6070 +7722,1076, 49,7723, 951,3211,3289,3290, 450,2837, 920,7724,1811,2792,2366,4184, # 6086 +1908,1138,2367,3806,3462,7725,3212,4470,1909,1147,1518,2423,4471,3807,7726,4472, # 6102 +2388,2604, 260,1795,3213,7727,7728,3808,3291, 708,7729,3565,1704,7730,3566,1351, # 6118 +1618,3357,2999,1886, 944,4185,3358,4186,3044,3359,4187,7731,3678, 422, 413,1714, # 6134 +3292, 500,2058,2345,4188,2479,7732,1344,1910, 954,7733,1668,7734,7735,3986,2404, # 6150 +4189,3567,3809,4190,7736,2302,1318,2505,3091, 133,3092,2873,4473, 629, 31,2838, # 6166 +2697,3810,4474, 850, 949,4475,3987,2955,1732,2088,4191,1496,1852,7737,3988, 620, # 6182 +3214, 981,1242,3679,3360,1619,3680,1643,3293,2139,2452,1970,1719,3463,2168,7738, # 6198 +3215,7739,7740,3361,1828,7741,1277,4476,1565,2047,7742,1636,3568,3093,7743, 869, # 6214 +2839, 655,3811,3812,3094,3989,3000,3813,1310,3569,4477,7744,7745,7746,1733, 558, # 6230 +4478,3681, 335,1549,3045,1756,4192,3682,1945,3464,1829,1291,1192, 470,2726,2107, # 6246 +2793, 913,1054,3990,7747,1027,7748,3046,3991,4479, 982,2662,3362,3148,3465,3216, # 6262 +3217,1946,2794,7749, 571,4480,7750,1830,7751,3570,2583,1523,2424,7752,2089, 984, # 6278 +4481,3683,1959,7753,3684, 852, 923,2795,3466,3685, 969,1519, 999,2048,2320,1705, # 6294 +7754,3095, 615,1662, 151, 597,3992,2405,2321,1049, 275,4482,3686,4193, 568,3687, # 6310 +3571,2480,4194,3688,7755,2425,2270, 409,3218,7756,1566,2874,3467,1002, 769,2840, # 6326 + 194,2090,3149,3689,2222,3294,4195, 628,1505,7757,7758,1763,2177,3001,3993, 521, # 6342 +1161,2584,1787,2203,2406,4483,3994,1625,4196,4197, 412, 42,3096, 464,7759,2632, # 6358 +4484,3363,1760,1571,2875,3468,2530,1219,2204,3814,2633,2140,2368,4485,4486,3295, # 6374 +1651,3364,3572,7760,7761,3573,2481,3469,7762,3690,7763,7764,2271,2091, 460,7765, # 6390 +4487,7766,3002, 962, 588,3574, 289,3219,2634,1116, 52,7767,3047,1796,7768,7769, # 6406 +7770,1467,7771,1598,1143,3691,4198,1984,1734,1067,4488,1280,3365, 465,4489,1572, # 6422 + 510,7772,1927,2241,1812,1644,3575,7773,4490,3692,7774,7775,2663,1573,1534,7776, # 6438 +7777,4199, 536,1807,1761,3470,3815,3150,2635,7778,7779,7780,4491,3471,2915,1911, # 6454 +2796,7781,3296,1122, 377,3220,7782, 360,7783,7784,4200,1529, 551,7785,2059,3693, # 6470 +1769,2426,7786,2916,4201,3297,3097,2322,2108,2030,4492,1404, 136,1468,1479, 672, # 6486 +1171,3221,2303, 271,3151,7787,2762,7788,2049, 678,2727, 865,1947,4493,7789,2013, # 6502 +3995,2956,7790,2728,2223,1397,3048,3694,4494,4495,1735,2917,3366,3576,7791,3816, # 6518 + 509,2841,2453,2876,3817,7792,7793,3152,3153,4496,4202,2531,4497,2304,1166,1010, # 6534 + 552, 681,1887,7794,7795,2957,2958,3996,1287,1596,1861,3154, 358, 453, 736, 175, # 6550 + 478,1117, 905,1167,1097,7796,1853,1530,7797,1706,7798,2178,3472,2287,3695,3473, # 6566 +3577,4203,2092,4204,7799,3367,1193,2482,4205,1458,2190,2205,1862,1888,1421,3298, # 6582 +2918,3049,2179,3474, 595,2122,7800,3997,7801,7802,4206,1707,2636, 223,3696,1359, # 6598 + 751,3098, 183,3475,7803,2797,3003, 419,2369, 633, 704,3818,2389, 241,7804,7805, # 6614 +7806, 838,3004,3697,2272,2763,2454,3819,1938,2050,3998,1309,3099,2242,1181,7807, # 6630 +1136,2206,3820,2370,1446,4207,2305,4498,7808,7809,4208,1055,2605, 484,3698,7810, # 6646 +3999, 625,4209,2273,3368,1499,4210,4000,7811,4001,4211,3222,2274,2275,3476,7812, # 6662 +7813,2764, 808,2606,3699,3369,4002,4212,3100,2532, 526,3370,3821,4213, 955,7814, # 6678 +1620,4214,2637,2427,7815,1429,3700,1669,1831, 994, 928,7816,3578,1260,7817,7818, # 6694 +7819,1948,2288, 741,2919,1626,4215,2729,2455, 867,1184, 362,3371,1392,7820,7821, # 6710 +4003,4216,1770,1736,3223,2920,4499,4500,1928,2698,1459,1158,7822,3050,3372,2877, # 6726 +1292,1929,2506,2842,3701,1985,1187,2071,2014,2607,4217,7823,2566,2507,2169,3702, # 6742 +2483,3299,7824,3703,4501,7825,7826, 666,1003,3005,1022,3579,4218,7827,4502,1813, # 6758 +2253, 574,3822,1603, 295,1535, 705,3823,4219, 283, 858, 417,7828,7829,3224,4503, # 6774 +4504,3051,1220,1889,1046,2276,2456,4004,1393,1599, 689,2567, 388,4220,7830,2484, # 6790 + 802,7831,2798,3824,2060,1405,2254,7832,4505,3825,2109,1052,1345,3225,1585,7833, # 6806 + 809,7834,7835,7836, 575,2730,3477, 956,1552,1469,1144,2323,7837,2324,1560,2457, # 6822 +3580,3226,4005, 616,2207,3155,2180,2289,7838,1832,7839,3478,4506,7840,1319,3704, # 6838 +3705,1211,3581,1023,3227,1293,2799,7841,7842,7843,3826, 607,2306,3827, 762,2878, # 6854 +1439,4221,1360,7844,1485,3052,7845,4507,1038,4222,1450,2061,2638,4223,1379,4508, # 6870 +2585,7846,7847,4224,1352,1414,2325,2921,1172,7848,7849,3828,3829,7850,1797,1451, # 6886 +7851,7852,7853,7854,2922,4006,4007,2485,2346, 411,4008,4009,3582,3300,3101,4509, # 6902 +1561,2664,1452,4010,1375,7855,7856, 47,2959, 316,7857,1406,1591,2923,3156,7858, # 6918 +1025,2141,3102,3157, 354,2731, 884,2224,4225,2407, 508,3706, 726,3583, 996,2428, # 6934 +3584, 729,7859, 392,2191,1453,4011,4510,3707,7860,7861,2458,3585,2608,1675,2800, # 6950 + 919,2347,2960,2348,1270,4511,4012, 73,7862,7863, 647,7864,3228,2843,2255,1550, # 6966 +1346,3006,7865,1332, 883,3479,7866,7867,7868,7869,3301,2765,7870,1212, 831,1347, # 6982 +4226,4512,2326,3830,1863,3053, 720,3831,4513,4514,3832,7871,4227,7872,7873,4515, # 6998 +7874,7875,1798,4516,3708,2609,4517,3586,1645,2371,7876,7877,2924, 669,2208,2665, # 7014 +2429,7878,2879,7879,7880,1028,3229,7881,4228,2408,7882,2256,1353,7883,7884,4518, # 7030 +3158, 518,7885,4013,7886,4229,1960,7887,2142,4230,7888,7889,3007,2349,2350,3833, # 7046 + 516,1833,1454,4014,2699,4231,4519,2225,2610,1971,1129,3587,7890,2766,7891,2961, # 7062 +1422, 577,1470,3008,1524,3373,7892,7893, 432,4232,3054,3480,7894,2586,1455,2508, # 7078 +2226,1972,1175,7895,1020,2732,4015,3481,4520,7896,2733,7897,1743,1361,3055,3482, # 7094 +2639,4016,4233,4521,2290, 895, 924,4234,2170, 331,2243,3056, 166,1627,3057,1098, # 7110 +7898,1232,2880,2227,3374,4522, 657, 403,1196,2372, 542,3709,3375,1600,4235,3483, # 7126 +7899,4523,2767,3230, 576, 530,1362,7900,4524,2533,2666,3710,4017,7901, 842,3834, # 7142 +7902,2801,2031,1014,4018, 213,2700,3376, 665, 621,4236,7903,3711,2925,2430,7904, # 7158 +2431,3302,3588,3377,7905,4237,2534,4238,4525,3589,1682,4239,3484,1380,7906, 724, # 7174 +2277, 600,1670,7907,1337,1233,4526,3103,2244,7908,1621,4527,7909, 651,4240,7910, # 7190 +1612,4241,2611,7911,2844,7912,2734,2307,3058,7913, 716,2459,3059, 174,1255,2701, # 7206 +4019,3590, 548,1320,1398, 728,4020,1574,7914,1890,1197,3060,4021,7915,3061,3062, # 7222 +3712,3591,3713, 747,7916, 635,4242,4528,7917,7918,7919,4243,7920,7921,4529,7922, # 7238 +3378,4530,2432, 451,7923,3714,2535,2072,4244,2735,4245,4022,7924,1764,4531,7925, # 7254 +4246, 350,7926,2278,2390,2486,7927,4247,4023,2245,1434,4024, 488,4532, 458,4248, # 7270 +4025,3715, 771,1330,2391,3835,2568,3159,2159,2409,1553,2667,3160,4249,7928,2487, # 7286 +2881,2612,1720,2702,4250,3379,4533,7929,2536,4251,7930,3231,4252,2768,7931,2015, # 7302 +2736,7932,1155,1017,3716,3836,7933,3303,2308, 201,1864,4253,1430,7934,4026,7935, # 7318 +7936,7937,7938,7939,4254,1604,7940, 414,1865, 371,2587,4534,4535,3485,2016,3104, # 7334 +4536,1708, 960,4255, 887, 389,2171,1536,1663,1721,7941,2228,4027,2351,2926,1580, # 7350 +7942,7943,7944,1744,7945,2537,4537,4538,7946,4539,7947,2073,7948,7949,3592,3380, # 7366 +2882,4256,7950,4257,2640,3381,2802, 673,2703,2460, 709,3486,4028,3593,4258,7951, # 7382 +1148, 502, 634,7952,7953,1204,4540,3594,1575,4541,2613,3717,7954,3718,3105, 948, # 7398 +3232, 121,1745,3837,1110,7955,4259,3063,2509,3009,4029,3719,1151,1771,3838,1488, # 7414 +4030,1986,7956,2433,3487,7957,7958,2093,7959,4260,3839,1213,1407,2803, 531,2737, # 7430 +2538,3233,1011,1537,7960,2769,4261,3106,1061,7961,3720,3721,1866,2883,7962,2017, # 7446 + 120,4262,4263,2062,3595,3234,2309,3840,2668,3382,1954,4542,7963,7964,3488,1047, # 7462 +2704,1266,7965,1368,4543,2845, 649,3383,3841,2539,2738,1102,2846,2669,7966,7967, # 7478 +1999,7968,1111,3596,2962,7969,2488,3842,3597,2804,1854,3384,3722,7970,7971,3385, # 7494 +2410,2884,3304,3235,3598,7972,2569,7973,3599,2805,4031,1460, 856,7974,3600,7975, # 7510 +2885,2963,7976,2886,3843,7977,4264, 632,2510, 875,3844,1697,3845,2291,7978,7979, # 7526 +4544,3010,1239, 580,4545,4265,7980, 914, 936,2074,1190,4032,1039,2123,7981,7982, # 7542 +7983,3386,1473,7984,1354,4266,3846,7985,2172,3064,4033, 915,3305,4267,4268,3306, # 7558 +1605,1834,7986,2739, 398,3601,4269,3847,4034, 328,1912,2847,4035,3848,1331,4270, # 7574 +3011, 937,4271,7987,3602,4036,4037,3387,2160,4546,3388, 524, 742, 538,3065,1012, # 7590 +7988,7989,3849,2461,7990, 658,1103, 225,3850,7991,7992,4547,7993,4548,7994,3236, # 7606 +1243,7995,4038, 963,2246,4549,7996,2705,3603,3161,7997,7998,2588,2327,7999,4550, # 7622 +8000,8001,8002,3489,3307, 957,3389,2540,2032,1930,2927,2462, 870,2018,3604,1746, # 7638 +2770,2771,2434,2463,8003,3851,8004,3723,3107,3724,3490,3390,3725,8005,1179,3066, # 7654 +8006,3162,2373,4272,3726,2541,3163,3108,2740,4039,8007,3391,1556,2542,2292, 977, # 7670 +2887,2033,4040,1205,3392,8008,1765,3393,3164,2124,1271,1689, 714,4551,3491,8009, # 7686 +2328,3852, 533,4273,3605,2181, 617,8010,2464,3308,3492,2310,8011,8012,3165,8013, # 7702 +8014,3853,1987, 618, 427,2641,3493,3394,8015,8016,1244,1690,8017,2806,4274,4552, # 7718 +8018,3494,8019,8020,2279,1576, 473,3606,4275,3395, 972,8021,3607,8022,3067,8023, # 7734 +8024,4553,4554,8025,3727,4041,4042,8026, 153,4555, 356,8027,1891,2888,4276,2143, # 7750 + 408, 803,2352,8028,3854,8029,4277,1646,2570,2511,4556,4557,3855,8030,3856,4278, # 7766 +8031,2411,3396, 752,8032,8033,1961,2964,8034, 746,3012,2465,8035,4279,3728, 698, # 7782 +4558,1892,4280,3608,2543,4559,3609,3857,8036,3166,3397,8037,1823,1302,4043,2706, # 7798 +3858,1973,4281,8038,4282,3167, 823,1303,1288,1236,2848,3495,4044,3398, 774,3859, # 7814 +8039,1581,4560,1304,2849,3860,4561,8040,2435,2161,1083,3237,4283,4045,4284, 344, # 7830 +1173, 288,2311, 454,1683,8041,8042,1461,4562,4046,2589,8043,8044,4563, 985, 894, # 7846 +8045,3399,3168,8046,1913,2928,3729,1988,8047,2110,1974,8048,4047,8049,2571,1194, # 7862 + 425,8050,4564,3169,1245,3730,4285,8051,8052,2850,8053, 636,4565,1855,3861, 760, # 7878 +1799,8054,4286,2209,1508,4566,4048,1893,1684,2293,8055,8056,8057,4287,4288,2210, # 7894 + 479,8058,8059, 832,8060,4049,2489,8061,2965,2490,3731, 990,3109, 627,1814,2642, # 7910 +4289,1582,4290,2125,2111,3496,4567,8062, 799,4291,3170,8063,4568,2112,1737,3013, # 7926 +1018, 543, 754,4292,3309,1676,4569,4570,4050,8064,1489,8065,3497,8066,2614,2889, # 7942 +4051,8067,8068,2966,8069,8070,8071,8072,3171,4571,4572,2182,1722,8073,3238,3239, # 7958 +1842,3610,1715, 481, 365,1975,1856,8074,8075,1962,2491,4573,8076,2126,3611,3240, # 7974 + 433,1894,2063,2075,8077, 602,2741,8078,8079,8080,8081,8082,3014,1628,3400,8083, # 7990 +3172,4574,4052,2890,4575,2512,8084,2544,2772,8085,8086,8087,3310,4576,2891,8088, # 8006 +4577,8089,2851,4578,4579,1221,2967,4053,2513,8090,8091,8092,1867,1989,8093,8094, # 8022 +8095,1895,8096,8097,4580,1896,4054, 318,8098,2094,4055,4293,8099,8100, 485,8101, # 8038 + 938,3862, 553,2670, 116,8102,3863,3612,8103,3498,2671,2773,3401,3311,2807,8104, # 8054 +3613,2929,4056,1747,2930,2968,8105,8106, 207,8107,8108,2672,4581,2514,8109,3015, # 8070 + 890,3614,3864,8110,1877,3732,3402,8111,2183,2353,3403,1652,8112,8113,8114, 941, # 8086 +2294, 208,3499,4057,2019, 330,4294,3865,2892,2492,3733,4295,8115,8116,8117,8118, # 8102 +) + diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/euctwprober.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/euctwprober.py new file mode 100644 index 0000000..35669cc --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/euctwprober.py @@ -0,0 +1,46 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import EUCTWDistributionAnalysis +from .mbcssm import EUCTW_SM_MODEL + +class EUCTWProber(MultiByteCharSetProber): + def __init__(self): + super(EUCTWProber, self).__init__() + self.coding_sm = CodingStateMachine(EUCTW_SM_MODEL) + self.distribution_analyzer = EUCTWDistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "EUC-TW" + + @property + def language(self): + return "Taiwan" diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/gb2312freq.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/gb2312freq.py new file mode 100644 index 0000000..697837b --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/gb2312freq.py @@ -0,0 +1,283 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# GB2312 most frequently used character table +# +# Char to FreqOrder table , from hz6763 + +# 512 --> 0.79 -- 0.79 +# 1024 --> 0.92 -- 0.13 +# 2048 --> 0.98 -- 0.06 +# 6768 --> 1.00 -- 0.02 +# +# Ideal Distribution Ratio = 0.79135/(1-0.79135) = 3.79 +# Random Distribution Ration = 512 / (3755 - 512) = 0.157 +# +# Typical Distribution Ratio about 25% of Ideal one, still much higher that RDR + +GB2312_TYPICAL_DISTRIBUTION_RATIO = 0.9 + +GB2312_TABLE_SIZE = 3760 + +GB2312_CHAR_TO_FREQ_ORDER = ( +1671, 749,1443,2364,3924,3807,2330,3921,1704,3463,2691,1511,1515, 572,3191,2205, +2361, 224,2558, 479,1711, 963,3162, 440,4060,1905,2966,2947,3580,2647,3961,3842, +2204, 869,4207, 970,2678,5626,2944,2956,1479,4048, 514,3595, 588,1346,2820,3409, + 249,4088,1746,1873,2047,1774, 581,1813, 358,1174,3590,1014,1561,4844,2245, 670, +1636,3112, 889,1286, 953, 556,2327,3060,1290,3141, 613, 185,3477,1367, 850,3820, +1715,2428,2642,2303,2732,3041,2562,2648,3566,3946,1349, 388,3098,2091,1360,3585, + 152,1687,1539, 738,1559, 59,1232,2925,2267,1388,1249,1741,1679,2960, 151,1566, +1125,1352,4271, 924,4296, 385,3166,4459, 310,1245,2850, 70,3285,2729,3534,3575, +2398,3298,3466,1960,2265, 217,3647, 864,1909,2084,4401,2773,1010,3269,5152, 853, +3051,3121,1244,4251,1895, 364,1499,1540,2313,1180,3655,2268, 562, 715,2417,3061, + 544, 336,3768,2380,1752,4075, 950, 280,2425,4382, 183,2759,3272, 333,4297,2155, +1688,2356,1444,1039,4540, 736,1177,3349,2443,2368,2144,2225, 565, 196,1482,3406, + 927,1335,4147, 692, 878,1311,1653,3911,3622,1378,4200,1840,2969,3149,2126,1816, +2534,1546,2393,2760, 737,2494, 13, 447, 245,2747, 38,2765,2129,2589,1079, 606, + 360, 471,3755,2890, 404, 848, 699,1785,1236, 370,2221,1023,3746,2074,2026,2023, +2388,1581,2119, 812,1141,3091,2536,1519, 804,2053, 406,1596,1090, 784, 548,4414, +1806,2264,2936,1100, 343,4114,5096, 622,3358, 743,3668,1510,1626,5020,3567,2513, +3195,4115,5627,2489,2991, 24,2065,2697,1087,2719, 48,1634, 315, 68, 985,2052, + 198,2239,1347,1107,1439, 597,2366,2172, 871,3307, 919,2487,2790,1867, 236,2570, +1413,3794, 906,3365,3381,1701,1982,1818,1524,2924,1205, 616,2586,2072,2004, 575, + 253,3099, 32,1365,1182, 197,1714,2454,1201, 554,3388,3224,2748, 756,2587, 250, +2567,1507,1517,3529,1922,2761,2337,3416,1961,1677,2452,2238,3153, 615, 911,1506, +1474,2495,1265,1906,2749,3756,3280,2161, 898,2714,1759,3450,2243,2444, 563, 26, +3286,2266,3769,3344,2707,3677, 611,1402, 531,1028,2871,4548,1375, 261,2948, 835, +1190,4134, 353, 840,2684,1900,3082,1435,2109,1207,1674, 329,1872,2781,4055,2686, +2104, 608,3318,2423,2957,2768,1108,3739,3512,3271,3985,2203,1771,3520,1418,2054, +1681,1153, 225,1627,2929, 162,2050,2511,3687,1954, 124,1859,2431,1684,3032,2894, + 585,4805,3969,2869,2704,2088,2032,2095,3656,2635,4362,2209, 256, 518,2042,2105, +3777,3657, 643,2298,1148,1779, 190, 989,3544, 414, 11,2135,2063,2979,1471, 403, +3678, 126, 770,1563, 671,2499,3216,2877, 600,1179, 307,2805,4937,1268,1297,2694, + 252,4032,1448,1494,1331,1394, 127,2256, 222,1647,1035,1481,3056,1915,1048, 873, +3651, 210, 33,1608,2516, 200,1520, 415, 102, 0,3389,1287, 817, 91,3299,2940, + 836,1814, 549,2197,1396,1669,2987,3582,2297,2848,4528,1070, 687, 20,1819, 121, +1552,1364,1461,1968,2617,3540,2824,2083, 177, 948,4938,2291, 110,4549,2066, 648, +3359,1755,2110,2114,4642,4845,1693,3937,3308,1257,1869,2123, 208,1804,3159,2992, +2531,2549,3361,2418,1350,2347,2800,2568,1291,2036,2680, 72, 842,1990, 212,1233, +1154,1586, 75,2027,3410,4900,1823,1337,2710,2676, 728,2810,1522,3026,4995, 157, + 755,1050,4022, 710, 785,1936,2194,2085,1406,2777,2400, 150,1250,4049,1206, 807, +1910, 534, 529,3309,1721,1660, 274, 39,2827, 661,2670,1578, 925,3248,3815,1094, +4278,4901,4252, 41,1150,3747,2572,2227,4501,3658,4902,3813,3357,3617,2884,2258, + 887, 538,4187,3199,1294,2439,3042,2329,2343,2497,1255, 107, 543,1527, 521,3478, +3568, 194,5062, 15, 961,3870,1241,1192,2664, 66,5215,3260,2111,1295,1127,2152, +3805,4135, 901,1164,1976, 398,1278, 530,1460, 748, 904,1054,1966,1426, 53,2909, + 509, 523,2279,1534, 536,1019, 239,1685, 460,2353, 673,1065,2401,3600,4298,2272, +1272,2363, 284,1753,3679,4064,1695, 81, 815,2677,2757,2731,1386, 859, 500,4221, +2190,2566, 757,1006,2519,2068,1166,1455, 337,2654,3203,1863,1682,1914,3025,1252, +1409,1366, 847, 714,2834,2038,3209, 964,2970,1901, 885,2553,1078,1756,3049, 301, +1572,3326, 688,2130,1996,2429,1805,1648,2930,3421,2750,3652,3088, 262,1158,1254, + 389,1641,1812, 526,1719, 923,2073,1073,1902, 468, 489,4625,1140, 857,2375,3070, +3319,2863, 380, 116,1328,2693,1161,2244, 273,1212,1884,2769,3011,1775,1142, 461, +3066,1200,2147,2212, 790, 702,2695,4222,1601,1058, 434,2338,5153,3640, 67,2360, +4099,2502, 618,3472,1329, 416,1132, 830,2782,1807,2653,3211,3510,1662, 192,2124, + 296,3979,1739,1611,3684, 23, 118, 324, 446,1239,1225, 293,2520,3814,3795,2535, +3116, 17,1074, 467,2692,2201, 387,2922, 45,1326,3055,1645,3659,2817, 958, 243, +1903,2320,1339,2825,1784,3289, 356, 576, 865,2315,2381,3377,3916,1088,3122,1713, +1655, 935, 628,4689,1034,1327, 441, 800, 720, 894,1979,2183,1528,5289,2702,1071, +4046,3572,2399,1571,3281, 79, 761,1103, 327, 134, 758,1899,1371,1615, 879, 442, + 215,2605,2579, 173,2048,2485,1057,2975,3317,1097,2253,3801,4263,1403,1650,2946, + 814,4968,3487,1548,2644,1567,1285, 2, 295,2636, 97, 946,3576, 832, 141,4257, +3273, 760,3821,3521,3156,2607, 949,1024,1733,1516,1803,1920,2125,2283,2665,3180, +1501,2064,3560,2171,1592, 803,3518,1416, 732,3897,4258,1363,1362,2458, 119,1427, + 602,1525,2608,1605,1639,3175, 694,3064, 10, 465, 76,2000,4846,4208, 444,3781, +1619,3353,2206,1273,3796, 740,2483, 320,1723,2377,3660,2619,1359,1137,1762,1724, +2345,2842,1850,1862, 912, 821,1866, 612,2625,1735,2573,3369,1093, 844, 89, 937, + 930,1424,3564,2413,2972,1004,3046,3019,2011, 711,3171,1452,4178, 428, 801,1943, + 432, 445,2811, 206,4136,1472, 730, 349, 73, 397,2802,2547, 998,1637,1167, 789, + 396,3217, 154,1218, 716,1120,1780,2819,4826,1931,3334,3762,2139,1215,2627, 552, +3664,3628,3232,1405,2383,3111,1356,2652,3577,3320,3101,1703, 640,1045,1370,1246, +4996, 371,1575,2436,1621,2210, 984,4033,1734,2638, 16,4529, 663,2755,3255,1451, +3917,2257,1253,1955,2234,1263,2951, 214,1229, 617, 485, 359,1831,1969, 473,2310, + 750,2058, 165, 80,2864,2419, 361,4344,2416,2479,1134, 796,3726,1266,2943, 860, +2715, 938, 390,2734,1313,1384, 248, 202, 877,1064,2854, 522,3907, 279,1602, 297, +2357, 395,3740, 137,2075, 944,4089,2584,1267,3802, 62,1533,2285, 178, 176, 780, +2440, 201,3707, 590, 478,1560,4354,2117,1075, 30, 74,4643,4004,1635,1441,2745, + 776,2596, 238,1077,1692,1912,2844, 605, 499,1742,3947, 241,3053, 980,1749, 936, +2640,4511,2582, 515,1543,2162,5322,2892,2993, 890,2148,1924, 665,1827,3581,1032, + 968,3163, 339,1044,1896, 270, 583,1791,1720,4367,1194,3488,3669, 43,2523,1657, + 163,2167, 290,1209,1622,3378, 550, 634,2508,2510, 695,2634,2384,2512,1476,1414, + 220,1469,2341,2138,2852,3183,2900,4939,2865,3502,1211,3680, 854,3227,1299,2976, +3172, 186,2998,1459, 443,1067,3251,1495, 321,1932,3054, 909, 753,1410,1828, 436, +2441,1119,1587,3164,2186,1258, 227, 231,1425,1890,3200,3942, 247, 959, 725,5254, +2741, 577,2158,2079, 929, 120, 174, 838,2813, 591,1115, 417,2024, 40,3240,1536, +1037, 291,4151,2354, 632,1298,2406,2500,3535,1825,1846,3451, 205,1171, 345,4238, + 18,1163, 811, 685,2208,1217, 425,1312,1508,1175,4308,2552,1033, 587,1381,3059, +2984,3482, 340,1316,4023,3972, 792,3176, 519, 777,4690, 918, 933,4130,2981,3741, + 90,3360,2911,2200,5184,4550, 609,3079,2030, 272,3379,2736, 363,3881,1130,1447, + 286, 779, 357,1169,3350,3137,1630,1220,2687,2391, 747,1277,3688,2618,2682,2601, +1156,3196,5290,4034,3102,1689,3596,3128, 874, 219,2783, 798, 508,1843,2461, 269, +1658,1776,1392,1913,2983,3287,2866,2159,2372, 829,4076, 46,4253,2873,1889,1894, + 915,1834,1631,2181,2318, 298, 664,2818,3555,2735, 954,3228,3117, 527,3511,2173, + 681,2712,3033,2247,2346,3467,1652, 155,2164,3382, 113,1994, 450, 899, 494, 994, +1237,2958,1875,2336,1926,3727, 545,1577,1550, 633,3473, 204,1305,3072,2410,1956, +2471, 707,2134, 841,2195,2196,2663,3843,1026,4940, 990,3252,4997, 368,1092, 437, +3212,3258,1933,1829, 675,2977,2893, 412, 943,3723,4644,3294,3283,2230,2373,5154, +2389,2241,2661,2323,1404,2524, 593, 787, 677,3008,1275,2059, 438,2709,2609,2240, +2269,2246,1446, 36,1568,1373,3892,1574,2301,1456,3962, 693,2276,5216,2035,1143, +2720,1919,1797,1811,2763,4137,2597,1830,1699,1488,1198,2090, 424,1694, 312,3634, +3390,4179,3335,2252,1214, 561,1059,3243,2295,2561, 975,5155,2321,2751,3772, 472, +1537,3282,3398,1047,2077,2348,2878,1323,3340,3076, 690,2906, 51, 369, 170,3541, +1060,2187,2688,3670,2541,1083,1683, 928,3918, 459, 109,4427, 599,3744,4286, 143, +2101,2730,2490, 82,1588,3036,2121, 281,1860, 477,4035,1238,2812,3020,2716,3312, +1530,2188,2055,1317, 843, 636,1808,1173,3495, 649, 181,1002, 147,3641,1159,2414, +3750,2289,2795, 813,3123,2610,1136,4368, 5,3391,4541,2174, 420, 429,1728, 754, +1228,2115,2219, 347,2223,2733, 735,1518,3003,2355,3134,1764,3948,3329,1888,2424, +1001,1234,1972,3321,3363,1672,1021,1450,1584, 226, 765, 655,2526,3404,3244,2302, +3665, 731, 594,2184, 319,1576, 621, 658,2656,4299,2099,3864,1279,2071,2598,2739, + 795,3086,3699,3908,1707,2352,2402,1382,3136,2475,1465,4847,3496,3865,1085,3004, +2591,1084, 213,2287,1963,3565,2250, 822, 793,4574,3187,1772,1789,3050, 595,1484, +1959,2770,1080,2650, 456, 422,2996, 940,3322,4328,4345,3092,2742, 965,2784, 739, +4124, 952,1358,2498,2949,2565, 332,2698,2378, 660,2260,2473,4194,3856,2919, 535, +1260,2651,1208,1428,1300,1949,1303,2942, 433,2455,2450,1251,1946, 614,1269, 641, +1306,1810,2737,3078,2912, 564,2365,1419,1415,1497,4460,2367,2185,1379,3005,1307, +3218,2175,1897,3063, 682,1157,4040,4005,1712,1160,1941,1399, 394, 402,2952,1573, +1151,2986,2404, 862, 299,2033,1489,3006, 346, 171,2886,3401,1726,2932, 168,2533, + 47,2507,1030,3735,1145,3370,1395,1318,1579,3609,4560,2857,4116,1457,2529,1965, + 504,1036,2690,2988,2405, 745,5871, 849,2397,2056,3081, 863,2359,3857,2096, 99, +1397,1769,2300,4428,1643,3455,1978,1757,3718,1440, 35,4879,3742,1296,4228,2280, + 160,5063,1599,2013, 166, 520,3479,1646,3345,3012, 490,1937,1545,1264,2182,2505, +1096,1188,1369,1436,2421,1667,2792,2460,1270,2122, 727,3167,2143, 806,1706,1012, +1800,3037, 960,2218,1882, 805, 139,2456,1139,1521, 851,1052,3093,3089, 342,2039, + 744,5097,1468,1502,1585,2087, 223, 939, 326,2140,2577, 892,2481,1623,4077, 982, +3708, 135,2131, 87,2503,3114,2326,1106, 876,1616, 547,2997,2831,2093,3441,4530, +4314, 9,3256,4229,4148, 659,1462,1986,1710,2046,2913,2231,4090,4880,5255,3392, +3274,1368,3689,4645,1477, 705,3384,3635,1068,1529,2941,1458,3782,1509, 100,1656, +2548, 718,2339, 408,1590,2780,3548,1838,4117,3719,1345,3530, 717,3442,2778,3220, +2898,1892,4590,3614,3371,2043,1998,1224,3483, 891, 635, 584,2559,3355, 733,1766, +1729,1172,3789,1891,2307, 781,2982,2271,1957,1580,5773,2633,2005,4195,3097,1535, +3213,1189,1934,5693,3262, 586,3118,1324,1598, 517,1564,2217,1868,1893,4445,3728, +2703,3139,1526,1787,1992,3882,2875,1549,1199,1056,2224,1904,2711,5098,4287, 338, +1993,3129,3489,2689,1809,2815,1997, 957,1855,3898,2550,3275,3057,1105,1319, 627, +1505,1911,1883,3526, 698,3629,3456,1833,1431, 746, 77,1261,2017,2296,1977,1885, + 125,1334,1600, 525,1798,1109,2222,1470,1945, 559,2236,1186,3443,2476,1929,1411, +2411,3135,1777,3372,2621,1841,1613,3229, 668,1430,1839,2643,2916, 195,1989,2671, +2358,1387, 629,3205,2293,5256,4439, 123,1310, 888,1879,4300,3021,3605,1003,1162, +3192,2910,2010, 140,2395,2859, 55,1082,2012,2901, 662, 419,2081,1438, 680,2774, +4654,3912,1620,1731,1625,5035,4065,2328, 512,1344, 802,5443,2163,2311,2537, 524, +3399, 98,1155,2103,1918,2606,3925,2816,1393,2465,1504,3773,2177,3963,1478,4346, + 180,1113,4655,3461,2028,1698, 833,2696,1235,1322,1594,4408,3623,3013,3225,2040, +3022, 541,2881, 607,3632,2029,1665,1219, 639,1385,1686,1099,2803,3231,1938,3188, +2858, 427, 676,2772,1168,2025, 454,3253,2486,3556, 230,1950, 580, 791,1991,1280, +1086,1974,2034, 630, 257,3338,2788,4903,1017, 86,4790, 966,2789,1995,1696,1131, + 259,3095,4188,1308, 179,1463,5257, 289,4107,1248, 42,3413,1725,2288, 896,1947, + 774,4474,4254, 604,3430,4264, 392,2514,2588, 452, 237,1408,3018, 988,4531,1970, +3034,3310, 540,2370,1562,1288,2990, 502,4765,1147, 4,1853,2708, 207, 294,2814, +4078,2902,2509, 684, 34,3105,3532,2551, 644, 709,2801,2344, 573,1727,3573,3557, +2021,1081,3100,4315,2100,3681, 199,2263,1837,2385, 146,3484,1195,2776,3949, 997, +1939,3973,1008,1091,1202,1962,1847,1149,4209,5444,1076, 493, 117,5400,2521, 972, +1490,2934,1796,4542,2374,1512,2933,2657, 413,2888,1135,2762,2314,2156,1355,2369, + 766,2007,2527,2170,3124,2491,2593,2632,4757,2437, 234,3125,3591,1898,1750,1376, +1942,3468,3138, 570,2127,2145,3276,4131, 962, 132,1445,4196, 19, 941,3624,3480, +3366,1973,1374,4461,3431,2629, 283,2415,2275, 808,2887,3620,2112,2563,1353,3610, + 955,1089,3103,1053, 96, 88,4097, 823,3808,1583, 399, 292,4091,3313, 421,1128, + 642,4006, 903,2539,1877,2082, 596, 29,4066,1790, 722,2157, 130, 995,1569, 769, +1485, 464, 513,2213, 288,1923,1101,2453,4316, 133, 486,2445, 50, 625, 487,2207, + 57, 423, 481,2962, 159,3729,1558, 491, 303, 482, 501, 240,2837, 112,3648,2392, +1783, 362, 8,3433,3422, 610,2793,3277,1390,1284,1654, 21,3823, 734, 367, 623, + 193, 287, 374,1009,1483, 816, 476, 313,2255,2340,1262,2150,2899,1146,2581, 782, +2116,1659,2018,1880, 255,3586,3314,1110,2867,2137,2564, 986,2767,5185,2006, 650, + 158, 926, 762, 881,3157,2717,2362,3587, 306,3690,3245,1542,3077,2427,1691,2478, +2118,2985,3490,2438, 539,2305, 983, 129,1754, 355,4201,2386, 827,2923, 104,1773, +2838,2771, 411,2905,3919, 376, 767, 122,1114, 828,2422,1817,3506, 266,3460,1007, +1609,4998, 945,2612,4429,2274, 726,1247,1964,2914,2199,2070,4002,4108, 657,3323, +1422, 579, 455,2764,4737,1222,2895,1670, 824,1223,1487,2525, 558, 861,3080, 598, +2659,2515,1967, 752,2583,2376,2214,4180, 977, 704,2464,4999,2622,4109,1210,2961, + 819,1541, 142,2284, 44, 418, 457,1126,3730,4347,4626,1644,1876,3671,1864, 302, +1063,5694, 624, 723,1984,3745,1314,1676,2488,1610,1449,3558,3569,2166,2098, 409, +1011,2325,3704,2306, 818,1732,1383,1824,1844,3757, 999,2705,3497,1216,1423,2683, +2426,2954,2501,2726,2229,1475,2554,5064,1971,1794,1666,2014,1343, 783, 724, 191, +2434,1354,2220,5065,1763,2752,2472,4152, 131, 175,2885,3434, 92,1466,4920,2616, +3871,3872,3866, 128,1551,1632, 669,1854,3682,4691,4125,1230, 188,2973,3290,1302, +1213, 560,3266, 917, 763,3909,3249,1760, 868,1958, 764,1782,2097, 145,2277,3774, +4462, 64,1491,3062, 971,2132,3606,2442, 221,1226,1617, 218, 323,1185,3207,3147, + 571, 619,1473,1005,1744,2281, 449,1887,2396,3685, 275, 375,3816,1743,3844,3731, + 845,1983,2350,4210,1377, 773, 967,3499,3052,3743,2725,4007,1697,1022,3943,1464, +3264,2855,2722,1952,1029,2839,2467, 84,4383,2215, 820,1391,2015,2448,3672, 377, +1948,2168, 797,2545,3536,2578,2645, 94,2874,1678, 405,1259,3071, 771, 546,1315, + 470,1243,3083, 895,2468, 981, 969,2037, 846,4181, 653,1276,2928, 14,2594, 557, +3007,2474, 156, 902,1338,1740,2574, 537,2518, 973,2282,2216,2433,1928, 138,2903, +1293,2631,1612, 646,3457, 839,2935, 111, 496,2191,2847, 589,3186, 149,3994,2060, +4031,2641,4067,3145,1870, 37,3597,2136,1025,2051,3009,3383,3549,1121,1016,3261, +1301, 251,2446,2599,2153, 872,3246, 637, 334,3705, 831, 884, 921,3065,3140,4092, +2198,1944, 246,2964, 108,2045,1152,1921,2308,1031, 203,3173,4170,1907,3890, 810, +1401,2003,1690, 506, 647,1242,2828,1761,1649,3208,2249,1589,3709,2931,5156,1708, + 498, 666,2613, 834,3817,1231, 184,2851,1124, 883,3197,2261,3710,1765,1553,2658, +1178,2639,2351, 93,1193, 942,2538,2141,4402, 235,1821, 870,1591,2192,1709,1871, +3341,1618,4126,2595,2334, 603, 651, 69, 701, 268,2662,3411,2555,1380,1606, 503, + 448, 254,2371,2646, 574,1187,2309,1770, 322,2235,1292,1801, 305, 566,1133, 229, +2067,2057, 706, 167, 483,2002,2672,3295,1820,3561,3067, 316, 378,2746,3452,1112, + 136,1981, 507,1651,2917,1117, 285,4591, 182,2580,3522,1304, 335,3303,1835,2504, +1795,1792,2248, 674,1018,2106,2449,1857,2292,2845, 976,3047,1781,2600,2727,1389, +1281, 52,3152, 153, 265,3950, 672,3485,3951,4463, 430,1183, 365, 278,2169, 27, +1407,1336,2304, 209,1340,1730,2202,1852,2403,2883, 979,1737,1062, 631,2829,2542, +3876,2592, 825,2086,2226,3048,3625, 352,1417,3724, 542, 991, 431,1351,3938,1861, +2294, 826,1361,2927,3142,3503,1738, 463,2462,2723, 582,1916,1595,2808, 400,3845, +3891,2868,3621,2254, 58,2492,1123, 910,2160,2614,1372,1603,1196,1072,3385,1700, +3267,1980, 696, 480,2430, 920, 799,1570,2920,1951,2041,4047,2540,1321,4223,2469, +3562,2228,1271,2602, 401,2833,3351,2575,5157, 907,2312,1256, 410, 263,3507,1582, + 996, 678,1849,2316,1480, 908,3545,2237, 703,2322, 667,1826,2849,1531,2604,2999, +2407,3146,2151,2630,1786,3711, 469,3542, 497,3899,2409, 858, 837,4446,3393,1274, + 786, 620,1845,2001,3311, 484, 308,3367,1204,1815,3691,2332,1532,2557,1842,2020, +2724,1927,2333,4440, 567, 22,1673,2728,4475,1987,1858,1144,1597, 101,1832,3601, + 12, 974,3783,4391, 951,1412, 1,3720, 453,4608,4041, 528,1041,1027,3230,2628, +1129, 875,1051,3291,1203,2262,1069,2860,2799,2149,2615,3278, 144,1758,3040, 31, + 475,1680, 366,2685,3184, 311,1642,4008,2466,5036,1593,1493,2809, 216,1420,1668, + 233, 304,2128,3284, 232,1429,1768,1040,2008,3407,2740,2967,2543, 242,2133, 778, +1565,2022,2620, 505,2189,2756,1098,2273, 372,1614, 708, 553,2846,2094,2278, 169, +3626,2835,4161, 228,2674,3165, 809,1454,1309, 466,1705,1095, 900,3423, 880,2667, +3751,5258,2317,3109,2571,4317,2766,1503,1342, 866,4447,1118, 63,2076, 314,1881, +1348,1061, 172, 978,3515,1747, 532, 511,3970, 6, 601, 905,2699,3300,1751, 276, +1467,3725,2668, 65,4239,2544,2779,2556,1604, 578,2451,1802, 992,2331,2624,1320, +3446, 713,1513,1013, 103,2786,2447,1661, 886,1702, 916, 654,3574,2031,1556, 751, +2178,2821,2179,1498,1538,2176, 271, 914,2251,2080,1325, 638,1953,2937,3877,2432, +2754, 95,3265,1716, 260,1227,4083, 775, 106,1357,3254, 426,1607, 555,2480, 772, +1985, 244,2546, 474, 495,1046,2611,1851,2061, 71,2089,1675,2590, 742,3758,2843, +3222,1433, 267,2180,2576,2826,2233,2092,3913,2435, 956,1745,3075, 856,2113,1116, + 451, 3,1988,2896,1398, 993,2463,1878,2049,1341,2718,2721,2870,2108, 712,2904, +4363,2753,2324, 277,2872,2349,2649, 384, 987, 435, 691,3000, 922, 164,3939, 652, +1500,1184,4153,2482,3373,2165,4848,2335,3775,3508,3154,2806,2830,1554,2102,1664, +2530,1434,2408, 893,1547,2623,3447,2832,2242,2532,3169,2856,3223,2078, 49,3770, +3469, 462, 318, 656,2259,3250,3069, 679,1629,2758, 344,1138,1104,3120,1836,1283, +3115,2154,1437,4448, 934, 759,1999, 794,2862,1038, 533,2560,1722,2342, 855,2626, +1197,1663,4476,3127, 85,4240,2528, 25,1111,1181,3673, 407,3470,4561,2679,2713, + 768,1925,2841,3986,1544,1165, 932, 373,1240,2146,1930,2673, 721,4766, 354,4333, + 391,2963, 187, 61,3364,1442,1102, 330,1940,1767, 341,3809,4118, 393,2496,2062, +2211, 105, 331, 300, 439, 913,1332, 626, 379,3304,1557, 328, 689,3952, 309,1555, + 931, 317,2517,3027, 325, 569, 686,2107,3084, 60,1042,1333,2794, 264,3177,4014, +1628, 258,3712, 7,4464,1176,1043,1778, 683, 114,1975, 78,1492, 383,1886, 510, + 386, 645,5291,2891,2069,3305,4138,3867,2939,2603,2493,1935,1066,1848,3588,1015, +1282,1289,4609, 697,1453,3044,2666,3611,1856,2412, 54, 719,1330, 568,3778,2459, +1748, 788, 492, 551,1191,1000, 488,3394,3763, 282,1799, 348,2016,1523,3155,2390, +1049, 382,2019,1788,1170, 729,2968,3523, 897,3926,2785,2938,3292, 350,2319,3238, +1718,1717,2655,3453,3143,4465, 161,2889,2980,2009,1421, 56,1908,1640,2387,2232, +1917,1874,2477,4921, 148, 83,3438, 592,4245,2882,1822,1055, 741, 115,1496,1624, + 381,1638,4592,1020, 516,3214, 458, 947,4575,1432, 211,1514,2926,1865,2142, 189, + 852,1221,1400,1486, 882,2299,4036, 351, 28,1122, 700,6479,6480,6481,6482,6483, #last 512 +) + diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/gb2312prober.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/gb2312prober.py new file mode 100644 index 0000000..8446d2d --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/gb2312prober.py @@ -0,0 +1,46 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import GB2312DistributionAnalysis +from .mbcssm import GB2312_SM_MODEL + +class GB2312Prober(MultiByteCharSetProber): + def __init__(self): + super(GB2312Prober, self).__init__() + self.coding_sm = CodingStateMachine(GB2312_SM_MODEL) + self.distribution_analyzer = GB2312DistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "GB2312" + + @property + def language(self): + return "Chinese" diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/hebrewprober.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/hebrewprober.py new file mode 100644 index 0000000..b0e1bf4 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/hebrewprober.py @@ -0,0 +1,292 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Shy Shalom +# Portions created by the Initial Developer are Copyright (C) 2005 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState + +# This prober doesn't actually recognize a language or a charset. +# It is a helper prober for the use of the Hebrew model probers + +### General ideas of the Hebrew charset recognition ### +# +# Four main charsets exist in Hebrew: +# "ISO-8859-8" - Visual Hebrew +# "windows-1255" - Logical Hebrew +# "ISO-8859-8-I" - Logical Hebrew +# "x-mac-hebrew" - ?? Logical Hebrew ?? +# +# Both "ISO" charsets use a completely identical set of code points, whereas +# "windows-1255" and "x-mac-hebrew" are two different proper supersets of +# these code points. windows-1255 defines additional characters in the range +# 0x80-0x9F as some misc punctuation marks as well as some Hebrew-specific +# diacritics and additional 'Yiddish' ligature letters in the range 0xc0-0xd6. +# x-mac-hebrew defines similar additional code points but with a different +# mapping. +# +# As far as an average Hebrew text with no diacritics is concerned, all four +# charsets are identical with respect to code points. Meaning that for the +# main Hebrew alphabet, all four map the same values to all 27 Hebrew letters +# (including final letters). +# +# The dominant difference between these charsets is their directionality. +# "Visual" directionality means that the text is ordered as if the renderer is +# not aware of a BIDI rendering algorithm. The renderer sees the text and +# draws it from left to right. The text itself when ordered naturally is read +# backwards. A buffer of Visual Hebrew generally looks like so: +# "[last word of first line spelled backwards] [whole line ordered backwards +# and spelled backwards] [first word of first line spelled backwards] +# [end of line] [last word of second line] ... etc' " +# adding punctuation marks, numbers and English text to visual text is +# naturally also "visual" and from left to right. +# +# "Logical" directionality means the text is ordered "naturally" according to +# the order it is read. It is the responsibility of the renderer to display +# the text from right to left. A BIDI algorithm is used to place general +# punctuation marks, numbers and English text in the text. +# +# Texts in x-mac-hebrew are almost impossible to find on the Internet. From +# what little evidence I could find, it seems that its general directionality +# is Logical. +# +# To sum up all of the above, the Hebrew probing mechanism knows about two +# charsets: +# Visual Hebrew - "ISO-8859-8" - backwards text - Words and sentences are +# backwards while line order is natural. For charset recognition purposes +# the line order is unimportant (In fact, for this implementation, even +# word order is unimportant). +# Logical Hebrew - "windows-1255" - normal, naturally ordered text. +# +# "ISO-8859-8-I" is a subset of windows-1255 and doesn't need to be +# specifically identified. +# "x-mac-hebrew" is also identified as windows-1255. A text in x-mac-hebrew +# that contain special punctuation marks or diacritics is displayed with +# some unconverted characters showing as question marks. This problem might +# be corrected using another model prober for x-mac-hebrew. Due to the fact +# that x-mac-hebrew texts are so rare, writing another model prober isn't +# worth the effort and performance hit. +# +#### The Prober #### +# +# The prober is divided between two SBCharSetProbers and a HebrewProber, +# all of which are managed, created, fed data, inquired and deleted by the +# SBCSGroupProber. The two SBCharSetProbers identify that the text is in +# fact some kind of Hebrew, Logical or Visual. The final decision about which +# one is it is made by the HebrewProber by combining final-letter scores +# with the scores of the two SBCharSetProbers to produce a final answer. +# +# The SBCSGroupProber is responsible for stripping the original text of HTML +# tags, English characters, numbers, low-ASCII punctuation characters, spaces +# and new lines. It reduces any sequence of such characters to a single space. +# The buffer fed to each prober in the SBCS group prober is pure text in +# high-ASCII. +# The two SBCharSetProbers (model probers) share the same language model: +# Win1255Model. +# The first SBCharSetProber uses the model normally as any other +# SBCharSetProber does, to recognize windows-1255, upon which this model was +# built. The second SBCharSetProber is told to make the pair-of-letter +# lookup in the language model backwards. This in practice exactly simulates +# a visual Hebrew model using the windows-1255 logical Hebrew model. +# +# The HebrewProber is not using any language model. All it does is look for +# final-letter evidence suggesting the text is either logical Hebrew or visual +# Hebrew. Disjointed from the model probers, the results of the HebrewProber +# alone are meaningless. HebrewProber always returns 0.00 as confidence +# since it never identifies a charset by itself. Instead, the pointer to the +# HebrewProber is passed to the model probers as a helper "Name Prober". +# When the Group prober receives a positive identification from any prober, +# it asks for the name of the charset identified. If the prober queried is a +# Hebrew model prober, the model prober forwards the call to the +# HebrewProber to make the final decision. In the HebrewProber, the +# decision is made according to the final-letters scores maintained and Both +# model probers scores. The answer is returned in the form of the name of the +# charset identified, either "windows-1255" or "ISO-8859-8". + +class HebrewProber(CharSetProber): + # windows-1255 / ISO-8859-8 code points of interest + FINAL_KAF = 0xea + NORMAL_KAF = 0xeb + FINAL_MEM = 0xed + NORMAL_MEM = 0xee + FINAL_NUN = 0xef + NORMAL_NUN = 0xf0 + FINAL_PE = 0xf3 + NORMAL_PE = 0xf4 + FINAL_TSADI = 0xf5 + NORMAL_TSADI = 0xf6 + + # Minimum Visual vs Logical final letter score difference. + # If the difference is below this, don't rely solely on the final letter score + # distance. + MIN_FINAL_CHAR_DISTANCE = 5 + + # Minimum Visual vs Logical model score difference. + # If the difference is below this, don't rely at all on the model score + # distance. + MIN_MODEL_DISTANCE = 0.01 + + VISUAL_HEBREW_NAME = "ISO-8859-8" + LOGICAL_HEBREW_NAME = "windows-1255" + + def __init__(self): + super(HebrewProber, self).__init__() + self._final_char_logical_score = None + self._final_char_visual_score = None + self._prev = None + self._before_prev = None + self._logical_prober = None + self._visual_prober = None + self.reset() + + def reset(self): + self._final_char_logical_score = 0 + self._final_char_visual_score = 0 + # The two last characters seen in the previous buffer, + # mPrev and mBeforePrev are initialized to space in order to simulate + # a word delimiter at the beginning of the data + self._prev = ' ' + self._before_prev = ' ' + # These probers are owned by the group prober. + + def set_model_probers(self, logicalProber, visualProber): + self._logical_prober = logicalProber + self._visual_prober = visualProber + + def is_final(self, c): + return c in [self.FINAL_KAF, self.FINAL_MEM, self.FINAL_NUN, + self.FINAL_PE, self.FINAL_TSADI] + + def is_non_final(self, c): + # The normal Tsadi is not a good Non-Final letter due to words like + # 'lechotet' (to chat) containing an apostrophe after the tsadi. This + # apostrophe is converted to a space in FilterWithoutEnglishLetters + # causing the Non-Final tsadi to appear at an end of a word even + # though this is not the case in the original text. + # The letters Pe and Kaf rarely display a related behavior of not being + # a good Non-Final letter. Words like 'Pop', 'Winamp' and 'Mubarak' + # for example legally end with a Non-Final Pe or Kaf. However, the + # benefit of these letters as Non-Final letters outweighs the damage + # since these words are quite rare. + return c in [self.NORMAL_KAF, self.NORMAL_MEM, + self.NORMAL_NUN, self.NORMAL_PE] + + def feed(self, byte_str): + # Final letter analysis for logical-visual decision. + # Look for evidence that the received buffer is either logical Hebrew + # or visual Hebrew. + # The following cases are checked: + # 1) A word longer than 1 letter, ending with a final letter. This is + # an indication that the text is laid out "naturally" since the + # final letter really appears at the end. +1 for logical score. + # 2) A word longer than 1 letter, ending with a Non-Final letter. In + # normal Hebrew, words ending with Kaf, Mem, Nun, Pe or Tsadi, + # should not end with the Non-Final form of that letter. Exceptions + # to this rule are mentioned above in isNonFinal(). This is an + # indication that the text is laid out backwards. +1 for visual + # score + # 3) A word longer than 1 letter, starting with a final letter. Final + # letters should not appear at the beginning of a word. This is an + # indication that the text is laid out backwards. +1 for visual + # score. + # + # The visual score and logical score are accumulated throughout the + # text and are finally checked against each other in GetCharSetName(). + # No checking for final letters in the middle of words is done since + # that case is not an indication for either Logical or Visual text. + # + # We automatically filter out all 7-bit characters (replace them with + # spaces) so the word boundary detection works properly. [MAP] + + if self.state == ProbingState.NOT_ME: + # Both model probers say it's not them. No reason to continue. + return ProbingState.NOT_ME + + byte_str = self.filter_high_byte_only(byte_str) + + for cur in byte_str: + if cur == ' ': + # We stand on a space - a word just ended + if self._before_prev != ' ': + # next-to-last char was not a space so self._prev is not a + # 1 letter word + if self.is_final(self._prev): + # case (1) [-2:not space][-1:final letter][cur:space] + self._final_char_logical_score += 1 + elif self.is_non_final(self._prev): + # case (2) [-2:not space][-1:Non-Final letter][ + # cur:space] + self._final_char_visual_score += 1 + else: + # Not standing on a space + if ((self._before_prev == ' ') and + (self.is_final(self._prev)) and (cur != ' ')): + # case (3) [-2:space][-1:final letter][cur:not space] + self._final_char_visual_score += 1 + self._before_prev = self._prev + self._prev = cur + + # Forever detecting, till the end or until both model probers return + # ProbingState.NOT_ME (handled above) + return ProbingState.DETECTING + + @property + def charset_name(self): + # Make the decision: is it Logical or Visual? + # If the final letter score distance is dominant enough, rely on it. + finalsub = self._final_char_logical_score - self._final_char_visual_score + if finalsub >= self.MIN_FINAL_CHAR_DISTANCE: + return self.LOGICAL_HEBREW_NAME + if finalsub <= -self.MIN_FINAL_CHAR_DISTANCE: + return self.VISUAL_HEBREW_NAME + + # It's not dominant enough, try to rely on the model scores instead. + modelsub = (self._logical_prober.get_confidence() + - self._visual_prober.get_confidence()) + if modelsub > self.MIN_MODEL_DISTANCE: + return self.LOGICAL_HEBREW_NAME + if modelsub < -self.MIN_MODEL_DISTANCE: + return self.VISUAL_HEBREW_NAME + + # Still no good, back to final letter distance, maybe it'll save the + # day. + if finalsub < 0.0: + return self.VISUAL_HEBREW_NAME + + # (finalsub > 0 - Logical) or (don't know what to do) default to + # Logical. + return self.LOGICAL_HEBREW_NAME + + @property + def language(self): + return 'Hebrew' + + @property + def state(self): + # Remain active as long as any of the model probers are active. + if (self._logical_prober.state == ProbingState.NOT_ME) and \ + (self._visual_prober.state == ProbingState.NOT_ME): + return ProbingState.NOT_ME + return ProbingState.DETECTING diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/jisfreq.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/jisfreq.py new file mode 100644 index 0000000..83fc082 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/jisfreq.py @@ -0,0 +1,325 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# Sampling from about 20M text materials include literature and computer technology +# +# Japanese frequency table, applied to both S-JIS and EUC-JP +# They are sorted in order. + +# 128 --> 0.77094 +# 256 --> 0.85710 +# 512 --> 0.92635 +# 1024 --> 0.97130 +# 2048 --> 0.99431 +# +# Ideal Distribution Ratio = 0.92635 / (1-0.92635) = 12.58 +# Random Distribution Ration = 512 / (2965+62+83+86-512) = 0.191 +# +# Typical Distribution Ratio, 25% of IDR + +JIS_TYPICAL_DISTRIBUTION_RATIO = 3.0 + +# Char to FreqOrder table , +JIS_TABLE_SIZE = 4368 + +JIS_CHAR_TO_FREQ_ORDER = ( + 40, 1, 6, 182, 152, 180, 295,2127, 285, 381,3295,4304,3068,4606,3165,3510, # 16 +3511,1822,2785,4607,1193,2226,5070,4608, 171,2996,1247, 18, 179,5071, 856,1661, # 32 +1262,5072, 619, 127,3431,3512,3230,1899,1700, 232, 228,1294,1298, 284, 283,2041, # 48 +2042,1061,1062, 48, 49, 44, 45, 433, 434,1040,1041, 996, 787,2997,1255,4305, # 64 +2108,4609,1684,1648,5073,5074,5075,5076,5077,5078,3687,5079,4610,5080,3927,3928, # 80 +5081,3296,3432, 290,2285,1471,2187,5082,2580,2825,1303,2140,1739,1445,2691,3375, # 96 +1691,3297,4306,4307,4611, 452,3376,1182,2713,3688,3069,4308,5083,5084,5085,5086, # 112 +5087,5088,5089,5090,5091,5092,5093,5094,5095,5096,5097,5098,5099,5100,5101,5102, # 128 +5103,5104,5105,5106,5107,5108,5109,5110,5111,5112,4097,5113,5114,5115,5116,5117, # 144 +5118,5119,5120,5121,5122,5123,5124,5125,5126,5127,5128,5129,5130,5131,5132,5133, # 160 +5134,5135,5136,5137,5138,5139,5140,5141,5142,5143,5144,5145,5146,5147,5148,5149, # 176 +5150,5151,5152,4612,5153,5154,5155,5156,5157,5158,5159,5160,5161,5162,5163,5164, # 192 +5165,5166,5167,5168,5169,5170,5171,5172,5173,5174,5175,1472, 598, 618, 820,1205, # 208 +1309,1412,1858,1307,1692,5176,5177,5178,5179,5180,5181,5182,1142,1452,1234,1172, # 224 +1875,2043,2149,1793,1382,2973, 925,2404,1067,1241, 960,1377,2935,1491, 919,1217, # 240 +1865,2030,1406,1499,2749,4098,5183,5184,5185,5186,5187,5188,2561,4099,3117,1804, # 256 +2049,3689,4309,3513,1663,5189,3166,3118,3298,1587,1561,3433,5190,3119,1625,2998, # 272 +3299,4613,1766,3690,2786,4614,5191,5192,5193,5194,2161, 26,3377, 2,3929, 20, # 288 +3691, 47,4100, 50, 17, 16, 35, 268, 27, 243, 42, 155, 24, 154, 29, 184, # 304 + 4, 91, 14, 92, 53, 396, 33, 289, 9, 37, 64, 620, 21, 39, 321, 5, # 320 + 12, 11, 52, 13, 3, 208, 138, 0, 7, 60, 526, 141, 151,1069, 181, 275, # 336 +1591, 83, 132,1475, 126, 331, 829, 15, 69, 160, 59, 22, 157, 55,1079, 312, # 352 + 109, 38, 23, 25, 10, 19, 79,5195, 61, 382,1124, 8, 30,5196,5197,5198, # 368 +5199,5200,5201,5202,5203,5204,5205,5206, 89, 62, 74, 34,2416, 112, 139, 196, # 384 + 271, 149, 84, 607, 131, 765, 46, 88, 153, 683, 76, 874, 101, 258, 57, 80, # 400 + 32, 364, 121,1508, 169,1547, 68, 235, 145,2999, 41, 360,3027, 70, 63, 31, # 416 + 43, 259, 262,1383, 99, 533, 194, 66, 93, 846, 217, 192, 56, 106, 58, 565, # 432 + 280, 272, 311, 256, 146, 82, 308, 71, 100, 128, 214, 655, 110, 261, 104,1140, # 448 + 54, 51, 36, 87, 67,3070, 185,2618,2936,2020, 28,1066,2390,2059,5207,5208, # 464 +5209,5210,5211,5212,5213,5214,5215,5216,4615,5217,5218,5219,5220,5221,5222,5223, # 480 +5224,5225,5226,5227,5228,5229,5230,5231,5232,5233,5234,5235,5236,3514,5237,5238, # 496 +5239,5240,5241,5242,5243,5244,2297,2031,4616,4310,3692,5245,3071,5246,3598,5247, # 512 +4617,3231,3515,5248,4101,4311,4618,3808,4312,4102,5249,4103,4104,3599,5250,5251, # 528 +5252,5253,5254,5255,5256,5257,5258,5259,5260,5261,5262,5263,5264,5265,5266,5267, # 544 +5268,5269,5270,5271,5272,5273,5274,5275,5276,5277,5278,5279,5280,5281,5282,5283, # 560 +5284,5285,5286,5287,5288,5289,5290,5291,5292,5293,5294,5295,5296,5297,5298,5299, # 576 +5300,5301,5302,5303,5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315, # 592 +5316,5317,5318,5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331, # 608 +5332,5333,5334,5335,5336,5337,5338,5339,5340,5341,5342,5343,5344,5345,5346,5347, # 624 +5348,5349,5350,5351,5352,5353,5354,5355,5356,5357,5358,5359,5360,5361,5362,5363, # 640 +5364,5365,5366,5367,5368,5369,5370,5371,5372,5373,5374,5375,5376,5377,5378,5379, # 656 +5380,5381, 363, 642,2787,2878,2788,2789,2316,3232,2317,3434,2011, 165,1942,3930, # 672 +3931,3932,3933,5382,4619,5383,4620,5384,5385,5386,5387,5388,5389,5390,5391,5392, # 688 +5393,5394,5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408, # 704 +5409,5410,5411,5412,5413,5414,5415,5416,5417,5418,5419,5420,5421,5422,5423,5424, # 720 +5425,5426,5427,5428,5429,5430,5431,5432,5433,5434,5435,5436,5437,5438,5439,5440, # 736 +5441,5442,5443,5444,5445,5446,5447,5448,5449,5450,5451,5452,5453,5454,5455,5456, # 752 +5457,5458,5459,5460,5461,5462,5463,5464,5465,5466,5467,5468,5469,5470,5471,5472, # 768 +5473,5474,5475,5476,5477,5478,5479,5480,5481,5482,5483,5484,5485,5486,5487,5488, # 784 +5489,5490,5491,5492,5493,5494,5495,5496,5497,5498,5499,5500,5501,5502,5503,5504, # 800 +5505,5506,5507,5508,5509,5510,5511,5512,5513,5514,5515,5516,5517,5518,5519,5520, # 816 +5521,5522,5523,5524,5525,5526,5527,5528,5529,5530,5531,5532,5533,5534,5535,5536, # 832 +5537,5538,5539,5540,5541,5542,5543,5544,5545,5546,5547,5548,5549,5550,5551,5552, # 848 +5553,5554,5555,5556,5557,5558,5559,5560,5561,5562,5563,5564,5565,5566,5567,5568, # 864 +5569,5570,5571,5572,5573,5574,5575,5576,5577,5578,5579,5580,5581,5582,5583,5584, # 880 +5585,5586,5587,5588,5589,5590,5591,5592,5593,5594,5595,5596,5597,5598,5599,5600, # 896 +5601,5602,5603,5604,5605,5606,5607,5608,5609,5610,5611,5612,5613,5614,5615,5616, # 912 +5617,5618,5619,5620,5621,5622,5623,5624,5625,5626,5627,5628,5629,5630,5631,5632, # 928 +5633,5634,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646,5647,5648, # 944 +5649,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660,5661,5662,5663,5664, # 960 +5665,5666,5667,5668,5669,5670,5671,5672,5673,5674,5675,5676,5677,5678,5679,5680, # 976 +5681,5682,5683,5684,5685,5686,5687,5688,5689,5690,5691,5692,5693,5694,5695,5696, # 992 +5697,5698,5699,5700,5701,5702,5703,5704,5705,5706,5707,5708,5709,5710,5711,5712, # 1008 +5713,5714,5715,5716,5717,5718,5719,5720,5721,5722,5723,5724,5725,5726,5727,5728, # 1024 +5729,5730,5731,5732,5733,5734,5735,5736,5737,5738,5739,5740,5741,5742,5743,5744, # 1040 +5745,5746,5747,5748,5749,5750,5751,5752,5753,5754,5755,5756,5757,5758,5759,5760, # 1056 +5761,5762,5763,5764,5765,5766,5767,5768,5769,5770,5771,5772,5773,5774,5775,5776, # 1072 +5777,5778,5779,5780,5781,5782,5783,5784,5785,5786,5787,5788,5789,5790,5791,5792, # 1088 +5793,5794,5795,5796,5797,5798,5799,5800,5801,5802,5803,5804,5805,5806,5807,5808, # 1104 +5809,5810,5811,5812,5813,5814,5815,5816,5817,5818,5819,5820,5821,5822,5823,5824, # 1120 +5825,5826,5827,5828,5829,5830,5831,5832,5833,5834,5835,5836,5837,5838,5839,5840, # 1136 +5841,5842,5843,5844,5845,5846,5847,5848,5849,5850,5851,5852,5853,5854,5855,5856, # 1152 +5857,5858,5859,5860,5861,5862,5863,5864,5865,5866,5867,5868,5869,5870,5871,5872, # 1168 +5873,5874,5875,5876,5877,5878,5879,5880,5881,5882,5883,5884,5885,5886,5887,5888, # 1184 +5889,5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,5904, # 1200 +5905,5906,5907,5908,5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,5919,5920, # 1216 +5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,5936, # 1232 +5937,5938,5939,5940,5941,5942,5943,5944,5945,5946,5947,5948,5949,5950,5951,5952, # 1248 +5953,5954,5955,5956,5957,5958,5959,5960,5961,5962,5963,5964,5965,5966,5967,5968, # 1264 +5969,5970,5971,5972,5973,5974,5975,5976,5977,5978,5979,5980,5981,5982,5983,5984, # 1280 +5985,5986,5987,5988,5989,5990,5991,5992,5993,5994,5995,5996,5997,5998,5999,6000, # 1296 +6001,6002,6003,6004,6005,6006,6007,6008,6009,6010,6011,6012,6013,6014,6015,6016, # 1312 +6017,6018,6019,6020,6021,6022,6023,6024,6025,6026,6027,6028,6029,6030,6031,6032, # 1328 +6033,6034,6035,6036,6037,6038,6039,6040,6041,6042,6043,6044,6045,6046,6047,6048, # 1344 +6049,6050,6051,6052,6053,6054,6055,6056,6057,6058,6059,6060,6061,6062,6063,6064, # 1360 +6065,6066,6067,6068,6069,6070,6071,6072,6073,6074,6075,6076,6077,6078,6079,6080, # 1376 +6081,6082,6083,6084,6085,6086,6087,6088,6089,6090,6091,6092,6093,6094,6095,6096, # 1392 +6097,6098,6099,6100,6101,6102,6103,6104,6105,6106,6107,6108,6109,6110,6111,6112, # 1408 +6113,6114,2044,2060,4621, 997,1235, 473,1186,4622, 920,3378,6115,6116, 379,1108, # 1424 +4313,2657,2735,3934,6117,3809, 636,3233, 573,1026,3693,3435,2974,3300,2298,4105, # 1440 + 854,2937,2463, 393,2581,2417, 539, 752,1280,2750,2480, 140,1161, 440, 708,1569, # 1456 + 665,2497,1746,1291,1523,3000, 164,1603, 847,1331, 537,1997, 486, 508,1693,2418, # 1472 +1970,2227, 878,1220, 299,1030, 969, 652,2751, 624,1137,3301,2619, 65,3302,2045, # 1488 +1761,1859,3120,1930,3694,3516, 663,1767, 852, 835,3695, 269, 767,2826,2339,1305, # 1504 + 896,1150, 770,1616,6118, 506,1502,2075,1012,2519, 775,2520,2975,2340,2938,4314, # 1520 +3028,2086,1224,1943,2286,6119,3072,4315,2240,1273,1987,3935,1557, 175, 597, 985, # 1536 +3517,2419,2521,1416,3029, 585, 938,1931,1007,1052,1932,1685,6120,3379,4316,4623, # 1552 + 804, 599,3121,1333,2128,2539,1159,1554,2032,3810, 687,2033,2904, 952, 675,1467, # 1568 +3436,6121,2241,1096,1786,2440,1543,1924, 980,1813,2228, 781,2692,1879, 728,1918, # 1584 +3696,4624, 548,1950,4625,1809,1088,1356,3303,2522,1944, 502, 972, 373, 513,2827, # 1600 + 586,2377,2391,1003,1976,1631,6122,2464,1084, 648,1776,4626,2141, 324, 962,2012, # 1616 +2177,2076,1384, 742,2178,1448,1173,1810, 222, 102, 301, 445, 125,2420, 662,2498, # 1632 + 277, 200,1476,1165,1068, 224,2562,1378,1446, 450,1880, 659, 791, 582,4627,2939, # 1648 +3936,1516,1274, 555,2099,3697,1020,1389,1526,3380,1762,1723,1787,2229, 412,2114, # 1664 +1900,2392,3518, 512,2597, 427,1925,2341,3122,1653,1686,2465,2499, 697, 330, 273, # 1680 + 380,2162, 951, 832, 780, 991,1301,3073, 965,2270,3519, 668,2523,2636,1286, 535, # 1696 +1407, 518, 671, 957,2658,2378, 267, 611,2197,3030,6123, 248,2299, 967,1799,2356, # 1712 + 850,1418,3437,1876,1256,1480,2828,1718,6124,6125,1755,1664,2405,6126,4628,2879, # 1728 +2829, 499,2179, 676,4629, 557,2329,2214,2090, 325,3234, 464, 811,3001, 992,2342, # 1744 +2481,1232,1469, 303,2242, 466,1070,2163, 603,1777,2091,4630,2752,4631,2714, 322, # 1760 +2659,1964,1768, 481,2188,1463,2330,2857,3600,2092,3031,2421,4632,2318,2070,1849, # 1776 +2598,4633,1302,2254,1668,1701,2422,3811,2905,3032,3123,2046,4106,1763,1694,4634, # 1792 +1604, 943,1724,1454, 917, 868,2215,1169,2940, 552,1145,1800,1228,1823,1955, 316, # 1808 +1080,2510, 361,1807,2830,4107,2660,3381,1346,1423,1134,4108,6127, 541,1263,1229, # 1824 +1148,2540, 545, 465,1833,2880,3438,1901,3074,2482, 816,3937, 713,1788,2500, 122, # 1840 +1575, 195,1451,2501,1111,6128, 859, 374,1225,2243,2483,4317, 390,1033,3439,3075, # 1856 +2524,1687, 266, 793,1440,2599, 946, 779, 802, 507, 897,1081, 528,2189,1292, 711, # 1872 +1866,1725,1167,1640, 753, 398,2661,1053, 246, 348,4318, 137,1024,3440,1600,2077, # 1888 +2129, 825,4319, 698, 238, 521, 187,2300,1157,2423,1641,1605,1464,1610,1097,2541, # 1904 +1260,1436, 759,2255,1814,2150, 705,3235, 409,2563,3304, 561,3033,2005,2564, 726, # 1920 +1956,2343,3698,4109, 949,3812,3813,3520,1669, 653,1379,2525, 881,2198, 632,2256, # 1936 +1027, 778,1074, 733,1957, 514,1481,2466, 554,2180, 702,3938,1606,1017,1398,6129, # 1952 +1380,3521, 921, 993,1313, 594, 449,1489,1617,1166, 768,1426,1360, 495,1794,3601, # 1968 +1177,3602,1170,4320,2344, 476, 425,3167,4635,3168,1424, 401,2662,1171,3382,1998, # 1984 +1089,4110, 477,3169, 474,6130,1909, 596,2831,1842, 494, 693,1051,1028,1207,3076, # 2000 + 606,2115, 727,2790,1473,1115, 743,3522, 630, 805,1532,4321,2021, 366,1057, 838, # 2016 + 684,1114,2142,4322,2050,1492,1892,1808,2271,3814,2424,1971,1447,1373,3305,1090, # 2032 +1536,3939,3523,3306,1455,2199, 336, 369,2331,1035, 584,2393, 902, 718,2600,6131, # 2048 +2753, 463,2151,1149,1611,2467, 715,1308,3124,1268, 343,1413,3236,1517,1347,2663, # 2064 +2093,3940,2022,1131,1553,2100,2941,1427,3441,2942,1323,2484,6132,1980, 872,2368, # 2080 +2441,2943, 320,2369,2116,1082, 679,1933,3941,2791,3815, 625,1143,2023, 422,2200, # 2096 +3816,6133, 730,1695, 356,2257,1626,2301,2858,2637,1627,1778, 937, 883,2906,2693, # 2112 +3002,1769,1086, 400,1063,1325,3307,2792,4111,3077, 456,2345,1046, 747,6134,1524, # 2128 + 884,1094,3383,1474,2164,1059, 974,1688,2181,2258,1047, 345,1665,1187, 358, 875, # 2144 +3170, 305, 660,3524,2190,1334,1135,3171,1540,1649,2542,1527, 927, 968,2793, 885, # 2160 +1972,1850, 482, 500,2638,1218,1109,1085,2543,1654,2034, 876, 78,2287,1482,1277, # 2176 + 861,1675,1083,1779, 724,2754, 454, 397,1132,1612,2332, 893, 672,1237, 257,2259, # 2192 +2370, 135,3384, 337,2244, 547, 352, 340, 709,2485,1400, 788,1138,2511, 540, 772, # 2208 +1682,2260,2272,2544,2013,1843,1902,4636,1999,1562,2288,4637,2201,1403,1533, 407, # 2224 + 576,3308,1254,2071, 978,3385, 170, 136,1201,3125,2664,3172,2394, 213, 912, 873, # 2240 +3603,1713,2202, 699,3604,3699, 813,3442, 493, 531,1054, 468,2907,1483, 304, 281, # 2256 +4112,1726,1252,2094, 339,2319,2130,2639, 756,1563,2944, 748, 571,2976,1588,2425, # 2272 +2715,1851,1460,2426,1528,1392,1973,3237, 288,3309, 685,3386, 296, 892,2716,2216, # 2288 +1570,2245, 722,1747,2217, 905,3238,1103,6135,1893,1441,1965, 251,1805,2371,3700, # 2304 +2601,1919,1078, 75,2182,1509,1592,1270,2640,4638,2152,6136,3310,3817, 524, 706, # 2320 +1075, 292,3818,1756,2602, 317, 98,3173,3605,3525,1844,2218,3819,2502, 814, 567, # 2336 + 385,2908,1534,6137, 534,1642,3239, 797,6138,1670,1529, 953,4323, 188,1071, 538, # 2352 + 178, 729,3240,2109,1226,1374,2000,2357,2977, 731,2468,1116,2014,2051,6139,1261, # 2368 +1593, 803,2859,2736,3443, 556, 682, 823,1541,6140,1369,2289,1706,2794, 845, 462, # 2384 +2603,2665,1361, 387, 162,2358,1740, 739,1770,1720,1304,1401,3241,1049, 627,1571, # 2400 +2427,3526,1877,3942,1852,1500, 431,1910,1503, 677, 297,2795, 286,1433,1038,1198, # 2416 +2290,1133,1596,4113,4639,2469,1510,1484,3943,6141,2442, 108, 712,4640,2372, 866, # 2432 +3701,2755,3242,1348, 834,1945,1408,3527,2395,3243,1811, 824, 994,1179,2110,1548, # 2448 +1453, 790,3003, 690,4324,4325,2832,2909,3820,1860,3821, 225,1748, 310, 346,1780, # 2464 +2470, 821,1993,2717,2796, 828, 877,3528,2860,2471,1702,2165,2910,2486,1789, 453, # 2480 + 359,2291,1676, 73,1164,1461,1127,3311, 421, 604, 314,1037, 589, 116,2487, 737, # 2496 + 837,1180, 111, 244, 735,6142,2261,1861,1362, 986, 523, 418, 581,2666,3822, 103, # 2512 + 855, 503,1414,1867,2488,1091, 657,1597, 979, 605,1316,4641,1021,2443,2078,2001, # 2528 +1209, 96, 587,2166,1032, 260,1072,2153, 173, 94, 226,3244, 819,2006,4642,4114, # 2544 +2203, 231,1744, 782, 97,2667, 786,3387, 887, 391, 442,2219,4326,1425,6143,2694, # 2560 + 633,1544,1202, 483,2015, 592,2052,1958,2472,1655, 419, 129,4327,3444,3312,1714, # 2576 +1257,3078,4328,1518,1098, 865,1310,1019,1885,1512,1734, 469,2444, 148, 773, 436, # 2592 +1815,1868,1128,1055,4329,1245,2756,3445,2154,1934,1039,4643, 579,1238, 932,2320, # 2608 + 353, 205, 801, 115,2428, 944,2321,1881, 399,2565,1211, 678, 766,3944, 335,2101, # 2624 +1459,1781,1402,3945,2737,2131,1010, 844, 981,1326,1013, 550,1816,1545,2620,1335, # 2640 +1008, 371,2881, 936,1419,1613,3529,1456,1395,2273,1834,2604,1317,2738,2503, 416, # 2656 +1643,4330, 806,1126, 229, 591,3946,1314,1981,1576,1837,1666, 347,1790, 977,3313, # 2672 + 764,2861,1853, 688,2429,1920,1462, 77, 595, 415,2002,3034, 798,1192,4115,6144, # 2688 +2978,4331,3035,2695,2582,2072,2566, 430,2430,1727, 842,1396,3947,3702, 613, 377, # 2704 + 278, 236,1417,3388,3314,3174, 757,1869, 107,3530,6145,1194, 623,2262, 207,1253, # 2720 +2167,3446,3948, 492,1117,1935, 536,1838,2757,1246,4332, 696,2095,2406,1393,1572, # 2736 +3175,1782, 583, 190, 253,1390,2230, 830,3126,3389, 934,3245,1703,1749,2979,1870, # 2752 +2545,1656,2204, 869,2346,4116,3176,1817, 496,1764,4644, 942,1504, 404,1903,1122, # 2768 +1580,3606,2945,1022, 515, 372,1735, 955,2431,3036,6146,2797,1110,2302,2798, 617, # 2784 +6147, 441, 762,1771,3447,3607,3608,1904, 840,3037, 86, 939,1385, 572,1370,2445, # 2800 +1336, 114,3703, 898, 294, 203,3315, 703,1583,2274, 429, 961,4333,1854,1951,3390, # 2816 +2373,3704,4334,1318,1381, 966,1911,2322,1006,1155, 309, 989, 458,2718,1795,1372, # 2832 +1203, 252,1689,1363,3177, 517,1936, 168,1490, 562, 193,3823,1042,4117,1835, 551, # 2848 + 470,4645, 395, 489,3448,1871,1465,2583,2641, 417,1493, 279,1295, 511,1236,1119, # 2864 + 72,1231,1982,1812,3004, 871,1564, 984,3449,1667,2696,2096,4646,2347,2833,1673, # 2880 +3609, 695,3246,2668, 807,1183,4647, 890, 388,2333,1801,1457,2911,1765,1477,1031, # 2896 +3316,3317,1278,3391,2799,2292,2526, 163,3450,4335,2669,1404,1802,6148,2323,2407, # 2912 +1584,1728,1494,1824,1269, 298, 909,3318,1034,1632, 375, 776,1683,2061, 291, 210, # 2928 +1123, 809,1249,1002,2642,3038, 206,1011,2132, 144, 975, 882,1565, 342, 667, 754, # 2944 +1442,2143,1299,2303,2062, 447, 626,2205,1221,2739,2912,1144,1214,2206,2584, 760, # 2960 +1715, 614, 950,1281,2670,2621, 810, 577,1287,2546,4648, 242,2168, 250,2643, 691, # 2976 + 123,2644, 647, 313,1029, 689,1357,2946,1650, 216, 771,1339,1306, 808,2063, 549, # 2992 + 913,1371,2913,2914,6149,1466,1092,1174,1196,1311,2605,2396,1783,1796,3079, 406, # 3008 +2671,2117,3949,4649, 487,1825,2220,6150,2915, 448,2348,1073,6151,2397,1707, 130, # 3024 + 900,1598, 329, 176,1959,2527,1620,6152,2275,4336,3319,1983,2191,3705,3610,2155, # 3040 +3706,1912,1513,1614,6153,1988, 646, 392,2304,1589,3320,3039,1826,1239,1352,1340, # 3056 +2916, 505,2567,1709,1437,2408,2547, 906,6154,2672, 384,1458,1594,1100,1329, 710, # 3072 + 423,3531,2064,2231,2622,1989,2673,1087,1882, 333, 841,3005,1296,2882,2379, 580, # 3088 +1937,1827,1293,2585, 601, 574, 249,1772,4118,2079,1120, 645, 901,1176,1690, 795, # 3104 +2207, 478,1434, 516,1190,1530, 761,2080, 930,1264, 355, 435,1552, 644,1791, 987, # 3120 + 220,1364,1163,1121,1538, 306,2169,1327,1222, 546,2645, 218, 241, 610,1704,3321, # 3136 +1984,1839,1966,2528, 451,6155,2586,3707,2568, 907,3178, 254,2947, 186,1845,4650, # 3152 + 745, 432,1757, 428,1633, 888,2246,2221,2489,3611,2118,1258,1265, 956,3127,1784, # 3168 +4337,2490, 319, 510, 119, 457,3612, 274,2035,2007,4651,1409,3128, 970,2758, 590, # 3184 +2800, 661,2247,4652,2008,3950,1420,1549,3080,3322,3951,1651,1375,2111, 485,2491, # 3200 +1429,1156,6156,2548,2183,1495, 831,1840,2529,2446, 501,1657, 307,1894,3247,1341, # 3216 + 666, 899,2156,1539,2549,1559, 886, 349,2208,3081,2305,1736,3824,2170,2759,1014, # 3232 +1913,1386, 542,1397,2948, 490, 368, 716, 362, 159, 282,2569,1129,1658,1288,1750, # 3248 +2674, 276, 649,2016, 751,1496, 658,1818,1284,1862,2209,2087,2512,3451, 622,2834, # 3264 + 376, 117,1060,2053,1208,1721,1101,1443, 247,1250,3179,1792,3952,2760,2398,3953, # 3280 +6157,2144,3708, 446,2432,1151,2570,3452,2447,2761,2835,1210,2448,3082, 424,2222, # 3296 +1251,2449,2119,2836, 504,1581,4338, 602, 817, 857,3825,2349,2306, 357,3826,1470, # 3312 +1883,2883, 255, 958, 929,2917,3248, 302,4653,1050,1271,1751,2307,1952,1430,2697, # 3328 +2719,2359, 354,3180, 777, 158,2036,4339,1659,4340,4654,2308,2949,2248,1146,2232, # 3344 +3532,2720,1696,2623,3827,6158,3129,1550,2698,1485,1297,1428, 637, 931,2721,2145, # 3360 + 914,2550,2587, 81,2450, 612, 827,2646,1242,4655,1118,2884, 472,1855,3181,3533, # 3376 +3534, 569,1353,2699,1244,1758,2588,4119,2009,2762,2171,3709,1312,1531,6159,1152, # 3392 +1938, 134,1830, 471,3710,2276,1112,1535,3323,3453,3535, 982,1337,2950, 488, 826, # 3408 + 674,1058,1628,4120,2017, 522,2399, 211, 568,1367,3454, 350, 293,1872,1139,3249, # 3424 +1399,1946,3006,1300,2360,3324, 588, 736,6160,2606, 744, 669,3536,3828,6161,1358, # 3440 + 199, 723, 848, 933, 851,1939,1505,1514,1338,1618,1831,4656,1634,3613, 443,2740, # 3456 +3829, 717,1947, 491,1914,6162,2551,1542,4121,1025,6163,1099,1223, 198,3040,2722, # 3472 + 370, 410,1905,2589, 998,1248,3182,2380, 519,1449,4122,1710, 947, 928,1153,4341, # 3488 +2277, 344,2624,1511, 615, 105, 161,1212,1076,1960,3130,2054,1926,1175,1906,2473, # 3504 + 414,1873,2801,6164,2309, 315,1319,3325, 318,2018,2146,2157, 963, 631, 223,4342, # 3520 +4343,2675, 479,3711,1197,2625,3712,2676,2361,6165,4344,4123,6166,2451,3183,1886, # 3536 +2184,1674,1330,1711,1635,1506, 799, 219,3250,3083,3954,1677,3713,3326,2081,3614, # 3552 +1652,2073,4657,1147,3041,1752, 643,1961, 147,1974,3955,6167,1716,2037, 918,3007, # 3568 +1994, 120,1537, 118, 609,3184,4345, 740,3455,1219, 332,1615,3830,6168,1621,2980, # 3584 +1582, 783, 212, 553,2350,3714,1349,2433,2082,4124, 889,6169,2310,1275,1410, 973, # 3600 + 166,1320,3456,1797,1215,3185,2885,1846,2590,2763,4658, 629, 822,3008, 763, 940, # 3616 +1990,2862, 439,2409,1566,1240,1622, 926,1282,1907,2764, 654,2210,1607, 327,1130, # 3632 +3956,1678,1623,6170,2434,2192, 686, 608,3831,3715, 903,3957,3042,6171,2741,1522, # 3648 +1915,1105,1555,2552,1359, 323,3251,4346,3457, 738,1354,2553,2311,2334,1828,2003, # 3664 +3832,1753,2351,1227,6172,1887,4125,1478,6173,2410,1874,1712,1847, 520,1204,2607, # 3680 + 264,4659, 836,2677,2102, 600,4660,3833,2278,3084,6174,4347,3615,1342, 640, 532, # 3696 + 543,2608,1888,2400,2591,1009,4348,1497, 341,1737,3616,2723,1394, 529,3252,1321, # 3712 + 983,4661,1515,2120, 971,2592, 924, 287,1662,3186,4349,2700,4350,1519, 908,1948, # 3728 +2452, 156, 796,1629,1486,2223,2055, 694,4126,1259,1036,3392,1213,2249,2742,1889, # 3744 +1230,3958,1015, 910, 408, 559,3617,4662, 746, 725, 935,4663,3959,3009,1289, 563, # 3760 + 867,4664,3960,1567,2981,2038,2626, 988,2263,2381,4351, 143,2374, 704,1895,6175, # 3776 +1188,3716,2088, 673,3085,2362,4352, 484,1608,1921,2765,2918, 215, 904,3618,3537, # 3792 + 894, 509, 976,3043,2701,3961,4353,2837,2982, 498,6176,6177,1102,3538,1332,3393, # 3808 +1487,1636,1637, 233, 245,3962, 383, 650, 995,3044, 460,1520,1206,2352, 749,3327, # 3824 + 530, 700, 389,1438,1560,1773,3963,2264, 719,2951,2724,3834, 870,1832,1644,1000, # 3840 + 839,2474,3717, 197,1630,3394, 365,2886,3964,1285,2133, 734, 922, 818,1106, 732, # 3856 + 480,2083,1774,3458, 923,2279,1350, 221,3086, 85,2233,2234,3835,1585,3010,2147, # 3872 +1387,1705,2382,1619,2475, 133, 239,2802,1991,1016,2084,2383, 411,2838,1113, 651, # 3888 +1985,1160,3328, 990,1863,3087,1048,1276,2647, 265,2627,1599,3253,2056, 150, 638, # 3904 +2019, 656, 853, 326,1479, 680,1439,4354,1001,1759, 413,3459,3395,2492,1431, 459, # 3920 +4355,1125,3329,2265,1953,1450,2065,2863, 849, 351,2678,3131,3254,3255,1104,1577, # 3936 + 227,1351,1645,2453,2193,1421,2887, 812,2121, 634, 95,2435, 201,2312,4665,1646, # 3952 +1671,2743,1601,2554,2702,2648,2280,1315,1366,2089,3132,1573,3718,3965,1729,1189, # 3968 + 328,2679,1077,1940,1136, 558,1283, 964,1195, 621,2074,1199,1743,3460,3619,1896, # 3984 +1916,1890,3836,2952,1154,2112,1064, 862, 378,3011,2066,2113,2803,1568,2839,6178, # 4000 +3088,2919,1941,1660,2004,1992,2194, 142, 707,1590,1708,1624,1922,1023,1836,1233, # 4016 +1004,2313, 789, 741,3620,6179,1609,2411,1200,4127,3719,3720,4666,2057,3721, 593, # 4032 +2840, 367,2920,1878,6180,3461,1521, 628,1168, 692,2211,2649, 300, 720,2067,2571, # 4048 +2953,3396, 959,2504,3966,3539,3462,1977, 701,6181, 954,1043, 800, 681, 183,3722, # 4064 +1803,1730,3540,4128,2103, 815,2314, 174, 467, 230,2454,1093,2134, 755,3541,3397, # 4080 +1141,1162,6182,1738,2039, 270,3256,2513,1005,1647,2185,3837, 858,1679,1897,1719, # 4096 +2954,2324,1806, 402, 670, 167,4129,1498,2158,2104, 750,6183, 915, 189,1680,1551, # 4112 + 455,4356,1501,2455, 405,1095,2955, 338,1586,1266,1819, 570, 641,1324, 237,1556, # 4128 +2650,1388,3723,6184,1368,2384,1343,1978,3089,2436, 879,3724, 792,1191, 758,3012, # 4144 +1411,2135,1322,4357, 240,4667,1848,3725,1574,6185, 420,3045,1546,1391, 714,4358, # 4160 +1967, 941,1864, 863, 664, 426, 560,1731,2680,1785,2864,1949,2363, 403,3330,1415, # 4176 +1279,2136,1697,2335, 204, 721,2097,3838, 90,6186,2085,2505, 191,3967, 124,2148, # 4192 +1376,1798,1178,1107,1898,1405, 860,4359,1243,1272,2375,2983,1558,2456,1638, 113, # 4208 +3621, 578,1923,2609, 880, 386,4130, 784,2186,2266,1422,2956,2172,1722, 497, 263, # 4224 +2514,1267,2412,2610, 177,2703,3542, 774,1927,1344, 616,1432,1595,1018, 172,4360, # 4240 +2325, 911,4361, 438,1468,3622, 794,3968,2024,2173,1681,1829,2957, 945, 895,3090, # 4256 + 575,2212,2476, 475,2401,2681, 785,2744,1745,2293,2555,1975,3133,2865, 394,4668, # 4272 +3839, 635,4131, 639, 202,1507,2195,2766,1345,1435,2572,3726,1908,1184,1181,2457, # 4288 +3727,3134,4362, 843,2611, 437, 916,4669, 234, 769,1884,3046,3047,3623, 833,6187, # 4304 +1639,2250,2402,1355,1185,2010,2047, 999, 525,1732,1290,1488,2612, 948,1578,3728, # 4320 +2413,2477,1216,2725,2159, 334,3840,1328,3624,2921,1525,4132, 564,1056, 891,4363, # 4336 +1444,1698,2385,2251,3729,1365,2281,2235,1717,6188, 864,3841,2515, 444, 527,2767, # 4352 +2922,3625, 544, 461,6189, 566, 209,2437,3398,2098,1065,2068,3331,3626,3257,2137, # 4368 #last 512 +) + + diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/jpcntx.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/jpcntx.py new file mode 100644 index 0000000..20044e4 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/jpcntx.py @@ -0,0 +1,233 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + + +# This is hiragana 2-char sequence table, the number in each cell represents its frequency category +jp2CharContext = ( +(0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1), +(2,4,0,4,0,3,0,4,0,3,4,4,4,2,4,3,3,4,3,2,3,3,4,2,3,3,3,2,4,1,4,3,3,1,5,4,3,4,3,4,3,5,3,0,3,5,4,2,0,3,1,0,3,3,0,3,3,0,1,1,0,4,3,0,3,3,0,4,0,2,0,3,5,5,5,5,4,0,4,1,0,3,4), +(0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2), +(0,4,0,5,0,5,0,4,0,4,5,4,4,3,5,3,5,1,5,3,4,3,4,4,3,4,3,3,4,3,5,4,4,3,5,5,3,5,5,5,3,5,5,3,4,5,5,3,1,3,2,0,3,4,0,4,2,0,4,2,1,5,3,2,3,5,0,4,0,2,0,5,4,4,5,4,5,0,4,0,0,4,4), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,3,0,4,0,3,0,3,0,4,5,4,3,3,3,3,4,3,5,4,4,3,5,4,4,3,4,3,4,4,4,4,5,3,4,4,3,4,5,5,4,5,5,1,4,5,4,3,0,3,3,1,3,3,0,4,4,0,3,3,1,5,3,3,3,5,0,4,0,3,0,4,4,3,4,3,3,0,4,1,1,3,4), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,4,0,3,0,3,0,4,0,3,4,4,3,2,2,1,2,1,3,1,3,3,3,3,3,4,3,1,3,3,5,3,3,0,4,3,0,5,4,3,3,5,4,4,3,4,4,5,0,1,2,0,1,2,0,2,2,0,1,0,0,5,2,2,1,4,0,3,0,1,0,4,4,3,5,4,3,0,2,1,0,4,3), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,3,0,5,0,4,0,2,1,4,4,2,4,1,4,2,4,2,4,3,3,3,4,3,3,3,3,1,4,2,3,3,3,1,4,4,1,1,1,4,3,3,2,0,2,4,3,2,0,3,3,0,3,1,1,0,0,0,3,3,0,4,2,2,3,4,0,4,0,3,0,4,4,5,3,4,4,0,3,0,0,1,4), +(1,4,0,4,0,4,0,4,0,3,5,4,4,3,4,3,5,4,3,3,4,3,5,4,4,4,4,3,4,2,4,3,3,1,5,4,3,2,4,5,4,5,5,4,4,5,4,4,0,3,2,2,3,3,0,4,3,1,3,2,1,4,3,3,4,5,0,3,0,2,0,4,5,5,4,5,4,0,4,0,0,5,4), +(0,5,0,5,0,4,0,3,0,4,4,3,4,3,3,3,4,0,4,4,4,3,4,3,4,3,3,1,4,2,4,3,4,0,5,4,1,4,5,4,4,5,3,2,4,3,4,3,2,4,1,3,3,3,2,3,2,0,4,3,3,4,3,3,3,4,0,4,0,3,0,4,5,4,4,4,3,0,4,1,0,1,3), +(0,3,1,4,0,3,0,2,0,3,4,4,3,1,4,2,3,3,4,3,4,3,4,3,4,4,3,2,3,1,5,4,4,1,4,4,3,5,4,4,3,5,5,4,3,4,4,3,1,2,3,1,2,2,0,3,2,0,3,1,0,5,3,3,3,4,3,3,3,3,4,4,4,4,5,4,2,0,3,3,2,4,3), +(0,2,0,3,0,1,0,1,0,0,3,2,0,0,2,0,1,0,2,1,3,3,3,1,2,3,1,0,1,0,4,2,1,1,3,3,0,4,3,3,1,4,3,3,0,3,3,2,0,0,0,0,1,0,0,2,0,0,0,0,0,4,1,0,2,3,2,2,2,1,3,3,3,4,4,3,2,0,3,1,0,3,3), +(0,4,0,4,0,3,0,3,0,4,4,4,3,3,3,3,3,3,4,3,4,2,4,3,4,3,3,2,4,3,4,5,4,1,4,5,3,5,4,5,3,5,4,0,3,5,5,3,1,3,3,2,2,3,0,3,4,1,3,3,2,4,3,3,3,4,0,4,0,3,0,4,5,4,4,5,3,0,4,1,0,3,4), +(0,2,0,3,0,3,0,0,0,2,2,2,1,0,1,0,0,0,3,0,3,0,3,0,1,3,1,0,3,1,3,3,3,1,3,3,3,0,1,3,1,3,4,0,0,3,1,1,0,3,2,0,0,0,0,1,3,0,1,0,0,3,3,2,0,3,0,0,0,0,0,3,4,3,4,3,3,0,3,0,0,2,3), +(2,3,0,3,0,2,0,1,0,3,3,4,3,1,3,1,1,1,3,1,4,3,4,3,3,3,0,0,3,1,5,4,3,1,4,3,2,5,5,4,4,4,4,3,3,4,4,4,0,2,1,1,3,2,0,1,2,0,0,1,0,4,1,3,3,3,0,3,0,1,0,4,4,4,5,5,3,0,2,0,0,4,4), +(0,2,0,1,0,3,1,3,0,2,3,3,3,0,3,1,0,0,3,0,3,2,3,1,3,2,1,1,0,0,4,2,1,0,2,3,1,4,3,2,0,4,4,3,1,3,1,3,0,1,0,0,1,0,0,0,1,0,0,0,0,4,1,1,1,2,0,3,0,0,0,3,4,2,4,3,2,0,1,0,0,3,3), +(0,1,0,4,0,5,0,4,0,2,4,4,2,3,3,2,3,3,5,3,3,3,4,3,4,2,3,0,4,3,3,3,4,1,4,3,2,1,5,5,3,4,5,1,3,5,4,2,0,3,3,0,1,3,0,4,2,0,1,3,1,4,3,3,3,3,0,3,0,1,0,3,4,4,4,5,5,0,3,0,1,4,5), +(0,2,0,3,0,3,0,0,0,2,3,1,3,0,4,0,1,1,3,0,3,4,3,2,3,1,0,3,3,2,3,1,3,0,2,3,0,2,1,4,1,2,2,0,0,3,3,0,0,2,0,0,0,1,0,0,0,0,2,2,0,3,2,1,3,3,0,2,0,2,0,0,3,3,1,2,4,0,3,0,2,2,3), +(2,4,0,5,0,4,0,4,0,2,4,4,4,3,4,3,3,3,1,2,4,3,4,3,4,4,5,0,3,3,3,3,2,0,4,3,1,4,3,4,1,4,4,3,3,4,4,3,1,2,3,0,4,2,0,4,1,0,3,3,0,4,3,3,3,4,0,4,0,2,0,3,5,3,4,5,2,0,3,0,0,4,5), +(0,3,0,4,0,1,0,1,0,1,3,2,2,1,3,0,3,0,2,0,2,0,3,0,2,0,0,0,1,0,1,1,0,0,3,1,0,0,0,4,0,3,1,0,2,1,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,4,2,2,3,1,0,3,0,0,0,1,4,4,4,3,0,0,4,0,0,1,4), +(1,4,1,5,0,3,0,3,0,4,5,4,4,3,5,3,3,4,4,3,4,1,3,3,3,3,2,1,4,1,5,4,3,1,4,4,3,5,4,4,3,5,4,3,3,4,4,4,0,3,3,1,2,3,0,3,1,0,3,3,0,5,4,4,4,4,4,4,3,3,5,4,4,3,3,5,4,0,3,2,0,4,4), +(0,2,0,3,0,1,0,0,0,1,3,3,3,2,4,1,3,0,3,1,3,0,2,2,1,1,0,0,2,0,4,3,1,0,4,3,0,4,4,4,1,4,3,1,1,3,3,1,0,2,0,0,1,3,0,0,0,0,2,0,0,4,3,2,4,3,5,4,3,3,3,4,3,3,4,3,3,0,2,1,0,3,3), +(0,2,0,4,0,3,0,2,0,2,5,5,3,4,4,4,4,1,4,3,3,0,4,3,4,3,1,3,3,2,4,3,0,3,4,3,0,3,4,4,2,4,4,0,4,5,3,3,2,2,1,1,1,2,0,1,5,0,3,3,2,4,3,3,3,4,0,3,0,2,0,4,4,3,5,5,0,0,3,0,2,3,3), +(0,3,0,4,0,3,0,1,0,3,4,3,3,1,3,3,3,0,3,1,3,0,4,3,3,1,1,0,3,0,3,3,0,0,4,4,0,1,5,4,3,3,5,0,3,3,4,3,0,2,0,1,1,1,0,1,3,0,1,2,1,3,3,2,3,3,0,3,0,1,0,1,3,3,4,4,1,0,1,2,2,1,3), +(0,1,0,4,0,4,0,3,0,1,3,3,3,2,3,1,1,0,3,0,3,3,4,3,2,4,2,0,1,0,4,3,2,0,4,3,0,5,3,3,2,4,4,4,3,3,3,4,0,1,3,0,0,1,0,0,1,0,0,0,0,4,2,3,3,3,0,3,0,0,0,4,4,4,5,3,2,0,3,3,0,3,5), +(0,2,0,3,0,0,0,3,0,1,3,0,2,0,0,0,1,0,3,1,1,3,3,0,0,3,0,0,3,0,2,3,1,0,3,1,0,3,3,2,0,4,2,2,0,2,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,2,1,2,0,1,0,1,0,0,0,1,3,1,2,0,0,0,1,0,0,1,4), +(0,3,0,3,0,5,0,1,0,2,4,3,1,3,3,2,1,1,5,2,1,0,5,1,2,0,0,0,3,3,2,2,3,2,4,3,0,0,3,3,1,3,3,0,2,5,3,4,0,3,3,0,1,2,0,2,2,0,3,2,0,2,2,3,3,3,0,2,0,1,0,3,4,4,2,5,4,0,3,0,0,3,5), +(0,3,0,3,0,3,0,1,0,3,3,3,3,0,3,0,2,0,2,1,1,0,2,0,1,0,0,0,2,1,0,0,1,0,3,2,0,0,3,3,1,2,3,1,0,3,3,0,0,1,0,0,0,0,0,2,0,0,0,0,0,2,3,1,2,3,0,3,0,1,0,3,2,1,0,4,3,0,1,1,0,3,3), +(0,4,0,5,0,3,0,3,0,4,5,5,4,3,5,3,4,3,5,3,3,2,5,3,4,4,4,3,4,3,4,5,5,3,4,4,3,4,4,5,4,4,4,3,4,5,5,4,2,3,4,2,3,4,0,3,3,1,4,3,2,4,3,3,5,5,0,3,0,3,0,5,5,5,5,4,4,0,4,0,1,4,4), +(0,4,0,4,0,3,0,3,0,3,5,4,4,2,3,2,5,1,3,2,5,1,4,2,3,2,3,3,4,3,3,3,3,2,5,4,1,3,3,5,3,4,4,0,4,4,3,1,1,3,1,0,2,3,0,2,3,0,3,0,0,4,3,1,3,4,0,3,0,2,0,4,4,4,3,4,5,0,4,0,0,3,4), +(0,3,0,3,0,3,1,2,0,3,4,4,3,3,3,0,2,2,4,3,3,1,3,3,3,1,1,0,3,1,4,3,2,3,4,4,2,4,4,4,3,4,4,3,2,4,4,3,1,3,3,1,3,3,0,4,1,0,2,2,1,4,3,2,3,3,5,4,3,3,5,4,4,3,3,0,4,0,3,2,2,4,4), +(0,2,0,1,0,0,0,0,0,1,2,1,3,0,0,0,0,0,2,0,1,2,1,0,0,1,0,0,0,0,3,0,0,1,0,1,1,3,1,0,0,0,1,1,0,1,1,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,1,2,2,0,3,4,0,0,0,1,1,0,0,1,0,0,0,0,0,1,1), +(0,1,0,0,0,1,0,0,0,0,4,0,4,1,4,0,3,0,4,0,3,0,4,0,3,0,3,0,4,1,5,1,4,0,0,3,0,5,0,5,2,0,1,0,0,0,2,1,4,0,1,3,0,0,3,0,0,3,1,1,4,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0), +(1,4,0,5,0,3,0,2,0,3,5,4,4,3,4,3,5,3,4,3,3,0,4,3,3,3,3,3,3,2,4,4,3,1,3,4,4,5,4,4,3,4,4,1,3,5,4,3,3,3,1,2,2,3,3,1,3,1,3,3,3,5,3,3,4,5,0,3,0,3,0,3,4,3,4,4,3,0,3,0,2,4,3), +(0,1,0,4,0,0,0,0,0,1,4,0,4,1,4,2,4,0,3,0,1,0,1,0,0,0,0,0,2,0,3,1,1,1,0,3,0,0,0,1,2,1,0,0,1,1,1,1,0,1,0,0,0,1,0,0,3,0,0,0,0,3,2,0,2,2,0,1,0,0,0,2,3,2,3,3,0,0,0,0,2,1,0), +(0,5,1,5,0,3,0,3,0,5,4,4,5,1,5,3,3,0,4,3,4,3,5,3,4,3,3,2,4,3,4,3,3,0,3,3,1,4,4,3,4,4,4,3,4,5,5,3,2,3,1,1,3,3,1,3,1,1,3,3,2,4,5,3,3,5,0,4,0,3,0,4,4,3,5,3,3,0,3,4,0,4,3), +(0,5,0,5,0,3,0,2,0,4,4,3,5,2,4,3,3,3,4,4,4,3,5,3,5,3,3,1,4,0,4,3,3,0,3,3,0,4,4,4,4,5,4,3,3,5,5,3,2,3,1,2,3,2,0,1,0,0,3,2,2,4,4,3,1,5,0,4,0,3,0,4,3,1,3,2,1,0,3,3,0,3,3), +(0,4,0,5,0,5,0,4,0,4,5,5,5,3,4,3,3,2,5,4,4,3,5,3,5,3,4,0,4,3,4,4,3,2,4,4,3,4,5,4,4,5,5,0,3,5,5,4,1,3,3,2,3,3,1,3,1,0,4,3,1,4,4,3,4,5,0,4,0,2,0,4,3,4,4,3,3,0,4,0,0,5,5), +(0,4,0,4,0,5,0,1,1,3,3,4,4,3,4,1,3,0,5,1,3,0,3,1,3,1,1,0,3,0,3,3,4,0,4,3,0,4,4,4,3,4,4,0,3,5,4,1,0,3,0,0,2,3,0,3,1,0,3,1,0,3,2,1,3,5,0,3,0,1,0,3,2,3,3,4,4,0,2,2,0,4,4), +(2,4,0,5,0,4,0,3,0,4,5,5,4,3,5,3,5,3,5,3,5,2,5,3,4,3,3,4,3,4,5,3,2,1,5,4,3,2,3,4,5,3,4,1,2,5,4,3,0,3,3,0,3,2,0,2,3,0,4,1,0,3,4,3,3,5,0,3,0,1,0,4,5,5,5,4,3,0,4,2,0,3,5), +(0,5,0,4,0,4,0,2,0,5,4,3,4,3,4,3,3,3,4,3,4,2,5,3,5,3,4,1,4,3,4,4,4,0,3,5,0,4,4,4,4,5,3,1,3,4,5,3,3,3,3,3,3,3,0,2,2,0,3,3,2,4,3,3,3,5,3,4,1,3,3,5,3,2,0,0,0,0,4,3,1,3,3), +(0,1,0,3,0,3,0,1,0,1,3,3,3,2,3,3,3,0,3,0,0,0,3,1,3,0,0,0,2,2,2,3,0,0,3,2,0,1,2,4,1,3,3,0,0,3,3,3,0,1,0,0,2,1,0,0,3,0,3,1,0,3,0,0,1,3,0,2,0,1,0,3,3,1,3,3,0,0,1,1,0,3,3), +(0,2,0,3,0,2,1,4,0,2,2,3,1,1,3,1,1,0,2,0,3,1,2,3,1,3,0,0,1,0,4,3,2,3,3,3,1,4,2,3,3,3,3,1,0,3,1,4,0,1,1,0,1,2,0,1,1,0,1,1,0,3,1,3,2,2,0,1,0,0,0,2,3,3,3,1,0,0,0,0,0,2,3), +(0,5,0,4,0,5,0,2,0,4,5,5,3,3,4,3,3,1,5,4,4,2,4,4,4,3,4,2,4,3,5,5,4,3,3,4,3,3,5,5,4,5,5,1,3,4,5,3,1,4,3,1,3,3,0,3,3,1,4,3,1,4,5,3,3,5,0,4,0,3,0,5,3,3,1,4,3,0,4,0,1,5,3), +(0,5,0,5,0,4,0,2,0,4,4,3,4,3,3,3,3,3,5,4,4,4,4,4,4,5,3,3,5,2,4,4,4,3,4,4,3,3,4,4,5,5,3,3,4,3,4,3,3,4,3,3,3,3,1,2,2,1,4,3,3,5,4,4,3,4,0,4,0,3,0,4,4,4,4,4,1,0,4,2,0,2,4), +(0,4,0,4,0,3,0,1,0,3,5,2,3,0,3,0,2,1,4,2,3,3,4,1,4,3,3,2,4,1,3,3,3,0,3,3,0,0,3,3,3,5,3,3,3,3,3,2,0,2,0,0,2,0,0,2,0,0,1,0,0,3,1,2,2,3,0,3,0,2,0,4,4,3,3,4,1,0,3,0,0,2,4), +(0,0,0,4,0,0,0,0,0,0,1,0,1,0,2,0,0,0,0,0,1,0,2,0,1,0,0,0,0,0,3,1,3,0,3,2,0,0,0,1,0,3,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,4,0,2,0,0,0,0,0,0,2), +(0,2,1,3,0,2,0,2,0,3,3,3,3,1,3,1,3,3,3,3,3,3,4,2,2,1,2,1,4,0,4,3,1,3,3,3,2,4,3,5,4,3,3,3,3,3,3,3,0,1,3,0,2,0,0,1,0,0,1,0,0,4,2,0,2,3,0,3,3,0,3,3,4,2,3,1,4,0,1,2,0,2,3), +(0,3,0,3,0,1,0,3,0,2,3,3,3,0,3,1,2,0,3,3,2,3,3,2,3,2,3,1,3,0,4,3,2,0,3,3,1,4,3,3,2,3,4,3,1,3,3,1,1,0,1,1,0,1,0,1,0,1,0,0,0,4,1,1,0,3,0,3,1,0,2,3,3,3,3,3,1,0,0,2,0,3,3), +(0,0,0,0,0,0,0,0,0,0,3,0,2,0,3,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,0,3,0,3,1,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,2,0,2,3,0,0,0,0,0,0,0,0,3), +(0,2,0,3,1,3,0,3,0,2,3,3,3,1,3,1,3,1,3,1,3,3,3,1,3,0,2,3,1,1,4,3,3,2,3,3,1,2,2,4,1,3,3,0,1,4,2,3,0,1,3,0,3,0,0,1,3,0,2,0,0,3,3,2,1,3,0,3,0,2,0,3,4,4,4,3,1,0,3,0,0,3,3), +(0,2,0,1,0,2,0,0,0,1,3,2,2,1,3,0,1,1,3,0,3,2,3,1,2,0,2,0,1,1,3,3,3,0,3,3,1,1,2,3,2,3,3,1,2,3,2,0,0,1,0,0,0,0,0,0,3,0,1,0,0,2,1,2,1,3,0,3,0,0,0,3,4,4,4,3,2,0,2,0,0,2,4), +(0,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,2,2,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,3,1,0,0,0,0,0,0,0,3), +(0,3,0,3,0,2,0,3,0,3,3,3,2,3,2,2,2,0,3,1,3,3,3,2,3,3,0,0,3,0,3,2,2,0,2,3,1,4,3,4,3,3,2,3,1,5,4,4,0,3,1,2,1,3,0,3,1,1,2,0,2,3,1,3,1,3,0,3,0,1,0,3,3,4,4,2,1,0,2,1,0,2,4), +(0,1,0,3,0,1,0,2,0,1,4,2,5,1,4,0,2,0,2,1,3,1,4,0,2,1,0,0,2,1,4,1,1,0,3,3,0,5,1,3,2,3,3,1,0,3,2,3,0,1,0,0,0,0,0,0,1,0,0,0,0,4,0,1,0,3,0,2,0,1,0,3,3,3,4,3,3,0,0,0,0,2,3), +(0,0,0,1,0,0,0,0,0,0,2,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,0,0,1,0,0,0,0,0,3), +(0,1,0,3,0,4,0,3,0,2,4,3,1,0,3,2,2,1,3,1,2,2,3,1,1,1,2,1,3,0,1,2,0,1,3,2,1,3,0,5,5,1,0,0,1,3,2,1,0,3,0,0,1,0,0,0,0,0,3,4,0,1,1,1,3,2,0,2,0,1,0,2,3,3,1,2,3,0,1,0,1,0,4), +(0,0,0,1,0,3,0,3,0,2,2,1,0,0,4,0,3,0,3,1,3,0,3,0,3,0,1,0,3,0,3,1,3,0,3,3,0,0,1,2,1,1,1,0,1,2,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,2,2,1,2,0,0,2,0,0,0,0,2,3,3,3,3,0,0,0,0,1,4), +(0,0,0,3,0,3,0,0,0,0,3,1,1,0,3,0,1,0,2,0,1,0,0,0,0,0,0,0,1,0,3,0,2,0,2,3,0,0,2,2,3,1,2,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,2,0,0,0,0,2,3), +(2,4,0,5,0,5,0,4,0,3,4,3,3,3,4,3,3,3,4,3,4,4,5,4,5,5,5,2,3,0,5,5,4,1,5,4,3,1,5,4,3,4,4,3,3,4,3,3,0,3,2,0,2,3,0,3,0,0,3,3,0,5,3,2,3,3,0,3,0,3,0,3,4,5,4,5,3,0,4,3,0,3,4), +(0,3,0,3,0,3,0,3,0,3,3,4,3,2,3,2,3,0,4,3,3,3,3,3,3,3,3,0,3,2,4,3,3,1,3,4,3,4,4,4,3,4,4,3,2,4,4,1,0,2,0,0,1,1,0,2,0,0,3,1,0,5,3,2,1,3,0,3,0,1,2,4,3,2,4,3,3,0,3,2,0,4,4), +(0,3,0,3,0,1,0,0,0,1,4,3,3,2,3,1,3,1,4,2,3,2,4,2,3,4,3,0,2,2,3,3,3,0,3,3,3,0,3,4,1,3,3,0,3,4,3,3,0,1,1,0,1,0,0,0,4,0,3,0,0,3,1,2,1,3,0,4,0,1,0,4,3,3,4,3,3,0,2,0,0,3,3), +(0,3,0,4,0,1,0,3,0,3,4,3,3,0,3,3,3,1,3,1,3,3,4,3,3,3,0,0,3,1,5,3,3,1,3,3,2,5,4,3,3,4,5,3,2,5,3,4,0,1,0,0,0,0,0,2,0,0,1,1,0,4,2,2,1,3,0,3,0,2,0,4,4,3,5,3,2,0,1,1,0,3,4), +(0,5,0,4,0,5,0,2,0,4,4,3,3,2,3,3,3,1,4,3,4,1,5,3,4,3,4,0,4,2,4,3,4,1,5,4,0,4,4,4,4,5,4,1,3,5,4,2,1,4,1,1,3,2,0,3,1,0,3,2,1,4,3,3,3,4,0,4,0,3,0,4,4,4,3,3,3,0,4,2,0,3,4), +(1,4,0,4,0,3,0,1,0,3,3,3,1,1,3,3,2,2,3,3,1,0,3,2,2,1,2,0,3,1,2,1,2,0,3,2,0,2,2,3,3,4,3,0,3,3,1,2,0,1,1,3,1,2,0,0,3,0,1,1,0,3,2,2,3,3,0,3,0,0,0,2,3,3,4,3,3,0,1,0,0,1,4), +(0,4,0,4,0,4,0,0,0,3,4,4,3,1,4,2,3,2,3,3,3,1,4,3,4,0,3,0,4,2,3,3,2,2,5,4,2,1,3,4,3,4,3,1,3,3,4,2,0,2,1,0,3,3,0,0,2,0,3,1,0,4,4,3,4,3,0,4,0,1,0,2,4,4,4,4,4,0,3,2,0,3,3), +(0,0,0,1,0,4,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,3,2,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,2), +(0,2,0,3,0,4,0,4,0,1,3,3,3,0,4,0,2,1,2,1,1,1,2,0,3,1,1,0,1,0,3,1,0,0,3,3,2,0,1,1,0,0,0,0,0,1,0,2,0,2,2,0,3,1,0,0,1,0,1,1,0,1,2,0,3,0,0,0,0,1,0,0,3,3,4,3,1,0,1,0,3,0,2), +(0,0,0,3,0,5,0,0,0,0,1,0,2,0,3,1,0,1,3,0,0,0,2,0,0,0,1,0,0,0,1,1,0,0,4,0,0,0,2,3,0,1,4,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,1,0,0,0,0,0,0,0,2,0,0,3,0,0,0,0,0,3), +(0,2,0,5,0,5,0,1,0,2,4,3,3,2,5,1,3,2,3,3,3,0,4,1,2,0,3,0,4,0,2,2,1,1,5,3,0,0,1,4,2,3,2,0,3,3,3,2,0,2,4,1,1,2,0,1,1,0,3,1,0,1,3,1,2,3,0,2,0,0,0,1,3,5,4,4,4,0,3,0,0,1,3), +(0,4,0,5,0,4,0,4,0,4,5,4,3,3,4,3,3,3,4,3,4,4,5,3,4,5,4,2,4,2,3,4,3,1,4,4,1,3,5,4,4,5,5,4,4,5,5,5,2,3,3,1,4,3,1,3,3,0,3,3,1,4,3,4,4,4,0,3,0,4,0,3,3,4,4,5,0,0,4,3,0,4,5), +(0,4,0,4,0,3,0,3,0,3,4,4,4,3,3,2,4,3,4,3,4,3,5,3,4,3,2,1,4,2,4,4,3,1,3,4,2,4,5,5,3,4,5,4,1,5,4,3,0,3,2,2,3,2,1,3,1,0,3,3,3,5,3,3,3,5,4,4,2,3,3,4,3,3,3,2,1,0,3,2,1,4,3), +(0,4,0,5,0,4,0,3,0,3,5,5,3,2,4,3,4,0,5,4,4,1,4,4,4,3,3,3,4,3,5,5,2,3,3,4,1,2,5,5,3,5,5,2,3,5,5,4,0,3,2,0,3,3,1,1,5,1,4,1,0,4,3,2,3,5,0,4,0,3,0,5,4,3,4,3,0,0,4,1,0,4,4), +(1,3,0,4,0,2,0,2,0,2,5,5,3,3,3,3,3,0,4,2,3,4,4,4,3,4,0,0,3,4,5,4,3,3,3,3,2,5,5,4,5,5,5,4,3,5,5,5,1,3,1,0,1,0,0,3,2,0,4,2,0,5,2,3,2,4,1,3,0,3,0,4,5,4,5,4,3,0,4,2,0,5,4), +(0,3,0,4,0,5,0,3,0,3,4,4,3,2,3,2,3,3,3,3,3,2,4,3,3,2,2,0,3,3,3,3,3,1,3,3,3,0,4,4,3,4,4,1,1,4,4,2,0,3,1,0,1,1,0,4,1,0,2,3,1,3,3,1,3,4,0,3,0,1,0,3,1,3,0,0,1,0,2,0,0,4,4), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,3,0,3,0,2,0,3,0,1,5,4,3,3,3,1,4,2,1,2,3,4,4,2,4,4,5,0,3,1,4,3,4,0,4,3,3,3,2,3,2,5,3,4,3,2,2,3,0,0,3,0,2,1,0,1,2,0,0,0,0,2,1,1,3,1,0,2,0,4,0,3,4,4,4,5,2,0,2,0,0,1,3), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,0,0,1,1,0,0,0,4,2,1,1,0,1,0,3,2,0,0,3,1,1,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,1,0,0,0,2,0,0,0,1,4,0,4,2,1,0,0,0,0,0,1), +(0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,0,0,3,1,0,0,0,2,0,2,1,0,0,1,2,1,0,1,1,0,0,3,0,0,0,0,0,0,0,0,0,0,0,1,3,1,0,0,0,0,0,1,0,0,2,1,0,0,0,0,0,0,0,0,2), +(0,4,0,4,0,4,0,3,0,4,4,3,4,2,4,3,2,0,4,4,4,3,5,3,5,3,3,2,4,2,4,3,4,3,1,4,0,2,3,4,4,4,3,3,3,4,4,4,3,4,1,3,4,3,2,1,2,1,3,3,3,4,4,3,3,5,0,4,0,3,0,4,3,3,3,2,1,0,3,0,0,3,3), +(0,4,0,3,0,3,0,3,0,3,5,5,3,3,3,3,4,3,4,3,3,3,4,4,4,3,3,3,3,4,3,5,3,3,1,3,2,4,5,5,5,5,4,3,4,5,5,3,2,2,3,3,3,3,2,3,3,1,2,3,2,4,3,3,3,4,0,4,0,2,0,4,3,2,2,1,2,0,3,0,0,4,1), +) + +class JapaneseContextAnalysis(object): + NUM_OF_CATEGORY = 6 + DONT_KNOW = -1 + ENOUGH_REL_THRESHOLD = 100 + MAX_REL_THRESHOLD = 1000 + MINIMUM_DATA_THRESHOLD = 4 + + def __init__(self): + self._total_rel = None + self._rel_sample = None + self._need_to_skip_char_num = None + self._last_char_order = None + self._done = None + self.reset() + + def reset(self): + self._total_rel = 0 # total sequence received + # category counters, each integer counts sequence in its category + self._rel_sample = [0] * self.NUM_OF_CATEGORY + # if last byte in current buffer is not the last byte of a character, + # we need to know how many bytes to skip in next buffer + self._need_to_skip_char_num = 0 + self._last_char_order = -1 # The order of previous char + # If this flag is set to True, detection is done and conclusion has + # been made + self._done = False + + def feed(self, byte_str, num_bytes): + if self._done: + return + + # The buffer we got is byte oriented, and a character may span in more than one + # buffers. In case the last one or two byte in last buffer is not + # complete, we record how many byte needed to complete that character + # and skip these bytes here. We can choose to record those bytes as + # well and analyse the character once it is complete, but since a + # character will not make much difference, by simply skipping + # this character will simply our logic and improve performance. + i = self._need_to_skip_char_num + while i < num_bytes: + order, char_len = self.get_order(byte_str[i:i + 2]) + i += char_len + if i > num_bytes: + self._need_to_skip_char_num = i - num_bytes + self._last_char_order = -1 + else: + if (order != -1) and (self._last_char_order != -1): + self._total_rel += 1 + if self._total_rel > self.MAX_REL_THRESHOLD: + self._done = True + break + self._rel_sample[jp2CharContext[self._last_char_order][order]] += 1 + self._last_char_order = order + + def got_enough_data(self): + return self._total_rel > self.ENOUGH_REL_THRESHOLD + + def get_confidence(self): + # This is just one way to calculate confidence. It works well for me. + if self._total_rel > self.MINIMUM_DATA_THRESHOLD: + return (self._total_rel - self._rel_sample[0]) / self._total_rel + else: + return self.DONT_KNOW + + def get_order(self, byte_str): + return -1, 1 + +class SJISContextAnalysis(JapaneseContextAnalysis): + def __init__(self): + super(SJISContextAnalysis, self).__init__() + self._charset_name = "SHIFT_JIS" + + @property + def charset_name(self): + return self._charset_name + + def get_order(self, byte_str): + if not byte_str: + return -1, 1 + # find out current char's byte length + first_char = byte_str[0] + if (0x81 <= first_char <= 0x9F) or (0xE0 <= first_char <= 0xFC): + char_len = 2 + if (first_char == 0x87) or (0xFA <= first_char <= 0xFC): + self._charset_name = "CP932" + else: + char_len = 1 + + # return its order if it is hiragana + if len(byte_str) > 1: + second_char = byte_str[1] + if (first_char == 202) and (0x9F <= second_char <= 0xF1): + return second_char - 0x9F, char_len + + return -1, char_len + +class EUCJPContextAnalysis(JapaneseContextAnalysis): + def get_order(self, byte_str): + if not byte_str: + return -1, 1 + # find out current char's byte length + first_char = byte_str[0] + if (first_char == 0x8E) or (0xA1 <= first_char <= 0xFE): + char_len = 2 + elif first_char == 0x8F: + char_len = 3 + else: + char_len = 1 + + # return its order if it is hiragana + if len(byte_str) > 1: + second_char = byte_str[1] + if (first_char == 0xA4) and (0xA1 <= second_char <= 0xF3): + return second_char - 0xA1, char_len + + return -1, char_len + + diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/langbulgarianmodel.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/langbulgarianmodel.py new file mode 100644 index 0000000..2aa4fb2 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/langbulgarianmodel.py @@ -0,0 +1,228 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# 255: Control characters that usually does not exist in any text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 + +# Character Mapping Table: +# this table is modified base on win1251BulgarianCharToOrderMap, so +# only number <64 is sure valid + +Latin5_BulgarianCharToOrderMap = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 77, 90, 99,100, 72,109,107,101, 79,185, 81,102, 76, 94, 82, # 40 +110,186,108, 91, 74,119, 84, 96,111,187,115,253,253,253,253,253, # 50 +253, 65, 69, 70, 66, 63, 68,112,103, 92,194,104, 95, 86, 87, 71, # 60 +116,195, 85, 93, 97,113,196,197,198,199,200,253,253,253,253,253, # 70 +194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209, # 80 +210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225, # 90 + 81,226,227,228,229,230,105,231,232,233,234,235,236, 45,237,238, # a0 + 31, 32, 35, 43, 37, 44, 55, 47, 40, 59, 33, 46, 38, 36, 41, 30, # b0 + 39, 28, 34, 51, 48, 49, 53, 50, 54, 57, 61,239, 67,240, 60, 56, # c0 + 1, 18, 9, 20, 11, 3, 23, 15, 2, 26, 12, 10, 14, 6, 4, 13, # d0 + 7, 8, 5, 19, 29, 25, 22, 21, 27, 24, 17, 75, 52,241, 42, 16, # e0 + 62,242,243,244, 58,245, 98,246,247,248,249,250,251, 91,252,253, # f0 +) + +win1251BulgarianCharToOrderMap = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 77, 90, 99,100, 72,109,107,101, 79,185, 81,102, 76, 94, 82, # 40 +110,186,108, 91, 74,119, 84, 96,111,187,115,253,253,253,253,253, # 50 +253, 65, 69, 70, 66, 63, 68,112,103, 92,194,104, 95, 86, 87, 71, # 60 +116,195, 85, 93, 97,113,196,197,198,199,200,253,253,253,253,253, # 70 +206,207,208,209,210,211,212,213,120,214,215,216,217,218,219,220, # 80 +221, 78, 64, 83,121, 98,117,105,222,223,224,225,226,227,228,229, # 90 + 88,230,231,232,233,122, 89,106,234,235,236,237,238, 45,239,240, # a0 + 73, 80,118,114,241,242,243,244,245, 62, 58,246,247,248,249,250, # b0 + 31, 32, 35, 43, 37, 44, 55, 47, 40, 59, 33, 46, 38, 36, 41, 30, # c0 + 39, 28, 34, 51, 48, 49, 53, 50, 54, 57, 61,251, 67,252, 60, 56, # d0 + 1, 18, 9, 20, 11, 3, 23, 15, 2, 26, 12, 10, 14, 6, 4, 13, # e0 + 7, 8, 5, 19, 29, 25, 22, 21, 27, 24, 17, 75, 52,253, 42, 16, # f0 +) + +# Model Table: +# total sequences: 100% +# first 512 sequences: 96.9392% +# first 1024 sequences:3.0618% +# rest sequences: 0.2992% +# negative sequences: 0.0020% +BulgarianLangModel = ( +0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,2,3,3,3,3,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,3,2,2,3,2,2,1,2,2, +3,1,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,3,3,3,3,3,3,3,3,0,3,0,1, +0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,3,3,3,3,3,3,3,3,0,3,1,0, +0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,1,3,2,3,3,3,3,3,3,3,3,0,3,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,1,3,2,3,3,3,3,3,3,3,3,0,3,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,2,3,2,2,1,3,3,3,3,2,2,2,1,1,2,0,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,2,3,2,2,3,3,1,1,2,3,3,2,3,3,3,3,2,1,2,0,2,0,3,0,0, +0,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,1,3,3,3,3,3,2,3,2,3,3,3,3,3,2,3,3,1,3,0,3,0,2,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,3,1,3,3,2,3,3,3,1,3,3,2,3,2,2,2,0,0,2,0,2,0,2,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,3,3,0,3,3,3,2,2,3,3,3,1,2,2,3,2,1,1,2,0,2,0,0,0,0, +1,0,0,0,0,0,0,0,0,0,2,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,2,3,3,1,2,3,2,2,2,3,3,3,3,3,2,2,3,1,2,0,2,1,2,0,0, +0,0,0,0,0,0,0,0,0,0,3,0,0,1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,1,3,3,3,3,3,2,3,3,3,2,3,3,2,3,2,2,2,3,1,2,0,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,3,3,3,3,1,1,1,2,2,1,3,1,3,2,2,3,0,0,1,0,1,0,1,0,0, +0,0,0,1,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,2,2,3,2,2,3,1,2,1,1,1,2,3,1,3,1,2,2,0,1,1,1,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,1,3,2,2,3,3,1,2,3,1,1,3,3,3,3,1,2,2,1,1,1,0,2,0,2,0,1, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,2,2,3,3,3,2,2,1,1,2,0,2,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,0,1,2,1,3,3,2,3,3,3,3,3,2,3,2,1,0,3,1,2,1,2,1,2,3,2,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,1,1,2,3,3,3,3,3,3,3,3,3,3,3,3,0,0,3,1,3,3,2,3,3,2,2,2,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,3,0,3,3,3,3,3,2,1,1,2,1,3,3,0,3,1,1,1,1,3,2,0,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,1,1,3,1,3,3,2,3,2,2,2,3,0,2,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,2,3,3,2,2,3,2,1,1,1,1,1,3,1,3,1,1,0,0,0,1,0,0,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,2,3,2,0,3,2,0,3,0,2,0,0,2,1,3,1,0,0,1,0,0,0,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,2,1,1,1,1,2,1,1,2,1,1,1,2,2,1,2,1,1,1,0,1,1,0,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,2,1,3,1,1,2,1,3,2,1,1,0,1,2,3,2,1,1,1,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,3,2,2,1,0,1,0,0,1,0,0,0,2,1,0,3,0,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,2,3,2,3,3,1,3,2,1,1,1,2,1,1,2,1,3,0,1,0,0,0,1,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,1,2,2,3,3,2,3,2,2,2,3,1,2,2,1,1,2,1,1,2,2,0,1,1,0,1,0,2,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,2,1,3,1,0,2,2,1,3,2,1,0,0,2,0,2,0,1,0,0,0,0,0,0,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,1,2,0,2,3,1,2,3,2,0,1,3,1,2,1,1,1,0,0,1,0,0,2,2,2,3, +2,2,2,2,1,2,1,1,2,2,1,1,2,0,1,1,1,0,0,1,1,0,0,1,1,0,0,0,1,1,0,1, +3,3,3,3,3,2,1,2,2,1,2,0,2,0,1,0,1,2,1,2,1,1,0,0,0,1,0,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, +3,3,2,3,3,1,1,3,1,0,3,2,1,0,0,0,1,2,0,2,0,1,0,0,0,1,0,1,2,1,2,2, +1,1,1,1,1,1,1,2,2,2,1,1,1,1,1,1,1,0,1,2,1,1,1,0,0,0,0,0,1,1,0,0, +3,1,0,1,0,2,3,2,2,2,3,2,2,2,2,2,1,0,2,1,2,1,1,1,0,1,2,1,2,2,2,1, +1,1,2,2,2,2,1,2,1,1,0,1,2,1,2,2,2,1,1,1,0,1,1,1,1,2,0,1,0,0,0,0, +2,3,2,3,3,0,0,2,1,0,2,1,0,0,0,0,2,3,0,2,0,0,0,0,0,1,0,0,2,0,1,2, +2,1,2,1,2,2,1,1,1,2,1,1,1,0,1,2,2,1,1,1,1,1,0,1,1,1,0,0,1,2,0,0, +3,3,2,2,3,0,2,3,1,1,2,0,0,0,1,0,0,2,0,2,0,0,0,1,0,1,0,1,2,0,2,2, +1,1,1,1,2,1,0,1,2,2,2,1,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0,1,1,0,0, +2,3,2,3,3,0,0,3,0,1,1,0,1,0,0,0,2,2,1,2,0,0,0,0,0,0,0,0,2,0,1,2, +2,2,1,1,1,1,1,2,2,2,1,0,2,0,1,0,1,0,0,1,0,1,0,0,1,0,0,0,0,1,0,0, +3,3,3,3,2,2,2,2,2,0,2,1,1,1,1,2,1,2,1,1,0,2,0,1,0,1,0,0,2,0,1,2, +1,1,1,1,1,1,1,2,2,1,1,0,2,0,1,0,2,0,0,1,1,1,0,0,2,0,0,0,1,1,0,0, +2,3,3,3,3,1,0,0,0,0,0,0,0,0,0,0,2,0,0,1,1,0,0,0,0,0,0,1,2,0,1,2, +2,2,2,1,1,2,1,1,2,2,2,1,2,0,1,1,1,1,1,1,0,1,1,1,1,0,0,1,1,1,0,0, +2,3,3,3,3,0,2,2,0,2,1,0,0,0,1,1,1,2,0,2,0,0,0,3,0,0,0,0,2,0,2,2, +1,1,1,2,1,2,1,1,2,2,2,1,2,0,1,1,1,0,1,1,1,1,0,2,1,0,0,0,1,1,0,0, +2,3,3,3,3,0,2,1,0,0,2,0,0,0,0,0,1,2,0,2,0,0,0,0,0,0,0,0,2,0,1,2, +1,1,1,2,1,1,1,1,2,2,2,0,1,0,1,1,1,0,0,1,1,1,0,0,1,0,0,0,0,1,0,0, +3,3,2,2,3,0,1,0,1,0,0,0,0,0,0,0,1,1,0,3,0,0,0,0,0,0,0,0,1,0,2,2, +1,1,1,1,1,2,1,1,2,2,1,2,2,1,0,1,1,1,1,1,0,1,0,0,1,0,0,0,1,1,0,0, +3,1,0,1,0,2,2,2,2,3,2,1,1,1,2,3,0,0,1,0,2,1,1,0,1,1,1,1,2,1,1,1, +1,2,2,1,2,1,2,2,1,1,0,1,2,1,2,2,1,1,1,0,0,1,1,1,2,1,0,1,0,0,0,0, +2,1,0,1,0,3,1,2,2,2,2,1,2,2,1,1,1,0,2,1,2,2,1,1,2,1,1,0,2,1,1,1, +1,2,2,2,2,2,2,2,1,2,0,1,1,0,2,1,1,1,1,1,0,0,1,1,1,1,0,1,0,0,0,0, +2,1,1,1,1,2,2,2,2,1,2,2,2,1,2,2,1,1,2,1,2,3,2,2,1,1,1,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,3,2,0,1,2,0,1,2,1,1,0,1,0,1,2,1,2,0,0,0,1,1,0,0,0,1,0,0,2, +1,1,0,0,1,1,0,1,1,1,1,0,2,0,1,1,1,0,0,1,1,0,0,0,0,1,0,0,0,1,0,0, +2,0,0,0,0,1,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,0,1,1,1,1,1,2,1,1,1, +1,2,2,2,2,1,1,2,1,2,1,1,1,0,2,1,2,1,1,1,0,2,1,1,1,1,0,1,0,0,0,0, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0, +1,1,0,1,0,1,1,1,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,3,2,0,0,0,0,1,0,0,0,0,0,0,1,1,0,2,0,0,0,0,0,0,0,0,1,0,1,2, +1,1,1,1,1,1,0,0,2,2,2,2,2,0,1,1,0,1,1,1,1,1,0,0,1,0,0,0,1,1,0,1, +2,3,1,2,1,0,1,1,0,2,2,2,0,0,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,0,1,2, +1,1,1,1,2,1,1,1,1,1,1,1,1,0,1,1,0,1,0,1,0,1,0,0,1,0,0,0,0,1,0,0, +2,2,2,2,2,0,0,2,0,0,2,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,2,0,2,2, +1,1,1,1,1,0,0,1,2,1,1,0,1,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,2,2,0,0,2,0,1,1,0,0,0,1,0,0,2,0,2,0,0,0,0,0,0,0,0,0,0,1,1, +0,0,0,1,1,1,1,1,1,1,1,1,1,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,3,2,0,0,1,0,0,1,0,0,0,0,0,0,1,0,2,0,0,0,1,0,0,0,0,0,0,0,2, +1,1,0,0,1,0,0,0,1,1,0,0,1,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, +2,1,2,2,2,1,2,1,2,2,1,1,2,1,1,1,0,1,1,1,1,2,0,1,0,1,1,1,1,0,1,1, +1,1,2,1,1,1,1,1,1,0,0,1,2,1,1,1,1,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0, +1,0,0,1,3,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,2,1,0,0,1,0,2,0,0,0,0,0,1,1,1,0,1,0,0,0,0,0,0,0,0,2,0,0,1, +0,2,0,1,0,0,1,1,2,0,1,0,1,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,2,2,0,1,1,0,2,1,0,1,1,1,0,0,1,0,2,0,1,0,0,0,0,0,0,0,0,0,1, +0,1,0,0,1,0,0,0,1,1,0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,2,2,0,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1, +0,1,0,1,1,1,0,0,1,1,1,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, +2,0,1,0,0,1,2,1,1,1,1,1,1,2,2,1,0,0,1,0,1,0,0,0,0,1,1,1,1,0,0,0, +1,1,2,1,1,1,1,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,1,2,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1, +0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, +0,1,1,0,1,1,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0, +1,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,2,0,0,2,0,1,0,0,1,0,0,1, +1,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0, +1,1,1,1,1,1,1,2,0,0,0,0,0,0,2,1,0,1,1,0,0,1,1,1,0,1,0,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,0,1,1,1,1,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +) + +Latin5BulgarianModel = { + 'char_to_order_map': Latin5_BulgarianCharToOrderMap, + 'precedence_matrix': BulgarianLangModel, + 'typical_positive_ratio': 0.969392, + 'keep_english_letter': False, + 'charset_name': "ISO-8859-5", + 'language': 'Bulgairan', +} + +Win1251BulgarianModel = { + 'char_to_order_map': win1251BulgarianCharToOrderMap, + 'precedence_matrix': BulgarianLangModel, + 'typical_positive_ratio': 0.969392, + 'keep_english_letter': False, + 'charset_name': "windows-1251", + 'language': 'Bulgarian', +} diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/langcyrillicmodel.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/langcyrillicmodel.py new file mode 100644 index 0000000..e5f9a1f --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/langcyrillicmodel.py @@ -0,0 +1,333 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# KOI8-R language model +# Character Mapping Table: +KOI8R_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 +191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, # 80 +207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, # 90 +223,224,225, 68,226,227,228,229,230,231,232,233,234,235,236,237, # a0 +238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253, # b0 + 27, 3, 21, 28, 13, 2, 39, 19, 26, 4, 23, 11, 8, 12, 5, 1, # c0 + 15, 16, 9, 7, 6, 14, 24, 10, 17, 18, 20, 25, 30, 29, 22, 54, # d0 + 59, 37, 44, 58, 41, 48, 53, 46, 55, 42, 60, 36, 49, 38, 31, 34, # e0 + 35, 43, 45, 32, 40, 52, 56, 33, 61, 62, 51, 57, 47, 63, 50, 70, # f0 +) + +win1251_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 +191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, +207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, +223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, +239,240,241,242,243,244,245,246, 68,247,248,249,250,251,252,253, + 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, + 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, + 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, + 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16, +) + +latin5_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 +191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, +207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, +223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, + 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, + 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, + 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, + 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16, +239, 68,240,241,242,243,244,245,246,247,248,249,250,251,252,255, +) + +macCyrillic_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 + 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, + 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, +191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, +207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, +223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, +239,240,241,242,243,244,245,246,247,248,249,250,251,252, 68, 16, + 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, + 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27,255, +) + +IBM855_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 +191,192,193,194, 68,195,196,197,198,199,200,201,202,203,204,205, +206,207,208,209,210,211,212,213,214,215,216,217, 27, 59, 54, 70, + 3, 37, 21, 44, 28, 58, 13, 41, 2, 48, 39, 53, 19, 46,218,219, +220,221,222,223,224, 26, 55, 4, 42,225,226,227,228, 23, 60,229, +230,231,232,233,234,235, 11, 36,236,237,238,239,240,241,242,243, + 8, 49, 12, 38, 5, 31, 1, 34, 15,244,245,246,247, 35, 16,248, + 43, 9, 45, 7, 32, 6, 40, 14, 52, 24, 56, 10, 33, 17, 61,249, +250, 18, 62, 20, 51, 25, 57, 30, 47, 29, 63, 22, 50,251,252,255, +) + +IBM866_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 + 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, + 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, + 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, +191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, +207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, +223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, + 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16, +239, 68,240,241,242,243,244,245,246,247,248,249,250,251,252,255, +) + +# Model Table: +# total sequences: 100% +# first 512 sequences: 97.6601% +# first 1024 sequences: 2.3389% +# rest sequences: 0.1237% +# negative sequences: 0.0009% +RussianLangModel = ( +0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,1,3,3,3,3,1,3,3,3,2,3,2,3,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,3,2,2,2,2,2,0,0,2, +3,3,3,2,3,3,3,3,3,3,3,3,3,3,2,3,3,0,0,3,3,3,3,3,3,3,3,3,2,3,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,2,2,3,3,3,3,3,3,3,3,3,2,3,3,0,0,3,3,3,3,3,3,3,3,2,3,3,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,3,3,3,3,3,3,3,3,3,3,3,2,1, +0,0,0,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,0,0,3,3,3,3,3,3,3,3,3,3,3,2,1, +0,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,2,2,2,3,1,3,3,1,3,3,3,3,2,2,3,0,2,2,2,3,3,2,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,3,3,3,3,3,2,2,3,2,3,3,3,2,1,2,2,0,1,2,2,2,2,2,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,0,2,2,3,3,2,1,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,3,3,1,2,3,2,2,3,2,3,3,3,3,2,2,3,0,3,2,2,3,1,1,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,2,3,3,3,3,2,2,2,0,3,3,3,2,2,2,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,2,3,2,3,3,3,3,3,3,2,3,2,2,0,1,3,2,1,2,2,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,2,1,1,3,0,1,1,1,1,2,1,1,0,2,2,2,1,2,0,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,3,3,2,2,2,2,1,3,2,3,2,3,2,1,2,2,0,1,1,2,1,2,1,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,3,3,3,2,2,2,2,0,2,2,2,2,3,1,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +3,2,3,2,2,3,3,3,3,3,3,3,3,3,1,3,2,0,0,3,3,3,3,2,3,3,3,3,2,3,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,3,3,2,2,3,3,0,2,1,0,3,2,3,2,3,0,0,1,2,0,0,1,0,1,2,1,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,3,0,2,3,3,3,3,2,3,3,3,3,1,2,2,0,0,2,3,2,2,2,3,2,3,2,2,3,0,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,3,0,2,3,2,3,0,1,2,3,3,2,0,2,3,0,0,2,3,2,2,0,1,3,1,3,2,2,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,3,0,2,3,3,3,3,3,3,3,3,2,1,3,2,0,0,2,2,3,3,3,2,3,3,0,2,2,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,2,3,3,2,2,2,3,3,0,0,1,1,1,1,1,2,0,0,1,1,1,1,0,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,2,3,3,3,3,3,3,3,0,3,2,3,3,2,3,2,0,2,1,0,1,1,0,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,3,3,3,2,2,2,2,3,1,3,2,3,1,1,2,1,0,2,2,2,2,1,3,1,0, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +2,2,3,3,3,3,3,1,2,2,1,3,1,0,3,0,0,3,0,0,0,1,1,0,1,2,1,0,0,0,0,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,2,1,1,3,3,3,2,2,1,2,2,3,1,1,2,0,0,2,2,1,3,0,0,2,1,1,2,1,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,3,3,3,3,1,2,2,2,1,2,1,3,3,1,1,2,1,2,1,2,2,0,2,0,0,1,1,0,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,3,3,2,1,3,2,2,3,2,0,3,2,0,3,0,1,0,1,1,0,0,1,1,1,1,0,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,2,3,3,3,2,2,2,3,3,1,2,1,2,1,0,1,0,1,1,0,1,0,0,2,1,1,1,0,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +3,1,1,2,1,2,3,3,2,2,1,2,2,3,0,2,1,0,0,2,2,3,2,1,2,2,2,2,2,3,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,1,1,0,1,1,2,2,1,1,3,0,0,1,3,1,1,1,0,0,0,1,0,1,1,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,1,3,3,3,2,0,0,0,2,1,0,1,0,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,1,0,0,2,3,2,2,2,1,2,2,2,1,2,1,0,0,1,1,1,0,2,0,1,1,1,0,0,1,1, +1,0,0,0,0,0,1,2,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,3,0,0,0,0,1,0,0,0,0,3,0,1,2,1,0,0,0,0,0,0,0,1,1,0,0,1,1, +1,0,1,0,1,2,0,0,1,1,2,1,0,1,1,1,1,0,1,1,1,1,0,1,0,0,1,0,0,1,1,0, +2,2,3,2,2,2,3,1,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,0,1,0,1,1,1,0,2,1, +1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,0,1,1,1,0,1,1,0, +3,3,3,2,2,2,2,3,2,2,1,1,2,2,2,2,1,1,3,1,2,1,2,0,0,1,1,0,1,0,2,1, +1,1,1,1,1,2,1,0,1,1,1,1,0,1,0,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,1,0, +2,0,0,1,0,3,2,2,2,2,1,2,1,2,1,2,0,0,0,2,1,2,2,1,1,2,2,0,1,1,0,2, +1,1,1,1,1,0,1,1,1,2,1,1,1,2,1,0,1,2,1,1,1,1,0,1,1,1,0,0,1,0,0,1, +1,3,2,2,2,1,1,1,2,3,0,0,0,0,2,0,2,2,1,0,0,0,0,0,0,1,0,0,0,0,1,1, +1,0,1,1,0,1,0,1,1,0,1,1,0,2,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0, +2,3,2,3,2,1,2,2,2,2,1,0,0,0,2,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,2,1, +1,1,2,1,0,2,0,0,1,0,1,0,0,1,0,0,1,1,0,1,1,0,0,0,0,0,1,0,0,0,0,0, +3,0,0,1,0,2,2,2,3,2,2,2,2,2,2,2,0,0,0,2,1,2,1,1,1,2,2,0,0,0,1,2, +1,1,1,1,1,0,1,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0,0,1, +2,3,2,3,3,2,0,1,1,1,0,0,1,0,2,0,1,1,3,1,0,0,0,0,0,0,0,1,0,0,2,1, +1,1,1,1,1,1,1,0,1,0,1,1,1,1,0,1,1,1,0,0,1,1,0,1,0,0,0,0,0,0,1,0, +2,3,3,3,3,1,2,2,2,2,0,1,1,0,2,1,1,1,2,1,0,1,1,0,0,1,0,1,0,0,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,2,0,0,1,1,2,2,1,0,0,2,0,1,1,3,0,0,1,0,0,0,0,0,1,0,1,2,1, +1,1,2,0,1,1,1,0,1,0,1,1,0,1,0,1,1,1,1,0,1,0,0,0,0,0,0,1,0,1,1,0, +1,3,2,3,2,1,0,0,2,2,2,0,1,0,2,0,1,1,1,0,1,0,0,0,3,0,1,1,0,0,2,1, +1,1,1,0,1,1,0,0,0,0,1,1,0,1,0,0,2,1,1,0,1,0,0,0,1,0,1,0,0,1,1,0, +3,1,2,1,1,2,2,2,2,2,2,1,2,2,1,1,0,0,0,2,2,2,0,0,0,1,2,1,0,1,0,1, +2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,2,1,1,1,0,1,0,1,1,0,1,1,1,0,0,1, +3,0,0,0,0,2,0,1,1,1,1,1,1,1,0,1,0,0,0,1,1,1,0,1,0,1,1,0,0,1,0,1, +1,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,1, +1,3,3,2,2,0,0,0,2,2,0,0,0,1,2,0,1,1,2,0,0,0,0,0,0,0,0,1,0,0,2,1, +0,1,1,0,0,1,1,0,0,0,1,1,0,1,1,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,1,0, +2,3,2,3,2,0,0,0,0,1,1,0,0,0,2,0,2,0,2,0,0,0,0,0,1,0,0,1,0,0,1,1, +1,1,2,0,1,2,1,0,1,1,2,1,1,1,1,1,2,1,1,0,1,0,0,1,1,1,1,1,0,1,1,0, +1,3,2,2,2,1,0,0,2,2,1,0,1,2,2,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1,1, +0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,1,0,2,3,1,2,2,2,2,2,2,1,1,0,0,0,1,0,1,0,2,1,1,1,0,0,0,0,1, +1,1,0,1,1,0,1,1,1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, +2,0,2,0,0,1,0,3,2,1,2,1,2,2,0,1,0,0,0,2,1,0,0,2,1,1,1,1,0,2,0,2, +2,1,1,1,1,1,1,1,1,1,1,1,1,2,1,0,1,1,1,1,0,0,0,1,1,1,1,0,1,0,0,1, +1,2,2,2,2,1,0,0,1,0,0,0,0,0,2,0,1,1,1,1,0,0,0,0,1,0,1,2,0,0,2,0, +1,0,1,1,1,2,1,0,1,0,1,1,0,0,1,0,1,1,1,0,1,0,0,0,1,0,0,1,0,1,1,0, +2,1,2,2,2,0,3,0,1,1,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +0,0,0,1,1,1,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0, +1,2,2,3,2,2,0,0,1,1,2,0,1,2,1,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1, +0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,1,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0, +2,2,1,1,2,1,2,2,2,2,2,1,2,2,0,1,0,0,0,1,2,2,2,1,2,1,1,1,1,1,2,1, +1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,0,1,1,1,0,0,0,0,1,1,1,0,1,1,0,0,1, +1,2,2,2,2,0,1,0,2,2,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0, +0,0,1,0,0,1,0,0,0,0,1,0,1,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,2,2,0,0,0,2,2,2,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1, +0,1,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,2,2,0,0,0,0,1,0,0,1,1,2,0,0,0,0,1,0,1,0,0,1,0,0,2,0,0,0,1, +0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,2,1,1,2,0,2,1,1,1,1,0,2,2,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1, +0,0,1,0,1,1,0,0,0,0,1,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +1,0,2,1,2,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0, +0,0,1,0,1,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0, +1,0,0,0,0,2,0,1,2,1,0,1,1,1,0,1,0,0,0,1,0,1,0,0,1,0,1,0,0,0,0,1, +0,0,0,0,0,1,0,0,1,1,0,0,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1, +2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +1,1,1,0,1,0,1,0,0,1,1,1,1,0,0,0,1,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +1,1,0,1,1,0,1,0,1,0,0,0,0,1,1,0,1,1,0,0,0,0,0,1,0,1,1,0,1,0,0,0, +0,1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, +) + +Koi8rModel = { + 'char_to_order_map': KOI8R_char_to_order_map, + 'precedence_matrix': RussianLangModel, + 'typical_positive_ratio': 0.976601, + 'keep_english_letter': False, + 'charset_name': "KOI8-R", + 'language': 'Russian', +} + +Win1251CyrillicModel = { + 'char_to_order_map': win1251_char_to_order_map, + 'precedence_matrix': RussianLangModel, + 'typical_positive_ratio': 0.976601, + 'keep_english_letter': False, + 'charset_name': "windows-1251", + 'language': 'Russian', +} + +Latin5CyrillicModel = { + 'char_to_order_map': latin5_char_to_order_map, + 'precedence_matrix': RussianLangModel, + 'typical_positive_ratio': 0.976601, + 'keep_english_letter': False, + 'charset_name': "ISO-8859-5", + 'language': 'Russian', +} + +MacCyrillicModel = { + 'char_to_order_map': macCyrillic_char_to_order_map, + 'precedence_matrix': RussianLangModel, + 'typical_positive_ratio': 0.976601, + 'keep_english_letter': False, + 'charset_name': "MacCyrillic", + 'language': 'Russian', +} + +Ibm866Model = { + 'char_to_order_map': IBM866_char_to_order_map, + 'precedence_matrix': RussianLangModel, + 'typical_positive_ratio': 0.976601, + 'keep_english_letter': False, + 'charset_name': "IBM866", + 'language': 'Russian', +} + +Ibm855Model = { + 'char_to_order_map': IBM855_char_to_order_map, + 'precedence_matrix': RussianLangModel, + 'typical_positive_ratio': 0.976601, + 'keep_english_letter': False, + 'charset_name': "IBM855", + 'language': 'Russian', +} diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/langgreekmodel.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/langgreekmodel.py new file mode 100644 index 0000000..5332221 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/langgreekmodel.py @@ -0,0 +1,225 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# 255: Control characters that usually does not exist in any text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 + +# Character Mapping Table: +Latin7_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 82,100,104, 94, 98,101,116,102,111,187,117, 92, 88,113, 85, # 40 + 79,118,105, 83, 67,114,119, 95, 99,109,188,253,253,253,253,253, # 50 +253, 72, 70, 80, 81, 60, 96, 93, 89, 68,120, 97, 77, 86, 69, 55, # 60 + 78,115, 65, 66, 58, 76,106,103, 87,107,112,253,253,253,253,253, # 70 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 80 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 90 +253,233, 90,253,253,253,253,253,253,253,253,253,253, 74,253,253, # a0 +253,253,253,253,247,248, 61, 36, 46, 71, 73,253, 54,253,108,123, # b0 +110, 31, 51, 43, 41, 34, 91, 40, 52, 47, 44, 53, 38, 49, 59, 39, # c0 + 35, 48,250, 37, 33, 45, 56, 50, 84, 57,120,121, 17, 18, 22, 15, # d0 +124, 1, 29, 20, 21, 3, 32, 13, 25, 5, 11, 16, 10, 6, 30, 4, # e0 + 9, 8, 14, 7, 2, 12, 28, 23, 42, 24, 64, 75, 19, 26, 27,253, # f0 +) + +win1253_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 82,100,104, 94, 98,101,116,102,111,187,117, 92, 88,113, 85, # 40 + 79,118,105, 83, 67,114,119, 95, 99,109,188,253,253,253,253,253, # 50 +253, 72, 70, 80, 81, 60, 96, 93, 89, 68,120, 97, 77, 86, 69, 55, # 60 + 78,115, 65, 66, 58, 76,106,103, 87,107,112,253,253,253,253,253, # 70 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 80 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 90 +253,233, 61,253,253,253,253,253,253,253,253,253,253, 74,253,253, # a0 +253,253,253,253,247,253,253, 36, 46, 71, 73,253, 54,253,108,123, # b0 +110, 31, 51, 43, 41, 34, 91, 40, 52, 47, 44, 53, 38, 49, 59, 39, # c0 + 35, 48,250, 37, 33, 45, 56, 50, 84, 57,120,121, 17, 18, 22, 15, # d0 +124, 1, 29, 20, 21, 3, 32, 13, 25, 5, 11, 16, 10, 6, 30, 4, # e0 + 9, 8, 14, 7, 2, 12, 28, 23, 42, 24, 64, 75, 19, 26, 27,253, # f0 +) + +# Model Table: +# total sequences: 100% +# first 512 sequences: 98.2851% +# first 1024 sequences:1.7001% +# rest sequences: 0.0359% +# negative sequences: 0.0148% +GreekLangModel = ( +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,2,2,3,3,3,3,3,3,3,3,1,3,3,3,0,2,2,3,3,0,3,0,3,2,0,3,3,3,0, +3,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,0,3,3,0,3,2,3,3,0,3,2,3,3,3,0,0,3,0,3,0,3,3,2,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, +0,2,3,2,2,3,3,3,3,3,3,3,3,0,3,3,3,3,0,2,3,3,0,3,3,3,3,2,3,3,3,0, +2,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,0,2,1,3,3,3,3,2,3,3,2,3,3,2,0, +0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,0,3,3,3,3,3,3,0,3,3,0,3,3,3,3,3,3,3,3,3,3,0,3,2,3,3,0, +2,0,1,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,2,3,0,0,0,0,3,3,0,3,1,3,3,3,0,3,3,0,3,3,3,3,0,0,0,0, +2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,0,3,0,3,3,3,3,3,0,3,2,2,2,3,0,2,3,3,3,3,3,2,3,3,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,3,2,2,2,3,3,3,3,0,3,1,3,3,3,3,2,3,3,3,3,3,3,3,2,2,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,2,0,3,0,0,0,3,3,2,3,3,3,3,3,0,0,3,2,3,0,2,3,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,3,3,3,3,0,0,3,3,0,2,3,0,3,0,3,3,3,0,0,3,0,3,0,2,2,3,3,0,0, +0,0,1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,2,0,3,2,3,3,3,3,0,3,3,3,3,3,0,3,3,2,3,2,3,3,2,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,2,3,2,3,3,3,3,3,3,0,2,3,2,3,2,2,2,3,2,3,3,2,3,0,2,2,2,3,0, +2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,0,0,0,3,3,3,2,3,3,0,0,3,0,3,0,0,0,3,2,0,3,0,3,0,0,2,0,2,0, +0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,0,3,3,3,3,3,3,0,3,3,0,3,0,0,0,3,3,0,3,3,3,0,0,1,2,3,0, +3,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,2,0,0,3,2,2,3,3,0,3,3,3,3,3,2,1,3,0,3,2,3,3,2,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,3,0,2,3,3,3,3,3,3,0,0,3,0,3,0,0,0,3,3,0,3,2,3,0,0,3,3,3,0, +3,0,0,0,2,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,0,3,3,3,3,3,3,0,0,3,0,3,0,0,0,3,2,0,3,2,3,0,0,3,2,3,0, +2,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,1,2,2,3,3,3,3,3,3,0,2,3,0,3,0,0,0,3,3,0,3,0,2,0,0,2,3,1,0, +2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,3,3,3,3,0,3,0,3,3,2,3,0,3,3,3,3,3,3,0,3,3,3,0,2,3,0,0,3,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,3,3,3,0,0,3,0,0,0,3,3,0,3,0,2,3,3,0,0,3,0,3,0,3,3,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,0,0,0,3,3,3,3,3,3,0,0,3,0,2,0,0,0,3,3,0,3,0,3,0,0,2,0,2,0, +0,0,0,0,1,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,3,0,3,0,2,0,3,2,0,3,2,3,2,3,0,0,3,2,3,2,3,3,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,0,0,2,3,3,3,3,3,0,0,0,3,0,2,1,0,0,3,2,2,2,0,3,0,0,2,2,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,3,3,3,2,0,3,0,3,0,3,3,0,2,1,2,3,3,0,0,3,0,3,0,3,3,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,3,3,3,0,3,3,3,3,3,3,0,2,3,0,3,0,0,0,2,1,0,2,2,3,0,0,2,2,2,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,0,0,2,3,3,3,2,3,0,0,1,3,0,2,0,0,0,0,3,0,1,0,2,0,0,1,1,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,1,0,3,0,0,0,3,2,0,3,2,3,3,3,0,0,3,0,3,2,2,2,1,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,3,3,3,0,0,3,0,0,0,0,2,0,2,3,3,2,2,2,2,3,0,2,0,2,2,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,2,0,0,0,0,0,0,2,3,0,2,0,2,3,2,0,0,3,0,3,0,3,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,3,2,3,3,2,2,3,0,2,0,3,0,0,0,2,0,0,0,0,1,2,0,2,0,2,0, +0,2,0,2,0,2,2,0,0,1,0,2,2,2,0,2,2,2,0,2,2,2,0,0,2,0,0,1,0,0,0,0, +0,2,0,3,3,2,0,0,0,0,0,0,1,3,0,2,0,2,2,2,0,0,2,0,3,0,0,2,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,2,3,2,0,2,2,0,2,0,2,2,0,2,0,2,2,2,0,0,0,0,0,0,2,3,0,0,0,2, +0,1,2,0,0,0,0,2,2,0,0,0,2,1,0,2,2,0,0,0,0,0,0,1,0,2,0,0,0,0,0,0, +0,0,2,1,0,2,3,2,2,3,2,3,2,0,0,3,3,3,0,0,3,2,0,0,0,1,1,0,2,0,2,2, +0,2,0,2,0,2,2,0,0,2,0,2,2,2,0,2,2,2,2,0,0,2,0,0,0,2,0,1,0,0,0,0, +0,3,0,3,3,2,2,0,3,0,0,0,2,2,0,2,2,2,1,2,0,0,1,2,2,0,0,3,0,0,0,2, +0,1,2,0,0,0,1,2,0,0,0,0,0,0,0,2,2,0,1,0,0,2,0,0,0,2,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,3,3,2,2,0,0,0,2,0,2,3,3,0,2,0,0,0,0,0,0,2,2,2,0,2,2,0,2,0,2, +0,2,2,0,0,2,2,2,2,1,0,0,2,2,0,2,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0, +0,2,0,3,2,3,0,0,0,3,0,0,2,2,0,2,0,2,2,2,0,0,2,0,0,0,0,0,0,0,0,2, +0,0,2,2,0,0,2,2,2,0,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,2,0,0,3,2,0,2,2,2,2,2,0,0,0,2,0,0,0,0,2,0,1,0,0,2,0,1,0,0,0, +0,2,2,2,0,2,2,0,1,2,0,2,2,2,0,2,2,2,2,1,2,2,0,0,2,0,0,0,0,0,0,0, +0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +0,2,0,2,0,2,2,0,0,0,0,1,2,1,0,0,2,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,3,2,3,0,0,2,0,0,0,2,2,0,2,0,0,0,1,0,0,2,0,2,0,2,2,0,0,0,0, +0,0,2,0,0,0,0,2,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0, +0,2,2,3,2,2,0,0,0,0,0,0,1,3,0,2,0,2,2,0,0,0,1,0,2,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,0,2,0,3,2,0,2,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +0,0,2,0,0,0,0,1,1,0,0,2,1,2,0,2,2,0,1,0,0,1,0,0,0,2,0,0,0,0,0,0, +0,3,0,2,2,2,0,0,2,0,0,0,2,0,0,0,2,3,0,2,0,0,0,0,0,0,2,2,0,0,0,2, +0,1,2,0,0,0,1,2,2,1,0,0,0,2,0,0,2,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,1,2,0,2,2,0,2,0,0,2,0,0,0,0,1,2,1,0,2,1,0,0,0,0,0,0,0,0,0,0, +0,0,2,0,0,0,3,1,2,2,0,2,0,0,0,0,2,0,0,0,2,0,0,3,0,0,0,0,2,2,2,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,1,0,2,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,0,0,0,0,0,0,2, +0,2,2,0,0,2,2,2,2,2,0,1,2,0,0,0,2,2,0,1,0,2,0,0,2,2,0,0,0,0,0,0, +0,0,0,0,1,0,0,0,0,0,0,0,3,0,0,2,0,0,0,0,0,0,0,0,2,0,2,0,0,0,0,2, +0,1,2,0,0,0,0,2,2,1,0,1,0,1,0,2,2,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0, +0,2,0,1,2,0,0,0,0,0,0,0,0,0,0,2,0,0,2,2,0,0,0,0,1,0,0,0,0,0,0,2, +0,2,2,0,0,0,0,2,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0,0, +0,2,2,2,2,0,0,0,3,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0,1, +0,0,2,0,0,0,0,1,2,0,0,0,0,0,0,2,2,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0, +0,2,0,2,2,2,0,0,2,0,0,0,0,0,0,0,2,2,2,0,0,0,2,0,0,0,0,0,0,0,0,2, +0,0,1,0,0,0,0,2,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, +0,3,0,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,2, +0,0,2,0,0,0,0,2,2,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,0,2,2,1,0,0,0,0,0,0,2,0,0,2,0,2,2,2,0,0,0,0,0,0,2,0,0,0,0,2, +0,0,2,0,0,2,0,2,2,0,0,0,0,2,0,2,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0, +0,0,3,0,0,0,2,2,0,2,2,0,0,0,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0,0,0,0, +0,2,2,2,2,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1, +0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,2,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +0,2,0,0,0,2,0,0,0,0,0,1,0,0,0,0,2,2,0,0,0,1,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,2,0,0,0, +0,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,2,0,2,0,0,0, +0,0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,2,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +) + +Latin7GreekModel = { + 'char_to_order_map': Latin7_char_to_order_map, + 'precedence_matrix': GreekLangModel, + 'typical_positive_ratio': 0.982851, + 'keep_english_letter': False, + 'charset_name': "ISO-8859-7", + 'language': 'Greek', +} + +Win1253GreekModel = { + 'char_to_order_map': win1253_char_to_order_map, + 'precedence_matrix': GreekLangModel, + 'typical_positive_ratio': 0.982851, + 'keep_english_letter': False, + 'charset_name': "windows-1253", + 'language': 'Greek', +} diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/langhebrewmodel.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/langhebrewmodel.py new file mode 100644 index 0000000..58f4c87 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/langhebrewmodel.py @@ -0,0 +1,200 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Simon Montagu +# Portions created by the Initial Developer are Copyright (C) 2005 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# Shoshannah Forbes - original C code (?) +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# 255: Control characters that usually does not exist in any text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 + +# Windows-1255 language model +# Character Mapping Table: +WIN1255_CHAR_TO_ORDER_MAP = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 69, 91, 79, 80, 92, 89, 97, 90, 68,111,112, 82, 73, 95, 85, # 40 + 78,121, 86, 71, 67,102,107, 84,114,103,115,253,253,253,253,253, # 50 +253, 50, 74, 60, 61, 42, 76, 70, 64, 53,105, 93, 56, 65, 54, 49, # 60 + 66,110, 51, 43, 44, 63, 81, 77, 98, 75,108,253,253,253,253,253, # 70 +124,202,203,204,205, 40, 58,206,207,208,209,210,211,212,213,214, +215, 83, 52, 47, 46, 72, 32, 94,216,113,217,109,218,219,220,221, + 34,116,222,118,100,223,224,117,119,104,125,225,226, 87, 99,227, +106,122,123,228, 55,229,230,101,231,232,120,233, 48, 39, 57,234, + 30, 59, 41, 88, 33, 37, 36, 31, 29, 35,235, 62, 28,236,126,237, +238, 38, 45,239,240,241,242,243,127,244,245,246,247,248,249,250, + 9, 8, 20, 16, 3, 2, 24, 14, 22, 1, 25, 15, 4, 11, 6, 23, + 12, 19, 13, 26, 18, 27, 21, 17, 7, 10, 5,251,252,128, 96,253, +) + +# Model Table: +# total sequences: 100% +# first 512 sequences: 98.4004% +# first 1024 sequences: 1.5981% +# rest sequences: 0.087% +# negative sequences: 0.0015% +HEBREW_LANG_MODEL = ( +0,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,2,3,2,1,2,0,1,0,0, +3,0,3,1,0,0,1,3,2,0,1,1,2,0,2,2,2,1,1,1,1,2,1,1,1,2,0,0,2,2,0,1, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2, +1,2,1,2,1,2,0,0,2,0,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2, +1,2,1,3,1,1,0,0,2,0,0,0,1,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,0,1,2,2,1,3, +1,2,1,1,2,2,0,0,2,2,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,1,0,1,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,3,2, +1,2,1,2,2,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,2,2,3,2,2,2,1,2,2,2,2, +1,2,1,1,2,2,0,1,2,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,0,2,2,2,2,2, +0,2,0,2,2,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,0,2,2,2, +0,2,1,2,2,2,0,0,2,1,0,0,0,0,1,0,1,0,0,0,0,0,0,2,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,1,2,3,2,2,2, +1,2,1,2,2,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,0, +3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,1,0,2,0,2, +0,2,1,2,2,2,0,0,1,2,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,2,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,3,2,2,3,2,1,2,1,1,1, +0,1,1,1,1,1,3,0,1,0,0,0,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,0,0,1,0,0,1,0,0,0,0, +0,0,1,0,0,0,0,0,2,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2, +0,2,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,2,3,3,3,2,1,2,3,3,2,3,3,3,3,2,3,2,1,2,0,2,1,2, +0,2,0,2,2,2,0,0,1,2,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0, +3,3,3,3,3,3,3,3,3,2,3,3,3,1,2,2,3,3,2,3,2,3,2,2,3,1,2,2,0,2,2,2, +0,2,1,2,2,2,0,0,1,2,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,2,2,3,3,3,3,1,3,2,2,2, +0,2,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,2,3,2,2,2,1,2,2,0,2,2,2,2, +0,2,0,2,2,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,1,3,2,3,3,2,3,3,2,2,1,2,2,2,2,2,2, +0,2,1,2,1,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,2,3,2,3,3,2,3,3,3,3,2,3,2,3,3,3,3,3,2,2,2,2,2,2,2,1, +0,2,0,1,2,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,2,1,2,3,3,3,3,3,3,3,2,3,2,3,2,1,2,3,0,2,1,2,2, +0,2,1,1,2,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,2,0, +3,3,3,3,3,3,3,3,3,2,3,3,3,3,2,1,3,1,2,2,2,1,2,3,3,1,2,1,2,2,2,2, +0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,0,2,3,3,3,1,3,3,3,1,2,2,2,2,1,1,2,2,2,2,2,2, +0,2,0,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,2,3,3,3,2,2,3,3,3,2,1,2,3,2,3,2,2,2,2,1,2,1,1,1,2,2, +0,2,1,1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,1,0,0,0,0,0, +1,0,1,0,0,0,0,0,2,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,2,3,3,2,3,1,2,2,2,2,3,2,3,1,1,2,2,1,2,2,1,1,0,2,2,2,2, +0,1,0,1,2,2,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,0,0,1,1,0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,2,0, +0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,1,0,1,0,1,1,0,1,1,0,0,0,1,1,0,1,1,1,0,0,0,0,0,0,1,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,0,0,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +3,2,2,1,2,2,2,2,2,2,2,1,2,2,1,2,2,1,1,1,1,1,1,1,1,2,1,1,0,3,3,3, +0,3,0,2,2,2,2,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,1,1,1,2,0,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,0,0,0,0, +0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,1,0,2,1,0, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +0,3,1,1,2,2,2,2,2,1,2,2,2,1,1,2,2,2,2,2,2,2,1,2,2,1,0,1,1,1,1,0, +0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,1,1,1,1,2,1,1,2,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0, +0,0,2,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,1,0,0, +2,1,1,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,1,2,1,2,1,1,1,1,0,0,0,0, +0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,2,1,2,2,2,2,2,2,2,2,2,2,1,2,1,2,1,1,2,1,1,1,2,1,2,1,2,0,1,0,1, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,1,2,2,2,1,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,2,1,2,1,1,0,1,0,1, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,1,2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2, +0,2,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,1,1,1,1,1,1,1,0,1,1,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,2,0,1,1,1,0,1,0,0,0,1,1,0,1,1,0,0,0,0,0,1,1,0,0, +0,1,1,1,2,1,2,2,2,0,2,0,2,0,1,1,2,1,1,1,1,2,1,0,1,1,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,1,0,0,0,0,0,1,0,1,2,2,0,1,0,0,1,1,2,2,1,2,0,2,0,0,0,1,2,0,1, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,2,0,2,1,2,0,2,0,0,1,1,1,1,1,1,0,1,0,0,0,1,0,0,1, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,1,0,0,0,0,0,1,0,2,1,1,0,1,0,0,1,1,1,2,2,0,0,1,0,0,0,1,0,0,1, +1,1,2,1,0,1,1,1,0,1,0,1,1,1,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,2,2,1, +0,2,0,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,1,0,0,1,0,1,1,1,1,0,0,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,1,1,1,1,1,1,1,1,2,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,1,1,0,1,0,0,0,1,1,0,1, +2,0,1,0,1,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,0,1,1,2,1,1,2,0,1,0,0,0,1,1,0,1, +1,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,1,1,2,0,1,0,0,0,0,2,1,1,2,0,2,0,0,0,1,1,0,1, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,2,1,1,0,1,0,0,2,2,1,2,1,1,0,1,0,0,0,1,1,0,1, +2,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,2,2,0,0,0,0,0,1,1,0,1,0,0,1,0,0,0,0,1,0,1, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,2,2,0,0,0,0,2,1,1,1,0,2,1,1,0,0,0,2,1,0,1, +1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,1,1,2,0,1,0,0,1,1,0,2,1,1,0,1,0,0,0,1,1,0,1, +2,2,1,1,1,0,1,1,0,1,1,0,1,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,2,1,1,0,1,0,0,1,1,0,1,2,1,0,2,0,0,0,1,1,0,1, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0, +0,1,0,0,2,0,2,1,1,0,1,0,1,0,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,1,1,2,0,1,0,0,1,1,1,0,1,0,0,1,0,0,0,1,0,0,1, +1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,0,0,0,0,0,1,0,1,1,0,0,1,0,0,2,1,1,1,1,1,0,1,0,0,0,0,1,0,1, +0,1,1,1,2,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,1,1,1,1,1,0,1,0,0,0,1,1,0,0, +) + +Win1255HebrewModel = { + 'char_to_order_map': WIN1255_CHAR_TO_ORDER_MAP, + 'precedence_matrix': HEBREW_LANG_MODEL, + 'typical_positive_ratio': 0.984004, + 'keep_english_letter': False, + 'charset_name': "windows-1255", + 'language': 'Hebrew', +} diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/langhungarianmodel.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/langhungarianmodel.py new file mode 100644 index 0000000..bb7c095 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/langhungarianmodel.py @@ -0,0 +1,225 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# 255: Control characters that usually does not exist in any text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 + +# Character Mapping Table: +Latin2_HungarianCharToOrderMap = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 28, 40, 54, 45, 32, 50, 49, 38, 39, 53, 36, 41, 34, 35, 47, + 46, 71, 43, 33, 37, 57, 48, 64, 68, 55, 52,253,253,253,253,253, +253, 2, 18, 26, 17, 1, 27, 12, 20, 9, 22, 7, 6, 13, 4, 8, + 23, 67, 10, 5, 3, 21, 19, 65, 62, 16, 11,253,253,253,253,253, +159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174, +175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190, +191,192,193,194,195,196,197, 75,198,199,200,201,202,203,204,205, + 79,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220, +221, 51, 81,222, 78,223,224,225,226, 44,227,228,229, 61,230,231, +232,233,234, 58,235, 66, 59,236,237,238, 60, 69, 63,239,240,241, + 82, 14, 74,242, 70, 80,243, 72,244, 15, 83, 77, 84, 30, 76, 85, +245,246,247, 25, 73, 42, 24,248,249,250, 31, 56, 29,251,252,253, +) + +win1250HungarianCharToOrderMap = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 28, 40, 54, 45, 32, 50, 49, 38, 39, 53, 36, 41, 34, 35, 47, + 46, 72, 43, 33, 37, 57, 48, 64, 68, 55, 52,253,253,253,253,253, +253, 2, 18, 26, 17, 1, 27, 12, 20, 9, 22, 7, 6, 13, 4, 8, + 23, 67, 10, 5, 3, 21, 19, 65, 62, 16, 11,253,253,253,253,253, +161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176, +177,178,179,180, 78,181, 69,182,183,184,185,186,187,188,189,190, +191,192,193,194,195,196,197, 76,198,199,200,201,202,203,204,205, + 81,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220, +221, 51, 83,222, 80,223,224,225,226, 44,227,228,229, 61,230,231, +232,233,234, 58,235, 66, 59,236,237,238, 60, 70, 63,239,240,241, + 84, 14, 75,242, 71, 82,243, 73,244, 15, 85, 79, 86, 30, 77, 87, +245,246,247, 25, 74, 42, 24,248,249,250, 31, 56, 29,251,252,253, +) + +# Model Table: +# total sequences: 100% +# first 512 sequences: 94.7368% +# first 1024 sequences:5.2623% +# rest sequences: 0.8894% +# negative sequences: 0.0009% +HungarianLangModel = ( +0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,2,2,3,3,1,1,2,2,2,2,2,1,2, +3,2,2,3,3,3,3,3,2,3,3,3,3,3,3,1,2,3,3,3,3,2,3,3,1,1,3,3,0,1,1,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0, +3,2,1,3,3,3,3,3,2,3,3,3,3,3,1,1,2,3,3,3,3,3,3,3,1,1,3,2,0,1,1,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,1,1,2,3,3,3,1,3,3,3,3,3,1,3,3,2,2,0,3,2,3, +0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,3,3,3,2,3,3,2,3,3,3,3,3,2,3,3,2,2,3,2,3,2,0,3,2,2, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0, +3,3,3,3,3,3,2,3,3,3,3,3,2,3,3,3,1,2,3,2,2,3,1,2,3,3,2,2,0,3,3,3, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,3,2,3,3,3,3,2,3,3,3,3,0,2,3,2, +0,0,0,1,1,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,1,1,1,3,3,2,1,3,2,2,3,2,1,3,2,2,1,0,3,3,1, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,2,2,3,3,3,3,3,1,2,3,3,3,3,1,2,1,3,3,3,3,2,2,3,1,1,3,2,0,1,1,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,2,1,3,3,3,3,3,2,2,1,3,3,3,0,1,1,2, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,3,3,3,2,0,3,2,3, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,1,0, +3,3,3,3,3,3,2,3,3,3,2,3,2,3,3,3,1,3,2,2,2,3,1,1,3,3,1,1,0,3,3,2, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,2,3,3,3,2,3,2,3,3,3,2,3,3,3,3,3,1,2,3,2,2,0,2,2,2, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,2,2,2,3,1,3,3,2,2,1,3,3,3,1,1,3,1,2,3,2,3,2,2,2,1,0,2,2,2, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0, +3,1,1,3,3,3,3,3,1,2,3,3,3,3,1,2,1,3,3,3,2,2,3,2,1,0,3,2,0,1,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,1,3,3,3,3,3,1,2,3,3,3,3,1,1,0,3,3,3,3,0,2,3,0,0,2,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,2,3,3,2,2,2,2,3,3,0,1,2,3,2,3,2,2,3,2,1,2,0,2,2,2, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0, +3,3,3,3,3,3,1,2,3,3,3,2,1,2,3,3,2,2,2,3,2,3,3,1,3,3,1,1,0,2,3,2, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,1,2,2,2,2,3,3,3,1,1,1,3,3,1,1,3,1,1,3,2,1,2,3,1,1,0,2,2,2, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,2,1,2,1,1,3,3,1,1,1,1,3,3,1,1,2,2,1,2,1,1,2,2,1,1,0,2,2,1, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,1,1,2,1,1,3,3,1,0,1,1,3,3,2,0,1,1,2,3,1,0,2,2,1,0,0,1,3,2, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,2,1,3,3,3,3,3,1,2,3,2,3,3,2,1,1,3,2,3,2,1,2,2,0,1,2,1,0,0,1,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,2,2,2,2,3,1,2,2,1,1,3,3,0,3,2,1,2,3,2,1,3,3,1,1,0,2,1,3, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,2,2,2,3,2,3,3,3,2,1,1,3,3,1,1,1,2,2,3,2,3,2,2,2,1,0,2,2,1, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +1,0,0,3,3,3,3,3,0,0,3,3,2,3,0,0,0,2,3,3,1,0,1,2,0,0,1,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,2,3,3,3,3,3,1,2,3,3,2,2,1,1,0,3,3,2,2,1,2,2,1,0,2,2,0,1,1,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,2,2,1,3,1,2,3,3,2,2,1,1,2,2,1,1,1,1,3,2,1,1,1,1,2,1,0,1,2,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +2,3,3,1,1,1,1,1,3,3,3,0,1,1,3,3,1,1,1,1,1,2,2,0,3,1,1,2,0,2,1,1, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,1,0,1,2,1,2,2,0,1,2,3,1,2,0,0,0,2,1,1,1,1,1,2,0,0,1,1,0,0,0,0, +1,2,1,2,2,2,1,2,1,2,0,2,0,2,2,1,1,2,1,1,2,1,1,1,0,1,0,0,0,1,1,0, +1,1,1,2,3,2,3,3,0,1,2,2,3,1,0,1,0,2,1,2,2,0,1,1,0,0,1,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,3,3,2,2,1,0,0,3,2,3,2,0,0,0,1,1,3,0,0,1,1,0,0,2,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,1,2,2,3,3,1,0,1,3,2,3,1,1,1,0,1,1,1,1,1,3,1,0,0,2,2,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,1,1,2,2,2,1,0,1,2,3,3,2,0,0,0,2,1,1,1,2,1,1,1,0,1,1,1,0,0,0, +1,2,2,2,2,2,1,1,1,2,0,2,1,1,1,1,1,2,1,1,1,1,1,1,0,1,1,1,0,0,1,1, +3,2,2,1,0,0,1,1,2,2,0,3,0,1,2,1,1,0,0,1,1,1,0,1,1,1,1,0,2,1,1,1, +2,2,1,1,1,2,1,2,1,1,1,1,1,1,1,2,1,1,1,2,3,1,1,1,1,1,1,1,1,1,0,1, +2,3,3,0,1,0,0,0,3,3,1,0,0,1,2,2,1,0,0,0,0,2,0,0,1,1,1,0,2,1,1,1, +2,1,1,1,1,1,1,2,1,1,0,1,1,0,1,1,1,0,1,2,1,1,0,1,1,1,1,1,1,1,0,1, +2,3,3,0,1,0,0,0,2,2,0,0,0,0,1,2,2,0,0,0,0,1,0,0,1,1,0,0,2,0,1,0, +2,1,1,1,1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,2,0,1,1,1,1,1,0,1, +3,2,2,0,1,0,1,0,2,3,2,0,0,1,2,2,1,0,0,1,1,1,0,0,2,1,0,1,2,2,1,1, +2,1,1,1,1,1,1,2,1,1,1,1,1,1,0,2,1,0,1,1,0,1,1,1,0,1,1,2,1,1,0,1, +2,2,2,0,0,1,0,0,2,2,1,1,0,0,2,1,1,0,0,0,1,2,0,0,2,1,0,0,2,1,1,1, +2,1,1,1,1,2,1,2,1,1,1,2,2,1,1,2,1,1,1,2,1,1,1,1,1,1,1,1,1,1,0,1, +1,2,3,0,0,0,1,0,3,2,1,0,0,1,2,1,1,0,0,0,0,2,1,0,1,1,0,0,2,1,2,1, +1,1,0,0,0,1,0,1,1,1,1,1,2,0,0,1,0,0,0,2,0,0,1,1,1,1,1,1,1,1,0,1, +3,0,0,2,1,2,2,1,0,0,2,1,2,2,0,0,0,2,1,1,1,0,1,1,0,0,1,1,2,0,0,0, +1,2,1,2,2,1,1,2,1,2,0,1,1,1,1,1,1,1,1,1,2,1,1,0,0,1,1,1,1,0,0,1, +1,3,2,0,0,0,1,0,2,2,2,0,0,0,2,2,1,0,0,0,0,3,1,1,1,1,0,0,2,1,1,1, +2,1,0,1,1,1,0,1,1,1,1,1,1,1,0,2,1,0,0,1,0,1,1,0,1,1,1,1,1,1,0,1, +2,3,2,0,0,0,1,0,2,2,0,0,0,0,2,1,1,0,0,0,0,2,1,0,1,1,0,0,2,1,1,0, +2,1,1,1,1,2,1,2,1,2,0,1,1,1,0,2,1,1,1,2,1,1,1,1,0,1,1,1,1,1,0,1, +3,1,1,2,2,2,3,2,1,1,2,2,1,1,0,1,0,2,2,1,1,1,1,1,0,0,1,1,0,1,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,0,0,0,0,0,2,2,0,0,0,0,2,2,1,0,0,0,1,1,0,0,1,2,0,0,2,1,1,1, +2,2,1,1,1,2,1,2,1,1,0,1,1,1,1,2,1,1,1,2,1,1,1,1,0,1,2,1,1,1,0,1, +1,0,0,1,2,3,2,1,0,0,2,0,1,1,0,0,0,1,1,1,1,0,1,1,0,0,1,0,0,0,0,0, +1,2,1,2,1,2,1,1,1,2,0,2,1,1,1,0,1,2,0,0,1,1,1,0,0,0,0,0,0,0,0,0, +2,3,2,0,0,0,0,0,1,1,2,1,0,0,1,1,1,0,0,0,0,2,0,0,1,1,0,0,2,1,1,1, +2,1,1,1,1,1,1,2,1,0,1,1,1,1,0,2,1,1,1,1,1,1,0,1,0,1,1,1,1,1,0,1, +1,2,2,0,1,1,1,0,2,2,2,0,0,0,3,2,1,0,0,0,1,1,0,0,1,1,0,1,1,1,0,0, +1,1,0,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1,1,1,0,0,1,1,1,0,1,0,1, +2,1,0,2,1,1,2,2,1,1,2,1,1,1,0,0,0,1,1,0,1,1,1,1,0,0,1,1,1,0,0,0, +1,2,2,2,2,2,1,1,1,2,0,2,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,0,1,0, +1,2,3,0,0,0,1,0,2,2,0,0,0,0,2,2,0,0,0,0,0,1,0,0,1,0,0,0,2,0,1,0, +2,1,1,1,1,1,0,2,0,0,0,1,2,1,1,1,1,0,1,2,0,1,0,1,0,1,1,1,0,1,0,1, +2,2,2,0,0,0,1,0,2,1,2,0,0,0,1,1,2,0,0,0,0,1,0,0,1,1,0,0,2,1,0,1, +2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,1,1,1,1,1,0,1, +1,2,2,0,0,0,1,0,2,2,2,0,0,0,1,1,0,0,0,0,0,1,1,0,2,0,0,1,1,1,0,1, +1,0,1,1,1,1,1,1,0,1,1,1,1,0,0,1,0,0,1,1,0,1,0,1,1,1,1,1,0,0,0,1, +1,0,0,1,0,1,2,1,0,0,1,1,1,2,0,0,0,1,1,0,1,0,1,1,0,0,1,0,0,0,0,0, +0,2,1,2,1,1,1,1,1,2,0,2,0,1,1,0,1,2,1,0,1,1,1,0,0,0,0,0,0,1,0,0, +2,1,1,0,1,2,0,0,1,1,1,0,0,0,1,1,0,0,0,0,0,1,0,0,1,0,0,0,2,1,0,1, +2,2,1,1,1,1,1,2,1,1,0,1,1,1,1,2,1,1,1,2,1,1,0,1,0,1,1,1,1,1,0,1, +1,2,2,0,0,0,0,0,1,1,0,0,0,0,2,1,0,0,0,0,0,2,0,0,2,2,0,0,2,0,0,1, +2,1,1,1,1,1,1,1,0,1,1,0,1,1,0,1,0,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1, +1,1,2,0,0,3,1,0,2,1,1,1,0,0,1,1,1,0,0,0,1,1,0,0,0,1,0,0,1,0,1,0, +1,2,1,0,1,1,1,2,1,1,0,1,1,1,1,1,0,0,0,1,1,1,1,1,0,1,0,0,0,1,0,0, +2,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,2,0,0,0, +2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,1,1,0,0,1,1,1,1,1,0,1, +2,1,1,1,2,1,1,1,0,1,1,2,1,0,0,0,0,1,1,1,1,0,1,0,0,0,0,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,1,0,1,1,1,1,1,0,0,1,1,2,1,0,0,0,1,1,0,0,0,1,1,0,0,1,0,1,0,0,0, +1,2,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0,1,0,0, +2,0,0,0,1,1,1,1,0,0,1,1,0,0,0,0,0,1,1,1,2,0,0,1,0,0,1,0,1,0,0,0, +0,1,1,1,1,1,1,1,1,2,0,1,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0, +1,0,0,1,1,1,1,1,0,0,2,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0, +0,1,1,1,1,1,1,0,1,1,0,1,0,1,1,0,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0, +1,0,0,1,1,1,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +0,1,1,1,1,1,0,0,1,1,0,1,0,1,0,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0, +0,0,0,1,0,0,0,0,0,0,1,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,1,1,1,0,1,0,0,1,1,0,1,0,1,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0, +2,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,0,0,1,0,0,1,0,1,0,1,1,1,0,0,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, +0,1,1,1,1,1,1,0,1,1,0,1,0,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0, +) + +Latin2HungarianModel = { + 'char_to_order_map': Latin2_HungarianCharToOrderMap, + 'precedence_matrix': HungarianLangModel, + 'typical_positive_ratio': 0.947368, + 'keep_english_letter': True, + 'charset_name': "ISO-8859-2", + 'language': 'Hungarian', +} + +Win1250HungarianModel = { + 'char_to_order_map': win1250HungarianCharToOrderMap, + 'precedence_matrix': HungarianLangModel, + 'typical_positive_ratio': 0.947368, + 'keep_english_letter': True, + 'charset_name': "windows-1250", + 'language': 'Hungarian', +} diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/langthaimodel.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/langthaimodel.py new file mode 100644 index 0000000..15f94c2 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/langthaimodel.py @@ -0,0 +1,199 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# 255: Control characters that usually does not exist in any text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 + +# The following result for thai was collected from a limited sample (1M). + +# Character Mapping Table: +TIS620CharToOrderMap = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,182,106,107,100,183,184,185,101, 94,186,187,108,109,110,111, # 40 +188,189,190, 89, 95,112,113,191,192,193,194,253,253,253,253,253, # 50 +253, 64, 72, 73,114, 74,115,116,102, 81,201,117, 90,103, 78, 82, # 60 + 96,202, 91, 79, 84,104,105, 97, 98, 92,203,253,253,253,253,253, # 70 +209,210,211,212,213, 88,214,215,216,217,218,219,220,118,221,222, +223,224, 99, 85, 83,225,226,227,228,229,230,231,232,233,234,235, +236, 5, 30,237, 24,238, 75, 8, 26, 52, 34, 51,119, 47, 58, 57, + 49, 53, 55, 43, 20, 19, 44, 14, 48, 3, 17, 25, 39, 62, 31, 54, + 45, 9, 16, 2, 61, 15,239, 12, 42, 46, 18, 21, 76, 4, 66, 63, + 22, 10, 1, 36, 23, 13, 40, 27, 32, 35, 86,240,241,242,243,244, + 11, 28, 41, 29, 33,245, 50, 37, 6, 7, 67, 77, 38, 93,246,247, + 68, 56, 59, 65, 69, 60, 70, 80, 71, 87,248,249,250,251,252,253, +) + +# Model Table: +# total sequences: 100% +# first 512 sequences: 92.6386% +# first 1024 sequences:7.3177% +# rest sequences: 1.0230% +# negative sequences: 0.0436% +ThaiLangModel = ( +0,1,3,3,3,3,0,0,3,3,0,3,3,0,3,3,3,3,3,3,3,3,0,0,3,3,3,0,3,3,3,3, +0,3,3,0,0,0,1,3,0,3,3,2,3,3,0,1,2,3,3,3,3,0,2,0,2,0,0,3,2,1,2,2, +3,0,3,3,2,3,0,0,3,3,0,3,3,0,3,3,3,3,3,3,3,3,3,0,3,2,3,0,2,2,2,3, +0,2,3,0,0,0,0,1,0,1,2,3,1,1,3,2,2,0,1,1,0,0,1,0,0,0,0,0,0,0,1,1, +3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,3,3,2,3,2,3,3,2,2,2, +3,1,2,3,0,3,3,2,2,1,2,3,3,1,2,0,1,3,0,1,0,0,1,0,0,0,0,0,0,0,1,1, +3,3,2,2,3,3,3,3,1,2,3,3,3,3,3,2,2,2,2,3,3,2,2,3,3,2,2,3,2,3,2,2, +3,3,1,2,3,1,2,2,3,3,1,0,2,1,0,0,3,1,2,1,0,0,1,0,0,0,0,0,0,1,0,1, +3,3,3,3,3,3,2,2,3,3,3,3,2,3,2,2,3,3,2,2,3,2,2,2,2,1,1,3,1,2,1,1, +3,2,1,0,2,1,0,1,0,1,1,0,1,1,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0, +3,3,3,2,3,2,3,3,2,2,3,2,3,3,2,3,1,1,2,3,2,2,2,3,2,2,2,2,2,1,2,1, +2,2,1,1,3,3,2,1,0,1,2,2,0,1,3,0,0,0,1,1,0,0,0,0,0,2,3,0,0,2,1,1, +3,3,2,3,3,2,0,0,3,3,0,3,3,0,2,2,3,1,2,2,1,1,1,0,2,2,2,0,2,2,1,1, +0,2,1,0,2,0,0,2,0,1,0,0,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,2,3,3,2,0,0,3,3,0,2,3,0,2,1,2,2,2,2,1,2,0,0,2,2,2,0,2,2,1,1, +0,2,1,0,2,0,0,2,0,1,1,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0, +3,3,2,3,2,3,2,0,2,2,1,3,2,1,3,2,1,2,3,2,2,3,0,2,3,2,2,1,2,2,2,2, +1,2,2,0,0,0,0,2,0,1,2,0,1,1,1,0,1,0,3,1,1,0,0,0,0,0,0,0,0,0,1,0, +3,3,2,3,3,2,3,2,2,2,3,2,2,3,2,2,1,2,3,2,2,3,1,3,2,2,2,3,2,2,2,3, +3,2,1,3,0,1,1,1,0,2,1,1,1,1,1,0,1,0,1,1,0,0,0,0,0,0,0,0,0,2,0,0, +1,0,0,3,0,3,3,3,3,3,0,0,3,0,2,2,3,3,3,3,3,0,0,0,1,1,3,0,0,0,0,2, +0,0,1,0,0,0,0,0,0,0,2,3,0,0,0,3,0,2,0,0,0,0,0,3,0,0,0,0,0,0,0,0, +2,0,3,3,3,3,0,0,2,3,0,0,3,0,3,3,2,3,3,3,3,3,0,0,3,3,3,0,0,0,3,3, +0,0,3,0,0,0,0,2,0,0,2,1,1,3,0,0,1,0,0,2,3,0,1,0,0,0,0,0,0,0,1,0, +3,3,3,3,2,3,3,3,3,3,3,3,1,2,1,3,3,2,2,1,2,2,2,3,1,1,2,0,2,1,2,1, +2,2,1,0,0,0,1,1,0,1,0,1,1,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0, +3,0,2,1,2,3,3,3,0,2,0,2,2,0,2,1,3,2,2,1,2,1,0,0,2,2,1,0,2,1,2,2, +0,1,1,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,2,1,3,3,1,1,3,0,2,3,1,1,3,2,1,1,2,0,2,2,3,2,1,1,1,1,1,2, +3,0,0,1,3,1,2,1,2,0,3,0,0,0,1,0,3,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, +3,3,1,1,3,2,3,3,3,1,3,2,1,3,2,1,3,2,2,2,2,1,3,3,1,2,1,3,1,2,3,0, +2,1,1,3,2,2,2,1,2,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2, +3,3,2,3,2,3,3,2,3,2,3,2,3,3,2,1,0,3,2,2,2,1,2,2,2,1,2,2,1,2,1,1, +2,2,2,3,0,1,3,1,1,1,1,0,1,1,0,2,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,2,3,2,2,1,1,3,2,3,2,3,2,0,3,2,2,1,2,0,2,2,2,1,2,2,2,2,1, +3,2,1,2,2,1,0,2,0,1,0,0,1,1,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,2,3,1,2,3,3,2,2,3,0,1,1,2,0,3,3,2,2,3,0,1,1,3,0,0,0,0, +3,1,0,3,3,0,2,0,2,1,0,0,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,2,3,2,3,3,0,1,3,1,1,2,1,2,1,1,3,1,1,0,2,3,1,1,1,1,1,1,1,1, +3,1,1,2,2,2,2,1,1,1,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,2,2,1,1,2,1,3,3,2,3,2,2,3,2,2,3,1,2,2,1,2,0,3,2,1,2,2,2,2,2,1, +3,2,1,2,2,2,1,1,1,1,0,0,1,1,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,1,3,3,0,2,1,0,3,2,0,0,3,1,0,1,1,0,1,0,0,0,0,0,1, +1,0,0,1,0,3,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,2,2,2,3,0,0,1,3,0,3,2,0,3,2,2,3,3,3,3,3,1,0,2,2,2,0,2,2,1,2, +0,2,3,0,0,0,0,1,0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,0,2,3,1,3,3,2,3,3,0,3,3,0,3,2,2,3,2,3,3,3,0,0,2,2,3,0,1,1,1,3, +0,0,3,0,0,0,2,2,0,1,3,0,1,2,2,2,3,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1, +3,2,3,3,2,0,3,3,2,2,3,1,3,2,1,3,2,0,1,2,2,0,2,3,2,1,0,3,0,0,0,0, +3,0,0,2,3,1,3,0,0,3,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,3,2,2,2,1,2,0,1,3,1,1,3,1,3,0,0,2,1,1,1,1,2,1,1,1,0,2,1,0,1, +1,2,0,0,0,3,1,1,0,0,0,0,1,0,1,0,0,1,0,1,0,0,0,0,0,3,1,0,0,0,1,0, +3,3,3,3,2,2,2,2,2,1,3,1,1,1,2,0,1,1,2,1,2,1,3,2,0,0,3,1,1,1,1,1, +3,1,0,2,3,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,2,3,0,3,3,0,2,0,0,0,0,0,0,0,3,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,2,3,1,3,0,0,1,2,0,0,2,0,3,3,2,3,3,3,2,3,0,0,2,2,2,0,0,0,2,2, +0,0,1,0,0,0,0,3,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +0,0,0,3,0,2,0,0,0,0,0,0,0,0,0,0,1,2,3,1,3,3,0,0,1,0,3,0,0,0,0,0, +0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,1,2,3,1,2,3,1,0,3,0,2,2,1,0,2,1,1,2,0,1,0,0,1,1,1,1,0,1,0,0, +1,0,0,0,0,1,1,0,3,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,2,1,0,1,1,1,3,1,2,2,2,2,2,2,1,1,1,1,0,3,1,0,1,3,1,1,1,1, +1,1,0,2,0,1,3,1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,1, +3,0,2,2,1,3,3,2,3,3,0,1,1,0,2,2,1,2,1,3,3,1,0,0,3,2,0,0,0,0,2,1, +0,1,0,0,0,0,1,2,0,1,1,3,1,1,2,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +0,0,3,0,0,1,0,0,0,3,0,0,3,0,3,1,0,1,1,1,3,2,0,0,0,3,0,0,0,0,2,0, +0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0, +3,3,1,3,2,1,3,3,1,2,2,0,1,2,1,0,1,2,0,0,0,0,0,3,0,0,0,3,0,0,0,0, +3,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,1,2,0,3,3,3,2,2,0,1,1,0,1,3,0,0,0,2,2,0,0,0,0,3,1,0,1,0,0,0, +0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,2,3,1,2,0,0,2,1,0,3,1,0,1,2,0,1,1,1,1,3,0,0,3,1,1,0,2,2,1,1, +0,2,0,0,0,0,0,1,0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,0,3,1,2,0,0,2,2,0,1,2,0,1,0,1,3,1,2,1,0,0,0,2,0,3,0,0,0,1,0, +0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,1,1,2,2,0,0,0,2,0,2,1,0,1,1,0,1,1,1,2,1,0,0,1,1,1,0,2,1,1,1, +0,1,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1, +0,0,0,2,0,1,3,1,1,1,1,0,0,0,0,3,2,0,1,0,0,0,1,2,0,0,0,1,0,0,0,0, +0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,3,3,3,3,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,2,3,2,2,0,0,0,1,0,0,0,0,2,3,2,1,2,2,3,0,0,0,2,3,1,0,0,0,1,1, +0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0, +3,3,2,2,0,1,0,0,0,0,2,0,2,0,1,0,0,0,1,1,0,0,0,2,1,0,1,0,1,1,0,0, +0,1,0,2,0,0,1,0,3,0,1,0,0,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,1,0,0,1,0,0,0,0,0,1,1,2,0,0,0,0,1,0,0,1,3,1,0,0,0,0,1,1,0,0, +0,1,0,0,0,0,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0, +3,3,1,1,1,1,2,3,0,0,2,1,1,1,1,1,0,2,1,1,0,0,0,2,1,0,1,2,1,1,0,1, +2,1,0,3,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,3,1,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1, +0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,2,0,0,0,0,0,0,1,2,1,0,1,1,0,2,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,2,0,0,0,1,3,0,1,0,0,0,2,0,0,0,0,0,0,0,1,2,0,0,0,0,0, +3,3,0,0,1,1,2,0,0,1,2,1,0,1,1,1,0,1,1,0,0,2,1,1,0,1,0,0,1,1,1,0, +0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,1,0,0,0,0,1,0,0,0,0,3,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0, +2,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,0,0,1,1,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,1,0,1,2,0,1,2,0,0,1,1,0,2,0,1,0,0,1,0,0,0,0,1,0,0,0,2,0,0,0,0, +1,0,0,1,0,1,1,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,1,0,0,0,0,0,0,0,1,1,0,1,1,0,2,1,3,0,0,0,0,1,1,0,0,0,0,0,0,0,3, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,1,0,1,0,0,2,0,0,2,0,0,1,1,2,0,0,1,1,0,0,0,1,0,0,0,1,1,0,0,0, +1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +1,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,1,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,3,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,0,0,0,0, +1,0,0,0,0,0,0,0,0,1,0,0,0,0,2,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,1,1,0,0,2,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +) + +TIS620ThaiModel = { + 'char_to_order_map': TIS620CharToOrderMap, + 'precedence_matrix': ThaiLangModel, + 'typical_positive_ratio': 0.926386, + 'keep_english_letter': False, + 'charset_name': "TIS-620", + 'language': 'Thai', +} diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/langturkishmodel.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/langturkishmodel.py new file mode 100644 index 0000000..a427a45 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/langturkishmodel.py @@ -0,0 +1,193 @@ +# -*- coding: utf-8 -*- +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Özgür Baskın - Turkish Language Model +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# 255: Control characters that usually does not exist in any text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 + +# Character Mapping Table: +Latin5_TurkishCharToOrderMap = ( +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255, 23, 37, 47, 39, 29, 52, 36, 45, 53, 60, 16, 49, 20, 46, 42, + 48, 69, 44, 35, 31, 51, 38, 62, 65, 43, 56,255,255,255,255,255, +255, 1, 21, 28, 12, 2, 18, 27, 25, 3, 24, 10, 5, 13, 4, 15, + 26, 64, 7, 8, 9, 14, 32, 57, 58, 11, 22,255,255,255,255,255, +180,179,178,177,176,175,174,173,172,171,170,169,168,167,166,165, +164,163,162,161,160,159,101,158,157,156,155,154,153,152,151,106, +150,149,148,147,146,145,144,100,143,142,141,140,139,138,137,136, + 94, 80, 93,135,105,134,133, 63,132,131,130,129,128,127,126,125, +124,104, 73, 99, 79, 85,123, 54,122, 98, 92,121,120, 91,103,119, + 68,118,117, 97,116,115, 50, 90,114,113,112,111, 55, 41, 40, 86, + 89, 70, 59, 78, 71, 82, 88, 33, 77, 66, 84, 83,110, 75, 61, 96, + 30, 67,109, 74, 87,102, 34, 95, 81,108, 76, 72, 17, 6, 19,107, +) + +TurkishLangModel = ( +3,2,3,3,3,1,3,3,3,3,3,3,3,3,2,1,1,3,3,1,3,3,0,3,3,3,3,3,0,3,1,3, +3,2,1,0,0,1,1,0,0,0,1,0,0,1,1,1,1,0,0,0,0,0,0,0,2,2,0,0,1,0,0,1, +3,2,2,3,3,0,3,3,3,3,3,3,3,2,3,1,0,3,3,1,3,3,0,3,3,3,3,3,0,3,0,3, +3,1,1,0,1,0,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,2,2,0,0,0,1,0,1, +3,3,2,3,3,0,3,3,3,3,3,3,3,2,3,1,1,3,3,0,3,3,1,2,3,3,3,3,0,3,0,3, +3,1,1,0,0,0,1,0,0,0,0,1,1,0,1,2,1,0,0,0,1,0,0,0,0,2,0,0,0,0,0,1, +3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,1,3,3,2,0,3,2,1,2,2,1,3,3,0,0,0,2, +2,2,0,1,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,1,0,0,1, +3,3,3,2,3,3,1,2,3,3,3,3,3,3,3,1,3,2,1,0,3,2,0,1,2,3,3,2,1,0,0,2, +2,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,2,0,0,0, +1,0,1,3,3,1,3,3,3,3,3,3,3,1,2,0,0,2,3,0,2,3,0,0,2,2,2,3,0,3,0,1, +2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,3,0,3,2,0,2,3,2,3,3,1,0,0,2, +3,2,0,0,1,0,0,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,1,1,1,0,2,0,0,1, +3,3,3,2,3,3,2,3,3,3,3,2,3,3,3,0,3,3,0,0,2,1,0,0,2,3,2,2,0,0,0,2, +2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,0,1,0,2,0,0,1, +3,3,3,2,3,3,3,3,3,3,3,2,3,3,3,0,3,2,0,1,3,2,1,1,3,2,3,2,1,0,0,2, +2,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, +3,3,3,2,3,3,3,3,3,3,3,2,3,3,3,0,3,2,2,0,2,3,0,0,2,2,2,2,0,0,0,2, +3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,2,0,1,0,0,0, +3,3,3,3,3,3,3,2,2,2,2,3,2,3,3,0,3,3,1,1,2,2,0,0,2,2,3,2,0,0,1,3, +0,3,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1, +3,3,3,2,3,3,3,2,1,2,2,3,2,3,3,0,3,2,0,0,1,1,0,1,1,2,1,2,0,0,0,1, +0,3,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,0,0, +3,3,3,2,3,3,2,3,2,2,2,3,3,3,3,1,3,1,1,0,3,2,1,1,3,3,2,3,1,0,0,1, +1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,2,0,0,1, +3,2,2,3,3,0,3,3,3,3,3,3,3,2,2,1,0,3,3,1,3,3,0,1,3,3,2,3,0,3,0,3, +2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0, +2,2,2,3,3,0,3,3,3,3,3,3,3,3,3,0,0,3,2,0,3,3,0,3,2,3,3,3,0,3,1,3, +2,0,0,0,0,0,0,0,0,0,0,1,0,1,2,0,1,0,0,0,0,0,0,0,2,2,0,0,1,0,0,1, +3,3,3,1,2,3,3,1,0,0,1,0,0,3,3,2,3,0,0,2,0,0,2,0,2,0,0,0,2,0,2,0, +0,3,1,0,1,0,0,0,2,2,1,0,1,1,2,1,2,2,2,0,2,1,1,0,0,0,2,0,0,0,0,0, +1,2,1,3,3,0,3,3,3,3,3,2,3,0,0,0,0,2,3,0,2,3,1,0,2,3,1,3,0,3,0,2, +3,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,1,3,3,2,2,3,2,2,0,1,2,3,0,1,2,1,0,1,0,0,0,1,0,2,2,0,0,0,1, +1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0, +3,3,3,1,3,3,1,1,3,3,1,1,3,3,1,0,2,1,2,0,2,1,0,0,1,1,2,1,0,0,0,2, +2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,1,0,2,1,3,0,0,2,0,0,3,3,0,3,0,0,1,0,1,2,0,0,1,1,2,2,0,1,0, +0,1,2,1,1,0,1,0,1,1,1,1,1,0,1,1,1,2,2,1,2,0,1,0,0,0,0,0,0,1,0,0, +3,3,3,2,3,2,3,3,0,2,2,2,3,3,3,0,3,0,0,0,2,2,0,1,2,1,1,1,0,0,0,1, +0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, +3,3,3,3,3,3,2,1,2,2,3,3,3,3,2,0,2,0,0,0,2,2,0,0,2,1,3,3,0,0,1,1, +1,1,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0, +1,1,2,3,3,0,3,3,3,3,3,3,2,2,0,2,0,2,3,2,3,2,2,2,2,2,2,2,1,3,2,3, +2,0,2,1,2,2,2,2,1,1,2,2,1,2,2,1,2,0,0,2,1,1,0,2,1,0,0,1,0,0,0,1, +2,3,3,1,1,1,0,1,1,1,2,3,2,1,1,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0, +0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,2,2,2,3,2,3,2,2,1,3,3,3,0,2,1,2,0,2,1,0,0,1,1,1,1,1,0,0,1, +2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,2,0,1,0,0,0, +3,3,3,2,3,3,3,3,3,2,3,1,2,3,3,1,2,0,0,0,0,0,0,0,3,2,1,1,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0, +3,3,3,2,2,3,3,2,1,1,1,1,1,3,3,0,3,1,0,0,1,1,0,0,3,1,2,1,0,0,0,0, +0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0, +3,3,3,2,2,3,2,2,2,3,2,1,1,3,3,0,3,0,0,0,0,1,0,0,3,1,1,2,0,0,0,1, +1,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +1,1,1,3,3,0,3,3,3,3,3,2,2,2,1,2,0,2,1,2,2,1,1,0,1,2,2,2,2,2,2,2, +0,0,2,1,2,1,2,1,0,1,1,3,1,2,1,1,2,0,0,2,0,1,0,1,0,1,0,0,0,1,0,1, +3,3,3,1,3,3,3,0,1,1,0,2,2,3,1,0,3,0,0,0,1,0,0,0,1,0,0,1,0,1,0,0, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,2,0,0,2,2,1,0,0,1,0,0,3,3,1,3,0,0,1,1,0,2,0,3,0,0,0,2,0,1,1, +0,1,2,0,1,2,2,0,2,2,2,2,1,0,2,1,1,0,2,0,2,1,2,0,0,0,0,0,0,0,0,0, +3,3,3,1,3,2,3,2,0,2,2,2,1,3,2,0,2,1,2,0,1,2,0,0,1,0,2,2,0,0,0,2, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0, +3,3,3,0,3,3,1,1,2,3,1,0,3,2,3,0,3,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0, +1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,3,3,0,3,3,2,3,3,2,2,0,0,0,0,1,2,0,1,3,0,0,0,3,1,1,0,3,0,2, +2,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,1,2,2,1,0,3,1,1,1,1,3,3,2,3,0,0,1,0,1,2,0,2,2,0,2,2,0,2,1, +0,2,2,1,1,1,1,0,2,1,1,0,1,1,1,1,2,1,2,1,2,0,1,0,1,0,0,0,0,0,0,0, +3,3,3,0,1,1,3,0,0,1,1,0,0,2,2,0,3,0,0,1,1,0,1,0,0,0,0,0,2,0,0,0, +0,3,1,0,1,0,1,0,2,0,0,1,0,1,0,1,1,1,2,1,1,0,2,0,0,0,0,0,0,0,0,0, +3,3,3,0,2,0,2,0,1,1,1,0,0,3,3,0,2,0,0,1,0,0,2,1,1,0,1,0,1,0,1,0, +0,2,0,1,2,0,2,0,2,1,1,0,1,0,2,1,1,0,2,1,1,0,1,0,0,0,1,1,0,0,0,0, +3,2,3,0,1,0,0,0,0,0,0,0,0,1,2,0,1,0,0,1,0,0,1,0,0,0,0,0,2,0,0,0, +0,0,1,1,0,0,1,0,1,0,0,1,0,0,0,2,1,0,1,0,2,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,0,0,2,3,0,0,1,0,1,0,2,3,2,3,0,0,1,3,0,2,1,0,0,0,0,2,0,1,0, +0,2,1,0,0,1,1,0,2,1,0,0,1,0,0,1,1,0,1,1,2,0,1,0,0,0,0,1,0,0,0,0, +3,2,2,0,0,1,1,0,0,0,0,0,0,3,1,1,1,0,0,0,0,0,1,0,0,0,0,0,2,0,1,0, +0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,3,3,0,2,3,2,2,1,2,2,1,1,2,0,1,3,2,2,2,0,0,2,2,0,0,0,1,2,1, +3,0,2,1,1,0,1,1,1,0,1,2,2,2,1,1,2,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0, +0,1,1,2,3,0,3,3,3,2,2,2,2,1,0,1,0,1,0,1,2,2,0,0,2,2,1,3,1,1,2,1, +0,0,1,1,2,0,1,1,0,0,1,2,0,2,1,1,2,0,0,1,0,0,0,1,0,1,0,1,0,0,0,0, +3,3,2,0,0,3,1,0,0,0,0,0,0,3,2,1,2,0,0,1,0,0,2,0,0,0,0,0,2,0,1,0, +0,2,1,1,0,0,1,0,1,2,0,0,1,1,0,0,2,1,1,1,1,0,2,0,0,0,0,0,0,0,0,0, +3,3,2,0,0,1,0,0,0,0,1,0,0,3,3,2,2,0,0,1,0,0,2,0,1,0,0,0,2,0,1,0, +0,0,1,1,0,0,2,0,2,1,0,0,1,1,2,1,2,0,2,1,2,1,1,1,0,0,1,1,0,0,0,0, +3,3,2,0,0,2,2,0,0,0,1,1,0,2,2,1,3,1,0,1,0,1,2,0,0,0,0,0,1,0,1,0, +0,1,1,0,0,0,0,0,1,0,0,1,0,0,0,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,2,0,0,0,1,0,0,1,0,0,2,3,1,2,0,0,1,0,0,2,0,0,0,1,0,2,0,2,0, +0,1,1,2,2,1,2,0,2,1,1,0,0,1,1,0,1,1,1,1,2,1,1,0,0,0,0,0,0,0,0,0, +3,3,3,0,2,1,2,1,0,0,1,1,0,3,3,1,2,0,0,1,0,0,2,0,2,0,1,1,2,0,0,0, +0,0,1,1,1,1,2,0,1,1,0,1,1,1,1,0,0,0,1,1,1,0,1,0,0,0,1,0,0,0,0,0, +3,3,3,0,2,2,3,2,0,0,1,0,0,2,3,1,0,0,0,0,0,0,2,0,2,0,0,0,2,0,0,0, +0,1,1,0,0,0,1,0,0,1,0,1,1,0,1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0, +3,2,3,0,0,0,0,0,0,0,1,0,0,2,2,2,2,0,0,1,0,0,2,0,0,0,0,0,2,0,1,0, +0,0,2,1,1,0,1,0,2,1,1,0,0,1,1,2,1,0,2,0,2,0,1,0,0,0,2,0,0,0,0,0, +0,0,0,2,2,0,2,1,1,1,1,2,2,0,0,1,0,1,0,0,1,3,0,0,0,0,1,0,0,2,1,0, +0,0,1,0,1,0,0,0,0,0,2,1,0,1,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, +2,0,0,2,3,0,2,3,1,2,2,0,2,0,0,2,0,2,1,1,1,2,1,0,0,1,2,1,1,2,1,0, +1,0,2,0,1,0,1,1,0,0,2,2,1,2,1,1,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,0,2,1,2,0,0,0,1,0,0,3,2,0,1,0,0,1,0,0,2,0,0,0,1,2,1,0,1,0, +0,0,0,0,1,0,1,0,0,1,0,0,0,0,1,0,1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,2,2,0,2,2,1,1,0,1,1,1,1,1,0,0,1,2,1,1,1,0,1,0,0,0,1,1,1,1, +0,0,2,1,0,1,1,1,0,1,1,2,1,2,1,1,2,0,1,1,2,1,0,2,0,0,0,0,0,0,0,0, +3,2,2,0,0,2,0,0,0,0,0,0,0,2,2,0,2,0,0,1,0,0,2,0,0,0,0,0,2,0,0,0, +0,2,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,3,2,0,2,2,0,1,1,0,1,0,0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,0, +2,0,1,0,1,0,1,1,0,0,1,2,0,1,0,1,1,0,0,1,0,1,0,2,0,0,0,0,0,0,0,0, +2,2,2,0,1,1,0,0,0,1,0,0,0,1,2,0,1,0,0,1,0,0,1,0,0,0,0,1,2,0,1,0, +0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,1,0,1,0,2,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,2,1,0,1,1,1,0,0,0,0,1,2,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0, +1,1,2,0,1,0,0,0,1,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,2,0,0,0,0,0,1, +0,0,1,2,2,0,2,1,2,1,1,2,2,0,0,0,0,1,0,0,1,1,0,0,2,0,0,0,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, +2,2,2,0,0,0,1,0,0,0,0,0,0,2,2,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,0,1,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,1,0,0,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +) + +Latin5TurkishModel = { + 'char_to_order_map': Latin5_TurkishCharToOrderMap, + 'precedence_matrix': TurkishLangModel, + 'typical_positive_ratio': 0.970290, + 'keep_english_letter': True, + 'charset_name': "ISO-8859-9", + 'language': 'Turkish', +} diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/latin1prober.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/latin1prober.py new file mode 100644 index 0000000..7d1e8c2 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/latin1prober.py @@ -0,0 +1,145 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState + +FREQ_CAT_NUM = 4 + +UDF = 0 # undefined +OTH = 1 # other +ASC = 2 # ascii capital letter +ASS = 3 # ascii small letter +ACV = 4 # accent capital vowel +ACO = 5 # accent capital other +ASV = 6 # accent small vowel +ASO = 7 # accent small other +CLASS_NUM = 8 # total classes + +Latin1_CharToClass = ( + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 00 - 07 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 08 - 0F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 10 - 17 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 18 - 1F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 20 - 27 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 28 - 2F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 30 - 37 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 38 - 3F + OTH, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 40 - 47 + ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 48 - 4F + ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 50 - 57 + ASC, ASC, ASC, OTH, OTH, OTH, OTH, OTH, # 58 - 5F + OTH, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 60 - 67 + ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 68 - 6F + ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 70 - 77 + ASS, ASS, ASS, OTH, OTH, OTH, OTH, OTH, # 78 - 7F + OTH, UDF, OTH, ASO, OTH, OTH, OTH, OTH, # 80 - 87 + OTH, OTH, ACO, OTH, ACO, UDF, ACO, UDF, # 88 - 8F + UDF, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 90 - 97 + OTH, OTH, ASO, OTH, ASO, UDF, ASO, ACO, # 98 - 9F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # A0 - A7 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # A8 - AF + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # B0 - B7 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # B8 - BF + ACV, ACV, ACV, ACV, ACV, ACV, ACO, ACO, # C0 - C7 + ACV, ACV, ACV, ACV, ACV, ACV, ACV, ACV, # C8 - CF + ACO, ACO, ACV, ACV, ACV, ACV, ACV, OTH, # D0 - D7 + ACV, ACV, ACV, ACV, ACV, ACO, ACO, ACO, # D8 - DF + ASV, ASV, ASV, ASV, ASV, ASV, ASO, ASO, # E0 - E7 + ASV, ASV, ASV, ASV, ASV, ASV, ASV, ASV, # E8 - EF + ASO, ASO, ASV, ASV, ASV, ASV, ASV, OTH, # F0 - F7 + ASV, ASV, ASV, ASV, ASV, ASO, ASO, ASO, # F8 - FF +) + +# 0 : illegal +# 1 : very unlikely +# 2 : normal +# 3 : very likely +Latin1ClassModel = ( +# UDF OTH ASC ASS ACV ACO ASV ASO + 0, 0, 0, 0, 0, 0, 0, 0, # UDF + 0, 3, 3, 3, 3, 3, 3, 3, # OTH + 0, 3, 3, 3, 3, 3, 3, 3, # ASC + 0, 3, 3, 3, 1, 1, 3, 3, # ASS + 0, 3, 3, 3, 1, 2, 1, 2, # ACV + 0, 3, 3, 3, 3, 3, 3, 3, # ACO + 0, 3, 1, 3, 1, 1, 1, 3, # ASV + 0, 3, 1, 3, 1, 1, 3, 3, # ASO +) + + +class Latin1Prober(CharSetProber): + def __init__(self): + super(Latin1Prober, self).__init__() + self._last_char_class = None + self._freq_counter = None + self.reset() + + def reset(self): + self._last_char_class = OTH + self._freq_counter = [0] * FREQ_CAT_NUM + CharSetProber.reset(self) + + @property + def charset_name(self): + return "ISO-8859-1" + + @property + def language(self): + return "" + + def feed(self, byte_str): + byte_str = self.filter_with_english_letters(byte_str) + for c in byte_str: + char_class = Latin1_CharToClass[c] + freq = Latin1ClassModel[(self._last_char_class * CLASS_NUM) + + char_class] + if freq == 0: + self._state = ProbingState.NOT_ME + break + self._freq_counter[freq] += 1 + self._last_char_class = char_class + + return self.state + + def get_confidence(self): + if self.state == ProbingState.NOT_ME: + return 0.01 + + total = sum(self._freq_counter) + if total < 0.01: + confidence = 0.0 + else: + confidence = ((self._freq_counter[3] - self._freq_counter[1] * 20.0) + / total) + if confidence < 0.0: + confidence = 0.0 + # lower the confidence of latin1 so that other more accurate + # detector can take priority. + confidence = confidence * 0.73 + return confidence diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/mbcharsetprober.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/mbcharsetprober.py new file mode 100644 index 0000000..6256ecf --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/mbcharsetprober.py @@ -0,0 +1,91 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# Proofpoint, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState, MachineState + + +class MultiByteCharSetProber(CharSetProber): + """ + MultiByteCharSetProber + """ + + def __init__(self, lang_filter=None): + super(MultiByteCharSetProber, self).__init__(lang_filter=lang_filter) + self.distribution_analyzer = None + self.coding_sm = None + self._last_char = [0, 0] + + def reset(self): + super(MultiByteCharSetProber, self).reset() + if self.coding_sm: + self.coding_sm.reset() + if self.distribution_analyzer: + self.distribution_analyzer.reset() + self._last_char = [0, 0] + + @property + def charset_name(self): + raise NotImplementedError + + @property + def language(self): + raise NotImplementedError + + def feed(self, byte_str): + for i in range(len(byte_str)): + coding_state = self.coding_sm.next_state(byte_str[i]) + if coding_state == MachineState.ERROR: + self.logger.debug('%s %s prober hit error at byte %s', + self.charset_name, self.language, i) + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + char_len = self.coding_sm.get_current_charlen() + if i == 0: + self._last_char[1] = byte_str[0] + self.distribution_analyzer.feed(self._last_char, char_len) + else: + self.distribution_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + + self._last_char[0] = byte_str[-1] + + if self.state == ProbingState.DETECTING: + if (self.distribution_analyzer.got_enough_data() and + (self.get_confidence() > self.SHORTCUT_THRESHOLD)): + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + return self.distribution_analyzer.get_confidence() diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/mbcsgroupprober.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/mbcsgroupprober.py new file mode 100644 index 0000000..530abe7 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/mbcsgroupprober.py @@ -0,0 +1,54 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# Proofpoint, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetgroupprober import CharSetGroupProber +from .utf8prober import UTF8Prober +from .sjisprober import SJISProber +from .eucjpprober import EUCJPProber +from .gb2312prober import GB2312Prober +from .euckrprober import EUCKRProber +from .cp949prober import CP949Prober +from .big5prober import Big5Prober +from .euctwprober import EUCTWProber + + +class MBCSGroupProber(CharSetGroupProber): + def __init__(self, lang_filter=None): + super(MBCSGroupProber, self).__init__(lang_filter=lang_filter) + self.probers = [ + UTF8Prober(), + SJISProber(), + EUCJPProber(), + GB2312Prober(), + EUCKRProber(), + CP949Prober(), + Big5Prober(), + EUCTWProber() + ] + self.reset() diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/mbcssm.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/mbcssm.py new file mode 100644 index 0000000..8360d0f --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/mbcssm.py @@ -0,0 +1,572 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import MachineState + +# BIG5 + +BIG5_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 #allow 0x00 as legal value + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,1, # 78 - 7f + 4,4,4,4,4,4,4,4, # 80 - 87 + 4,4,4,4,4,4,4,4, # 88 - 8f + 4,4,4,4,4,4,4,4, # 90 - 97 + 4,4,4,4,4,4,4,4, # 98 - 9f + 4,3,3,3,3,3,3,3, # a0 - a7 + 3,3,3,3,3,3,3,3, # a8 - af + 3,3,3,3,3,3,3,3, # b0 - b7 + 3,3,3,3,3,3,3,3, # b8 - bf + 3,3,3,3,3,3,3,3, # c0 - c7 + 3,3,3,3,3,3,3,3, # c8 - cf + 3,3,3,3,3,3,3,3, # d0 - d7 + 3,3,3,3,3,3,3,3, # d8 - df + 3,3,3,3,3,3,3,3, # e0 - e7 + 3,3,3,3,3,3,3,3, # e8 - ef + 3,3,3,3,3,3,3,3, # f0 - f7 + 3,3,3,3,3,3,3,0 # f8 - ff +) + +BIG5_ST = ( + MachineState.ERROR,MachineState.START,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,#08-0f + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START#10-17 +) + +BIG5_CHAR_LEN_TABLE = (0, 1, 1, 2, 0) + +BIG5_SM_MODEL = {'class_table': BIG5_CLS, + 'class_factor': 5, + 'state_table': BIG5_ST, + 'char_len_table': BIG5_CHAR_LEN_TABLE, + 'name': 'Big5'} + +# CP949 + +CP949_CLS = ( + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,0,0, # 00 - 0f + 1,1,1,1,1,1,1,1, 1,1,1,0,1,1,1,1, # 10 - 1f + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, # 20 - 2f + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, # 30 - 3f + 1,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4, # 40 - 4f + 4,4,5,5,5,5,5,5, 5,5,5,1,1,1,1,1, # 50 - 5f + 1,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5, # 60 - 6f + 5,5,5,5,5,5,5,5, 5,5,5,1,1,1,1,1, # 70 - 7f + 0,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, # 80 - 8f + 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, # 90 - 9f + 6,7,7,7,7,7,7,7, 7,7,7,7,7,8,8,8, # a0 - af + 7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7, # b0 - bf + 7,7,7,7,7,7,9,2, 2,3,2,2,2,2,2,2, # c0 - cf + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, # d0 - df + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, # e0 - ef + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,0, # f0 - ff +) + +CP949_ST = ( +#cls= 0 1 2 3 4 5 6 7 8 9 # previous state = + MachineState.ERROR,MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START, 4, 5,MachineState.ERROR, 6, # MachineState.START + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, # MachineState.ERROR + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME, # MachineState.ITS_ME + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START, # 3 + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, # 4 + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, # 5 + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START, # 6 +) + +CP949_CHAR_LEN_TABLE = (0, 1, 2, 0, 1, 1, 2, 2, 0, 2) + +CP949_SM_MODEL = {'class_table': CP949_CLS, + 'class_factor': 10, + 'state_table': CP949_ST, + 'char_len_table': CP949_CHAR_LEN_TABLE, + 'name': 'CP949'} + +# EUC-JP + +EUCJP_CLS = ( + 4,4,4,4,4,4,4,4, # 00 - 07 + 4,4,4,4,4,4,5,5, # 08 - 0f + 4,4,4,4,4,4,4,4, # 10 - 17 + 4,4,4,5,4,4,4,4, # 18 - 1f + 4,4,4,4,4,4,4,4, # 20 - 27 + 4,4,4,4,4,4,4,4, # 28 - 2f + 4,4,4,4,4,4,4,4, # 30 - 37 + 4,4,4,4,4,4,4,4, # 38 - 3f + 4,4,4,4,4,4,4,4, # 40 - 47 + 4,4,4,4,4,4,4,4, # 48 - 4f + 4,4,4,4,4,4,4,4, # 50 - 57 + 4,4,4,4,4,4,4,4, # 58 - 5f + 4,4,4,4,4,4,4,4, # 60 - 67 + 4,4,4,4,4,4,4,4, # 68 - 6f + 4,4,4,4,4,4,4,4, # 70 - 77 + 4,4,4,4,4,4,4,4, # 78 - 7f + 5,5,5,5,5,5,5,5, # 80 - 87 + 5,5,5,5,5,5,1,3, # 88 - 8f + 5,5,5,5,5,5,5,5, # 90 - 97 + 5,5,5,5,5,5,5,5, # 98 - 9f + 5,2,2,2,2,2,2,2, # a0 - a7 + 2,2,2,2,2,2,2,2, # a8 - af + 2,2,2,2,2,2,2,2, # b0 - b7 + 2,2,2,2,2,2,2,2, # b8 - bf + 2,2,2,2,2,2,2,2, # c0 - c7 + 2,2,2,2,2,2,2,2, # c8 - cf + 2,2,2,2,2,2,2,2, # d0 - d7 + 2,2,2,2,2,2,2,2, # d8 - df + 0,0,0,0,0,0,0,0, # e0 - e7 + 0,0,0,0,0,0,0,0, # e8 - ef + 0,0,0,0,0,0,0,0, # f0 - f7 + 0,0,0,0,0,0,0,5 # f8 - ff +) + +EUCJP_ST = ( + 3, 4, 3, 5,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.START,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#10-17 + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 3,MachineState.ERROR,#18-1f + 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START#20-27 +) + +EUCJP_CHAR_LEN_TABLE = (2, 2, 2, 3, 1, 0) + +EUCJP_SM_MODEL = {'class_table': EUCJP_CLS, + 'class_factor': 6, + 'state_table': EUCJP_ST, + 'char_len_table': EUCJP_CHAR_LEN_TABLE, + 'name': 'EUC-JP'} + +# EUC-KR + +EUCKR_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 1,1,1,1,1,1,1,1, # 40 - 47 + 1,1,1,1,1,1,1,1, # 48 - 4f + 1,1,1,1,1,1,1,1, # 50 - 57 + 1,1,1,1,1,1,1,1, # 58 - 5f + 1,1,1,1,1,1,1,1, # 60 - 67 + 1,1,1,1,1,1,1,1, # 68 - 6f + 1,1,1,1,1,1,1,1, # 70 - 77 + 1,1,1,1,1,1,1,1, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,0,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,2,2,2,2,2,2,2, # a0 - a7 + 2,2,2,2,2,3,3,3, # a8 - af + 2,2,2,2,2,2,2,2, # b0 - b7 + 2,2,2,2,2,2,2,2, # b8 - bf + 2,2,2,2,2,2,2,2, # c0 - c7 + 2,3,2,2,2,2,2,2, # c8 - cf + 2,2,2,2,2,2,2,2, # d0 - d7 + 2,2,2,2,2,2,2,2, # d8 - df + 2,2,2,2,2,2,2,2, # e0 - e7 + 2,2,2,2,2,2,2,2, # e8 - ef + 2,2,2,2,2,2,2,2, # f0 - f7 + 2,2,2,2,2,2,2,0 # f8 - ff +) + +EUCKR_ST = ( + MachineState.ERROR,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START #08-0f +) + +EUCKR_CHAR_LEN_TABLE = (0, 1, 2, 0) + +EUCKR_SM_MODEL = {'class_table': EUCKR_CLS, + 'class_factor': 4, + 'state_table': EUCKR_ST, + 'char_len_table': EUCKR_CHAR_LEN_TABLE, + 'name': 'EUC-KR'} + +# EUC-TW + +EUCTW_CLS = ( + 2,2,2,2,2,2,2,2, # 00 - 07 + 2,2,2,2,2,2,0,0, # 08 - 0f + 2,2,2,2,2,2,2,2, # 10 - 17 + 2,2,2,0,2,2,2,2, # 18 - 1f + 2,2,2,2,2,2,2,2, # 20 - 27 + 2,2,2,2,2,2,2,2, # 28 - 2f + 2,2,2,2,2,2,2,2, # 30 - 37 + 2,2,2,2,2,2,2,2, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,2, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,6,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,3,4,4,4,4,4,4, # a0 - a7 + 5,5,1,1,1,1,1,1, # a8 - af + 1,1,1,1,1,1,1,1, # b0 - b7 + 1,1,1,1,1,1,1,1, # b8 - bf + 1,1,3,1,3,3,3,3, # c0 - c7 + 3,3,3,3,3,3,3,3, # c8 - cf + 3,3,3,3,3,3,3,3, # d0 - d7 + 3,3,3,3,3,3,3,3, # d8 - df + 3,3,3,3,3,3,3,3, # e0 - e7 + 3,3,3,3,3,3,3,3, # e8 - ef + 3,3,3,3,3,3,3,3, # f0 - f7 + 3,3,3,3,3,3,3,0 # f8 - ff +) + +EUCTW_ST = ( + MachineState.ERROR,MachineState.ERROR,MachineState.START, 3, 3, 3, 4,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,MachineState.ERROR,#10-17 + MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f + 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.START,MachineState.START,#20-27 + MachineState.START,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START #28-2f +) + +EUCTW_CHAR_LEN_TABLE = (0, 0, 1, 2, 2, 2, 3) + +EUCTW_SM_MODEL = {'class_table': EUCTW_CLS, + 'class_factor': 7, + 'state_table': EUCTW_ST, + 'char_len_table': EUCTW_CHAR_LEN_TABLE, + 'name': 'x-euc-tw'} + +# GB2312 + +GB2312_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 3,3,3,3,3,3,3,3, # 30 - 37 + 3,3,1,1,1,1,1,1, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,4, # 78 - 7f + 5,6,6,6,6,6,6,6, # 80 - 87 + 6,6,6,6,6,6,6,6, # 88 - 8f + 6,6,6,6,6,6,6,6, # 90 - 97 + 6,6,6,6,6,6,6,6, # 98 - 9f + 6,6,6,6,6,6,6,6, # a0 - a7 + 6,6,6,6,6,6,6,6, # a8 - af + 6,6,6,6,6,6,6,6, # b0 - b7 + 6,6,6,6,6,6,6,6, # b8 - bf + 6,6,6,6,6,6,6,6, # c0 - c7 + 6,6,6,6,6,6,6,6, # c8 - cf + 6,6,6,6,6,6,6,6, # d0 - d7 + 6,6,6,6,6,6,6,6, # d8 - df + 6,6,6,6,6,6,6,6, # e0 - e7 + 6,6,6,6,6,6,6,6, # e8 - ef + 6,6,6,6,6,6,6,6, # f0 - f7 + 6,6,6,6,6,6,6,0 # f8 - ff +) + +GB2312_ST = ( + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, 3,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,#10-17 + 4,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f + MachineState.ERROR,MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,#20-27 + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START #28-2f +) + +# To be accurate, the length of class 6 can be either 2 or 4. +# But it is not necessary to discriminate between the two since +# it is used for frequency analysis only, and we are validating +# each code range there as well. So it is safe to set it to be +# 2 here. +GB2312_CHAR_LEN_TABLE = (0, 1, 1, 1, 1, 1, 2) + +GB2312_SM_MODEL = {'class_table': GB2312_CLS, + 'class_factor': 7, + 'state_table': GB2312_ST, + 'char_len_table': GB2312_CHAR_LEN_TABLE, + 'name': 'GB2312'} + +# Shift_JIS + +SJIS_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,1, # 78 - 7f + 3,3,3,3,3,2,2,3, # 80 - 87 + 3,3,3,3,3,3,3,3, # 88 - 8f + 3,3,3,3,3,3,3,3, # 90 - 97 + 3,3,3,3,3,3,3,3, # 98 - 9f + #0xa0 is illegal in sjis encoding, but some pages does + #contain such byte. We need to be more error forgiven. + 2,2,2,2,2,2,2,2, # a0 - a7 + 2,2,2,2,2,2,2,2, # a8 - af + 2,2,2,2,2,2,2,2, # b0 - b7 + 2,2,2,2,2,2,2,2, # b8 - bf + 2,2,2,2,2,2,2,2, # c0 - c7 + 2,2,2,2,2,2,2,2, # c8 - cf + 2,2,2,2,2,2,2,2, # d0 - d7 + 2,2,2,2,2,2,2,2, # d8 - df + 3,3,3,3,3,3,3,3, # e0 - e7 + 3,3,3,3,3,4,4,4, # e8 - ef + 3,3,3,3,3,3,3,3, # f0 - f7 + 3,3,3,3,3,0,0,0) # f8 - ff + + +SJIS_ST = ( + MachineState.ERROR,MachineState.START,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START #10-17 +) + +SJIS_CHAR_LEN_TABLE = (0, 1, 1, 2, 0, 0) + +SJIS_SM_MODEL = {'class_table': SJIS_CLS, + 'class_factor': 6, + 'state_table': SJIS_ST, + 'char_len_table': SJIS_CHAR_LEN_TABLE, + 'name': 'Shift_JIS'} + +# UCS2-BE + +UCS2BE_CLS = ( + 0,0,0,0,0,0,0,0, # 00 - 07 + 0,0,1,0,0,2,0,0, # 08 - 0f + 0,0,0,0,0,0,0,0, # 10 - 17 + 0,0,0,3,0,0,0,0, # 18 - 1f + 0,0,0,0,0,0,0,0, # 20 - 27 + 0,3,3,3,3,3,0,0, # 28 - 2f + 0,0,0,0,0,0,0,0, # 30 - 37 + 0,0,0,0,0,0,0,0, # 38 - 3f + 0,0,0,0,0,0,0,0, # 40 - 47 + 0,0,0,0,0,0,0,0, # 48 - 4f + 0,0,0,0,0,0,0,0, # 50 - 57 + 0,0,0,0,0,0,0,0, # 58 - 5f + 0,0,0,0,0,0,0,0, # 60 - 67 + 0,0,0,0,0,0,0,0, # 68 - 6f + 0,0,0,0,0,0,0,0, # 70 - 77 + 0,0,0,0,0,0,0,0, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,0,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,0,0,0,0,0,0,0, # a0 - a7 + 0,0,0,0,0,0,0,0, # a8 - af + 0,0,0,0,0,0,0,0, # b0 - b7 + 0,0,0,0,0,0,0,0, # b8 - bf + 0,0,0,0,0,0,0,0, # c0 - c7 + 0,0,0,0,0,0,0,0, # c8 - cf + 0,0,0,0,0,0,0,0, # d0 - d7 + 0,0,0,0,0,0,0,0, # d8 - df + 0,0,0,0,0,0,0,0, # e0 - e7 + 0,0,0,0,0,0,0,0, # e8 - ef + 0,0,0,0,0,0,0,0, # f0 - f7 + 0,0,0,0,0,0,4,5 # f8 - ff +) + +UCS2BE_ST = ( + 5, 7, 7,MachineState.ERROR, 4, 3,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME, 6, 6, 6, 6,MachineState.ERROR,MachineState.ERROR,#10-17 + 6, 6, 6, 6, 6,MachineState.ITS_ME, 6, 6,#18-1f + 6, 6, 6, 6, 5, 7, 7,MachineState.ERROR,#20-27 + 5, 8, 6, 6,MachineState.ERROR, 6, 6, 6,#28-2f + 6, 6, 6, 6,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START #30-37 +) + +UCS2BE_CHAR_LEN_TABLE = (2, 2, 2, 0, 2, 2) + +UCS2BE_SM_MODEL = {'class_table': UCS2BE_CLS, + 'class_factor': 6, + 'state_table': UCS2BE_ST, + 'char_len_table': UCS2BE_CHAR_LEN_TABLE, + 'name': 'UTF-16BE'} + +# UCS2-LE + +UCS2LE_CLS = ( + 0,0,0,0,0,0,0,0, # 00 - 07 + 0,0,1,0,0,2,0,0, # 08 - 0f + 0,0,0,0,0,0,0,0, # 10 - 17 + 0,0,0,3,0,0,0,0, # 18 - 1f + 0,0,0,0,0,0,0,0, # 20 - 27 + 0,3,3,3,3,3,0,0, # 28 - 2f + 0,0,0,0,0,0,0,0, # 30 - 37 + 0,0,0,0,0,0,0,0, # 38 - 3f + 0,0,0,0,0,0,0,0, # 40 - 47 + 0,0,0,0,0,0,0,0, # 48 - 4f + 0,0,0,0,0,0,0,0, # 50 - 57 + 0,0,0,0,0,0,0,0, # 58 - 5f + 0,0,0,0,0,0,0,0, # 60 - 67 + 0,0,0,0,0,0,0,0, # 68 - 6f + 0,0,0,0,0,0,0,0, # 70 - 77 + 0,0,0,0,0,0,0,0, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,0,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,0,0,0,0,0,0,0, # a0 - a7 + 0,0,0,0,0,0,0,0, # a8 - af + 0,0,0,0,0,0,0,0, # b0 - b7 + 0,0,0,0,0,0,0,0, # b8 - bf + 0,0,0,0,0,0,0,0, # c0 - c7 + 0,0,0,0,0,0,0,0, # c8 - cf + 0,0,0,0,0,0,0,0, # d0 - d7 + 0,0,0,0,0,0,0,0, # d8 - df + 0,0,0,0,0,0,0,0, # e0 - e7 + 0,0,0,0,0,0,0,0, # e8 - ef + 0,0,0,0,0,0,0,0, # f0 - f7 + 0,0,0,0,0,0,4,5 # f8 - ff +) + +UCS2LE_ST = ( + 6, 6, 7, 6, 4, 3,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME, 5, 5, 5,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,#10-17 + 5, 5, 5,MachineState.ERROR, 5,MachineState.ERROR, 6, 6,#18-1f + 7, 6, 8, 8, 5, 5, 5,MachineState.ERROR,#20-27 + 5, 5, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5, 5,#28-2f + 5, 5, 5,MachineState.ERROR, 5,MachineState.ERROR,MachineState.START,MachineState.START #30-37 +) + +UCS2LE_CHAR_LEN_TABLE = (2, 2, 2, 2, 2, 2) + +UCS2LE_SM_MODEL = {'class_table': UCS2LE_CLS, + 'class_factor': 6, + 'state_table': UCS2LE_ST, + 'char_len_table': UCS2LE_CHAR_LEN_TABLE, + 'name': 'UTF-16LE'} + +# UTF-8 + +UTF8_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 #allow 0x00 as a legal value + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 1,1,1,1,1,1,1,1, # 40 - 47 + 1,1,1,1,1,1,1,1, # 48 - 4f + 1,1,1,1,1,1,1,1, # 50 - 57 + 1,1,1,1,1,1,1,1, # 58 - 5f + 1,1,1,1,1,1,1,1, # 60 - 67 + 1,1,1,1,1,1,1,1, # 68 - 6f + 1,1,1,1,1,1,1,1, # 70 - 77 + 1,1,1,1,1,1,1,1, # 78 - 7f + 2,2,2,2,3,3,3,3, # 80 - 87 + 4,4,4,4,4,4,4,4, # 88 - 8f + 4,4,4,4,4,4,4,4, # 90 - 97 + 4,4,4,4,4,4,4,4, # 98 - 9f + 5,5,5,5,5,5,5,5, # a0 - a7 + 5,5,5,5,5,5,5,5, # a8 - af + 5,5,5,5,5,5,5,5, # b0 - b7 + 5,5,5,5,5,5,5,5, # b8 - bf + 0,0,6,6,6,6,6,6, # c0 - c7 + 6,6,6,6,6,6,6,6, # c8 - cf + 6,6,6,6,6,6,6,6, # d0 - d7 + 6,6,6,6,6,6,6,6, # d8 - df + 7,8,8,8,8,8,8,8, # e0 - e7 + 8,8,8,8,8,9,8,8, # e8 - ef + 10,11,11,11,11,11,11,11, # f0 - f7 + 12,13,13,13,14,15,0,0 # f8 - ff +) + +UTF8_ST = ( + MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 12, 10,#00-07 + 9, 11, 8, 7, 6, 5, 4, 3,#08-0f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#10-17 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#20-27 + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#28-2f + MachineState.ERROR,MachineState.ERROR, 5, 5, 5, 5,MachineState.ERROR,MachineState.ERROR,#30-37 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#38-3f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5, 5, 5,MachineState.ERROR,MachineState.ERROR,#40-47 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#48-4f + MachineState.ERROR,MachineState.ERROR, 7, 7, 7, 7,MachineState.ERROR,MachineState.ERROR,#50-57 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#58-5f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 7, 7,MachineState.ERROR,MachineState.ERROR,#60-67 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#68-6f + MachineState.ERROR,MachineState.ERROR, 9, 9, 9, 9,MachineState.ERROR,MachineState.ERROR,#70-77 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#78-7f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 9,MachineState.ERROR,MachineState.ERROR,#80-87 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#88-8f + MachineState.ERROR,MachineState.ERROR, 12, 12, 12, 12,MachineState.ERROR,MachineState.ERROR,#90-97 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#98-9f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 12,MachineState.ERROR,MachineState.ERROR,#a0-a7 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#a8-af + MachineState.ERROR,MachineState.ERROR, 12, 12, 12,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#b0-b7 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#b8-bf + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,#c0-c7 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR #c8-cf +) + +UTF8_CHAR_LEN_TABLE = (0, 1, 0, 0, 0, 0, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6) + +UTF8_SM_MODEL = {'class_table': UTF8_CLS, + 'class_factor': 16, + 'state_table': UTF8_ST, + 'char_len_table': UTF8_CHAR_LEN_TABLE, + 'name': 'UTF-8'} diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/sbcharsetprober.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/sbcharsetprober.py new file mode 100644 index 0000000..0adb51d --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/sbcharsetprober.py @@ -0,0 +1,132 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import CharacterCategory, ProbingState, SequenceLikelihood + + +class SingleByteCharSetProber(CharSetProber): + SAMPLE_SIZE = 64 + SB_ENOUGH_REL_THRESHOLD = 1024 # 0.25 * SAMPLE_SIZE^2 + POSITIVE_SHORTCUT_THRESHOLD = 0.95 + NEGATIVE_SHORTCUT_THRESHOLD = 0.05 + + def __init__(self, model, reversed=False, name_prober=None): + super(SingleByteCharSetProber, self).__init__() + self._model = model + # TRUE if we need to reverse every pair in the model lookup + self._reversed = reversed + # Optional auxiliary prober for name decision + self._name_prober = name_prober + self._last_order = None + self._seq_counters = None + self._total_seqs = None + self._total_char = None + self._freq_char = None + self.reset() + + def reset(self): + super(SingleByteCharSetProber, self).reset() + # char order of last character + self._last_order = 255 + self._seq_counters = [0] * SequenceLikelihood.get_num_categories() + self._total_seqs = 0 + self._total_char = 0 + # characters that fall in our sampling range + self._freq_char = 0 + + @property + def charset_name(self): + if self._name_prober: + return self._name_prober.charset_name + else: + return self._model['charset_name'] + + @property + def language(self): + if self._name_prober: + return self._name_prober.language + else: + return self._model.get('language') + + def feed(self, byte_str): + if not self._model['keep_english_letter']: + byte_str = self.filter_international_words(byte_str) + if not byte_str: + return self.state + char_to_order_map = self._model['char_to_order_map'] + for i, c in enumerate(byte_str): + # XXX: Order is in range 1-64, so one would think we want 0-63 here, + # but that leads to 27 more test failures than before. + order = char_to_order_map[c] + # XXX: This was SYMBOL_CAT_ORDER before, with a value of 250, but + # CharacterCategory.SYMBOL is actually 253, so we use CONTROL + # to make it closer to the original intent. The only difference + # is whether or not we count digits and control characters for + # _total_char purposes. + if order < CharacterCategory.CONTROL: + self._total_char += 1 + if order < self.SAMPLE_SIZE: + self._freq_char += 1 + if self._last_order < self.SAMPLE_SIZE: + self._total_seqs += 1 + if not self._reversed: + i = (self._last_order * self.SAMPLE_SIZE) + order + model = self._model['precedence_matrix'][i] + else: # reverse the order of the letters in the lookup + i = (order * self.SAMPLE_SIZE) + self._last_order + model = self._model['precedence_matrix'][i] + self._seq_counters[model] += 1 + self._last_order = order + + charset_name = self._model['charset_name'] + if self.state == ProbingState.DETECTING: + if self._total_seqs > self.SB_ENOUGH_REL_THRESHOLD: + confidence = self.get_confidence() + if confidence > self.POSITIVE_SHORTCUT_THRESHOLD: + self.logger.debug('%s confidence = %s, we have a winner', + charset_name, confidence) + self._state = ProbingState.FOUND_IT + elif confidence < self.NEGATIVE_SHORTCUT_THRESHOLD: + self.logger.debug('%s confidence = %s, below negative ' + 'shortcut threshhold %s', charset_name, + confidence, + self.NEGATIVE_SHORTCUT_THRESHOLD) + self._state = ProbingState.NOT_ME + + return self.state + + def get_confidence(self): + r = 0.01 + if self._total_seqs > 0: + r = ((1.0 * self._seq_counters[SequenceLikelihood.POSITIVE]) / + self._total_seqs / self._model['typical_positive_ratio']) + r = r * self._freq_char / self._total_char + if r >= 1.0: + r = 0.99 + return r diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/sbcsgroupprober.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/sbcsgroupprober.py new file mode 100644 index 0000000..98e95dc --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/sbcsgroupprober.py @@ -0,0 +1,73 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetgroupprober import CharSetGroupProber +from .sbcharsetprober import SingleByteCharSetProber +from .langcyrillicmodel import (Win1251CyrillicModel, Koi8rModel, + Latin5CyrillicModel, MacCyrillicModel, + Ibm866Model, Ibm855Model) +from .langgreekmodel import Latin7GreekModel, Win1253GreekModel +from .langbulgarianmodel import Latin5BulgarianModel, Win1251BulgarianModel +# from .langhungarianmodel import Latin2HungarianModel, Win1250HungarianModel +from .langthaimodel import TIS620ThaiModel +from .langhebrewmodel import Win1255HebrewModel +from .hebrewprober import HebrewProber +from .langturkishmodel import Latin5TurkishModel + + +class SBCSGroupProber(CharSetGroupProber): + def __init__(self): + super(SBCSGroupProber, self).__init__() + self.probers = [ + SingleByteCharSetProber(Win1251CyrillicModel), + SingleByteCharSetProber(Koi8rModel), + SingleByteCharSetProber(Latin5CyrillicModel), + SingleByteCharSetProber(MacCyrillicModel), + SingleByteCharSetProber(Ibm866Model), + SingleByteCharSetProber(Ibm855Model), + SingleByteCharSetProber(Latin7GreekModel), + SingleByteCharSetProber(Win1253GreekModel), + SingleByteCharSetProber(Latin5BulgarianModel), + SingleByteCharSetProber(Win1251BulgarianModel), + # TODO: Restore Hungarian encodings (iso-8859-2 and windows-1250) + # after we retrain model. + # SingleByteCharSetProber(Latin2HungarianModel), + # SingleByteCharSetProber(Win1250HungarianModel), + SingleByteCharSetProber(TIS620ThaiModel), + SingleByteCharSetProber(Latin5TurkishModel), + ] + hebrew_prober = HebrewProber() + logical_hebrew_prober = SingleByteCharSetProber(Win1255HebrewModel, + False, hebrew_prober) + visual_hebrew_prober = SingleByteCharSetProber(Win1255HebrewModel, True, + hebrew_prober) + hebrew_prober.set_model_probers(logical_hebrew_prober, visual_hebrew_prober) + self.probers.extend([hebrew_prober, logical_hebrew_prober, + visual_hebrew_prober]) + + self.reset() diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/sjisprober.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/sjisprober.py new file mode 100644 index 0000000..9e29623 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/sjisprober.py @@ -0,0 +1,92 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import SJISDistributionAnalysis +from .jpcntx import SJISContextAnalysis +from .mbcssm import SJIS_SM_MODEL +from .enums import ProbingState, MachineState + + +class SJISProber(MultiByteCharSetProber): + def __init__(self): + super(SJISProber, self).__init__() + self.coding_sm = CodingStateMachine(SJIS_SM_MODEL) + self.distribution_analyzer = SJISDistributionAnalysis() + self.context_analyzer = SJISContextAnalysis() + self.reset() + + def reset(self): + super(SJISProber, self).reset() + self.context_analyzer.reset() + + @property + def charset_name(self): + return self.context_analyzer.charset_name + + @property + def language(self): + return "Japanese" + + def feed(self, byte_str): + for i in range(len(byte_str)): + coding_state = self.coding_sm.next_state(byte_str[i]) + if coding_state == MachineState.ERROR: + self.logger.debug('%s %s prober hit error at byte %s', + self.charset_name, self.language, i) + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + char_len = self.coding_sm.get_current_charlen() + if i == 0: + self._last_char[1] = byte_str[0] + self.context_analyzer.feed(self._last_char[2 - char_len:], + char_len) + self.distribution_analyzer.feed(self._last_char, char_len) + else: + self.context_analyzer.feed(byte_str[i + 1 - char_len:i + 3 + - char_len], char_len) + self.distribution_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + + self._last_char[0] = byte_str[-1] + + if self.state == ProbingState.DETECTING: + if (self.context_analyzer.got_enough_data() and + (self.get_confidence() > self.SHORTCUT_THRESHOLD)): + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + context_conf = self.context_analyzer.get_confidence() + distrib_conf = self.distribution_analyzer.get_confidence() + return max(context_conf, distrib_conf) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/universaldetector.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/universaldetector.py new file mode 100644 index 0000000..7b4e92d --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/universaldetector.py @@ -0,0 +1,286 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### +""" +Module containing the UniversalDetector detector class, which is the primary +class a user of ``chardet`` should use. + +:author: Mark Pilgrim (initial port to Python) +:author: Shy Shalom (original C code) +:author: Dan Blanchard (major refactoring for 3.0) +:author: Ian Cordasco +""" + + +import codecs +import logging +import re + +from .charsetgroupprober import CharSetGroupProber +from .enums import InputState, LanguageFilter, ProbingState +from .escprober import EscCharSetProber +from .latin1prober import Latin1Prober +from .mbcsgroupprober import MBCSGroupProber +from .sbcsgroupprober import SBCSGroupProber + + +class UniversalDetector(object): + """ + The ``UniversalDetector`` class underlies the ``chardet.detect`` function + and coordinates all of the different charset probers. + + To get a ``dict`` containing an encoding and its confidence, you can simply + run: + + .. code:: + + u = UniversalDetector() + u.feed(some_bytes) + u.close() + detected = u.result + + """ + + MINIMUM_THRESHOLD = 0.20 + HIGH_BYTE_DETECTOR = re.compile(b'[\x80-\xFF]') + ESC_DETECTOR = re.compile(b'(\033|~{)') + WIN_BYTE_DETECTOR = re.compile(b'[\x80-\x9F]') + ISO_WIN_MAP = {'iso-8859-1': 'Windows-1252', + 'iso-8859-2': 'Windows-1250', + 'iso-8859-5': 'Windows-1251', + 'iso-8859-6': 'Windows-1256', + 'iso-8859-7': 'Windows-1253', + 'iso-8859-8': 'Windows-1255', + 'iso-8859-9': 'Windows-1254', + 'iso-8859-13': 'Windows-1257'} + + def __init__(self, lang_filter=LanguageFilter.ALL): + self._esc_charset_prober = None + self._charset_probers = [] + self.result = None + self.done = None + self._got_data = None + self._input_state = None + self._last_char = None + self.lang_filter = lang_filter + self.logger = logging.getLogger(__name__) + self._has_win_bytes = None + self.reset() + + def reset(self): + """ + Reset the UniversalDetector and all of its probers back to their + initial states. This is called by ``__init__``, so you only need to + call this directly in between analyses of different documents. + """ + self.result = {'encoding': None, 'confidence': 0.0, 'language': None} + self.done = False + self._got_data = False + self._has_win_bytes = False + self._input_state = InputState.PURE_ASCII + self._last_char = b'' + if self._esc_charset_prober: + self._esc_charset_prober.reset() + for prober in self._charset_probers: + prober.reset() + + def feed(self, byte_str): + """ + Takes a chunk of a document and feeds it through all of the relevant + charset probers. + + After calling ``feed``, you can check the value of the ``done`` + attribute to see if you need to continue feeding the + ``UniversalDetector`` more data, or if it has made a prediction + (in the ``result`` attribute). + + .. note:: + You should always call ``close`` when you're done feeding in your + document if ``done`` is not already ``True``. + """ + if self.done: + return + + if not len(byte_str): + return + + if not isinstance(byte_str, bytearray): + byte_str = bytearray(byte_str) + + # First check for known BOMs, since these are guaranteed to be correct + if not self._got_data: + # If the data starts with BOM, we know it is UTF + if byte_str.startswith(codecs.BOM_UTF8): + # EF BB BF UTF-8 with BOM + self.result = {'encoding': "UTF-8-SIG", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith((codecs.BOM_UTF32_LE, + codecs.BOM_UTF32_BE)): + # FF FE 00 00 UTF-32, little-endian BOM + # 00 00 FE FF UTF-32, big-endian BOM + self.result = {'encoding': "UTF-32", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith(b'\xFE\xFF\x00\x00'): + # FE FF 00 00 UCS-4, unusual octet order BOM (3412) + self.result = {'encoding': "X-ISO-10646-UCS-4-3412", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith(b'\x00\x00\xFF\xFE'): + # 00 00 FF FE UCS-4, unusual octet order BOM (2143) + self.result = {'encoding': "X-ISO-10646-UCS-4-2143", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith((codecs.BOM_LE, codecs.BOM_BE)): + # FF FE UTF-16, little endian BOM + # FE FF UTF-16, big endian BOM + self.result = {'encoding': "UTF-16", + 'confidence': 1.0, + 'language': ''} + + self._got_data = True + if self.result['encoding'] is not None: + self.done = True + return + + # If none of those matched and we've only see ASCII so far, check + # for high bytes and escape sequences + if self._input_state == InputState.PURE_ASCII: + if self.HIGH_BYTE_DETECTOR.search(byte_str): + self._input_state = InputState.HIGH_BYTE + elif self._input_state == InputState.PURE_ASCII and \ + self.ESC_DETECTOR.search(self._last_char + byte_str): + self._input_state = InputState.ESC_ASCII + + self._last_char = byte_str[-1:] + + # If we've seen escape sequences, use the EscCharSetProber, which + # uses a simple state machine to check for known escape sequences in + # HZ and ISO-2022 encodings, since those are the only encodings that + # use such sequences. + if self._input_state == InputState.ESC_ASCII: + if not self._esc_charset_prober: + self._esc_charset_prober = EscCharSetProber(self.lang_filter) + if self._esc_charset_prober.feed(byte_str) == ProbingState.FOUND_IT: + self.result = {'encoding': + self._esc_charset_prober.charset_name, + 'confidence': + self._esc_charset_prober.get_confidence(), + 'language': + self._esc_charset_prober.language} + self.done = True + # If we've seen high bytes (i.e., those with values greater than 127), + # we need to do more complicated checks using all our multi-byte and + # single-byte probers that are left. The single-byte probers + # use character bigram distributions to determine the encoding, whereas + # the multi-byte probers use a combination of character unigram and + # bigram distributions. + elif self._input_state == InputState.HIGH_BYTE: + if not self._charset_probers: + self._charset_probers = [MBCSGroupProber(self.lang_filter)] + # If we're checking non-CJK encodings, use single-byte prober + if self.lang_filter & LanguageFilter.NON_CJK: + self._charset_probers.append(SBCSGroupProber()) + self._charset_probers.append(Latin1Prober()) + for prober in self._charset_probers: + if prober.feed(byte_str) == ProbingState.FOUND_IT: + self.result = {'encoding': prober.charset_name, + 'confidence': prober.get_confidence(), + 'language': prober.language} + self.done = True + break + if self.WIN_BYTE_DETECTOR.search(byte_str): + self._has_win_bytes = True + + def close(self): + """ + Stop analyzing the current document and come up with a final + prediction. + + :returns: The ``result`` attribute, a ``dict`` with the keys + `encoding`, `confidence`, and `language`. + """ + # Don't bother with checks if we're already done + if self.done: + return self.result + self.done = True + + if not self._got_data: + self.logger.debug('no data received!') + + # Default to ASCII if it is all we've seen so far + elif self._input_state == InputState.PURE_ASCII: + self.result = {'encoding': 'ascii', + 'confidence': 1.0, + 'language': ''} + + # If we have seen non-ASCII, return the best that met MINIMUM_THRESHOLD + elif self._input_state == InputState.HIGH_BYTE: + prober_confidence = None + max_prober_confidence = 0.0 + max_prober = None + for prober in self._charset_probers: + if not prober: + continue + prober_confidence = prober.get_confidence() + if prober_confidence > max_prober_confidence: + max_prober_confidence = prober_confidence + max_prober = prober + if max_prober and (max_prober_confidence > self.MINIMUM_THRESHOLD): + charset_name = max_prober.charset_name + lower_charset_name = max_prober.charset_name.lower() + confidence = max_prober.get_confidence() + # Use Windows encoding name instead of ISO-8859 if we saw any + # extra Windows-specific bytes + if lower_charset_name.startswith('iso-8859'): + if self._has_win_bytes: + charset_name = self.ISO_WIN_MAP.get(lower_charset_name, + charset_name) + self.result = {'encoding': charset_name, + 'confidence': confidence, + 'language': max_prober.language} + + # Log all prober confidences if none met MINIMUM_THRESHOLD + if self.logger.getEffectiveLevel() == logging.DEBUG: + if self.result['encoding'] is None: + self.logger.debug('no probers hit minimum threshold') + for group_prober in self._charset_probers: + if not group_prober: + continue + if isinstance(group_prober, CharSetGroupProber): + for prober in group_prober.probers: + self.logger.debug('%s %s confidence = %s', + prober.charset_name, + prober.language, + prober.get_confidence()) + else: + self.logger.debug('%s %s confidence = %s', + prober.charset_name, + prober.language, + prober.get_confidence()) + return self.result diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/utf8prober.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/utf8prober.py new file mode 100644 index 0000000..6c3196c --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/utf8prober.py @@ -0,0 +1,82 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState, MachineState +from .codingstatemachine import CodingStateMachine +from .mbcssm import UTF8_SM_MODEL + + + +class UTF8Prober(CharSetProber): + ONE_CHAR_PROB = 0.5 + + def __init__(self): + super(UTF8Prober, self).__init__() + self.coding_sm = CodingStateMachine(UTF8_SM_MODEL) + self._num_mb_chars = None + self.reset() + + def reset(self): + super(UTF8Prober, self).reset() + self.coding_sm.reset() + self._num_mb_chars = 0 + + @property + def charset_name(self): + return "utf-8" + + @property + def language(self): + return "" + + def feed(self, byte_str): + for c in byte_str: + coding_state = self.coding_sm.next_state(c) + if coding_state == MachineState.ERROR: + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + if self.coding_sm.get_current_charlen() >= 2: + self._num_mb_chars += 1 + + if self.state == ProbingState.DETECTING: + if self.get_confidence() > self.SHORTCUT_THRESHOLD: + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + unlike = 0.99 + if self._num_mb_chars < 6: + unlike *= self.ONE_CHAR_PROB ** self._num_mb_chars + return 1.0 - unlike + else: + return unlike diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/chardet/version.py b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/version.py new file mode 100644 index 0000000..bb2a34a --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/chardet/version.py @@ -0,0 +1,9 @@ +""" +This module exists only to simplify retrieving the version number of chardet +from within setup.py and from chardet subpackages. + +:author: Dan Blanchard (dan.blanchard@gmail.com) +""" + +__version__ = "3.0.4" +VERSION = __version__.split('.') diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/colorama/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/colorama/__init__.py new file mode 100644 index 0000000..f4d9ce2 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/colorama/__init__.py @@ -0,0 +1,7 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +from .initialise import init, deinit, reinit, colorama_text +from .ansi import Fore, Back, Style, Cursor +from .ansitowin32 import AnsiToWin32 + +__version__ = '0.3.9' + diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c786e0ed4ad58ae4bc201cb645351bf6447c9069 GIT binary patch literal 452 zcmXv~%}&BV5bi&P(s(8D33`A<8Z{)wC>oDmATimPYzi%~vfFL8r9hv-7x9($>dBjD zPwqgNWWI0yb~fKk!mwj#`@EdL|7!k*<ZPA>9<-Ow8d4)QnZZqLatmAB#x{4bV?y0x zF88p<Te!u2?DIBmAL};j@Bjxoc5pX!r$*%cn0i&@D2L{>QeK*!Se`gs2qt906H;aS z3dUZ9%#<@p78~VGs{_lF_q3Izkddi^$GoI7@kaA_)VRYzJQ%-5q3Xa&nlM^s5)?=q zzyWYIC@0a+qz8Emzz1kUCxA{RcCb*wSyVtsoyn4loRBX=Uce~8pG1YEby8)hP9$0i zmg+IY*JyE7ka08q81CX_+LSkOEl2yR;X`e!9L-Qci$2ZEDq*aDeLG)ow(}JfkFI~q hQz6m$4u}v?L&%^wDF2R&bjz}PP*s9}p4l_I);}ULd$s@o literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/ansi.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/ansi.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9d84605b5872436e5a42863d26e6a2ae58f4a081 GIT binary patch literal 3350 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 Nm&uLM6^}Dq{{T3zic0_h literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/ansitowin32.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/ansitowin32.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..23ab5330b4186a065928e555e89b96219fef2212 GIT binary patch literal 7063 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 O#8WOkM_H~lGygwY^nwon literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/initialise.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/initialise.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..335104cb6bebda2fe6dd1db39b709a3e6fc125be GIT binary patch literal 1671 zcma)6OK%%D5GJ_~tyT{|n!2s)qJj?v1T;|+qbX7}MIWdSJ?K&)34{OwEz;83t6gD8 zNwFYbY9D%N`y1?I|I%K2%3tWIGgKtoK?{_N8FI)WIs45w{JvI;8Mfa(K6-UtV(c$6 zR?Wx3w<yM<QcUrbb(cNwa%YRKP(pdBH}bnaM-LgGgeWDHNcpm?0u^4eZmhOdq{^4P zTT!v9;7nEXlbWik+9kW--MXr)4V>Ljn`#UDO~rp^&G+8m&8+=~qi*t|@?B<<PW~dv z4jv!&X=&924t_u}AEL4t<Y^i1S!VeKzY^CBLt}UxZ#O;g(4(m2kPLdps(fOLGH9c1 zPp0Xg3_@IX>TlZ`Lo$_Cx26(W$9bwWnAT|6>OUIyp3a}1Je(aItGRh{Fonmj?R@kQ z+aPOoTH|DVKgo>66YqcV<<anTax|bxC%vi8R1U3vp5`D&vXx|sO=OxF{a}0s0p7oj zVhDZ4BkpE8eP`kf^%SG~+h1|8@XW4d3%1}3G4L)p>{_nyzklIYoOsel9mtTzh)M)c z6qBWF$41tt9k|cC2z+Km&yywcbzZN~tL(hOcf0~wwz0Xim8+_)U2{ZM$k?IlwdbGD zK#rds%GBsaKhKWSq;E}Qme^rKW@nAu4mC6+44!phqC3rc;o)=<KbPr5{|Jyn;h8g2 zgv-PL{i`!Hz)i}?sMAGbtyU?lkc|dtIl8mxc47`+C$^{ZOc&wOC?e2<#8_M>#G8Im zmJ^#hCKM%%eX7A00iKwQ3!hHEVFqBKu)?RjeSjmgi;9VD9t9x}Ma)BQhdb^0*aK1W z-^tp*mA7QA6Ipx0Qj*HBXFat16=?&91W=_yg;b4HmDHN9%aMyLRGMNtz;zR$A{K?j zq>pgCj)Y2v+;bGOk7`MxKQN_pOz3kgnip6$SVA~@xh^2#{>L5F6orq;#C)C3sJ|7A zi=(!pcn|TnU(r1-9E3>lSim06ti!=ETUT)djsFKs9X)RWvq|QE0|O2iS2}lq`2@H1 zi3ijO(shM>hQ`8&{Z)l6JjH+a&x1v9#jhFcFM<<sj@5^+i=fx#ee{PNQuk1;pBppG zC#mWYkBHDj(`E>tlHc7OK#VF%OM1gQh{6Ug{)A%a7a8~QtGeX6m8O5#Zg-knK<`Hp zBZ&$3G&ynr6%~oEr_E>ddb(F|$tuSs2crXT3-`K`xXE)-e|ywOW^#ZPLx}^z%w2mc oNXJH(`{?UYt|qDehH`3XLxh1wqKY-)3nyL_#CuVxUXDut0A4v^FaQ7m literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/win32.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/win32.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a9605d1003c1f68d393eaab44dc08b8f95fff0eb GIT binary patch literal 3886 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 RbRE|mExA@@(yh3a{{!I1c*Xz# literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/winterm.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/winterm.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5af802b21c97a73322ae1844e61e6f7a74538941 GIT binary patch literal 4575 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/colorama/ansi.py b/venv/lib/python3.7/site-packages/pip/_vendor/colorama/ansi.py new file mode 100644 index 0000000..7877658 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/colorama/ansi.py @@ -0,0 +1,102 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +''' +This module generates ANSI character codes to printing colors to terminals. +See: http://en.wikipedia.org/wiki/ANSI_escape_code +''' + +CSI = '\033[' +OSC = '\033]' +BEL = '\007' + + +def code_to_chars(code): + return CSI + str(code) + 'm' + +def set_title(title): + return OSC + '2;' + title + BEL + +def clear_screen(mode=2): + return CSI + str(mode) + 'J' + +def clear_line(mode=2): + return CSI + str(mode) + 'K' + + +class AnsiCodes(object): + def __init__(self): + # the subclasses declare class attributes which are numbers. + # Upon instantiation we define instance attributes, which are the same + # as the class attributes but wrapped with the ANSI escape sequence + for name in dir(self): + if not name.startswith('_'): + value = getattr(self, name) + setattr(self, name, code_to_chars(value)) + + +class AnsiCursor(object): + def UP(self, n=1): + return CSI + str(n) + 'A' + def DOWN(self, n=1): + return CSI + str(n) + 'B' + def FORWARD(self, n=1): + return CSI + str(n) + 'C' + def BACK(self, n=1): + return CSI + str(n) + 'D' + def POS(self, x=1, y=1): + return CSI + str(y) + ';' + str(x) + 'H' + + +class AnsiFore(AnsiCodes): + BLACK = 30 + RED = 31 + GREEN = 32 + YELLOW = 33 + BLUE = 34 + MAGENTA = 35 + CYAN = 36 + WHITE = 37 + RESET = 39 + + # These are fairly well supported, but not part of the standard. + LIGHTBLACK_EX = 90 + LIGHTRED_EX = 91 + LIGHTGREEN_EX = 92 + LIGHTYELLOW_EX = 93 + LIGHTBLUE_EX = 94 + LIGHTMAGENTA_EX = 95 + LIGHTCYAN_EX = 96 + LIGHTWHITE_EX = 97 + + +class AnsiBack(AnsiCodes): + BLACK = 40 + RED = 41 + GREEN = 42 + YELLOW = 43 + BLUE = 44 + MAGENTA = 45 + CYAN = 46 + WHITE = 47 + RESET = 49 + + # These are fairly well supported, but not part of the standard. + LIGHTBLACK_EX = 100 + LIGHTRED_EX = 101 + LIGHTGREEN_EX = 102 + LIGHTYELLOW_EX = 103 + LIGHTBLUE_EX = 104 + LIGHTMAGENTA_EX = 105 + LIGHTCYAN_EX = 106 + LIGHTWHITE_EX = 107 + + +class AnsiStyle(AnsiCodes): + BRIGHT = 1 + DIM = 2 + NORMAL = 22 + RESET_ALL = 0 + +Fore = AnsiFore() +Back = AnsiBack() +Style = AnsiStyle() +Cursor = AnsiCursor() diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/colorama/ansitowin32.py b/venv/lib/python3.7/site-packages/pip/_vendor/colorama/ansitowin32.py new file mode 100644 index 0000000..1d6e605 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/colorama/ansitowin32.py @@ -0,0 +1,236 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +import re +import sys +import os + +from .ansi import AnsiFore, AnsiBack, AnsiStyle, Style +from .winterm import WinTerm, WinColor, WinStyle +from .win32 import windll, winapi_test + + +winterm = None +if windll is not None: + winterm = WinTerm() + + +def is_stream_closed(stream): + return not hasattr(stream, 'closed') or stream.closed + + +def is_a_tty(stream): + return hasattr(stream, 'isatty') and stream.isatty() + + +class StreamWrapper(object): + ''' + Wraps a stream (such as stdout), acting as a transparent proxy for all + attribute access apart from method 'write()', which is delegated to our + Converter instance. + ''' + def __init__(self, wrapped, converter): + # double-underscore everything to prevent clashes with names of + # attributes on the wrapped stream object. + self.__wrapped = wrapped + self.__convertor = converter + + def __getattr__(self, name): + return getattr(self.__wrapped, name) + + def write(self, text): + self.__convertor.write(text) + + +class AnsiToWin32(object): + ''' + Implements a 'write()' method which, on Windows, will strip ANSI character + sequences from the text, and if outputting to a tty, will convert them into + win32 function calls. + ''' + ANSI_CSI_RE = re.compile('\001?\033\\[((?:\\d|;)*)([a-zA-Z])\002?') # Control Sequence Introducer + ANSI_OSC_RE = re.compile('\001?\033\\]((?:.|;)*?)(\x07)\002?') # Operating System Command + + def __init__(self, wrapped, convert=None, strip=None, autoreset=False): + # The wrapped stream (normally sys.stdout or sys.stderr) + self.wrapped = wrapped + + # should we reset colors to defaults after every .write() + self.autoreset = autoreset + + # create the proxy wrapping our output stream + self.stream = StreamWrapper(wrapped, self) + + on_windows = os.name == 'nt' + # We test if the WinAPI works, because even if we are on Windows + # we may be using a terminal that doesn't support the WinAPI + # (e.g. Cygwin Terminal). In this case it's up to the terminal + # to support the ANSI codes. + conversion_supported = on_windows and winapi_test() + + # should we strip ANSI sequences from our output? + if strip is None: + strip = conversion_supported or (not is_stream_closed(wrapped) and not is_a_tty(wrapped)) + self.strip = strip + + # should we should convert ANSI sequences into win32 calls? + if convert is None: + convert = conversion_supported and not is_stream_closed(wrapped) and is_a_tty(wrapped) + self.convert = convert + + # dict of ansi codes to win32 functions and parameters + self.win32_calls = self.get_win32_calls() + + # are we wrapping stderr? + self.on_stderr = self.wrapped is sys.stderr + + def should_wrap(self): + ''' + True if this class is actually needed. If false, then the output + stream will not be affected, nor will win32 calls be issued, so + wrapping stdout is not actually required. This will generally be + False on non-Windows platforms, unless optional functionality like + autoreset has been requested using kwargs to init() + ''' + return self.convert or self.strip or self.autoreset + + def get_win32_calls(self): + if self.convert and winterm: + return { + AnsiStyle.RESET_ALL: (winterm.reset_all, ), + AnsiStyle.BRIGHT: (winterm.style, WinStyle.BRIGHT), + AnsiStyle.DIM: (winterm.style, WinStyle.NORMAL), + AnsiStyle.NORMAL: (winterm.style, WinStyle.NORMAL), + AnsiFore.BLACK: (winterm.fore, WinColor.BLACK), + AnsiFore.RED: (winterm.fore, WinColor.RED), + AnsiFore.GREEN: (winterm.fore, WinColor.GREEN), + AnsiFore.YELLOW: (winterm.fore, WinColor.YELLOW), + AnsiFore.BLUE: (winterm.fore, WinColor.BLUE), + AnsiFore.MAGENTA: (winterm.fore, WinColor.MAGENTA), + AnsiFore.CYAN: (winterm.fore, WinColor.CYAN), + AnsiFore.WHITE: (winterm.fore, WinColor.GREY), + AnsiFore.RESET: (winterm.fore, ), + AnsiFore.LIGHTBLACK_EX: (winterm.fore, WinColor.BLACK, True), + AnsiFore.LIGHTRED_EX: (winterm.fore, WinColor.RED, True), + AnsiFore.LIGHTGREEN_EX: (winterm.fore, WinColor.GREEN, True), + AnsiFore.LIGHTYELLOW_EX: (winterm.fore, WinColor.YELLOW, True), + AnsiFore.LIGHTBLUE_EX: (winterm.fore, WinColor.BLUE, True), + AnsiFore.LIGHTMAGENTA_EX: (winterm.fore, WinColor.MAGENTA, True), + AnsiFore.LIGHTCYAN_EX: (winterm.fore, WinColor.CYAN, True), + AnsiFore.LIGHTWHITE_EX: (winterm.fore, WinColor.GREY, True), + AnsiBack.BLACK: (winterm.back, WinColor.BLACK), + AnsiBack.RED: (winterm.back, WinColor.RED), + AnsiBack.GREEN: (winterm.back, WinColor.GREEN), + AnsiBack.YELLOW: (winterm.back, WinColor.YELLOW), + AnsiBack.BLUE: (winterm.back, WinColor.BLUE), + AnsiBack.MAGENTA: (winterm.back, WinColor.MAGENTA), + AnsiBack.CYAN: (winterm.back, WinColor.CYAN), + AnsiBack.WHITE: (winterm.back, WinColor.GREY), + AnsiBack.RESET: (winterm.back, ), + AnsiBack.LIGHTBLACK_EX: (winterm.back, WinColor.BLACK, True), + AnsiBack.LIGHTRED_EX: (winterm.back, WinColor.RED, True), + AnsiBack.LIGHTGREEN_EX: (winterm.back, WinColor.GREEN, True), + AnsiBack.LIGHTYELLOW_EX: (winterm.back, WinColor.YELLOW, True), + AnsiBack.LIGHTBLUE_EX: (winterm.back, WinColor.BLUE, True), + AnsiBack.LIGHTMAGENTA_EX: (winterm.back, WinColor.MAGENTA, True), + AnsiBack.LIGHTCYAN_EX: (winterm.back, WinColor.CYAN, True), + AnsiBack.LIGHTWHITE_EX: (winterm.back, WinColor.GREY, True), + } + return dict() + + def write(self, text): + if self.strip or self.convert: + self.write_and_convert(text) + else: + self.wrapped.write(text) + self.wrapped.flush() + if self.autoreset: + self.reset_all() + + + def reset_all(self): + if self.convert: + self.call_win32('m', (0,)) + elif not self.strip and not is_stream_closed(self.wrapped): + self.wrapped.write(Style.RESET_ALL) + + + def write_and_convert(self, text): + ''' + Write the given text to our wrapped stream, stripping any ANSI + sequences from the text, and optionally converting them into win32 + calls. + ''' + cursor = 0 + text = self.convert_osc(text) + for match in self.ANSI_CSI_RE.finditer(text): + start, end = match.span() + self.write_plain_text(text, cursor, start) + self.convert_ansi(*match.groups()) + cursor = end + self.write_plain_text(text, cursor, len(text)) + + + def write_plain_text(self, text, start, end): + if start < end: + self.wrapped.write(text[start:end]) + self.wrapped.flush() + + + def convert_ansi(self, paramstring, command): + if self.convert: + params = self.extract_params(command, paramstring) + self.call_win32(command, params) + + + def extract_params(self, command, paramstring): + if command in 'Hf': + params = tuple(int(p) if len(p) != 0 else 1 for p in paramstring.split(';')) + while len(params) < 2: + # defaults: + params = params + (1,) + else: + params = tuple(int(p) for p in paramstring.split(';') if len(p) != 0) + if len(params) == 0: + # defaults: + if command in 'JKm': + params = (0,) + elif command in 'ABCD': + params = (1,) + + return params + + + def call_win32(self, command, params): + if command == 'm': + for param in params: + if param in self.win32_calls: + func_args = self.win32_calls[param] + func = func_args[0] + args = func_args[1:] + kwargs = dict(on_stderr=self.on_stderr) + func(*args, **kwargs) + elif command in 'J': + winterm.erase_screen(params[0], on_stderr=self.on_stderr) + elif command in 'K': + winterm.erase_line(params[0], on_stderr=self.on_stderr) + elif command in 'Hf': # cursor position - absolute + winterm.set_cursor_position(params, on_stderr=self.on_stderr) + elif command in 'ABCD': # cursor position - relative + n = params[0] + # A - up, B - down, C - forward, D - back + x, y = {'A': (0, -n), 'B': (0, n), 'C': (n, 0), 'D': (-n, 0)}[command] + winterm.cursor_adjust(x, y, on_stderr=self.on_stderr) + + + def convert_osc(self, text): + for match in self.ANSI_OSC_RE.finditer(text): + start, end = match.span() + text = text[:start] + text[end:] + paramstring, command = match.groups() + if command in '\x07': # \x07 = BEL + params = paramstring.split(";") + # 0 - change title and icon (we will only change title) + # 1 - change icon (we don't support this) + # 2 - change title + if params[0] in '02': + winterm.set_title(params[1]) + return text diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/colorama/initialise.py b/venv/lib/python3.7/site-packages/pip/_vendor/colorama/initialise.py new file mode 100644 index 0000000..834962a --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/colorama/initialise.py @@ -0,0 +1,82 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +import atexit +import contextlib +import sys + +from .ansitowin32 import AnsiToWin32 + + +orig_stdout = None +orig_stderr = None + +wrapped_stdout = None +wrapped_stderr = None + +atexit_done = False + + +def reset_all(): + if AnsiToWin32 is not None: # Issue #74: objects might become None at exit + AnsiToWin32(orig_stdout).reset_all() + + +def init(autoreset=False, convert=None, strip=None, wrap=True): + + if not wrap and any([autoreset, convert, strip]): + raise ValueError('wrap=False conflicts with any other arg=True') + + global wrapped_stdout, wrapped_stderr + global orig_stdout, orig_stderr + + orig_stdout = sys.stdout + orig_stderr = sys.stderr + + if sys.stdout is None: + wrapped_stdout = None + else: + sys.stdout = wrapped_stdout = \ + wrap_stream(orig_stdout, convert, strip, autoreset, wrap) + if sys.stderr is None: + wrapped_stderr = None + else: + sys.stderr = wrapped_stderr = \ + wrap_stream(orig_stderr, convert, strip, autoreset, wrap) + + global atexit_done + if not atexit_done: + atexit.register(reset_all) + atexit_done = True + + +def deinit(): + if orig_stdout is not None: + sys.stdout = orig_stdout + if orig_stderr is not None: + sys.stderr = orig_stderr + + +@contextlib.contextmanager +def colorama_text(*args, **kwargs): + init(*args, **kwargs) + try: + yield + finally: + deinit() + + +def reinit(): + if wrapped_stdout is not None: + sys.stdout = wrapped_stdout + if wrapped_stderr is not None: + sys.stderr = wrapped_stderr + + +def wrap_stream(stream, convert, strip, autoreset, wrap): + if wrap: + wrapper = AnsiToWin32(stream, + convert=convert, strip=strip, autoreset=autoreset) + if wrapper.should_wrap(): + stream = wrapper.stream + return stream + + diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/colorama/win32.py b/venv/lib/python3.7/site-packages/pip/_vendor/colorama/win32.py new file mode 100644 index 0000000..8262e35 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/colorama/win32.py @@ -0,0 +1,156 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. + +# from winbase.h +STDOUT = -11 +STDERR = -12 + +try: + import ctypes + from ctypes import LibraryLoader + windll = LibraryLoader(ctypes.WinDLL) + from ctypes import wintypes +except (AttributeError, ImportError): + windll = None + SetConsoleTextAttribute = lambda *_: None + winapi_test = lambda *_: None +else: + from ctypes import byref, Structure, c_char, POINTER + + COORD = wintypes._COORD + + class CONSOLE_SCREEN_BUFFER_INFO(Structure): + """struct in wincon.h.""" + _fields_ = [ + ("dwSize", COORD), + ("dwCursorPosition", COORD), + ("wAttributes", wintypes.WORD), + ("srWindow", wintypes.SMALL_RECT), + ("dwMaximumWindowSize", COORD), + ] + def __str__(self): + return '(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)' % ( + self.dwSize.Y, self.dwSize.X + , self.dwCursorPosition.Y, self.dwCursorPosition.X + , self.wAttributes + , self.srWindow.Top, self.srWindow.Left, self.srWindow.Bottom, self.srWindow.Right + , self.dwMaximumWindowSize.Y, self.dwMaximumWindowSize.X + ) + + _GetStdHandle = windll.kernel32.GetStdHandle + _GetStdHandle.argtypes = [ + wintypes.DWORD, + ] + _GetStdHandle.restype = wintypes.HANDLE + + _GetConsoleScreenBufferInfo = windll.kernel32.GetConsoleScreenBufferInfo + _GetConsoleScreenBufferInfo.argtypes = [ + wintypes.HANDLE, + POINTER(CONSOLE_SCREEN_BUFFER_INFO), + ] + _GetConsoleScreenBufferInfo.restype = wintypes.BOOL + + _SetConsoleTextAttribute = windll.kernel32.SetConsoleTextAttribute + _SetConsoleTextAttribute.argtypes = [ + wintypes.HANDLE, + wintypes.WORD, + ] + _SetConsoleTextAttribute.restype = wintypes.BOOL + + _SetConsoleCursorPosition = windll.kernel32.SetConsoleCursorPosition + _SetConsoleCursorPosition.argtypes = [ + wintypes.HANDLE, + COORD, + ] + _SetConsoleCursorPosition.restype = wintypes.BOOL + + _FillConsoleOutputCharacterA = windll.kernel32.FillConsoleOutputCharacterA + _FillConsoleOutputCharacterA.argtypes = [ + wintypes.HANDLE, + c_char, + wintypes.DWORD, + COORD, + POINTER(wintypes.DWORD), + ] + _FillConsoleOutputCharacterA.restype = wintypes.BOOL + + _FillConsoleOutputAttribute = windll.kernel32.FillConsoleOutputAttribute + _FillConsoleOutputAttribute.argtypes = [ + wintypes.HANDLE, + wintypes.WORD, + wintypes.DWORD, + COORD, + POINTER(wintypes.DWORD), + ] + _FillConsoleOutputAttribute.restype = wintypes.BOOL + + _SetConsoleTitleW = windll.kernel32.SetConsoleTitleW + _SetConsoleTitleW.argtypes = [ + wintypes.LPCWSTR + ] + _SetConsoleTitleW.restype = wintypes.BOOL + + handles = { + STDOUT: _GetStdHandle(STDOUT), + STDERR: _GetStdHandle(STDERR), + } + + def _winapi_test(handle): + csbi = CONSOLE_SCREEN_BUFFER_INFO() + success = _GetConsoleScreenBufferInfo( + handle, byref(csbi)) + return bool(success) + + def winapi_test(): + return any(_winapi_test(h) for h in handles.values()) + + def GetConsoleScreenBufferInfo(stream_id=STDOUT): + handle = handles[stream_id] + csbi = CONSOLE_SCREEN_BUFFER_INFO() + success = _GetConsoleScreenBufferInfo( + handle, byref(csbi)) + return csbi + + def SetConsoleTextAttribute(stream_id, attrs): + handle = handles[stream_id] + return _SetConsoleTextAttribute(handle, attrs) + + def SetConsoleCursorPosition(stream_id, position, adjust=True): + position = COORD(*position) + # If the position is out of range, do nothing. + if position.Y <= 0 or position.X <= 0: + return + # Adjust for Windows' SetConsoleCursorPosition: + # 1. being 0-based, while ANSI is 1-based. + # 2. expecting (x,y), while ANSI uses (y,x). + adjusted_position = COORD(position.Y - 1, position.X - 1) + if adjust: + # Adjust for viewport's scroll position + sr = GetConsoleScreenBufferInfo(STDOUT).srWindow + adjusted_position.Y += sr.Top + adjusted_position.X += sr.Left + # Resume normal processing + handle = handles[stream_id] + return _SetConsoleCursorPosition(handle, adjusted_position) + + def FillConsoleOutputCharacter(stream_id, char, length, start): + handle = handles[stream_id] + char = c_char(char.encode()) + length = wintypes.DWORD(length) + num_written = wintypes.DWORD(0) + # Note that this is hard-coded for ANSI (vs wide) bytes. + success = _FillConsoleOutputCharacterA( + handle, char, length, start, byref(num_written)) + return num_written.value + + def FillConsoleOutputAttribute(stream_id, attr, length, start): + ''' FillConsoleOutputAttribute( hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten )''' + handle = handles[stream_id] + attribute = wintypes.WORD(attr) + length = wintypes.DWORD(length) + num_written = wintypes.DWORD(0) + # Note that this is hard-coded for ANSI (vs wide) bytes. + return _FillConsoleOutputAttribute( + handle, attribute, length, start, byref(num_written)) + + def SetConsoleTitle(title): + return _SetConsoleTitleW(title) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/colorama/winterm.py b/venv/lib/python3.7/site-packages/pip/_vendor/colorama/winterm.py new file mode 100644 index 0000000..60309d3 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/colorama/winterm.py @@ -0,0 +1,162 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +from . import win32 + + +# from wincon.h +class WinColor(object): + BLACK = 0 + BLUE = 1 + GREEN = 2 + CYAN = 3 + RED = 4 + MAGENTA = 5 + YELLOW = 6 + GREY = 7 + +# from wincon.h +class WinStyle(object): + NORMAL = 0x00 # dim text, dim background + BRIGHT = 0x08 # bright text, dim background + BRIGHT_BACKGROUND = 0x80 # dim text, bright background + +class WinTerm(object): + + def __init__(self): + self._default = win32.GetConsoleScreenBufferInfo(win32.STDOUT).wAttributes + self.set_attrs(self._default) + self._default_fore = self._fore + self._default_back = self._back + self._default_style = self._style + # In order to emulate LIGHT_EX in windows, we borrow the BRIGHT style. + # So that LIGHT_EX colors and BRIGHT style do not clobber each other, + # we track them separately, since LIGHT_EX is overwritten by Fore/Back + # and BRIGHT is overwritten by Style codes. + self._light = 0 + + def get_attrs(self): + return self._fore + self._back * 16 + (self._style | self._light) + + def set_attrs(self, value): + self._fore = value & 7 + self._back = (value >> 4) & 7 + self._style = value & (WinStyle.BRIGHT | WinStyle.BRIGHT_BACKGROUND) + + def reset_all(self, on_stderr=None): + self.set_attrs(self._default) + self.set_console(attrs=self._default) + + def fore(self, fore=None, light=False, on_stderr=False): + if fore is None: + fore = self._default_fore + self._fore = fore + # Emulate LIGHT_EX with BRIGHT Style + if light: + self._light |= WinStyle.BRIGHT + else: + self._light &= ~WinStyle.BRIGHT + self.set_console(on_stderr=on_stderr) + + def back(self, back=None, light=False, on_stderr=False): + if back is None: + back = self._default_back + self._back = back + # Emulate LIGHT_EX with BRIGHT_BACKGROUND Style + if light: + self._light |= WinStyle.BRIGHT_BACKGROUND + else: + self._light &= ~WinStyle.BRIGHT_BACKGROUND + self.set_console(on_stderr=on_stderr) + + def style(self, style=None, on_stderr=False): + if style is None: + style = self._default_style + self._style = style + self.set_console(on_stderr=on_stderr) + + def set_console(self, attrs=None, on_stderr=False): + if attrs is None: + attrs = self.get_attrs() + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + win32.SetConsoleTextAttribute(handle, attrs) + + def get_position(self, handle): + position = win32.GetConsoleScreenBufferInfo(handle).dwCursorPosition + # Because Windows coordinates are 0-based, + # and win32.SetConsoleCursorPosition expects 1-based. + position.X += 1 + position.Y += 1 + return position + + def set_cursor_position(self, position=None, on_stderr=False): + if position is None: + # I'm not currently tracking the position, so there is no default. + # position = self.get_position() + return + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + win32.SetConsoleCursorPosition(handle, position) + + def cursor_adjust(self, x, y, on_stderr=False): + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + position = self.get_position(handle) + adjusted_position = (position.Y + y, position.X + x) + win32.SetConsoleCursorPosition(handle, adjusted_position, adjust=False) + + def erase_screen(self, mode=0, on_stderr=False): + # 0 should clear from the cursor to the end of the screen. + # 1 should clear from the cursor to the beginning of the screen. + # 2 should clear the entire screen, and move cursor to (1,1) + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + csbi = win32.GetConsoleScreenBufferInfo(handle) + # get the number of character cells in the current buffer + cells_in_screen = csbi.dwSize.X * csbi.dwSize.Y + # get number of character cells before current cursor position + cells_before_cursor = csbi.dwSize.X * csbi.dwCursorPosition.Y + csbi.dwCursorPosition.X + if mode == 0: + from_coord = csbi.dwCursorPosition + cells_to_erase = cells_in_screen - cells_before_cursor + if mode == 1: + from_coord = win32.COORD(0, 0) + cells_to_erase = cells_before_cursor + elif mode == 2: + from_coord = win32.COORD(0, 0) + cells_to_erase = cells_in_screen + # fill the entire screen with blanks + win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) + # now set the buffer's attributes accordingly + win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) + if mode == 2: + # put the cursor where needed + win32.SetConsoleCursorPosition(handle, (1, 1)) + + def erase_line(self, mode=0, on_stderr=False): + # 0 should clear from the cursor to the end of the line. + # 1 should clear from the cursor to the beginning of the line. + # 2 should clear the entire line. + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + csbi = win32.GetConsoleScreenBufferInfo(handle) + if mode == 0: + from_coord = csbi.dwCursorPosition + cells_to_erase = csbi.dwSize.X - csbi.dwCursorPosition.X + if mode == 1: + from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) + cells_to_erase = csbi.dwCursorPosition.X + elif mode == 2: + from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) + cells_to_erase = csbi.dwSize.X + # fill the entire screen with blanks + win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) + # now set the buffer's attributes accordingly + win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) + + def set_title(self, title): + win32.SetConsoleTitle(title) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/__init__.py new file mode 100644 index 0000000..d4aab45 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2017 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +import logging + +__version__ = '0.2.7' + +class DistlibException(Exception): + pass + +try: + from logging import NullHandler +except ImportError: # pragma: no cover + class NullHandler(logging.Handler): + def handle(self, record): pass + def emit(self, record): pass + def createLock(self): self.lock = None + +logger = logging.getLogger(__name__) +logger.addHandler(NullHandler()) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0d2b2dc7daccf4bfb0b91ef56ecb6b58b3abb20c GIT binary patch literal 1050 zcma)5&1w`u5U!s8olU|TMFg)R%pp55K|??!s6mCW2Nl#oXm+Q2H<Qd?dS=&T@s=EY zh~(%i_0^NF;K{0)Bpbzp)pSjD_t#a`U)4NcUiJay+x^k!T?60;Ew02vV+UuIqY@xk z3K0k+Vy{4$!a4(CN#oRv%#$9T+9_mKWHI;v`9lk&edw#V3}_(U5ia6g2?q||us%U< zd;|&SuJkTg)RCQYUs|Vd!5GGQ2Z8q!W5Qr=ulG0lTQM!JgrTv6vsywWAz}g|qq$`0 z-piz_(`2-J9Lus!ihK~5+T%PQW|DL5bDkAqnv%W5`O$QkwkO{~Iq0oXzmCFEC9`2I z!`V=U<02JORbjRt#*a$AJ>Nc9|FSt2^XkdwOl=(3^K2bul85iZGAY-RysC$3y7qW$ zw0}4qO=z>3d?s^Is8F;ihMXsPQghxfPZUxQU3wE49&6SC)7`-|O<xalkxKOk2L#(8 z`~y@A4uo+Ak=Yg}vV<)hT-(AWLKT%Wri&!>B_dzotSnRl5X1%z1A(EfN~UA&C>a+@ zEVxlFLbbEsq_j$Ral(A{MxOol@P8wz4mwcOgnvh|WR}#o@t}>-yBULyV#=R{zVx2v zE#yhSSKwDKLK>~Khz|qShPtkE`xZY|5=*^@h&y<-jdk~CtOZ~YILbtjBEpnSii)PF z5!DK*h4aQDwi@1Vp;6J6$7nQrL07wJF_|R!M0YuMhpMn)u`@f@-P`m*1J>O)Sy`xh zSE)j2_p&E+XCmu8^dVJ~n0CmaRN5a3af$g?PTG6g{s+$}!>UJ#8J5vA4c22T?4Iqj E-`tYmtN;K2 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a91027176969aa80d86cabbdda399f63d5297aeb GIT binary patch literal 32060 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/database.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/database.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0e3eb849eafdf3f6214999f0d26bd1b8365426e1 GIT binary patch literal 42533 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 G?EBwxrD-kz literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/index.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/index.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..531a2a0e287cb6e1129636e229446cf22b90399a GIT binary patch literal 17346 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 VP^WY=AePvwn69;AQ6RFd{{e@ooE888 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/locators.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/locators.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dca0597001f3a6c374997b19174be454b8ea89d9 GIT binary patch literal 38653 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 Nj|TRfp3(Ek{|%cEmDT_N literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/manifest.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/manifest.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1ecc31a8fcef37f869f8e3f364cf750b7eadc8f7 GIT binary patch literal 10298 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 Avj6}9 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/markers.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/markers.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..083af5d40fb28454aa68f2ea90afea0ba593b31e GIT binary patch literal 4484 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 S71q`*-Kn*^&QC3-ga03F922tu literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/metadata.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/metadata.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6d2e7d15df4f0f4994fde6f048ac044e7a15d479 GIT binary patch literal 27693 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7806dbe416b68249964c413212c30839410375f2 GIT binary patch literal 10894 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/scripts.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/scripts.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..384c87c051d45961e315c9b68f79270ad454dddc GIT binary patch literal 11070 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 bq>b|41KS_|lYhi;$#iCrL_KSnxvBpH8j)V; literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7478b97cd5311a48373a95200f3a431d8e17a704 GIT binary patch literal 47891 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 Re|Tv4q2VpV9~~b1{{Wv2k469h literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/version.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/version.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a0c773e5bb073ccbb9e6baacd84da62e0150bdd6 GIT binary patch literal 20434 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/wheel.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/wheel.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..32eb745a1420de7e0105a7e93b286524d65e8e98 GIT binary patch literal 25084 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 V>faj;^?$q3{g;TJjapXd{{Xi`p!fg) literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__init__.py new file mode 100644 index 0000000..f7dbf4c --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__init__.py @@ -0,0 +1,6 @@ +"""Modules copied from Python 3 standard libraries, for internal use only. + +Individual classes and functions are found in d2._backport.misc. Intended +usage is to always import things missing from 3.1 from that module: the +built-in/stdlib objects will be used if found. +""" diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2a45cb5f947ea2519f2cac7a1237d5cf23d58a75 GIT binary patch literal 492 zcmX|8%}N9@4DNbR8S&!PORj=W)kQ@S5pNz8K~Ex-&a|@=?X*MFnRVA!@I`#3z4{iO z%<Q6pge1++_oX-6+nHeb+$~;qMnZfK!Jlv}u32f5jS<hnj2^|_n%?4vyI?wJ3Chr- zHBiOSz{4!n!NV9RX>W8i;IN1~qNRPPLIm{5Mz0-oWFdGr%d_m(8|=|^oGqOu;+fnG zRp-lu!E+QXH+P&v59T;mg)ZOP5L4bDl{vsIPxZ!{tRp?KfCMRkc2hkgz-Fj~RHL5| za09WkLOafnR!*vQf@aC*f-7xSbm-CndP&JJ0|>>dEfc{MorA&-=ow74LX~Itd!xmM zQYMs2eTlfn$6A`757|cSb+WS8QC7hj8%Z{`ERR}sK0kjwoQ^9qr_*sCkKfb0Ib@l5 z`6OFxc|V`gxr39lqJHa&$&g&C>X~kc(jX;<C;ty3l|qk6sl1&nHZNC{uGWViWEH;z C@tuPJ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/misc.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/misc.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a54cbdce29e4401c334caec2fbe10dbc3e1b4270 GIT binary patch literal 1089 zcmZ8fTWb?R6rP#gO*We}wBY5TB8#9Hu-$4=DHPEb9|XyZ0d*0U-I+<c>E4)`q)muE z*gpCr+806apZE{v)hGXgPoCLCyv%aWo^$40zcUAGYaW90X)}5E%|htAQGOp6gr`9A zD=>ya#4sZn4srb_Az>D?nKQCNYqk!yMrP+u=wS336*q0f8^@k_iIMqOhq=r;$D#8U z732+?xx5)R!S62kx#0I<<%d}-Yvo?(L5#=ja}+jL5gy0mcG!lP8xYfhn9r-2HgmwQ zz4T+`73!_cgM*kJSEW$WAC|&T3zkk(Hi<KzX0eo9`f<Vh;iRA{EepB*14cxBy+LDo z#G|1o^GKExLAiEmoMmy6fi#r7pe5ryEC{#{sNv=Sa>&SsK=KN(1r{#DmB+|?vOo)R z9YI%CUt_9q`31zVS<Rwh3RxY-lgUV1{8Wi1gx2imNl=M&8Y>=5V-XC?jBz1@{3xLJ zt7vb&H{Lnf9kRK6v^y0KPSrf$fio(CK~SaDR$52}U2i>noE#lbl94gi6is=-N)fPB zsw_={C|SW2<f)|F)vO+D!;E1AL%4%`Si6TS2q-p2IOcDLt_L<RNTCH%_{@Nh`#qw) zRMt%tl#4dpLl&z{#(yRhCQ6tbn?SNg691FmG*IW?2jO>q(Om$PwMNc}xU)bPma;FL zOLU3B-e6cY7w8O+-D|)<VrGCR{rM(8tvFSFGE=a7co9;Gdwx+W|F-P4L<dS}r@qt{ zT<OMg)1b_xzB=N{><VPX^ZF(&M!GeaRs6XSrO>tlQM*x8#5s>5gP931+W#Y)v2FoL zQxjni+dy4n1JHxsnr=oBD`^yIQc7VKVJrYYSgbU!>iy{Ui`=~Jx^|7BZuOzmvX?e3 zvkYc6@4Cibn3B5tOev8j6SZ{vtF8LgnRRG)KQGxN<4+o(NgtR^T<j9hB6uBl@w!8> N3;z!3+QhVte*v3!2^|0c literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/shutil.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/shutil.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5fd36938faca7f7af77647d93625b857533bbc57 GIT binary patch literal 21405 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 NeBMdalDwee{{}0i9FPD2 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/sysconfig.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/sysconfig.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f5233af1421581c19d1864b6eacd20c857eb5312 GIT binary patch literal 15870 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/tarfile.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/tarfile.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..45f0ede623fe1502a4ec50be6903f44b484f79c0 GIT binary patch literal 62735 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 TpXmRFj$@sxl<o`$vg!W;xI9vq literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/misc.py b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/misc.py new file mode 100644 index 0000000..cfb318d --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/misc.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +"""Backports for individual classes and functions.""" + +import os +import sys + +__all__ = ['cache_from_source', 'callable', 'fsencode'] + + +try: + from imp import cache_from_source +except ImportError: + def cache_from_source(py_file, debug=__debug__): + ext = debug and 'c' or 'o' + return py_file + ext + + +try: + callable = callable +except NameError: + from collections import Callable + + def callable(obj): + return isinstance(obj, Callable) + + +try: + fsencode = os.fsencode +except AttributeError: + def fsencode(filename): + if isinstance(filename, bytes): + return filename + elif isinstance(filename, str): + return filename.encode(sys.getfilesystemencoding()) + else: + raise TypeError("expect bytes or str, not %s" % + type(filename).__name__) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/shutil.py b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/shutil.py new file mode 100644 index 0000000..159e49e --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/shutil.py @@ -0,0 +1,761 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +"""Utility functions for copying and archiving files and directory trees. + +XXX The functions here don't copy the resource fork or other metadata on Mac. + +""" + +import os +import sys +import stat +from os.path import abspath +import fnmatch +import collections +import errno +from . import tarfile + +try: + import bz2 + _BZ2_SUPPORTED = True +except ImportError: + _BZ2_SUPPORTED = False + +try: + from pwd import getpwnam +except ImportError: + getpwnam = None + +try: + from grp import getgrnam +except ImportError: + getgrnam = None + +__all__ = ["copyfileobj", "copyfile", "copymode", "copystat", "copy", "copy2", + "copytree", "move", "rmtree", "Error", "SpecialFileError", + "ExecError", "make_archive", "get_archive_formats", + "register_archive_format", "unregister_archive_format", + "get_unpack_formats", "register_unpack_format", + "unregister_unpack_format", "unpack_archive", "ignore_patterns"] + +class Error(EnvironmentError): + pass + +class SpecialFileError(EnvironmentError): + """Raised when trying to do a kind of operation (e.g. copying) which is + not supported on a special file (e.g. a named pipe)""" + +class ExecError(EnvironmentError): + """Raised when a command could not be executed""" + +class ReadError(EnvironmentError): + """Raised when an archive cannot be read""" + +class RegistryError(Exception): + """Raised when a registry operation with the archiving + and unpacking registries fails""" + + +try: + WindowsError +except NameError: + WindowsError = None + +def copyfileobj(fsrc, fdst, length=16*1024): + """copy data from file-like object fsrc to file-like object fdst""" + while 1: + buf = fsrc.read(length) + if not buf: + break + fdst.write(buf) + +def _samefile(src, dst): + # Macintosh, Unix. + if hasattr(os.path, 'samefile'): + try: + return os.path.samefile(src, dst) + except OSError: + return False + + # All other platforms: check for same pathname. + return (os.path.normcase(os.path.abspath(src)) == + os.path.normcase(os.path.abspath(dst))) + +def copyfile(src, dst): + """Copy data from src to dst""" + if _samefile(src, dst): + raise Error("`%s` and `%s` are the same file" % (src, dst)) + + for fn in [src, dst]: + try: + st = os.stat(fn) + except OSError: + # File most likely does not exist + pass + else: + # XXX What about other special files? (sockets, devices...) + if stat.S_ISFIFO(st.st_mode): + raise SpecialFileError("`%s` is a named pipe" % fn) + + with open(src, 'rb') as fsrc: + with open(dst, 'wb') as fdst: + copyfileobj(fsrc, fdst) + +def copymode(src, dst): + """Copy mode bits from src to dst""" + if hasattr(os, 'chmod'): + st = os.stat(src) + mode = stat.S_IMODE(st.st_mode) + os.chmod(dst, mode) + +def copystat(src, dst): + """Copy all stat info (mode bits, atime, mtime, flags) from src to dst""" + st = os.stat(src) + mode = stat.S_IMODE(st.st_mode) + if hasattr(os, 'utime'): + os.utime(dst, (st.st_atime, st.st_mtime)) + if hasattr(os, 'chmod'): + os.chmod(dst, mode) + if hasattr(os, 'chflags') and hasattr(st, 'st_flags'): + try: + os.chflags(dst, st.st_flags) + except OSError as why: + if (not hasattr(errno, 'EOPNOTSUPP') or + why.errno != errno.EOPNOTSUPP): + raise + +def copy(src, dst): + """Copy data and mode bits ("cp src dst"). + + The destination may be a directory. + + """ + if os.path.isdir(dst): + dst = os.path.join(dst, os.path.basename(src)) + copyfile(src, dst) + copymode(src, dst) + +def copy2(src, dst): + """Copy data and all stat info ("cp -p src dst"). + + The destination may be a directory. + + """ + if os.path.isdir(dst): + dst = os.path.join(dst, os.path.basename(src)) + copyfile(src, dst) + copystat(src, dst) + +def ignore_patterns(*patterns): + """Function that can be used as copytree() ignore parameter. + + Patterns is a sequence of glob-style patterns + that are used to exclude files""" + def _ignore_patterns(path, names): + ignored_names = [] + for pattern in patterns: + ignored_names.extend(fnmatch.filter(names, pattern)) + return set(ignored_names) + return _ignore_patterns + +def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, + ignore_dangling_symlinks=False): + """Recursively copy a directory tree. + + The destination directory must not already exist. + If exception(s) occur, an Error is raised with a list of reasons. + + If the optional symlinks flag is true, symbolic links in the + source tree result in symbolic links in the destination tree; if + it is false, the contents of the files pointed to by symbolic + links are copied. If the file pointed by the symlink doesn't + exist, an exception will be added in the list of errors raised in + an Error exception at the end of the copy process. + + You can set the optional ignore_dangling_symlinks flag to true if you + want to silence this exception. Notice that this has no effect on + platforms that don't support os.symlink. + + The optional ignore argument is a callable. If given, it + is called with the `src` parameter, which is the directory + being visited by copytree(), and `names` which is the list of + `src` contents, as returned by os.listdir(): + + callable(src, names) -> ignored_names + + Since copytree() is called recursively, the callable will be + called once for each directory that is copied. It returns a + list of names relative to the `src` directory that should + not be copied. + + The optional copy_function argument is a callable that will be used + to copy each file. It will be called with the source path and the + destination path as arguments. By default, copy2() is used, but any + function that supports the same signature (like copy()) can be used. + + """ + names = os.listdir(src) + if ignore is not None: + ignored_names = ignore(src, names) + else: + ignored_names = set() + + os.makedirs(dst) + errors = [] + for name in names: + if name in ignored_names: + continue + srcname = os.path.join(src, name) + dstname = os.path.join(dst, name) + try: + if os.path.islink(srcname): + linkto = os.readlink(srcname) + if symlinks: + os.symlink(linkto, dstname) + else: + # ignore dangling symlink if the flag is on + if not os.path.exists(linkto) and ignore_dangling_symlinks: + continue + # otherwise let the copy occurs. copy2 will raise an error + copy_function(srcname, dstname) + elif os.path.isdir(srcname): + copytree(srcname, dstname, symlinks, ignore, copy_function) + else: + # Will raise a SpecialFileError for unsupported file types + copy_function(srcname, dstname) + # catch the Error from the recursive copytree so that we can + # continue with other files + except Error as err: + errors.extend(err.args[0]) + except EnvironmentError as why: + errors.append((srcname, dstname, str(why))) + try: + copystat(src, dst) + except OSError as why: + if WindowsError is not None and isinstance(why, WindowsError): + # Copying file access times may fail on Windows + pass + else: + errors.extend((src, dst, str(why))) + if errors: + raise Error(errors) + +def rmtree(path, ignore_errors=False, onerror=None): + """Recursively delete a directory tree. + + If ignore_errors is set, errors are ignored; otherwise, if onerror + is set, it is called to handle the error with arguments (func, + path, exc_info) where func is os.listdir, os.remove, or os.rmdir; + path is the argument to that function that caused it to fail; and + exc_info is a tuple returned by sys.exc_info(). If ignore_errors + is false and onerror is None, an exception is raised. + + """ + if ignore_errors: + def onerror(*args): + pass + elif onerror is None: + def onerror(*args): + raise + try: + if os.path.islink(path): + # symlinks to directories are forbidden, see bug #1669 + raise OSError("Cannot call rmtree on a symbolic link") + except OSError: + onerror(os.path.islink, path, sys.exc_info()) + # can't continue even if onerror hook returns + return + names = [] + try: + names = os.listdir(path) + except os.error: + onerror(os.listdir, path, sys.exc_info()) + for name in names: + fullname = os.path.join(path, name) + try: + mode = os.lstat(fullname).st_mode + except os.error: + mode = 0 + if stat.S_ISDIR(mode): + rmtree(fullname, ignore_errors, onerror) + else: + try: + os.remove(fullname) + except os.error: + onerror(os.remove, fullname, sys.exc_info()) + try: + os.rmdir(path) + except os.error: + onerror(os.rmdir, path, sys.exc_info()) + + +def _basename(path): + # A basename() variant which first strips the trailing slash, if present. + # Thus we always get the last component of the path, even for directories. + return os.path.basename(path.rstrip(os.path.sep)) + +def move(src, dst): + """Recursively move a file or directory to another location. This is + similar to the Unix "mv" command. + + If the destination is a directory or a symlink to a directory, the source + is moved inside the directory. The destination path must not already + exist. + + If the destination already exists but is not a directory, it may be + overwritten depending on os.rename() semantics. + + If the destination is on our current filesystem, then rename() is used. + Otherwise, src is copied to the destination and then removed. + A lot more could be done here... A look at a mv.c shows a lot of + the issues this implementation glosses over. + + """ + real_dst = dst + if os.path.isdir(dst): + if _samefile(src, dst): + # We might be on a case insensitive filesystem, + # perform the rename anyway. + os.rename(src, dst) + return + + real_dst = os.path.join(dst, _basename(src)) + if os.path.exists(real_dst): + raise Error("Destination path '%s' already exists" % real_dst) + try: + os.rename(src, real_dst) + except OSError: + if os.path.isdir(src): + if _destinsrc(src, dst): + raise Error("Cannot move a directory '%s' into itself '%s'." % (src, dst)) + copytree(src, real_dst, symlinks=True) + rmtree(src) + else: + copy2(src, real_dst) + os.unlink(src) + +def _destinsrc(src, dst): + src = abspath(src) + dst = abspath(dst) + if not src.endswith(os.path.sep): + src += os.path.sep + if not dst.endswith(os.path.sep): + dst += os.path.sep + return dst.startswith(src) + +def _get_gid(name): + """Returns a gid, given a group name.""" + if getgrnam is None or name is None: + return None + try: + result = getgrnam(name) + except KeyError: + result = None + if result is not None: + return result[2] + return None + +def _get_uid(name): + """Returns an uid, given a user name.""" + if getpwnam is None or name is None: + return None + try: + result = getpwnam(name) + except KeyError: + result = None + if result is not None: + return result[2] + return None + +def _make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0, + owner=None, group=None, logger=None): + """Create a (possibly compressed) tar file from all the files under + 'base_dir'. + + 'compress' must be "gzip" (the default), "bzip2", or None. + + 'owner' and 'group' can be used to define an owner and a group for the + archive that is being built. If not provided, the current owner and group + will be used. + + The output tar file will be named 'base_name' + ".tar", possibly plus + the appropriate compression extension (".gz", or ".bz2"). + + Returns the output filename. + """ + tar_compression = {'gzip': 'gz', None: ''} + compress_ext = {'gzip': '.gz'} + + if _BZ2_SUPPORTED: + tar_compression['bzip2'] = 'bz2' + compress_ext['bzip2'] = '.bz2' + + # flags for compression program, each element of list will be an argument + if compress is not None and compress not in compress_ext: + raise ValueError("bad value for 'compress', or compression format not " + "supported : {0}".format(compress)) + + archive_name = base_name + '.tar' + compress_ext.get(compress, '') + archive_dir = os.path.dirname(archive_name) + + if not os.path.exists(archive_dir): + if logger is not None: + logger.info("creating %s", archive_dir) + if not dry_run: + os.makedirs(archive_dir) + + # creating the tarball + if logger is not None: + logger.info('Creating tar archive') + + uid = _get_uid(owner) + gid = _get_gid(group) + + def _set_uid_gid(tarinfo): + if gid is not None: + tarinfo.gid = gid + tarinfo.gname = group + if uid is not None: + tarinfo.uid = uid + tarinfo.uname = owner + return tarinfo + + if not dry_run: + tar = tarfile.open(archive_name, 'w|%s' % tar_compression[compress]) + try: + tar.add(base_dir, filter=_set_uid_gid) + finally: + tar.close() + + return archive_name + +def _call_external_zip(base_dir, zip_filename, verbose=False, dry_run=False): + # XXX see if we want to keep an external call here + if verbose: + zipoptions = "-r" + else: + zipoptions = "-rq" + from distutils.errors import DistutilsExecError + from distutils.spawn import spawn + try: + spawn(["zip", zipoptions, zip_filename, base_dir], dry_run=dry_run) + except DistutilsExecError: + # XXX really should distinguish between "couldn't find + # external 'zip' command" and "zip failed". + raise ExecError("unable to create zip file '%s': " + "could neither import the 'zipfile' module nor " + "find a standalone zip utility") % zip_filename + +def _make_zipfile(base_name, base_dir, verbose=0, dry_run=0, logger=None): + """Create a zip file from all the files under 'base_dir'. + + The output zip file will be named 'base_name' + ".zip". Uses either the + "zipfile" Python module (if available) or the InfoZIP "zip" utility + (if installed and found on the default search path). If neither tool is + available, raises ExecError. Returns the name of the output zip + file. + """ + zip_filename = base_name + ".zip" + archive_dir = os.path.dirname(base_name) + + if not os.path.exists(archive_dir): + if logger is not None: + logger.info("creating %s", archive_dir) + if not dry_run: + os.makedirs(archive_dir) + + # If zipfile module is not available, try spawning an external 'zip' + # command. + try: + import zipfile + except ImportError: + zipfile = None + + if zipfile is None: + _call_external_zip(base_dir, zip_filename, verbose, dry_run) + else: + if logger is not None: + logger.info("creating '%s' and adding '%s' to it", + zip_filename, base_dir) + + if not dry_run: + zip = zipfile.ZipFile(zip_filename, "w", + compression=zipfile.ZIP_DEFLATED) + + for dirpath, dirnames, filenames in os.walk(base_dir): + for name in filenames: + path = os.path.normpath(os.path.join(dirpath, name)) + if os.path.isfile(path): + zip.write(path, path) + if logger is not None: + logger.info("adding '%s'", path) + zip.close() + + return zip_filename + +_ARCHIVE_FORMATS = { + 'gztar': (_make_tarball, [('compress', 'gzip')], "gzip'ed tar-file"), + 'bztar': (_make_tarball, [('compress', 'bzip2')], "bzip2'ed tar-file"), + 'tar': (_make_tarball, [('compress', None)], "uncompressed tar file"), + 'zip': (_make_zipfile, [], "ZIP file"), + } + +if _BZ2_SUPPORTED: + _ARCHIVE_FORMATS['bztar'] = (_make_tarball, [('compress', 'bzip2')], + "bzip2'ed tar-file") + +def get_archive_formats(): + """Returns a list of supported formats for archiving and unarchiving. + + Each element of the returned sequence is a tuple (name, description) + """ + formats = [(name, registry[2]) for name, registry in + _ARCHIVE_FORMATS.items()] + formats.sort() + return formats + +def register_archive_format(name, function, extra_args=None, description=''): + """Registers an archive format. + + name is the name of the format. function is the callable that will be + used to create archives. If provided, extra_args is a sequence of + (name, value) tuples that will be passed as arguments to the callable. + description can be provided to describe the format, and will be returned + by the get_archive_formats() function. + """ + if extra_args is None: + extra_args = [] + if not isinstance(function, collections.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') + for element in extra_args: + if not isinstance(element, (tuple, list)) or len(element) !=2: + raise TypeError('extra_args elements are : (arg_name, value)') + + _ARCHIVE_FORMATS[name] = (function, extra_args, description) + +def unregister_archive_format(name): + del _ARCHIVE_FORMATS[name] + +def make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0, + dry_run=0, owner=None, group=None, logger=None): + """Create an archive file (eg. zip or tar). + + 'base_name' is the name of the file to create, minus any format-specific + extension; 'format' is the archive format: one of "zip", "tar", "bztar" + or "gztar". + + 'root_dir' is a directory that will be the root directory of the + archive; ie. we typically chdir into 'root_dir' before creating the + archive. 'base_dir' is the directory where we start archiving from; + ie. 'base_dir' will be the common prefix of all files and + directories in the archive. 'root_dir' and 'base_dir' both default + to the current directory. Returns the name of the archive file. + + 'owner' and 'group' are used when creating a tar archive. By default, + uses the current owner and group. + """ + save_cwd = os.getcwd() + if root_dir is not None: + if logger is not None: + logger.debug("changing into '%s'", root_dir) + base_name = os.path.abspath(base_name) + if not dry_run: + os.chdir(root_dir) + + if base_dir is None: + base_dir = os.curdir + + kwargs = {'dry_run': dry_run, 'logger': logger} + + try: + format_info = _ARCHIVE_FORMATS[format] + except KeyError: + raise ValueError("unknown archive format '%s'" % format) + + func = format_info[0] + for arg, val in format_info[1]: + kwargs[arg] = val + + if format != 'zip': + kwargs['owner'] = owner + kwargs['group'] = group + + try: + filename = func(base_name, base_dir, **kwargs) + finally: + if root_dir is not None: + if logger is not None: + logger.debug("changing back to '%s'", save_cwd) + os.chdir(save_cwd) + + return filename + + +def get_unpack_formats(): + """Returns a list of supported formats for unpacking. + + Each element of the returned sequence is a tuple + (name, extensions, description) + """ + formats = [(name, info[0], info[3]) for name, info in + _UNPACK_FORMATS.items()] + formats.sort() + return formats + +def _check_unpack_options(extensions, function, extra_args): + """Checks what gets registered as an unpacker.""" + # first make sure no other unpacker is registered for this extension + existing_extensions = {} + for name, info in _UNPACK_FORMATS.items(): + for ext in info[0]: + existing_extensions[ext] = name + + for extension in extensions: + if extension in existing_extensions: + msg = '%s is already registered for "%s"' + raise RegistryError(msg % (extension, + existing_extensions[extension])) + + if not isinstance(function, collections.Callable): + raise TypeError('The registered function must be a callable') + + +def register_unpack_format(name, extensions, function, extra_args=None, + description=''): + """Registers an unpack format. + + `name` is the name of the format. `extensions` is a list of extensions + corresponding to the format. + + `function` is the callable that will be + used to unpack archives. The callable will receive archives to unpack. + If it's unable to handle an archive, it needs to raise a ReadError + exception. + + If provided, `extra_args` is a sequence of + (name, value) tuples that will be passed as arguments to the callable. + description can be provided to describe the format, and will be returned + by the get_unpack_formats() function. + """ + if extra_args is None: + extra_args = [] + _check_unpack_options(extensions, function, extra_args) + _UNPACK_FORMATS[name] = extensions, function, extra_args, description + +def unregister_unpack_format(name): + """Removes the pack format from the registry.""" + del _UNPACK_FORMATS[name] + +def _ensure_directory(path): + """Ensure that the parent directory of `path` exists""" + dirname = os.path.dirname(path) + if not os.path.isdir(dirname): + os.makedirs(dirname) + +def _unpack_zipfile(filename, extract_dir): + """Unpack zip `filename` to `extract_dir` + """ + try: + import zipfile + except ImportError: + raise ReadError('zlib not supported, cannot unpack this archive.') + + if not zipfile.is_zipfile(filename): + raise ReadError("%s is not a zip file" % filename) + + zip = zipfile.ZipFile(filename) + try: + for info in zip.infolist(): + name = info.filename + + # don't extract absolute paths or ones with .. in them + if name.startswith('/') or '..' in name: + continue + + target = os.path.join(extract_dir, *name.split('/')) + if not target: + continue + + _ensure_directory(target) + if not name.endswith('/'): + # file + data = zip.read(info.filename) + f = open(target, 'wb') + try: + f.write(data) + finally: + f.close() + del data + finally: + zip.close() + +def _unpack_tarfile(filename, extract_dir): + """Unpack tar/tar.gz/tar.bz2 `filename` to `extract_dir` + """ + try: + tarobj = tarfile.open(filename) + except tarfile.TarError: + raise ReadError( + "%s is not a compressed or uncompressed tar file" % filename) + try: + tarobj.extractall(extract_dir) + finally: + tarobj.close() + +_UNPACK_FORMATS = { + 'gztar': (['.tar.gz', '.tgz'], _unpack_tarfile, [], "gzip'ed tar-file"), + 'tar': (['.tar'], _unpack_tarfile, [], "uncompressed tar file"), + 'zip': (['.zip'], _unpack_zipfile, [], "ZIP file") + } + +if _BZ2_SUPPORTED: + _UNPACK_FORMATS['bztar'] = (['.bz2'], _unpack_tarfile, [], + "bzip2'ed tar-file") + +def _find_unpack_format(filename): + for name, info in _UNPACK_FORMATS.items(): + for extension in info[0]: + if filename.endswith(extension): + return name + return None + +def unpack_archive(filename, extract_dir=None, format=None): + """Unpack an archive. + + `filename` is the name of the archive. + + `extract_dir` is the name of the target directory, where the archive + is unpacked. If not provided, the current working directory is used. + + `format` is the archive format: one of "zip", "tar", or "gztar". Or any + other registered format. If not provided, unpack_archive will use the + filename extension and see if an unpacker was registered for that + extension. + + In case none is found, a ValueError is raised. + """ + if extract_dir is None: + extract_dir = os.getcwd() + + if format is not None: + try: + format_info = _UNPACK_FORMATS[format] + except KeyError: + raise ValueError("Unknown unpack format '{0}'".format(format)) + + func = format_info[1] + func(filename, extract_dir, **dict(format_info[2])) + else: + # we need to look at the registered unpackers supported extensions + format = _find_unpack_format(filename) + if format is None: + raise ReadError("Unknown archive format '{0}'".format(filename)) + + func = _UNPACK_FORMATS[format][1] + kwargs = dict(_UNPACK_FORMATS[format][2]) + func(filename, extract_dir, **kwargs) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/sysconfig.cfg b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/sysconfig.cfg new file mode 100644 index 0000000..1746bd0 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/sysconfig.cfg @@ -0,0 +1,84 @@ +[posix_prefix] +# Configuration directories. Some of these come straight out of the +# configure script. They are for implementing the other variables, not to +# be used directly in [resource_locations]. +confdir = /etc +datadir = /usr/share +libdir = /usr/lib +statedir = /var +# User resource directory +local = ~/.local/{distribution.name} + +stdlib = {base}/lib/python{py_version_short} +platstdlib = {platbase}/lib/python{py_version_short} +purelib = {base}/lib/python{py_version_short}/site-packages +platlib = {platbase}/lib/python{py_version_short}/site-packages +include = {base}/include/python{py_version_short}{abiflags} +platinclude = {platbase}/include/python{py_version_short}{abiflags} +data = {base} + +[posix_home] +stdlib = {base}/lib/python +platstdlib = {base}/lib/python +purelib = {base}/lib/python +platlib = {base}/lib/python +include = {base}/include/python +platinclude = {base}/include/python +scripts = {base}/bin +data = {base} + +[nt] +stdlib = {base}/Lib +platstdlib = {base}/Lib +purelib = {base}/Lib/site-packages +platlib = {base}/Lib/site-packages +include = {base}/Include +platinclude = {base}/Include +scripts = {base}/Scripts +data = {base} + +[os2] +stdlib = {base}/Lib +platstdlib = {base}/Lib +purelib = {base}/Lib/site-packages +platlib = {base}/Lib/site-packages +include = {base}/Include +platinclude = {base}/Include +scripts = {base}/Scripts +data = {base} + +[os2_home] +stdlib = {userbase}/lib/python{py_version_short} +platstdlib = {userbase}/lib/python{py_version_short} +purelib = {userbase}/lib/python{py_version_short}/site-packages +platlib = {userbase}/lib/python{py_version_short}/site-packages +include = {userbase}/include/python{py_version_short} +scripts = {userbase}/bin +data = {userbase} + +[nt_user] +stdlib = {userbase}/Python{py_version_nodot} +platstdlib = {userbase}/Python{py_version_nodot} +purelib = {userbase}/Python{py_version_nodot}/site-packages +platlib = {userbase}/Python{py_version_nodot}/site-packages +include = {userbase}/Python{py_version_nodot}/Include +scripts = {userbase}/Scripts +data = {userbase} + +[posix_user] +stdlib = {userbase}/lib/python{py_version_short} +platstdlib = {userbase}/lib/python{py_version_short} +purelib = {userbase}/lib/python{py_version_short}/site-packages +platlib = {userbase}/lib/python{py_version_short}/site-packages +include = {userbase}/include/python{py_version_short} +scripts = {userbase}/bin +data = {userbase} + +[osx_framework_user] +stdlib = {userbase}/lib/python +platstdlib = {userbase}/lib/python +purelib = {userbase}/lib/python/site-packages +platlib = {userbase}/lib/python/site-packages +include = {userbase}/include +scripts = {userbase}/bin +data = {userbase} diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/sysconfig.py b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/sysconfig.py new file mode 100644 index 0000000..1df3aba --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/sysconfig.py @@ -0,0 +1,788 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +"""Access to Python's configuration information.""" + +import codecs +import os +import re +import sys +from os.path import pardir, realpath +try: + import configparser +except ImportError: + import ConfigParser as configparser + + +__all__ = [ + 'get_config_h_filename', + 'get_config_var', + 'get_config_vars', + 'get_makefile_filename', + 'get_path', + 'get_path_names', + 'get_paths', + 'get_platform', + 'get_python_version', + 'get_scheme_names', + 'parse_config_h', +] + + +def _safe_realpath(path): + try: + return realpath(path) + except OSError: + return path + + +if sys.executable: + _PROJECT_BASE = os.path.dirname(_safe_realpath(sys.executable)) +else: + # sys.executable can be empty if argv[0] has been changed and Python is + # unable to retrieve the real program name + _PROJECT_BASE = _safe_realpath(os.getcwd()) + +if os.name == "nt" and "pcbuild" in _PROJECT_BASE[-8:].lower(): + _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir)) +# PC/VS7.1 +if os.name == "nt" and "\\pc\\v" in _PROJECT_BASE[-10:].lower(): + _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir)) +# PC/AMD64 +if os.name == "nt" and "\\pcbuild\\amd64" in _PROJECT_BASE[-14:].lower(): + _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir)) + + +def is_python_build(): + for fn in ("Setup.dist", "Setup.local"): + if os.path.isfile(os.path.join(_PROJECT_BASE, "Modules", fn)): + return True + return False + +_PYTHON_BUILD = is_python_build() + +_cfg_read = False + +def _ensure_cfg_read(): + global _cfg_read + if not _cfg_read: + from ..resources import finder + backport_package = __name__.rsplit('.', 1)[0] + _finder = finder(backport_package) + _cfgfile = _finder.find('sysconfig.cfg') + assert _cfgfile, 'sysconfig.cfg exists' + with _cfgfile.as_stream() as s: + _SCHEMES.readfp(s) + if _PYTHON_BUILD: + for scheme in ('posix_prefix', 'posix_home'): + _SCHEMES.set(scheme, 'include', '{srcdir}/Include') + _SCHEMES.set(scheme, 'platinclude', '{projectbase}/.') + + _cfg_read = True + + +_SCHEMES = configparser.RawConfigParser() +_VAR_REPL = re.compile(r'\{([^{]*?)\}') + +def _expand_globals(config): + _ensure_cfg_read() + if config.has_section('globals'): + globals = config.items('globals') + else: + globals = tuple() + + sections = config.sections() + for section in sections: + if section == 'globals': + continue + for option, value in globals: + if config.has_option(section, option): + continue + config.set(section, option, value) + config.remove_section('globals') + + # now expanding local variables defined in the cfg file + # + for section in config.sections(): + variables = dict(config.items(section)) + + def _replacer(matchobj): + name = matchobj.group(1) + if name in variables: + return variables[name] + return matchobj.group(0) + + for option, value in config.items(section): + config.set(section, option, _VAR_REPL.sub(_replacer, value)) + +#_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] +_PREFIX = os.path.normpath(sys.prefix) +_EXEC_PREFIX = os.path.normpath(sys.exec_prefix) +_CONFIG_VARS = None +_USER_BASE = None + + +def _subst_vars(path, local_vars): + """In the string `path`, replace tokens like {some.thing} with the + corresponding value from the map `local_vars`. + + If there is no corresponding value, leave the token unchanged. + """ + def _replacer(matchobj): + name = matchobj.group(1) + if name in local_vars: + return local_vars[name] + elif name in os.environ: + return os.environ[name] + return matchobj.group(0) + return _VAR_REPL.sub(_replacer, path) + + +def _extend_dict(target_dict, other_dict): + target_keys = target_dict.keys() + for key, value in other_dict.items(): + if key in target_keys: + continue + target_dict[key] = value + + +def _expand_vars(scheme, vars): + res = {} + if vars is None: + vars = {} + _extend_dict(vars, get_config_vars()) + + for key, value in _SCHEMES.items(scheme): + if os.name in ('posix', 'nt'): + value = os.path.expanduser(value) + res[key] = os.path.normpath(_subst_vars(value, vars)) + return res + + +def format_value(value, vars): + def _replacer(matchobj): + name = matchobj.group(1) + if name in vars: + return vars[name] + return matchobj.group(0) + return _VAR_REPL.sub(_replacer, value) + + +def _get_default_scheme(): + if os.name == 'posix': + # the default scheme for posix is posix_prefix + return 'posix_prefix' + return os.name + + +def _getuserbase(): + env_base = os.environ.get("PYTHONUSERBASE", None) + + def joinuser(*args): + return os.path.expanduser(os.path.join(*args)) + + # what about 'os2emx', 'riscos' ? + if os.name == "nt": + base = os.environ.get("APPDATA") or "~" + if env_base: + return env_base + else: + return joinuser(base, "Python") + + if sys.platform == "darwin": + framework = get_config_var("PYTHONFRAMEWORK") + if framework: + if env_base: + return env_base + else: + return joinuser("~", "Library", framework, "%d.%d" % + sys.version_info[:2]) + + if env_base: + return env_base + else: + return joinuser("~", ".local") + + +def _parse_makefile(filename, vars=None): + """Parse a Makefile-style file. + + A dictionary containing name/value pairs is returned. If an + optional dictionary is passed in as the second argument, it is + used instead of a new dictionary. + """ + # Regexes needed for parsing Makefile (and similar syntaxes, + # like old-style Setup files). + _variable_rx = re.compile(r"([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)") + _findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)") + _findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}") + + if vars is None: + vars = {} + done = {} + notdone = {} + + with codecs.open(filename, encoding='utf-8', errors="surrogateescape") as f: + lines = f.readlines() + + for line in lines: + if line.startswith('#') or line.strip() == '': + continue + m = _variable_rx.match(line) + if m: + n, v = m.group(1, 2) + v = v.strip() + # `$$' is a literal `$' in make + tmpv = v.replace('$$', '') + + if "$" in tmpv: + notdone[n] = v + else: + try: + v = int(v) + except ValueError: + # insert literal `$' + done[n] = v.replace('$$', '$') + else: + done[n] = v + + # do variable interpolation here + variables = list(notdone.keys()) + + # Variables with a 'PY_' prefix in the makefile. These need to + # be made available without that prefix through sysconfig. + # Special care is needed to ensure that variable expansion works, even + # if the expansion uses the name without a prefix. + renamed_variables = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS') + + while len(variables) > 0: + for name in tuple(variables): + value = notdone[name] + m = _findvar1_rx.search(value) or _findvar2_rx.search(value) + if m is not None: + n = m.group(1) + found = True + if n in done: + item = str(done[n]) + elif n in notdone: + # get it on a subsequent round + found = False + elif n in os.environ: + # do it like make: fall back to environment + item = os.environ[n] + + elif n in renamed_variables: + if (name.startswith('PY_') and + name[3:] in renamed_variables): + item = "" + + elif 'PY_' + n in notdone: + found = False + + else: + item = str(done['PY_' + n]) + + else: + done[n] = item = "" + + if found: + after = value[m.end():] + value = value[:m.start()] + item + after + if "$" in after: + notdone[name] = value + else: + try: + value = int(value) + except ValueError: + done[name] = value.strip() + else: + done[name] = value + variables.remove(name) + + if (name.startswith('PY_') and + name[3:] in renamed_variables): + + name = name[3:] + if name not in done: + done[name] = value + + else: + # bogus variable reference (e.g. "prefix=$/opt/python"); + # just drop it since we can't deal + done[name] = value + variables.remove(name) + + # strip spurious spaces + for k, v in done.items(): + if isinstance(v, str): + done[k] = v.strip() + + # save the results in the global dictionary + vars.update(done) + return vars + + +def get_makefile_filename(): + """Return the path of the Makefile.""" + if _PYTHON_BUILD: + return os.path.join(_PROJECT_BASE, "Makefile") + if hasattr(sys, 'abiflags'): + config_dir_name = 'config-%s%s' % (_PY_VERSION_SHORT, sys.abiflags) + else: + config_dir_name = 'config' + return os.path.join(get_path('stdlib'), config_dir_name, 'Makefile') + + +def _init_posix(vars): + """Initialize the module as appropriate for POSIX systems.""" + # load the installed Makefile: + makefile = get_makefile_filename() + try: + _parse_makefile(makefile, vars) + except IOError as e: + msg = "invalid Python installation: unable to open %s" % makefile + if hasattr(e, "strerror"): + msg = msg + " (%s)" % e.strerror + raise IOError(msg) + # load the installed pyconfig.h: + config_h = get_config_h_filename() + try: + with open(config_h) as f: + parse_config_h(f, vars) + except IOError as e: + msg = "invalid Python installation: unable to open %s" % config_h + if hasattr(e, "strerror"): + msg = msg + " (%s)" % e.strerror + raise IOError(msg) + # On AIX, there are wrong paths to the linker scripts in the Makefile + # -- these paths are relative to the Python source, but when installed + # the scripts are in another directory. + if _PYTHON_BUILD: + vars['LDSHARED'] = vars['BLDSHARED'] + + +def _init_non_posix(vars): + """Initialize the module as appropriate for NT""" + # set basic install directories + vars['LIBDEST'] = get_path('stdlib') + vars['BINLIBDEST'] = get_path('platstdlib') + vars['INCLUDEPY'] = get_path('include') + vars['SO'] = '.pyd' + vars['EXE'] = '.exe' + vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT + vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable)) + +# +# public APIs +# + + +def parse_config_h(fp, vars=None): + """Parse a config.h-style file. + + A dictionary containing name/value pairs is returned. If an + optional dictionary is passed in as the second argument, it is + used instead of a new dictionary. + """ + if vars is None: + vars = {} + define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n") + undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n") + + while True: + line = fp.readline() + if not line: + break + m = define_rx.match(line) + if m: + n, v = m.group(1, 2) + try: + v = int(v) + except ValueError: + pass + vars[n] = v + else: + m = undef_rx.match(line) + if m: + vars[m.group(1)] = 0 + return vars + + +def get_config_h_filename(): + """Return the path of pyconfig.h.""" + if _PYTHON_BUILD: + if os.name == "nt": + inc_dir = os.path.join(_PROJECT_BASE, "PC") + else: + inc_dir = _PROJECT_BASE + else: + inc_dir = get_path('platinclude') + return os.path.join(inc_dir, 'pyconfig.h') + + +def get_scheme_names(): + """Return a tuple containing the schemes names.""" + return tuple(sorted(_SCHEMES.sections())) + + +def get_path_names(): + """Return a tuple containing the paths names.""" + # xxx see if we want a static list + return _SCHEMES.options('posix_prefix') + + +def get_paths(scheme=_get_default_scheme(), vars=None, expand=True): + """Return a mapping containing an install scheme. + + ``scheme`` is the install scheme name. If not provided, it will + return the default scheme for the current platform. + """ + _ensure_cfg_read() + if expand: + return _expand_vars(scheme, vars) + else: + return dict(_SCHEMES.items(scheme)) + + +def get_path(name, scheme=_get_default_scheme(), vars=None, expand=True): + """Return a path corresponding to the scheme. + + ``scheme`` is the install scheme name. + """ + return get_paths(scheme, vars, expand)[name] + + +def get_config_vars(*args): + """With no arguments, return a dictionary of all configuration + variables relevant for the current platform. + + On Unix, this means every variable defined in Python's installed Makefile; + On Windows and Mac OS it's a much smaller set. + + With arguments, return a list of values that result from looking up + each argument in the configuration variable dictionary. + """ + global _CONFIG_VARS + if _CONFIG_VARS is None: + _CONFIG_VARS = {} + # Normalized versions of prefix and exec_prefix are handy to have; + # in fact, these are the standard versions used most places in the + # distutils2 module. + _CONFIG_VARS['prefix'] = _PREFIX + _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX + _CONFIG_VARS['py_version'] = _PY_VERSION + _CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT + _CONFIG_VARS['py_version_nodot'] = _PY_VERSION[0] + _PY_VERSION[2] + _CONFIG_VARS['base'] = _PREFIX + _CONFIG_VARS['platbase'] = _EXEC_PREFIX + _CONFIG_VARS['projectbase'] = _PROJECT_BASE + try: + _CONFIG_VARS['abiflags'] = sys.abiflags + except AttributeError: + # sys.abiflags may not be defined on all platforms. + _CONFIG_VARS['abiflags'] = '' + + if os.name in ('nt', 'os2'): + _init_non_posix(_CONFIG_VARS) + if os.name == 'posix': + _init_posix(_CONFIG_VARS) + # Setting 'userbase' is done below the call to the + # init function to enable using 'get_config_var' in + # the init-function. + if sys.version >= '2.6': + _CONFIG_VARS['userbase'] = _getuserbase() + + if 'srcdir' not in _CONFIG_VARS: + _CONFIG_VARS['srcdir'] = _PROJECT_BASE + else: + _CONFIG_VARS['srcdir'] = _safe_realpath(_CONFIG_VARS['srcdir']) + + # Convert srcdir into an absolute path if it appears necessary. + # Normally it is relative to the build directory. However, during + # testing, for example, we might be running a non-installed python + # from a different directory. + if _PYTHON_BUILD and os.name == "posix": + base = _PROJECT_BASE + try: + cwd = os.getcwd() + except OSError: + cwd = None + if (not os.path.isabs(_CONFIG_VARS['srcdir']) and + base != cwd): + # srcdir is relative and we are not in the same directory + # as the executable. Assume executable is in the build + # directory and make srcdir absolute. + srcdir = os.path.join(base, _CONFIG_VARS['srcdir']) + _CONFIG_VARS['srcdir'] = os.path.normpath(srcdir) + + if sys.platform == 'darwin': + kernel_version = os.uname()[2] # Kernel version (8.4.3) + major_version = int(kernel_version.split('.')[0]) + + if major_version < 8: + # On Mac OS X before 10.4, check if -arch and -isysroot + # are in CFLAGS or LDFLAGS and remove them if they are. + # This is needed when building extensions on a 10.3 system + # using a universal build of python. + for key in ('LDFLAGS', 'BASECFLAGS', + # a number of derived variables. These need to be + # patched up as well. + 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): + flags = _CONFIG_VARS[key] + flags = re.sub(r'-arch\s+\w+\s', ' ', flags) + flags = re.sub('-isysroot [^ \t]*', ' ', flags) + _CONFIG_VARS[key] = flags + else: + # Allow the user to override the architecture flags using + # an environment variable. + # NOTE: This name was introduced by Apple in OSX 10.5 and + # is used by several scripting languages distributed with + # that OS release. + if 'ARCHFLAGS' in os.environ: + arch = os.environ['ARCHFLAGS'] + for key in ('LDFLAGS', 'BASECFLAGS', + # a number of derived variables. These need to be + # patched up as well. + 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): + + flags = _CONFIG_VARS[key] + flags = re.sub(r'-arch\s+\w+\s', ' ', flags) + flags = flags + ' ' + arch + _CONFIG_VARS[key] = flags + + # If we're on OSX 10.5 or later and the user tries to + # compiles an extension using an SDK that is not present + # on the current machine it is better to not use an SDK + # than to fail. + # + # The major usecase for this is users using a Python.org + # binary installer on OSX 10.6: that installer uses + # the 10.4u SDK, but that SDK is not installed by default + # when you install Xcode. + # + CFLAGS = _CONFIG_VARS.get('CFLAGS', '') + m = re.search(r'-isysroot\s+(\S+)', CFLAGS) + if m is not None: + sdk = m.group(1) + if not os.path.exists(sdk): + for key in ('LDFLAGS', 'BASECFLAGS', + # a number of derived variables. These need to be + # patched up as well. + 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): + + flags = _CONFIG_VARS[key] + flags = re.sub(r'-isysroot\s+\S+(\s|$)', ' ', flags) + _CONFIG_VARS[key] = flags + + if args: + vals = [] + for name in args: + vals.append(_CONFIG_VARS.get(name)) + return vals + else: + return _CONFIG_VARS + + +def get_config_var(name): + """Return the value of a single variable using the dictionary returned by + 'get_config_vars()'. + + Equivalent to get_config_vars().get(name) + """ + return get_config_vars().get(name) + + +def get_platform(): + """Return a string that identifies the current platform. + + This is used mainly to distinguish platform-specific build directories and + platform-specific built distributions. Typically includes the OS name + and version and the architecture (as supplied by 'os.uname()'), + although the exact information included depends on the OS; eg. for IRIX + the architecture isn't particularly important (IRIX only runs on SGI + hardware), but for Linux the kernel version isn't particularly + important. + + Examples of returned values: + linux-i586 + linux-alpha (?) + solaris-2.6-sun4u + irix-5.3 + irix64-6.2 + + Windows will return one of: + win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc) + win-ia64 (64bit Windows on Itanium) + win32 (all others - specifically, sys.platform is returned) + + For other non-POSIX platforms, currently just returns 'sys.platform'. + """ + if os.name == 'nt': + # sniff sys.version for architecture. + prefix = " bit (" + i = sys.version.find(prefix) + if i == -1: + return sys.platform + j = sys.version.find(")", i) + look = sys.version[i+len(prefix):j].lower() + if look == 'amd64': + return 'win-amd64' + if look == 'itanium': + return 'win-ia64' + return sys.platform + + if os.name != "posix" or not hasattr(os, 'uname'): + # XXX what about the architecture? NT is Intel or Alpha, + # Mac OS is M68k or PPC, etc. + return sys.platform + + # Try to distinguish various flavours of Unix + osname, host, release, version, machine = os.uname() + + # Convert the OS name to lowercase, remove '/' characters + # (to accommodate BSD/OS), and translate spaces (for "Power Macintosh") + osname = osname.lower().replace('/', '') + machine = machine.replace(' ', '_') + machine = machine.replace('/', '-') + + if osname[:5] == "linux": + # At least on Linux/Intel, 'machine' is the processor -- + # i386, etc. + # XXX what about Alpha, SPARC, etc? + return "%s-%s" % (osname, machine) + elif osname[:5] == "sunos": + if release[0] >= "5": # SunOS 5 == Solaris 2 + osname = "solaris" + release = "%d.%s" % (int(release[0]) - 3, release[2:]) + # fall through to standard osname-release-machine representation + elif osname[:4] == "irix": # could be "irix64"! + return "%s-%s" % (osname, release) + elif osname[:3] == "aix": + return "%s-%s.%s" % (osname, version, release) + elif osname[:6] == "cygwin": + osname = "cygwin" + rel_re = re.compile(r'[\d.]+') + m = rel_re.match(release) + if m: + release = m.group() + elif osname[:6] == "darwin": + # + # For our purposes, we'll assume that the system version from + # distutils' perspective is what MACOSX_DEPLOYMENT_TARGET is set + # to. This makes the compatibility story a bit more sane because the + # machine is going to compile and link as if it were + # MACOSX_DEPLOYMENT_TARGET. + cfgvars = get_config_vars() + macver = cfgvars.get('MACOSX_DEPLOYMENT_TARGET') + + if True: + # Always calculate the release of the running machine, + # needed to determine if we can build fat binaries or not. + + macrelease = macver + # Get the system version. Reading this plist is a documented + # way to get the system version (see the documentation for + # the Gestalt Manager) + try: + f = open('/System/Library/CoreServices/SystemVersion.plist') + except IOError: + # We're on a plain darwin box, fall back to the default + # behaviour. + pass + else: + try: + m = re.search(r'<key>ProductUserVisibleVersion</key>\s*' + r'<string>(.*?)</string>', f.read()) + finally: + f.close() + if m is not None: + macrelease = '.'.join(m.group(1).split('.')[:2]) + # else: fall back to the default behaviour + + if not macver: + macver = macrelease + + if macver: + release = macver + osname = "macosx" + + if ((macrelease + '.') >= '10.4.' and + '-arch' in get_config_vars().get('CFLAGS', '').strip()): + # The universal build will build fat binaries, but not on + # systems before 10.4 + # + # Try to detect 4-way universal builds, those have machine-type + # 'universal' instead of 'fat'. + + machine = 'fat' + cflags = get_config_vars().get('CFLAGS') + + archs = re.findall(r'-arch\s+(\S+)', cflags) + archs = tuple(sorted(set(archs))) + + if len(archs) == 1: + machine = archs[0] + elif archs == ('i386', 'ppc'): + machine = 'fat' + elif archs == ('i386', 'x86_64'): + machine = 'intel' + elif archs == ('i386', 'ppc', 'x86_64'): + machine = 'fat3' + elif archs == ('ppc64', 'x86_64'): + machine = 'fat64' + elif archs == ('i386', 'ppc', 'ppc64', 'x86_64'): + machine = 'universal' + else: + raise ValueError( + "Don't know machine value for archs=%r" % (archs,)) + + elif machine == 'i386': + # On OSX the machine type returned by uname is always the + # 32-bit variant, even if the executable architecture is + # the 64-bit variant + if sys.maxsize >= 2**32: + machine = 'x86_64' + + elif machine in ('PowerPC', 'Power_Macintosh'): + # Pick a sane name for the PPC architecture. + # See 'i386' case + if sys.maxsize >= 2**32: + machine = 'ppc64' + else: + machine = 'ppc' + + return "%s-%s-%s" % (osname, release, machine) + + +def get_python_version(): + return _PY_VERSION_SHORT + + +def _print_dict(title, data): + for index, (key, value) in enumerate(sorted(data.items())): + if index == 0: + print('%s: ' % (title)) + print('\t%s = "%s"' % (key, value)) + + +def _main(): + """Display all information sysconfig detains.""" + print('Platform: "%s"' % get_platform()) + print('Python version: "%s"' % get_python_version()) + print('Current installation scheme: "%s"' % _get_default_scheme()) + print() + _print_dict('Paths', get_paths()) + print() + _print_dict('Variables', get_config_vars()) + + +if __name__ == '__main__': + _main() diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/tarfile.py b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/tarfile.py new file mode 100644 index 0000000..d66d856 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/tarfile.py @@ -0,0 +1,2607 @@ +#------------------------------------------------------------------- +# tarfile.py +#------------------------------------------------------------------- +# Copyright (C) 2002 Lars Gustaebel <lars@gustaebel.de> +# All rights reserved. +# +# 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. +# +from __future__ import print_function + +"""Read from and write to tar format archives. +""" + +__version__ = "$Revision$" + +version = "0.9.0" +__author__ = "Lars Gust\u00e4bel (lars@gustaebel.de)" +__date__ = "$Date: 2011-02-25 17:42:01 +0200 (Fri, 25 Feb 2011) $" +__cvsid__ = "$Id: tarfile.py 88586 2011-02-25 15:42:01Z marc-andre.lemburg $" +__credits__ = "Gustavo Niemeyer, Niels Gust\u00e4bel, Richard Townsend." + +#--------- +# Imports +#--------- +import sys +import os +import stat +import errno +import time +import struct +import copy +import re + +try: + import grp, pwd +except ImportError: + grp = pwd = None + +# os.symlink on Windows prior to 6.0 raises NotImplementedError +symlink_exception = (AttributeError, NotImplementedError) +try: + # WindowsError (1314) will be raised if the caller does not hold the + # SeCreateSymbolicLinkPrivilege privilege + symlink_exception += (WindowsError,) +except NameError: + pass + +# from tarfile import * +__all__ = ["TarFile", "TarInfo", "is_tarfile", "TarError"] + +if sys.version_info[0] < 3: + import __builtin__ as builtins +else: + import builtins + +_open = builtins.open # Since 'open' is TarFile.open + +#--------------------------------------------------------- +# tar constants +#--------------------------------------------------------- +NUL = b"\0" # the null character +BLOCKSIZE = 512 # length of processing blocks +RECORDSIZE = BLOCKSIZE * 20 # length of records +GNU_MAGIC = b"ustar \0" # magic gnu tar string +POSIX_MAGIC = b"ustar\x0000" # magic posix tar string + +LENGTH_NAME = 100 # maximum length of a filename +LENGTH_LINK = 100 # maximum length of a linkname +LENGTH_PREFIX = 155 # maximum length of the prefix field + +REGTYPE = b"0" # regular file +AREGTYPE = b"\0" # regular file +LNKTYPE = b"1" # link (inside tarfile) +SYMTYPE = b"2" # symbolic link +CHRTYPE = b"3" # character special device +BLKTYPE = b"4" # block special device +DIRTYPE = b"5" # directory +FIFOTYPE = b"6" # fifo special device +CONTTYPE = b"7" # contiguous file + +GNUTYPE_LONGNAME = b"L" # GNU tar longname +GNUTYPE_LONGLINK = b"K" # GNU tar longlink +GNUTYPE_SPARSE = b"S" # GNU tar sparse file + +XHDTYPE = b"x" # POSIX.1-2001 extended header +XGLTYPE = b"g" # POSIX.1-2001 global header +SOLARIS_XHDTYPE = b"X" # Solaris extended header + +USTAR_FORMAT = 0 # POSIX.1-1988 (ustar) format +GNU_FORMAT = 1 # GNU tar format +PAX_FORMAT = 2 # POSIX.1-2001 (pax) format +DEFAULT_FORMAT = GNU_FORMAT + +#--------------------------------------------------------- +# tarfile constants +#--------------------------------------------------------- +# File types that tarfile supports: +SUPPORTED_TYPES = (REGTYPE, AREGTYPE, LNKTYPE, + SYMTYPE, DIRTYPE, FIFOTYPE, + CONTTYPE, CHRTYPE, BLKTYPE, + GNUTYPE_LONGNAME, GNUTYPE_LONGLINK, + GNUTYPE_SPARSE) + +# File types that will be treated as a regular file. +REGULAR_TYPES = (REGTYPE, AREGTYPE, + CONTTYPE, GNUTYPE_SPARSE) + +# File types that are part of the GNU tar format. +GNU_TYPES = (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK, + GNUTYPE_SPARSE) + +# Fields from a pax header that override a TarInfo attribute. +PAX_FIELDS = ("path", "linkpath", "size", "mtime", + "uid", "gid", "uname", "gname") + +# Fields from a pax header that are affected by hdrcharset. +PAX_NAME_FIELDS = set(("path", "linkpath", "uname", "gname")) + +# Fields in a pax header that are numbers, all other fields +# are treated as strings. +PAX_NUMBER_FIELDS = { + "atime": float, + "ctime": float, + "mtime": float, + "uid": int, + "gid": int, + "size": int +} + +#--------------------------------------------------------- +# Bits used in the mode field, values in octal. +#--------------------------------------------------------- +S_IFLNK = 0o120000 # symbolic link +S_IFREG = 0o100000 # regular file +S_IFBLK = 0o060000 # block device +S_IFDIR = 0o040000 # directory +S_IFCHR = 0o020000 # character device +S_IFIFO = 0o010000 # fifo + +TSUID = 0o4000 # set UID on execution +TSGID = 0o2000 # set GID on execution +TSVTX = 0o1000 # reserved + +TUREAD = 0o400 # read by owner +TUWRITE = 0o200 # write by owner +TUEXEC = 0o100 # execute/search by owner +TGREAD = 0o040 # read by group +TGWRITE = 0o020 # write by group +TGEXEC = 0o010 # execute/search by group +TOREAD = 0o004 # read by other +TOWRITE = 0o002 # write by other +TOEXEC = 0o001 # execute/search by other + +#--------------------------------------------------------- +# initialization +#--------------------------------------------------------- +if os.name in ("nt", "ce"): + ENCODING = "utf-8" +else: + ENCODING = sys.getfilesystemencoding() + +#--------------------------------------------------------- +# Some useful functions +#--------------------------------------------------------- + +def stn(s, length, encoding, errors): + """Convert a string to a null-terminated bytes object. + """ + s = s.encode(encoding, errors) + return s[:length] + (length - len(s)) * NUL + +def nts(s, encoding, errors): + """Convert a null-terminated bytes object to a string. + """ + p = s.find(b"\0") + if p != -1: + s = s[:p] + return s.decode(encoding, errors) + +def nti(s): + """Convert a number field to a python number. + """ + # There are two possible encodings for a number field, see + # itn() below. + if s[0] != chr(0o200): + try: + n = int(nts(s, "ascii", "strict") or "0", 8) + except ValueError: + raise InvalidHeaderError("invalid header") + else: + n = 0 + for i in range(len(s) - 1): + n <<= 8 + n += ord(s[i + 1]) + return n + +def itn(n, digits=8, format=DEFAULT_FORMAT): + """Convert a python number to a number field. + """ + # POSIX 1003.1-1988 requires numbers to be encoded as a string of + # octal digits followed by a null-byte, this allows values up to + # (8**(digits-1))-1. GNU tar allows storing numbers greater than + # that if necessary. A leading 0o200 byte indicates this particular + # encoding, the following digits-1 bytes are a big-endian + # representation. This allows values up to (256**(digits-1))-1. + if 0 <= n < 8 ** (digits - 1): + s = ("%0*o" % (digits - 1, n)).encode("ascii") + NUL + else: + if format != GNU_FORMAT or n >= 256 ** (digits - 1): + raise ValueError("overflow in number field") + + if n < 0: + # XXX We mimic GNU tar's behaviour with negative numbers, + # this could raise OverflowError. + n = struct.unpack("L", struct.pack("l", n))[0] + + s = bytearray() + for i in range(digits - 1): + s.insert(0, n & 0o377) + n >>= 8 + s.insert(0, 0o200) + return s + +def calc_chksums(buf): + """Calculate the checksum for a member's header by summing up all + characters except for the chksum field which is treated as if + it was filled with spaces. According to the GNU tar sources, + some tars (Sun and NeXT) calculate chksum with signed char, + which will be different if there are chars in the buffer with + the high bit set. So we calculate two checksums, unsigned and + signed. + """ + unsigned_chksum = 256 + sum(struct.unpack("148B", buf[:148]) + struct.unpack("356B", buf[156:512])) + signed_chksum = 256 + sum(struct.unpack("148b", buf[:148]) + struct.unpack("356b", buf[156:512])) + return unsigned_chksum, signed_chksum + +def copyfileobj(src, dst, length=None): + """Copy length bytes from fileobj src to fileobj dst. + If length is None, copy the entire content. + """ + if length == 0: + return + if length is None: + while True: + buf = src.read(16*1024) + if not buf: + break + dst.write(buf) + return + + BUFSIZE = 16 * 1024 + blocks, remainder = divmod(length, BUFSIZE) + for b in range(blocks): + buf = src.read(BUFSIZE) + if len(buf) < BUFSIZE: + raise IOError("end of file reached") + dst.write(buf) + + if remainder != 0: + buf = src.read(remainder) + if len(buf) < remainder: + raise IOError("end of file reached") + dst.write(buf) + return + +filemode_table = ( + ((S_IFLNK, "l"), + (S_IFREG, "-"), + (S_IFBLK, "b"), + (S_IFDIR, "d"), + (S_IFCHR, "c"), + (S_IFIFO, "p")), + + ((TUREAD, "r"),), + ((TUWRITE, "w"),), + ((TUEXEC|TSUID, "s"), + (TSUID, "S"), + (TUEXEC, "x")), + + ((TGREAD, "r"),), + ((TGWRITE, "w"),), + ((TGEXEC|TSGID, "s"), + (TSGID, "S"), + (TGEXEC, "x")), + + ((TOREAD, "r"),), + ((TOWRITE, "w"),), + ((TOEXEC|TSVTX, "t"), + (TSVTX, "T"), + (TOEXEC, "x")) +) + +def filemode(mode): + """Convert a file's mode to a string of the form + -rwxrwxrwx. + Used by TarFile.list() + """ + perm = [] + for table in filemode_table: + for bit, char in table: + if mode & bit == bit: + perm.append(char) + break + else: + perm.append("-") + return "".join(perm) + +class TarError(Exception): + """Base exception.""" + pass +class ExtractError(TarError): + """General exception for extract errors.""" + pass +class ReadError(TarError): + """Exception for unreadable tar archives.""" + pass +class CompressionError(TarError): + """Exception for unavailable compression methods.""" + pass +class StreamError(TarError): + """Exception for unsupported operations on stream-like TarFiles.""" + pass +class HeaderError(TarError): + """Base exception for header errors.""" + pass +class EmptyHeaderError(HeaderError): + """Exception for empty headers.""" + pass +class TruncatedHeaderError(HeaderError): + """Exception for truncated headers.""" + pass +class EOFHeaderError(HeaderError): + """Exception for end of file headers.""" + pass +class InvalidHeaderError(HeaderError): + """Exception for invalid headers.""" + pass +class SubsequentHeaderError(HeaderError): + """Exception for missing and invalid extended headers.""" + pass + +#--------------------------- +# internal stream interface +#--------------------------- +class _LowLevelFile(object): + """Low-level file object. Supports reading and writing. + It is used instead of a regular file object for streaming + access. + """ + + def __init__(self, name, mode): + mode = { + "r": os.O_RDONLY, + "w": os.O_WRONLY | os.O_CREAT | os.O_TRUNC, + }[mode] + if hasattr(os, "O_BINARY"): + mode |= os.O_BINARY + self.fd = os.open(name, mode, 0o666) + + def close(self): + os.close(self.fd) + + def read(self, size): + return os.read(self.fd, size) + + def write(self, s): + os.write(self.fd, s) + +class _Stream(object): + """Class that serves as an adapter between TarFile and + a stream-like object. The stream-like object only + needs to have a read() or write() method and is accessed + blockwise. Use of gzip or bzip2 compression is possible. + A stream-like object could be for example: sys.stdin, + sys.stdout, a socket, a tape device etc. + + _Stream is intended to be used only internally. + """ + + def __init__(self, name, mode, comptype, fileobj, bufsize): + """Construct a _Stream object. + """ + self._extfileobj = True + if fileobj is None: + fileobj = _LowLevelFile(name, mode) + self._extfileobj = False + + if comptype == '*': + # Enable transparent compression detection for the + # stream interface + fileobj = _StreamProxy(fileobj) + comptype = fileobj.getcomptype() + + self.name = name or "" + self.mode = mode + self.comptype = comptype + self.fileobj = fileobj + self.bufsize = bufsize + self.buf = b"" + self.pos = 0 + self.closed = False + + try: + if comptype == "gz": + try: + import zlib + except ImportError: + raise CompressionError("zlib module is not available") + self.zlib = zlib + self.crc = zlib.crc32(b"") + if mode == "r": + self._init_read_gz() + else: + self._init_write_gz() + + if comptype == "bz2": + try: + import bz2 + except ImportError: + raise CompressionError("bz2 module is not available") + if mode == "r": + self.dbuf = b"" + self.cmp = bz2.BZ2Decompressor() + else: + self.cmp = bz2.BZ2Compressor() + except: + if not self._extfileobj: + self.fileobj.close() + self.closed = True + raise + + def __del__(self): + if hasattr(self, "closed") and not self.closed: + self.close() + + def _init_write_gz(self): + """Initialize for writing with gzip compression. + """ + self.cmp = self.zlib.compressobj(9, self.zlib.DEFLATED, + -self.zlib.MAX_WBITS, + self.zlib.DEF_MEM_LEVEL, + 0) + timestamp = struct.pack("<L", int(time.time())) + self.__write(b"\037\213\010\010" + timestamp + b"\002\377") + if self.name.endswith(".gz"): + self.name = self.name[:-3] + # RFC1952 says we must use ISO-8859-1 for the FNAME field. + self.__write(self.name.encode("iso-8859-1", "replace") + NUL) + + def write(self, s): + """Write string s to the stream. + """ + if self.comptype == "gz": + self.crc = self.zlib.crc32(s, self.crc) + self.pos += len(s) + if self.comptype != "tar": + s = self.cmp.compress(s) + self.__write(s) + + def __write(self, s): + """Write string s to the stream if a whole new block + is ready to be written. + """ + self.buf += s + while len(self.buf) > self.bufsize: + self.fileobj.write(self.buf[:self.bufsize]) + self.buf = self.buf[self.bufsize:] + + def close(self): + """Close the _Stream object. No operation should be + done on it afterwards. + """ + if self.closed: + return + + if self.mode == "w" and self.comptype != "tar": + self.buf += self.cmp.flush() + + if self.mode == "w" and self.buf: + self.fileobj.write(self.buf) + self.buf = b"" + if self.comptype == "gz": + # The native zlib crc is an unsigned 32-bit integer, but + # the Python wrapper implicitly casts that to a signed C + # long. So, on a 32-bit box self.crc may "look negative", + # while the same crc on a 64-bit box may "look positive". + # To avoid irksome warnings from the `struct` module, force + # it to look positive on all boxes. + self.fileobj.write(struct.pack("<L", self.crc & 0xffffffff)) + self.fileobj.write(struct.pack("<L", self.pos & 0xffffFFFF)) + + if not self._extfileobj: + self.fileobj.close() + + self.closed = True + + def _init_read_gz(self): + """Initialize for reading a gzip compressed fileobj. + """ + self.cmp = self.zlib.decompressobj(-self.zlib.MAX_WBITS) + self.dbuf = b"" + + # taken from gzip.GzipFile with some alterations + if self.__read(2) != b"\037\213": + raise ReadError("not a gzip file") + if self.__read(1) != b"\010": + raise CompressionError("unsupported compression method") + + flag = ord(self.__read(1)) + self.__read(6) + + if flag & 4: + xlen = ord(self.__read(1)) + 256 * ord(self.__read(1)) + self.read(xlen) + if flag & 8: + while True: + s = self.__read(1) + if not s or s == NUL: + break + if flag & 16: + while True: + s = self.__read(1) + if not s or s == NUL: + break + if flag & 2: + self.__read(2) + + def tell(self): + """Return the stream's file pointer position. + """ + return self.pos + + def seek(self, pos=0): + """Set the stream's file pointer to pos. Negative seeking + is forbidden. + """ + if pos - self.pos >= 0: + blocks, remainder = divmod(pos - self.pos, self.bufsize) + for i in range(blocks): + self.read(self.bufsize) + self.read(remainder) + else: + raise StreamError("seeking backwards is not allowed") + return self.pos + + def read(self, size=None): + """Return the next size number of bytes from the stream. + If size is not defined, return all bytes of the stream + up to EOF. + """ + if size is None: + t = [] + while True: + buf = self._read(self.bufsize) + if not buf: + break + t.append(buf) + buf = "".join(t) + else: + buf = self._read(size) + self.pos += len(buf) + return buf + + def _read(self, size): + """Return size bytes from the stream. + """ + if self.comptype == "tar": + return self.__read(size) + + c = len(self.dbuf) + while c < size: + buf = self.__read(self.bufsize) + if not buf: + break + try: + buf = self.cmp.decompress(buf) + except IOError: + raise ReadError("invalid compressed data") + self.dbuf += buf + c += len(buf) + buf = self.dbuf[:size] + self.dbuf = self.dbuf[size:] + return buf + + def __read(self, size): + """Return size bytes from stream. If internal buffer is empty, + read another block from the stream. + """ + c = len(self.buf) + while c < size: + buf = self.fileobj.read(self.bufsize) + if not buf: + break + self.buf += buf + c += len(buf) + buf = self.buf[:size] + self.buf = self.buf[size:] + return buf +# class _Stream + +class _StreamProxy(object): + """Small proxy class that enables transparent compression + detection for the Stream interface (mode 'r|*'). + """ + + def __init__(self, fileobj): + self.fileobj = fileobj + self.buf = self.fileobj.read(BLOCKSIZE) + + def read(self, size): + self.read = self.fileobj.read + return self.buf + + def getcomptype(self): + if self.buf.startswith(b"\037\213\010"): + return "gz" + if self.buf.startswith(b"BZh91"): + return "bz2" + return "tar" + + def close(self): + self.fileobj.close() +# class StreamProxy + +class _BZ2Proxy(object): + """Small proxy class that enables external file object + support for "r:bz2" and "w:bz2" modes. This is actually + a workaround for a limitation in bz2 module's BZ2File + class which (unlike gzip.GzipFile) has no support for + a file object argument. + """ + + blocksize = 16 * 1024 + + def __init__(self, fileobj, mode): + self.fileobj = fileobj + self.mode = mode + self.name = getattr(self.fileobj, "name", None) + self.init() + + def init(self): + import bz2 + self.pos = 0 + if self.mode == "r": + self.bz2obj = bz2.BZ2Decompressor() + self.fileobj.seek(0) + self.buf = b"" + else: + self.bz2obj = bz2.BZ2Compressor() + + def read(self, size): + x = len(self.buf) + while x < size: + raw = self.fileobj.read(self.blocksize) + if not raw: + break + data = self.bz2obj.decompress(raw) + self.buf += data + x += len(data) + + buf = self.buf[:size] + self.buf = self.buf[size:] + self.pos += len(buf) + return buf + + def seek(self, pos): + if pos < self.pos: + self.init() + self.read(pos - self.pos) + + def tell(self): + return self.pos + + def write(self, data): + self.pos += len(data) + raw = self.bz2obj.compress(data) + self.fileobj.write(raw) + + def close(self): + if self.mode == "w": + raw = self.bz2obj.flush() + self.fileobj.write(raw) +# class _BZ2Proxy + +#------------------------ +# Extraction file object +#------------------------ +class _FileInFile(object): + """A thin wrapper around an existing file object that + provides a part of its data as an individual file + object. + """ + + def __init__(self, fileobj, offset, size, blockinfo=None): + self.fileobj = fileobj + self.offset = offset + self.size = size + self.position = 0 + + if blockinfo is None: + blockinfo = [(0, size)] + + # Construct a map with data and zero blocks. + self.map_index = 0 + self.map = [] + lastpos = 0 + realpos = self.offset + for offset, size in blockinfo: + if offset > lastpos: + self.map.append((False, lastpos, offset, None)) + self.map.append((True, offset, offset + size, realpos)) + realpos += size + lastpos = offset + size + if lastpos < self.size: + self.map.append((False, lastpos, self.size, None)) + + def seekable(self): + if not hasattr(self.fileobj, "seekable"): + # XXX gzip.GzipFile and bz2.BZ2File + return True + return self.fileobj.seekable() + + def tell(self): + """Return the current file position. + """ + return self.position + + def seek(self, position): + """Seek to a position in the file. + """ + self.position = position + + def read(self, size=None): + """Read data from the file. + """ + if size is None: + size = self.size - self.position + else: + size = min(size, self.size - self.position) + + buf = b"" + while size > 0: + while True: + data, start, stop, offset = self.map[self.map_index] + if start <= self.position < stop: + break + else: + self.map_index += 1 + if self.map_index == len(self.map): + self.map_index = 0 + length = min(size, stop - self.position) + if data: + self.fileobj.seek(offset + (self.position - start)) + buf += self.fileobj.read(length) + else: + buf += NUL * length + size -= length + self.position += length + return buf +#class _FileInFile + + +class ExFileObject(object): + """File-like object for reading an archive member. + Is returned by TarFile.extractfile(). + """ + blocksize = 1024 + + def __init__(self, tarfile, tarinfo): + self.fileobj = _FileInFile(tarfile.fileobj, + tarinfo.offset_data, + tarinfo.size, + tarinfo.sparse) + self.name = tarinfo.name + self.mode = "r" + self.closed = False + self.size = tarinfo.size + + self.position = 0 + self.buffer = b"" + + def readable(self): + return True + + def writable(self): + return False + + def seekable(self): + return self.fileobj.seekable() + + def read(self, size=None): + """Read at most size bytes from the file. If size is not + present or None, read all data until EOF is reached. + """ + if self.closed: + raise ValueError("I/O operation on closed file") + + buf = b"" + if self.buffer: + if size is None: + buf = self.buffer + self.buffer = b"" + else: + buf = self.buffer[:size] + self.buffer = self.buffer[size:] + + if size is None: + buf += self.fileobj.read() + else: + buf += self.fileobj.read(size - len(buf)) + + self.position += len(buf) + return buf + + # XXX TextIOWrapper uses the read1() method. + read1 = read + + def readline(self, size=-1): + """Read one entire line from the file. If size is present + and non-negative, return a string with at most that + size, which may be an incomplete line. + """ + if self.closed: + raise ValueError("I/O operation on closed file") + + pos = self.buffer.find(b"\n") + 1 + if pos == 0: + # no newline found. + while True: + buf = self.fileobj.read(self.blocksize) + self.buffer += buf + if not buf or b"\n" in buf: + pos = self.buffer.find(b"\n") + 1 + if pos == 0: + # no newline found. + pos = len(self.buffer) + break + + if size != -1: + pos = min(size, pos) + + buf = self.buffer[:pos] + self.buffer = self.buffer[pos:] + self.position += len(buf) + return buf + + def readlines(self): + """Return a list with all remaining lines. + """ + result = [] + while True: + line = self.readline() + if not line: break + result.append(line) + return result + + def tell(self): + """Return the current file position. + """ + if self.closed: + raise ValueError("I/O operation on closed file") + + return self.position + + def seek(self, pos, whence=os.SEEK_SET): + """Seek to a position in the file. + """ + if self.closed: + raise ValueError("I/O operation on closed file") + + if whence == os.SEEK_SET: + self.position = min(max(pos, 0), self.size) + elif whence == os.SEEK_CUR: + if pos < 0: + self.position = max(self.position + pos, 0) + else: + self.position = min(self.position + pos, self.size) + elif whence == os.SEEK_END: + self.position = max(min(self.size + pos, self.size), 0) + else: + raise ValueError("Invalid argument") + + self.buffer = b"" + self.fileobj.seek(self.position) + + def close(self): + """Close the file object. + """ + self.closed = True + + def __iter__(self): + """Get an iterator over the file's lines. + """ + while True: + line = self.readline() + if not line: + break + yield line +#class ExFileObject + +#------------------ +# Exported Classes +#------------------ +class TarInfo(object): + """Informational class which holds the details about an + archive member given by a tar header block. + TarInfo objects are returned by TarFile.getmember(), + TarFile.getmembers() and TarFile.gettarinfo() and are + usually created internally. + """ + + __slots__ = ("name", "mode", "uid", "gid", "size", "mtime", + "chksum", "type", "linkname", "uname", "gname", + "devmajor", "devminor", + "offset", "offset_data", "pax_headers", "sparse", + "tarfile", "_sparse_structs", "_link_target") + + def __init__(self, name=""): + """Construct a TarInfo object. name is the optional name + of the member. + """ + self.name = name # member name + self.mode = 0o644 # file permissions + self.uid = 0 # user id + self.gid = 0 # group id + self.size = 0 # file size + self.mtime = 0 # modification time + self.chksum = 0 # header checksum + self.type = REGTYPE # member type + self.linkname = "" # link name + self.uname = "" # user name + self.gname = "" # group name + self.devmajor = 0 # device major number + self.devminor = 0 # device minor number + + self.offset = 0 # the tar header starts here + self.offset_data = 0 # the file's data starts here + + self.sparse = None # sparse member information + self.pax_headers = {} # pax header information + + # In pax headers the "name" and "linkname" field are called + # "path" and "linkpath". + def _getpath(self): + return self.name + def _setpath(self, name): + self.name = name + path = property(_getpath, _setpath) + + def _getlinkpath(self): + return self.linkname + def _setlinkpath(self, linkname): + self.linkname = linkname + linkpath = property(_getlinkpath, _setlinkpath) + + def __repr__(self): + return "<%s %r at %#x>" % (self.__class__.__name__,self.name,id(self)) + + def get_info(self): + """Return the TarInfo's attributes as a dictionary. + """ + info = { + "name": self.name, + "mode": self.mode & 0o7777, + "uid": self.uid, + "gid": self.gid, + "size": self.size, + "mtime": self.mtime, + "chksum": self.chksum, + "type": self.type, + "linkname": self.linkname, + "uname": self.uname, + "gname": self.gname, + "devmajor": self.devmajor, + "devminor": self.devminor + } + + if info["type"] == DIRTYPE and not info["name"].endswith("/"): + info["name"] += "/" + + return info + + def tobuf(self, format=DEFAULT_FORMAT, encoding=ENCODING, errors="surrogateescape"): + """Return a tar header as a string of 512 byte blocks. + """ + info = self.get_info() + + if format == USTAR_FORMAT: + return self.create_ustar_header(info, encoding, errors) + elif format == GNU_FORMAT: + return self.create_gnu_header(info, encoding, errors) + elif format == PAX_FORMAT: + return self.create_pax_header(info, encoding) + else: + raise ValueError("invalid format") + + def create_ustar_header(self, info, encoding, errors): + """Return the object as a ustar header block. + """ + info["magic"] = POSIX_MAGIC + + if len(info["linkname"]) > LENGTH_LINK: + raise ValueError("linkname is too long") + + if len(info["name"]) > LENGTH_NAME: + info["prefix"], info["name"] = self._posix_split_name(info["name"]) + + return self._create_header(info, USTAR_FORMAT, encoding, errors) + + def create_gnu_header(self, info, encoding, errors): + """Return the object as a GNU header block sequence. + """ + info["magic"] = GNU_MAGIC + + buf = b"" + if len(info["linkname"]) > LENGTH_LINK: + buf += self._create_gnu_long_header(info["linkname"], GNUTYPE_LONGLINK, encoding, errors) + + if len(info["name"]) > LENGTH_NAME: + buf += self._create_gnu_long_header(info["name"], GNUTYPE_LONGNAME, encoding, errors) + + return buf + self._create_header(info, GNU_FORMAT, encoding, errors) + + def create_pax_header(self, info, encoding): + """Return the object as a ustar header block. If it cannot be + represented this way, prepend a pax extended header sequence + with supplement information. + """ + info["magic"] = POSIX_MAGIC + pax_headers = self.pax_headers.copy() + + # Test string fields for values that exceed the field length or cannot + # be represented in ASCII encoding. + for name, hname, length in ( + ("name", "path", LENGTH_NAME), ("linkname", "linkpath", LENGTH_LINK), + ("uname", "uname", 32), ("gname", "gname", 32)): + + if hname in pax_headers: + # The pax header has priority. + continue + + # Try to encode the string as ASCII. + try: + info[name].encode("ascii", "strict") + except UnicodeEncodeError: + pax_headers[hname] = info[name] + continue + + if len(info[name]) > length: + pax_headers[hname] = info[name] + + # Test number fields for values that exceed the field limit or values + # that like to be stored as float. + for name, digits in (("uid", 8), ("gid", 8), ("size", 12), ("mtime", 12)): + if name in pax_headers: + # The pax header has priority. Avoid overflow. + info[name] = 0 + continue + + val = info[name] + if not 0 <= val < 8 ** (digits - 1) or isinstance(val, float): + pax_headers[name] = str(val) + info[name] = 0 + + # Create a pax extended header if necessary. + if pax_headers: + buf = self._create_pax_generic_header(pax_headers, XHDTYPE, encoding) + else: + buf = b"" + + return buf + self._create_header(info, USTAR_FORMAT, "ascii", "replace") + + @classmethod + def create_pax_global_header(cls, pax_headers): + """Return the object as a pax global header block sequence. + """ + return cls._create_pax_generic_header(pax_headers, XGLTYPE, "utf8") + + def _posix_split_name(self, name): + """Split a name longer than 100 chars into a prefix + and a name part. + """ + prefix = name[:LENGTH_PREFIX + 1] + while prefix and prefix[-1] != "/": + prefix = prefix[:-1] + + name = name[len(prefix):] + prefix = prefix[:-1] + + if not prefix or len(name) > LENGTH_NAME: + raise ValueError("name is too long") + return prefix, name + + @staticmethod + def _create_header(info, format, encoding, errors): + """Return a header block. info is a dictionary with file + information, format must be one of the *_FORMAT constants. + """ + parts = [ + stn(info.get("name", ""), 100, encoding, errors), + itn(info.get("mode", 0) & 0o7777, 8, format), + itn(info.get("uid", 0), 8, format), + itn(info.get("gid", 0), 8, format), + itn(info.get("size", 0), 12, format), + itn(info.get("mtime", 0), 12, format), + b" ", # checksum field + info.get("type", REGTYPE), + stn(info.get("linkname", ""), 100, encoding, errors), + info.get("magic", POSIX_MAGIC), + stn(info.get("uname", ""), 32, encoding, errors), + stn(info.get("gname", ""), 32, encoding, errors), + itn(info.get("devmajor", 0), 8, format), + itn(info.get("devminor", 0), 8, format), + stn(info.get("prefix", ""), 155, encoding, errors) + ] + + buf = struct.pack("%ds" % BLOCKSIZE, b"".join(parts)) + chksum = calc_chksums(buf[-BLOCKSIZE:])[0] + buf = buf[:-364] + ("%06o\0" % chksum).encode("ascii") + buf[-357:] + return buf + + @staticmethod + def _create_payload(payload): + """Return the string payload filled with zero bytes + up to the next 512 byte border. + """ + blocks, remainder = divmod(len(payload), BLOCKSIZE) + if remainder > 0: + payload += (BLOCKSIZE - remainder) * NUL + return payload + + @classmethod + def _create_gnu_long_header(cls, name, type, encoding, errors): + """Return a GNUTYPE_LONGNAME or GNUTYPE_LONGLINK sequence + for name. + """ + name = name.encode(encoding, errors) + NUL + + info = {} + info["name"] = "././@LongLink" + info["type"] = type + info["size"] = len(name) + info["magic"] = GNU_MAGIC + + # create extended header + name blocks. + return cls._create_header(info, USTAR_FORMAT, encoding, errors) + \ + cls._create_payload(name) + + @classmethod + def _create_pax_generic_header(cls, pax_headers, type, encoding): + """Return a POSIX.1-2008 extended or global header sequence + that contains a list of keyword, value pairs. The values + must be strings. + """ + # Check if one of the fields contains surrogate characters and thereby + # forces hdrcharset=BINARY, see _proc_pax() for more information. + binary = False + for keyword, value in pax_headers.items(): + try: + value.encode("utf8", "strict") + except UnicodeEncodeError: + binary = True + break + + records = b"" + if binary: + # Put the hdrcharset field at the beginning of the header. + records += b"21 hdrcharset=BINARY\n" + + for keyword, value in pax_headers.items(): + keyword = keyword.encode("utf8") + if binary: + # Try to restore the original byte representation of `value'. + # Needless to say, that the encoding must match the string. + value = value.encode(encoding, "surrogateescape") + else: + value = value.encode("utf8") + + l = len(keyword) + len(value) + 3 # ' ' + '=' + '\n' + n = p = 0 + while True: + n = l + len(str(p)) + if n == p: + break + p = n + records += bytes(str(p), "ascii") + b" " + keyword + b"=" + value + b"\n" + + # We use a hardcoded "././@PaxHeader" name like star does + # instead of the one that POSIX recommends. + info = {} + info["name"] = "././@PaxHeader" + info["type"] = type + info["size"] = len(records) + info["magic"] = POSIX_MAGIC + + # Create pax header + record blocks. + return cls._create_header(info, USTAR_FORMAT, "ascii", "replace") + \ + cls._create_payload(records) + + @classmethod + def frombuf(cls, buf, encoding, errors): + """Construct a TarInfo object from a 512 byte bytes object. + """ + if len(buf) == 0: + raise EmptyHeaderError("empty header") + if len(buf) != BLOCKSIZE: + raise TruncatedHeaderError("truncated header") + if buf.count(NUL) == BLOCKSIZE: + raise EOFHeaderError("end of file header") + + chksum = nti(buf[148:156]) + if chksum not in calc_chksums(buf): + raise InvalidHeaderError("bad checksum") + + obj = cls() + obj.name = nts(buf[0:100], encoding, errors) + obj.mode = nti(buf[100:108]) + obj.uid = nti(buf[108:116]) + obj.gid = nti(buf[116:124]) + obj.size = nti(buf[124:136]) + obj.mtime = nti(buf[136:148]) + obj.chksum = chksum + obj.type = buf[156:157] + obj.linkname = nts(buf[157:257], encoding, errors) + obj.uname = nts(buf[265:297], encoding, errors) + obj.gname = nts(buf[297:329], encoding, errors) + obj.devmajor = nti(buf[329:337]) + obj.devminor = nti(buf[337:345]) + prefix = nts(buf[345:500], encoding, errors) + + # Old V7 tar format represents a directory as a regular + # file with a trailing slash. + if obj.type == AREGTYPE and obj.name.endswith("/"): + obj.type = DIRTYPE + + # The old GNU sparse format occupies some of the unused + # space in the buffer for up to 4 sparse structures. + # Save the them for later processing in _proc_sparse(). + if obj.type == GNUTYPE_SPARSE: + pos = 386 + structs = [] + for i in range(4): + try: + offset = nti(buf[pos:pos + 12]) + numbytes = nti(buf[pos + 12:pos + 24]) + except ValueError: + break + structs.append((offset, numbytes)) + pos += 24 + isextended = bool(buf[482]) + origsize = nti(buf[483:495]) + obj._sparse_structs = (structs, isextended, origsize) + + # Remove redundant slashes from directories. + if obj.isdir(): + obj.name = obj.name.rstrip("/") + + # Reconstruct a ustar longname. + if prefix and obj.type not in GNU_TYPES: + obj.name = prefix + "/" + obj.name + return obj + + @classmethod + def fromtarfile(cls, tarfile): + """Return the next TarInfo object from TarFile object + tarfile. + """ + buf = tarfile.fileobj.read(BLOCKSIZE) + obj = cls.frombuf(buf, tarfile.encoding, tarfile.errors) + obj.offset = tarfile.fileobj.tell() - BLOCKSIZE + return obj._proc_member(tarfile) + + #-------------------------------------------------------------------------- + # The following are methods that are called depending on the type of a + # member. The entry point is _proc_member() which can be overridden in a + # subclass to add custom _proc_*() methods. A _proc_*() method MUST + # implement the following + # operations: + # 1. Set self.offset_data to the position where the data blocks begin, + # if there is data that follows. + # 2. Set tarfile.offset to the position where the next member's header will + # begin. + # 3. Return self or another valid TarInfo object. + def _proc_member(self, tarfile): + """Choose the right processing method depending on + the type and call it. + """ + if self.type in (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK): + return self._proc_gnulong(tarfile) + elif self.type == GNUTYPE_SPARSE: + return self._proc_sparse(tarfile) + elif self.type in (XHDTYPE, XGLTYPE, SOLARIS_XHDTYPE): + return self._proc_pax(tarfile) + else: + return self._proc_builtin(tarfile) + + def _proc_builtin(self, tarfile): + """Process a builtin type or an unknown type which + will be treated as a regular file. + """ + self.offset_data = tarfile.fileobj.tell() + offset = self.offset_data + if self.isreg() or self.type not in SUPPORTED_TYPES: + # Skip the following data blocks. + offset += self._block(self.size) + tarfile.offset = offset + + # Patch the TarInfo object with saved global + # header information. + self._apply_pax_info(tarfile.pax_headers, tarfile.encoding, tarfile.errors) + + return self + + def _proc_gnulong(self, tarfile): + """Process the blocks that hold a GNU longname + or longlink member. + """ + buf = tarfile.fileobj.read(self._block(self.size)) + + # Fetch the next header and process it. + try: + next = self.fromtarfile(tarfile) + except HeaderError: + raise SubsequentHeaderError("missing or bad subsequent header") + + # Patch the TarInfo object from the next header with + # the longname information. + next.offset = self.offset + if self.type == GNUTYPE_LONGNAME: + next.name = nts(buf, tarfile.encoding, tarfile.errors) + elif self.type == GNUTYPE_LONGLINK: + next.linkname = nts(buf, tarfile.encoding, tarfile.errors) + + return next + + def _proc_sparse(self, tarfile): + """Process a GNU sparse header plus extra headers. + """ + # We already collected some sparse structures in frombuf(). + structs, isextended, origsize = self._sparse_structs + del self._sparse_structs + + # Collect sparse structures from extended header blocks. + while isextended: + buf = tarfile.fileobj.read(BLOCKSIZE) + pos = 0 + for i in range(21): + try: + offset = nti(buf[pos:pos + 12]) + numbytes = nti(buf[pos + 12:pos + 24]) + except ValueError: + break + if offset and numbytes: + structs.append((offset, numbytes)) + pos += 24 + isextended = bool(buf[504]) + self.sparse = structs + + self.offset_data = tarfile.fileobj.tell() + tarfile.offset = self.offset_data + self._block(self.size) + self.size = origsize + return self + + def _proc_pax(self, tarfile): + """Process an extended or global header as described in + POSIX.1-2008. + """ + # Read the header information. + buf = tarfile.fileobj.read(self._block(self.size)) + + # A pax header stores supplemental information for either + # the following file (extended) or all following files + # (global). + if self.type == XGLTYPE: + pax_headers = tarfile.pax_headers + else: + pax_headers = tarfile.pax_headers.copy() + + # Check if the pax header contains a hdrcharset field. This tells us + # the encoding of the path, linkpath, uname and gname fields. Normally, + # these fields are UTF-8 encoded but since POSIX.1-2008 tar + # implementations are allowed to store them as raw binary strings if + # the translation to UTF-8 fails. + match = re.search(br"\d+ hdrcharset=([^\n]+)\n", buf) + if match is not None: + pax_headers["hdrcharset"] = match.group(1).decode("utf8") + + # For the time being, we don't care about anything other than "BINARY". + # The only other value that is currently allowed by the standard is + # "ISO-IR 10646 2000 UTF-8" in other words UTF-8. + hdrcharset = pax_headers.get("hdrcharset") + if hdrcharset == "BINARY": + encoding = tarfile.encoding + else: + encoding = "utf8" + + # Parse pax header information. A record looks like that: + # "%d %s=%s\n" % (length, keyword, value). length is the size + # of the complete record including the length field itself and + # the newline. keyword and value are both UTF-8 encoded strings. + regex = re.compile(br"(\d+) ([^=]+)=") + pos = 0 + while True: + match = regex.match(buf, pos) + if not match: + break + + length, keyword = match.groups() + length = int(length) + value = buf[match.end(2) + 1:match.start(1) + length - 1] + + # Normally, we could just use "utf8" as the encoding and "strict" + # as the error handler, but we better not take the risk. For + # example, GNU tar <= 1.23 is known to store filenames it cannot + # translate to UTF-8 as raw strings (unfortunately without a + # hdrcharset=BINARY header). + # We first try the strict standard encoding, and if that fails we + # fall back on the user's encoding and error handler. + keyword = self._decode_pax_field(keyword, "utf8", "utf8", + tarfile.errors) + if keyword in PAX_NAME_FIELDS: + value = self._decode_pax_field(value, encoding, tarfile.encoding, + tarfile.errors) + else: + value = self._decode_pax_field(value, "utf8", "utf8", + tarfile.errors) + + pax_headers[keyword] = value + pos += length + + # Fetch the next header. + try: + next = self.fromtarfile(tarfile) + except HeaderError: + raise SubsequentHeaderError("missing or bad subsequent header") + + # Process GNU sparse information. + if "GNU.sparse.map" in pax_headers: + # GNU extended sparse format version 0.1. + self._proc_gnusparse_01(next, pax_headers) + + elif "GNU.sparse.size" in pax_headers: + # GNU extended sparse format version 0.0. + self._proc_gnusparse_00(next, pax_headers, buf) + + elif pax_headers.get("GNU.sparse.major") == "1" and pax_headers.get("GNU.sparse.minor") == "0": + # GNU extended sparse format version 1.0. + self._proc_gnusparse_10(next, pax_headers, tarfile) + + if self.type in (XHDTYPE, SOLARIS_XHDTYPE): + # Patch the TarInfo object with the extended header info. + next._apply_pax_info(pax_headers, tarfile.encoding, tarfile.errors) + next.offset = self.offset + + if "size" in pax_headers: + # If the extended header replaces the size field, + # we need to recalculate the offset where the next + # header starts. + offset = next.offset_data + if next.isreg() or next.type not in SUPPORTED_TYPES: + offset += next._block(next.size) + tarfile.offset = offset + + return next + + def _proc_gnusparse_00(self, next, pax_headers, buf): + """Process a GNU tar extended sparse header, version 0.0. + """ + offsets = [] + for match in re.finditer(br"\d+ GNU.sparse.offset=(\d+)\n", buf): + offsets.append(int(match.group(1))) + numbytes = [] + for match in re.finditer(br"\d+ GNU.sparse.numbytes=(\d+)\n", buf): + numbytes.append(int(match.group(1))) + next.sparse = list(zip(offsets, numbytes)) + + def _proc_gnusparse_01(self, next, pax_headers): + """Process a GNU tar extended sparse header, version 0.1. + """ + sparse = [int(x) for x in pax_headers["GNU.sparse.map"].split(",")] + next.sparse = list(zip(sparse[::2], sparse[1::2])) + + def _proc_gnusparse_10(self, next, pax_headers, tarfile): + """Process a GNU tar extended sparse header, version 1.0. + """ + fields = None + sparse = [] + buf = tarfile.fileobj.read(BLOCKSIZE) + fields, buf = buf.split(b"\n", 1) + fields = int(fields) + while len(sparse) < fields * 2: + if b"\n" not in buf: + buf += tarfile.fileobj.read(BLOCKSIZE) + number, buf = buf.split(b"\n", 1) + sparse.append(int(number)) + next.offset_data = tarfile.fileobj.tell() + next.sparse = list(zip(sparse[::2], sparse[1::2])) + + def _apply_pax_info(self, pax_headers, encoding, errors): + """Replace fields with supplemental information from a previous + pax extended or global header. + """ + for keyword, value in pax_headers.items(): + if keyword == "GNU.sparse.name": + setattr(self, "path", value) + elif keyword == "GNU.sparse.size": + setattr(self, "size", int(value)) + elif keyword == "GNU.sparse.realsize": + setattr(self, "size", int(value)) + elif keyword in PAX_FIELDS: + if keyword in PAX_NUMBER_FIELDS: + try: + value = PAX_NUMBER_FIELDS[keyword](value) + except ValueError: + value = 0 + if keyword == "path": + value = value.rstrip("/") + setattr(self, keyword, value) + + self.pax_headers = pax_headers.copy() + + def _decode_pax_field(self, value, encoding, fallback_encoding, fallback_errors): + """Decode a single field from a pax record. + """ + try: + return value.decode(encoding, "strict") + except UnicodeDecodeError: + return value.decode(fallback_encoding, fallback_errors) + + def _block(self, count): + """Round up a byte count by BLOCKSIZE and return it, + e.g. _block(834) => 1024. + """ + blocks, remainder = divmod(count, BLOCKSIZE) + if remainder: + blocks += 1 + return blocks * BLOCKSIZE + + def isreg(self): + return self.type in REGULAR_TYPES + def isfile(self): + return self.isreg() + def isdir(self): + return self.type == DIRTYPE + def issym(self): + return self.type == SYMTYPE + def islnk(self): + return self.type == LNKTYPE + def ischr(self): + return self.type == CHRTYPE + def isblk(self): + return self.type == BLKTYPE + def isfifo(self): + return self.type == FIFOTYPE + def issparse(self): + return self.sparse is not None + def isdev(self): + return self.type in (CHRTYPE, BLKTYPE, FIFOTYPE) +# class TarInfo + +class TarFile(object): + """The TarFile Class provides an interface to tar archives. + """ + + debug = 0 # May be set from 0 (no msgs) to 3 (all msgs) + + dereference = False # If true, add content of linked file to the + # tar file, else the link. + + ignore_zeros = False # If true, skips empty or invalid blocks and + # continues processing. + + errorlevel = 1 # If 0, fatal errors only appear in debug + # messages (if debug >= 0). If > 0, errors + # are passed to the caller as exceptions. + + format = DEFAULT_FORMAT # The format to use when creating an archive. + + encoding = ENCODING # Encoding for 8-bit character strings. + + errors = None # Error handler for unicode conversion. + + tarinfo = TarInfo # The default TarInfo class to use. + + fileobject = ExFileObject # The default ExFileObject class to use. + + def __init__(self, name=None, mode="r", fileobj=None, format=None, + tarinfo=None, dereference=None, ignore_zeros=None, encoding=None, + errors="surrogateescape", pax_headers=None, debug=None, errorlevel=None): + """Open an (uncompressed) tar archive `name'. `mode' is either 'r' to + read from an existing archive, 'a' to append data to an existing + file or 'w' to create a new file overwriting an existing one. `mode' + defaults to 'r'. + If `fileobj' is given, it is used for reading or writing data. If it + can be determined, `mode' is overridden by `fileobj's mode. + `fileobj' is not closed, when TarFile is closed. + """ + if len(mode) > 1 or mode not in "raw": + raise ValueError("mode must be 'r', 'a' or 'w'") + self.mode = mode + self._mode = {"r": "rb", "a": "r+b", "w": "wb"}[mode] + + if not fileobj: + if self.mode == "a" and not os.path.exists(name): + # Create nonexistent files in append mode. + self.mode = "w" + self._mode = "wb" + fileobj = bltn_open(name, self._mode) + self._extfileobj = False + else: + if name is None and hasattr(fileobj, "name"): + name = fileobj.name + if hasattr(fileobj, "mode"): + self._mode = fileobj.mode + self._extfileobj = True + self.name = os.path.abspath(name) if name else None + self.fileobj = fileobj + + # Init attributes. + if format is not None: + self.format = format + if tarinfo is not None: + self.tarinfo = tarinfo + if dereference is not None: + self.dereference = dereference + if ignore_zeros is not None: + self.ignore_zeros = ignore_zeros + if encoding is not None: + self.encoding = encoding + self.errors = errors + + if pax_headers is not None and self.format == PAX_FORMAT: + self.pax_headers = pax_headers + else: + self.pax_headers = {} + + if debug is not None: + self.debug = debug + if errorlevel is not None: + self.errorlevel = errorlevel + + # Init datastructures. + self.closed = False + self.members = [] # list of members as TarInfo objects + self._loaded = False # flag if all members have been read + self.offset = self.fileobj.tell() + # current position in the archive file + self.inodes = {} # dictionary caching the inodes of + # archive members already added + + try: + if self.mode == "r": + self.firstmember = None + self.firstmember = self.next() + + if self.mode == "a": + # Move to the end of the archive, + # before the first empty block. + while True: + self.fileobj.seek(self.offset) + try: + tarinfo = self.tarinfo.fromtarfile(self) + self.members.append(tarinfo) + except EOFHeaderError: + self.fileobj.seek(self.offset) + break + except HeaderError as e: + raise ReadError(str(e)) + + if self.mode in "aw": + self._loaded = True + + if self.pax_headers: + buf = self.tarinfo.create_pax_global_header(self.pax_headers.copy()) + self.fileobj.write(buf) + self.offset += len(buf) + except: + if not self._extfileobj: + self.fileobj.close() + self.closed = True + raise + + #-------------------------------------------------------------------------- + # Below are the classmethods which act as alternate constructors to the + # TarFile class. The open() method is the only one that is needed for + # public use; it is the "super"-constructor and is able to select an + # adequate "sub"-constructor for a particular compression using the mapping + # from OPEN_METH. + # + # This concept allows one to subclass TarFile without losing the comfort of + # the super-constructor. A sub-constructor is registered and made available + # by adding it to the mapping in OPEN_METH. + + @classmethod + def open(cls, name=None, mode="r", fileobj=None, bufsize=RECORDSIZE, **kwargs): + """Open a tar archive for reading, writing or appending. Return + an appropriate TarFile class. + + mode: + 'r' or 'r:*' open for reading with transparent compression + 'r:' open for reading exclusively uncompressed + 'r:gz' open for reading with gzip compression + 'r:bz2' open for reading with bzip2 compression + 'a' or 'a:' open for appending, creating the file if necessary + 'w' or 'w:' open for writing without compression + 'w:gz' open for writing with gzip compression + 'w:bz2' open for writing with bzip2 compression + + 'r|*' open a stream of tar blocks with transparent compression + 'r|' open an uncompressed stream of tar blocks for reading + 'r|gz' open a gzip compressed stream of tar blocks + 'r|bz2' open a bzip2 compressed stream of tar blocks + 'w|' open an uncompressed stream for writing + 'w|gz' open a gzip compressed stream for writing + 'w|bz2' open a bzip2 compressed stream for writing + """ + + if not name and not fileobj: + raise ValueError("nothing to open") + + if mode in ("r", "r:*"): + # Find out which *open() is appropriate for opening the file. + for comptype in cls.OPEN_METH: + func = getattr(cls, cls.OPEN_METH[comptype]) + if fileobj is not None: + saved_pos = fileobj.tell() + try: + return func(name, "r", fileobj, **kwargs) + except (ReadError, CompressionError) as e: + if fileobj is not None: + fileobj.seek(saved_pos) + continue + raise ReadError("file could not be opened successfully") + + elif ":" in mode: + filemode, comptype = mode.split(":", 1) + filemode = filemode or "r" + comptype = comptype or "tar" + + # Select the *open() function according to + # given compression. + if comptype in cls.OPEN_METH: + func = getattr(cls, cls.OPEN_METH[comptype]) + else: + raise CompressionError("unknown compression type %r" % comptype) + return func(name, filemode, fileobj, **kwargs) + + elif "|" in mode: + filemode, comptype = mode.split("|", 1) + filemode = filemode or "r" + comptype = comptype or "tar" + + if filemode not in "rw": + raise ValueError("mode must be 'r' or 'w'") + + stream = _Stream(name, filemode, comptype, fileobj, bufsize) + try: + t = cls(name, filemode, stream, **kwargs) + except: + stream.close() + raise + t._extfileobj = False + return t + + elif mode in "aw": + return cls.taropen(name, mode, fileobj, **kwargs) + + raise ValueError("undiscernible mode") + + @classmethod + def taropen(cls, name, mode="r", fileobj=None, **kwargs): + """Open uncompressed tar archive name for reading or writing. + """ + if len(mode) > 1 or mode not in "raw": + raise ValueError("mode must be 'r', 'a' or 'w'") + return cls(name, mode, fileobj, **kwargs) + + @classmethod + def gzopen(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs): + """Open gzip compressed tar archive name for reading or writing. + Appending is not allowed. + """ + if len(mode) > 1 or mode not in "rw": + raise ValueError("mode must be 'r' or 'w'") + + try: + import gzip + gzip.GzipFile + except (ImportError, AttributeError): + raise CompressionError("gzip module is not available") + + extfileobj = fileobj is not None + try: + fileobj = gzip.GzipFile(name, mode + "b", compresslevel, fileobj) + t = cls.taropen(name, mode, fileobj, **kwargs) + except IOError: + if not extfileobj and fileobj is not None: + fileobj.close() + if fileobj is None: + raise + raise ReadError("not a gzip file") + except: + if not extfileobj and fileobj is not None: + fileobj.close() + raise + t._extfileobj = extfileobj + return t + + @classmethod + def bz2open(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs): + """Open bzip2 compressed tar archive name for reading or writing. + Appending is not allowed. + """ + if len(mode) > 1 or mode not in "rw": + raise ValueError("mode must be 'r' or 'w'.") + + try: + import bz2 + except ImportError: + raise CompressionError("bz2 module is not available") + + if fileobj is not None: + fileobj = _BZ2Proxy(fileobj, mode) + else: + fileobj = bz2.BZ2File(name, mode, compresslevel=compresslevel) + + try: + t = cls.taropen(name, mode, fileobj, **kwargs) + except (IOError, EOFError): + fileobj.close() + raise ReadError("not a bzip2 file") + t._extfileobj = False + return t + + # All *open() methods are registered here. + OPEN_METH = { + "tar": "taropen", # uncompressed tar + "gz": "gzopen", # gzip compressed tar + "bz2": "bz2open" # bzip2 compressed tar + } + + #-------------------------------------------------------------------------- + # The public methods which TarFile provides: + + def close(self): + """Close the TarFile. In write-mode, two finishing zero blocks are + appended to the archive. + """ + if self.closed: + return + + if self.mode in "aw": + self.fileobj.write(NUL * (BLOCKSIZE * 2)) + self.offset += (BLOCKSIZE * 2) + # fill up the end with zero-blocks + # (like option -b20 for tar does) + blocks, remainder = divmod(self.offset, RECORDSIZE) + if remainder > 0: + self.fileobj.write(NUL * (RECORDSIZE - remainder)) + + if not self._extfileobj: + self.fileobj.close() + self.closed = True + + def getmember(self, name): + """Return a TarInfo object for member `name'. If `name' can not be + found in the archive, KeyError is raised. If a member occurs more + than once in the archive, its last occurrence is assumed to be the + most up-to-date version. + """ + tarinfo = self._getmember(name) + if tarinfo is None: + raise KeyError("filename %r not found" % name) + return tarinfo + + def getmembers(self): + """Return the members of the archive as a list of TarInfo objects. The + list has the same order as the members in the archive. + """ + self._check() + if not self._loaded: # if we want to obtain a list of + self._load() # all members, we first have to + # scan the whole archive. + return self.members + + def getnames(self): + """Return the members of the archive as a list of their names. It has + the same order as the list returned by getmembers(). + """ + return [tarinfo.name for tarinfo in self.getmembers()] + + def gettarinfo(self, name=None, arcname=None, fileobj=None): + """Create a TarInfo object for either the file `name' or the file + object `fileobj' (using os.fstat on its file descriptor). You can + modify some of the TarInfo's attributes before you add it using + addfile(). If given, `arcname' specifies an alternative name for the + file in the archive. + """ + self._check("aw") + + # When fileobj is given, replace name by + # fileobj's real name. + if fileobj is not None: + name = fileobj.name + + # Building the name of the member in the archive. + # Backward slashes are converted to forward slashes, + # Absolute paths are turned to relative paths. + if arcname is None: + arcname = name + drv, arcname = os.path.splitdrive(arcname) + arcname = arcname.replace(os.sep, "/") + arcname = arcname.lstrip("/") + + # Now, fill the TarInfo object with + # information specific for the file. + tarinfo = self.tarinfo() + tarinfo.tarfile = self + + # Use os.stat or os.lstat, depending on platform + # and if symlinks shall be resolved. + if fileobj is None: + if hasattr(os, "lstat") and not self.dereference: + statres = os.lstat(name) + else: + statres = os.stat(name) + else: + statres = os.fstat(fileobj.fileno()) + linkname = "" + + stmd = statres.st_mode + if stat.S_ISREG(stmd): + inode = (statres.st_ino, statres.st_dev) + if not self.dereference and statres.st_nlink > 1 and \ + inode in self.inodes and arcname != self.inodes[inode]: + # Is it a hardlink to an already + # archived file? + type = LNKTYPE + linkname = self.inodes[inode] + else: + # The inode is added only if its valid. + # For win32 it is always 0. + type = REGTYPE + if inode[0]: + self.inodes[inode] = arcname + elif stat.S_ISDIR(stmd): + type = DIRTYPE + elif stat.S_ISFIFO(stmd): + type = FIFOTYPE + elif stat.S_ISLNK(stmd): + type = SYMTYPE + linkname = os.readlink(name) + elif stat.S_ISCHR(stmd): + type = CHRTYPE + elif stat.S_ISBLK(stmd): + type = BLKTYPE + else: + return None + + # Fill the TarInfo object with all + # information we can get. + tarinfo.name = arcname + tarinfo.mode = stmd + tarinfo.uid = statres.st_uid + tarinfo.gid = statres.st_gid + if type == REGTYPE: + tarinfo.size = statres.st_size + else: + tarinfo.size = 0 + tarinfo.mtime = statres.st_mtime + tarinfo.type = type + tarinfo.linkname = linkname + if pwd: + try: + tarinfo.uname = pwd.getpwuid(tarinfo.uid)[0] + except KeyError: + pass + if grp: + try: + tarinfo.gname = grp.getgrgid(tarinfo.gid)[0] + except KeyError: + pass + + if type in (CHRTYPE, BLKTYPE): + if hasattr(os, "major") and hasattr(os, "minor"): + tarinfo.devmajor = os.major(statres.st_rdev) + tarinfo.devminor = os.minor(statres.st_rdev) + return tarinfo + + def list(self, verbose=True): + """Print a table of contents to sys.stdout. If `verbose' is False, only + the names of the members are printed. If it is True, an `ls -l'-like + output is produced. + """ + self._check() + + for tarinfo in self: + if verbose: + print(filemode(tarinfo.mode), end=' ') + print("%s/%s" % (tarinfo.uname or tarinfo.uid, + tarinfo.gname or tarinfo.gid), end=' ') + if tarinfo.ischr() or tarinfo.isblk(): + print("%10s" % ("%d,%d" \ + % (tarinfo.devmajor, tarinfo.devminor)), end=' ') + else: + print("%10d" % tarinfo.size, end=' ') + print("%d-%02d-%02d %02d:%02d:%02d" \ + % time.localtime(tarinfo.mtime)[:6], end=' ') + + print(tarinfo.name + ("/" if tarinfo.isdir() else ""), end=' ') + + if verbose: + if tarinfo.issym(): + print("->", tarinfo.linkname, end=' ') + if tarinfo.islnk(): + print("link to", tarinfo.linkname, end=' ') + print() + + def add(self, name, arcname=None, recursive=True, exclude=None, filter=None): + """Add the file `name' to the archive. `name' may be any type of file + (directory, fifo, symbolic link, etc.). If given, `arcname' + specifies an alternative name for the file in the archive. + Directories are added recursively by default. This can be avoided by + setting `recursive' to False. `exclude' is a function that should + return True for each filename to be excluded. `filter' is a function + that expects a TarInfo object argument and returns the changed + TarInfo object, if it returns None the TarInfo object will be + excluded from the archive. + """ + self._check("aw") + + if arcname is None: + arcname = name + + # Exclude pathnames. + if exclude is not None: + import warnings + warnings.warn("use the filter argument instead", + DeprecationWarning, 2) + if exclude(name): + self._dbg(2, "tarfile: Excluded %r" % name) + return + + # Skip if somebody tries to archive the archive... + if self.name is not None and os.path.abspath(name) == self.name: + self._dbg(2, "tarfile: Skipped %r" % name) + return + + self._dbg(1, name) + + # Create a TarInfo object from the file. + tarinfo = self.gettarinfo(name, arcname) + + if tarinfo is None: + self._dbg(1, "tarfile: Unsupported type %r" % name) + return + + # Change or exclude the TarInfo object. + if filter is not None: + tarinfo = filter(tarinfo) + if tarinfo is None: + self._dbg(2, "tarfile: Excluded %r" % name) + return + + # Append the tar header and data to the archive. + if tarinfo.isreg(): + f = bltn_open(name, "rb") + self.addfile(tarinfo, f) + f.close() + + elif tarinfo.isdir(): + self.addfile(tarinfo) + if recursive: + for f in os.listdir(name): + self.add(os.path.join(name, f), os.path.join(arcname, f), + recursive, exclude, filter=filter) + + else: + self.addfile(tarinfo) + + def addfile(self, tarinfo, fileobj=None): + """Add the TarInfo object `tarinfo' to the archive. If `fileobj' is + given, tarinfo.size bytes are read from it and added to the archive. + You can create TarInfo objects using gettarinfo(). + On Windows platforms, `fileobj' should always be opened with mode + 'rb' to avoid irritation about the file size. + """ + self._check("aw") + + tarinfo = copy.copy(tarinfo) + + buf = tarinfo.tobuf(self.format, self.encoding, self.errors) + self.fileobj.write(buf) + self.offset += len(buf) + + # If there's data to follow, append it. + if fileobj is not None: + copyfileobj(fileobj, self.fileobj, tarinfo.size) + blocks, remainder = divmod(tarinfo.size, BLOCKSIZE) + if remainder > 0: + self.fileobj.write(NUL * (BLOCKSIZE - remainder)) + blocks += 1 + self.offset += blocks * BLOCKSIZE + + self.members.append(tarinfo) + + def extractall(self, path=".", members=None): + """Extract all members from the archive to the current working + directory and set owner, modification time and permissions on + directories afterwards. `path' specifies a different directory + to extract to. `members' is optional and must be a subset of the + list returned by getmembers(). + """ + directories = [] + + if members is None: + members = self + + for tarinfo in members: + if tarinfo.isdir(): + # Extract directories with a safe mode. + directories.append(tarinfo) + tarinfo = copy.copy(tarinfo) + tarinfo.mode = 0o700 + # Do not set_attrs directories, as we will do that further down + self.extract(tarinfo, path, set_attrs=not tarinfo.isdir()) + + # Reverse sort directories. + directories.sort(key=lambda a: a.name) + directories.reverse() + + # Set correct owner, mtime and filemode on directories. + for tarinfo in directories: + dirpath = os.path.join(path, tarinfo.name) + try: + self.chown(tarinfo, dirpath) + self.utime(tarinfo, dirpath) + self.chmod(tarinfo, dirpath) + except ExtractError as e: + if self.errorlevel > 1: + raise + else: + self._dbg(1, "tarfile: %s" % e) + + def extract(self, member, path="", set_attrs=True): + """Extract a member from the archive to the current working directory, + using its full name. Its file information is extracted as accurately + as possible. `member' may be a filename or a TarInfo object. You can + specify a different directory using `path'. File attributes (owner, + mtime, mode) are set unless `set_attrs' is False. + """ + self._check("r") + + if isinstance(member, str): + tarinfo = self.getmember(member) + else: + tarinfo = member + + # Prepare the link target for makelink(). + if tarinfo.islnk(): + tarinfo._link_target = os.path.join(path, tarinfo.linkname) + + try: + self._extract_member(tarinfo, os.path.join(path, tarinfo.name), + set_attrs=set_attrs) + except EnvironmentError as e: + if self.errorlevel > 0: + raise + else: + if e.filename is None: + self._dbg(1, "tarfile: %s" % e.strerror) + else: + self._dbg(1, "tarfile: %s %r" % (e.strerror, e.filename)) + except ExtractError as e: + if self.errorlevel > 1: + raise + else: + self._dbg(1, "tarfile: %s" % e) + + def extractfile(self, member): + """Extract a member from the archive as a file object. `member' may be + a filename or a TarInfo object. If `member' is a regular file, a + file-like object is returned. If `member' is a link, a file-like + object is constructed from the link's target. If `member' is none of + the above, None is returned. + The file-like object is read-only and provides the following + methods: read(), readline(), readlines(), seek() and tell() + """ + self._check("r") + + if isinstance(member, str): + tarinfo = self.getmember(member) + else: + tarinfo = member + + if tarinfo.isreg(): + return self.fileobject(self, tarinfo) + + elif tarinfo.type not in SUPPORTED_TYPES: + # If a member's type is unknown, it is treated as a + # regular file. + return self.fileobject(self, tarinfo) + + elif tarinfo.islnk() or tarinfo.issym(): + if isinstance(self.fileobj, _Stream): + # A small but ugly workaround for the case that someone tries + # to extract a (sym)link as a file-object from a non-seekable + # stream of tar blocks. + raise StreamError("cannot extract (sym)link as file object") + else: + # A (sym)link's file object is its target's file object. + return self.extractfile(self._find_link_target(tarinfo)) + else: + # If there's no data associated with the member (directory, chrdev, + # blkdev, etc.), return None instead of a file object. + return None + + def _extract_member(self, tarinfo, targetpath, set_attrs=True): + """Extract the TarInfo object tarinfo to a physical + file called targetpath. + """ + # Fetch the TarInfo object for the given name + # and build the destination pathname, replacing + # forward slashes to platform specific separators. + targetpath = targetpath.rstrip("/") + targetpath = targetpath.replace("/", os.sep) + + # Create all upper directories. + upperdirs = os.path.dirname(targetpath) + if upperdirs and not os.path.exists(upperdirs): + # Create directories that are not part of the archive with + # default permissions. + os.makedirs(upperdirs) + + if tarinfo.islnk() or tarinfo.issym(): + self._dbg(1, "%s -> %s" % (tarinfo.name, tarinfo.linkname)) + else: + self._dbg(1, tarinfo.name) + + if tarinfo.isreg(): + self.makefile(tarinfo, targetpath) + elif tarinfo.isdir(): + self.makedir(tarinfo, targetpath) + elif tarinfo.isfifo(): + self.makefifo(tarinfo, targetpath) + elif tarinfo.ischr() or tarinfo.isblk(): + self.makedev(tarinfo, targetpath) + elif tarinfo.islnk() or tarinfo.issym(): + self.makelink(tarinfo, targetpath) + elif tarinfo.type not in SUPPORTED_TYPES: + self.makeunknown(tarinfo, targetpath) + else: + self.makefile(tarinfo, targetpath) + + if set_attrs: + self.chown(tarinfo, targetpath) + if not tarinfo.issym(): + self.chmod(tarinfo, targetpath) + self.utime(tarinfo, targetpath) + + #-------------------------------------------------------------------------- + # Below are the different file methods. They are called via + # _extract_member() when extract() is called. They can be replaced in a + # subclass to implement other functionality. + + def makedir(self, tarinfo, targetpath): + """Make a directory called targetpath. + """ + try: + # Use a safe mode for the directory, the real mode is set + # later in _extract_member(). + os.mkdir(targetpath, 0o700) + except EnvironmentError as e: + if e.errno != errno.EEXIST: + raise + + def makefile(self, tarinfo, targetpath): + """Make a file called targetpath. + """ + source = self.fileobj + source.seek(tarinfo.offset_data) + target = bltn_open(targetpath, "wb") + if tarinfo.sparse is not None: + for offset, size in tarinfo.sparse: + target.seek(offset) + copyfileobj(source, target, size) + else: + copyfileobj(source, target, tarinfo.size) + target.seek(tarinfo.size) + target.truncate() + target.close() + + def makeunknown(self, tarinfo, targetpath): + """Make a file from a TarInfo object with an unknown type + at targetpath. + """ + self.makefile(tarinfo, targetpath) + self._dbg(1, "tarfile: Unknown file type %r, " \ + "extracted as regular file." % tarinfo.type) + + def makefifo(self, tarinfo, targetpath): + """Make a fifo called targetpath. + """ + if hasattr(os, "mkfifo"): + os.mkfifo(targetpath) + else: + raise ExtractError("fifo not supported by system") + + def makedev(self, tarinfo, targetpath): + """Make a character or block device called targetpath. + """ + if not hasattr(os, "mknod") or not hasattr(os, "makedev"): + raise ExtractError("special devices not supported by system") + + mode = tarinfo.mode + if tarinfo.isblk(): + mode |= stat.S_IFBLK + else: + mode |= stat.S_IFCHR + + os.mknod(targetpath, mode, + os.makedev(tarinfo.devmajor, tarinfo.devminor)) + + def makelink(self, tarinfo, targetpath): + """Make a (symbolic) link called targetpath. If it cannot be created + (platform limitation), we try to make a copy of the referenced file + instead of a link. + """ + try: + # For systems that support symbolic and hard links. + if tarinfo.issym(): + os.symlink(tarinfo.linkname, targetpath) + else: + # See extract(). + if os.path.exists(tarinfo._link_target): + os.link(tarinfo._link_target, targetpath) + else: + self._extract_member(self._find_link_target(tarinfo), + targetpath) + except symlink_exception: + if tarinfo.issym(): + linkpath = os.path.join(os.path.dirname(tarinfo.name), + tarinfo.linkname) + else: + linkpath = tarinfo.linkname + else: + try: + self._extract_member(self._find_link_target(tarinfo), + targetpath) + except KeyError: + raise ExtractError("unable to resolve link inside archive") + + def chown(self, tarinfo, targetpath): + """Set owner of targetpath according to tarinfo. + """ + if pwd and hasattr(os, "geteuid") and os.geteuid() == 0: + # We have to be root to do so. + try: + g = grp.getgrnam(tarinfo.gname)[2] + except KeyError: + g = tarinfo.gid + try: + u = pwd.getpwnam(tarinfo.uname)[2] + except KeyError: + u = tarinfo.uid + try: + if tarinfo.issym() and hasattr(os, "lchown"): + os.lchown(targetpath, u, g) + else: + if sys.platform != "os2emx": + os.chown(targetpath, u, g) + except EnvironmentError as e: + raise ExtractError("could not change owner") + + def chmod(self, tarinfo, targetpath): + """Set file permissions of targetpath according to tarinfo. + """ + if hasattr(os, 'chmod'): + try: + os.chmod(targetpath, tarinfo.mode) + except EnvironmentError as e: + raise ExtractError("could not change mode") + + def utime(self, tarinfo, targetpath): + """Set modification time of targetpath according to tarinfo. + """ + if not hasattr(os, 'utime'): + return + try: + os.utime(targetpath, (tarinfo.mtime, tarinfo.mtime)) + except EnvironmentError as e: + raise ExtractError("could not change modification time") + + #-------------------------------------------------------------------------- + def next(self): + """Return the next member of the archive as a TarInfo object, when + TarFile is opened for reading. Return None if there is no more + available. + """ + self._check("ra") + if self.firstmember is not None: + m = self.firstmember + self.firstmember = None + return m + + # Read the next block. + self.fileobj.seek(self.offset) + tarinfo = None + while True: + try: + tarinfo = self.tarinfo.fromtarfile(self) + except EOFHeaderError as e: + if self.ignore_zeros: + self._dbg(2, "0x%X: %s" % (self.offset, e)) + self.offset += BLOCKSIZE + continue + except InvalidHeaderError as e: + if self.ignore_zeros: + self._dbg(2, "0x%X: %s" % (self.offset, e)) + self.offset += BLOCKSIZE + continue + elif self.offset == 0: + raise ReadError(str(e)) + except EmptyHeaderError: + if self.offset == 0: + raise ReadError("empty file") + except TruncatedHeaderError as e: + if self.offset == 0: + raise ReadError(str(e)) + except SubsequentHeaderError as e: + raise ReadError(str(e)) + break + + if tarinfo is not None: + self.members.append(tarinfo) + else: + self._loaded = True + + return tarinfo + + #-------------------------------------------------------------------------- + # Little helper methods: + + def _getmember(self, name, tarinfo=None, normalize=False): + """Find an archive member by name from bottom to top. + If tarinfo is given, it is used as the starting point. + """ + # Ensure that all members have been loaded. + members = self.getmembers() + + # Limit the member search list up to tarinfo. + if tarinfo is not None: + members = members[:members.index(tarinfo)] + + if normalize: + name = os.path.normpath(name) + + for member in reversed(members): + if normalize: + member_name = os.path.normpath(member.name) + else: + member_name = member.name + + if name == member_name: + return member + + def _load(self): + """Read through the entire archive file and look for readable + members. + """ + while True: + tarinfo = self.next() + if tarinfo is None: + break + self._loaded = True + + def _check(self, mode=None): + """Check if TarFile is still open, and if the operation's mode + corresponds to TarFile's mode. + """ + if self.closed: + raise IOError("%s is closed" % self.__class__.__name__) + if mode is not None and self.mode not in mode: + raise IOError("bad operation for mode %r" % self.mode) + + def _find_link_target(self, tarinfo): + """Find the target member of a symlink or hardlink member in the + archive. + """ + if tarinfo.issym(): + # Always search the entire archive. + linkname = os.path.dirname(tarinfo.name) + "/" + tarinfo.linkname + limit = None + else: + # Search the archive before the link, because a hard link is + # just a reference to an already archived file. + linkname = tarinfo.linkname + limit = tarinfo + + member = self._getmember(linkname, tarinfo=limit, normalize=True) + if member is None: + raise KeyError("linkname %r not found" % linkname) + return member + + def __iter__(self): + """Provide an iterator object. + """ + if self._loaded: + return iter(self.members) + else: + return TarIter(self) + + def _dbg(self, level, msg): + """Write debugging output to sys.stderr. + """ + if level <= self.debug: + print(msg, file=sys.stderr) + + def __enter__(self): + self._check() + return self + + def __exit__(self, type, value, traceback): + if type is None: + self.close() + else: + # An exception occurred. We must not call close() because + # it would try to write end-of-archive blocks and padding. + if not self._extfileobj: + self.fileobj.close() + self.closed = True +# class TarFile + +class TarIter(object): + """Iterator Class. + + for tarinfo in TarFile(...): + suite... + """ + + def __init__(self, tarfile): + """Construct a TarIter object. + """ + self.tarfile = tarfile + self.index = 0 + def __iter__(self): + """Return iterator object. + """ + return self + + def __next__(self): + """Return the next item using TarFile's next() method. + When all members have been read, set TarFile as _loaded. + """ + # Fix for SF #1100429: Under rare circumstances it can + # happen that getmembers() is called during iteration, + # which will cause TarIter to stop prematurely. + if not self.tarfile._loaded: + tarinfo = self.tarfile.next() + if not tarinfo: + self.tarfile._loaded = True + raise StopIteration + else: + try: + tarinfo = self.tarfile.members[self.index] + except IndexError: + raise StopIteration + self.index += 1 + return tarinfo + + next = __next__ # for Python 2.x + +#-------------------- +# exported functions +#-------------------- +def is_tarfile(name): + """Return True if name points to a tar archive that we + are able to handle, else return False. + """ + try: + t = open(name) + t.close() + return True + except TarError: + return False + +bltn_open = open +open = TarFile.open diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/compat.py b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/compat.py new file mode 100644 index 0000000..ff328c8 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/compat.py @@ -0,0 +1,1120 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013-2017 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +from __future__ import absolute_import + +import os +import re +import sys + +try: + import ssl +except ImportError: # pragma: no cover + ssl = None + +if sys.version_info[0] < 3: # pragma: no cover + from StringIO import StringIO + string_types = basestring, + text_type = unicode + from types import FileType as file_type + import __builtin__ as builtins + import ConfigParser as configparser + from ._backport import shutil + from urlparse import urlparse, urlunparse, urljoin, urlsplit, urlunsplit + from urllib import (urlretrieve, quote as _quote, unquote, url2pathname, + pathname2url, ContentTooShortError, splittype) + + def quote(s): + if isinstance(s, unicode): + s = s.encode('utf-8') + return _quote(s) + + import urllib2 + from urllib2 import (Request, urlopen, URLError, HTTPError, + HTTPBasicAuthHandler, HTTPPasswordMgr, + HTTPHandler, HTTPRedirectHandler, + build_opener) + if ssl: + from urllib2 import HTTPSHandler + import httplib + import xmlrpclib + import Queue as queue + from HTMLParser import HTMLParser + import htmlentitydefs + raw_input = raw_input + from itertools import ifilter as filter + from itertools import ifilterfalse as filterfalse + + _userprog = None + def splituser(host): + """splituser('user[:passwd]@host[:port]') --> 'user[:passwd]', 'host[:port]'.""" + global _userprog + if _userprog is None: + import re + _userprog = re.compile('^(.*)@(.*)$') + + match = _userprog.match(host) + if match: return match.group(1, 2) + return None, host + +else: # pragma: no cover + from io import StringIO + string_types = str, + text_type = str + from io import TextIOWrapper as file_type + import builtins + import configparser + import shutil + from urllib.parse import (urlparse, urlunparse, urljoin, splituser, quote, + unquote, urlsplit, urlunsplit, splittype) + from urllib.request import (urlopen, urlretrieve, Request, url2pathname, + pathname2url, + HTTPBasicAuthHandler, HTTPPasswordMgr, + HTTPHandler, HTTPRedirectHandler, + build_opener) + if ssl: + from urllib.request import HTTPSHandler + from urllib.error import HTTPError, URLError, ContentTooShortError + import http.client as httplib + import urllib.request as urllib2 + import xmlrpc.client as xmlrpclib + import queue + from html.parser import HTMLParser + import html.entities as htmlentitydefs + raw_input = input + from itertools import filterfalse + filter = filter + +try: + from ssl import match_hostname, CertificateError +except ImportError: # pragma: no cover + class CertificateError(ValueError): + pass + + + def _dnsname_match(dn, hostname, max_wildcards=1): + """Matching according to RFC 6125, section 6.4.3 + + http://tools.ietf.org/html/rfc6125#section-6.4.3 + """ + pats = [] + if not dn: + return False + + parts = dn.split('.') + leftmost, remainder = parts[0], parts[1:] + + 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)) + + # speed up common case w/o wildcards + if not wildcards: + 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. + 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--'): + # 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 + # U-label of an internationalized domain name. + pats.append(re.escape(leftmost)) + else: + # Otherwise, '*' matches any dotless string, e.g. www* + 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) + return pat.match(hostname) + + + def match_hostname(cert, hostname): + """Verify that *cert* (in decoded format as returned by + SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125 + rules are followed, but IP addresses are not accepted for *hostname*. + + CertificateError is raised on failure. On success, the function + 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") + dnsnames = [] + san = cert.get('subjectAltName', ()) + for key, value in san: + if key == 'DNS': + if _dnsname_match(value, hostname): + 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 key, value in sub: + # XXX according to RFC 2818, the most specific Common Name + # must be used. + 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)))) + elif len(dnsnames) == 1: + raise CertificateError("hostname %r " + "doesn't match %r" + % (hostname, dnsnames[0])) + else: + raise CertificateError("no appropriate commonName or " + "subjectAltName fields were found") + + +try: + from types import SimpleNamespace as Container +except ImportError: # pragma: no cover + class Container(object): + """ + A generic container for when multiple values need to be returned + """ + def __init__(self, **kwargs): + self.__dict__.update(kwargs) + + +try: + from shutil import which +except ImportError: # pragma: no cover + # Implementation from Python 3.3 + def which(cmd, mode=os.F_OK | os.X_OK, path=None): + """Given a command, mode, and a PATH string, return the path which + conforms to the given mode on the PATH, or None if there is no such + file. + + `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result + of os.environ.get("PATH"), or can be overridden with a custom search + path. + + """ + # Check that a given file can be accessed with the correct mode. + # Additionally check that `file` is not a directory, as on Windows + # directories pass the os.access check. + def _access_check(fn, mode): + return (os.path.exists(fn) and os.access(fn, mode) + and not os.path.isdir(fn)) + + # If we're given a path with a directory part, look it up directly rather + # than referring to PATH directories. This includes checking relative to the + # current directory, e.g. ./script + if os.path.dirname(cmd): + if _access_check(cmd, mode): + return cmd + return None + + if path is None: + path = os.environ.get("PATH", os.defpath) + if not path: + return None + path = path.split(os.pathsep) + + if sys.platform == "win32": + # The current directory takes precedence on Windows. + if not os.curdir in path: + path.insert(0, os.curdir) + + # PATHEXT is necessary to check on Windows. + pathext = os.environ.get("PATHEXT", "").split(os.pathsep) + # See if the given file matches any of the expected path extensions. + # This will allow us to short circuit when given "python.exe". + # If it does match, only test that one, otherwise we have to try + # others. + if any(cmd.lower().endswith(ext.lower()) for ext in pathext): + files = [cmd] + else: + files = [cmd + ext for ext in pathext] + else: + # On other platforms you don't have things like PATHEXT to tell you + # what file suffixes are executable, so just pass on cmd as-is. + files = [cmd] + + seen = set() + for dir in path: + normdir = os.path.normcase(dir) + if not normdir in seen: + seen.add(normdir) + for thefile in files: + name = os.path.join(dir, thefile) + if _access_check(name, mode): + return name + return None + + +# ZipFile is a context manager in 2.7, but not in 2.6 + +from zipfile import ZipFile as BaseZipFile + +if hasattr(BaseZipFile, '__enter__'): # pragma: no cover + ZipFile = BaseZipFile +else: # pragma: no cover + from zipfile import ZipExtFile as BaseZipExtFile + + class ZipExtFile(BaseZipExtFile): + def __init__(self, base): + self.__dict__.update(base.__dict__) + + def __enter__(self): + return self + + def __exit__(self, *exc_info): + self.close() + # return None, so if an exception occurred, it will propagate + + class ZipFile(BaseZipFile): + def __enter__(self): + return self + + def __exit__(self, *exc_info): + self.close() + # return None, so if an exception occurred, it will propagate + + def open(self, *args, **kwargs): + base = BaseZipFile.open(self, *args, **kwargs) + return ZipExtFile(base) + +try: + from platform import python_implementation +except ImportError: # pragma: no cover + def python_implementation(): + """Return a string identifying the Python implementation.""" + if 'PyPy' in sys.version: + return 'PyPy' + if os.name == 'java': + return 'Jython' + if sys.version.startswith('IronPython'): + return 'IronPython' + return 'CPython' + +try: + import sysconfig +except ImportError: # pragma: no cover + from ._backport import sysconfig + +try: + callable = callable +except NameError: # pragma: no cover + from collections import Callable + + def callable(obj): + return isinstance(obj, Callable) + + +try: + fsencode = os.fsencode + fsdecode = os.fsdecode +except AttributeError: # pragma: no cover + # Issue #99: on some systems (e.g. containerised), + # sys.getfilesystemencoding() returns None, and we need a real value, + # so fall back to utf-8. From the CPython 2.7 docs relating to Unix and + # sys.getfilesystemencoding(): the return value is "the user’s preference + # according to the result of nl_langinfo(CODESET), or None if the + # nl_langinfo(CODESET) failed." + _fsencoding = sys.getfilesystemencoding() or 'utf-8' + if _fsencoding == 'mbcs': + _fserrors = 'strict' + else: + _fserrors = 'surrogateescape' + + def fsencode(filename): + if isinstance(filename, bytes): + return filename + elif isinstance(filename, text_type): + return filename.encode(_fsencoding, _fserrors) + else: + raise TypeError("expect bytes or str, not %s" % + type(filename).__name__) + + def fsdecode(filename): + if isinstance(filename, text_type): + return filename + elif isinstance(filename, bytes): + return filename.decode(_fsencoding, _fserrors) + else: + raise TypeError("expect bytes or str, not %s" % + type(filename).__name__) + +try: + from tokenize import detect_encoding +except ImportError: # pragma: no cover + from codecs import BOM_UTF8, lookup + import re + + cookie_re = re.compile(r"coding[:=]\s*([-\w.]+)") + + def _get_normal_name(orig_enc): + """Imitates get_normal_name in tokenizer.c.""" + # Only care about the first 12 characters. + enc = orig_enc[:12].lower().replace("_", "-") + if enc == "utf-8" or enc.startswith("utf-8-"): + return "utf-8" + if enc in ("latin-1", "iso-8859-1", "iso-latin-1") or \ + enc.startswith(("latin-1-", "iso-8859-1-", "iso-latin-1-")): + return "iso-8859-1" + return orig_enc + + def detect_encoding(readline): + """ + The detect_encoding() function is used to detect the encoding that should + be used to decode a Python source file. It requires one argument, readline, + in the same way as the tokenize() generator. + + It will call readline a maximum of twice, and return the encoding used + (as a string) and a list of any lines (left as bytes) it has read in. + + It detects the encoding from the presence of a utf-8 bom or an encoding + cookie as specified in pep-0263. If both a bom and a cookie are present, + but disagree, a SyntaxError will be raised. If the encoding cookie is an + invalid charset, raise a SyntaxError. Note that if a utf-8 bom is found, + 'utf-8-sig' is returned. + + If no encoding is specified, then the default of 'utf-8' will be returned. + """ + try: + filename = readline.__self__.name + except AttributeError: + filename = None + bom_found = False + encoding = None + default = 'utf-8' + def read_or_stop(): + try: + return readline() + except StopIteration: + return b'' + + def find_cookie(line): + try: + # Decode as UTF-8. Either the line is an encoding declaration, + # in which case it should be pure ASCII, or it must be UTF-8 + # per default encoding. + line_string = line.decode('utf-8') + except UnicodeDecodeError: + msg = "invalid or missing encoding declaration" + if filename is not None: + msg = '{} for {!r}'.format(msg, filename) + raise SyntaxError(msg) + + matches = cookie_re.findall(line_string) + if not matches: + return None + encoding = _get_normal_name(matches[0]) + try: + codec = lookup(encoding) + except LookupError: + # This behaviour mimics the Python interpreter + if filename is None: + msg = "unknown encoding: " + encoding + else: + msg = "unknown encoding for {!r}: {}".format(filename, + encoding) + raise SyntaxError(msg) + + if bom_found: + if codec.name != 'utf-8': + # This behaviour mimics the Python interpreter + if filename is None: + msg = 'encoding problem: utf-8' + else: + msg = 'encoding problem for {!r}: utf-8'.format(filename) + raise SyntaxError(msg) + encoding += '-sig' + return encoding + + first = read_or_stop() + if first.startswith(BOM_UTF8): + bom_found = True + first = first[3:] + default = 'utf-8-sig' + if not first: + return default, [] + + encoding = find_cookie(first) + if encoding: + return encoding, [first] + + second = read_or_stop() + if not second: + return default, [first] + + encoding = find_cookie(second) + if encoding: + return encoding, [first, second] + + return default, [first, second] + +# For converting & <-> & etc. +try: + from html import escape +except ImportError: + from cgi import escape +if sys.version_info[:2] < (3, 4): + unescape = HTMLParser().unescape +else: + from html import unescape + +try: + from collections import ChainMap +except ImportError: # pragma: no cover + from collections import MutableMapping + + try: + from reprlib import recursive_repr as _recursive_repr + except ImportError: + def _recursive_repr(fillvalue='...'): + ''' + Decorator to make a repr function return fillvalue for a recursive + call + ''' + + def decorating_function(user_function): + repr_running = set() + + def wrapper(self): + key = id(self), get_ident() + if key in repr_running: + return fillvalue + repr_running.add(key) + try: + result = user_function(self) + finally: + repr_running.discard(key) + return result + + # Can't use functools.wraps() here because of bootstrap issues + wrapper.__module__ = getattr(user_function, '__module__') + wrapper.__doc__ = getattr(user_function, '__doc__') + wrapper.__name__ = getattr(user_function, '__name__') + wrapper.__annotations__ = getattr(user_function, '__annotations__', {}) + return wrapper + + return decorating_function + + class ChainMap(MutableMapping): + ''' A ChainMap groups multiple dicts (or other mappings) together + to create a single, updateable view. + + The underlying mappings are stored in a list. That list is public and can + accessed or updated using the *maps* attribute. There is no other state. + + Lookups search the underlying mappings successively until a key is found. + In contrast, writes, updates, and deletions only operate on the first + mapping. + + ''' + + def __init__(self, *maps): + '''Initialize a ChainMap by setting *maps* to the given mappings. + If no mappings are provided, a single empty dictionary is used. + + ''' + self.maps = list(maps) or [{}] # always at least one map + + def __missing__(self, key): + raise KeyError(key) + + def __getitem__(self, key): + for mapping in self.maps: + try: + return mapping[key] # can't use 'key in mapping' with defaultdict + except KeyError: + pass + return self.__missing__(key) # support subclasses that define __missing__ + + def get(self, key, default=None): + return self[key] if key in self else default + + def __len__(self): + return len(set().union(*self.maps)) # reuses stored hash values if possible + + def __iter__(self): + return iter(set().union(*self.maps)) + + def __contains__(self, key): + return any(key in m for m in self.maps) + + def __bool__(self): + return any(self.maps) + + @_recursive_repr() + def __repr__(self): + return '{0.__class__.__name__}({1})'.format( + self, ', '.join(map(repr, self.maps))) + + @classmethod + def fromkeys(cls, iterable, *args): + 'Create a ChainMap with a single dict created from the iterable.' + return cls(dict.fromkeys(iterable, *args)) + + def copy(self): + 'New ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]' + return self.__class__(self.maps[0].copy(), *self.maps[1:]) + + __copy__ = copy + + def new_child(self): # like Django's Context.push() + 'New ChainMap with a new dict followed by all previous maps.' + return self.__class__({}, *self.maps) + + @property + def parents(self): # like Django's Context.pop() + 'New ChainMap from maps[1:].' + return self.__class__(*self.maps[1:]) + + def __setitem__(self, key, value): + self.maps[0][key] = value + + def __delitem__(self, key): + try: + del self.maps[0][key] + except KeyError: + raise KeyError('Key not found in the first mapping: {!r}'.format(key)) + + def popitem(self): + 'Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.' + try: + return self.maps[0].popitem() + except KeyError: + raise KeyError('No keys found in the first mapping.') + + def pop(self, key, *args): + 'Remove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].' + try: + return self.maps[0].pop(key, *args) + except KeyError: + raise KeyError('Key not found in the first mapping: {!r}'.format(key)) + + def clear(self): + 'Clear maps[0], leaving maps[1:] intact.' + self.maps[0].clear() + +try: + from importlib.util import cache_from_source # Python >= 3.4 +except ImportError: # pragma: no cover + try: + from imp import cache_from_source + except ImportError: # pragma: no cover + def cache_from_source(path, debug_override=None): + assert path.endswith('.py') + if debug_override is None: + debug_override = __debug__ + if debug_override: + suffix = 'c' + else: + suffix = 'o' + return path + suffix + +try: + from collections import OrderedDict +except ImportError: # pragma: no cover +## {{{ http://code.activestate.com/recipes/576693/ (r9) +# Backport of OrderedDict() class that runs on Python 2.4, 2.5, 2.6, 2.7 and pypy. +# Passes Python2.7's test suite and incorporates all the latest updates. + try: + from thread import get_ident as _get_ident + except ImportError: + from dummy_thread import get_ident as _get_ident + + try: + from _abcoll import KeysView, ValuesView, ItemsView + except ImportError: + pass + + + class OrderedDict(dict): + 'Dictionary that remembers insertion order' + # An inherited dict maps keys to values. + # The inherited dict provides __getitem__, __len__, __contains__, and get. + # The remaining methods are order-aware. + # Big-O running times for all methods are the same as for regular dictionaries. + + # The internal self.__map dictionary maps keys to links in a doubly linked list. + # The circular doubly linked list starts and ends with a sentinel element. + # The sentinel element never gets deleted (this simplifies the algorithm). + # Each link is stored as a list of length three: [PREV, NEXT, KEY]. + + def __init__(self, *args, **kwds): + '''Initialize an ordered dictionary. Signature is the same as for + regular dictionaries, but keyword arguments are not recommended + because their insertion order is arbitrary. + + ''' + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + try: + self.__root + except AttributeError: + self.__root = root = [] # sentinel node + root[:] = [root, root, None] + self.__map = {} + self.__update(*args, **kwds) + + def __setitem__(self, key, value, dict_setitem=dict.__setitem__): + 'od.__setitem__(i, y) <==> od[i]=y' + # Setting a new item creates a new link which goes at the end of the linked + # list, and the inherited dictionary is updated with the new key/value pair. + if key not in self: + root = self.__root + last = root[0] + last[1] = root[0] = self.__map[key] = [last, root, key] + dict_setitem(self, key, value) + + def __delitem__(self, key, dict_delitem=dict.__delitem__): + 'od.__delitem__(y) <==> del od[y]' + # Deleting an existing item uses self.__map to find the link which is + # then removed by updating the links in the predecessor and successor nodes. + dict_delitem(self, key) + link_prev, link_next, key = self.__map.pop(key) + link_prev[1] = link_next + link_next[0] = link_prev + + def __iter__(self): + 'od.__iter__() <==> iter(od)' + root = self.__root + curr = root[1] + while curr is not root: + yield curr[2] + curr = curr[1] + + def __reversed__(self): + 'od.__reversed__() <==> reversed(od)' + root = self.__root + curr = root[0] + while curr is not root: + yield curr[2] + curr = curr[0] + + def clear(self): + 'od.clear() -> None. Remove all items from od.' + try: + for node in self.__map.itervalues(): + del node[:] + root = self.__root + root[:] = [root, root, None] + self.__map.clear() + except AttributeError: + pass + dict.clear(self) + + def popitem(self, last=True): + '''od.popitem() -> (k, v), return and remove a (key, value) pair. + Pairs are returned in LIFO order if last is true or FIFO order if false. + + ''' + if not self: + raise KeyError('dictionary is empty') + root = self.__root + if last: + link = root[0] + link_prev = link[0] + link_prev[1] = root + root[0] = link_prev + else: + link = root[1] + link_next = link[1] + root[1] = link_next + link_next[0] = root + key = link[2] + del self.__map[key] + value = dict.pop(self, key) + return key, value + + # -- the following methods do not depend on the internal structure -- + + def keys(self): + 'od.keys() -> list of keys in od' + return list(self) + + def values(self): + 'od.values() -> list of values in od' + return [self[key] for key in self] + + def items(self): + 'od.items() -> list of (key, value) pairs in od' + return [(key, self[key]) for key in self] + + def iterkeys(self): + 'od.iterkeys() -> an iterator over the keys in od' + return iter(self) + + def itervalues(self): + 'od.itervalues -> an iterator over the values in od' + for k in self: + yield self[k] + + def iteritems(self): + 'od.iteritems -> an iterator over the (key, value) items in od' + for k in self: + yield (k, self[k]) + + def update(*args, **kwds): + '''od.update(E, **F) -> None. Update od from dict/iterable E and F. + + If E is a dict instance, does: for k in E: od[k] = E[k] + If E has a .keys() method, does: for k in E.keys(): od[k] = E[k] + Or if E is an iterable of items, does: for k, v in E: od[k] = v + In either case, this is followed by: for k, v in F.items(): od[k] = v + + ''' + if len(args) > 2: + raise TypeError('update() takes at most 2 positional ' + 'arguments (%d given)' % (len(args),)) + elif not args: + raise TypeError('update() takes at least 1 argument (0 given)') + self = args[0] + # Make progressively weaker assumptions about "other" + other = () + if len(args) == 2: + other = args[1] + if isinstance(other, dict): + for key in other: + self[key] = other[key] + elif hasattr(other, 'keys'): + for key in other.keys(): + self[key] = other[key] + else: + for key, value in other: + self[key] = value + for key, value in kwds.items(): + self[key] = value + + __update = update # let subclasses override update without breaking __init__ + + __marker = object() + + def pop(self, key, default=__marker): + '''od.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. + + ''' + if key in self: + result = self[key] + del self[key] + return result + if default is self.__marker: + raise KeyError(key) + return default + + def setdefault(self, key, default=None): + 'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od' + if key in self: + return self[key] + self[key] = default + return default + + def __repr__(self, _repr_running=None): + 'od.__repr__() <==> repr(od)' + if not _repr_running: _repr_running = {} + call_key = id(self), _get_ident() + if call_key in _repr_running: + return '...' + _repr_running[call_key] = 1 + try: + if not self: + return '%s()' % (self.__class__.__name__,) + return '%s(%r)' % (self.__class__.__name__, self.items()) + finally: + del _repr_running[call_key] + + def __reduce__(self): + 'Return state information for pickling' + items = [[k, self[k]] for k in self] + inst_dict = vars(self).copy() + for k in vars(OrderedDict()): + inst_dict.pop(k, None) + if inst_dict: + return (self.__class__, (items,), inst_dict) + return self.__class__, (items,) + + def copy(self): + 'od.copy() -> a shallow copy of od' + return self.__class__(self) + + @classmethod + def fromkeys(cls, iterable, value=None): + '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S + and values equal to v (which defaults to None). + + ''' + d = cls() + for key in iterable: + d[key] = value + return d + + def __eq__(self, other): + '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive + while comparison to a regular mapping is order-insensitive. + + ''' + if isinstance(other, OrderedDict): + return len(self)==len(other) and self.items() == other.items() + return dict.__eq__(self, other) + + def __ne__(self, other): + return not self == other + + # -- the following methods are only used in Python 2.7 -- + + def viewkeys(self): + "od.viewkeys() -> a set-like object providing a view on od's keys" + return KeysView(self) + + def viewvalues(self): + "od.viewvalues() -> an object providing a view on od's values" + return ValuesView(self) + + def viewitems(self): + "od.viewitems() -> a set-like object providing a view on od's items" + return ItemsView(self) + +try: + from logging.config import BaseConfigurator, valid_ident +except ImportError: # pragma: no cover + IDENTIFIER = re.compile('^[a-z_][a-z0-9_]*$', re.I) + + + def valid_ident(s): + m = IDENTIFIER.match(s) + if not m: + raise ValueError('Not a valid Python identifier: %r' % s) + return True + + + # The ConvertingXXX classes are wrappers around standard Python containers, + # and they serve to convert any suitable values in the container. The + # conversion converts base dicts, lists and tuples to their wrapped + # equivalents, whereas strings which match a conversion format are converted + # appropriately. + # + # Each wrapper should have a configurator attribute holding the actual + # configurator to use for conversion. + + class ConvertingDict(dict): + """A converting dictionary wrapper.""" + + def __getitem__(self, key): + value = dict.__getitem__(self, key) + result = self.configurator.convert(value) + #If the converted value is different, save for next time + if value is not result: + self[key] = result + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + def get(self, key, default=None): + value = dict.get(self, key, default) + result = self.configurator.convert(value) + #If the converted value is different, save for next time + if value is not result: + self[key] = result + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + def pop(self, key, default=None): + value = dict.pop(self, key, default) + result = self.configurator.convert(value) + if value is not result: + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + class ConvertingList(list): + """A converting list wrapper.""" + def __getitem__(self, key): + value = list.__getitem__(self, key) + result = self.configurator.convert(value) + #If the converted value is different, save for next time + if value is not result: + self[key] = result + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + def pop(self, idx=-1): + value = list.pop(self, idx) + result = self.configurator.convert(value) + if value is not result: + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + return result + + class ConvertingTuple(tuple): + """A converting tuple wrapper.""" + def __getitem__(self, key): + value = tuple.__getitem__(self, key) + result = self.configurator.convert(value) + if value is not result: + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + class BaseConfigurator(object): + """ + The configurator base class which defines some useful defaults. + """ + + CONVERT_PATTERN = re.compile(r'^(?P<prefix>[a-z]+)://(?P<suffix>.*)$') + + WORD_PATTERN = re.compile(r'^\s*(\w+)\s*') + DOT_PATTERN = re.compile(r'^\.\s*(\w+)\s*') + INDEX_PATTERN = re.compile(r'^\[\s*(\w+)\s*\]\s*') + DIGIT_PATTERN = re.compile(r'^\d+$') + + value_converters = { + 'ext' : 'ext_convert', + 'cfg' : 'cfg_convert', + } + + # We might want to use a different one, e.g. importlib + importer = staticmethod(__import__) + + def __init__(self, config): + self.config = ConvertingDict(config) + self.config.configurator = self + + def resolve(self, s): + """ + Resolve strings to objects using standard import and attribute + syntax. + """ + name = s.split('.') + used = name.pop(0) + try: + found = self.importer(used) + for frag in name: + used += '.' + frag + try: + found = getattr(found, frag) + except AttributeError: + self.importer(used) + found = getattr(found, frag) + return found + except ImportError: + e, tb = sys.exc_info()[1:] + v = ValueError('Cannot resolve %r: %s' % (s, e)) + v.__cause__, v.__traceback__ = e, tb + raise v + + def ext_convert(self, value): + """Default converter for the ext:// protocol.""" + return self.resolve(value) + + def cfg_convert(self, value): + """Default converter for the cfg:// protocol.""" + rest = value + m = self.WORD_PATTERN.match(rest) + if m is None: + raise ValueError("Unable to convert %r" % value) + else: + rest = rest[m.end():] + d = self.config[m.groups()[0]] + #print d, rest + while rest: + m = self.DOT_PATTERN.match(rest) + if m: + d = d[m.groups()[0]] + else: + m = self.INDEX_PATTERN.match(rest) + if m: + idx = m.groups()[0] + if not self.DIGIT_PATTERN.match(idx): + d = d[idx] + else: + try: + n = int(idx) # try as number first (most likely) + d = d[n] + except TypeError: + d = d[idx] + if m: + rest = rest[m.end():] + else: + raise ValueError('Unable to convert ' + '%r at %r' % (value, rest)) + #rest should be empty + return d + + def convert(self, value): + """ + Convert values to an appropriate type. dicts, lists and tuples are + replaced by their converting alternatives. Strings are checked to + see if they have a conversion format and are converted if they do. + """ + if not isinstance(value, ConvertingDict) and isinstance(value, dict): + value = ConvertingDict(value) + value.configurator = self + elif not isinstance(value, ConvertingList) and isinstance(value, list): + value = ConvertingList(value) + value.configurator = self + elif not isinstance(value, ConvertingTuple) and\ + isinstance(value, tuple): + value = ConvertingTuple(value) + value.configurator = self + elif isinstance(value, string_types): + m = self.CONVERT_PATTERN.match(value) + if m: + d = m.groupdict() + prefix = d['prefix'] + converter = self.value_converters.get(prefix, None) + if converter: + suffix = d['suffix'] + converter = getattr(self, converter) + value = converter(suffix) + return value + + def configure_custom(self, config): + """Configure an object with a user-supplied factory.""" + c = config.pop('()') + if not callable(c): + c = self.resolve(c) + props = config.pop('.', None) + # Check for valid identifiers + kwargs = dict([(k, config[k]) for k in config if valid_ident(k)]) + result = c(**kwargs) + if props: + for name, value in props.items(): + setattr(result, name, value) + return result + + def as_tuple(self, value): + """Utility function which converts lists to tuples.""" + if isinstance(value, list): + value = tuple(value) + return value diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/database.py b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/database.py new file mode 100644 index 0000000..a19905e --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/database.py @@ -0,0 +1,1336 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2017 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +"""PEP 376 implementation.""" + +from __future__ import unicode_literals + +import base64 +import codecs +import contextlib +import hashlib +import logging +import os +import posixpath +import sys +import zipimport + +from . import DistlibException, resources +from .compat import StringIO +from .version import get_scheme, UnsupportedVersionError +from .metadata import Metadata, METADATA_FILENAME, WHEEL_METADATA_FILENAME +from .util import (parse_requirement, cached_property, parse_name_and_version, + read_exports, write_exports, CSVReader, CSVWriter) + + +__all__ = ['Distribution', 'BaseInstalledDistribution', + 'InstalledDistribution', 'EggInfoDistribution', + 'DistributionPath'] + + +logger = logging.getLogger(__name__) + +EXPORTS_FILENAME = 'pydist-exports.json' +COMMANDS_FILENAME = 'pydist-commands.json' + +DIST_FILES = ('INSTALLER', METADATA_FILENAME, 'RECORD', 'REQUESTED', + 'RESOURCES', EXPORTS_FILENAME, 'SHARED') + +DISTINFO_EXT = '.dist-info' + + +class _Cache(object): + """ + A simple cache mapping names and .dist-info paths to distributions + """ + def __init__(self): + """ + Initialise an instance. There is normally one for each DistributionPath. + """ + self.name = {} + self.path = {} + self.generated = False + + def clear(self): + """ + Clear the cache, setting it to its initial state. + """ + self.name.clear() + self.path.clear() + self.generated = False + + def add(self, dist): + """ + Add a distribution to the cache. + :param dist: The distribution to add. + """ + if dist.path not in self.path: + self.path[dist.path] = dist + self.name.setdefault(dist.key, []).append(dist) + + +class DistributionPath(object): + """ + Represents a set of distributions installed on a path (typically sys.path). + """ + def __init__(self, path=None, include_egg=False): + """ + Create an instance from a path, optionally including legacy (distutils/ + setuptools/distribute) distributions. + :param path: The path to use, as a list of directories. If not specified, + sys.path is used. + :param include_egg: If True, this instance will look for and return legacy + distributions as well as those based on PEP 376. + """ + if path is None: + path = sys.path + self.path = path + self._include_dist = True + self._include_egg = include_egg + + self._cache = _Cache() + self._cache_egg = _Cache() + self._cache_enabled = True + self._scheme = get_scheme('default') + + def _get_cache_enabled(self): + return self._cache_enabled + + def _set_cache_enabled(self, value): + self._cache_enabled = value + + cache_enabled = property(_get_cache_enabled, _set_cache_enabled) + + def clear_cache(self): + """ + Clears the internal cache. + """ + self._cache.clear() + self._cache_egg.clear() + + + def _yield_distributions(self): + """ + Yield .dist-info and/or .egg(-info) distributions. + """ + # We need to check if we've seen some resources already, because on + # some Linux systems (e.g. some Debian/Ubuntu variants) there are + # symlinks which alias other files in the environment. + seen = set() + for path in self.path: + finder = resources.finder_for_path(path) + if finder is None: + continue + r = finder.find('') + if not r or not r.is_container: + continue + rset = sorted(r.resources) + for entry in rset: + r = finder.find(entry) + if not r or r.path in seen: + continue + if self._include_dist and entry.endswith(DISTINFO_EXT): + possible_filenames = [METADATA_FILENAME, WHEEL_METADATA_FILENAME] + for metadata_filename in possible_filenames: + metadata_path = posixpath.join(entry, metadata_filename) + pydist = finder.find(metadata_path) + if pydist: + break + else: + continue + + with contextlib.closing(pydist.as_stream()) as stream: + metadata = Metadata(fileobj=stream, scheme='legacy') + logger.debug('Found %s', r.path) + seen.add(r.path) + yield new_dist_class(r.path, metadata=metadata, + env=self) + elif self._include_egg and entry.endswith(('.egg-info', + '.egg')): + logger.debug('Found %s', r.path) + seen.add(r.path) + yield old_dist_class(r.path, self) + + def _generate_cache(self): + """ + Scan the path for distributions and populate the cache with + those that are found. + """ + gen_dist = not self._cache.generated + gen_egg = self._include_egg and not self._cache_egg.generated + if gen_dist or gen_egg: + for dist in self._yield_distributions(): + if isinstance(dist, InstalledDistribution): + self._cache.add(dist) + else: + self._cache_egg.add(dist) + + if gen_dist: + self._cache.generated = True + if gen_egg: + self._cache_egg.generated = True + + @classmethod + def distinfo_dirname(cls, name, version): + """ + The *name* and *version* parameters are converted into their + filename-escaped form, i.e. any ``'-'`` characters are replaced + with ``'_'`` other than the one in ``'dist-info'`` and the one + separating the name from the version number. + + :parameter name: is converted to a standard distribution name by replacing + any runs of non- alphanumeric characters with a single + ``'-'``. + :type name: string + :parameter version: is converted to a standard version string. Spaces + become dots, and all other non-alphanumeric characters + (except dots) become dashes, with runs of multiple + dashes condensed to a single dash. + :type version: string + :returns: directory name + :rtype: string""" + name = name.replace('-', '_') + return '-'.join([name, version]) + DISTINFO_EXT + + def get_distributions(self): + """ + Provides an iterator that looks for distributions and returns + :class:`InstalledDistribution` or + :class:`EggInfoDistribution` instances for each one of them. + + :rtype: iterator of :class:`InstalledDistribution` and + :class:`EggInfoDistribution` instances + """ + if not self._cache_enabled: + for dist in self._yield_distributions(): + yield dist + else: + self._generate_cache() + + for dist in self._cache.path.values(): + yield dist + + if self._include_egg: + for dist in self._cache_egg.path.values(): + yield dist + + def get_distribution(self, name): + """ + Looks for a named distribution on the path. + + This function only returns the first result found, as no more than one + value is expected. If nothing is found, ``None`` is returned. + + :rtype: :class:`InstalledDistribution`, :class:`EggInfoDistribution` + or ``None`` + """ + result = None + name = name.lower() + if not self._cache_enabled: + for dist in self._yield_distributions(): + if dist.key == name: + result = dist + break + else: + self._generate_cache() + + if name in self._cache.name: + result = self._cache.name[name][0] + elif self._include_egg and name in self._cache_egg.name: + result = self._cache_egg.name[name][0] + return result + + def provides_distribution(self, name, version=None): + """ + Iterates over all distributions to find which distributions provide *name*. + If a *version* is provided, it will be used to filter the results. + + This function only returns the first result found, since no more than + one values are expected. If the directory is not found, returns ``None``. + + :parameter version: a version specifier that indicates the version + required, conforming to the format in ``PEP-345`` + + :type name: string + :type version: string + """ + matcher = None + if version is not None: + try: + matcher = self._scheme.matcher('%s (%s)' % (name, version)) + except ValueError: + raise DistlibException('invalid name or version: %r, %r' % + (name, version)) + + for dist in self.get_distributions(): + # We hit a problem on Travis where enum34 was installed and doesn't + # have a provides attribute ... + if not hasattr(dist, 'provides'): + logger.debug('No "provides": %s', dist) + else: + provided = dist.provides + + for p in provided: + p_name, p_ver = parse_name_and_version(p) + if matcher is None: + if p_name == name: + yield dist + break + else: + if p_name == name and matcher.match(p_ver): + yield dist + break + + def get_file_path(self, name, relative_path): + """ + Return the path to a resource file. + """ + dist = self.get_distribution(name) + if dist is None: + raise LookupError('no distribution named %r found' % name) + return dist.get_resource_path(relative_path) + + def get_exported_entries(self, category, name=None): + """ + Return all of the exported entries in a particular category. + + :param category: The category to search for entries. + :param name: If specified, only entries with that name are returned. + """ + for dist in self.get_distributions(): + r = dist.exports + if category in r: + d = r[category] + if name is not None: + if name in d: + yield d[name] + else: + for v in d.values(): + yield v + + +class Distribution(object): + """ + A base class for distributions, whether installed or from indexes. + Either way, it must have some metadata, so that's all that's needed + for construction. + """ + + build_time_dependency = False + """ + Set to True if it's known to be only a build-time dependency (i.e. + not needed after installation). + """ + + requested = False + """A boolean that indicates whether the ``REQUESTED`` metadata file is + present (in other words, whether the package was installed by user + request or it was installed as a dependency).""" + + def __init__(self, metadata): + """ + Initialise an instance. + :param metadata: The instance of :class:`Metadata` describing this + distribution. + """ + self.metadata = metadata + self.name = metadata.name + self.key = self.name.lower() # for case-insensitive comparisons + self.version = metadata.version + self.locator = None + self.digest = None + self.extras = None # additional features requested + self.context = None # environment marker overrides + self.download_urls = set() + self.digests = {} + + @property + def source_url(self): + """ + The source archive download URL for this distribution. + """ + return self.metadata.source_url + + download_url = source_url # Backward compatibility + + @property + def name_and_version(self): + """ + A utility property which displays the name and version in parentheses. + """ + return '%s (%s)' % (self.name, self.version) + + @property + def provides(self): + """ + A set of distribution names and versions provided by this distribution. + :return: A set of "name (version)" strings. + """ + plist = self.metadata.provides + s = '%s (%s)' % (self.name, self.version) + if s not in plist: + plist.append(s) + return plist + + def _get_requirements(self, req_attr): + md = self.metadata + logger.debug('Getting requirements from metadata %r', md.todict()) + reqts = getattr(md, req_attr) + return set(md.get_requirements(reqts, extras=self.extras, + env=self.context)) + + @property + def run_requires(self): + return self._get_requirements('run_requires') + + @property + def meta_requires(self): + return self._get_requirements('meta_requires') + + @property + def build_requires(self): + return self._get_requirements('build_requires') + + @property + def test_requires(self): + return self._get_requirements('test_requires') + + @property + def dev_requires(self): + return self._get_requirements('dev_requires') + + def matches_requirement(self, req): + """ + Say if this instance matches (fulfills) a requirement. + :param req: The requirement to match. + :rtype req: str + :return: True if it matches, else False. + """ + # Requirement may contain extras - parse to lose those + # from what's passed to the matcher + r = parse_requirement(req) + scheme = get_scheme(self.metadata.scheme) + try: + matcher = scheme.matcher(r.requirement) + except UnsupportedVersionError: + # XXX compat-mode if cannot read the version + logger.warning('could not read version %r - using name only', + req) + name = req.split()[0] + matcher = scheme.matcher(name) + + name = matcher.key # case-insensitive + + result = False + for p in self.provides: + p_name, p_ver = parse_name_and_version(p) + if p_name != name: + continue + try: + result = matcher.match(p_ver) + break + except UnsupportedVersionError: + pass + return result + + def __repr__(self): + """ + Return a textual representation of this instance, + """ + if self.source_url: + suffix = ' [%s]' % self.source_url + else: + suffix = '' + return '<Distribution %s (%s)%s>' % (self.name, self.version, suffix) + + def __eq__(self, other): + """ + See if this distribution is the same as another. + :param other: The distribution to compare with. To be equal to one + another. distributions must have the same type, name, + version and source_url. + :return: True if it is the same, else False. + """ + if type(other) is not type(self): + result = False + else: + result = (self.name == other.name and + self.version == other.version and + self.source_url == other.source_url) + return result + + def __hash__(self): + """ + Compute hash in a way which matches the equality test. + """ + return hash(self.name) + hash(self.version) + hash(self.source_url) + + +class BaseInstalledDistribution(Distribution): + """ + This is the base class for installed distributions (whether PEP 376 or + legacy). + """ + + hasher = None + + def __init__(self, metadata, path, env=None): + """ + Initialise an instance. + :param metadata: An instance of :class:`Metadata` which describes the + distribution. This will normally have been initialised + from a metadata file in the ``path``. + :param path: The path of the ``.dist-info`` or ``.egg-info`` + directory for the distribution. + :param env: This is normally the :class:`DistributionPath` + instance where this distribution was found. + """ + super(BaseInstalledDistribution, self).__init__(metadata) + self.path = path + self.dist_path = env + + def get_hash(self, data, hasher=None): + """ + Get the hash of some data, using a particular hash algorithm, if + specified. + + :param data: The data to be hashed. + :type data: bytes + :param hasher: The name of a hash implementation, supported by hashlib, + or ``None``. Examples of valid values are ``'sha1'``, + ``'sha224'``, ``'sha384'``, '``sha256'``, ``'md5'`` and + ``'sha512'``. If no hasher is specified, the ``hasher`` + attribute of the :class:`InstalledDistribution` instance + is used. If the hasher is determined to be ``None``, MD5 + is used as the hashing algorithm. + :returns: The hash of the data. If a hasher was explicitly specified, + the returned hash will be prefixed with the specified hasher + followed by '='. + :rtype: str + """ + if hasher is None: + hasher = self.hasher + if hasher is None: + hasher = hashlib.md5 + prefix = '' + else: + hasher = getattr(hashlib, hasher) + prefix = '%s=' % self.hasher + digest = hasher(data).digest() + digest = base64.urlsafe_b64encode(digest).rstrip(b'=').decode('ascii') + return '%s%s' % (prefix, digest) + + +class InstalledDistribution(BaseInstalledDistribution): + """ + Created with the *path* of the ``.dist-info`` directory provided to the + constructor. It reads the metadata contained in ``pydist.json`` when it is + instantiated., or uses a passed in Metadata instance (useful for when + dry-run mode is being used). + """ + + hasher = 'sha256' + + def __init__(self, path, metadata=None, env=None): + self.modules = [] + self.finder = finder = resources.finder_for_path(path) + if finder is None: + raise ValueError('finder unavailable for %s' % path) + if env and env._cache_enabled and path in env._cache.path: + metadata = env._cache.path[path].metadata + elif metadata is None: + r = finder.find(METADATA_FILENAME) + # Temporary - for Wheel 0.23 support + if r is None: + r = finder.find(WHEEL_METADATA_FILENAME) + # Temporary - for legacy support + if r is None: + r = finder.find('METADATA') + if r is None: + raise ValueError('no %s found in %s' % (METADATA_FILENAME, + path)) + with contextlib.closing(r.as_stream()) as stream: + metadata = Metadata(fileobj=stream, scheme='legacy') + + super(InstalledDistribution, self).__init__(metadata, path, env) + + if env and env._cache_enabled: + env._cache.add(self) + + r = finder.find('REQUESTED') + self.requested = r is not None + p = os.path.join(path, 'top_level.txt') + if os.path.exists(p): + with open(p, 'rb') as f: + data = f.read() + self.modules = data.splitlines() + + def __repr__(self): + return '<InstalledDistribution %r %s at %r>' % ( + self.name, self.version, self.path) + + def __str__(self): + return "%s %s" % (self.name, self.version) + + def _get_records(self): + """ + Get the list of installed files for the distribution + :return: A list of tuples of path, hash and size. Note that hash and + size might be ``None`` for some entries. The path is exactly + as stored in the file (which is as in PEP 376). + """ + results = [] + r = self.get_distinfo_resource('RECORD') + with contextlib.closing(r.as_stream()) as stream: + with CSVReader(stream=stream) as record_reader: + # Base location is parent dir of .dist-info dir + #base_location = os.path.dirname(self.path) + #base_location = os.path.abspath(base_location) + for row in record_reader: + missing = [None for i in range(len(row), 3)] + path, checksum, size = row + missing + #if not os.path.isabs(path): + # path = path.replace('/', os.sep) + # path = os.path.join(base_location, path) + results.append((path, checksum, size)) + return results + + @cached_property + def exports(self): + """ + Return the information exported by this distribution. + :return: A dictionary of exports, mapping an export category to a dict + of :class:`ExportEntry` instances describing the individual + export entries, and keyed by name. + """ + result = {} + r = self.get_distinfo_resource(EXPORTS_FILENAME) + if r: + result = self.read_exports() + return result + + def read_exports(self): + """ + Read exports data from a file in .ini format. + + :return: A dictionary of exports, mapping an export category to a list + of :class:`ExportEntry` instances describing the individual + export entries. + """ + result = {} + r = self.get_distinfo_resource(EXPORTS_FILENAME) + if r: + with contextlib.closing(r.as_stream()) as stream: + result = read_exports(stream) + return result + + def write_exports(self, exports): + """ + Write a dictionary of exports to a file in .ini format. + :param exports: A dictionary of exports, mapping an export category to + a list of :class:`ExportEntry` instances describing the + individual export entries. + """ + rf = self.get_distinfo_file(EXPORTS_FILENAME) + with open(rf, 'w') as f: + write_exports(exports, f) + + def get_resource_path(self, relative_path): + """ + NOTE: This API may change in the future. + + Return the absolute path to a resource file with the given relative + path. + + :param relative_path: The path, relative to .dist-info, of the resource + of interest. + :return: The absolute path where the resource is to be found. + """ + r = self.get_distinfo_resource('RESOURCES') + with contextlib.closing(r.as_stream()) as stream: + with CSVReader(stream=stream) as resources_reader: + for relative, destination in resources_reader: + if relative == relative_path: + return destination + raise KeyError('no resource file with relative path %r ' + 'is installed' % relative_path) + + def list_installed_files(self): + """ + Iterates over the ``RECORD`` entries and returns a tuple + ``(path, hash, size)`` for each line. + + :returns: iterator of (path, hash, size) + """ + for result in self._get_records(): + yield result + + def write_installed_files(self, paths, prefix, dry_run=False): + """ + Writes the ``RECORD`` file, using the ``paths`` iterable passed in. Any + existing ``RECORD`` file is silently overwritten. + + prefix is used to determine when to write absolute paths. + """ + prefix = os.path.join(prefix, '') + base = os.path.dirname(self.path) + base_under_prefix = base.startswith(prefix) + base = os.path.join(base, '') + record_path = self.get_distinfo_file('RECORD') + logger.info('creating %s', record_path) + if dry_run: + return None + with CSVWriter(record_path) as writer: + for path in paths: + if os.path.isdir(path) or path.endswith(('.pyc', '.pyo')): + # do not put size and hash, as in PEP-376 + hash_value = size = '' + else: + size = '%d' % os.path.getsize(path) + with open(path, 'rb') as fp: + hash_value = self.get_hash(fp.read()) + if path.startswith(base) or (base_under_prefix and + path.startswith(prefix)): + path = os.path.relpath(path, base) + writer.writerow((path, hash_value, size)) + + # add the RECORD file itself + if record_path.startswith(base): + record_path = os.path.relpath(record_path, base) + writer.writerow((record_path, '', '')) + return record_path + + def check_installed_files(self): + """ + Checks that the hashes and sizes of the files in ``RECORD`` are + matched by the files themselves. Returns a (possibly empty) list of + mismatches. Each entry in the mismatch list will be a tuple consisting + of the path, 'exists', 'size' or 'hash' according to what didn't match + (existence is checked first, then size, then hash), the expected + value and the actual value. + """ + mismatches = [] + base = os.path.dirname(self.path) + record_path = self.get_distinfo_file('RECORD') + for path, hash_value, size in self.list_installed_files(): + if not os.path.isabs(path): + path = os.path.join(base, path) + if path == record_path: + continue + if not os.path.exists(path): + mismatches.append((path, 'exists', True, False)) + elif os.path.isfile(path): + actual_size = str(os.path.getsize(path)) + if size and actual_size != size: + mismatches.append((path, 'size', size, actual_size)) + elif hash_value: + if '=' in hash_value: + hasher = hash_value.split('=', 1)[0] + else: + hasher = None + + with open(path, 'rb') as f: + actual_hash = self.get_hash(f.read(), hasher) + if actual_hash != hash_value: + mismatches.append((path, 'hash', hash_value, actual_hash)) + return mismatches + + @cached_property + def shared_locations(self): + """ + A dictionary of shared locations whose keys are in the set 'prefix', + 'purelib', 'platlib', 'scripts', 'headers', 'data' and 'namespace'. + The corresponding value is the absolute path of that category for + this distribution, and takes into account any paths selected by the + user at installation time (e.g. via command-line arguments). In the + case of the 'namespace' key, this would be a list of absolute paths + for the roots of namespace packages in this distribution. + + The first time this property is accessed, the relevant information is + read from the SHARED file in the .dist-info directory. + """ + result = {} + shared_path = os.path.join(self.path, 'SHARED') + if os.path.isfile(shared_path): + with codecs.open(shared_path, 'r', encoding='utf-8') as f: + lines = f.read().splitlines() + for line in lines: + key, value = line.split('=', 1) + if key == 'namespace': + result.setdefault(key, []).append(value) + else: + result[key] = value + return result + + def write_shared_locations(self, paths, dry_run=False): + """ + Write shared location information to the SHARED file in .dist-info. + :param paths: A dictionary as described in the documentation for + :meth:`shared_locations`. + :param dry_run: If True, the action is logged but no file is actually + written. + :return: The path of the file written to. + """ + shared_path = os.path.join(self.path, 'SHARED') + logger.info('creating %s', shared_path) + if dry_run: + return None + lines = [] + for key in ('prefix', 'lib', 'headers', 'scripts', 'data'): + path = paths[key] + if os.path.isdir(paths[key]): + lines.append('%s=%s' % (key, path)) + for ns in paths.get('namespace', ()): + lines.append('namespace=%s' % ns) + + with codecs.open(shared_path, 'w', encoding='utf-8') as f: + f.write('\n'.join(lines)) + return shared_path + + def get_distinfo_resource(self, path): + if path not in DIST_FILES: + raise DistlibException('invalid path for a dist-info file: ' + '%r at %r' % (path, self.path)) + finder = resources.finder_for_path(self.path) + if finder is None: + raise DistlibException('Unable to get a finder for %s' % self.path) + return finder.find(path) + + def get_distinfo_file(self, path): + """ + Returns a path located under the ``.dist-info`` directory. Returns a + string representing the path. + + :parameter path: a ``'/'``-separated path relative to the + ``.dist-info`` directory or an absolute path; + If *path* is an absolute path and doesn't start + with the ``.dist-info`` directory path, + a :class:`DistlibException` is raised + :type path: str + :rtype: str + """ + # Check if it is an absolute path # XXX use relpath, add tests + if path.find(os.sep) >= 0: + # it's an absolute path? + distinfo_dirname, path = path.split(os.sep)[-2:] + if distinfo_dirname != self.path.split(os.sep)[-1]: + raise DistlibException( + 'dist-info file %r does not belong to the %r %s ' + 'distribution' % (path, self.name, self.version)) + + # The file must be relative + if path not in DIST_FILES: + raise DistlibException('invalid path for a dist-info file: ' + '%r at %r' % (path, self.path)) + + return os.path.join(self.path, path) + + def list_distinfo_files(self): + """ + Iterates over the ``RECORD`` entries and returns paths for each line if + the path is pointing to a file located in the ``.dist-info`` directory + or one of its subdirectories. + + :returns: iterator of paths + """ + base = os.path.dirname(self.path) + for path, checksum, size in self._get_records(): + # XXX add separator or use real relpath algo + if not os.path.isabs(path): + path = os.path.join(base, path) + if path.startswith(self.path): + yield path + + def __eq__(self, other): + return (isinstance(other, InstalledDistribution) and + self.path == other.path) + + # See http://docs.python.org/reference/datamodel#object.__hash__ + __hash__ = object.__hash__ + + +class EggInfoDistribution(BaseInstalledDistribution): + """Created with the *path* of the ``.egg-info`` directory or file provided + to the constructor. It reads the metadata contained in the file itself, or + if the given path happens to be a directory, the metadata is read from the + file ``PKG-INFO`` under that directory.""" + + requested = True # as we have no way of knowing, assume it was + shared_locations = {} + + def __init__(self, path, env=None): + def set_name_and_version(s, n, v): + s.name = n + s.key = n.lower() # for case-insensitive comparisons + s.version = v + + self.path = path + self.dist_path = env + if env and env._cache_enabled and path in env._cache_egg.path: + metadata = env._cache_egg.path[path].metadata + set_name_and_version(self, metadata.name, metadata.version) + else: + metadata = self._get_metadata(path) + + # Need to be set before caching + set_name_and_version(self, metadata.name, metadata.version) + + if env and env._cache_enabled: + env._cache_egg.add(self) + super(EggInfoDistribution, self).__init__(metadata, path, env) + + def _get_metadata(self, path): + requires = None + + def parse_requires_data(data): + """Create a list of dependencies from a requires.txt file. + + *data*: the contents of a setuptools-produced requires.txt file. + """ + reqs = [] + lines = data.splitlines() + for line in lines: + line = line.strip() + if line.startswith('['): + logger.warning('Unexpected line: quitting requirement scan: %r', + line) + break + r = parse_requirement(line) + if not r: + logger.warning('Not recognised as a requirement: %r', line) + continue + if r.extras: + logger.warning('extra requirements in requires.txt are ' + 'not supported') + if not r.constraints: + reqs.append(r.name) + else: + cons = ', '.join('%s%s' % c for c in r.constraints) + reqs.append('%s (%s)' % (r.name, cons)) + return reqs + + def parse_requires_path(req_path): + """Create a list of dependencies from a requires.txt file. + + *req_path*: the path to a setuptools-produced requires.txt file. + """ + + reqs = [] + try: + with codecs.open(req_path, 'r', 'utf-8') as fp: + reqs = parse_requires_data(fp.read()) + except IOError: + pass + return reqs + + tl_path = tl_data = None + if path.endswith('.egg'): + if os.path.isdir(path): + p = os.path.join(path, 'EGG-INFO') + meta_path = os.path.join(p, 'PKG-INFO') + metadata = Metadata(path=meta_path, scheme='legacy') + req_path = os.path.join(p, 'requires.txt') + tl_path = os.path.join(p, 'top_level.txt') + requires = parse_requires_path(req_path) + else: + # FIXME handle the case where zipfile is not available + zipf = zipimport.zipimporter(path) + fileobj = StringIO( + zipf.get_data('EGG-INFO/PKG-INFO').decode('utf8')) + metadata = Metadata(fileobj=fileobj, scheme='legacy') + try: + data = zipf.get_data('EGG-INFO/requires.txt') + tl_data = zipf.get_data('EGG-INFO/top_level.txt').decode('utf-8') + requires = parse_requires_data(data.decode('utf-8')) + except IOError: + requires = None + elif path.endswith('.egg-info'): + if os.path.isdir(path): + req_path = os.path.join(path, 'requires.txt') + requires = parse_requires_path(req_path) + path = os.path.join(path, 'PKG-INFO') + tl_path = os.path.join(path, 'top_level.txt') + metadata = Metadata(path=path, scheme='legacy') + else: + raise DistlibException('path must end with .egg-info or .egg, ' + 'got %r' % path) + + if requires: + metadata.add_requirements(requires) + # look for top-level modules in top_level.txt, if present + if tl_data is None: + if tl_path is not None and os.path.exists(tl_path): + with open(tl_path, 'rb') as f: + tl_data = f.read().decode('utf-8') + if not tl_data: + tl_data = [] + else: + tl_data = tl_data.splitlines() + self.modules = tl_data + return metadata + + def __repr__(self): + return '<EggInfoDistribution %r %s at %r>' % ( + self.name, self.version, self.path) + + def __str__(self): + return "%s %s" % (self.name, self.version) + + def check_installed_files(self): + """ + Checks that the hashes and sizes of the files in ``RECORD`` are + matched by the files themselves. Returns a (possibly empty) list of + mismatches. Each entry in the mismatch list will be a tuple consisting + of the path, 'exists', 'size' or 'hash' according to what didn't match + (existence is checked first, then size, then hash), the expected + value and the actual value. + """ + mismatches = [] + record_path = os.path.join(self.path, 'installed-files.txt') + if os.path.exists(record_path): + for path, _, _ in self.list_installed_files(): + if path == record_path: + continue + if not os.path.exists(path): + mismatches.append((path, 'exists', True, False)) + return mismatches + + def list_installed_files(self): + """ + Iterates over the ``installed-files.txt`` entries and returns a tuple + ``(path, hash, size)`` for each line. + + :returns: a list of (path, hash, size) + """ + + def _md5(path): + f = open(path, 'rb') + try: + content = f.read() + finally: + f.close() + return hashlib.md5(content).hexdigest() + + def _size(path): + return os.stat(path).st_size + + record_path = os.path.join(self.path, 'installed-files.txt') + result = [] + if os.path.exists(record_path): + with codecs.open(record_path, 'r', encoding='utf-8') as f: + for line in f: + line = line.strip() + p = os.path.normpath(os.path.join(self.path, line)) + # "./" is present as a marker between installed files + # and installation metadata files + if not os.path.exists(p): + logger.warning('Non-existent file: %s', p) + if p.endswith(('.pyc', '.pyo')): + continue + #otherwise fall through and fail + if not os.path.isdir(p): + result.append((p, _md5(p), _size(p))) + result.append((record_path, None, None)) + return result + + def list_distinfo_files(self, absolute=False): + """ + Iterates over the ``installed-files.txt`` entries and returns paths for + each line if the path is pointing to a file located in the + ``.egg-info`` directory or one of its subdirectories. + + :parameter absolute: If *absolute* is ``True``, each returned path is + transformed into a local absolute path. Otherwise the + raw value from ``installed-files.txt`` is returned. + :type absolute: boolean + :returns: iterator of paths + """ + record_path = os.path.join(self.path, 'installed-files.txt') + if os.path.exists(record_path): + skip = True + with codecs.open(record_path, 'r', encoding='utf-8') as f: + for line in f: + line = line.strip() + if line == './': + skip = False + continue + if not skip: + p = os.path.normpath(os.path.join(self.path, line)) + if p.startswith(self.path): + if absolute: + yield p + else: + yield line + + def __eq__(self, other): + return (isinstance(other, EggInfoDistribution) and + self.path == other.path) + + # See http://docs.python.org/reference/datamodel#object.__hash__ + __hash__ = object.__hash__ + +new_dist_class = InstalledDistribution +old_dist_class = EggInfoDistribution + + +class DependencyGraph(object): + """ + Represents a dependency graph between distributions. + + The dependency relationships are stored in an ``adjacency_list`` that maps + distributions to a list of ``(other, label)`` tuples where ``other`` + is a distribution and the edge is labeled with ``label`` (i.e. the version + specifier, if such was provided). Also, for more efficient traversal, for + every distribution ``x``, a list of predecessors is kept in + ``reverse_list[x]``. An edge from distribution ``a`` to + distribution ``b`` means that ``a`` depends on ``b``. If any missing + dependencies are found, they are stored in ``missing``, which is a + dictionary that maps distributions to a list of requirements that were not + provided by any other distributions. + """ + + def __init__(self): + self.adjacency_list = {} + self.reverse_list = {} + self.missing = {} + + def add_distribution(self, distribution): + """Add the *distribution* to the graph. + + :type distribution: :class:`distutils2.database.InstalledDistribution` + or :class:`distutils2.database.EggInfoDistribution` + """ + self.adjacency_list[distribution] = [] + self.reverse_list[distribution] = [] + #self.missing[distribution] = [] + + def add_edge(self, x, y, label=None): + """Add an edge from distribution *x* to distribution *y* with the given + *label*. + + :type x: :class:`distutils2.database.InstalledDistribution` or + :class:`distutils2.database.EggInfoDistribution` + :type y: :class:`distutils2.database.InstalledDistribution` or + :class:`distutils2.database.EggInfoDistribution` + :type label: ``str`` or ``None`` + """ + self.adjacency_list[x].append((y, label)) + # multiple edges are allowed, so be careful + if x not in self.reverse_list[y]: + self.reverse_list[y].append(x) + + def add_missing(self, distribution, requirement): + """ + Add a missing *requirement* for the given *distribution*. + + :type distribution: :class:`distutils2.database.InstalledDistribution` + or :class:`distutils2.database.EggInfoDistribution` + :type requirement: ``str`` + """ + logger.debug('%s missing %r', distribution, requirement) + self.missing.setdefault(distribution, []).append(requirement) + + def _repr_dist(self, dist): + return '%s %s' % (dist.name, dist.version) + + def repr_node(self, dist, level=1): + """Prints only a subgraph""" + output = [self._repr_dist(dist)] + for other, label in self.adjacency_list[dist]: + dist = self._repr_dist(other) + if label is not None: + dist = '%s [%s]' % (dist, label) + output.append(' ' * level + str(dist)) + suboutput = self.repr_node(other, level + 1) + subs = suboutput.split('\n') + output.extend(subs[1:]) + return '\n'.join(output) + + def to_dot(self, f, skip_disconnected=True): + """Writes a DOT output for the graph to the provided file *f*. + + If *skip_disconnected* is set to ``True``, then all distributions + that are not dependent on any other distribution are skipped. + + :type f: has to support ``file``-like operations + :type skip_disconnected: ``bool`` + """ + disconnected = [] + + f.write("digraph dependencies {\n") + for dist, adjs in self.adjacency_list.items(): + if len(adjs) == 0 and not skip_disconnected: + disconnected.append(dist) + for other, label in adjs: + if not label is None: + f.write('"%s" -> "%s" [label="%s"]\n' % + (dist.name, other.name, label)) + else: + f.write('"%s" -> "%s"\n' % (dist.name, other.name)) + if not skip_disconnected and len(disconnected) > 0: + f.write('subgraph disconnected {\n') + f.write('label = "Disconnected"\n') + f.write('bgcolor = red\n') + + for dist in disconnected: + f.write('"%s"' % dist.name) + f.write('\n') + f.write('}\n') + f.write('}\n') + + def topological_sort(self): + """ + Perform a topological sort of the graph. + :return: A tuple, the first element of which is a topologically sorted + list of distributions, and the second element of which is a + list of distributions that cannot be sorted because they have + circular dependencies and so form a cycle. + """ + result = [] + # Make a shallow copy of the adjacency list + alist = {} + for k, v in self.adjacency_list.items(): + alist[k] = v[:] + while True: + # See what we can remove in this run + to_remove = [] + for k, v in list(alist.items())[:]: + if not v: + to_remove.append(k) + del alist[k] + if not to_remove: + # What's left in alist (if anything) is a cycle. + break + # Remove from the adjacency list of others + for k, v in alist.items(): + alist[k] = [(d, r) for d, r in v if d not in to_remove] + logger.debug('Moving to result: %s', + ['%s (%s)' % (d.name, d.version) for d in to_remove]) + result.extend(to_remove) + return result, list(alist.keys()) + + def __repr__(self): + """Representation of the graph""" + output = [] + for dist, adjs in self.adjacency_list.items(): + output.append(self.repr_node(dist)) + return '\n'.join(output) + + +def make_graph(dists, scheme='default'): + """Makes a dependency graph from the given distributions. + + :parameter dists: a list of distributions + :type dists: list of :class:`distutils2.database.InstalledDistribution` and + :class:`distutils2.database.EggInfoDistribution` instances + :rtype: a :class:`DependencyGraph` instance + """ + scheme = get_scheme(scheme) + graph = DependencyGraph() + provided = {} # maps names to lists of (version, dist) tuples + + # first, build the graph and find out what's provided + for dist in dists: + graph.add_distribution(dist) + + for p in dist.provides: + name, version = parse_name_and_version(p) + logger.debug('Add to provided: %s, %s, %s', name, version, dist) + provided.setdefault(name, []).append((version, dist)) + + # now make the edges + for dist in dists: + requires = (dist.run_requires | dist.meta_requires | + dist.build_requires | dist.dev_requires) + for req in requires: + try: + matcher = scheme.matcher(req) + except UnsupportedVersionError: + # XXX compat-mode if cannot read the version + logger.warning('could not read version %r - using name only', + req) + name = req.split()[0] + matcher = scheme.matcher(name) + + name = matcher.key # case-insensitive + + matched = False + if name in provided: + for version, provider in provided[name]: + try: + match = matcher.match(version) + except UnsupportedVersionError: + match = False + + if match: + graph.add_edge(dist, provider, req) + matched = True + break + if not matched: + graph.add_missing(dist, req) + return graph + + +def get_dependent_dists(dists, dist): + """Recursively generate a list of distributions from *dists* that are + dependent on *dist*. + + :param dists: a list of distributions + :param dist: a distribution, member of *dists* for which we are interested + """ + if dist not in dists: + raise DistlibException('given distribution %r is not a member ' + 'of the list' % dist.name) + graph = make_graph(dists) + + dep = [dist] # dependent distributions + todo = graph.reverse_list[dist] # list of nodes we should inspect + + while todo: + d = todo.pop() + dep.append(d) + for succ in graph.reverse_list[d]: + if succ not in dep: + todo.append(succ) + + dep.pop(0) # remove dist from dep, was there to prevent infinite loops + return dep + + +def get_required_dists(dists, dist): + """Recursively generate a list of distributions from *dists* that are + required by *dist*. + + :param dists: a list of distributions + :param dist: a distribution, member of *dists* for which we are interested + """ + if dist not in dists: + raise DistlibException('given distribution %r is not a member ' + 'of the list' % dist.name) + graph = make_graph(dists) + + req = [] # required distributions + todo = graph.adjacency_list[dist] # list of nodes we should inspect + + while todo: + d = todo.pop()[0] + req.append(d) + for pred in graph.adjacency_list[d]: + if pred not in req: + todo.append(pred) + + return req + + +def make_dist(name, version, **kwargs): + """ + A convenience method for making a dist given just a name and version. + """ + summary = kwargs.pop('summary', 'Placeholder for summary') + md = Metadata(**kwargs) + md.name = name + md.version = version + md.summary = summary or 'Placeholder for summary' + return Distribution(md) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/index.py b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/index.py new file mode 100644 index 0000000..2406be2 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/index.py @@ -0,0 +1,516 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +import hashlib +import logging +import os +import shutil +import subprocess +import tempfile +try: + from threading import Thread +except ImportError: + from dummy_threading import Thread + +from . import DistlibException +from .compat import (HTTPBasicAuthHandler, Request, HTTPPasswordMgr, + urlparse, build_opener, string_types) +from .util import cached_property, zip_dir, ServerProxy + +logger = logging.getLogger(__name__) + +DEFAULT_INDEX = 'https://pypi.python.org/pypi' +DEFAULT_REALM = 'pypi' + +class PackageIndex(object): + """ + This class represents a package index compatible with PyPI, the Python + Package Index. + """ + + boundary = b'----------ThIs_Is_tHe_distlib_index_bouNdaRY_$' + + def __init__(self, url=None): + """ + Initialise an instance. + + :param url: The URL of the index. If not specified, the URL for PyPI is + used. + """ + self.url = url or DEFAULT_INDEX + self.read_configuration() + scheme, netloc, path, params, query, frag = urlparse(self.url) + if params or query or frag or scheme not in ('http', 'https'): + raise DistlibException('invalid repository: %s' % self.url) + self.password_handler = None + self.ssl_verifier = None + self.gpg = None + self.gpg_home = None + with open(os.devnull, 'w') as sink: + # Use gpg by default rather than gpg2, as gpg2 insists on + # prompting for passwords + for s in ('gpg', 'gpg2'): + try: + rc = subprocess.check_call([s, '--version'], stdout=sink, + stderr=sink) + if rc == 0: + self.gpg = s + break + except OSError: + pass + + def _get_pypirc_command(self): + """ + Get the distutils command for interacting with PyPI configurations. + :return: the command. + """ + from distutils.core import Distribution + from distutils.config import PyPIRCCommand + d = Distribution() + return PyPIRCCommand(d) + + def read_configuration(self): + """ + Read the PyPI access configuration as supported by distutils, getting + PyPI to do the actual work. This populates ``username``, ``password``, + ``realm`` and ``url`` attributes from the configuration. + """ + # get distutils to do the work + c = self._get_pypirc_command() + c.repository = self.url + cfg = c._read_pypirc() + self.username = cfg.get('username') + self.password = cfg.get('password') + self.realm = cfg.get('realm', 'pypi') + self.url = cfg.get('repository', self.url) + + def save_configuration(self): + """ + Save the PyPI access configuration. You must have set ``username`` and + ``password`` attributes before calling this method. + + Again, distutils is used to do the actual work. + """ + self.check_credentials() + # get distutils to do the work + c = self._get_pypirc_command() + c._store_pypirc(self.username, self.password) + + def check_credentials(self): + """ + Check that ``username`` and ``password`` have been set, and raise an + exception if not. + """ + if self.username is None or self.password is None: + raise DistlibException('username and password must be set') + pm = HTTPPasswordMgr() + _, netloc, _, _, _, _ = urlparse(self.url) + pm.add_password(self.realm, netloc, self.username, self.password) + self.password_handler = HTTPBasicAuthHandler(pm) + + def register(self, metadata): + """ + Register a distribution on PyPI, using the provided metadata. + + :param metadata: A :class:`Metadata` instance defining at least a name + and version number for the distribution to be + registered. + :return: The HTTP response received from PyPI upon submission of the + request. + """ + self.check_credentials() + metadata.validate() + d = metadata.todict() + d[':action'] = 'verify' + request = self.encode_request(d.items(), []) + response = self.send_request(request) + d[':action'] = 'submit' + request = self.encode_request(d.items(), []) + return self.send_request(request) + + def _reader(self, name, stream, outbuf): + """ + Thread runner for reading lines of from a subprocess into a buffer. + + :param name: The logical name of the stream (used for logging only). + :param stream: The stream to read from. This will typically a pipe + connected to the output stream of a subprocess. + :param outbuf: The list to append the read lines to. + """ + while True: + s = stream.readline() + if not s: + break + s = s.decode('utf-8').rstrip() + outbuf.append(s) + logger.debug('%s: %s' % (name, s)) + stream.close() + + def get_sign_command(self, filename, signer, sign_password, + keystore=None): + """ + Return a suitable command for signing a file. + + :param filename: The pathname to the file to be signed. + :param signer: The identifier of the signer of the file. + :param sign_password: The passphrase for the signer's + private key used for signing. + :param keystore: The path to a directory which contains the keys + used in verification. If not specified, the + instance's ``gpg_home`` attribute is used instead. + :return: The signing command as a list suitable to be + passed to :class:`subprocess.Popen`. + """ + cmd = [self.gpg, '--status-fd', '2', '--no-tty'] + if keystore is None: + keystore = self.gpg_home + if keystore: + cmd.extend(['--homedir', keystore]) + if sign_password is not None: + cmd.extend(['--batch', '--passphrase-fd', '0']) + td = tempfile.mkdtemp() + sf = os.path.join(td, os.path.basename(filename) + '.asc') + cmd.extend(['--detach-sign', '--armor', '--local-user', + signer, '--output', sf, filename]) + logger.debug('invoking: %s', ' '.join(cmd)) + return cmd, sf + + def run_command(self, cmd, input_data=None): + """ + Run a command in a child process , passing it any input data specified. + + :param cmd: The command to run. + :param input_data: If specified, this must be a byte string containing + data to be sent to the child process. + :return: A tuple consisting of the subprocess' exit code, a list of + lines read from the subprocess' ``stdout``, and a list of + lines read from the subprocess' ``stderr``. + """ + kwargs = { + 'stdout': subprocess.PIPE, + 'stderr': subprocess.PIPE, + } + if input_data is not None: + kwargs['stdin'] = subprocess.PIPE + stdout = [] + stderr = [] + p = subprocess.Popen(cmd, **kwargs) + # We don't use communicate() here because we may need to + # get clever with interacting with the command + t1 = Thread(target=self._reader, args=('stdout', p.stdout, stdout)) + t1.start() + t2 = Thread(target=self._reader, args=('stderr', p.stderr, stderr)) + t2.start() + if input_data is not None: + p.stdin.write(input_data) + p.stdin.close() + + p.wait() + t1.join() + t2.join() + return p.returncode, stdout, stderr + + def sign_file(self, filename, signer, sign_password, keystore=None): + """ + Sign a file. + + :param filename: The pathname to the file to be signed. + :param signer: The identifier of the signer of the file. + :param sign_password: The passphrase for the signer's + private key used for signing. + :param keystore: The path to a directory which contains the keys + used in signing. If not specified, the instance's + ``gpg_home`` attribute is used instead. + :return: The absolute pathname of the file where the signature is + stored. + """ + cmd, sig_file = self.get_sign_command(filename, signer, sign_password, + keystore) + rc, stdout, stderr = self.run_command(cmd, + sign_password.encode('utf-8')) + if rc != 0: + raise DistlibException('sign command failed with error ' + 'code %s' % rc) + return sig_file + + def upload_file(self, metadata, filename, signer=None, sign_password=None, + filetype='sdist', pyversion='source', keystore=None): + """ + Upload a release file to the index. + + :param metadata: A :class:`Metadata` instance defining at least a name + and version number for the file to be uploaded. + :param filename: The pathname of the file to be uploaded. + :param signer: The identifier of the signer of the file. + :param sign_password: The passphrase for the signer's + private key used for signing. + :param filetype: The type of the file being uploaded. This is the + distutils command which produced that file, e.g. + ``sdist`` or ``bdist_wheel``. + :param pyversion: The version of Python which the release relates + to. For code compatible with any Python, this would + be ``source``, otherwise it would be e.g. ``3.2``. + :param keystore: The path to a directory which contains the keys + used in signing. If not specified, the instance's + ``gpg_home`` attribute is used instead. + :return: The HTTP response received from PyPI upon submission of the + request. + """ + self.check_credentials() + if not os.path.exists(filename): + raise DistlibException('not found: %s' % filename) + metadata.validate() + d = metadata.todict() + sig_file = None + if signer: + if not self.gpg: + logger.warning('no signing program available - not signed') + else: + sig_file = self.sign_file(filename, signer, sign_password, + keystore) + with open(filename, 'rb') as f: + file_data = f.read() + md5_digest = hashlib.md5(file_data).hexdigest() + sha256_digest = hashlib.sha256(file_data).hexdigest() + d.update({ + ':action': 'file_upload', + 'protocol_version': '1', + 'filetype': filetype, + 'pyversion': pyversion, + 'md5_digest': md5_digest, + 'sha256_digest': sha256_digest, + }) + files = [('content', os.path.basename(filename), file_data)] + if sig_file: + with open(sig_file, 'rb') as f: + sig_data = f.read() + files.append(('gpg_signature', os.path.basename(sig_file), + sig_data)) + shutil.rmtree(os.path.dirname(sig_file)) + request = self.encode_request(d.items(), files) + return self.send_request(request) + + def upload_documentation(self, metadata, doc_dir): + """ + Upload documentation to the index. + + :param metadata: A :class:`Metadata` instance defining at least a name + and version number for the documentation to be + uploaded. + :param doc_dir: The pathname of the directory which contains the + documentation. This should be the directory that + contains the ``index.html`` for the documentation. + :return: The HTTP response received from PyPI upon submission of the + request. + """ + self.check_credentials() + if not os.path.isdir(doc_dir): + raise DistlibException('not a directory: %r' % doc_dir) + fn = os.path.join(doc_dir, 'index.html') + if not os.path.exists(fn): + raise DistlibException('not found: %r' % fn) + metadata.validate() + name, version = metadata.name, metadata.version + zip_data = zip_dir(doc_dir).getvalue() + fields = [(':action', 'doc_upload'), + ('name', name), ('version', version)] + files = [('content', name, zip_data)] + request = self.encode_request(fields, files) + return self.send_request(request) + + def get_verify_command(self, signature_filename, data_filename, + keystore=None): + """ + Return a suitable command for verifying a file. + + :param signature_filename: The pathname to the file containing the + signature. + :param data_filename: The pathname to the file containing the + signed data. + :param keystore: The path to a directory which contains the keys + used in verification. If not specified, the + instance's ``gpg_home`` attribute is used instead. + :return: The verifying command as a list suitable to be + passed to :class:`subprocess.Popen`. + """ + cmd = [self.gpg, '--status-fd', '2', '--no-tty'] + if keystore is None: + keystore = self.gpg_home + if keystore: + cmd.extend(['--homedir', keystore]) + cmd.extend(['--verify', signature_filename, data_filename]) + logger.debug('invoking: %s', ' '.join(cmd)) + return cmd + + def verify_signature(self, signature_filename, data_filename, + keystore=None): + """ + Verify a signature for a file. + + :param signature_filename: The pathname to the file containing the + signature. + :param data_filename: The pathname to the file containing the + signed data. + :param keystore: The path to a directory which contains the keys + used in verification. If not specified, the + instance's ``gpg_home`` attribute is used instead. + :return: True if the signature was verified, else False. + """ + if not self.gpg: + raise DistlibException('verification unavailable because gpg ' + 'unavailable') + cmd = self.get_verify_command(signature_filename, data_filename, + keystore) + rc, stdout, stderr = self.run_command(cmd) + if rc not in (0, 1): + raise DistlibException('verify command failed with error ' + 'code %s' % rc) + return rc == 0 + + def download_file(self, url, destfile, digest=None, reporthook=None): + """ + This is a convenience method for downloading a file from an URL. + Normally, this will be a file from the index, though currently + no check is made for this (i.e. a file can be downloaded from + anywhere). + + The method is just like the :func:`urlretrieve` function in the + standard library, except that it allows digest computation to be + done during download and checking that the downloaded data + matched any expected value. + + :param url: The URL of the file to be downloaded (assumed to be + available via an HTTP GET request). + :param destfile: The pathname where the downloaded file is to be + saved. + :param digest: If specified, this must be a (hasher, value) + tuple, where hasher is the algorithm used (e.g. + ``'md5'``) and ``value`` is the expected value. + :param reporthook: The same as for :func:`urlretrieve` in the + standard library. + """ + if digest is None: + digester = None + logger.debug('No digest specified') + else: + if isinstance(digest, (list, tuple)): + hasher, digest = digest + else: + hasher = 'md5' + digester = getattr(hashlib, hasher)() + logger.debug('Digest specified: %s' % digest) + # The following code is equivalent to urlretrieve. + # We need to do it this way so that we can compute the + # digest of the file as we go. + with open(destfile, 'wb') as dfp: + # addinfourl is not a context manager on 2.x + # so we have to use try/finally + sfp = self.send_request(Request(url)) + try: + headers = sfp.info() + blocksize = 8192 + size = -1 + read = 0 + blocknum = 0 + if "content-length" in headers: + size = int(headers["Content-Length"]) + if reporthook: + reporthook(blocknum, blocksize, size) + while True: + block = sfp.read(blocksize) + if not block: + break + read += len(block) + dfp.write(block) + if digester: + digester.update(block) + blocknum += 1 + if reporthook: + reporthook(blocknum, blocksize, size) + finally: + sfp.close() + + # check that we got the whole file, if we can + if size >= 0 and read < size: + raise DistlibException( + 'retrieval incomplete: got only %d out of %d bytes' + % (read, size)) + # if we have a digest, it must match. + if digester: + actual = digester.hexdigest() + if digest != actual: + raise DistlibException('%s digest mismatch for %s: expected ' + '%s, got %s' % (hasher, destfile, + digest, actual)) + logger.debug('Digest verified: %s', digest) + + def send_request(self, req): + """ + Send a standard library :class:`Request` to PyPI and return its + response. + + :param req: The request to send. + :return: The HTTP response from PyPI (a standard library HTTPResponse). + """ + handlers = [] + if self.password_handler: + handlers.append(self.password_handler) + if self.ssl_verifier: + handlers.append(self.ssl_verifier) + opener = build_opener(*handlers) + return opener.open(req) + + def encode_request(self, fields, files): + """ + Encode fields and files for posting to an HTTP server. + + :param fields: The fields to send as a list of (fieldname, value) + tuples. + :param files: The files to send as a list of (fieldname, filename, + file_bytes) tuple. + """ + # Adapted from packaging, which in turn was adapted from + # http://code.activestate.com/recipes/146306 + + parts = [] + boundary = self.boundary + for k, values in fields: + if not isinstance(values, (list, tuple)): + values = [values] + + for v in values: + parts.extend(( + b'--' + boundary, + ('Content-Disposition: form-data; name="%s"' % + k).encode('utf-8'), + b'', + v.encode('utf-8'))) + for key, filename, value in files: + parts.extend(( + b'--' + boundary, + ('Content-Disposition: form-data; name="%s"; filename="%s"' % + (key, filename)).encode('utf-8'), + b'', + value)) + + parts.extend((b'--' + boundary + b'--', b'')) + + body = b'\r\n'.join(parts) + ct = b'multipart/form-data; boundary=' + boundary + headers = { + 'Content-type': ct, + 'Content-length': str(len(body)) + } + return Request(self.url, body, headers) + + def search(self, terms, operator=None): + if isinstance(terms, string_types): + terms = {'name': terms} + rpc_proxy = ServerProxy(self.url, timeout=3.0) + try: + return rpc_proxy.search(terms, operator or 'and') + finally: + rpc_proxy('close')() diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/locators.py b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/locators.py new file mode 100644 index 0000000..11d2636 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/locators.py @@ -0,0 +1,1292 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2015 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# + +import gzip +from io import BytesIO +import json +import logging +import os +import posixpath +import re +try: + import threading +except ImportError: # pragma: no cover + import dummy_threading as threading +import zlib + +from . import DistlibException +from .compat import (urljoin, urlparse, urlunparse, url2pathname, pathname2url, + queue, quote, unescape, string_types, build_opener, + HTTPRedirectHandler as BaseRedirectHandler, text_type, + Request, HTTPError, URLError) +from .database import Distribution, DistributionPath, make_dist +from .metadata import Metadata, MetadataInvalidError +from .util import (cached_property, parse_credentials, ensure_slash, + split_filename, get_project_data, parse_requirement, + parse_name_and_version, ServerProxy, normalize_name) +from .version import get_scheme, UnsupportedVersionError +from .wheel import Wheel, is_compatible + +logger = logging.getLogger(__name__) + +HASHER_HASH = re.compile(r'^(\w+)=([a-f0-9]+)') +CHARSET = re.compile(r';\s*charset\s*=\s*(.*)\s*$', re.I) +HTML_CONTENT_TYPE = re.compile('text/html|application/x(ht)?ml') +DEFAULT_INDEX = 'https://pypi.python.org/pypi' + +def get_all_distribution_names(url=None): + """ + Return all distribution names known by an index. + :param url: The URL of the index. + :return: A list of all known distribution names. + """ + if url is None: + url = DEFAULT_INDEX + client = ServerProxy(url, timeout=3.0) + try: + return client.list_packages() + finally: + client('close')() + +class RedirectHandler(BaseRedirectHandler): + """ + A class to work around a bug in some Python 3.2.x releases. + """ + # There's a bug in the base version for some 3.2.x + # (e.g. 3.2.2 on Ubuntu Oneiric). If a Location header + # returns e.g. /abc, it bails because it says the scheme '' + # is bogus, when actually it should use the request's + # URL for the scheme. See Python issue #13696. + def http_error_302(self, req, fp, code, msg, headers): + # Some servers (incorrectly) return multiple Location headers + # (so probably same goes for URI). Use first header. + newurl = None + for key in ('location', 'uri'): + if key in headers: + newurl = headers[key] + break + if newurl is None: # pragma: no cover + return + urlparts = urlparse(newurl) + if urlparts.scheme == '': + newurl = urljoin(req.get_full_url(), newurl) + if hasattr(headers, 'replace_header'): + headers.replace_header(key, newurl) + else: + headers[key] = newurl + return BaseRedirectHandler.http_error_302(self, req, fp, code, msg, + headers) + + http_error_301 = http_error_303 = http_error_307 = http_error_302 + +class Locator(object): + """ + A base class for locators - things that locate distributions. + """ + source_extensions = ('.tar.gz', '.tar.bz2', '.tar', '.zip', '.tgz', '.tbz') + binary_extensions = ('.egg', '.exe', '.whl') + excluded_extensions = ('.pdf',) + + # A list of tags indicating which wheels you want to match. The default + # value of None matches against the tags compatible with the running + # Python. If you want to match other values, set wheel_tags on a locator + # instance to a list of tuples (pyver, abi, arch) which you want to match. + wheel_tags = None + + downloadable_extensions = source_extensions + ('.whl',) + + def __init__(self, scheme='default'): + """ + Initialise an instance. + :param scheme: Because locators look for most recent versions, they + need to know the version scheme to use. This specifies + the current PEP-recommended scheme - use ``'legacy'`` + if you need to support existing distributions on PyPI. + """ + self._cache = {} + self.scheme = scheme + # Because of bugs in some of the handlers on some of the platforms, + # we use our own opener rather than just using urlopen. + self.opener = build_opener(RedirectHandler()) + # If get_project() is called from locate(), the matcher instance + # is set from the requirement passed to locate(). See issue #18 for + # why this can be useful to know. + self.matcher = None + self.errors = queue.Queue() + + def get_errors(self): + """ + Return any errors which have occurred. + """ + result = [] + while not self.errors.empty(): # pragma: no cover + try: + e = self.errors.get(False) + result.append(e) + except self.errors.Empty: + continue + self.errors.task_done() + return result + + def clear_errors(self): + """ + Clear any errors which may have been logged. + """ + # Just get the errors and throw them away + self.get_errors() + + def clear_cache(self): + self._cache.clear() + + def _get_scheme(self): + return self._scheme + + def _set_scheme(self, value): + self._scheme = value + + scheme = property(_get_scheme, _set_scheme) + + def _get_project(self, name): + """ + For a given project, get a dictionary mapping available versions to Distribution + instances. + + This should be implemented in subclasses. + + If called from a locate() request, self.matcher will be set to a + matcher for the requirement to satisfy, otherwise it will be None. + """ + raise NotImplementedError('Please implement in the subclass') + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + raise NotImplementedError('Please implement in the subclass') + + def get_project(self, name): + """ + For a given project, get a dictionary mapping available versions to Distribution + instances. + + This calls _get_project to do all the work, and just implements a caching layer on top. + """ + if self._cache is None: # pragma: no cover + result = self._get_project(name) + elif name in self._cache: + result = self._cache[name] + else: + self.clear_errors() + result = self._get_project(name) + self._cache[name] = result + return result + + def score_url(self, url): + """ + Give an url a score which can be used to choose preferred URLs + for a given project release. + """ + t = urlparse(url) + basename = posixpath.basename(t.path) + compatible = True + is_wheel = basename.endswith('.whl') + is_downloadable = basename.endswith(self.downloadable_extensions) + if is_wheel: + compatible = is_compatible(Wheel(basename), self.wheel_tags) + return (t.scheme == 'https', 'pypi.python.org' in t.netloc, + is_downloadable, is_wheel, compatible, basename) + + def prefer_url(self, url1, url2): + """ + Choose one of two URLs where both are candidates for distribution + archives for the same version of a distribution (for example, + .tar.gz vs. zip). + + The current implementation favours https:// URLs over http://, archives + from PyPI over those from other locations, wheel compatibility (if a + wheel) and then the archive name. + """ + result = url2 + if url1: + s1 = self.score_url(url1) + s2 = self.score_url(url2) + if s1 > s2: + result = url1 + if result != url2: + logger.debug('Not replacing %r with %r', url1, url2) + else: + logger.debug('Replacing %r with %r', url1, url2) + return result + + def split_filename(self, filename, project_name): + """ + Attempt to split a filename in project name, version and Python version. + """ + return split_filename(filename, project_name) + + def convert_url_to_download_info(self, url, project_name): + """ + See if a URL is a candidate for a download URL for a project (the URL + has typically been scraped from an HTML page). + + If it is, a dictionary is returned with keys "name", "version", + "filename" and "url"; otherwise, None is returned. + """ + def same_project(name1, name2): + return normalize_name(name1) == normalize_name(name2) + + result = None + scheme, netloc, path, params, query, frag = urlparse(url) + if frag.lower().startswith('egg='): # pragma: no cover + logger.debug('%s: version hint in fragment: %r', + project_name, frag) + m = HASHER_HASH.match(frag) + if m: + algo, digest = m.groups() + else: + algo, digest = None, None + origpath = path + if path and path[-1] == '/': # pragma: no cover + path = path[:-1] + if path.endswith('.whl'): + try: + wheel = Wheel(path) + if is_compatible(wheel, self.wheel_tags): + if project_name is None: + include = True + else: + include = same_project(wheel.name, project_name) + if include: + result = { + 'name': wheel.name, + 'version': wheel.version, + 'filename': wheel.filename, + 'url': urlunparse((scheme, netloc, origpath, + params, query, '')), + 'python-version': ', '.join( + ['.'.join(list(v[2:])) for v in wheel.pyver]), + } + except Exception as e: # pragma: no cover + logger.warning('invalid path for wheel: %s', path) + elif not path.endswith(self.downloadable_extensions): # pragma: no cover + logger.debug('Not downloadable: %s', path) + else: # downloadable extension + path = filename = posixpath.basename(path) + for ext in self.downloadable_extensions: + if path.endswith(ext): + path = path[:-len(ext)] + t = self.split_filename(path, project_name) + if not t: # pragma: no cover + logger.debug('No match for project/version: %s', path) + else: + name, version, pyver = t + if not project_name or same_project(project_name, name): + result = { + 'name': name, + 'version': version, + 'filename': filename, + 'url': urlunparse((scheme, netloc, origpath, + params, query, '')), + #'packagetype': 'sdist', + } + if pyver: # pragma: no cover + result['python-version'] = pyver + break + if result and algo: + result['%s_digest' % algo] = digest + return result + + def _get_digest(self, info): + """ + Get a digest from a dictionary by looking at 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 + return result + + def _update_version_data(self, result, info): + """ + Update a result dictionary (the final result from _get_project) with a + dictionary for a specific version, which typically holds information + gleaned from a filename or URL for an archive for the distribution. + """ + name = info.pop('name') + version = info.pop('version') + if version in result: + dist = result[version] + md = dist.metadata + else: + dist = make_dist(name, version, scheme=self.scheme) + md = dist.metadata + dist.digest = digest = self._get_digest(info) + url = info['url'] + result['digests'][url] = digest + if md.source_url != info['url']: + md.source_url = self.prefer_url(md.source_url, url) + result['urls'].setdefault(version, set()).add(url) + dist.locator = self + result[version] = dist + + def locate(self, requirement, prereleases=False): + """ + Find the most recent distribution which matches the given + requirement. + + :param requirement: A requirement of the form 'foo (1.0)' or perhaps + 'foo (>= 1.0, < 2.0, != 1.3)' + :param prereleases: If ``True``, allow pre-release versions + to be located. Otherwise, pre-release versions + are not returned. + :return: A :class:`Distribution` instance, or ``None`` if no such + distribution could be located. + """ + result = None + r = parse_requirement(requirement) + if r is None: # pragma: no cover + raise DistlibException('Not a valid requirement: %r' % requirement) + scheme = get_scheme(self.scheme) + self.matcher = matcher = scheme.matcher(r.requirement) + logger.debug('matcher: %s (%s)', matcher, type(matcher).__name__) + versions = self.get_project(r.name) + if len(versions) > 2: # urls and digests keys are present + # sometimes, versions are invalid + slist = [] + vcls = matcher.version_class + for k in versions: + if k in ('urls', 'digests'): + continue + try: + if not matcher.match(k): + logger.debug('%s did not match %r', matcher, k) + else: + if prereleases or not vcls(k).is_prerelease: + slist.append(k) + else: + logger.debug('skipping pre-release ' + 'version %s of %s', k, matcher.name) + except Exception: # pragma: no cover + logger.warning('error matching %s with %r', matcher, k) + pass # slist.append(k) + if len(slist) > 1: + slist = sorted(slist, key=scheme.key) + if slist: + logger.debug('sorted list: %s', slist) + version = slist[-1] + result = versions[version] + if result: + if r.extras: + result.extras = r.extras + result.download_urls = versions.get('urls', {}).get(version, set()) + d = {} + sd = versions.get('digests', {}) + for url in result.download_urls: + if url in sd: # pragma: no cover + d[url] = sd[url] + result.digests = d + self.matcher = None + return result + + +class PyPIRPCLocator(Locator): + """ + This locator uses XML-RPC to locate distributions. It therefore + cannot be used with simple mirrors (that only mirror file content). + """ + def __init__(self, url, **kwargs): + """ + Initialise an instance. + + :param url: The URL to use for XML-RPC. + :param kwargs: Passed to the superclass constructor. + """ + super(PyPIRPCLocator, self).__init__(**kwargs) + self.base_url = url + self.client = ServerProxy(url, timeout=3.0) + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + return set(self.client.list_packages()) + + def _get_project(self, name): + result = {'urls': {}, 'digests': {}} + versions = self.client.package_releases(name, True) + for v in versions: + urls = self.client.release_urls(name, v) + data = self.client.release_data(name, v) + metadata = Metadata(scheme=self.scheme) + metadata.name = data['name'] + metadata.version = data['version'] + metadata.license = data.get('license') + metadata.keywords = data.get('keywords', []) + metadata.summary = data.get('summary') + dist = Distribution(metadata) + if urls: + info = urls[0] + metadata.source_url = info['url'] + dist.digest = self._get_digest(info) + dist.locator = self + result[v] = dist + for info in urls: + url = info['url'] + digest = self._get_digest(info) + result['urls'].setdefault(v, set()).add(url) + result['digests'][url] = digest + return result + +class PyPIJSONLocator(Locator): + """ + This locator uses PyPI's JSON interface. It's very limited in functionality + and probably not worth using. + """ + def __init__(self, url, **kwargs): + super(PyPIJSONLocator, self).__init__(**kwargs) + self.base_url = ensure_slash(url) + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + raise NotImplementedError('Not available from this locator') + + def _get_project(self, name): + result = {'urls': {}, 'digests': {}} + url = urljoin(self.base_url, '%s/json' % quote(name)) + try: + resp = self.opener.open(url) + data = resp.read().decode() # for now + d = json.loads(data) + md = Metadata(scheme=self.scheme) + data = d['info'] + md.name = data['name'] + md.version = data['version'] + md.license = data.get('license') + md.keywords = data.get('keywords', []) + md.summary = data.get('summary') + dist = Distribution(md) + dist.locator = self + urls = d['urls'] + result[md.version] = dist + for info in d['urls']: + url = info['url'] + dist.download_urls.add(url) + dist.digests[url] = self._get_digest(info) + result['urls'].setdefault(md.version, set()).add(url) + result['digests'][url] = self._get_digest(info) + # Now get other releases + for version, infos in d['releases'].items(): + if version == md.version: + continue # already done + omd = Metadata(scheme=self.scheme) + omd.name = md.name + omd.version = version + odist = Distribution(omd) + odist.locator = self + result[version] = odist + for info in infos: + url = info['url'] + odist.download_urls.add(url) + odist.digests[url] = self._get_digest(info) + result['urls'].setdefault(version, set()).add(url) + result['digests'][url] = self._get_digest(info) +# for info in urls: +# md.source_url = info['url'] +# dist.digest = self._get_digest(info) +# dist.locator = self +# for info in urls: +# url = info['url'] +# result['urls'].setdefault(md.version, set()).add(url) +# result['digests'][url] = self._get_digest(info) + except Exception as e: + self.errors.put(text_type(e)) + logger.exception('JSON fetch failed: %s', e) + return result + + +class Page(object): + """ + This class represents a scraped HTML page. + """ + # The following slightly hairy-looking regex just looks for the contents of + # an anchor link, which has an attribute "href" either immediately preceded + # or immediately followed by a "rel" attribute. The attribute values can be + # declared with double quotes, single quotes or no quotes - which leads to + # the length of the expression. + _href = re.compile(""" +(rel\\s*=\\s*(?:"(?P<rel1>[^"]*)"|'(?P<rel2>[^']*)'|(?P<rel3>[^>\\s\n]*))\\s+)? +href\\s*=\\s*(?:"(?P<url1>[^"]*)"|'(?P<url2>[^']*)'|(?P<url3>[^>\\s\n]*)) +(\\s+rel\\s*=\\s*(?:"(?P<rel4>[^"]*)"|'(?P<rel5>[^']*)'|(?P<rel6>[^>\\s\n]*)))? +""", re.I | re.S | re.X) + _base = re.compile(r"""<base\s+href\s*=\s*['"]?([^'">]+)""", re.I | re.S) + + def __init__(self, data, url): + """ + Initialise an instance with the Unicode page contents and the URL they + came from. + """ + self.data = data + self.base_url = self.url = url + m = self._base.search(self.data) + if m: + self.base_url = m.group(1) + + _clean_re = re.compile(r'[^a-z0-9$&+,/:;=?@.#%_\\|-]', re.I) + + @cached_property + def links(self): + """ + Return the URLs of all the links on a page together with information + about their "rel" attribute, for determining which ones to treat as + downloads and which ones to queue for further scraping. + """ + def clean(url): + "Tidy up an URL." + scheme, netloc, path, params, query, frag = urlparse(url) + return urlunparse((scheme, netloc, quote(path), + params, query, frag)) + + result = set() + for match in self._href.finditer(self.data): + d = match.groupdict('') + rel = (d['rel1'] or d['rel2'] or d['rel3'] or + d['rel4'] or d['rel5'] or d['rel6']) + url = d['url1'] or d['url2'] or d['url3'] + url = urljoin(self.base_url, url) + url = unescape(url) + url = self._clean_re.sub(lambda m: '%%%2x' % ord(m.group(0)), url) + result.add((url, rel)) + # We sort the result, hoping to bring the most recent versions + # to the front + result = sorted(result, key=lambda t: t[0], reverse=True) + return result + + +class SimpleScrapingLocator(Locator): + """ + A locator which scrapes HTML pages to locate downloads for a distribution. + This runs multiple threads to do the I/O; performance is at least as good + as pip's PackageFinder, which works in an analogous fashion. + """ + + # These are used to deal with various Content-Encoding schemes. + decoders = { + 'deflate': zlib.decompress, + 'gzip': lambda b: gzip.GzipFile(fileobj=BytesIO(d)).read(), + 'none': lambda b: b, + } + + def __init__(self, url, timeout=None, num_workers=10, **kwargs): + """ + Initialise an instance. + :param url: The root URL to use for scraping. + :param timeout: The timeout, in seconds, to be applied to requests. + This defaults to ``None`` (no timeout specified). + :param num_workers: The number of worker threads you want to do I/O, + This defaults to 10. + :param kwargs: Passed to the superclass. + """ + super(SimpleScrapingLocator, self).__init__(**kwargs) + self.base_url = ensure_slash(url) + self.timeout = timeout + self._page_cache = {} + self._seen = set() + self._to_fetch = queue.Queue() + self._bad_hosts = set() + self.skip_externals = False + self.num_workers = num_workers + self._lock = threading.RLock() + # See issue #45: we need to be resilient when the locator is used + # in a thread, e.g. with concurrent.futures. We can't use self._lock + # as it is for coordinating our internal threads - the ones created + # in _prepare_threads. + self._gplock = threading.RLock() + + def _prepare_threads(self): + """ + Threads are created only when get_project is called, and terminate + before it returns. They are there primarily to parallelise I/O (i.e. + fetching web pages). + """ + self._threads = [] + for i in range(self.num_workers): + t = threading.Thread(target=self._fetch) + t.setDaemon(True) + t.start() + self._threads.append(t) + + def _wait_threads(self): + """ + Tell all the threads to terminate (by sending a sentinel value) and + wait for them to do so. + """ + # Note that you need two loops, since you can't say which + # thread will get each sentinel + for t in self._threads: + self._to_fetch.put(None) # sentinel + for t in self._threads: + t.join() + self._threads = [] + + def _get_project(self, name): + result = {'urls': {}, 'digests': {}} + with self._gplock: + self.result = result + self.project_name = name + url = urljoin(self.base_url, '%s/' % quote(name)) + self._seen.clear() + self._page_cache.clear() + self._prepare_threads() + try: + logger.debug('Queueing %s', url) + self._to_fetch.put(url) + self._to_fetch.join() + finally: + self._wait_threads() + del self.result + return result + + platform_dependent = re.compile(r'\b(linux-(i\d86|x86_64|arm\w+)|' + r'win(32|-amd64)|macosx-?\d+)\b', re.I) + + def _is_platform_dependent(self, url): + """ + Does an URL refer to a platform-specific download? + """ + return self.platform_dependent.search(url) + + def _process_download(self, url): + """ + See if an URL is a suitable download for a project. + + If it is, register information in the result dictionary (for + _get_project) about the specific version it's for. + + Note that the return value isn't actually used other than as a boolean + value. + """ + if self._is_platform_dependent(url): + info = None + else: + info = self.convert_url_to_download_info(url, self.project_name) + logger.debug('process_download: %s -> %s', url, info) + if info: + with self._lock: # needed because self.result is shared + self._update_version_data(self.result, info) + return info + + def _should_queue(self, link, referrer, rel): + """ + Determine whether a link URL from a referring page and with a + particular "rel" attribute should be queued for scraping. + """ + scheme, netloc, path, _, _, _ = urlparse(link) + if path.endswith(self.source_extensions + self.binary_extensions + + self.excluded_extensions): + result = False + elif self.skip_externals and not link.startswith(self.base_url): + result = False + elif not referrer.startswith(self.base_url): + result = False + elif rel not in ('homepage', 'download'): + result = False + elif scheme not in ('http', 'https', 'ftp'): + result = False + elif self._is_platform_dependent(link): + result = False + else: + host = netloc.split(':', 1)[0] + if host.lower() == 'localhost': + result = False + else: + result = True + logger.debug('should_queue: %s (%s) from %s -> %s', link, rel, + referrer, result) + return result + + def _fetch(self): + """ + Get a URL to fetch from the work queue, get the HTML page, examine its + links for download candidates and candidates for further scraping. + + This is a handy method to run in a thread. + """ + while True: + url = self._to_fetch.get() + try: + if url: + page = self.get_page(url) + if page is None: # e.g. after an error + continue + for link, rel in page.links: + if link not in self._seen: + try: + self._seen.add(link) + if (not self._process_download(link) and + self._should_queue(link, url, rel)): + logger.debug('Queueing %s from %s', link, url) + self._to_fetch.put(link) + except MetadataInvalidError: # e.g. invalid versions + pass + except Exception as e: # pragma: no cover + self.errors.put(text_type(e)) + finally: + # always do this, to avoid hangs :-) + self._to_fetch.task_done() + if not url: + #logger.debug('Sentinel seen, quitting.') + break + + def get_page(self, url): + """ + Get the HTML for an URL, possibly from an in-memory cache. + + XXX TODO Note: this cache is never actually cleared. It's assumed that + the data won't get stale over the lifetime of a locator instance (not + necessarily true for the default_locator). + """ + # http://peak.telecommunity.com/DevCenter/EasyInstall#package-index-api + scheme, netloc, path, _, _, _ = urlparse(url) + if scheme == 'file' and os.path.isdir(url2pathname(path)): + url = urljoin(ensure_slash(url), 'index.html') + + if url in self._page_cache: + result = self._page_cache[url] + logger.debug('Returning %s from cache: %s', url, result) + else: + host = netloc.split(':', 1)[0] + result = None + if host in self._bad_hosts: + logger.debug('Skipping %s due to bad host %s', url, host) + else: + req = Request(url, headers={'Accept-encoding': 'identity'}) + try: + logger.debug('Fetching %s', url) + resp = self.opener.open(req, timeout=self.timeout) + logger.debug('Fetched %s', url) + headers = resp.info() + content_type = headers.get('Content-Type', '') + if HTML_CONTENT_TYPE.match(content_type): + final_url = resp.geturl() + data = resp.read() + encoding = headers.get('Content-Encoding') + if encoding: + decoder = self.decoders[encoding] # fail if not found + data = decoder(data) + encoding = 'utf-8' + m = CHARSET.search(content_type) + if m: + encoding = m.group(1) + try: + data = data.decode(encoding) + except UnicodeError: # pragma: no cover + data = data.decode('latin-1') # fallback + result = Page(data, final_url) + self._page_cache[final_url] = result + except HTTPError as e: + if e.code != 404: + logger.exception('Fetch failed: %s: %s', url, e) + except URLError as e: # pragma: no cover + logger.exception('Fetch failed: %s: %s', url, e) + with self._lock: + self._bad_hosts.add(host) + except Exception as e: # pragma: no cover + logger.exception('Fetch failed: %s: %s', url, e) + finally: + self._page_cache[url] = result # even if None (failure) + return result + + _distname_re = re.compile('<a href=[^>]*>([^<]+)<') + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + result = set() + page = self.get_page(self.base_url) + if not page: + raise DistlibException('Unable to get %s' % self.base_url) + for match in self._distname_re.finditer(page.data): + result.add(match.group(1)) + return result + +class DirectoryLocator(Locator): + """ + This class locates distributions in a directory tree. + """ + + def __init__(self, path, **kwargs): + """ + Initialise an instance. + :param path: The root of the directory tree to search. + :param kwargs: Passed to the superclass constructor, + except for: + * recursive - if True (the default), subdirectories are + recursed into. If False, only the top-level directory + is searched, + """ + self.recursive = kwargs.pop('recursive', True) + super(DirectoryLocator, self).__init__(**kwargs) + path = os.path.abspath(path) + if not os.path.isdir(path): # pragma: no cover + raise DistlibException('Not a directory: %r' % path) + self.base_dir = path + + def should_include(self, filename, parent): + """ + Should a filename be considered as a candidate for a distribution + archive? As well as the filename, the directory which contains it + is provided, though not used by the current implementation. + """ + return filename.endswith(self.downloadable_extensions) + + def _get_project(self, name): + result = {'urls': {}, 'digests': {}} + for root, dirs, files in os.walk(self.base_dir): + for fn in files: + if self.should_include(fn, root): + fn = os.path.join(root, fn) + url = urlunparse(('file', '', + pathname2url(os.path.abspath(fn)), + '', '', '')) + info = self.convert_url_to_download_info(url, name) + if info: + self._update_version_data(result, info) + if not self.recursive: + break + return result + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + result = set() + for root, dirs, files in os.walk(self.base_dir): + for fn in files: + if self.should_include(fn, root): + fn = os.path.join(root, fn) + url = urlunparse(('file', '', + pathname2url(os.path.abspath(fn)), + '', '', '')) + info = self.convert_url_to_download_info(url, None) + if info: + result.add(info['name']) + if not self.recursive: + break + return result + +class JSONLocator(Locator): + """ + This locator uses special extended metadata (not available on PyPI) and is + the basis of performant dependency resolution in distlib. Other locators + require archive downloads before dependencies can be determined! As you + might imagine, that can be slow. + """ + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + raise NotImplementedError('Not available from this locator') + + def _get_project(self, name): + result = {'urls': {}, 'digests': {}} + data = get_project_data(name) + if data: + for info in data.get('files', []): + if info['ptype'] != 'sdist' or info['pyversion'] != 'source': + continue + # We don't store summary in project metadata as it makes + # the data bigger for no benefit during dependency + # resolution + dist = make_dist(data['name'], info['version'], + summary=data.get('summary', + 'Placeholder for summary'), + scheme=self.scheme) + md = dist.metadata + md.source_url = info['url'] + # TODO SHA256 digest + if 'digest' in info and info['digest']: + dist.digest = ('md5', info['digest']) + md.dependencies = info.get('requirements', {}) + dist.exports = info.get('exports', {}) + result[dist.version] = dist + result['urls'].setdefault(dist.version, set()).add(info['url']) + return result + +class DistPathLocator(Locator): + """ + This locator finds installed distributions in a path. It can be useful for + adding to an :class:`AggregatingLocator`. + """ + def __init__(self, distpath, **kwargs): + """ + Initialise an instance. + + :param distpath: A :class:`DistributionPath` instance to search. + """ + super(DistPathLocator, self).__init__(**kwargs) + assert isinstance(distpath, DistributionPath) + self.distpath = distpath + + def _get_project(self, name): + dist = self.distpath.get_distribution(name) + if dist is None: + result = {'urls': {}, 'digests': {}} + else: + result = { + dist.version: dist, + 'urls': {dist.version: set([dist.source_url])}, + 'digests': {dist.version: set([None])} + } + return result + + +class AggregatingLocator(Locator): + """ + This class allows you to chain and/or merge a list of locators. + """ + def __init__(self, *locators, **kwargs): + """ + Initialise an instance. + + :param locators: The list of locators to search. + :param kwargs: Passed to the superclass constructor, + except for: + * merge - if False (the default), the first successful + search from any of the locators is returned. If True, + the results from all locators are merged (this can be + slow). + """ + self.merge = kwargs.pop('merge', False) + self.locators = locators + super(AggregatingLocator, self).__init__(**kwargs) + + def clear_cache(self): + super(AggregatingLocator, self).clear_cache() + for locator in self.locators: + locator.clear_cache() + + def _set_scheme(self, value): + self._scheme = value + for locator in self.locators: + locator.scheme = value + + scheme = property(Locator.scheme.fget, _set_scheme) + + def _get_project(self, name): + result = {} + for locator in self.locators: + d = locator.get_project(name) + if d: + if self.merge: + files = result.get('urls', {}) + digests = result.get('digests', {}) + # next line could overwrite result['urls'], result['digests'] + result.update(d) + df = result.get('urls') + if files and df: + for k, v in files.items(): + if k in df: + df[k] |= v + else: + df[k] = v + dd = result.get('digests') + if digests and dd: + dd.update(digests) + else: + # See issue #18. If any dists are found and we're looking + # for specific constraints, we only return something if + # a match is found. For example, if a DirectoryLocator + # returns just foo (1.0) while we're looking for + # foo (>= 2.0), we'll pretend there was nothing there so + # that subsequent locators can be queried. Otherwise we + # would just return foo (1.0) which would then lead to a + # failure to find foo (>= 2.0), because other locators + # weren't searched. Note that this only matters when + # merge=False. + if self.matcher is None: + found = True + else: + found = False + for k in d: + if self.matcher.match(k): + found = True + break + if found: + result = d + break + return result + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + result = set() + for locator in self.locators: + try: + result |= locator.get_distribution_names() + except NotImplementedError: + pass + return result + + +# We use a legacy scheme simply because most of the dists on PyPI use legacy +# versions which don't conform to PEP 426 / PEP 440. +default_locator = AggregatingLocator( + JSONLocator(), + SimpleScrapingLocator('https://pypi.python.org/simple/', + timeout=3.0), + scheme='legacy') + +locate = default_locator.locate + +NAME_VERSION_RE = re.compile(r'(?P<name>[\w-]+)\s*' + r'\(\s*(==\s*)?(?P<ver>[^)]+)\)$') + +class DependencyFinder(object): + """ + Locate dependencies for distributions. + """ + + def __init__(self, locator=None): + """ + Initialise an instance, using the specified locator + to locate distributions. + """ + self.locator = locator or default_locator + self.scheme = get_scheme(self.locator.scheme) + + def add_distribution(self, dist): + """ + Add a distribution to the finder. This will update internal information + about who provides what. + :param dist: The distribution to add. + """ + logger.debug('adding distribution %s', dist) + name = dist.key + self.dists_by_name[name] = dist + self.dists[(name, dist.version)] = dist + for p in dist.provides: + name, version = parse_name_and_version(p) + logger.debug('Add to provided: %s, %s, %s', name, version, dist) + self.provided.setdefault(name, set()).add((version, dist)) + + def remove_distribution(self, dist): + """ + Remove a distribution from the finder. This will update internal + information about who provides what. + :param dist: The distribution to remove. + """ + logger.debug('removing distribution %s', dist) + name = dist.key + del self.dists_by_name[name] + del self.dists[(name, dist.version)] + for p in dist.provides: + name, version = parse_name_and_version(p) + logger.debug('Remove from provided: %s, %s, %s', name, version, dist) + s = self.provided[name] + s.remove((version, dist)) + if not s: + del self.provided[name] + + def get_matcher(self, reqt): + """ + Get a version matcher for a requirement. + :param reqt: The requirement + :type reqt: str + :return: A version matcher (an instance of + :class:`distlib.version.Matcher`). + """ + try: + matcher = self.scheme.matcher(reqt) + except UnsupportedVersionError: # pragma: no cover + # XXX compat-mode if cannot read the version + name = reqt.split()[0] + matcher = self.scheme.matcher(name) + return matcher + + def find_providers(self, reqt): + """ + Find the distributions which can fulfill a requirement. + + :param reqt: The requirement. + :type reqt: str + :return: A set of distribution which can fulfill the requirement. + """ + matcher = self.get_matcher(reqt) + name = matcher.key # case-insensitive + result = set() + provided = self.provided + if name in provided: + for version, provider in provided[name]: + try: + match = matcher.match(version) + except UnsupportedVersionError: + match = False + + if match: + result.add(provider) + break + return result + + def try_to_replace(self, provider, other, problems): + """ + Attempt to replace one provider with another. This is typically used + when resolving dependencies from multiple sources, e.g. A requires + (B >= 1.0) while C requires (B >= 1.1). + + For successful replacement, ``provider`` must meet all the requirements + which ``other`` fulfills. + + :param provider: The provider we are trying to replace with. + :param other: The provider we're trying to replace. + :param problems: If False is returned, this will contain what + problems prevented replacement. This is currently + a tuple of the literal string 'cantreplace', + ``provider``, ``other`` and the set of requirements + that ``provider`` couldn't fulfill. + :return: True if we can replace ``other`` with ``provider``, else + False. + """ + rlist = self.reqts[other] + unmatched = set() + for s in rlist: + matcher = self.get_matcher(s) + if not matcher.match(provider.version): + unmatched.add(s) + if unmatched: + # can't replace other with provider + problems.add(('cantreplace', provider, other, + frozenset(unmatched))) + result = False + else: + # can replace other with provider + self.remove_distribution(other) + del self.reqts[other] + for s in rlist: + self.reqts.setdefault(provider, set()).add(s) + self.add_distribution(provider) + result = True + return result + + def find(self, requirement, meta_extras=None, prereleases=False): + """ + Find a distribution and all distributions it depends on. + + :param requirement: The requirement specifying the distribution to + find, or a Distribution instance. + :param meta_extras: A list of meta extras such as :test:, :build: and + so on. + :param prereleases: If ``True``, allow pre-release versions to be + returned - otherwise, don't return prereleases + unless they're all that's available. + + Return a set of :class:`Distribution` instances and a set of + problems. + + The distributions returned should be such that they have the + :attr:`required` attribute set to ``True`` if they were + from the ``requirement`` passed to ``find()``, and they have the + :attr:`build_time_dependency` attribute set to ``True`` unless they + are post-installation dependencies of the ``requirement``. + + The problems should be a tuple consisting of the string + ``'unsatisfied'`` and the requirement which couldn't be satisfied + by any distribution known to the locator. + """ + + self.provided = {} + self.dists = {} + self.dists_by_name = {} + self.reqts = {} + + meta_extras = set(meta_extras or []) + if ':*:' in meta_extras: + meta_extras.remove(':*:') + # :meta: and :run: are implicitly included + meta_extras |= set([':test:', ':build:', ':dev:']) + + if isinstance(requirement, Distribution): + dist = odist = requirement + logger.debug('passed %s as requirement', odist) + else: + dist = odist = self.locator.locate(requirement, + prereleases=prereleases) + if dist is None: + raise DistlibException('Unable to locate %r' % requirement) + logger.debug('located %s', odist) + dist.requested = True + problems = set() + todo = set([dist]) + install_dists = set([odist]) + while todo: + dist = todo.pop() + name = dist.key # case-insensitive + if name not in self.dists_by_name: + self.add_distribution(dist) + else: + #import pdb; pdb.set_trace() + other = self.dists_by_name[name] + if other != dist: + self.try_to_replace(dist, other, problems) + + ireqts = dist.run_requires | dist.meta_requires + sreqts = dist.build_requires + ereqts = set() + if meta_extras and dist in install_dists: + for key in ('test', 'build', 'dev'): + e = ':%s:' % key + if e in meta_extras: + ereqts |= getattr(dist, '%s_requires' % key) + all_reqts = ireqts | sreqts | ereqts + for r in all_reqts: + providers = self.find_providers(r) + if not providers: + logger.debug('No providers found for %r', r) + provider = self.locator.locate(r, prereleases=prereleases) + # If no provider is found and we didn't consider + # prereleases, consider them now. + if provider is None and not prereleases: + provider = self.locator.locate(r, prereleases=True) + if provider is None: + logger.debug('Cannot satisfy %r', r) + problems.add(('unsatisfied', r)) + else: + n, v = provider.key, provider.version + if (n, v) not in self.dists: + todo.add(provider) + providers.add(provider) + if r in ireqts and dist in install_dists: + install_dists.add(provider) + logger.debug('Adding %s to install_dists', + provider.name_and_version) + for p in providers: + name = p.key + if name not in self.dists_by_name: + self.reqts.setdefault(p, set()).add(r) + else: + other = self.dists_by_name[name] + if other != p: + # see if other can be replaced by p + self.try_to_replace(p, other, problems) + + dists = set(self.dists.values()) + for dist in dists: + dist.build_time_dependency = dist not in install_dists + if dist.build_time_dependency: + logger.debug('%s is a build-time dependency only.', + dist.name_and_version) + logger.debug('find done for %s', odist) + return dists, problems diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/manifest.py b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/manifest.py new file mode 100644 index 0000000..ca0fe44 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/manifest.py @@ -0,0 +1,393 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2013 Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +""" +Class representing the list of files in a distribution. + +Equivalent to distutils.filelist, but fixes some problems. +""" +import fnmatch +import logging +import os +import re +import sys + +from . import DistlibException +from .compat import fsdecode +from .util import convert_path + + +__all__ = ['Manifest'] + +logger = logging.getLogger(__name__) + +# a \ followed by some spaces + EOL +_COLLAPSE_PATTERN = re.compile('\\\\w*\n', re.M) +_COMMENTED_LINE = re.compile('#.*?(?=\n)|\n(?=$)', re.M | re.S) + +# +# Due to the different results returned by fnmatch.translate, we need +# to do slightly different processing for Python 2.7 and 3.2 ... this needed +# to be brought in for Python 3.6 onwards. +# +_PYTHON_VERSION = sys.version_info[:2] + +class Manifest(object): + """A list of files built by on exploring the filesystem and filtered by + applying various patterns to what we find there. + """ + + def __init__(self, base=None): + """ + Initialise an instance. + + :param base: The base directory to explore under. + """ + self.base = os.path.abspath(os.path.normpath(base or os.getcwd())) + self.prefix = self.base + os.sep + self.allfiles = None + self.files = set() + + # + # Public API + # + + def findall(self): + """Find all files under the base and set ``allfiles`` to the absolute + pathnames of files found. + """ + from stat import S_ISREG, S_ISDIR, S_ISLNK + + self.allfiles = allfiles = [] + root = self.base + stack = [root] + pop = stack.pop + push = stack.append + + while stack: + root = pop() + names = os.listdir(root) + + for name in names: + fullname = os.path.join(root, name) + + # Avoid excess stat calls -- just one will do, thank you! + stat = os.stat(fullname) + mode = stat.st_mode + if S_ISREG(mode): + allfiles.append(fsdecode(fullname)) + elif S_ISDIR(mode) and not S_ISLNK(mode): + push(fullname) + + def add(self, item): + """ + Add a file to the manifest. + + :param item: The pathname to add. This can be relative to the base. + """ + if not item.startswith(self.prefix): + item = os.path.join(self.base, item) + self.files.add(os.path.normpath(item)) + + def add_many(self, items): + """ + Add a list of files to the manifest. + + :param items: The pathnames to add. These can be relative to the base. + """ + for item in items: + self.add(item) + + def sorted(self, wantdirs=False): + """ + Return sorted files in directory order + """ + + def add_dir(dirs, d): + dirs.add(d) + logger.debug('add_dir added %s', d) + if d != self.base: + parent, _ = os.path.split(d) + assert parent not in ('', '/') + add_dir(dirs, parent) + + result = set(self.files) # make a copy! + if wantdirs: + dirs = set() + for f in result: + add_dir(dirs, os.path.dirname(f)) + result |= dirs + return [os.path.join(*path_tuple) for path_tuple in + sorted(os.path.split(path) for path in result)] + + def clear(self): + """Clear all collected files.""" + self.files = set() + self.allfiles = [] + + def process_directive(self, directive): + """ + Process a directive which either adds some files from ``allfiles`` to + ``files``, or removes some files from ``files``. + + :param directive: The directive to process. This should be in a format + compatible with distutils ``MANIFEST.in`` files: + + http://docs.python.org/distutils/sourcedist.html#commands + """ + # Parse the line: split it up, make sure the right number of words + # is there, and return the relevant words. 'action' is always + # defined: it's the first word of the line. Which of the other + # three are defined depends on the action; it'll be either + # patterns, (dir and patterns), or (dirpattern). + action, patterns, thedir, dirpattern = self._parse_directive(directive) + + # OK, now we know that the action is valid and we have the + # right number of words on the line for that action -- so we + # can proceed with minimal error-checking. + if action == 'include': + for pattern in patterns: + if not self._include_pattern(pattern, anchor=True): + logger.warning('no files found matching %r', pattern) + + elif action == 'exclude': + for pattern in patterns: + found = self._exclude_pattern(pattern, anchor=True) + #if not found: + # logger.warning('no previously-included files ' + # 'found matching %r', pattern) + + elif action == 'global-include': + for pattern in patterns: + if not self._include_pattern(pattern, anchor=False): + logger.warning('no files found matching %r ' + 'anywhere in distribution', pattern) + + elif action == 'global-exclude': + for pattern in patterns: + found = self._exclude_pattern(pattern, anchor=False) + #if not found: + # logger.warning('no previously-included files ' + # 'matching %r found anywhere in ' + # 'distribution', pattern) + + elif action == 'recursive-include': + for pattern in patterns: + if not self._include_pattern(pattern, prefix=thedir): + logger.warning('no files found matching %r ' + 'under directory %r', pattern, thedir) + + elif action == 'recursive-exclude': + for pattern in patterns: + found = self._exclude_pattern(pattern, prefix=thedir) + #if not found: + # logger.warning('no previously-included files ' + # 'matching %r found under directory %r', + # pattern, thedir) + + elif action == 'graft': + if not self._include_pattern(None, prefix=dirpattern): + logger.warning('no directories found matching %r', + dirpattern) + + elif action == 'prune': + if not self._exclude_pattern(None, prefix=dirpattern): + logger.warning('no previously-included directories found ' + 'matching %r', dirpattern) + else: # pragma: no cover + # This should never happen, as it should be caught in + # _parse_template_line + raise DistlibException( + 'invalid action %r' % action) + + # + # Private API + # + + def _parse_directive(self, directive): + """ + Validate a directive. + :param directive: The directive to validate. + :return: A tuple of action, patterns, thedir, dir_patterns + """ + words = directive.split() + if len(words) == 1 and words[0] not in ('include', 'exclude', + 'global-include', + 'global-exclude', + 'recursive-include', + 'recursive-exclude', + 'graft', 'prune'): + # no action given, let's use the default 'include' + words.insert(0, 'include') + + action = words[0] + patterns = thedir = dir_pattern = None + + if action in ('include', 'exclude', + 'global-include', 'global-exclude'): + if len(words) < 2: + raise DistlibException( + '%r expects <pattern1> <pattern2> ...' % action) + + patterns = [convert_path(word) for word in words[1:]] + + elif action in ('recursive-include', 'recursive-exclude'): + if len(words) < 3: + raise DistlibException( + '%r expects <dir> <pattern1> <pattern2> ...' % action) + + thedir = convert_path(words[1]) + patterns = [convert_path(word) for word in words[2:]] + + elif action in ('graft', 'prune'): + if len(words) != 2: + raise DistlibException( + '%r expects a single <dir_pattern>' % action) + + dir_pattern = convert_path(words[1]) + + else: + raise DistlibException('unknown action %r' % action) + + return action, patterns, thedir, dir_pattern + + def _include_pattern(self, pattern, anchor=True, prefix=None, + is_regex=False): + """Select strings (presumably filenames) from 'self.files' that + match 'pattern', a Unix-style wildcard (glob) pattern. + + Patterns are not quite the same as implemented by the 'fnmatch' + module: '*' and '?' match non-special characters, where "special" + is platform-dependent: slash on Unix; colon, slash, and backslash on + DOS/Windows; and colon on Mac OS. + + If 'anchor' is true (the default), then the pattern match is more + stringent: "*.py" will match "foo.py" but not "foo/bar.py". If + 'anchor' is false, both of these will match. + + If 'prefix' is supplied, then only filenames starting with 'prefix' + (itself a pattern) and ending with 'pattern', with anything in between + them, will match. 'anchor' is ignored in this case. + + If 'is_regex' is true, 'anchor' and 'prefix' are ignored, and + 'pattern' is assumed to be either a string containing a regex or a + regex object -- no translation is done, the regex is just compiled + and used as-is. + + Selected strings will be added to self.files. + + Return True if files are found. + """ + # XXX docstring lying about what the special chars are? + found = False + pattern_re = self._translate_pattern(pattern, anchor, prefix, is_regex) + + # delayed loading of allfiles list + if self.allfiles is None: + self.findall() + + for name in self.allfiles: + if pattern_re.search(name): + self.files.add(name) + found = True + return found + + def _exclude_pattern(self, pattern, anchor=True, prefix=None, + is_regex=False): + """Remove strings (presumably filenames) from 'files' that match + 'pattern'. + + Other parameters are the same as for 'include_pattern()', above. + The list 'self.files' is modified in place. Return True if files are + found. + + This API is public to allow e.g. exclusion of SCM subdirs, e.g. when + packaging source distributions + """ + found = False + pattern_re = self._translate_pattern(pattern, anchor, prefix, is_regex) + for f in list(self.files): + if pattern_re.search(f): + self.files.remove(f) + found = True + return found + + def _translate_pattern(self, pattern, anchor=True, prefix=None, + is_regex=False): + """Translate a shell-like wildcard pattern to a compiled regular + expression. + + Return the compiled regex. If 'is_regex' true, + then 'pattern' is directly compiled to a regex (if it's a string) + or just returned as-is (assumes it's a regex object). + """ + if is_regex: + if isinstance(pattern, str): + return re.compile(pattern) + else: + return pattern + + if _PYTHON_VERSION > (3, 2): + # ditch start and end characters + start, _, end = self._glob_to_re('_').partition('_') + + if pattern: + pattern_re = self._glob_to_re(pattern) + if _PYTHON_VERSION > (3, 2): + assert pattern_re.startswith(start) and pattern_re.endswith(end) + else: + pattern_re = '' + + base = re.escape(os.path.join(self.base, '')) + if prefix is not None: + # ditch end of pattern character + if _PYTHON_VERSION <= (3, 2): + empty_pattern = self._glob_to_re('') + prefix_re = self._glob_to_re(prefix)[:-len(empty_pattern)] + else: + prefix_re = self._glob_to_re(prefix) + assert prefix_re.startswith(start) and prefix_re.endswith(end) + prefix_re = prefix_re[len(start): len(prefix_re) - len(end)] + sep = os.sep + if os.sep == '\\': + sep = r'\\' + if _PYTHON_VERSION <= (3, 2): + pattern_re = '^' + base + sep.join((prefix_re, + '.*' + pattern_re)) + else: + pattern_re = pattern_re[len(start): len(pattern_re) - len(end)] + pattern_re = r'%s%s%s%s.*%s%s' % (start, base, prefix_re, sep, + pattern_re, end) + else: # no prefix -- respect anchor flag + if anchor: + if _PYTHON_VERSION <= (3, 2): + pattern_re = '^' + base + pattern_re + else: + pattern_re = r'%s%s%s' % (start, base, pattern_re[len(start):]) + + return re.compile(pattern_re) + + def _glob_to_re(self, pattern): + """Translate a shell-like glob pattern to a regular expression. + + Return a string containing the regex. Differs from + 'fnmatch.translate()' in that '*' does not match "special characters" + (which are platform-specific). + """ + pattern_re = fnmatch.translate(pattern) + + # '?' and '*' in the glob pattern become '.' and '.*' in the RE, which + # IMHO is wrong -- '?' and '*' aren't supposed to match slash in Unix, + # and by extension they shouldn't match such "special characters" under + # any OS. So change all non-escaped dots in the RE to match any + # character except the special characters (currently: just os.sep). + sep = os.sep + if os.sep == '\\': + # we're using a regex to manipulate a regex, so we need + # to escape the backslash twice + sep = r'\\\\' + escaped = r'\1[^%s]' % sep + pattern_re = re.sub(r'((?<!\\)(\\\\)*)\.', escaped, pattern_re) + return pattern_re diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/markers.py b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/markers.py new file mode 100644 index 0000000..ee1f3e2 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/markers.py @@ -0,0 +1,131 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2017 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +""" +Parser for the environment markers micro-language defined in PEP 508. +""" + +# Note: In PEP 345, the micro-language was Python compatible, so the ast +# module could be used to parse it. However, PEP 508 introduced operators such +# as ~= and === which aren't in Python, necessitating a different approach. + +import os +import sys +import platform +import re + +from .compat import python_implementation, urlparse, string_types +from .util import in_venv, parse_marker + +__all__ = ['interpret'] + +def _is_literal(o): + if not isinstance(o, string_types) or not o: + return False + return o[0] in '\'"' + +class Evaluator(object): + """ + This class is used to evaluate marker expessions. + """ + + operations = { + '==': lambda x, y: x == y, + '===': lambda x, y: x == y, + '~=': lambda x, y: x == y or x > y, + '!=': lambda x, y: x != y, + '<': lambda x, y: x < y, + '<=': lambda x, y: x == y or x < y, + '>': lambda x, y: x > y, + '>=': lambda x, y: x == y or x > y, + 'and': lambda x, y: x and y, + 'or': lambda x, y: x or y, + 'in': lambda x, y: x in y, + 'not in': lambda x, y: x not in y, + } + + def evaluate(self, expr, context): + """ + Evaluate a marker expression returned by the :func:`parse_requirement` + function in the specified context. + """ + if isinstance(expr, string_types): + if expr[0] in '\'"': + result = expr[1:-1] + else: + if expr not in context: + raise SyntaxError('unknown variable: %s' % expr) + result = context[expr] + else: + assert isinstance(expr, dict) + op = expr['op'] + if op not in self.operations: + raise NotImplementedError('op not implemented: %s' % op) + elhs = expr['lhs'] + erhs = expr['rhs'] + if _is_literal(expr['lhs']) and _is_literal(expr['rhs']): + raise SyntaxError('invalid comparison: %s %s %s' % (elhs, op, erhs)) + + lhs = self.evaluate(elhs, context) + rhs = self.evaluate(erhs, context) + result = self.operations[op](lhs, rhs) + return result + +def default_context(): + def format_full_version(info): + version = '%s.%s.%s' % (info.major, info.minor, info.micro) + kind = info.releaselevel + if kind != 'final': + version += kind[0] + str(info.serial) + return version + + if hasattr(sys, 'implementation'): + implementation_version = format_full_version(sys.implementation.version) + implementation_name = sys.implementation.name + else: + implementation_version = '0' + implementation_name = '' + + result = { + 'implementation_name': implementation_name, + 'implementation_version': implementation_version, + 'os_name': os.name, + 'platform_machine': platform.machine(), + 'platform_python_implementation': platform.python_implementation(), + 'platform_release': platform.release(), + 'platform_system': platform.system(), + 'platform_version': platform.version(), + 'platform_in_venv': str(in_venv()), + 'python_full_version': platform.python_version(), + 'python_version': platform.python_version()[:3], + 'sys_platform': sys.platform, + } + return result + +DEFAULT_CONTEXT = default_context() +del default_context + +evaluator = Evaluator() + +def interpret(marker, execution_context=None): + """ + Interpret a marker and return a result depending on environment. + + :param marker: The marker to interpret. + :type marker: str + :param execution_context: The context used for name lookup. + :type execution_context: mapping + """ + try: + expr, rest = parse_marker(marker) + except Exception as e: + raise SyntaxError('Unable to interpret marker syntax: %s: %s' % (marker, e)) + if rest and rest[0] != '#': + raise SyntaxError('unexpected trailing data in marker: %s: %s' % (marker, rest)) + context = dict(DEFAULT_CONTEXT) + if execution_context: + context.update(execution_context) + return evaluator.evaluate(expr, context) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/metadata.py b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/metadata.py new file mode 100644 index 0000000..6d6470f --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/metadata.py @@ -0,0 +1,1091 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +"""Implementation of the Metadata for Python packages PEPs. + +Supports all metadata formats (1.0, 1.1, 1.2, and 2.0 experimental). +""" +from __future__ import unicode_literals + +import codecs +from email import message_from_file +import json +import logging +import re + + +from . import DistlibException, __version__ +from .compat import StringIO, string_types, text_type +from .markers import interpret +from .util import extract_by_key, get_extras +from .version import get_scheme, PEP440_VERSION_RE + +logger = logging.getLogger(__name__) + + +class MetadataMissingError(DistlibException): + """A required metadata is missing""" + + +class MetadataConflictError(DistlibException): + """Attempt to read or write metadata fields that are conflictual.""" + + +class MetadataUnrecognizedVersionError(DistlibException): + """Unknown metadata version number.""" + + +class MetadataInvalidError(DistlibException): + """A metadata value is invalid""" + +# public API of this module +__all__ = ['Metadata', 'PKG_INFO_ENCODING', 'PKG_INFO_PREFERRED_VERSION'] + +# Encoding used for the PKG-INFO files +PKG_INFO_ENCODING = 'utf-8' + +# preferred version. Hopefully will be changed +# to 1.2 once PEP 345 is supported everywhere +PKG_INFO_PREFERRED_VERSION = '1.1' + +_LINE_PREFIX_1_2 = re.compile('\n \\|') +_LINE_PREFIX_PRE_1_2 = re.compile('\n ') +_241_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', + 'Summary', 'Description', + 'Keywords', 'Home-page', 'Author', 'Author-email', + 'License') + +_314_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', + 'Supported-Platform', 'Summary', 'Description', + 'Keywords', 'Home-page', 'Author', 'Author-email', + 'License', 'Classifier', 'Download-URL', 'Obsoletes', + 'Provides', 'Requires') + +_314_MARKERS = ('Obsoletes', 'Provides', 'Requires', 'Classifier', + 'Download-URL') + +_345_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', + 'Supported-Platform', 'Summary', 'Description', + 'Keywords', 'Home-page', 'Author', 'Author-email', + 'Maintainer', 'Maintainer-email', 'License', + 'Classifier', 'Download-URL', 'Obsoletes-Dist', + 'Project-URL', 'Provides-Dist', 'Requires-Dist', + 'Requires-Python', 'Requires-External') + +_345_MARKERS = ('Provides-Dist', 'Requires-Dist', 'Requires-Python', + 'Obsoletes-Dist', 'Requires-External', 'Maintainer', + 'Maintainer-email', 'Project-URL') + +_426_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', + 'Supported-Platform', 'Summary', 'Description', + 'Keywords', 'Home-page', 'Author', 'Author-email', + 'Maintainer', 'Maintainer-email', 'License', + 'Classifier', 'Download-URL', 'Obsoletes-Dist', + 'Project-URL', 'Provides-Dist', 'Requires-Dist', + 'Requires-Python', 'Requires-External', 'Private-Version', + 'Obsoleted-By', 'Setup-Requires-Dist', 'Extension', + 'Provides-Extra') + +_426_MARKERS = ('Private-Version', 'Provides-Extra', 'Obsoleted-By', + 'Setup-Requires-Dist', 'Extension') + +_566_FIELDS = _426_FIELDS + ('Description-Content-Type',) + +_566_MARKERS = ('Description-Content-Type',) + +_ALL_FIELDS = set() +_ALL_FIELDS.update(_241_FIELDS) +_ALL_FIELDS.update(_314_FIELDS) +_ALL_FIELDS.update(_345_FIELDS) +_ALL_FIELDS.update(_426_FIELDS) +_ALL_FIELDS.update(_566_FIELDS) + +EXTRA_RE = re.compile(r'''extra\s*==\s*("([^"]+)"|'([^']+)')''') + + +def _version2fieldlist(version): + if version == '1.0': + return _241_FIELDS + elif version == '1.1': + return _314_FIELDS + elif version == '1.2': + return _345_FIELDS + elif version in ('1.3', '2.1'): + return _345_FIELDS + _566_FIELDS + elif version == '2.0': + return _426_FIELDS + raise MetadataUnrecognizedVersionError(version) + + +def _best_version(fields): + """Detect the best version depending on the fields used.""" + def _has_marker(keys, markers): + for marker in markers: + if marker in keys: + return True + return False + + keys = [] + for key, value in fields.items(): + if value in ([], 'UNKNOWN', None): + continue + keys.append(key) + + possible_versions = ['1.0', '1.1', '1.2', '1.3', '2.0', '2.1'] + + # first let's try to see if a field is not part of one of the version + for key in keys: + if key not in _241_FIELDS and '1.0' in possible_versions: + possible_versions.remove('1.0') + logger.debug('Removed 1.0 due to %s', key) + if key not in _314_FIELDS and '1.1' in possible_versions: + possible_versions.remove('1.1') + logger.debug('Removed 1.1 due to %s', key) + if key not in _345_FIELDS and '1.2' in possible_versions: + possible_versions.remove('1.2') + logger.debug('Removed 1.2 due to %s', key) + if key not in _566_FIELDS and '1.3' in possible_versions: + possible_versions.remove('1.3') + logger.debug('Removed 1.3 due to %s', key) + if key not in _566_FIELDS and '2.1' in possible_versions: + if key != 'Description': # In 2.1, description allowed after headers + possible_versions.remove('2.1') + logger.debug('Removed 2.1 due to %s', key) + if key not in _426_FIELDS and '2.0' in possible_versions: + possible_versions.remove('2.0') + logger.debug('Removed 2.0 due to %s', key) + + # possible_version contains qualified versions + if len(possible_versions) == 1: + return possible_versions[0] # found ! + elif len(possible_versions) == 0: + logger.debug('Out of options - unknown metadata set: %s', fields) + raise MetadataConflictError('Unknown metadata set') + + # let's see if one unique marker is found + is_1_1 = '1.1' in possible_versions and _has_marker(keys, _314_MARKERS) + is_1_2 = '1.2' in possible_versions and _has_marker(keys, _345_MARKERS) + is_2_1 = '2.1' in possible_versions and _has_marker(keys, _566_MARKERS) + is_2_0 = '2.0' in possible_versions and _has_marker(keys, _426_MARKERS) + if int(is_1_1) + int(is_1_2) + int(is_2_1) + int(is_2_0) > 1: + raise MetadataConflictError('You used incompatible 1.1/1.2/2.0/2.1 fields') + + # we have the choice, 1.0, or 1.2, or 2.0 + # - 1.0 has a broken Summary field but works with all tools + # - 1.1 is to avoid + # - 1.2 fixes Summary but has little adoption + # - 2.0 adds more features and is very new + if not is_1_1 and not is_1_2 and not is_2_1 and not is_2_0: + # we couldn't find any specific marker + if PKG_INFO_PREFERRED_VERSION in possible_versions: + return PKG_INFO_PREFERRED_VERSION + if is_1_1: + return '1.1' + if is_1_2: + return '1.2' + if is_2_1: + return '2.1' + + return '2.0' + +_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', +} + +_PREDICATE_FIELDS = ('Requires-Dist', 'Obsoletes-Dist', 'Provides-Dist') +_VERSIONS_FIELDS = ('Requires-Python',) +_VERSION_FIELDS = ('Version',) +_LISTFIELDS = ('Platform', 'Classifier', 'Obsoletes', + 'Requires', 'Provides', 'Obsoletes-Dist', + 'Provides-Dist', 'Requires-Dist', 'Requires-External', + 'Project-URL', 'Supported-Platform', 'Setup-Requires-Dist', + 'Provides-Extra', 'Extension') +_LISTTUPLEFIELDS = ('Project-URL',) + +_ELEMENTSFIELD = ('Keywords',) + +_UNICODEFIELDS = ('Author', 'Maintainer', 'Summary', 'Description') + +_MISSING = object() + +_FILESAFE = re.compile('[^A-Za-z0-9.]+') + + +def _get_name_and_version(name, version, for_filename=False): + """Return the distribution name with version. + + If for_filename is true, return a filename-escaped form.""" + if for_filename: + # For both name and version any runs of non-alphanumeric or '.' + # characters are replaced with a single '-'. Additionally any + # spaces in the version string become '.' + name = _FILESAFE.sub('-', name) + version = _FILESAFE.sub('-', version.replace(' ', '.')) + return '%s-%s' % (name, version) + + +class LegacyMetadata(object): + """The legacy metadata of a release. + + Supports versions 1.0, 1.1 and 1.2 (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 + - *mapping* is a dict-like object + - *scheme* is a version scheme name + """ + # TODO document the mapping API and UNKNOWN default key + + def __init__(self, path=None, fileobj=None, mapping=None, + scheme='default'): + if [path, fileobj, mapping].count(None) < 2: + raise TypeError('path, fileobj and mapping are exclusive') + self._fields = {} + self.requires_files = [] + self._dependencies = None + self.scheme = scheme + if path is not None: + self.read(path) + elif fileobj is not None: + self.read_file(fileobj) + elif mapping is not None: + self.update(mapping) + self.set_metadata_version() + + def set_metadata_version(self): + self._fields['Metadata-Version'] = _best_version(self._fields) + + def _write_field(self, fileobj, name, value): + fileobj.write('%s: %s\n' % (name, value)) + + def __getitem__(self, name): + return self.get(name) + + def __setitem__(self, name, value): + return self.set(name, value) + + def __delitem__(self, name): + field_name = self._convert_name(name) + try: + del self._fields[field_name] + except KeyError: + raise KeyError(name) + + def __contains__(self, name): + return (name in self._fields or + self._convert_name(name) in self._fields) + + def _convert_name(self, name): + if name in _ALL_FIELDS: + return name + name = name.replace('-', '_').lower() + return _ATTR2FIELD.get(name, name) + + def _default_value(self, name): + if name in _LISTFIELDS or name in _ELEMENTSFIELD: + return [] + return 'UNKNOWN' + + def _remove_line_prefix(self, value): + if self.metadata_version in ('1.0', '1.1'): + return _LINE_PREFIX_PRE_1_2.sub('\n', value) + else: + return _LINE_PREFIX_1_2.sub('\n', value) + + def __getattr__(self, name): + if name in _ATTR2FIELD: + return self[name] + raise AttributeError(name) + + # + # Public API + # + +# dependencies = property(_get_dependencies, _set_dependencies) + + def get_fullname(self, filesafe=False): + """Return the distribution name with version. + + If filesafe is true, return a filename-escaped form.""" + return _get_name_and_version(self['Name'], self['Version'], filesafe) + + def is_field(self, name): + """return True if name is a valid metadata key""" + name = self._convert_name(name) + return name in _ALL_FIELDS + + def is_multi_field(self, name): + name = self._convert_name(name) + return name in _LISTFIELDS + + def read(self, filepath): + """Read the metadata values from a file path.""" + fp = codecs.open(filepath, 'r', encoding='utf-8') + try: + self.read_file(fp) + finally: + fp.close() + + def read_file(self, fileob): + """Read the metadata values from a file object.""" + msg = message_from_file(fileob) + self._fields['Metadata-Version'] = msg['metadata-version'] + + # When reading, get all the fields we can + for field in _ALL_FIELDS: + if field not in msg: + continue + if field in _LISTFIELDS: + # we can have multiple lines + values = msg.get_all(field) + if field in _LISTTUPLEFIELDS and values is not None: + values = [tuple(value.split(',')) for value in values] + self.set(field, values) + else: + # single line + value = msg[field] + if value is not None and value != 'UNKNOWN': + self.set(field, value) + logger.debug('Attempting to set metadata for %s', self) + self.set_metadata_version() + + def write(self, filepath, skip_unknown=False): + """Write the metadata fields to filepath.""" + fp = codecs.open(filepath, 'w', encoding='utf-8') + try: + self.write_file(fp, skip_unknown) + finally: + fp.close() + + def write_file(self, fileobject, skip_unknown=False): + """Write the PKG-INFO format data to a file object.""" + self.set_metadata_version() + + for field in _version2fieldlist(self['Metadata-Version']): + values = self.get(field) + if skip_unknown and values in ('UNKNOWN', [], ['UNKNOWN']): + continue + if field in _ELEMENTSFIELD: + self._write_field(fileobject, field, ','.join(values)) + continue + if field not in _LISTFIELDS: + if field == 'Description': + if self.metadata_version in ('1.0', '1.1'): + values = values.replace('\n', '\n ') + else: + values = values.replace('\n', '\n |') + values = [values] + + if field in _LISTTUPLEFIELDS: + values = [','.join(value) for value in values] + + for value in values: + self._write_field(fileobject, field, value) + + def update(self, other=None, **kwargs): + """Set metadata values from the given iterable `other` and kwargs. + + Behavior is like `dict.update`: If `other` has a ``keys`` method, + they are looped over and ``self[key]`` is assigned ``other[key]``. + Else, ``other`` is an iterable of ``(key, value)`` iterables. + + Keys that don't match a metadata field or that have an empty value are + dropped. + """ + def _set(key, value): + if key in _ATTR2FIELD and value: + self.set(self._convert_name(key), value) + + if not other: + # other is None or empty container + pass + elif hasattr(other, 'keys'): + for k in other.keys(): + _set(k, other[k]) + else: + for k, v in other: + _set(k, v) + + if kwargs: + for k, v in kwargs.items(): + _set(k, v) + + def set(self, name, value): + """Control then set a metadata field.""" + name = self._convert_name(name) + + if ((name in _ELEMENTSFIELD or name == 'Platform') and + not isinstance(value, (list, tuple))): + if isinstance(value, string_types): + value = [v.strip() for v in value.split(',')] + else: + value = [] + elif (name in _LISTFIELDS and + not isinstance(value, (list, tuple))): + if isinstance(value, string_types): + value = [value] + else: + value = [] + + if logger.isEnabledFor(logging.WARNING): + project_name = self['Name'] + + scheme = get_scheme(self.scheme) + if name in _PREDICATE_FIELDS and value is not None: + for v in value: + # check that the values are valid + if not scheme.is_valid_matcher(v.split(';')[0]): + logger.warning( + "'%s': '%s' is not valid (field '%s')", + project_name, v, name) + # FIXME this rejects UNKNOWN, is that right? + elif name in _VERSIONS_FIELDS and value is not None: + if not scheme.is_valid_constraint_list(value): + logger.warning("'%s': '%s' is not a valid version (field '%s')", + project_name, value, name) + elif name in _VERSION_FIELDS and value is not None: + if not scheme.is_valid_version(value): + logger.warning("'%s': '%s' is not a valid version (field '%s')", + project_name, value, name) + + if name in _UNICODEFIELDS: + if name == 'Description': + value = self._remove_line_prefix(value) + + self._fields[name] = value + + def get(self, name, default=_MISSING): + """Get a metadata field.""" + name = self._convert_name(name) + if name not in self._fields: + if default is _MISSING: + default = self._default_value(name) + return default + if name in _UNICODEFIELDS: + value = self._fields[name] + return value + elif name in _LISTFIELDS: + value = self._fields[name] + if value is None: + return [] + res = [] + for val in value: + if name not in _LISTTUPLEFIELDS: + res.append(val) + else: + # That's for Project-URL + res.append((val[0], val[1])) + return res + + elif name in _ELEMENTSFIELD: + value = self._fields[name] + if isinstance(value, string_types): + return value.split(',') + return self._fields[name] + + def check(self, strict=False): + """Check if the metadata is compliant. If strict is True then raise if + no Name or Version are provided""" + self.set_metadata_version() + + # XXX should check the versions (if the file was loaded) + missing, warnings = [], [] + + for attr in ('Name', 'Version'): # required by PEP 345 + if attr not in self: + missing.append(attr) + + if strict and missing != []: + msg = 'missing required metadata: %s' % ', '.join(missing) + raise MetadataMissingError(msg) + + for attr in ('Home-page', 'Author'): + if attr not in self: + missing.append(attr) + + # checking metadata 1.2 (XXX needs to check 1.1, 1.0) + if self['Metadata-Version'] != '1.2': + return missing, warnings + + scheme = get_scheme(self.scheme) + + def are_valid_constraints(value): + for v in value: + if not scheme.is_valid_matcher(v.split(';')[0]): + return False + return True + + for fields, controller in ((_PREDICATE_FIELDS, are_valid_constraints), + (_VERSIONS_FIELDS, + scheme.is_valid_constraint_list), + (_VERSION_FIELDS, + scheme.is_valid_version)): + for field in fields: + value = self.get(field, None) + if value is not None and not controller(value): + warnings.append("Wrong value for '%s': %s" % (field, value)) + + return missing, warnings + + def todict(self, skip_missing=False): + """Return fields as a dict. + + Field names will be converted to use the underscore-lowercase style + instead of hyphen-mixed case (i.e. home_page instead of Home-page). + """ + 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'), + ) + + data = {} + for key, field_name in mapping_1_0: + 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: + data[key] = self[field_name] + + return data + + def add_requirements(self, requirements): + if self['Metadata-Version'] == '1.1': + # we can't have 1.1 metadata *and* Setuptools requires + for field in ('Obsoletes', 'Requires', 'Provides'): + if field in self: + del self[field] + self['Requires-Dist'] += requirements + + # Mapping API + # TODO could add iter* variants + + def keys(self): + return list(_version2fieldlist(self['Metadata-Version'])) + + def __iter__(self): + for key in self.keys(): + yield key + + def values(self): + return [self[key] for key in self.keys()] + + def items(self): + return [(key, self[key]) for key in self.keys()] + + def __repr__(self): + return '<%s %s %s>' % (self.__class__.__name__, self.name, + self.version) + + +METADATA_FILENAME = 'pydist.json' +WHEEL_METADATA_FILENAME = 'metadata.json' + + +class Metadata(object): + """ + The metadata of a release. This implementation uses 2.0 (JSON) + metadata where possible. If not possible, it wraps a LegacyMetadata + instance which handles the key-value metadata format. + """ + + METADATA_VERSION_MATCHER = re.compile(r'^\d+(\.\d+)*$') + + NAME_MATCHER = re.compile('^[0-9A-Z]([0-9A-Z_.-]*[0-9A-Z])?$', re.I) + + VERSION_MATCHER = PEP440_VERSION_RE + + SUMMARY_MATCHER = re.compile('.{1,2047}') + + METADATA_VERSION = '2.0' + + GENERATOR = 'distlib (%s)' % __version__ + + MANDATORY_KEYS = { + 'name': (), + 'version': (), + 'summary': ('legacy',), + } + + INDEX_KEYS = ('name version license summary description author ' + 'author_email keywords platform home_page classifiers ' + 'download_url') + + DEPENDENCY_KEYS = ('extras run_requires test_requires build_requires ' + 'dev_requires provides meta_requires obsoleted_by ' + 'supports_environments') + + SYNTAX_VALIDATORS = { + 'metadata_version': (METADATA_VERSION_MATCHER, ()), + 'name': (NAME_MATCHER, ('legacy',)), + 'version': (VERSION_MATCHER, ('legacy',)), + 'summary': (SUMMARY_MATCHER, ('legacy',)), + } + + __slots__ = ('_legacy', '_data', 'scheme') + + def __init__(self, path=None, fileobj=None, mapping=None, + scheme='default'): + if [path, fileobj, mapping].count(None) < 2: + raise TypeError('path, fileobj and mapping are exclusive') + self._legacy = None + self._data = None + self.scheme = scheme + #import pdb; pdb.set_trace() + if mapping is not None: + try: + self._validate_mapping(mapping, scheme) + self._data = mapping + except MetadataUnrecognizedVersionError: + self._legacy = LegacyMetadata(mapping=mapping, scheme=scheme) + self.validate() + else: + data = None + if path: + with open(path, 'rb') as f: + data = f.read() + elif fileobj: + data = fileobj.read() + if data is None: + # Initialised with no args - to be added + self._data = { + 'metadata_version': self.METADATA_VERSION, + 'generator': self.GENERATOR, + } + else: + if not isinstance(data, text_type): + data = data.decode('utf-8') + try: + self._data = json.loads(data) + self._validate_mapping(self._data, scheme) + except ValueError: + # Note: MetadataUnrecognizedVersionError does not + # inherit from ValueError (it's a DistlibException, + # which should not inherit from ValueError). + # The ValueError comes from the json.load - if that + # succeeds and we get a validation error, we want + # that to propagate + self._legacy = LegacyMetadata(fileobj=StringIO(data), + scheme=scheme) + self.validate() + + common_keys = set(('name', 'version', 'license', 'keywords', 'summary')) + + none_list = (None, list) + none_dict = (None, dict) + + mapped_keys = { + 'run_requires': ('Requires-Dist', list), + 'build_requires': ('Setup-Requires-Dist', list), + 'dev_requires': none_list, + 'test_requires': none_list, + 'meta_requires': none_list, + 'extras': ('Provides-Extra', list), + 'modules': none_list, + 'namespaces': none_list, + 'exports': none_dict, + 'commands': none_dict, + 'classifiers': ('Classifier', list), + 'source_url': ('Download-URL', None), + 'metadata_version': ('Metadata-Version', None), + } + + del none_list, none_dict + + def __getattribute__(self, key): + common = object.__getattribute__(self, 'common_keys') + mapped = object.__getattribute__(self, 'mapped_keys') + if key in mapped: + lk, maker = mapped[key] + if self._legacy: + if lk is None: + result = None if maker is None else maker() + else: + result = self._legacy.get(lk) + else: + value = None if maker is None else maker() + if key not in ('commands', 'exports', 'modules', 'namespaces', + 'classifiers'): + result = self._data.get(key, value) + else: + # special cases for PEP 459 + sentinel = object() + result = sentinel + d = self._data.get('extensions') + if d: + if key == 'commands': + result = d.get('python.commands', value) + elif key == 'classifiers': + d = d.get('python.details') + if d: + result = d.get(key, value) + else: + d = d.get('python.exports') + if not d: + d = self._data.get('python.exports') + if d: + result = d.get(key, value) + if result is sentinel: + result = value + elif key not in common: + result = object.__getattribute__(self, key) + elif self._legacy: + result = self._legacy.get(key) + else: + result = self._data.get(key) + return result + + def _validate_value(self, key, value, scheme=None): + if key in self.SYNTAX_VALIDATORS: + pattern, exclusions = self.SYNTAX_VALIDATORS[key] + if (scheme or self.scheme) not in exclusions: + m = pattern.match(value) + if not m: + raise MetadataInvalidError("'%s' is an invalid value for " + "the '%s' property" % (value, + key)) + + def __setattr__(self, key, value): + self._validate_value(key, value) + common = object.__getattribute__(self, 'common_keys') + mapped = object.__getattribute__(self, 'mapped_keys') + if key in mapped: + lk, _ = mapped[key] + if self._legacy: + if lk is None: + raise NotImplementedError + self._legacy[lk] = value + elif key not in ('commands', 'exports', 'modules', 'namespaces', + 'classifiers'): + self._data[key] = value + else: + # special cases for PEP 459 + d = self._data.setdefault('extensions', {}) + if key == 'commands': + d['python.commands'] = value + elif key == 'classifiers': + d = d.setdefault('python.details', {}) + d[key] = value + else: + d = d.setdefault('python.exports', {}) + d[key] = value + elif key not in common: + object.__setattr__(self, key, value) + else: + if key == 'keywords': + if isinstance(value, string_types): + value = value.strip() + if value: + value = value.split() + else: + value = [] + if self._legacy: + self._legacy[key] = value + else: + self._data[key] = value + + @property + def name_and_version(self): + return _get_name_and_version(self.name, self.version, True) + + @property + def provides(self): + if self._legacy: + result = self._legacy['Provides-Dist'] + else: + result = self._data.setdefault('provides', []) + s = '%s (%s)' % (self.name, self.version) + if s not in result: + result.append(s) + return result + + @provides.setter + def provides(self, value): + if self._legacy: + self._legacy['Provides-Dist'] = value + else: + self._data['provides'] = value + + def get_requirements(self, reqts, extras=None, env=None): + """ + Base method to get dependencies, given a set of extras + to satisfy and an optional environment context. + :param reqts: A list of sometimes-wanted dependencies, + perhaps dependent on extras and environment. + :param extras: A list of optional components being requested. + :param env: An optional environment for marker evaluation. + """ + if self._legacy: + result = reqts + else: + result = [] + extras = get_extras(extras or [], self.extras) + for d in reqts: + if 'extra' not in d and 'environment' not in d: + # unconditional + include = True + else: + if 'extra' not in d: + # Not extra-dependent - only environment-dependent + include = True + else: + include = d.get('extra') in extras + if include: + # Not excluded because of extras, check environment + marker = d.get('environment') + if marker: + include = interpret(marker, env) + if include: + result.extend(d['requires']) + for key in ('build', 'dev', 'test'): + e = ':%s:' % key + if e in extras: + extras.remove(e) + # A recursive call, but it should terminate since 'test' + # has been removed from the extras + reqts = self._data.get('%s_requires' % key, []) + result.extend(self.get_requirements(reqts, extras=extras, + env=env)) + return result + + @property + def dictionary(self): + if self._legacy: + return self._from_legacy() + return self._data + + @property + def dependencies(self): + if self._legacy: + raise NotImplementedError + else: + return extract_by_key(self._data, self.DEPENDENCY_KEYS) + + @dependencies.setter + def dependencies(self, value): + if self._legacy: + raise NotImplementedError + else: + self._data.update(value) + + def _validate_mapping(self, mapping, scheme): + if mapping.get('metadata_version') != self.METADATA_VERSION: + raise MetadataUnrecognizedVersionError() + missing = [] + for key, exclusions in self.MANDATORY_KEYS.items(): + if key not in mapping: + if scheme not in exclusions: + missing.append(key) + if missing: + msg = 'Missing metadata items: %s' % ', '.join(missing) + raise MetadataMissingError(msg) + for k, v in mapping.items(): + self._validate_value(k, v, scheme) + + def validate(self): + if self._legacy: + missing, warnings = self._legacy.check(True) + if missing or warnings: + logger.warning('Metadata: missing: %s, warnings: %s', + missing, warnings) + else: + self._validate_mapping(self._data, self.scheme) + + def todict(self): + if self._legacy: + return self._legacy.todict(True) + else: + result = extract_by_key(self._data, self.INDEX_KEYS) + return result + + def _from_legacy(self): + assert self._legacy and not self._data + result = { + 'metadata_version': self.METADATA_VERSION, + 'generator': self.GENERATOR, + } + lmd = self._legacy.todict(True) # skip missing ones + for k in ('name', 'version', 'license', 'summary', 'description', + 'classifier'): + if k in lmd: + if k == 'classifier': + nk = 'classifiers' + else: + nk = k + result[nk] = lmd[k] + kw = lmd.get('Keywords', []) + if kw == ['']: + kw = [] + result['keywords'] = kw + keys = (('requires_dist', 'run_requires'), + ('setup_requires_dist', 'build_requires')) + for ok, nk in keys: + if ok in lmd and lmd[ok]: + result[nk] = [{'requires': lmd[ok]}] + result['provides'] = self.provides + author = {} + maintainer = {} + return result + + LEGACY_MAPPING = { + 'name': 'Name', + 'version': 'Version', + 'license': 'License', + 'summary': 'Summary', + 'description': 'Description', + 'classifiers': 'Classifier', + } + + def _to_legacy(self): + def process_entries(entries): + reqts = set() + for e in entries: + extra = e.get('extra') + env = e.get('environment') + rlist = e['requires'] + for r in rlist: + if not env and not extra: + reqts.add(r) + else: + marker = '' + if extra: + marker = 'extra == "%s"' % extra + if env: + if marker: + marker = '(%s) and %s' % (env, marker) + else: + marker = env + reqts.add(';'.join((r, marker))) + return reqts + + assert self._data and not self._legacy + result = LegacyMetadata() + nmd = self._data + for nk, ok in self.LEGACY_MAPPING.items(): + if nk in nmd: + result[ok] = nmd[nk] + 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 + return result + + def write(self, path=None, fileobj=None, legacy=False, skip_unknown=True): + if [path, fileobj].count(None) != 1: + raise ValueError('Exactly one of path and fileobj is needed') + self.validate() + if legacy: + if self._legacy: + legacy_md = self._legacy + else: + legacy_md = self._to_legacy() + if path: + legacy_md.write(path, skip_unknown=skip_unknown) + else: + legacy_md.write_file(fileobj, skip_unknown=skip_unknown) + else: + if self._legacy: + d = self._from_legacy() + else: + d = self._data + if fileobj: + json.dump(d, fileobj, ensure_ascii=True, indent=2, + sort_keys=True) + else: + with codecs.open(path, 'w', 'utf-8') as f: + json.dump(d, f, ensure_ascii=True, indent=2, + sort_keys=True) + + def add_requirements(self, requirements): + if self._legacy: + self._legacy.add_requirements(requirements) + else: + run_requires = self._data.setdefault('run_requires', []) + always = None + for entry in run_requires: + if 'environment' not in entry and 'extra' not in entry: + always = entry + break + if always is None: + always = { 'requires': requirements } + run_requires.insert(0, always) + else: + rset = set(always['requires']) | set(requirements) + always['requires'] = sorted(rset) + + def __repr__(self): + name = self.name or '(no name)' + version = self.version or 'no version' + return '<%s %s %s (%s)>' % (self.__class__.__name__, + self.metadata_version, name, version) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/resources.py b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/resources.py new file mode 100644 index 0000000..1884016 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/resources.py @@ -0,0 +1,355 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013-2017 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +from __future__ import unicode_literals + +import bisect +import io +import logging +import os +import pkgutil +import shutil +import sys +import types +import zipimport + +from . import DistlibException +from .util import cached_property, get_cache_base, path_to_cache_dir, Cache + +logger = logging.getLogger(__name__) + + +cache = None # created when needed + + +class ResourceCache(Cache): + def __init__(self, base=None): + if base is None: + # Use native string to avoid issues on 2.x: see Python #20140. + base = os.path.join(get_cache_base(), str('resource-cache')) + super(ResourceCache, self).__init__(base) + + def is_stale(self, resource, path): + """ + Is the cache stale for the given resource? + + :param resource: The :class:`Resource` being cached. + :param path: The path of the resource in the cache. + :return: True if the cache is stale. + """ + # Cache invalidation is a hard problem :-) + return True + + def get(self, resource): + """ + Get a resource into the cache, + + :param resource: A :class:`Resource` instance. + :return: The pathname of the resource in the cache. + """ + prefix, path = resource.finder.get_cache_info(resource) + if prefix is None: + result = path + else: + result = os.path.join(self.base, self.prefix_to_dir(prefix), path) + dirname = os.path.dirname(result) + if not os.path.isdir(dirname): + os.makedirs(dirname) + if not os.path.exists(result): + stale = True + else: + stale = self.is_stale(resource, path) + if stale: + # write the bytes of the resource to the cache location + with open(result, 'wb') as f: + f.write(resource.bytes) + return result + + +class ResourceBase(object): + def __init__(self, finder, name): + self.finder = finder + self.name = name + + +class Resource(ResourceBase): + """ + A class representing an in-package resource, such as a data file. This is + not normally instantiated by user code, but rather by a + :class:`ResourceFinder` which manages the resource. + """ + is_container = False # Backwards compatibility + + def as_stream(self): + """ + Get the resource as a stream. + + This is not a property to make it obvious that it returns a new stream + each time. + """ + return self.finder.get_stream(self) + + @cached_property + def file_path(self): + global cache + if cache is None: + cache = ResourceCache() + return cache.get(self) + + @cached_property + def bytes(self): + return self.finder.get_bytes(self) + + @cached_property + def size(self): + return self.finder.get_size(self) + + +class ResourceContainer(ResourceBase): + is_container = True # Backwards compatibility + + @cached_property + def resources(self): + return self.finder.get_resources(self) + + +class ResourceFinder(object): + """ + Resource finder for file system resources. + """ + + if sys.platform.startswith('java'): + skipped_extensions = ('.pyc', '.pyo', '.class') + else: + skipped_extensions = ('.pyc', '.pyo') + + def __init__(self, module): + self.module = module + self.loader = getattr(module, '__loader__', None) + self.base = os.path.dirname(getattr(module, '__file__', '')) + + def _adjust_path(self, path): + return os.path.realpath(path) + + def _make_path(self, resource_name): + # Issue #50: need to preserve type of path on Python 2.x + # like os.path._get_sep + if isinstance(resource_name, bytes): # should only happen on 2.x + sep = b'/' + else: + sep = '/' + parts = resource_name.split(sep) + parts.insert(0, self.base) + result = os.path.join(*parts) + return self._adjust_path(result) + + def _find(self, path): + return os.path.exists(path) + + def get_cache_info(self, resource): + return None, resource.path + + def find(self, resource_name): + path = self._make_path(resource_name) + if not self._find(path): + result = None + else: + if self._is_directory(path): + result = ResourceContainer(self, resource_name) + else: + result = Resource(self, resource_name) + result.path = path + return result + + def get_stream(self, resource): + return open(resource.path, 'rb') + + def get_bytes(self, resource): + with open(resource.path, 'rb') as f: + return f.read() + + def get_size(self, resource): + return os.path.getsize(resource.path) + + def get_resources(self, resource): + def allowed(f): + return (f != '__pycache__' and not + f.endswith(self.skipped_extensions)) + return set([f for f in os.listdir(resource.path) if allowed(f)]) + + def is_container(self, resource): + return self._is_directory(resource.path) + + _is_directory = staticmethod(os.path.isdir) + + def iterator(self, resource_name): + resource = self.find(resource_name) + if resource is not None: + todo = [resource] + while todo: + resource = todo.pop(0) + yield resource + if resource.is_container: + rname = resource.name + for name in resource.resources: + if not rname: + new_name = name + else: + new_name = '/'.join([rname, name]) + child = self.find(new_name) + if child.is_container: + todo.append(child) + else: + yield child + + +class ZipResourceFinder(ResourceFinder): + """ + Resource finder for resources in .zip files. + """ + def __init__(self, module): + super(ZipResourceFinder, self).__init__(module) + archive = self.loader.archive + self.prefix_len = 1 + len(archive) + # PyPy doesn't have a _files attr on zipimporter, and you can't set one + if hasattr(self.loader, '_files'): + self._files = self.loader._files + else: + self._files = zipimport._zip_directory_cache[archive] + self.index = sorted(self._files) + + def _adjust_path(self, path): + return path + + def _find(self, path): + path = path[self.prefix_len:] + if path in self._files: + result = True + else: + if path and path[-1] != os.sep: + path = path + os.sep + i = bisect.bisect(self.index, path) + try: + result = self.index[i].startswith(path) + except IndexError: + result = False + if not result: + logger.debug('_find failed: %r %r', path, self.loader.prefix) + else: + logger.debug('_find worked: %r %r', path, self.loader.prefix) + return result + + def get_cache_info(self, resource): + prefix = self.loader.archive + path = resource.path[1 + len(prefix):] + return prefix, path + + def get_bytes(self, resource): + return self.loader.get_data(resource.path) + + def get_stream(self, resource): + return io.BytesIO(self.get_bytes(resource)) + + def get_size(self, resource): + path = resource.path[self.prefix_len:] + return self._files[path][3] + + def get_resources(self, resource): + path = resource.path[self.prefix_len:] + if path and path[-1] != os.sep: + path += os.sep + plen = len(path) + result = set() + i = bisect.bisect(self.index, path) + while i < len(self.index): + if not self.index[i].startswith(path): + break + s = self.index[i][plen:] + result.add(s.split(os.sep, 1)[0]) # only immediate children + i += 1 + return result + + def _is_directory(self, path): + path = path[self.prefix_len:] + if path and path[-1] != os.sep: + path += os.sep + i = bisect.bisect(self.index, path) + try: + result = self.index[i].startswith(path) + except IndexError: + result = False + return result + +_finder_registry = { + type(None): ResourceFinder, + zipimport.zipimporter: ZipResourceFinder +} + +try: + # In Python 3.6, _frozen_importlib -> _frozen_importlib_external + try: + import _frozen_importlib_external as _fi + except ImportError: + import _frozen_importlib as _fi + _finder_registry[_fi.SourceFileLoader] = ResourceFinder + _finder_registry[_fi.FileFinder] = ResourceFinder + del _fi +except (ImportError, AttributeError): + pass + + +def register_finder(loader, finder_maker): + _finder_registry[type(loader)] = finder_maker + +_finder_cache = {} + + +def finder(package): + """ + Return a resource finder for a package. + :param package: The name of the package. + :return: A :class:`ResourceFinder` instance for the package. + """ + if package in _finder_cache: + result = _finder_cache[package] + else: + if package not in sys.modules: + __import__(package) + module = sys.modules[package] + path = getattr(module, '__path__', None) + if path is None: + raise DistlibException('You cannot get a finder for a module, ' + 'only for a package') + loader = getattr(module, '__loader__', None) + finder_maker = _finder_registry.get(type(loader)) + if finder_maker is None: + raise DistlibException('Unable to locate finder for %r' % package) + result = finder_maker(module) + _finder_cache[package] = result + return result + + +_dummy_module = types.ModuleType(str('__dummy__')) + + +def finder_for_path(path): + """ + Return a resource finder for a path, which should represent a container. + + :param path: The path. + :return: A :class:`ResourceFinder` instance for the path. + """ + result = None + # calls any path hooks, gets importer into cache + pkgutil.get_importer(path) + loader = sys.path_importer_cache.get(path) + finder = _finder_registry.get(type(loader)) + if finder: + module = _dummy_module + module.__file__ = os.path.join(path, '') + module.__loader__ = loader + result = finder(module) + return result diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/scripts.py b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/scripts.py new file mode 100644 index 0000000..0b7c3d0 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/scripts.py @@ -0,0 +1,415 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013-2015 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +from io import BytesIO +import logging +import os +import re +import struct +import sys + +from .compat import sysconfig, detect_encoding, ZipFile +from .resources import finder +from .util import (FileOperator, get_export_entry, convert_path, + get_executable, in_venv) + +logger = logging.getLogger(__name__) + +_DEFAULT_MANIFEST = ''' +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> + <assemblyIdentity version="1.0.0.0" + processorArchitecture="X86" + name="%s" + type="win32"/> + + <!-- Identify the application security requirements. --> + <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> + <security> + <requestedPrivileges> + <requestedExecutionLevel level="asInvoker" uiAccess="false"/> + </requestedPrivileges> + </security> + </trustInfo> +</assembly>'''.strip() + +# check if Python is called on the first line with this expression +FIRST_LINE_RE = re.compile(b'^#!.*pythonw?[0-9.]*([ \t].*)?$') +SCRIPT_TEMPLATE = r'''# -*- coding: utf-8 -*- +if __name__ == '__main__': + import sys, re + + def _resolve(module, func): + __import__(module) + mod = sys.modules[module] + parts = func.split('.') + result = getattr(mod, parts.pop(0)) + for p in parts: + result = getattr(result, p) + return result + + try: + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + + func = _resolve('%(module)s', '%(func)s') + rc = func() # None interpreted as 0 + except Exception as e: # only supporting Python >= 2.6 + sys.stderr.write('%%s\n' %% e) + rc = 1 + sys.exit(rc) +''' + + +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" + # instead of "/usr/bin/env /dir with spaces/bin/jython" + # otherwise whole + if executable.startswith('/usr/bin/env '): + env, _executable = executable.split(' ', 1) + if ' ' in _executable and not _executable.startswith('"'): + executable = '%s "%s"' % (env, _executable) + else: + if not executable.startswith('"'): + executable = '"%s"' % executable + return executable + + +class ScriptMaker(object): + """ + A class to copy or create scripts from source scripts or callable + specifications. + """ + script_template = SCRIPT_TEMPLATE + + executable = None # for shebangs + + def __init__(self, source_dir, target_dir, add_launchers=True, + dry_run=False, fileop=None): + self.source_dir = source_dir + self.target_dir = target_dir + self.add_launchers = add_launchers + self.force = False + self.clobber = False + # It only makes sense to set mode bits on POSIX. + self.set_mode = (os.name == 'posix') or (os.name == 'java' and + os._name == 'posix') + self.variants = set(('', 'X.Y')) + self._fileop = fileop or FileOperator(dry_run) + + self._is_nt = os.name == 'nt' or ( + os.name == 'java' and os._name == 'nt') + + def _get_alternate_executable(self, executable, options): + if options.get('gui', False) and self._is_nt: # pragma: no cover + dn, fn = os.path.split(executable) + fn = fn.replace('python', 'pythonw') + executable = os.path.join(dn, fn) + return executable + + if sys.platform.startswith('java'): # pragma: no cover + def _is_shell(self, executable): + """ + Determine if the specified executable is a script + (contains a #! line) + """ + try: + with open(executable) as fp: + return fp.read(2) == '#!' + except (OSError, IOError): + logger.warning('Failed to open %s', executable) + return False + + def _fix_jython_executable(self, executable): + if self._is_shell(executable): + # Workaround for Jython is not needed on Linux systems. + import java + + if java.lang.System.getProperty('os.name') == 'Linux': + return executable + elif executable.lower().endswith('jython.exe'): + # Use wrapper exe for Jython on Windows + return executable + return '/usr/bin/env %s' % executable + + def _build_shebang(self, executable, post_interp): + """ + Build a shebang line. In the simple case (on Windows, or a shebang line + which is not too long or contains spaces) use a simple formulation for + the shebang. Otherwise, use /bin/sh as the executable, with a contrived + shebang which allows the script to run either under Python or sh, using + suitable quoting. Thanks to Harald Nordgren for his input. + + See also: http://www.in-ulm.de/~mascheck/various/shebang/#length + https://hg.mozilla.org/mozilla-central/file/tip/mach + """ + if os.name != 'posix': + simple_shebang = True + else: + # Add 3 for '#!' prefix and newline suffix. + shebang_length = len(executable) + len(post_interp) + 3 + if sys.platform == 'darwin': + max_shebang_length = 512 + else: + max_shebang_length = 127 + simple_shebang = ((b' ' not in executable) and + (shebang_length <= max_shebang_length)) + + if simple_shebang: + result = b'#!' + executable + post_interp + b'\n' + else: + result = b'#!/bin/sh\n' + result += b"'''exec' " + executable + post_interp + b' "$0" "$@"\n' + result += b"' '''" + return result + + def _get_shebang(self, encoding, post_interp=b'', options=None): + enquote = True + if self.executable: + executable = self.executable + enquote = False # assume this will be taken care of + elif not sysconfig.is_python_build(): + executable = get_executable() + elif in_venv(): # pragma: no cover + executable = os.path.join(sysconfig.get_path('scripts'), + 'python%s' % sysconfig.get_config_var('EXE')) + else: # pragma: no cover + executable = os.path.join( + sysconfig.get_config_var('BINDIR'), + 'python%s%s' % (sysconfig.get_config_var('VERSION'), + sysconfig.get_config_var('EXE'))) + if options: + executable = self._get_alternate_executable(executable, options) + + if sys.platform.startswith('java'): # pragma: no cover + executable = self._fix_jython_executable(executable) + # Normalise case for Windows + executable = os.path.normcase(executable) + # 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) + # 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') + # in case of IronPython, play safe and enable frames support + if (sys.platform == 'cli' and '-X:Frames' not in post_interp + and '-X:FullFrames' not in post_interp): # pragma: no cover + post_interp += b' -X:Frames' + shebang = self._build_shebang(executable, post_interp) + # Python parser starts to read a script using UTF-8 until + # it gets a #coding:xxx cookie. The shebang has to be the + # first line of a file, the #coding:xxx cookie cannot be + # written before. So the shebang has to be decodable from + # UTF-8. + try: + shebang.decode('utf-8') + except UnicodeDecodeError: # pragma: no cover + raise ValueError( + 'The shebang (%r) is not decodable from utf-8' % shebang) + # If the script is encoded to a custom encoding (use a + # #coding:xxx cookie), the shebang has to be decodable from + # the script encoding too. + if encoding != 'utf-8': + try: + shebang.decode(encoding) + except UnicodeDecodeError: # pragma: no cover + raise ValueError( + 'The shebang (%r) is not decodable ' + 'from the script encoding (%r)' % (shebang, encoding)) + return shebang + + def _get_script_text(self, entry): + return self.script_template % dict(module=entry.prefix, + func=entry.suffix) + + manifest = _DEFAULT_MANIFEST + + def get_manifest(self, exename): + base = os.path.basename(exename) + return self.manifest % base + + def _write_script(self, names, shebang, script_bytes, filenames, ext): + use_launcher = self.add_launchers and self._is_nt + linesep = os.linesep.encode('utf-8') + if not use_launcher: + script_bytes = shebang + linesep + script_bytes + else: # pragma: no cover + if ext == 'py': + launcher = self._get_launcher('t') + else: + launcher = self._get_launcher('w') + stream = BytesIO() + with ZipFile(stream, 'w') as zf: + zf.writestr('__main__.py', script_bytes) + zip_data = stream.getvalue() + script_bytes = launcher + shebang + linesep + zip_data + for name in names: + outname = os.path.join(self.target_dir, name) + if use_launcher: # pragma: no cover + n, e = os.path.splitext(outname) + if e.startswith('.py'): + outname = n + outname = '%s.exe' % outname + try: + self._fileop.write_binary_file(outname, script_bytes) + except Exception: + # Failed writing an executable - it might be in use. + logger.warning('Failed to write executable - trying to ' + 'use .deleteme logic') + dfname = '%s.deleteme' % outname + if os.path.exists(dfname): + os.remove(dfname) # Not allowed to fail here + os.rename(outname, dfname) # nor here + self._fileop.write_binary_file(outname, script_bytes) + logger.debug('Able to replace executable using ' + '.deleteme logic') + try: + os.remove(dfname) + except Exception: + pass # still in use - ignore error + else: + if self._is_nt and not outname.endswith('.' + ext): # pragma: no cover + outname = '%s.%s' % (outname, ext) + if os.path.exists(outname) and not self.clobber: + logger.warning('Skipping existing file %s', outname) + continue + self._fileop.write_binary_file(outname, script_bytes) + if self.set_mode: + self._fileop.set_executable_mode([outname]) + filenames.append(outname) + + def _make_script(self, entry, filenames, options=None): + post_interp = b'' + if options: + args = options.get('interpreter_args', []) + if args: + args = ' %s' % ' '.join(args) + post_interp = args.encode('utf-8') + shebang = self._get_shebang('utf-8', post_interp, options=options) + script = self._get_script_text(entry).encode('utf-8') + name = entry.name + scriptnames = set() + if '' in self.variants: + scriptnames.add(name) + if 'X' in self.variants: + scriptnames.add('%s%s' % (name, sys.version[0])) + if 'X.Y' in self.variants: + scriptnames.add('%s-%s' % (name, sys.version[:3])) + if options and options.get('gui', False): + ext = 'pyw' + else: + ext = 'py' + self._write_script(scriptnames, shebang, script, filenames, ext) + + def _copy_script(self, script, filenames): + adjust = False + script = os.path.join(self.source_dir, convert_path(script)) + outname = os.path.join(self.target_dir, os.path.basename(script)) + if not self.force and not self._fileop.newer(script, outname): + logger.debug('not copying %s (up-to-date)', script) + return + + # Always open the file, but ignore failures in dry-run mode -- + # that way, we'll get accurate feedback if we can read the + # script. + try: + f = open(script, 'rb') + except IOError: # pragma: no cover + if not self.dry_run: + raise + f = None + else: + first_line = f.readline() + if not first_line: # pragma: no cover + logger.warning('%s: %s is an empty file (skipping)', + self.get_command_name(), script) + return + + match = FIRST_LINE_RE.match(first_line.replace(b'\r\n', b'\n')) + if match: + adjust = True + post_interp = match.group(1) or b'' + + if not adjust: + if f: + f.close() + self._fileop.copy_file(script, outname) + if self.set_mode: + self._fileop.set_executable_mode([outname]) + filenames.append(outname) + else: + logger.info('copying and adjusting %s -> %s', script, + self.target_dir) + if not self._fileop.dry_run: + encoding, lines = detect_encoding(f.readline) + f.seek(0) + shebang = self._get_shebang(encoding, post_interp) + if b'pythonw' in first_line: # pragma: no cover + ext = 'pyw' + else: + ext = 'py' + n = os.path.basename(outname) + self._write_script([n], shebang, f.read(), filenames, ext) + if f: + f.close() + + @property + def dry_run(self): + return self._fileop.dry_run + + @dry_run.setter + def dry_run(self, value): + self._fileop.dry_run = value + + if os.name == 'nt' or (os.name == 'java' and os._name == 'nt'): # pragma: no cover + # Executable launcher support. + # Launchers are from https://bitbucket.org/vinay.sajip/simple_launcher/ + + def _get_launcher(self, kind): + if struct.calcsize('P') == 8: # 64-bit + bits = '64' + else: + bits = '32' + name = '%s%s.exe' % (kind, bits) + # 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 + + # Public API follows + + def make(self, specification, options=None): + """ + Make a script. + + :param specification: The specification, which is either a valid export + entry specification (to make a script from a + callable) or a filename (to make a script by + copying from a source location). + :param options: A dictionary of options controlling script generation. + :return: A list of all absolute pathnames written to. + """ + filenames = [] + entry = get_export_entry(specification) + if entry is None: + self._copy_script(specification, filenames) + else: + self._make_script(entry, filenames, options=options) + return filenames + + def make_multiple(self, specifications, options=None): + """ + Take a list of specifications and make scripts from them, + :param specifications: A list of specifications. + :return: A list of all absolute pathnames written to, + """ + filenames = [] + for specification in specifications: + filenames.extend(self.make(specification, options)) + return filenames diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/t32.exe b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/t32.exe new file mode 100644 index 0000000000000000000000000000000000000000..a09d926872d84ae22a617dfe9ebb560d420b37de GIT binary patch literal 92672 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/t64.exe b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/t64.exe new file mode 100644 index 0000000000000000000000000000000000000000..9da9b40de922fb203df6b9a1d0ad4139af536850 GIT binary patch literal 102400 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�vlnW`{LoXpTySn$@;x8yoz96jn?+Kk z+8+$D$B^0(dpJ6<hZa-dac!=Dhn7&}Ml@L8?2`HV^PF4PZHDWFvVxb6nK^I63}Ihy z5|`ET>A18uUe?`-6oJ;)kr577Q&Vi><kIszZ_Qr$uhe^fsNOTolL}S>eB)*fB=t!> z-VTs@&yaf8Q*)_o#I@2F(QesP)-{|(k4g>Cwre=A!xmwMY;-K8yUmySJ@MCm|CJ}& zc_7=d`c9fRLg$#ug2UUQz30hw(;n+0IrXqxE4M$qE!^uU@ncbAh1*({4{wX~#v7|h zt!Ft>u19Wbj`B@4NCff}+~v}ieMORYgqxzJ`{&g7c6~pRG;{)TWAZbx<ie!<90O}9 zFuPst_a~ifU7)u$k|UHeV&x#2(^Kba%8_f6es?Tqy=O2BmwS}1RxI0mFO%57W>(dK zj`6KWJ}w7wdDMsql_NPa){*Rv&G4++R*ji#uw-r)A6qgo=lJ7HdO42m-T9`*@Q7Dz zf+UuVF*`x*lEuy`b}3{lL+qQx-V%G0F)qPi+bXtgzTai9vLpp|U<Ej8B$MXm=2j~8 z#PV~8bbWRN7g3L|ARg-t){(9tPfc@phf2~Fgk5B)l7bbK*Iq$2%`9=Gq9I(EFH}L% zrh*VWhLZT6_2Z6h6H2s_uv8FF<8p763W9KbOfoJW-bwWRO;=Bqsh;-w*7d^;>m{as zs0*o<P&JwQ+18<ca_sbkzHLHZ2%ZxQ>1V`BC1hJ-*Ccia#IBKi=^B#in@UCIn4Fmk zior7R+v?|Wna0Stc!;T_-oKJ_$^PsZYv(fQ1ujjn{%Vk9>tTa9t=}6Y#k$KNsn#7D z>0#YsEHbRM2Ju)c4U%UqHppyip+WMkB7-cjt};lPHO(LuR<=QwS{WMg3(c%?245?9 ziow?lKEUA8&sYft-za#b!KE9r+HRE6_%{pwp}}QbvYHIuAo$A$-!1rVgEtEPguxF8 zzS-bSg5P6sOYqwb-YWRb25%F*+TbFcu)GG35qyEc(VnQRIR;M_JkQ`x!QBRz*{79e z@KnKv8(fYKTTX+sfK^r>gL?#zF?gQfM{m$&uMoV|;Bs!(I%M!_!4DXGt>AkNzFzPK zgWoRr!v<d<_$GsI5`2TfHw(Vr;9CT*HF$&IOAWqT@G^rp3Z8H9je^fG_yNH^25%Dl zB7<9kry9If@WBRe6Fk}ABIdH<3?3u6GI)aEpI@)(kSw@maHrsJ7(7MrMuVpczQf>Y zf^RW6q5)++U~rG%8x5W(_-zKCE%;i4=L^2f;0pw=FnERFMFw9g_-un$3!Y=}wSs3D ze7)e~41T-dDF)vt_yB`%5<J1+n+1<F_!hz2mQwZ_`wj)?KT6u$dUsEH{NL_G91~@| zD8BrcqOvvqIb+jcY}f&g-)3z7Xl!O<bHvzeFgDy)iT}vhtP>lZn(kW^HPoJ7b}}B9 z8IJ`fs1ut?V>89rq+qka*o-$eXnlyk#@GxqHfh+*FgE>+O$IiTjZL(%@nDl-Y`$2c z3%3B9%Z$yt#-;)rx3Sr8Y?fkkp|N>N+vpAm%Mr%%cg9kBA}pQ8@~6g9x+E-n8_R03 zwCQfn2S5?@&$E{%8|J<N?zLgou%ETBlOOvjQ!$P}NmZf0Bp00|>s01iG?D}w*pSou zNIoLCujkrC>z{ZwSCF3JqS>>diBbD}gUJvNhszwO|GKb=>-u!R@M+)WoJJ?AS)L=? z5Ed)n`|GoLl1KkmO|I|Ly=2up0Y}NIui6|-o?|kMf)-fhY2Q=Xj|YzF--?`w7d<tt z6bwxfW1r4mv)zlf0#APyeg^{ESqaN5r}jnfP_{bH^lbYe0lYtWUmJIT_b}FxwTFFv z*+sAen<8|`KP&npuX%ne8D++{ejQ4q8i;Q0rfA0REx`=67XW4dOa?e$6O$A1tmnv! z*<<%-pZSuPIaOX8;ii)GC3ZG003T)JgCu(<OR;2WD;sxV9G>RyG5z-&{r9N;`?dc2 zmHzvs{@d1RR@x!|!$c8BOywC;1%1eW*oBd?zTrlv26n!W?Wv1zAnf3E7<X3oTIa^6 z9Dd%;)q1G9o|$O4_k8NZlTHj*p+10S$~45614{dJ$0qp3gVMU(vB|!XGNBYT9?#3X zBsf3%WiWhyU3WNtEK^u?Oi`7g&mV`5j@=%|9#mGE)I*%rxqc+mKEq_~bs%LOXxNQ{ zz;UzWjNN7M+~gq7z1@k?_IF^kXLR0bteAF&TZ~qc)&Oj0v)i_oI3Z1tYra3Pt(9OD zLiVYw*EyE$@voIZURq^jV1J9UuDlpijn;jNA5VS!ex`JRq_G~X>!L)txN#+py7=W{ ztczb^z)AzE0XhwT{6et_3^|6hUHof(zoIg&!vZyxr`1JST>jX@{{1x{aC!Y1@&n?X zCx3F~&+M8HBD~XUK8W;=tofju_msf1-gB)lZV^fUDR{P4gSK#|YseSu{&E)LV?eWr z60!QHv1$RdEW>=zm|qfenKc8Y!sgJKIi4d@==NhkIfYT@&*Sp%6_N7F(>4~_4W4aH zJjVL8oCvaxGgd{3w{XsF))&O&`iBp0agy2`liEx`@G?PuAnD^tvJ$bfMWdb^c|A&2 zb2$?c>#EO<u!;~|?nN3DgSxNehtP*s^L30jvF7U@UY-t&<WL4;#*~)fIsPX%NfBj{ z?y0#?aD`7_Z@2%^&EUIklD|TQmMAyt$9!?Tz#o4_0n5_;$V#04sHxx)yVLhCKZgfj zv=+IWHWGl1-`z313d31yr$0UgPc1K5<L_icvo3NlIg2J|D;`8ue+-_}-(q{=XOfnG zABtdFqWsSR(%(X<K3VQgmK|%7VWFHlo!|7g9BaB`bl2%zHh&{Ca72&`f+t{)d!!TQ za#1p5JO-LEL?5fHpUmA~HpbXJLYfpvx+RN@*G2t;<30et0Ct3;>e0~1Ywc&66Jh$i z8GIO{<u)SO2<qk4=V3mz_R%KR!$Q*uA4tj~&K!Re=5%d7SJGg6JAH>^^)H1`{<iF4 zM|0}SW2nm*$Lb$qCz>{Ari)u^cKS0_Gxa-t3?LrI#70j<BWfHf6UEOX<XuEw4Zc&g z?5qBArU9>1W{cY$QZBldi#*%7`&mDrO>dF?3F$3G+wzbkg3hd8YcuY=29b2Dar}vP z{JX?xIduDGKUSY95j9G1j);0g$4N{-&>~eJI!uln2rzUQy~nm}+sWC3`H1hHiq*yK z5lA}QPE`)t@{Ci9M4u{=YT48D&~`OlOdj&wyKW-Wa_^IyH!eTxIJuT;wf<5U{({r0 z?$cCstl?w|Vv_iDHu3^VZ%P_S>qL(E6KRt5Nxg8;R2U>~;&6jF$hpj)XKEi!*N7Pj zX4L6K8c1prYjIy<+&6{XyJ`0WLHAk4eL=|m<9j9imZ1CjASfOo;`eZndO3p(4Km)5 z8wdS41fhQL)WRA$>Q9371i24{M^^8b(43)|$H@jSr#8vjp^1{m_<C{iw+514#w-lS znWc*)q4NW;2td4yjMJrGwvbC9X<E$5^|&vH#T9rNFVTlNFU`qFZcHS#WDw^do!UO{ zxIoehNd-S=%Tu0O@H!9=F}8=^=)<%<#Be6f`0>ZTc8?Gt({@SV2sUCiF1c$j@K=Kz zp!UdpoS|j#4@cL7NByt9%GQ^yudT`{$rE(YrE#Y=cxqsWzkSNbVVy+Y(UZ*s6wiGs z6TNPtc&_F7@1vdW9bz)`!A;Bu|G+qB`U_Fz*eKWEQH7`fyy$b{0gb$Sn3ORW?In)f z8|>F&=~*e5^;3yVh8J$>59*LbL~LC8&F1ivZ$R#_gB%(OFUhQn?48YShuj_*C9<#P zmXw@f`!hL)e=4tRMP$o4B-}&*=Z%tS$sv6kAGiJ_=vcFe9#Kcxqoi)m)MFeR&1+dN zxo`xF)a=8HZm%5ub=G_tz9PQn%Lv~o{-`|8bG8ifM|psC@e{?=+j@0fXml(Bl|xn1 zu=So*NM`LcH!p-Jv2uLtcVwgG2SW5{Yv;A#b38R)H7&`6S*}IAAgfyVNN#u{d*Rd* z(&|9c1uo6I@RzUrf~c?WWTHyDf6m%-mp=G1%v1Aq)8fC1&12YD7we405tBLmlq&sx zn(05RK{)Epe82>Tlik*yI(E(@TK;Cm1RWxb!)EOuhpGNz_Tk#gB$}YPPa?cyo-e(m z$#dkh?DPhnFWpA4(DS9^Q4>dF*yD|{?mbt^Krj1}oY{I+4@vs0*D0dwAkj076LN9U zQsC`Y9Rr^z!_(bfd*03b#u@7VIIUCvz~DwS5^PEB&m3jmp9sdDh(BumDiYH-;hm?- zNghtVpx9y%SFt$sodp?XO7LDcJW&w?tr6sTP@2_EXI)Qse!>YNDzteUescUAV0#z! zE4TihQDNIr&Y%BdpeXH?^J#gxoC0^P^E%RGmXMzjemJA?7$+{n^|?#V!E^pY>udUj z>#*B__P%(u_dTbz_g&kY3V6;Mmt?k`o((5E^-&{8WU@c93GdOOap)net=oRC`*QU8 z&0#j#AUskZ6@kwSuIM8<VK3F;xNSS<#Hc&zxR(<ONj|6W4?Ai_6c9){da+VafPL3D z87SstaXPa$7Z>rerWU?i$Dz&YFJsvm#XW}v?qX^wT8mvZ%lhUiuaoCO`{u088C>9! z1;1L0#!**I5l*6LFu#Qx?|ZEKlJ$<jxNNF#*!JuQX4<?Q@uNQwzn0LOpm2dT9H08! zz@Np9qo)JxopLxtWcgN)pod$;0~^3;`fsYDQ=G%PiMNya!<A#4)z}wh7d1*K!=g&0 z{eh%sIRv5A>NsjIlPCzs&|EawDb#yLPaETQ%aKg>+bDn#G0VS$_oE0WM3n74be0eM zCIZHhmnmmEZbsL#Vn;X!uAuVGOga?jb;QZ7*8F(Q9mhp%$`(j^<suXJPI5{-v%?%W z{~45f!*1U9y8+G#)0`9TJKgbE1ovUM{}Nk5c`{s%+jhtiOWA+Pk@+T|gZB#^j|tIk z;y6Z0I^KQrd9hXwJ`A$ePWktuzorN;g&{8_DGBSM$nNeluJoN%XElGo83qpB)+haj zd0}7|g?Y!d*6qlFE#GnNa!2P0!D*X0&0lKHdhtSx2bw>`plw?~pl~6fg%FzY;pAgj z%P{et=D6pGL-XKi5xmVXJ>Jd4$?d6s#7T?eu^aymJ3B*N>mmnd2X<T(>+7-h6c-nP z0y|mq@qcYML05elpdD4d;2Fe@l&5};ghy43dsu^95MxI%{`LE%?&G%UtC%vg*EKEm z?(x+BRQv~$CNP_nDj&rNKyBloBk~Mu^%OFz@}%!{+#E;#$=Bm@^2ub*v3e5zn?Hjd z(&Qa$4g?D&k~{73WW^f8phmfBc7#g>`*?Tr6c-gHcZ~JW%<x=N$D|tLsxOa83AdlT zgkRqG-6g!5N|F-h((|6Igy&F@&LvEj63Vkgy0R+7hkid?+9;dE?G-iZ_!7mzZTcxu zIiet+y$8l-(k4h=xwB)7meyP`jJ61nc03arbIep8mAzvaigEV0p~E&<C#G?Kbb-_} zm)eXbI?*vN)oq%0;R~Mn+v25av)FX3k3S&uFjzqR&}&G|`{QEV!*;U%AReX-JtCOA zyVH-Y+|t5KU!@60i!q7&Xr{pQ1FrOAj@1zmL~{|RP}ax_g?@HU&DT-BORZ<v+%^}8 ztb?HFq1^H%zLOq2U!rT-BR!0VKA2@IS;*3Jy+G1-5|d&)bd*V&+(v)B<sQa`EyU2g zl<+}5?yU<ExlNA@8QvbQ>g5WZU1RWKU8++aKyIvj&>E*|9*_Mn+LY|N*2^#`^T@Xf zB)$!U*D_vmcvObX;C}mDo^jRk1J<oE!2_|ZFgX6e;MsmZR+;#%1FM3C)kkj3{n%N| zXgl4HorBfM?#K2Sbi(~u9@OE&SMN4xA@^e|L#bFl1f^i+e(Y*O>ie<R8Cxs6-Qz3l zHQPtrySN|Q=?<9Ib(LVnhJrW$O6n8^S8IUj<Ja6xiI&R&ew5DJ_rI{ROT<|xx&LKu z{EFJDiO$gdFS+qM46DBk6y{?kvJN(2?!o1@jZB8j<u;fn$@&8sW(s^0z_5=g<DJAs z8GBm`Lk`wgD??>7%S?SQ43$GU_Pn#>-Crk~in#piKbWzunb{=TrZUz&A9&8%FPF<E zpy7PY>ns0Z&$7C_>-X*YhR#_kO!Zy*hQ6e|ev7`LtOD5gW=h3M##5KIQ6vh(tsAkh zB~LNh?L@^rGCg}8p{<K|A#8m^`?&_(u5W16!|-~2(#@;!lfKiN(m~(QCOl?;yS||{ zcnRqn+W9^84eeMF%Jx*yuJsM=Y#vOurMRMQK<3c9&^d6NzM(8s9tHIc9ikU&*EbYY zO(6P){(?&<eM67l9J8MDNA3EC(1IU_f|CYL=udJyTHAdyuC8rXq?=k{_SP2TsFg9y z<=@S;*il<Z&g2;A&4`@@j<exsw*B92xWR_CWI+@V4VJ9@`xOvHXV>iduPPuKTq|^Z z&Wf|>SO3POqm$Yo|3JF;jtYo&eX9bZH*0isT`C|7h13d&rf?Fbg94%_Xw_6cW6p63 zh%WhmO##u%v@7WO?^HlEL8{xTLN2BW#z@Z)iCz>gto@f15NY;l87Z;qSlSg3U1Agv z0YVChz)?VS$^U;85Y@2NM-RMN#8}aY2#!}kgiZXXt5^UF@j5CXsvQL%{I?Vk{h4Ta ze@@5Kl>(x5+I>Jr_Y)Klop*={gVBpa&-Op6fM_Li6^}n_qfF{DWLlipK>^Vpkx9U7 zCs9D;mTAtvrhsTUlRVuTzK;T;R8kkuwgRHVZccliTmezI@hxOLxdNhFj)VwJp*6E` zD0;W`<!qf)Pyvx1+uSnU4rw47dl6d_>(0;`h|Xnl%7EjIWeAE!?HP3Vc7;S|%`y|$ zZ&OG#9)&jxyd(J=R7kX5wA=J(sjI%QjPufgr^Oi8%!aur!bxZrksye(xfo=fQ9y)J zqCV9(h)yC|v`7F)vy71FBocd664~~sBpNC9MJUu0Sn8-fU0}JR_7s7rB<d*;l|<bH zqLN7N9EkRu{Nq&;ox@<-l}e&>&=G6s_?;?=0uO|0rFj*pKm)CkNcW%!rnE{TIsDFJ ze!>Lq=1L5mRT5pJJ=iLVrUs)yC6VqpX;)e$QJOf^oLnVQvI+PtDv1swU?7H==8p^# z*?h<#Va=}#0@0(J_ZzG5=G`DdwJuc>nbH`QM8C$P<wA&S&m3Ry+A4`|Jlydvfhd09 z@UUojN@G4Spb!0*-1A7ZqIB5q%=<meE>S~^4_T95B+Auf20we4K1-Y?-jV6QcD79D zwNj#3g0^rUnBxrFnRL$oIdO0wLM{k&R7xakxwPZ9bIhLYcdWT?rX(zVtRkSTq2g9@ z$(n0%`uKO*JE~fAoK7MOtFG2u+={g}B24I@lc<;0s~glwM7Q74*ZPJthW0wPmr2=U zRwQvkE0!b!tgrAQIeM|(>s(Nwn-s6py36bl1fp7Rl<=<^RkFQ*jDOJ{3kl<S%_YWG z8QanuL!{`I#UflPLp;gjExi2ZLA3=NVYW_-nlF#};;qX<d1#pkNk*o}H~tio@IV== zHj~}}KmKZ&)QICrcMQ+JWVH0M9HHRW25xO2GY{?0C5z4#r>!s~1Htn7*Aki8YD*PW zv*`SFJoc$$&6+St<XP)4Tv_7r+vLTFjq8ULkTk5~Jy+8mCs~4|h~X#V52h+KuP4-E z?C^R*Zp45$S|W1%Z}M_N+TfKJv12dlI3?hfIu<+1+>TLZ93SQAZ;z5k3LY2I5@oa< z<!CW{b)U&4FEH%0KEePD=JM|t{g%At$vd9e5yRg&oFx+KI*A7X>R=iBoG8zG!L=m{ zJL|<H5%@_jzeR2yH;cy$kkYNVSWe6j=7EQ$=ofT|4tO4^h;}^6Zf6539$I>GA&soP zYBeGE_U~pN$op5Mx`AiX3B7EW<FTD=zZFiA<0QxGro>R^XAw_H-RPDiPvIq4Hyo>z z*DaPZGDVlvv2_}a${>9!{8h4N{q-~{Ioo|A64{$4h18EZm+2GWTnyK`wEXeer4#^m z*c0ZtAbtkfM>fu0udVN)BEeI)l*79D&YAXmW{7Kz9%wn?%DS$%oL%YZMk&G&*#wD1 zBsR!w$>htH%mRIzNu;lG@SNA#nMNVX-*1hcCL*S*o3bt_?BhF=6)`tiAEh7>?zG}I zt#r4wX5((C`HkK$YWaiXQ3pdxlhuTsEaT{XC}3`r+g~TQQCu}&hOJ0-rGL6?n5Y4v z0Nfb)X#*mG$GhW`jy-sw|C7NcAYzJMp2AfU*puE`d6qkEewf$k*A|iqN9}oxX(SPR z*uMEJ%+`)_={U|I&J%Jf%k^;lh``Y30MdD2gOy{>yL1-(T%MJC1%6LtAgP#~P!xTT zq2)gI8Mz?VT+Ps;`;rU@EZk;wn=08r-0yZgiYlbF8RU2(qSY&gsA_INqFLHL?4KGu z>|e7ZgWkj5w+zO^CBP>%AN=bvnZB(nz0;>yTfUZe|KNSpo%y1;%iTfI^moZ@9FN&D z8^>cJvte@n{bV+ry9mjE<PeY+;e8+7)tQ{&AX670$L*lJ`ZUrN-Tlamd`Y6cy3f`L z)UOsN{Y~FdLxJ_)@1ek2s<yK{$;o<->-J5N!gWyxive1m)X4H&8j99mz0_03s-Ql1 zy-{C{%AUb_@Jj_-J2EBFI;>^KNAB~N@wu%}FM}7;7U~HpE1E4vrZf}_duH%(nYf8e zX_IbF8|~&KOge|<ChrMWOWS=8RRt+r$IJ46mBsx)L^4boGD>)l(@{GJf5>GT5I@yl zc7?nCnnBrU+RCZRs+I>u+Gto1@|hCXu<ca-k|d<i?~FHgjz@E1nobbWY(qrDuE}5V z1TV*hxwbVUrQu08S}#(XPb5PB9v*#j)K0dgGP&4^l%~x#-)qD5Hq5f&P$R8blV@jY zYY{cbrO+SuVtD0I6R53KMen8YXjRcuHG-;Wx$~n{ML(#K>5kfM1l8)IZzOC@+m+ra zT3z%8?T)%=*)(&bY{UK32z-hn*fK5|i+Jepjtn+f7#Wz~9g1<(9H!Pwn48WC9^1-k zPQukzGo8aMHBY7n7X)=pr|K9baF41}&^zs}FMs(CxxnWZjnnJ}wA|u$Je7u~N|_G2 z<yFhmMpa5BJ!kcO#jH;JZOwC~6FRa(>z<Ct>hUfwb9>M}%@D<t1a7q5@8q%tX=l~G z>!_VhY2Y5}pB?$r-o8#^6ZOwO>W6oC+9{6O1Q5rgXup}c-YTHE8_^CbYj&EwDtCHd z*(=Q-$eg%CqOgWmrtSJG2|xwbNxCG#l)dBFT`gjPwcfpU#^B<d!fNS?xs$tIM%p4; zL!(tCYbX&UUEf2(mbFBd)MYiIqPj85|4s99QrwlbR!5%|(Xw?u>1<Kd8P7MfO1-+# z-zsWKMRT?5DXK@w_L!&nSGrcwWG%CN9VmU<id|bv@c_eUHOE?`^$skymfN;>0Y$5I zf!1pMdkN{Yo!%6G$cZKNnlFgF-u0&z4<t1u7pnfGLK3GMWo8){*vA2t1W|k45YD<4 zwb$FxgGlW*|DNf6P^a~WMyIvWXASi#o|K|x)t8Eb+v}H=)HF<Guq_)rNAz0@d9P`? zHmKnG(DhTbZ+DOPc^kxNZPj$Qy0Z+`6m`^ALlTCSjI8=AiSk_$I7OrJI-1?7GNEbn zdXXSPN~7^wN9g)%DlRM<g37O(coWjrdQGqT_@TH;ZVT;<k@))Q6s1iB6<`lA3b2#3 zT?Yl&?H)U7!Tt~}*iBjsHnASB1-m;BZyaH#YRWM=lUN}~DC>W<k4&FL3AVFKCD;+J z2wMyGOF2ZtM(P@gLzsjb32diE+-u&4|LMYMrQO|W!yL5{(w_%7oVd%qc3ATlGzVW| zi95a7H^HSFdGpVy!}K=SQ+Gos$CNgS4YltphPJE0{)X)(`fL#_IBFN*T}z^58`aZ- zl1jw(T%U}e59@_mD&nYbj6Up!K++e;M`W;&<6EizT<-hs153e*`3^@)UJ^cciZ1M< zwk~X*S2l{S&mq!4(!)A}nd|8`0*$%_=n@3AVSlqoJpH(%C*3b)q@`<>*dH>9Wsdlq zb<cjyOwun!nZ8hZ#pVybq9-`KBh2gA!eUZ4{W;BF8Ov~QZ+*p17<Nwm(znTJPD^)+ zo};a$I=O4kJ;khHN8H1X5KT}UwtqK;Ll=p4AL1FhjV&Qz)SM2&s5fyWP>i=fe<OWK z+S68HT08UtJji3yjBtS!1t>j4X|;4hrsK(B@6>ce%*}b%;-8=E66y=xD~5=qVyPTL z$k)d*tV1livm?Hd_H=mV<2u_dBQ)SHxeTK%XNEGWlYdoK&y?J0oh#YkoD81Uyts6( zWY&9y$*i+IvwtB0&6;?1{Y4xk0C5`LnNEiwf~ovTtRdhYe8~XLa4p_UfaY`Yq~kE= z7Ew_2Oif$1H?O8`fj4t&8L^_rBYEp=keaq7jx~vdpe=vcqd6L^#C1W8b_;2${xGij zW7-K_LqhX=AdE20a^Fb8I7(bKY3KQP7`0|;xY2qYsqLE|#fLbKwH=M-YjOPC(R>Gv zTV%*4HHPbTVw4Wq7)8Cu7U_wNQF^B>()-qX-ZeIJv8i`CjbR!FFeVfpFc~OWg-~(k zC=F9hIykMZ-WvRcu7u_n=+4R7H|O}6327DAy1=?ylJ+a3$WhYsA7j+?=*I}PT<NiA zY*p8u<^wpp{93N$X?{*;RpJ|N>$>g`pDki~Kmye4Me8;EFkA1)(it1&*TfrCeqAlz zs4y35L@%ysJJUO6tF$R9?98n)`vB>q**krksiav%8q+dWqHdYQ->{Ypp?@@b_G<Qq zw~Tey&0H%qDU&}z#n<ncl9@?Gg0K=iq#xUrX`+r;ripr1xTa00##*l%v$km8c!ZjI zhMBw3UViwW_W0{%dMiuMsS~BKZWx@(w1?eznFe><jkkRBLNnHI(5_~z9MAisITzP) z-Y;{0j_9#4o}V7Sy%u4}Tokq<nAiu-Mz&}#WiMMan6h~K0&&+x(E(q2&G^f%L}86@ z2n9F=B~(2)McHpFtvt{Yx0QkgTB5en=s3}^D_P=^kaYt%OUFk29`<o<nbF@tYn&Zk zXzX%t+2mI%Un8H_rN{S|e3t5m#zzd*`TSaI6$y~f*Cn6d@Cu)7s%Mei<N!53{?}JX zc87MzZvQT_JNCsu(kUjx-%!-J2xL6uxNm!ohj*1@#7wrnjueqIC0X5!FYE95!J@Ws z#B}NC^!WT5vVOLw5ak5%W#Gr_a6#U*?XWw6oHKMqCLld~f*7EXbz3MVYY?cGo{8|O z3mJp!a$Tu~oQ!=}4k4llDx8!;QoeET>k+nQ+1NPc8&^N2yETE4biFa3%3^tJg8feX zcEmCqMSt<kuLAC|app<+-m4hJdBN{ef86`{?U%rQ4Bq6-fE+z%%t30oY;cAMD?B2A zbD@nEzSAYXVRcs}CYl7UQVlsOGQ*SH2goo@>3!ait-nT8_ugHtH8Mr}cj_(?o9oHh zdJde{NA)HdI-J2Zfec5zpWZ8{@W^EUfL0M^)P72HmsC<Yq}J+*Qav!HA8^#{!TxY& z49^Pw9<1g@h;xxCvQr|~7K1q6A0*Cw<QCya4|n~7FquH6v_u3lZ6bZVQrh-MKBnK7 zLZJS5m8j8@qRqWAGqt625Kj|!;^e6t%X@NHuHs?5VPtg6-Tsk}TX*?KdXBVkq=ssY z%tjcq&6<!C(d6H?ttkrCL0X*{Px;ntM~M1@6#P`eHxH!Qxzpcwtht491a>vcje^Hz zRH~o6+uUWPt4x&zQ<bOiRZ=}v%@nCFvau#=8yH7H;u^WJZwRxk>eQVXB1}!)nbAGA zCO?j5(J)&E-_({@w*4bYrbxU=Vk^6`wcK#lrC}#h(=a51S1~bTg63w5`492D6?!Y{ z`4!ABC=fi8FFa!eT(C=qIk#@kMl&%-a>FTJBQ?uMH!AvqjmXSrL}nr_3m=3w)aG@> zE2fB=?g1|ULxh!!ldL&cw;vq0<}ki*Z(*@ClXXpQll9rfMtbI|xv`IOtobuBpj;|# zD`FUt!z`XGNB?_?GMIRz7;+5b1*`8GBnI7x)kv?buZgsJd7JVpkq?BVT+&%r6AeYm z*XN~(37Q9dXIpy+Q9t(#j`7R_LqiiXGTBz@5W0CLW=<`NJa1P749x49Z4Bs1+FMpo zrq>*Wxu!UUA@fqi;91D#WYa)vK+37lN(&x%h3+_^p9XzQy@YGMy=#`IP~x!?ABp^i zbKSq<URk0{U2br!>96fiD0_djfmpF*TA%Bu06)9R6y8yL4@|~{DwMO^#9Z^C&J5kx z2yH||QK-LKfK0Rksrgc;evppW>g8oTR^<M-<+*xpYM@<cx3!kG$Gl$7R%#x}M+Xjc zZWN(&nRG?3d!3YL00mFcDm-@j|AvYgTT#z6O54(R*a59&tlo3X;n}A3j?)jgIpU|U z;*`k|zfM}$%{ZCN(4Nro3^@w*$A0AhD#!n+|4mqpj{ch~L*wo`(B`kGsvQ3y)W{l@ zxsM~GK~AyPI+QM~X6d!cv*Ibe$w){_E?5xm@t@nefH{_*Cwy<)<w-yH15Cd1vFs9k z%$-xwd)sm)Cp=>idSB4f_eG!~q|1KkVxbSsg3b-qAN8K@)|-e{sR|lHgSWqD*e5cz zU4wi_R3ft_&%nZ6iw2)H_9IW-D7tE-X6If<f}|5X5*0NSGi;wNak#Dfe?yFQQDyUJ zxrH00Jzsylb?dJM@m5%0UJ;~$-qH#2ef!-p&I__k@J2G2z9mVYS?`IlF81k2|ADwc zQlZ7CKnF`35Br>2Gqu&vczV(Hbf@vOU5x&ZrFGuy@psD|_MyjrEPMYq@<?h$ZXs8a z8@yRh3h8r2cYUK&z}P$4u-QZ6{Y26~@q%#+9JRl}2WT89+hDX+p^m8b_c5BCd$pu8 z?3mp8I`S6d4%64Qa)U4Df`v3ih8UDPvF6G7LRn{BDE)oFTat4@*%!)t8Y9{lL>0yv zWVy>)C)1z6PVMNk=yZchRz-tvqod|liOV1VVF|OkE!32<{vhS16gRe1l9QKkuyfMP z78JMlioQ^}bt79io6j+}uL;4^R^dn9s=p*WeV5~AFRd+ylUyRHlHb6b^ae+b?AaQ= zp&QFF2{5^rmRYzjr*80W$hSL&XsPM~QgmOyE{E4A#9Q~PK;X%6$z^?9H`b2f?DYxP zk;9qd{sY`|r90=b?>^nE=;gv1zNsQ^uP~OE(3hX%iFkz!XFIa~7D#%kryf3gvR!CB zHY?bjO0#|~%@C89-q>@&K$g(fcGovDuic{+EpoAws&-nHm$O|f-tINtnty?(PIpi; z<N}J;1?6=4zvPIjbrjE%wG`P2aMdo0IL$W@R!R~(XUCm^Gk40>Dhe5;cTc+7BcKn- zlkS5NSSxMw?{{sDgiw;rJ<X!pjlKlRbfx!O&uBgV55@*W=kX<B{!gt{Z<}sH_5$;; z3ukTnf^{vnvhnO4@1f%v#yy$W9Y5MeDuJX;45zNAL}g3;EI4jAr<emtcgvhccQ(G! z)|Jr6T(hyJfckOivfp#Eptu@M$B(OOrgJY?e<ywf=WhS@?DV%h{=a28a(7{U_g;n^ zvJ&UH-Q;9N|CZOSBx0^fi}LlbT4qXea`N57+XeE5%?s8~bXLF7;&R&KZkc8u!PGMI z`l}%nk>ly6CR0fBW(yX7U^#*3K+*;-C>=TA>Ce5$x47l#sX<sY#9AFn$oe@bg9PvY z5UFhYB52h|Du`TOf_=d{I~4g5_?_8;06o{tDdgbeX>Tu)zCu4MnQcES$%TaHCa!ab zrEwZ^PFPHMgKO2hPzI6vlZ~$ZU!mzJgWFZJf!KOQ^AV~gyeR_1mDec{ZJnNp)j44? z)yy@YL(`#3TZLJrg|(!1vR|$3!&{Q^6&ACyB_ZfeCa_7XMgg)fTI&er5yB$}`!@_x z4GN{XWI`%5hDkQ#ZHf#_eXWui!7kbQY&w^oPEim$)*tmWQi{4TC@xC}bKmscZ4d$$ zkKHPstV0+NM@^kWA$WC9v;E^t?=xKWo^b0iw$QXHVk@^)+L@hRKkG1w*c&D_prO@? z){_|jL;-s=C~4S{!X*C_`Zv}CdKhjVBhl<FVU~v!m&t-ZzUeAq92QY=RyG|DHZK^P z0Hv4xv6dm`<h}@bxO^c38l6kt0ip6K$ZL+rkj9dls6!0)1!aSigO7PI!C?QLHLsP% z)h++@WK{GWetI?9U{iG|*!fT#D{$)6n$wtk9e$d31+8A%^$ek8)7Ze_r^CGc>TZlV z{B#0x7A*C#gLjT`>Y#3VvOhB!x0<F;YIcX$WhVbtMDo5-){oB@+BBd&<bb!QwaS?C zG5LDHqch*qy(X>rIqQqR2LeYjS;ES$iwrvcVIKeVgkjevp!Sg0u_OGMgV7eoyB%vj zTG7w#e}?d-jTEP?Wme6zPO{K^5q%G@iJ`Lj*fH<vau*k&W_{8TFU8}m2}e$}LduA^ zr(2>~jQ)5g1$A-ltgm!A`r6seZ%TGWVe5y|S~yohC+=(+@K-8^kzmGPA|+`oS?XCI z?33ivzj3U265j}0^z1%E)Twtkf8M^nlirW@BHQ14yg63N&l#LdydJjrTdm$>B}qNR zjP%rBj%Ih}j=QY~7HcB$bil5bWWx#VgMu}WomqK^#Po0onP3C0vR-%<LlFu(`NM=+ z&j{td2Ng;Lk5i%yH<L)F$nQl{y1J;#kr)u%6MPdTK1*A0!XQo<)Z2}9T{rC|WqV-A zQqaJV8}wf}>J00l`;SzebnwjV^Q;T0?)60IL|vhFq4468Z#iw3)Q&D&$%V4+z0L#* zIoZ*rS}o^wiq5z|yZ!zc>y}@1;ks3NWow!pWhfsKP+w-Y&hOGmhZ@kqNy^q<I1}_} zMHdOy{I!}CSs0ng+<~tA=pBCRuU$EL3UkRD^Yo<EFs;Ym=UL0uq0~AX$K{09qO8g; zqw>f9ak`9`w=*~&R|`^lsh+DoX)k~sbBFrlJ%Uwf$le+pw{7$DuX8=tEJyR}SQeHQ zHOt4LvDs6|9bT>fmGyNkn}Hox#zy~ZtkwLnN%6S4ty!M0w6clcGmAeVqt>4ME^Pg| z8P*0nvg2!&9#L5ZUBzT18<RRX=|YE!Y?kR~b#RxO{J;BG?Gy%3>PI%*Xv06+aJLN) z+VEo=Mh-IJoHo43hSO}gz=pLp{DlqwXu~IM_<{}Jw_%$Nm&rRr{C;4=;j;71FU^K- z8_uzz*M>LQ@OB$MV8h)ueBXv&*|6uCCf*bqUSz|`HmtPaY8&2a!%a4P)P_53*l5Fp zHhkZPZ8q#S*reCThNs(bqz&CR%(LM<8!ootY8&2W!@F$wunqUx@MRkwvSF(Y!-tsk z2iWjD8|K(>o(-4T@Mas{Wy2?I_^b^N+R(CLn+;>_dOO{QBW;*r!z*pL)`q%r`P0X) zm!SD%@FJ%ueV6y74XpURZC+zw=Ww$>F!lomb?x5K|K@97zEaFGwC3`)azV2-!qBZL zGfbyj?KZGb6{;%y%v3YfBsD^=HtJu{JX)Qna#WUWEB-E1*(y^_QEqMPQ66=nTFAc( ziAQ2GzanM+4OdR`VE#F^o!DG&|C9XXs!`g0l(v)5dDzL%WkbQ;s+gP>lg>Q;R*IGW zU8c&_;x6o`;M<E^(D!uwRAAFN2AA@w`FvHl$!{`v89535#Jq@5!Jms*Dpe_d%r93J zU@lb1PV{dQe&=E1)Ak+XDIlJ9TT>ndH6{NFdP;s#Q>XJOWtV&f^J5@;%TT01=g#EA zn1vc9UGXRBNIV6^=OZUYb_gu_P13n<x0^xE#aC4)f3wI(kuLf1E;I05+`)G)`Crr_ z>~!3ZH%mT(=_<HP(o@RBFJ_5P$|3Pcz9l>(zvse*3oon+F;o%1;m%xsPC>5chcCkA zjw&h|Wej<+jmxl(au*jCFPv8#VwB6u7awPyQs^xg=jp{2-k^iaH{Vx9W+(f~bmWtL zi*&`iDk@8*zH<vI3q$o>Jg?GMP#LP=$pwqFk#rSlDdLy76>&;@e2WNwy&^7&M@=f8 zrwF5_7kGV@ML6)AR9R|c&}D(IvMOYPUd2U=iaS`$@EKEX`6BIWy3d9MUWrG-OBjVe zg&&2xB%#8>BO;@^MaOiH?GYE>(~*$at9PHIQ~D<NJGK9S(@r1g9CXH+gNK|oH0A7b zh7BJva#ZT*F=NM_d*1nJ7hITr(fEreWVj|~y0a!-;>n(TX-@8CQ}U)xn?3_^>Fg`6 zylT$X*UZf?m{(X-Trz(_=?|_gTezsa;=0NzuW#{^rPtqZ<Fe%|R;tYM%B-cO-n`24 z!eXi2h44}#bzcb=6swVNQkiaB(t;MjIi>h0rpJ&rU#a~$bvfdd%yWc)a%el#`Pb1; z&{g;;n>KdINnE90nF8;*w6CsWm`4AXs>bq9;v7LdE^=l15$R8yeC7O=9z^n)t5eJY zlTsCFyAqxAh1%}|N>l|_z+VX={h9PP(l<&wETz=*F)h;Vw^a9S9pe)BQqnBNy^Oy% z*#4yT#Ol^%;un8KxEE@7X|a-~lhmYNapJOwzt@vTNmbk`_$M)%5T&>*qCT8ZMoMX7 zU5KspluqsQTJmr5?xj^r>7^E{h_OujDOV-fNqkbL!IDY;)J~@nnobKzTl!S#bDS!L z5up%Mr8*l^3Gpq$EM=BFiH&fA&{IluBBd7TJPHSyF+j>E9M&<UTjxo7Q_0szUAw|h z!TKH(s_#XFl@b@@PpCDYvN}njg0M0oNvtOJGN37~*h;*{Wg$L;xo_u8Nv%D-(V_IZ z<}Zou_<EN#f^^R$-!m{v{YV`c7ei^GndEcizlA@7<q6U)HB^pZo`Ur2ssu$Lx*KW) z=`n_RNU*(0?HA})V#+10t*f}4ng@lCgL!JF?-+G{D868RzF&PVA+4@c?7B`39mddW z1oQv>)037ZZT7#C-npUlD&SGW1B;2Pk~n47Q3lmcY)Qek*-o)w{>O#l`~LZ#OU`Ak zw3Kwcv|*u8&?Fogti|@!g7rOGT@XsItNJddR;9j7PblrXT=y2zYZlW-O0QL{V+it5 z5SsFg?!-@$D~VD12h-<B|0TTB)ff<rtDT=lci<<<?}_m(gzC}@3MCfk`Y6zSo9QF2 zJ!v|@{Qg(?=lGOljwdwlNbPodx3^QN73np+^t;mEE+CAI7BX`V(%kgmLaF0p3&xk) zq5i%<zewzcM}==>oR<;*_!JC1QajY&_m5v@<}$Yr#$44Y?)LgjRqg$K3H4U4X(zpm zjFlCb1(#7kMmHHL4aH>iF{6VCBiwjAjbsfbzYJy8Te8z9zovj$$BE=we$}?w%xaWM zwasku=wIV8<DcDn{j0Fey==47Hutv84c{359Bk6RJlovQHY?kFs%>6>)cEgjo1M0q zldSsJ__c9A-8Qea%>!+716w0u;7;3|XPXDv=KMC}zSK5n*yi8_+G(3_u-%nyma~KM zYdd1X%P|f49k9*0y6ww+K>CCdT}PK=C-r1{y-YQXe@;e7X{pj8&5SY!Ojc^bB_<cK z_MB4UAF2QGZZUN&vCr2&WzHd^k%>X#yH<0+68@q<jbG<fvIuA9t%Ha?mbGoi*e(pw zD}@-O$0(x>$}eS+udECdv2r&Rrr7L@=%%`bCq!mtWkt#F+*INckIuBb+0ilT{M6K0 zdB~5QPR(L5`3v&-DYdj>DZdze@G@ge3?PPoV*Jk!3OG;rmqI^i{+;M{qK$`|`L=(x z>coG?`(LHn|AndV_pf6Nt5y5IaAZE;=U*_q^FKUrLjB7K_&>}6VXH#_j2is!{u``8 zfvdyX|AmKrzkk8-Cvx<^YV%z!KvL?%zhH`DYR407#sA-3V&kK;|L<4Yc3%mq9XD7Q zy=(igde!Qh+BG-*aBbZ>|IPJ3`tkZ(ZvDw^KmFOyZ@=RgzufSvJAb|LH+S8A&%O8E zzv;KX`~3rd_~V~8KltZ|9)9G}$F^*J{4Y=Z^~t9iwmrRl$1^*3?cVe3b9<kEVPE6^ z7hih$Z?C+1;I)IVzwzeZ-)egMop%qt_x?Yu<_}sv{OIFPT0i~gXP<v@_(<EAUwwTP zRowq=0nNz;FyBi+^S@pG|Lyeu+w}h~0olpjwSeq@yZlk?cgktq;O{ida<(b><ILP~ z=6cK>=Mq2aWd3m{^ZHI^&MO}m{?<<BpL8-m9Dcn2M>?4!$f(Sz8~Eb*E-4Pm8fTR* zDk@(x-CN)-MIMU%%&OwbDf50%T<FbSR8n5KP&>>bjQnuVDX8+g3caO^i}T7Wd=(*k zV`rjMxkxb!<`+*aUur_mME;k>EO0C<ijhbcQ3Y!P+JC!MSKm~<s+tL1#7)&Vt*-79 z6~&Bh&6+h3J~g#EuX-)Bvy`D}d9$jSuQ931%UerOXG-<jYC<Wdbqf|Oh>3|_T2Zm2 zqT+=4ob1e8#wYtXgYiG9z*|t}EUv69uXL6!a+VeN78NciuDsAWL=<PCX_Gmy{3aEY zmK7H{z2(mGisD7i;-$rfK5xOiGA#hdedZ!Dh<gcibQUaf7F6J|h%h1*he#uJJnjA} ziwlaJC6(n131Ol+bCB%qxX76Y8qEfB2}g%Q=3YLJ{DrE)d7ZDg^7_(6^PMF+V<)&* z6??rMoK=;#h~gFbD#}U=bwvgP+VSIF?(?491MU#%<nHa|Dx_fEVrPYsU^{(Pl8vE5 z%BqG+Qtfn{U+jg9rCw)Yc~P;myd)UHWN0KS#ie|~-zaAPRn*2P>O<C=qx5Q6c7~4s zWi73MVNFe$njrp#3k#?dYD2OD8HSFe{)P%xwV-%j0hVQ@i;Ai9G9>QicS1Z%7L<C6 zt11c#i=71}-r`E<&{4js%2D%57mX@jw0LMRa627z>g{|Yso}A-vV76P;ziz||Mql> zD;Jh7qH4$uRRJ@NxXxD&A*u5Y?DnmhChIdgL}S7)DfKRps;%-CRO;COrD)shOP9x{ z7w3aI(;1TJ{F`>vk*=Dc9sL&->niW)$7Yk6GbW8NJFFf3>y(F{In-HTmqNIuV`x%1 z(f^>Kkglw(e2L~iLU*d}lhpI^HP$JWF48HeobQtgt#YOmFQ#WGEpZkvtnglc_IIZ@ z4_2}}jRG=CyDSbdt1zT<Ve!IpdkgIhHH5Wql{$m@xWSy@o$Xj(Pj^rM)8Jpc`SFOK zT>6vWW<C<T?WdQ}b*jt@=SY8EHRp1e?D{$EFG<H<HK(d{VMST-++e>qr>L~bJI8z8 zxRDh_rsFeYI_Y1T947XTQN4@eRPS*;RPSky#`uOF6>p3&`|B?vF!_RS{RbwBufTgE zGzpsfjfg*Y;0}lC@9nAj7R3`soN|nft?bqm*%;0O-kVRqPtdT~NEJH{2|;DIim)DG zst36X>l3T`jB}_yV-i|>HpMl@HpEm!=Xc9X>=�?dYNUd4WaURX_A__M4W}D0!0n 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/util.py b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/util.py new file mode 100644 index 0000000..0b14a93 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/util.py @@ -0,0 +1,1755 @@ +# +# Copyright (C) 2012-2017 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +import codecs +from collections import deque +import contextlib +import csv +from glob import iglob as std_iglob +import io +import json +import logging +import os +import py_compile +import re +import socket +try: + import ssl +except ImportError: # pragma: no cover + ssl = None +import subprocess +import sys +import tarfile +import tempfile +import textwrap + +try: + import threading +except ImportError: # pragma: no cover + import dummy_threading as threading +import time + +from . import DistlibException +from .compat import (string_types, text_type, shutil, raw_input, StringIO, + cache_from_source, urlopen, urljoin, httplib, xmlrpclib, + splittype, HTTPHandler, BaseConfigurator, valid_ident, + Container, configparser, URLError, ZipFile, fsdecode, + unquote, urlparse) + +logger = logging.getLogger(__name__) + +# +# Requirement parsing code as per PEP 508 +# + +IDENTIFIER = re.compile(r'^([\w\.-]+)\s*') +VERSION_IDENTIFIER = re.compile(r'^([\w\.*+-]+)\s*') +COMPARE_OP = re.compile(r'^(<=?|>=?|={2,3}|[~!]=)\s*') +MARKER_OP = re.compile(r'^((<=?)|(>=?)|={2,3}|[~!]=|in|not\s+in)\s*') +OR = re.compile(r'^or\b\s*') +AND = re.compile(r'^and\b\s*') +NON_SPACE = re.compile(r'(\S+)\s*') +STRING_CHUNK = re.compile(r'([\s\w\.{}()*+#:;,/?!~`@$%^&=|<>\[\]-]+)') + + +def parse_marker(marker_string): + """ + Parse a marker string and return a dictionary containing a marker expression. + + The dictionary will contain keys "op", "lhs" and "rhs" for non-terminals in + the expression grammar, or strings. A string contained in quotes is to be + interpreted as a literal string, and a string not contained in quotes is a + variable (such as os_name). + """ + def marker_var(remaining): + # either identifier, or literal string + m = IDENTIFIER.match(remaining) + if m: + result = m.groups()[0] + remaining = remaining[m.end():] + elif not remaining: + raise SyntaxError('unexpected end of input') + else: + q = remaining[0] + if q not in '\'"': + raise SyntaxError('invalid expression: %s' % remaining) + oq = '\'"'.replace(q, '') + remaining = remaining[1:] + parts = [q] + while remaining: + # either a string chunk, or oq, or q to terminate + if remaining[0] == q: + break + elif remaining[0] == oq: + parts.append(oq) + remaining = remaining[1:] + else: + m = STRING_CHUNK.match(remaining) + if not m: + raise SyntaxError('error in string literal: %s' % remaining) + parts.append(m.groups()[0]) + remaining = remaining[m.end():] + else: + s = ''.join(parts) + raise SyntaxError('unterminated string: %s' % s) + parts.append(q) + result = ''.join(parts) + remaining = remaining[1:].lstrip() # skip past closing quote + return result, remaining + + def marker_expr(remaining): + if remaining and remaining[0] == '(': + result, remaining = marker(remaining[1:].lstrip()) + if remaining[0] != ')': + raise SyntaxError('unterminated parenthesis: %s' % remaining) + remaining = remaining[1:].lstrip() + else: + lhs, remaining = marker_var(remaining) + while remaining: + m = MARKER_OP.match(remaining) + if not m: + break + op = m.groups()[0] + remaining = remaining[m.end():] + rhs, remaining = marker_var(remaining) + lhs = {'op': op, 'lhs': lhs, 'rhs': rhs} + result = lhs + return result, remaining + + def marker_and(remaining): + lhs, remaining = marker_expr(remaining) + while remaining: + m = AND.match(remaining) + if not m: + break + remaining = remaining[m.end():] + rhs, remaining = marker_expr(remaining) + lhs = {'op': 'and', 'lhs': lhs, 'rhs': rhs} + return lhs, remaining + + def marker(remaining): + lhs, remaining = marker_and(remaining) + while remaining: + m = OR.match(remaining) + if not m: + break + remaining = remaining[m.end():] + rhs, remaining = marker_and(remaining) + lhs = {'op': 'or', 'lhs': lhs, 'rhs': rhs} + return lhs, remaining + + return marker(marker_string) + + +def parse_requirement(req): + """ + Parse a requirement passed in as a string. Return a Container + whose attributes contain the various parts of the requirement. + """ + remaining = req.strip() + if not remaining or remaining.startswith('#'): + return None + m = IDENTIFIER.match(remaining) + if not m: + raise SyntaxError('name expected: %s' % remaining) + distname = m.groups()[0] + remaining = remaining[m.end():] + extras = mark_expr = versions = uri = None + if remaining and remaining[0] == '[': + i = remaining.find(']', 1) + if i < 0: + raise SyntaxError('unterminated extra: %s' % remaining) + s = remaining[1:i] + remaining = remaining[i + 1:].lstrip() + extras = [] + while s: + m = IDENTIFIER.match(s) + if not m: + raise SyntaxError('malformed extra: %s' % s) + extras.append(m.groups()[0]) + s = s[m.end():] + if not s: + break + if s[0] != ',': + raise SyntaxError('comma expected in extras: %s' % s) + s = s[1:].lstrip() + if not extras: + extras = None + if remaining: + if remaining[0] == '@': + # it's a URI + remaining = remaining[1:].lstrip() + m = NON_SPACE.match(remaining) + if not m: + raise SyntaxError('invalid URI: %s' % remaining) + uri = m.groups()[0] + t = urlparse(uri) + # 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 (t.scheme and t.netloc): + raise SyntaxError('Invalid URL: %s' % uri) + remaining = remaining[m.end():].lstrip() + else: + + def get_versions(ver_remaining): + """ + Return a list of operator, version tuples if any are + specified, else None. + """ + m = COMPARE_OP.match(ver_remaining) + versions = None + if m: + versions = [] + while True: + op = m.groups()[0] + ver_remaining = ver_remaining[m.end():] + m = VERSION_IDENTIFIER.match(ver_remaining) + if not m: + raise SyntaxError('invalid version: %s' % ver_remaining) + v = m.groups()[0] + versions.append((op, v)) + ver_remaining = ver_remaining[m.end():] + if not ver_remaining or ver_remaining[0] != ',': + break + ver_remaining = ver_remaining[1:].lstrip() + m = COMPARE_OP.match(ver_remaining) + if not m: + raise SyntaxError('invalid constraint: %s' % ver_remaining) + if not versions: + versions = None + return versions, ver_remaining + + if remaining[0] != '(': + versions, remaining = get_versions(remaining) + else: + i = remaining.find(')', 1) + if i < 0: + raise SyntaxError('unterminated parenthesis: %s' % remaining) + s = remaining[1:i] + remaining = remaining[i + 1:].lstrip() + # As a special diversion from PEP 508, allow a version number + # a.b.c in parentheses as a synonym for ~= a.b.c (because this + # is allowed in earlier PEPs) + if COMPARE_OP.match(s): + versions, _ = get_versions(s) + else: + m = VERSION_IDENTIFIER.match(s) + if not m: + raise SyntaxError('invalid constraint: %s' % s) + v = m.groups()[0] + s = s[m.end():].lstrip() + if s: + raise SyntaxError('invalid constraint: %s' % s) + versions = [('~=', v)] + + if remaining: + if remaining[0] != ';': + raise SyntaxError('invalid requirement: %s' % remaining) + remaining = remaining[1:].lstrip() + + mark_expr, remaining = parse_marker(remaining) + + if remaining and remaining[0] != '#': + raise SyntaxError('unexpected trailing data: %s' % remaining) + + if not versions: + rs = distname + else: + rs = '%s %s' % (distname, ', '.join(['%s %s' % con for con in versions])) + return Container(name=distname, extras=extras, constraints=versions, + marker=mark_expr, url=uri, requirement=rs) + + +def get_resources_dests(resources_root, rules): + """Find destinations for resources files""" + + def get_rel_path(root, path): + # normalizes and returns a lstripped-/-separated path + root = root.replace(os.path.sep, '/') + path = path.replace(os.path.sep, '/') + assert path.startswith(root) + return path[len(root):].lstrip('/') + + destinations = {} + for base, suffix, dest in rules: + prefix = os.path.join(resources_root, base) + for abs_base in iglob(prefix): + abs_glob = os.path.join(abs_base, suffix) + for abs_path in iglob(abs_glob): + resource_file = get_rel_path(resources_root, abs_path) + if dest is None: # remove the entry if it was here + destinations.pop(resource_file, None) + else: + rel_path = get_rel_path(abs_base, abs_path) + rel_dest = dest.replace(os.path.sep, '/').rstrip('/') + destinations[resource_file] = rel_dest + '/' + rel_path + return destinations + + +def in_venv(): + if hasattr(sys, 'real_prefix'): + # virtualenv venvs + result = True + else: + # PEP 405 venvs + result = sys.prefix != getattr(sys, 'base_prefix', sys.prefix) + return result + + +def get_executable(): +# The __PYVENV_LAUNCHER__ dance is apparently no longer needed, as +# changes to the stub launcher mean that sys.executable always points +# to the stub on OS X +# if sys.platform == 'darwin' and ('__PYVENV_LAUNCHER__' +# in os.environ): +# result = os.environ['__PYVENV_LAUNCHER__'] +# else: +# result = sys.executable +# return result + result = os.path.normcase(sys.executable) + if not isinstance(result, text_type): + result = fsdecode(result) + return result + + +def proceed(prompt, allowed_chars, error_prompt=None, default=None): + p = prompt + while True: + s = raw_input(p) + p = prompt + if not s and default: + s = default + if s: + c = s[0].lower() + if c in allowed_chars: + break + if error_prompt: + p = '%c: %s\n%s' % (c, error_prompt, prompt) + return c + + +def extract_by_key(d, keys): + if isinstance(keys, string_types): + keys = keys.split() + result = {} + for key in keys: + if key in d: + result[key] = d[key] + return result + +def read_exports(stream): + if sys.version_info[0] >= 3: + # needs to be a text stream + stream = codecs.getreader('utf-8')(stream) + # Try to load as JSON, falling back on legacy format + data = stream.read() + stream = StringIO(data) + try: + jdata = json.load(stream) + result = jdata['extensions']['python.exports']['exports'] + for group, entries in result.items(): + for k, v in entries.items(): + s = '%s = %s' % (k, v) + entry = get_export_entry(s) + assert entry is not None + entries[k] = entry + return result + except Exception: + stream.seek(0, 0) + + def read_stream(cp, stream): + if hasattr(cp, 'read_file'): + cp.read_file(stream) + else: + cp.readfp(stream) + + cp = configparser.ConfigParser() + try: + read_stream(cp, stream) + except configparser.MissingSectionHeaderError: + stream.close() + data = textwrap.dedent(data) + stream = StringIO(data) + read_stream(cp, stream) + + result = {} + for key in cp.sections(): + result[key] = entries = {} + for name, value in cp.items(key): + s = '%s = %s' % (name, value) + entry = get_export_entry(s) + assert entry is not None + #entry.dist = self + entries[name] = entry + return result + + +def write_exports(exports, stream): + if sys.version_info[0] >= 3: + # needs to be a text stream + stream = codecs.getwriter('utf-8')(stream) + cp = configparser.ConfigParser() + for k, v in exports.items(): + # TODO check k, v for valid values + cp.add_section(k) + for entry in v.values(): + if entry.suffix is None: + s = entry.prefix + else: + s = '%s:%s' % (entry.prefix, entry.suffix) + if entry.flags: + s = '%s [%s]' % (s, ', '.join(entry.flags)) + cp.set(k, entry.name, s) + cp.write(stream) + + +@contextlib.contextmanager +def tempdir(): + td = tempfile.mkdtemp() + try: + yield td + finally: + shutil.rmtree(td) + +@contextlib.contextmanager +def chdir(d): + cwd = os.getcwd() + try: + os.chdir(d) + yield + finally: + os.chdir(cwd) + + +@contextlib.contextmanager +def socket_timeout(seconds=15): + cto = socket.getdefaulttimeout() + try: + socket.setdefaulttimeout(seconds) + yield + finally: + socket.setdefaulttimeout(cto) + + +class cached_property(object): + def __init__(self, func): + self.func = func + #for attr in ('__name__', '__module__', '__doc__'): + # setattr(self, attr, getattr(func, attr, None)) + + def __get__(self, obj, cls=None): + if obj is None: + return self + value = self.func(obj) + object.__setattr__(obj, self.func.__name__, value) + #obj.__dict__[self.func.__name__] = value = self.func(obj) + return value + +def convert_path(pathname): + """Return 'pathname' as a name that will work on the native filesystem. + + The path is split on '/' and put back together again using the current + directory separator. Needed because filenames in the setup script are + always supplied in Unix style, and have to be converted to the local + convention before we can actually use them in the filesystem. Raises + ValueError on non-Unix-ish systems if 'pathname' either starts or + ends with a slash. + """ + if os.sep == '/': + return pathname + if not pathname: + return pathname + if pathname[0] == '/': + raise ValueError("path '%s' cannot be absolute" % pathname) + if pathname[-1] == '/': + raise ValueError("path '%s' cannot end with '/'" % pathname) + + paths = pathname.split('/') + while os.curdir in paths: + paths.remove(os.curdir) + if not paths: + return os.curdir + return os.path.join(*paths) + + +class FileOperator(object): + def __init__(self, dry_run=False): + self.dry_run = dry_run + self.ensured = set() + self._init_record() + + def _init_record(self): + self.record = False + self.files_written = set() + self.dirs_created = set() + + def record_as_written(self, path): + if self.record: + self.files_written.add(path) + + def newer(self, source, target): + """Tell if the target is newer than the source. + + Returns true if 'source' exists and is more recently modified than + 'target', or if 'source' exists and 'target' doesn't. + + Returns false if both exist and 'target' is the same age or younger + than 'source'. Raise PackagingFileError if 'source' does not exist. + + Note that this test is not very accurate: files created in the same + second will have the same "age". + """ + if not os.path.exists(source): + raise DistlibException("file '%r' does not exist" % + os.path.abspath(source)) + if not os.path.exists(target): + return True + + return os.stat(source).st_mtime > os.stat(target).st_mtime + + def copy_file(self, infile, outfile, check=True): + """Copy a file respecting dry-run and force flags. + """ + self.ensure_dir(os.path.dirname(outfile)) + logger.info('Copying %s to %s', infile, outfile) + if not self.dry_run: + msg = None + if check: + if os.path.islink(outfile): + msg = '%s is a symlink' % outfile + elif os.path.exists(outfile) and not os.path.isfile(outfile): + msg = '%s is a non-regular file' % outfile + if msg: + raise ValueError(msg + ' which would be overwritten') + shutil.copyfile(infile, outfile) + self.record_as_written(outfile) + + def copy_stream(self, instream, outfile, encoding=None): + assert not os.path.isdir(outfile) + self.ensure_dir(os.path.dirname(outfile)) + logger.info('Copying stream %s to %s', instream, outfile) + if not self.dry_run: + if encoding is None: + outstream = open(outfile, 'wb') + else: + outstream = codecs.open(outfile, 'w', encoding=encoding) + try: + shutil.copyfileobj(instream, outstream) + finally: + outstream.close() + self.record_as_written(outfile) + + def write_binary_file(self, path, data): + self.ensure_dir(os.path.dirname(path)) + if not self.dry_run: + with open(path, 'wb') as f: + f.write(data) + self.record_as_written(path) + + def write_text_file(self, path, data, encoding): + self.ensure_dir(os.path.dirname(path)) + if not self.dry_run: + with open(path, 'wb') as f: + f.write(data.encode(encoding)) + self.record_as_written(path) + + def set_mode(self, bits, mask, files): + if os.name == 'posix' or (os.name == 'java' and os._name == 'posix'): + # Set the executable bits (owner, group, and world) on + # all the files specified. + for f in files: + if self.dry_run: + logger.info("changing mode of %s", f) + else: + mode = (os.stat(f).st_mode | bits) & mask + logger.info("changing mode of %s to %o", f, mode) + os.chmod(f, mode) + + set_executable_mode = lambda s, f: s.set_mode(0o555, 0o7777, f) + + def ensure_dir(self, path): + path = os.path.abspath(path) + if path not in self.ensured and not os.path.exists(path): + self.ensured.add(path) + d, f = os.path.split(path) + self.ensure_dir(d) + logger.info('Creating %s' % path) + if not self.dry_run: + os.mkdir(path) + if self.record: + self.dirs_created.add(path) + + def byte_compile(self, path, optimize=False, force=False, prefix=None): + dpath = cache_from_source(path, not optimize) + logger.info('Byte-compiling %s to %s', path, dpath) + if not self.dry_run: + if force or self.newer(path, dpath): + if not prefix: + diagpath = None + else: + assert path.startswith(prefix) + diagpath = path[len(prefix):] + py_compile.compile(path, dpath, diagpath, True) # raise error + self.record_as_written(dpath) + return dpath + + def ensure_removed(self, path): + if os.path.exists(path): + if os.path.isdir(path) and not os.path.islink(path): + logger.debug('Removing directory tree at %s', path) + if not self.dry_run: + shutil.rmtree(path) + if self.record: + if path in self.dirs_created: + self.dirs_created.remove(path) + else: + if os.path.islink(path): + s = 'link' + else: + s = 'file' + logger.debug('Removing %s %s', s, path) + if not self.dry_run: + os.remove(path) + if self.record: + if path in self.files_written: + self.files_written.remove(path) + + def is_writable(self, path): + result = False + while not result: + if os.path.exists(path): + result = os.access(path, os.W_OK) + break + parent = os.path.dirname(path) + if parent == path: + break + path = parent + return result + + def commit(self): + """ + Commit recorded changes, turn off recording, return + changes. + """ + assert self.record + result = self.files_written, self.dirs_created + self._init_record() + return result + + def rollback(self): + if not self.dry_run: + for f in list(self.files_written): + if os.path.exists(f): + os.remove(f) + # dirs should all be empty now, except perhaps for + # __pycache__ subdirs + # reverse so that subdirs appear before their parents + dirs = sorted(self.dirs_created, reverse=True) + for d in dirs: + flist = os.listdir(d) + if flist: + assert flist == ['__pycache__'] + sd = os.path.join(d, flist[0]) + os.rmdir(sd) + os.rmdir(d) # should fail if non-empty + self._init_record() + +def resolve(module_name, dotted_path): + if module_name in sys.modules: + mod = sys.modules[module_name] + else: + mod = __import__(module_name) + if dotted_path is None: + result = mod + else: + parts = dotted_path.split('.') + result = getattr(mod, parts.pop(0)) + for p in parts: + result = getattr(result, p) + return result + + +class ExportEntry(object): + def __init__(self, name, prefix, suffix, flags): + self.name = name + self.prefix = prefix + self.suffix = suffix + self.flags = flags + + @cached_property + def value(self): + return resolve(self.prefix, self.suffix) + + def __repr__(self): # pragma: no cover + return '<ExportEntry %s = %s:%s %s>' % (self.name, self.prefix, + self.suffix, self.flags) + + def __eq__(self, other): + if not isinstance(other, ExportEntry): + result = False + else: + result = (self.name == other.name and + self.prefix == other.prefix and + self.suffix == other.suffix and + self.flags == other.flags) + return result + + __hash__ = object.__hash__ + + +ENTRY_RE = re.compile(r'''(?P<name>(\w|[-.+])+) + \s*=\s*(?P<callable>(\w+)([:\.]\w+)*) + \s*(\[\s*(?P<flags>\w+(=\w+)?(,\s*\w+(=\w+)?)*)\s*\])? + ''', re.VERBOSE) + +def get_export_entry(specification): + m = ENTRY_RE.search(specification) + if not m: + result = None + if '[' in specification or ']' in specification: + raise DistlibException("Invalid specification " + "'%s'" % specification) + else: + d = m.groupdict() + name = d['name'] + path = d['callable'] + colons = path.count(':') + if colons == 0: + prefix, suffix = path, None + else: + if colons != 1: + raise DistlibException("Invalid specification " + "'%s'" % specification) + prefix, suffix = path.split(':') + flags = d['flags'] + if flags is None: + if '[' in specification or ']' in specification: + raise DistlibException("Invalid specification " + "'%s'" % specification) + flags = [] + else: + flags = [f.strip() for f in flags.split(',')] + result = ExportEntry(name, prefix, suffix, flags) + return result + + +def get_cache_base(suffix=None): + """ + Return the default base location for distlib caches. If the directory does + not exist, it is created. Use the suffix provided for the base directory, + and default to '.distlib' if it isn't provided. + + On Windows, if LOCALAPPDATA is defined in the environment, then it is + assumed to be a directory, and will be the parent directory of the result. + On POSIX, and on Windows if LOCALAPPDATA is not defined, the user's home + directory - using os.expanduser('~') - will be the parent directory of + the result. + + The result is just the directory '.distlib' in the parent directory as + determined above, or with the name specified with ``suffix``. + """ + if suffix is None: + suffix = '.distlib' + if os.name == 'nt' and 'LOCALAPPDATA' in os.environ: + result = os.path.expandvars('$localappdata') + else: + # Assume posix, or old Windows + result = os.path.expanduser('~') + # we use 'isdir' instead of 'exists', because we want to + # fail if there's a file with that name + if os.path.isdir(result): + usable = os.access(result, os.W_OK) + if not usable: + logger.warning('Directory exists but is not writable: %s', result) + else: + try: + os.makedirs(result) + usable = True + except OSError: + logger.warning('Unable to create %s', result, exc_info=True) + usable = False + if not usable: + result = tempfile.mkdtemp() + logger.warning('Default location unusable, using %s', result) + return os.path.join(result, suffix) + + +def path_to_cache_dir(path): + """ + Convert an absolute path to a directory name for use in a cache. + + The algorithm used is: + + #. On Windows, any ``':'`` in the drive is replaced with ``'---'``. + #. Any occurrence of ``os.sep`` is replaced with ``'--'``. + #. ``'.cache'`` is appended. + """ + d, p = os.path.splitdrive(os.path.abspath(path)) + if d: + d = d.replace(':', '---') + p = p.replace(os.sep, '--') + return d + p + '.cache' + + +def ensure_slash(s): + if not s.endswith('/'): + return s + '/' + return s + + +def parse_credentials(netloc): + username = password = None + if '@' in netloc: + prefix, netloc = netloc.split('@', 1) + if ':' not in prefix: + username = prefix + else: + username, password = prefix.split(':', 1) + return username, password, netloc + + +def get_process_umask(): + result = os.umask(0o22) + os.umask(result) + return result + +def is_string_sequence(seq): + result = True + i = None + for i, s in enumerate(seq): + if not isinstance(s, string_types): + result = False + break + assert i is not None + return result + +PROJECT_NAME_AND_VERSION = re.compile('([a-z0-9_]+([.-][a-z_][a-z0-9_]*)*)-' + '([a-z0-9_.+-]+)', re.I) +PYTHON_VERSION = re.compile(r'-py(\d\.?\d?)') + + +def split_filename(filename, project_name=None): + """ + Extract name, version, python version from a filename (no extension) + + Return name, version, pyver or None + """ + result = None + pyver = None + filename = unquote(filename).replace(' ', '-') + m = PYTHON_VERSION.search(filename) + if m: + pyver = m.group(1) + filename = filename[:m.start()] + if project_name and len(filename) > len(project_name) + 1: + m = re.match(re.escape(project_name) + r'\b', filename) + if m: + n = m.end() + result = filename[:n], filename[n + 1:], pyver + if result is None: + m = PROJECT_NAME_AND_VERSION.match(filename) + if m: + result = m.group(1), m.group(3), pyver + return result + +# Allow spaces in name because of legacy dists like "Twisted Core" +NAME_VERSION_RE = re.compile(r'(?P<name>[\w .-]+)\s*' + r'\(\s*(?P<ver>[^\s)]+)\)$') + +def parse_name_and_version(p): + """ + A utility method used to get name and version from a string. + + From e.g. a Provides-Dist value. + + :param p: A value in a form 'foo (1.0)' + :return: The name and version as a tuple. + """ + m = NAME_VERSION_RE.match(p) + if not m: + raise DistlibException('Ill-formed name/version string: \'%s\'' % p) + d = m.groupdict() + return d['name'].strip().lower(), d['ver'] + +def get_extras(requested, available): + result = set() + requested = set(requested or []) + available = set(available or []) + if '*' in requested: + requested.remove('*') + result |= available + for r in requested: + if r == '-': + result.add(r) + elif r.startswith('-'): + unwanted = r[1:] + if unwanted not in available: + logger.warning('undeclared extra: %s' % unwanted) + if unwanted in result: + result.remove(unwanted) + else: + if r not in available: + logger.warning('undeclared extra: %s' % r) + result.add(r) + return result +# +# Extended metadata functionality +# + +def _get_external_data(url): + result = {} + try: + # urlopen might fail if it runs into redirections, + # because of Python issue #13696. Fixed in locators + # using a custom redirect handler. + resp = urlopen(url) + headers = resp.info() + ct = headers.get('Content-Type') + if not ct.startswith('application/json'): + logger.debug('Unexpected response for JSON request: %s', ct) + else: + reader = codecs.getreader('utf-8')(resp) + #data = reader.read().decode('utf-8') + #result = json.loads(data) + result = json.load(reader) + except Exception as e: + logger.exception('Failed to get external data for %s: %s', url, e) + return result + +_external_data_base_url = 'https://www.red-dove.com/pypi/projects/' + +def get_project_data(name): + url = '%s/%s/project.json' % (name[0].upper(), name) + url = urljoin(_external_data_base_url, url) + result = _get_external_data(url) + return result + +def get_package_data(name, version): + url = '%s/%s/package-%s.json' % (name[0].upper(), name, version) + url = urljoin(_external_data_base_url, url) + return _get_external_data(url) + + +class Cache(object): + """ + A class implementing a cache for resources that need to live in the file system + e.g. shared libraries. This class was moved from resources to here because it + could be used by other modules, e.g. the wheel module. + """ + + def __init__(self, base): + """ + Initialise an instance. + + :param base: The base directory where the cache should be located. + """ + # we use 'isdir' instead of 'exists', because we want to + # fail if there's a file with that name + if not os.path.isdir(base): # pragma: no cover + os.makedirs(base) + if (os.stat(base).st_mode & 0o77) != 0: + logger.warning('Directory \'%s\' is not private', base) + self.base = os.path.abspath(os.path.normpath(base)) + + def prefix_to_dir(self, prefix): + """ + Converts a resource prefix to a directory name in the cache. + """ + return path_to_cache_dir(prefix) + + def clear(self): + """ + Clear the cache. + """ + not_removed = [] + for fn in os.listdir(self.base): + fn = os.path.join(self.base, fn) + try: + if os.path.islink(fn) or os.path.isfile(fn): + os.remove(fn) + elif os.path.isdir(fn): + shutil.rmtree(fn) + except Exception: + not_removed.append(fn) + return not_removed + + +class EventMixin(object): + """ + A very simple publish/subscribe system. + """ + def __init__(self): + self._subscribers = {} + + def add(self, event, subscriber, append=True): + """ + Add a subscriber for an event. + + :param event: The name of an event. + :param subscriber: The subscriber to be added (and called when the + event is published). + :param append: Whether to append or prepend the subscriber to an + existing subscriber list for the event. + """ + subs = self._subscribers + if event not in subs: + subs[event] = deque([subscriber]) + else: + sq = subs[event] + if append: + sq.append(subscriber) + else: + sq.appendleft(subscriber) + + def remove(self, event, subscriber): + """ + Remove a subscriber for an event. + + :param event: The name of an event. + :param subscriber: The subscriber to be removed. + """ + subs = self._subscribers + if event not in subs: + raise ValueError('No subscribers: %r' % event) + subs[event].remove(subscriber) + + def get_subscribers(self, event): + """ + Return an iterator for the subscribers for an event. + :param event: The event to return subscribers for. + """ + return iter(self._subscribers.get(event, ())) + + def publish(self, event, *args, **kwargs): + """ + Publish a event and return a list of values returned by its + subscribers. + + :param event: The event to publish. + :param args: The positional arguments to pass to the event's + subscribers. + :param kwargs: The keyword arguments to pass to the event's + subscribers. + """ + result = [] + for subscriber in self.get_subscribers(event): + try: + value = subscriber(event, *args, **kwargs) + except Exception: + logger.exception('Exception during event publication') + value = None + result.append(value) + logger.debug('publish %s: args = %s, kwargs = %s, result = %s', + event, args, kwargs, result) + return result + +# +# Simple sequencing +# +class Sequencer(object): + def __init__(self): + self._preds = {} + self._succs = {} + self._nodes = set() # nodes with no preds/succs + + def add_node(self, node): + self._nodes.add(node) + + def remove_node(self, node, edges=False): + if node in self._nodes: + self._nodes.remove(node) + if edges: + for p in set(self._preds.get(node, ())): + self.remove(p, node) + for s in set(self._succs.get(node, ())): + self.remove(node, s) + # Remove empties + for k, v in list(self._preds.items()): + if not v: + del self._preds[k] + for k, v in list(self._succs.items()): + if not v: + del self._succs[k] + + def add(self, pred, succ): + assert pred != succ + self._preds.setdefault(succ, set()).add(pred) + self._succs.setdefault(pred, set()).add(succ) + + def remove(self, pred, succ): + assert pred != succ + try: + preds = self._preds[succ] + succs = self._succs[pred] + except KeyError: # pragma: no cover + raise ValueError('%r not a successor of anything' % succ) + try: + preds.remove(pred) + succs.remove(succ) + except KeyError: # pragma: no cover + raise ValueError('%r not a successor of %r' % (succ, pred)) + + def is_step(self, step): + return (step in self._preds or step in self._succs or + step in self._nodes) + + def get_steps(self, final): + if not self.is_step(final): + raise ValueError('Unknown: %r' % final) + result = [] + todo = [] + seen = set() + todo.append(final) + while todo: + step = todo.pop(0) + if step in seen: + # if a step was already seen, + # move it to the end (so it will appear earlier + # when reversed on return) ... but not for the + # final step, as that would be confusing for + # users + if step != final: + result.remove(step) + result.append(step) + else: + seen.add(step) + result.append(step) + preds = self._preds.get(step, ()) + todo.extend(preds) + return reversed(result) + + @property + def strong_connections(self): + #http://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm + index_counter = [0] + stack = [] + lowlinks = {} + index = {} + result = [] + + graph = self._succs + + def strongconnect(node): + # set the depth index for this node to the smallest unused index + index[node] = index_counter[0] + lowlinks[node] = index_counter[0] + index_counter[0] += 1 + stack.append(node) + + # Consider successors + try: + successors = graph[node] + except Exception: + successors = [] + for successor in successors: + if successor not in lowlinks: + # Successor has not yet been visited + strongconnect(successor) + lowlinks[node] = min(lowlinks[node],lowlinks[successor]) + elif successor in stack: + # the successor is in the stack and hence in the current + # strongly connected component (SCC) + lowlinks[node] = min(lowlinks[node],index[successor]) + + # If `node` is a root node, pop the stack and generate an SCC + if lowlinks[node] == index[node]: + connected_component = [] + + while True: + successor = stack.pop() + connected_component.append(successor) + if successor == node: break + component = tuple(connected_component) + # storing the result + result.append(component) + + for node in graph: + if node not in lowlinks: + strongconnect(node) + + return result + + @property + def dot(self): + result = ['digraph G {'] + for succ in self._preds: + preds = self._preds[succ] + for pred in preds: + result.append(' %s -> %s;' % (pred, succ)) + for node in self._nodes: + result.append(' %s;' % node) + result.append('}') + return '\n'.join(result) + +# +# Unarchiving functionality for zip, tar, tgz, tbz, whl +# + +ARCHIVE_EXTENSIONS = ('.tar.gz', '.tar.bz2', '.tar', '.zip', + '.tgz', '.tbz', '.whl') + +def unarchive(archive_filename, dest_dir, format=None, check=True): + + def check_path(path): + if not isinstance(path, text_type): + path = path.decode('utf-8') + p = os.path.abspath(os.path.join(dest_dir, path)) + if not p.startswith(dest_dir) or p[plen] != os.sep: + raise ValueError('path outside destination: %r' % p) + + dest_dir = os.path.abspath(dest_dir) + plen = len(dest_dir) + archive = None + if format is None: + if archive_filename.endswith(('.zip', '.whl')): + format = 'zip' + elif archive_filename.endswith(('.tar.gz', '.tgz')): + format = 'tgz' + mode = 'r:gz' + elif archive_filename.endswith(('.tar.bz2', '.tbz')): + format = 'tbz' + mode = 'r:bz2' + elif archive_filename.endswith('.tar'): + format = 'tar' + mode = 'r' + else: # pragma: no cover + raise ValueError('Unknown format for %r' % archive_filename) + try: + if format == 'zip': + archive = ZipFile(archive_filename, 'r') + if check: + names = archive.namelist() + for name in names: + check_path(name) + else: + archive = tarfile.open(archive_filename, mode) + if check: + names = archive.getnames() + for name in names: + check_path(name) + if format != 'zip' and sys.version_info[0] < 3: + # See Python issue 17153. If the dest path contains Unicode, + # tarfile extraction fails on Python 2.x if a member path name + # contains non-ASCII characters - it leads to an implicit + # bytes -> unicode conversion using ASCII to decode. + for tarinfo in archive.getmembers(): + if not isinstance(tarinfo.name, text_type): + tarinfo.name = tarinfo.name.decode('utf-8') + archive.extractall(dest_dir) + + finally: + if archive: + archive.close() + + +def zip_dir(directory): + """zip a directory tree into a BytesIO object""" + result = io.BytesIO() + dlen = len(directory) + with ZipFile(result, "w") as zf: + for root, dirs, files in os.walk(directory): + for name in files: + full = os.path.join(root, name) + rel = root[dlen:] + dest = os.path.join(rel, name) + zf.write(full, dest) + return result + +# +# Simple progress bar +# + +UNITS = ('', 'K', 'M', 'G','T','P') + + +class Progress(object): + unknown = 'UNKNOWN' + + def __init__(self, minval=0, maxval=100): + assert maxval is None or maxval >= minval + self.min = self.cur = minval + self.max = maxval + self.started = None + self.elapsed = 0 + self.done = False + + def update(self, curval): + assert self.min <= curval + assert self.max is None or curval <= self.max + self.cur = curval + now = time.time() + if self.started is None: + self.started = now + else: + self.elapsed = now - self.started + + def increment(self, incr): + assert incr >= 0 + self.update(self.cur + incr) + + def start(self): + self.update(self.min) + return self + + def stop(self): + if self.max is not None: + self.update(self.max) + self.done = True + + @property + def maximum(self): + return self.unknown if self.max is None else self.max + + @property + def percentage(self): + if self.done: + result = '100 %' + elif self.max is None: + result = ' ?? %' + else: + v = 100.0 * (self.cur - self.min) / (self.max - self.min) + result = '%3d %%' % v + return result + + def format_duration(self, duration): + if (duration <= 0) and self.max is None or self.cur == self.min: + result = '??:??:??' + #elif duration < 1: + # result = '--:--:--' + else: + result = time.strftime('%H:%M:%S', time.gmtime(duration)) + return result + + @property + def ETA(self): + if self.done: + prefix = 'Done' + t = self.elapsed + #import pdb; pdb.set_trace() + else: + prefix = 'ETA ' + if self.max is None: + t = -1 + elif self.elapsed == 0 or (self.cur == self.min): + t = 0 + else: + #import pdb; pdb.set_trace() + t = float(self.max - self.min) + t /= self.cur - self.min + t = (t - 1) * self.elapsed + return '%s: %s' % (prefix, self.format_duration(t)) + + @property + def speed(self): + if self.elapsed == 0: + result = 0.0 + else: + result = (self.cur - self.min) / self.elapsed + for unit in UNITS: + if result < 1000: + break + result /= 1000.0 + return '%d %sB/s' % (result, unit) + +# +# Glob functionality +# + +RICH_GLOB = re.compile(r'\{([^}]*)\}') +_CHECK_RECURSIVE_GLOB = re.compile(r'[^/\\,{]\*\*|\*\*[^/\\,}]') +_CHECK_MISMATCH_SET = re.compile(r'^[^{]*\}|\{[^}]*$') + + +def iglob(path_glob): + """Extended globbing function that supports ** and {opt1,opt2,opt3}.""" + if _CHECK_RECURSIVE_GLOB.search(path_glob): + msg = """invalid glob %r: recursive glob "**" must be used alone""" + raise ValueError(msg % path_glob) + if _CHECK_MISMATCH_SET.search(path_glob): + msg = """invalid glob %r: mismatching set marker '{' or '}'""" + raise ValueError(msg % path_glob) + return _iglob(path_glob) + + +def _iglob(path_glob): + rich_path_glob = RICH_GLOB.split(path_glob, 1) + if len(rich_path_glob) > 1: + assert len(rich_path_glob) == 3, rich_path_glob + prefix, set, suffix = rich_path_glob + for item in set.split(','): + for path in _iglob(''.join((prefix, item, suffix))): + yield path + else: + if '**' not in path_glob: + for item in std_iglob(path_glob): + yield item + else: + prefix, radical = path_glob.split('**', 1) + if prefix == '': + prefix = '.' + if radical == '': + radical = '*' + else: + # we support both + radical = radical.lstrip('/') + radical = radical.lstrip('\\') + for path, dir, files in os.walk(prefix): + path = os.path.normpath(path) + for fn in _iglob(os.path.join(path, radical)): + yield fn + +if ssl: + from .compat import (HTTPSHandler as BaseHTTPSHandler, match_hostname, + CertificateError) + + +# +# HTTPSConnection which verifies certificates/matches domains +# + + class HTTPSConnection(httplib.HTTPSConnection): + ca_certs = None # set this to the path to the certs file (.pem) + check_domain = True # only used if ca_certs is not None + + # noinspection PyPropertyAccess + def connect(self): + sock = socket.create_connection((self.host, self.port), self.timeout) + if getattr(self, '_tunnel_host', False): + self.sock = sock + self._tunnel() + + if not hasattr(ssl, 'SSLContext'): + # For 2.x + if self.ca_certs: + cert_reqs = ssl.CERT_REQUIRED + else: + cert_reqs = ssl.CERT_NONE + self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, + cert_reqs=cert_reqs, + ssl_version=ssl.PROTOCOL_SSLv23, + ca_certs=self.ca_certs) + else: # pragma: no cover + context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + context.options |= ssl.OP_NO_SSLv2 + if self.cert_file: + context.load_cert_chain(self.cert_file, self.key_file) + kwargs = {} + if self.ca_certs: + context.verify_mode = ssl.CERT_REQUIRED + context.load_verify_locations(cafile=self.ca_certs) + if getattr(ssl, 'HAS_SNI', False): + kwargs['server_hostname'] = self.host + self.sock = context.wrap_socket(sock, **kwargs) + if self.ca_certs and self.check_domain: + try: + match_hostname(self.sock.getpeercert(), self.host) + logger.debug('Host verified: %s', self.host) + except CertificateError: # pragma: no cover + self.sock.shutdown(socket.SHUT_RDWR) + self.sock.close() + raise + + class HTTPSHandler(BaseHTTPSHandler): + def __init__(self, ca_certs, check_domain=True): + BaseHTTPSHandler.__init__(self) + self.ca_certs = ca_certs + self.check_domain = check_domain + + def _conn_maker(self, *args, **kwargs): + """ + This is called to create a connection instance. Normally you'd + pass a connection class to do_open, but it doesn't actually check for + a class, and just expects a callable. As long as we behave just as a + constructor would have, we should be OK. If it ever changes so that + we *must* pass a class, we'll create an UnsafeHTTPSConnection class + which just sets check_domain to False in the class definition, and + choose which one to pass to do_open. + """ + result = HTTPSConnection(*args, **kwargs) + if self.ca_certs: + result.ca_certs = self.ca_certs + result.check_domain = self.check_domain + return result + + def https_open(self, req): + try: + return self.do_open(self._conn_maker, req) + except URLError as e: + if 'certificate verify failed' in str(e.reason): + raise CertificateError('Unable to verify server certificate ' + 'for %s' % req.host) + else: + raise + + # + # To prevent against mixing HTTP traffic with HTTPS (examples: A Man-In-The- + # Middle proxy using HTTP listens on port 443, or an index mistakenly serves + # HTML containing a http://xyz link when it should be https://xyz), + # you can use the following handler class, which does not allow HTTP traffic. + # + # It works by inheriting from HTTPHandler - so build_opener won't add a + # handler for HTTP itself. + # + class HTTPSOnlyHandler(HTTPSHandler, HTTPHandler): + def http_open(self, req): + raise URLError('Unexpected HTTP request on what should be a secure ' + 'connection: %s' % req) + +# +# XML-RPC with timeouts +# + +_ver_info = sys.version_info[:2] + +if _ver_info == (2, 6): + class HTTP(httplib.HTTP): + def __init__(self, host='', port=None, **kwargs): + if port == 0: # 0 means use port 0, not the default port + port = None + self._setup(self._connection_class(host, port, **kwargs)) + + + if ssl: + class HTTPS(httplib.HTTPS): + def __init__(self, host='', port=None, **kwargs): + if port == 0: # 0 means use port 0, not the default port + port = None + self._setup(self._connection_class(host, port, **kwargs)) + + +class Transport(xmlrpclib.Transport): + def __init__(self, timeout, use_datetime=0): + self.timeout = timeout + xmlrpclib.Transport.__init__(self, use_datetime) + + def make_connection(self, host): + h, eh, x509 = self.get_host_info(host) + if _ver_info == (2, 6): + result = HTTP(h, timeout=self.timeout) + else: + if not self._connection or host != self._connection[0]: + self._extra_headers = eh + self._connection = host, httplib.HTTPConnection(h) + result = self._connection[1] + return result + +if ssl: + class SafeTransport(xmlrpclib.SafeTransport): + def __init__(self, timeout, use_datetime=0): + self.timeout = timeout + xmlrpclib.SafeTransport.__init__(self, use_datetime) + + def make_connection(self, host): + h, eh, kwargs = self.get_host_info(host) + if not kwargs: + kwargs = {} + kwargs['timeout'] = self.timeout + if _ver_info == (2, 6): + result = HTTPS(host, None, **kwargs) + else: + if not self._connection or host != self._connection[0]: + self._extra_headers = eh + self._connection = host, httplib.HTTPSConnection(h, None, + **kwargs) + result = self._connection[1] + return result + + +class ServerProxy(xmlrpclib.ServerProxy): + def __init__(self, uri, **kwargs): + self.timeout = timeout = kwargs.pop('timeout', None) + # The above classes only come into play if a timeout + # is specified + if timeout is not None: + scheme, _ = splittype(uri) + use_datetime = kwargs.get('use_datetime', 0) + if scheme == 'https': + tcls = SafeTransport + else: + tcls = Transport + kwargs['transport'] = t = tcls(timeout, use_datetime=use_datetime) + self.transport = t + xmlrpclib.ServerProxy.__init__(self, uri, **kwargs) + +# +# CSV functionality. This is provided because on 2.x, the csv module can't +# handle Unicode. However, we need to deal with Unicode in e.g. RECORD files. +# + +def _csv_open(fn, mode, **kwargs): + if sys.version_info[0] < 3: + mode += 'b' + else: + kwargs['newline'] = '' + # Python 3 determines encoding from locale. Force 'utf-8' + # file encoding to match other forced utf-8 encoding + kwargs['encoding'] = 'utf-8' + return open(fn, mode, **kwargs) + + +class CSVBase(object): + defaults = { + 'delimiter': str(','), # The strs are used because we need native + 'quotechar': str('"'), # str in the csv API (2.x won't take + 'lineterminator': str('\n') # Unicode) + } + + def __enter__(self): + return self + + def __exit__(self, *exc_info): + self.stream.close() + + +class CSVReader(CSVBase): + def __init__(self, **kwargs): + if 'stream' in kwargs: + stream = kwargs['stream'] + if sys.version_info[0] >= 3: + # needs to be a text stream + stream = codecs.getreader('utf-8')(stream) + self.stream = stream + else: + self.stream = _csv_open(kwargs['path'], 'r') + self.reader = csv.reader(self.stream, **self.defaults) + + def __iter__(self): + return self + + def next(self): + result = next(self.reader) + if sys.version_info[0] < 3: + for i, item in enumerate(result): + if not isinstance(item, text_type): + result[i] = item.decode('utf-8') + return result + + __next__ = next + +class CSVWriter(CSVBase): + def __init__(self, fn, **kwargs): + self.stream = _csv_open(fn, 'w') + self.writer = csv.writer(self.stream, **self.defaults) + + def writerow(self, row): + if sys.version_info[0] < 3: + r = [] + for item in row: + if isinstance(item, text_type): + item = item.encode('utf-8') + r.append(item) + row = r + self.writer.writerow(row) + +# +# Configurator functionality +# + +class Configurator(BaseConfigurator): + + value_converters = dict(BaseConfigurator.value_converters) + value_converters['inc'] = 'inc_convert' + + def __init__(self, config, base=None): + super(Configurator, self).__init__(config) + self.base = base or os.getcwd() + + def configure_custom(self, config): + def convert(o): + if isinstance(o, (list, tuple)): + result = type(o)([convert(i) for i in o]) + elif isinstance(o, dict): + if '()' in o: + result = self.configure_custom(o) + else: + result = {} + for k in o: + result[k] = convert(o[k]) + else: + result = self.convert(o) + return result + + c = config.pop('()') + if not callable(c): + c = self.resolve(c) + props = config.pop('.', None) + # Check for valid identifiers + args = config.pop('[]', ()) + if args: + args = tuple([convert(o) for o in args]) + items = [(k, convert(config[k])) for k in config if valid_ident(k)] + kwargs = dict(items) + result = c(*args, **kwargs) + if props: + for n, v in props.items(): + setattr(result, n, convert(v)) + return result + + def __getitem__(self, key): + result = self.config[key] + if isinstance(result, dict) and '()' in result: + self.config[key] = result = self.configure_custom(result) + return result + + def inc_convert(self, value): + """Default converter for the inc:// protocol.""" + if not os.path.isabs(value): + value = os.path.join(self.base, value) + with codecs.open(value, 'r', encoding='utf-8') as f: + result = json.load(f) + return result + + +class SubprocessMixin(object): + """ + Mixin for running subprocesses and capturing their output + """ + def __init__(self, verbose=False, progress=None): + self.verbose = verbose + self.progress = progress + + def reader(self, stream, context): + """ + Read lines from a subprocess' output stream and either pass to a progress + callable (if specified) or write progress information to sys.stderr. + """ + progress = self.progress + verbose = self.verbose + while True: + s = stream.readline() + if not s: + break + if progress is not None: + progress(s, context) + else: + if not verbose: + sys.stderr.write('.') + else: + sys.stderr.write(s.decode('utf-8')) + sys.stderr.flush() + stream.close() + + def run_command(self, cmd, **kwargs): + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, + stderr=subprocess.PIPE, **kwargs) + t1 = threading.Thread(target=self.reader, args=(p.stdout, 'stdout')) + t1.start() + t2 = threading.Thread(target=self.reader, args=(p.stderr, 'stderr')) + t2.start() + p.wait() + t1.join() + t2.join() + if self.progress is not None: + self.progress('done.', 'main') + elif self.verbose: + sys.stderr.write('done.\n') + return p + + +def normalize_name(name): + """Normalize a python package name a la PEP 503""" + # https://www.python.org/dev/peps/pep-0503/#normalized-names + return re.sub('[-_.]+', '-', name).lower() diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/version.py b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/version.py new file mode 100644 index 0000000..3eebe18 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/version.py @@ -0,0 +1,736 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2017 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +""" +Implementation of a flexible versioning scheme providing support for PEP-440, +setuptools-compatible and semantic versioning. +""" + +import logging +import re + +from .compat import string_types +from .util import parse_requirement + +__all__ = ['NormalizedVersion', 'NormalizedMatcher', + 'LegacyVersion', 'LegacyMatcher', + 'SemanticVersion', 'SemanticMatcher', + 'UnsupportedVersionError', 'get_scheme'] + +logger = logging.getLogger(__name__) + + +class UnsupportedVersionError(ValueError): + """This is an unsupported version.""" + pass + + +class Version(object): + def __init__(self, s): + self._string = s = s.strip() + self._parts = parts = self.parse(s) + assert isinstance(parts, tuple) + assert len(parts) > 0 + + def parse(self, s): + raise NotImplementedError('please implement in a subclass') + + def _check_compatible(self, other): + if type(self) != type(other): + raise TypeError('cannot compare %r and %r' % (self, other)) + + def __eq__(self, other): + self._check_compatible(other) + return self._parts == other._parts + + def __ne__(self, other): + return not self.__eq__(other) + + def __lt__(self, other): + self._check_compatible(other) + return self._parts < other._parts + + def __gt__(self, other): + return not (self.__lt__(other) or self.__eq__(other)) + + def __le__(self, other): + return self.__lt__(other) or self.__eq__(other) + + def __ge__(self, other): + return self.__gt__(other) or self.__eq__(other) + + # See http://docs.python.org/reference/datamodel#object.__hash__ + def __hash__(self): + return hash(self._parts) + + def __repr__(self): + return "%s('%s')" % (self.__class__.__name__, self._string) + + def __str__(self): + return self._string + + @property + def is_prerelease(self): + raise NotImplementedError('Please implement in subclasses.') + + +class Matcher(object): + version_class = None + + # value is either a callable or the name of a method + _operators = { + '<': lambda v, c, p: v < c, + '>': lambda v, c, p: v > c, + '<=': lambda v, c, p: v == c or v < c, + '>=': lambda v, c, p: v == c or v > c, + '==': lambda v, c, p: v == c, + '===': lambda v, c, p: v == c, + # by default, compatible => >=. + '~=': lambda v, c, p: v == c or v > c, + '!=': lambda v, c, p: v != c, + } + + # this is a method only to support alternative implementations + # via overriding + def parse_requirement(self, s): + return parse_requirement(s) + + def __init__(self, s): + if self.version_class is None: + raise ValueError('Please specify a version class') + self._string = s = s.strip() + r = self.parse_requirement(s) + if not r: + raise ValueError('Not valid: %r' % s) + self.name = r.name + self.key = self.name.lower() # for case-insensitive comparisons + clist = [] + if r.constraints: + # import pdb; pdb.set_trace() + for op, s in r.constraints: + if s.endswith('.*'): + if op not in ('==', '!='): + raise ValueError('\'.*\' not allowed for ' + '%r constraints' % op) + # Could be a partial version (e.g. for '2.*') which + # won't parse as a version, so keep it as a string + vn, prefix = s[:-2], True + # Just to check that vn is a valid version + self.version_class(vn) + else: + # Should parse as a version, so we can create an + # instance for the comparison + vn, prefix = self.version_class(s), False + clist.append((op, vn, prefix)) + self._parts = tuple(clist) + + def match(self, version): + """ + Check if the provided version matches the constraints. + + :param version: The version to match against this instance. + :type version: String or :class:`Version` instance. + """ + if isinstance(version, string_types): + version = self.version_class(version) + for operator, constraint, prefix in self._parts: + f = self._operators.get(operator) + if isinstance(f, string_types): + f = getattr(self, f) + if not f: + msg = ('%r not implemented ' + 'for %s' % (operator, self.__class__.__name__)) + raise NotImplementedError(msg) + if not f(version, constraint, prefix): + return False + return True + + @property + def exact_version(self): + result = None + if len(self._parts) == 1 and self._parts[0][0] in ('==', '==='): + result = self._parts[0][1] + return result + + def _check_compatible(self, other): + if type(self) != type(other) or self.name != other.name: + raise TypeError('cannot compare %s and %s' % (self, other)) + + def __eq__(self, other): + self._check_compatible(other) + return self.key == other.key and self._parts == other._parts + + def __ne__(self, other): + return not self.__eq__(other) + + # See http://docs.python.org/reference/datamodel#object.__hash__ + def __hash__(self): + return hash(self.key) + hash(self._parts) + + def __repr__(self): + return "%s(%r)" % (self.__class__.__name__, self._string) + + def __str__(self): + return self._string + + +PEP440_VERSION_RE = re.compile(r'^v?(\d+!)?(\d+(\.\d+)*)((a|b|c|rc)(\d+))?' + r'(\.(post)(\d+))?(\.(dev)(\d+))?' + r'(\+([a-zA-Z\d]+(\.[a-zA-Z\d]+)?))?$') + + +def _pep_440_key(s): + s = s.strip() + m = PEP440_VERSION_RE.match(s) + if not m: + raise UnsupportedVersionError('Not a valid version: %s' % s) + groups = m.groups() + nums = tuple(int(v) for v in groups[1].split('.')) + while len(nums) > 1 and nums[-1] == 0: + nums = nums[:-1] + + if not groups[0]: + epoch = 0 + else: + epoch = int(groups[0]) + pre = groups[4:6] + post = groups[7:9] + dev = groups[10:12] + local = groups[13] + if pre == (None, None): + pre = () + else: + pre = pre[0], int(pre[1]) + if post == (None, None): + post = () + else: + post = post[0], int(post[1]) + if dev == (None, None): + dev = () + else: + dev = dev[0], int(dev[1]) + if local is None: + local = () + else: + parts = [] + for part in local.split('.'): + # to ensure that numeric compares as > lexicographic, avoid + # comparing them directly, but encode a tuple which ensures + # correct sorting + if part.isdigit(): + part = (1, int(part)) + else: + part = (0, part) + parts.append(part) + local = tuple(parts) + if not pre: + # either before pre-release, or final release and after + if not post and dev: + # before pre-release + pre = ('a', -1) # to sort before a0 + else: + pre = ('z',) # to sort after all pre-releases + # now look at the state of post and dev. + if not post: + post = ('_',) # sort before 'a' + if not dev: + dev = ('final',) + + #print('%s -> %s' % (s, m.groups())) + return epoch, nums, pre, post, dev, local + + +_normalized_key = _pep_440_key + + +class NormalizedVersion(Version): + """A rational version. + + Good: + 1.2 # equivalent to "1.2.0" + 1.2.0 + 1.2a1 + 1.2.3a2 + 1.2.3b1 + 1.2.3c1 + 1.2.3.4 + TODO: fill this out + + Bad: + 1 # minimum two numbers + 1.2a # release level must have a release serial + 1.2.3b + """ + def parse(self, s): + result = _normalized_key(s) + # _normalized_key loses trailing zeroes in the release + # clause, since that's needed to ensure that X.Y == X.Y.0 == X.Y.0.0 + # However, PEP 440 prefix matching needs it: for example, + # (~= 1.4.5.0) matches differently to (~= 1.4.5.0.0). + m = PEP440_VERSION_RE.match(s) # must succeed + groups = m.groups() + self._release_clause = tuple(int(v) for v in groups[1].split('.')) + return result + + PREREL_TAGS = set(['a', 'b', 'c', 'rc', 'dev']) + + @property + def is_prerelease(self): + return any(t[0] in self.PREREL_TAGS for t in self._parts if t) + + +def _match_prefix(x, y): + x = str(x) + y = str(y) + if x == y: + return True + if not x.startswith(y): + return False + n = len(y) + return x[n] == '.' + + +class NormalizedMatcher(Matcher): + version_class = NormalizedVersion + + # value is either a callable or the name of a method + _operators = { + '~=': '_match_compatible', + '<': '_match_lt', + '>': '_match_gt', + '<=': '_match_le', + '>=': '_match_ge', + '==': '_match_eq', + '===': '_match_arbitrary', + '!=': '_match_ne', + } + + def _adjust_local(self, version, constraint, prefix): + if prefix: + strip_local = '+' not in constraint and version._parts[-1] + else: + # both constraint and version are + # NormalizedVersion instances. + # If constraint does not have a local component, + # ensure the version doesn't, either. + strip_local = not constraint._parts[-1] and version._parts[-1] + if strip_local: + s = version._string.split('+', 1)[0] + version = self.version_class(s) + return version, constraint + + def _match_lt(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + if version >= constraint: + return False + release_clause = constraint._release_clause + pfx = '.'.join([str(i) for i in release_clause]) + return not _match_prefix(version, pfx) + + def _match_gt(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + if version <= constraint: + return False + release_clause = constraint._release_clause + pfx = '.'.join([str(i) for i in release_clause]) + return not _match_prefix(version, pfx) + + def _match_le(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + return version <= constraint + + def _match_ge(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + return version >= constraint + + def _match_eq(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + if not prefix: + result = (version == constraint) + else: + result = _match_prefix(version, constraint) + return result + + def _match_arbitrary(self, version, constraint, prefix): + return str(version) == str(constraint) + + def _match_ne(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + if not prefix: + result = (version != constraint) + else: + result = not _match_prefix(version, constraint) + return result + + def _match_compatible(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + if version == constraint: + return True + if version < constraint: + return False +# if not prefix: +# return True + release_clause = constraint._release_clause + if len(release_clause) > 1: + release_clause = release_clause[:-1] + pfx = '.'.join([str(i) for i in release_clause]) + return _match_prefix(version, pfx) + +_REPLACEMENTS = ( + (re.compile('[.+-]$'), ''), # remove trailing puncts + (re.compile(r'^[.](\d)'), r'0.\1'), # .N -> 0.N at start + (re.compile('^[.-]'), ''), # remove leading puncts + (re.compile(r'^\((.*)\)$'), r'\1'), # remove parentheses + (re.compile(r'^v(ersion)?\s*(\d+)'), r'\2'), # remove leading v(ersion) + (re.compile(r'^r(ev)?\s*(\d+)'), r'\2'), # remove leading v(ersion) + (re.compile('[.]{2,}'), '.'), # multiple runs of '.' + (re.compile(r'\b(alfa|apha)\b'), 'alpha'), # misspelt alpha + (re.compile(r'\b(pre-alpha|prealpha)\b'), + 'pre.alpha'), # standardise + (re.compile(r'\(beta\)$'), 'beta'), # remove parentheses +) + +_SUFFIX_REPLACEMENTS = ( + (re.compile('^[:~._+-]+'), ''), # remove leading puncts + (re.compile('[,*")([\\]]'), ''), # remove unwanted chars + (re.compile('[~:+_ -]'), '.'), # replace illegal chars + (re.compile('[.]{2,}'), '.'), # multiple runs of '.' + (re.compile(r'\.$'), ''), # trailing '.' +) + +_NUMERIC_PREFIX = re.compile(r'(\d+(\.\d+)*)') + + +def _suggest_semantic_version(s): + """ + Try to suggest a semantic form for a version for which + _suggest_normalized_version couldn't come up with anything. + """ + result = s.strip().lower() + for pat, repl in _REPLACEMENTS: + result = pat.sub(repl, result) + if not result: + result = '0.0.0' + + # Now look for numeric prefix, and separate it out from + # the rest. + #import pdb; pdb.set_trace() + m = _NUMERIC_PREFIX.match(result) + if not m: + prefix = '0.0.0' + suffix = result + else: + prefix = m.groups()[0].split('.') + prefix = [int(i) for i in prefix] + while len(prefix) < 3: + prefix.append(0) + if len(prefix) == 3: + suffix = result[m.end():] + else: + suffix = '.'.join([str(i) for i in prefix[3:]]) + result[m.end():] + prefix = prefix[:3] + prefix = '.'.join([str(i) for i in prefix]) + suffix = suffix.strip() + if suffix: + #import pdb; pdb.set_trace() + # massage the suffix. + for pat, repl in _SUFFIX_REPLACEMENTS: + suffix = pat.sub(repl, suffix) + + if not suffix: + result = prefix + else: + sep = '-' if 'dev' in suffix else '+' + result = prefix + sep + suffix + if not is_semver(result): + result = None + return result + + +def _suggest_normalized_version(s): + """Suggest a normalized version close to the given version string. + + If you have a version string that isn't rational (i.e. NormalizedVersion + doesn't like it) then you might be able to get an equivalent (or close) + rational version from this function. + + This does a number of simple normalizations to the given string, based + on observation of versions currently in use on PyPI. Given a dump of + those version during PyCon 2009, 4287 of them: + - 2312 (53.93%) match NormalizedVersion without change + with the automatic suggestion + - 3474 (81.04%) match when using this suggestion method + + @param s {str} An irrational version string. + @returns A rational version string, or None, if couldn't determine one. + """ + try: + _normalized_key(s) + return s # already rational + except UnsupportedVersionError: + pass + + rs = s.lower() + + # part of this could use maketrans + for orig, repl in (('-alpha', 'a'), ('-beta', 'b'), ('alpha', 'a'), + ('beta', 'b'), ('rc', 'c'), ('-final', ''), + ('-pre', 'c'), + ('-release', ''), ('.release', ''), ('-stable', ''), + ('+', '.'), ('_', '.'), (' ', ''), ('.final', ''), + ('final', '')): + rs = rs.replace(orig, repl) + + # if something ends with dev or pre, we add a 0 + rs = re.sub(r"pre$", r"pre0", rs) + rs = re.sub(r"dev$", r"dev0", rs) + + # if we have something like "b-2" or "a.2" at the end of the + # version, that is probably beta, alpha, etc + # let's remove the dash or dot + rs = re.sub(r"([abc]|rc)[\-\.](\d+)$", r"\1\2", rs) + + # 1.0-dev-r371 -> 1.0.dev371 + # 0.1-dev-r79 -> 0.1.dev79 + rs = re.sub(r"[\-\.](dev)[\-\.]?r?(\d+)$", r".\1\2", rs) + + # Clean: 2.0.a.3, 2.0.b1, 0.9.0~c1 + rs = re.sub(r"[.~]?([abc])\.?", r"\1", rs) + + # Clean: v0.3, v1.0 + if rs.startswith('v'): + rs = rs[1:] + + # Clean leading '0's on numbers. + #TODO: unintended side-effect on, e.g., "2003.05.09" + # PyPI stats: 77 (~2%) better + rs = re.sub(r"\b0+(\d+)(?!\d)", r"\1", rs) + + # Clean a/b/c with no version. E.g. "1.0a" -> "1.0a0". Setuptools infers + # zero. + # PyPI stats: 245 (7.56%) better + rs = re.sub(r"(\d+[abc])$", r"\g<1>0", rs) + + # the 'dev-rNNN' tag is a dev tag + rs = re.sub(r"\.?(dev-r|dev\.r)\.?(\d+)$", r".dev\2", rs) + + # clean the - when used as a pre delimiter + rs = re.sub(r"-(a|b|c)(\d+)$", r"\1\2", rs) + + # a terminal "dev" or "devel" can be changed into ".dev0" + rs = re.sub(r"[\.\-](dev|devel)$", r".dev0", rs) + + # a terminal "dev" can be changed into ".dev0" + rs = re.sub(r"(?![\.\-])dev$", r".dev0", rs) + + # a terminal "final" or "stable" can be removed + rs = re.sub(r"(final|stable)$", "", rs) + + # The 'r' and the '-' tags are post release tags + # 0.4a1.r10 -> 0.4a1.post10 + # 0.9.33-17222 -> 0.9.33.post17222 + # 0.9.33-r17222 -> 0.9.33.post17222 + rs = re.sub(r"\.?(r|-|-r)\.?(\d+)$", r".post\2", rs) + + # Clean 'r' instead of 'dev' usage: + # 0.9.33+r17222 -> 0.9.33.dev17222 + # 1.0dev123 -> 1.0.dev123 + # 1.0.git123 -> 1.0.dev123 + # 1.0.bzr123 -> 1.0.dev123 + # 0.1a0dev.123 -> 0.1a0.dev123 + # PyPI stats: ~150 (~4%) better + rs = re.sub(r"\.?(dev|git|bzr)\.?(\d+)$", r".dev\2", rs) + + # Clean '.pre' (normalized from '-pre' above) instead of 'c' usage: + # 0.2.pre1 -> 0.2c1 + # 0.2-c1 -> 0.2c1 + # 1.0preview123 -> 1.0c123 + # PyPI stats: ~21 (0.62%) better + rs = re.sub(r"\.?(pre|preview|-c)(\d+)$", r"c\g<2>", rs) + + # Tcl/Tk uses "px" for their post release markers + rs = re.sub(r"p(\d+)$", r".post\1", rs) + + try: + _normalized_key(rs) + except UnsupportedVersionError: + rs = None + return rs + +# +# Legacy version processing (distribute-compatible) +# + +_VERSION_PART = re.compile(r'([a-z]+|\d+|[\.-])', re.I) +_VERSION_REPLACE = { + 'pre': 'c', + 'preview': 'c', + '-': 'final-', + 'rc': 'c', + 'dev': '@', + '': None, + '.': None, +} + + +def _legacy_key(s): + def get_parts(s): + result = [] + for p in _VERSION_PART.split(s.lower()): + p = _VERSION_REPLACE.get(p, p) + if p: + if '0' <= p[:1] <= '9': + p = p.zfill(8) + else: + p = '*' + p + result.append(p) + result.append('*final') + return result + + result = [] + for p in get_parts(s): + if p.startswith('*'): + if p < '*final': + while result and result[-1] == '*final-': + result.pop() + while result and result[-1] == '00000000': + result.pop() + result.append(p) + return tuple(result) + + +class LegacyVersion(Version): + def parse(self, s): + return _legacy_key(s) + + @property + def is_prerelease(self): + result = False + for x in self._parts: + if (isinstance(x, string_types) and x.startswith('*') and + x < '*final'): + result = True + break + return result + + +class LegacyMatcher(Matcher): + version_class = LegacyVersion + + _operators = dict(Matcher._operators) + _operators['~='] = '_match_compatible' + + numeric_re = re.compile(r'^(\d+(\.\d+)*)') + + def _match_compatible(self, version, constraint, prefix): + if version < constraint: + return False + m = self.numeric_re.match(str(constraint)) + if not m: + logger.warning('Cannot compute compatible match for version %s ' + ' and constraint %s', version, constraint) + return True + s = m.groups()[0] + if '.' in s: + s = s.rsplit('.', 1)[0] + return _match_prefix(version, s) + +# +# Semantic versioning +# + +_SEMVER_RE = re.compile(r'^(\d+)\.(\d+)\.(\d+)' + r'(-[a-z0-9]+(\.[a-z0-9-]+)*)?' + r'(\+[a-z0-9]+(\.[a-z0-9-]+)*)?$', re.I) + + +def is_semver(s): + return _SEMVER_RE.match(s) + + +def _semantic_key(s): + def make_tuple(s, absent): + if s is None: + result = (absent,) + else: + parts = s[1:].split('.') + # We can't compare ints and strings on Python 3, so fudge it + # by zero-filling numeric values so simulate a numeric comparison + result = tuple([p.zfill(8) if p.isdigit() else p for p in parts]) + return result + + m = is_semver(s) + if not m: + raise UnsupportedVersionError(s) + groups = m.groups() + major, minor, patch = [int(i) for i in groups[:3]] + # choose the '|' and '*' so that versions sort correctly + pre, build = make_tuple(groups[3], '|'), make_tuple(groups[5], '*') + return (major, minor, patch), pre, build + + +class SemanticVersion(Version): + def parse(self, s): + return _semantic_key(s) + + @property + def is_prerelease(self): + return self._parts[1][0] != '|' + + +class SemanticMatcher(Matcher): + version_class = SemanticVersion + + +class VersionScheme(object): + def __init__(self, key, matcher, suggester=None): + self.key = key + self.matcher = matcher + self.suggester = suggester + + def is_valid_version(self, s): + try: + self.matcher.version_class(s) + result = True + except UnsupportedVersionError: + result = False + return result + + def is_valid_matcher(self, s): + try: + self.matcher(s) + result = True + except UnsupportedVersionError: + result = False + return result + + def is_valid_constraint_list(self, s): + """ + Used for processing some metadata fields + """ + return self.is_valid_matcher('dummy_name (%s)' % s) + + def suggest(self, s): + if self.suggester is None: + result = None + else: + result = self.suggester(s) + return result + +_SCHEMES = { + 'normalized': VersionScheme(_normalized_key, NormalizedMatcher, + _suggest_normalized_version), + 'legacy': VersionScheme(_legacy_key, LegacyMatcher, lambda self, s: s), + 'semantic': VersionScheme(_semantic_key, SemanticMatcher, + _suggest_semantic_version), +} + +_SCHEMES['default'] = _SCHEMES['normalized'] + + +def get_scheme(name): + if name not in _SCHEMES: + raise ValueError('unknown scheme name: %r' % name) + return _SCHEMES[name] diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/w32.exe b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/w32.exe new file mode 100644 index 0000000000000000000000000000000000000000..732215a9d34ccb7b417d637a7646d9b843ecafa8 GIT binary patch literal 89088 zcmeFae|S?>wm*FGqitH!CO`{C3REl(SahnPNDYM`O{q#T7)Xdvz$<hz5gjb&0FD$| zPs=nt#$jgk-tk`NUb*PJIy$3wMg@OiORy=5PEkZ0P^;6cyPm2=Y8#~Xyq~pC(iU~@ z_dd`2ywCg3TS)e=wSTX@_S$Q$y;FJf9>F9Cf*Bu86NCeB>CeT#|L3nblC!40kR?2m z{>H@z3`^g*ct!B1Tk<#8{Ol(+x7?n8>n(TO@iQ_1pEl;#NO$D_^p5<p8@>6r|7^p? zD>5@P3KB)%InlPUc<U{5lb_$uJ2!U@!dIxT&CTYnHuoCtzCL#`-1%8w%`JjkymkHD zpYr&>Cg9H}+(GW%^wV2|ROUbGfyXTfOART)i?<!WISJD#7!6|#8G`TvV*Xu^z32+K zc6>T0?9%;4K}Zn{6fx`yPa}*$9C+R!7zI~72c&$InY+UdMGBkF3c`HyxD3K09`bzW z?_q;rO&5ec#{?noJ4vI19bbHBt~vx^h2FH$V8i|^#EsiUg#JboP3@w-(&Uf&%NK<8 zSJZ5{MZ852W)~s>WeT(LIf&1wKNqULLI)GN_(-E-D)X~ZK=1;t<%*guHMhdg`-(mb zHzDv1KBN9zR9?--O+N$ReOXAr81V9z!X5SJ5`=3<1^<8V|AP@&sr2}Qvp;hQT24iW zOHg|EiZd1ojV;oo#(r^ba2`^8T22{~_UQ@YMZp7O1R*2@?SerFE~TuJB_wDaYC0h8 zfONF1t%{=H`W`bdYp+>YBsg9Ty9ec3iy+O3xa}TIvPK#Q&udyx1MvwG0(#iaGC|N| zJ#3?<Y4YLRkU`54s9BYRjyISA>){9$tW;Y34lPnX=&>D4X~|k7c$TwEfOzs@Yh#Nz z`FV;`(w!E`sKg@`2E}bDY>ku^4XS@tV(WO*<eu67;0Clk;vRHp!Qf<+5w0B!*Y>g? zYH=KK#%%Yu1~&m>IlB^#2^syGG|2AB1(}4aOcaC%!)}%`I7AIC2(Ro3yW`GSttng^ z_xb=ECor!L{-PNO>_ulJ3%fm=O0X!s%)$GZ?~I94l-^KEAX0n$?4wGpr7&i4#~)OB zQD%2NrWUKtZuYT1Vnu}AeF`cSgx>Rkk@}Lg{WltgT76VeA2aic`cTnpXrt2WXmJkM z9%u<Rp-*9{$HQ)>Xm?McyDyZ28Ux7mpxy?mnmvzMMr-85vkRrJLaDRx>|I7je+cM+ zj{RJ(3Vrgke;W@#D!y%U%fQLtlPKTAzWtVuOQdXpwsy6eRjt^cZ%0D4bF7$F;f!th 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ðeLyi^XKZ@T)O?Rs!5wIFTl%?8Q=3bg%o36c5r4;Y4ycajn+NC8bv2_T% zc!;Bj2`||-6#*wY>mNg{QObQ%LH^V5KzX&$Pj)C`PL3m39-<OsbezPe4z0%YKtX;k zy@yv8<mcf=ucxwz`Wh7sr@7-sljc~dk}6a&;;=1oXnjl|eu5o(i>WU#AYJkuSR$}j znMO4xV6<u<CkKww!%mu%Tg-Yt11EZ7xLh4zM0J3`KDL&6fr2{d0&*;_l!~N4!>4cq z?#p`Ho!Qv73km`iByTbY#cV0wK_smZcB=-yCveh*Mk_?9O%&WfgkP=#c#PeZe;5gR zFU#jKce_>dkCGInEfEF<jR>avwoHFFzO^=6+i46rza4!c)3)K2W!N-jc;#bdt-wdV zbbkzu=Ar69H{~D7X}i!Pza+cmg(LPu;=<8t^7QJo3OHYK9I;_Rwaz_5IFuxGuq&N> zL5WaJsc`IUvfI|6i$c24cGjUvSt{j}Uy{>+-qt=2Rm-si0jtOTK#qO8cflG>FmU+N zMgPSO+!arkH6LA8To`%QYu7LxG4KKBhA7sv7_8GFS`8iha{axnw@X#~9qM<Nn|Ekg zXjHP@4?`WSSjYV2&t6Ky9mF|!O7&Ii08RCkHH^wd==z}u`->J<%gSE-EV2U6X{ghx z8`(M#MS&OAMp|+8DeJ)R&-5p+GJGZjgPi6EJ<t9Hd8f7FUWx`Uy=O<t&u?#v@4hR_ zI=Qwk8_i>!?S4T)7gIS%>@6&FPRJsr<tToVziU)urQ{{HP^l1S2Sm^W%oB&@_SJ4Z zka#ikDQmAaZRo*zk8y52S2OXi?ZuR9U`ZZZZP+Mfj-!a2F34YnUwq3V3waZp+MqD< z9I{--2N>d<U-m{hQnT9z`K!0qzOsnEH853iNQ^UEWzDp(K-l(N*)4W;=!-1tphZCa zX1+R6SUt&pyyAmcI6x-~^OPD<S8(mCvo#4jVK07~Sy@}jBHlRtmLkA<^=^_w^(&UU zFH?O0SWZk@h4neV{6J}v;{V$!ax;4|ZyK8N3xQ7^U2IKtS55D~yofVt82qh%AXKbe z9V$uy9sdU77QhO43ve2K`hbW#$9Q<*V3rF9ZrS5_x4S4ue|Aq+W5@PM58{JGk8V5r zu=eMRvQjl=Jr?J{svQS0mxs||JXV=jIzQ`xg4mDg;oY{D&Mue?)xKVE>~?%w7EL7= zQ;A&zxDfQ5HVcS=t+d5cs7#Gwovk>NTDJdc3$1>`d?D7*^0Zd0ZrJm4sBn5923Lwr zJ%(+VFmA#S0iP_rfq7oLSvc3g)p6MA_^5O(Y5_jA!L$QE56$Y}T&0JzRfTi5!)@6? zwN#`qNDVKrBvku!8N-25{XOho;?w0==S0w2;}Z%@P3qIPTubmNl_a-mI#w{@WLbM> ztLhwX(lXUhHWo}YWd)5q=9qBOIT!xwV9viW3vJl=#wpx8<B@3fz)mj!te-E)_x*;A zlb`za#;-pXOL2bx6||^ea%bmrm~F*2U@PG0L$!Xm<+#j&AR5Cj#}#(eK2mkpj-gvV z%CB3!y$3E9tm%d{mlcNK7at#5vG0VNttV_R7Y=e^cqiuwrUicYsZRdDBj}xWLfYpe z{IK7SiHFK^3-5Oz#bC@tXE1uM=>3}V9)o7(DX<Maa!q+F@Zii^i@F<{h65W%pkXv4 zSA1X)>u{I84IMwpHoY+M&aaS7d3Pan;7``3ehM{HUM!wvn{M!TtWhjck+F4P{%vFm zb_=-o7W8Kd@<Z{sJfHNSYn?v>>T!7!M-i#?DZ%C!T#%XH5l@Z=?z`>tp_|(*kM&(P z;oP#AU+j1JVVM?HP}xY+JKJNO2QZ%DCl3LRLgwl9fqM*A_lE}VG2Oc!2_tNN1m5El zgz+2&;nQ!fUiuq)ec@6eQg#!*SI`2*I=x-Oa5E52@}$-;j5!AzVPPQ?8VmhIp6IbP zLxlF>%Me7s76yviSgg4|7wgC;Q4RstY1<5w<Bbu_p|W-qQd-=%7vxiR{ENsY(~9%x zUD}IDKe`88Dpr*y7xq;rx-0Trvl<C+QW2Smn`y;HJji^eFIDQLcBB-9oxX$W*}9mv z_+V?E%i#2O?$)4?saH@$`U(n}vmS7qRPUS}x`WBdfr^u+{3zz560N7>X}uL&C&U&g zf9DU~Tmy3up<$q519j!E@-r>H2w^PsgukQt@>W`yW#di0j^+gsCcn}%kS3qK6iq*h z=2|@F7E@->+b5zJOR?4}N%O~6C-?q_5RMOg&U-0AD9j&$K-dE%yT|fY*sEj>3oZ8& zwkOf>*d>~U4#OVA!<Jl@t+4jxV@J6b#S7bO6z2CrXq2H!r0!x2XLc%_o8krLA65kN z-A*s15U{m^X=xhRU)sG2b?kY=0(C)p1pMslSs{SChB-x+xZg?S!%bUSxgU4mr{Ql0 z{vF(kSgNVbCMOrPb11UhcexcY3GFwzpoROcCB=MknUuZpM=47|y{S!EBHy`EHk_1= zR3WvxuIf0;!N!+`eAEeZA?u<}R-oe{CG1;na8pw6zK^8g#4-|fRdO~!p=Fi$oS!&x z=7eS#DHfJv(dyX3!VyT;Yr7i!#X7d*1Xpc$6q*Qm#IPyv5xo|vQUw{iVhi&IGICu- zYi;UY#DIavb3Q18&5Yl}Yod)eQyi*#YelTpTUF3az>cyI;KG>PoJSUsEz;M|sQ5T+ zM@fr)J*5{Zvd-5`->%vaVN0_Yt1#9+*igh@RY7d5G#Z8otvPj0#BG6hS%_Xe@4(}v zvi^p)p)wCeUq*>xu3rabXzb=}uHttDE1Wmt)^1kcQ8jfaM7)%$pw$#-*xl(oZDj`r zUnMx%%+oMZ^?l?~SOyT+xecy{4%;!BscL*5`I;W=(W+q1K-^x>_mK;3fC6#-K2mSl z<DBUgY`&UmyN(1`r#wu{tgi1RpM#h7z2tT#t2OA_Ns(%&c4sV1tvI{SvmlJSb~dv| zHTB#b){fn+vX*%8C=6>2FT6rc6^<}Zdm_Huchgrt>U|!Qa}(?X8aKEU(xsbogY)4k zFQ-3l%Z?j!sQR)?Or>I17B>(3$xvfWrT%e`T9LpFTAT7T=y+2;_xH!AmTv*$t;YOq z--*sw`GV84T_-x9!@cX)V-MrGdh0Pv*6v&$+O1no5cYp^f}n{`n-*DGkx+_DLQ`uc z6myk?@NMQ(Dxuq45;D6a)Vfwe9#<rUJppsAQ)!)#JeOKOmR}(`m){J<s3wdWzJcl@ z%BJGe$VKIgy|D}0{2LtDaBRpq?2gr3-w~}jSUBVyw!bdKXM)<cdV7WkE-GJmAQ@#; zX0{LWxIDj^150(WWu%+ELA|nO+>jIza*+{sp@raU`~T0O<g0!j_KHI%sQ!2?^+7{v zY~PP{1gc25XPUK*|I`-N7JfH#<8V)`%g`3G;L~Y*v!S}&<<79Vs63J7{<pWb-K+&_ zVA|Xq%UxVI7Dtbz>;uwm+Kkhq-vvMUS-N!*w;EXX5+3ar-4=I8Gq=#}bI5-x776bd z2Y!v6nA%8YVuO4xJIOCWXfB&+5vZbMnf>l`!%E*=#z$tRyksaOeXoGhJ8<v(74`&e zw<=d;Sf2yo&2=nXjvR}ekTgyKuaTQ6KLCNs-clnHuDDj~HqiU#x6CNIYGKCG1FpLm zY(uNP8LMSt${huJfE0F42<t9#(XhL2W1z3JV2YmVXbc`wZdi^qcOsVqHz~38f>Dd7 z5H|HWbm1q*5!`vgEqCm^kc9Vp9J}bcA1oV=`zd(CZG8~tVClin4}O2}NRz#`a~IA! z$`J~N4fwRU@U8p7tmc6TH_tQ66o{~M8;$mY$4%qAVbfdOdE&0=g`=22IVv3Q<FLig zn9rR%T4)=6Vh;^krsl&k)q#9-dSPB@(xf*j!pYdWr#=>BV>w_0ojKPqNQD~)sezCh z(-vB!VzHk**RJ4G(R#2+VGm&%rCOwh;QeB}pQNl(2kNp)%}1xRdhnvwe!)Tss}zb2 zYrP5!U&nlQLD6CUt~tfu{Fl^kh59|Be$T1jW9oOK`aOVOXF@i9HaZyRNjxj7)LK01 zL!AiR<`$R0M_Hxb#*JZ>`T-M}uozvo?l)~|i%B(j6%?ITzwfHw4g7uRBz}_vKQZM! zi|{zG&i!IR@zZ$cuVR>1%*SikjIa#@twvjFTaAjCmS#2bcC{MuHLXTt$kK|2ru&*9 z9oUS#He-YXn-R$cO^?DU$k*uA_@Hq>;|w`adJ@A1<Xh8bgm26=o6%<YHY#H9(k&cc z6!O-i^u?-sx6-F@zeK%9Z4jla7(+dl=HoWm4x5pe16z)H7==SbFqkMvu1W+ZBfc!< zFbC5(xTS$-i*7PfUj7Wco@9yAK1RCTYotq0rpuFIbq<u)Qz_ENHAOy`e#iND5MB|5 zZJ#P;T0`v>uo~f<Zyc`;FO4K+H7dqqvOOft*3$i={u)he>2r9kF{DN5<5l<O(v`S3 zZNWM0gKX`S?K$;)Z8u=nQ;!H9mCk113LnjPfabft0yxPW;5A11!d5g)-RQ<5PTuGF zsy8qfd8r%Ni@K^C7(CkZW<A9M96StXT%nS%-T5qKw7tUFmeskmoOU0Q4ZBZ&^b1UR z+wiOGK3r77L&#zGfdJeAz`2U1{4X)^wbSnNsGgE0)ea?O8UsQLi!0%&P0tsX;}!=I z;}`om7OX__yYtC%bb&?baXengC$*ZjXfIxBiI_`^abN9cYpB0>6f-t9qq5cCMkYa) z&Z`v6nn*b&R~D>crl!1$&=pve*+jRN@TGk{F%ga;KER~7vL)!@r{y@92zQ$LfcYJk z_lB3K@X&Z+69TCS@GoZMg$GKHAz@`%IsyD?ReFecI~$tv&Y{U5o8CeQ(-sQ4&-q~n zenkfm-4Og|ac>>EEPoH&!u;3qi#|LZY+Hz5AvdzQD^&iNrX)vkRHW)RVvcfwsi0^h zUX?XWE>M12h=P35rKz6MLBPSKPN=yBWpnb;*ji<CVjSxY7<N?4N9j)-8?PtAqVzl5 zyYMj9+2#<1=KzDy;`9wf1tWa?+ACmjdPlv7#pydv(!k=BPK#4FWpR22ei}P+3yP=? zt<&_n08W-otWpdpMQ7**RfY5Bqabt^DmxRkEA}m<ok=NL_uWdVQLIZZuw<0NfrW|b zLlf#!Byx%6V+iJc+!0>kh^s997!S4^pp|CW;x(ycB4r~3_uw=jC8dr%OD?X%yTyYG zH)*z^Qhd1UP?{XJA*yxo6}F*jzGDs?wjl~BBRbr5+t5y=xC$>F;jj%oh#S4oVFkj2 zvJEkgCLWlZp{NzA81b&Qp*5^5v<-a?a+Ga|vG6&Io*WLVtF{d#+l$Eq8izi24dG%O z3Q@)(CQ4ht@B&p|<4fB^jth#I^lsIDLQjaYZpuJ(4>Sj5{z>+ZXdv2$h+3$g2&I>< z#(ii;@O&Xcrg~#v%lr?KphG2SFByyHeR#%M>G&<>tfVfNh-J#>b9LRecGS`h)%Zg@ zQMj@bg;zdS)>iieYYkhGYWnrp*1GIP2E}@ot58x^_9Dem+KYIjBm(v#MlkF}d`~MP zUBg~PA_|Lsg~&V9d#N;{tI3E(p_z>8p9gI;8LeOfN2*LlFX2%$8Rat}Wi?WWqH<_D zv_L5?>zxp~hK^mie%{tNSxDJ)C<)Z`)Gpy&7NiuPW*x8gudd)_jm9Y3QUmwxFeaV# zQqd1qXt~&nHzG+C!Uj<9P}&tAVSC}@42YaZYM-*^*v;4@)vK%lcBO8eYMzu_P{^X) zolh>1V~*k@xbsp9)2o<o3zR5sXlm<LcC*$frJA)?X^eBZGEuNHV*vwgM8{<j<G_%@ z-!+HvTd0HwnvlVq_bD3@c|#jfKdq!aY&{$*m$DA2-dfs@onxH0)lU5@d+`Cp6t-E8 zHK%cd?HChbbj4i_MQmtbYU=pdk<MK|v*w|$v(#W%>L!cmr4gfL=PZF)#l4sTCgp#g zv$3o%R_x$GmUY)^v__FsrD)Kl2->XMhxi~C`sf5%d+P*U!LoRShh>v#>nyVuZ(v*+ zh<M{{I};(+t9O$es+;LhwF12n?4PHUV{+gwh|z)4IpC1L>Rn>qpqTvzScu&4vX1Vq zrgW=@nU3kYg=ojiIGp#zP;m}0=A}^a1mJnV4}eqf)4p)PNHrdl3X?S3N%mOnV_KR< z3^R!dTU6SEnoHY2{fIiQJhR<w$Ck=1xc0=>DlYY0nP*(;FJ<m=spoO#A7{rJ7IbXj zQ!=^iMrU~rJM8G`31<av?PksnX}c0(wI1e2w9g_wSU5Sb8SOXOagObnXK?(aaL^1F z+z9-<+9!69J;+;Hy^YiII(dCyZ4qVljJgUI_NEOm+AM41Os&Qu3%A%2!FBI<41{Q5 zYUiA&VdxC33XX6!rd>KX2k2qiR)ulCwHOlh@s%GUpO5gw-nRd8czCMAS3J*R&g)i0 z<F}IBKvZodTD^-XzK&*H#pXMAdfEo!An`ZRty0I6<GKA68+c;xnyII-ho@m|@<v?j z=5Ot!($;J}`nH;d5q{i`a}`GO+=t_P;JXvsk1p~=CilQ_sZU>l4_D41;p<(-eGqX$ zMZ1~3NX2xdz*#YVf_yBsi8F?Yz*MVtkmZ~%-u=pV__P@3ecNTIsW1?)9lpg}0mvo% z{OTSDA2>YJoBHhi1eTlZ599UuVK^#&vVAdDQThSHSD6sDFT$QB>fKFOvZ6lhZe{M= zU=^DqIeQ@u`=Vp`q_*%*Y;3LQW}4QU@IXTByF$zCI9(eXM<V?NOUMBg;alvw>V~1T zmxkx|%MHNHll9%pal9Cg;+D1r!%J_IXg;|!?Q0l)V=pQmv}H{!Y^vzM9FVq4t)u0V z9g3zM*==`)Vk3P|xhu4OV{Xrd{b&)X?2GN+)yFmjnk4MUGD)nE)XQrZ1t;FQ2aOK7 z>ft&8$*ROc?7j$v2sUrcCHBdtGbLkDb+Dol5pwX&)K@v%oeiyn^$+}#O*w9WuonC= z^T(S%q5O&E&t3e<EG)=H@*`{quyS~?V+U42T1{o{FgU~4tuU&^2z;*emC4%CvBT%{ z?cdk4dKR=VjPi)aRz)Y>tqqp74;x{-H2L<Ojw2U7x9@D>^^s4>ILAl$tQUT6VbQir z+shaSDS3>vRoqcJfvm)Kd*09)>$v$b76fB*IF=$N7NVkPo9DH1zHpDBML3DH7C5?0 z3g6&#RCzo5;<oJQRX3?_fay>->%KT=8V6j)WN-t>Mt^Ke4Nc2^0DXZDxY$IWqsQ)f zI40~AL<(oIw|DkO4miQCz|+~fDqGhA(u}^RoO$roW{96+UfK*XCS9@P^kQsmh@Ep! zKZf@>8Q2loQ9nVZo%4u#hwt_}K&o&$x~(09@*^AWq3Z|C%5HS*^V)-rf$QB~)&$$> z?lnDDQWzoJurymKb?m@af#qmr-Oy3RL{a!lsH$qSjuwsvm>I)*vmw@-`7vL6wK*jS z{lu}$t3Kmwuc&w72-B&4E-Tko2H;p=d}p{H9|ex`Z;18i+dV>Ye2wkG#L!faSm%b# z;0ewx#|BfFrtwT|<ZPS>+8o@ct&P{^Sm(Fs_^XqW9Ug-z(m&wLV=Qpy*UKt>%zi@q zOyo|o=djgzJLek<SmHOLq@9y-%VMW!#^E3k=z+lFR!i!TIOoQx$QS!9VX9|B;0fzk ze8}iOub$d@r(!KB3anp=Ut446Ac)#J^=6lC{#tJLhF!X?K4@|KId6X%e%$5KnFVHH zG#Bsu>P6mIM?1Z%@L-d{Lt*@F6{urSX2A2NR1fEjB2c=HDI&3>1>XLO{kB%{8l}9n zT&>#*yd7$zP9Xo97q?ufJP7q!?i_}$HHZkjY+CUfNc8tH<^2M;(0407Svr}(3DZgZ zXijbZftDV}=fJGs=5wAD%uB5|8Q)-4I@<u_N$xviogI;>&XYUfLBESHXnyg|?;h5r z!Ib|E^1$?~&)!0h;g~kY1g`te3!mMz7yJF}8H-J&gS1*;vd5g0&RgfRIC>*WyfX$U zO#&CJ=oM5tL-2&6n*{2x{r^$YGTLK!L35z*-@tYjx)s}~ne3zCq<UaDL~b~50FFv1 zu}}>js$fdJaED}V;KZVO7fuuouZK-dR^%haAzB)D<2E+cLr-Jh>naV-v?VfE?Bdq+ zje?d1b3DkN{#u%!!3X=MO@wu0E)oI0_upyYi<J~!jL3tQtH0tag+FGKv8Tbg<r7-x zjd$yW-VV2Q$B|7g^UJs31PXk43mL&Vx1n`TG<&G2W*qhUIC4f$)tI>E=iE(Dqn*pJ z&k^RJX^26s!2wF1&YvLAlh9>}i7)fUJGWt|{Vtz)hoVdzJbM04|N7lJ;G>eziO!*m z5e0a3!hybXKbYtoz-Q-tkZT;*%kGwQ23|PIjZKZ(;t9KVmVM<MQ{%m~srQcEW$!D# z;A2^I&;mc0TYau@3!E$5!6o&wFq|vg0-Iv|glT;%2=jDCVo;7#Dv7((6U1v<qFGx9 z9?x#!b#`K^a6bWU`?M-QZd7J$Rc$}r4!djM5H>e{;OL2SRqzF>Gx2lu*dm>3r<{Tb zIBr5(C-I;sl@t6Ndv19j?By|0Vcd*jQ46o~n=YA_?Si!Cc;Z-ibqe8Dn%?5DQD&Rl z(F1^%PlJQ?O;AQ{ozWm$<CZf7w+;cE_U@d?ISS^|2DP0nJvhIxagIme*(?voPT0J5 zLBpbgc{=+XQ?wAZL60%_`3-VDLiz1?@Y_>-E#m1s2yA#XSS6&wKw&0O@cCSw2;w|y zMG}7XZB3lTxYPE9vhS17hh@cqzvj$Yh-|ZGfoQ!ka7G`M(m3VHlotUuGaIj8z<N+O z1xah?z>j#WAhP_H9oVl7=-F;{-dUBrGa0vrOkn$ZTlp=vbJ(lIl*c{JkrlStax&2q zpSfnmI)%DJN6CosEs9!iRM=YUvp3e3SGn(79)=@$;!T?uc;E{fZ3*qciY32_P>fw; z;ey51p>Q#nwf3M}PgrlJi!D)x<VJbqIvN*_>fdd7%iOP)<i78=tYulxns1lpzF)7* znVaa5Q`W57C$~#(KF^7>HB@`UP2EXmbQdK!M3Y(TbrFgS<=@5`4O4^O+We3OMRnut z2+-^<Sm+91%$T|}-my#dtW5da1+?Zt`<FS}zi()@;GC`}@B-bVj0S+w=w4+^G~?$^ zcCQ)&#^6;>JYMA_;8jL)D1Opo@iX@>{4CCd#|*s7$-ujud3cwTlUcYq7iku5<8QQW z9hRj>;n1`1J<us@>zZFq!@{{O3UgXS+s@#~IBPeIoNx?8GsleuZ3}U%bdE<97R=%U z9CvFY?f^1uc$DqJ?RO?j-T4-(g77-v_5N7L4kN&g%i5{{+nqI%7-2g*sk8~}u&yR` zBPBjNYJt<uTH-9gX5b=hl=TYQL2=!qJ-DO4t5ko^+*Z!huzhMD`>(<sK0SkCXh+N4 zqDgpEHcV6gDxd_LYU?*)(V|If?jYDfO-Q~;JPwWD@uaF?&b3HDYloZ<Gc9!lbB&G4 z5vxbwuk*~#xy-feodw>`4!ENsG9N1qX(B2`n=Y5(xCWx#K-*eQ88U-Nryj-|_k}S{ z$Hv7^#QLb1)??!erZ!bZQLg_$#MU@s%9O8m3yARy{J>gV;8ymgreEz9cboEKkpPrW z9z;t9{%X2+7F?2Y;R!`b>0~@Brm~rES!DPC>J|1~(j|1PeaJ?%n3u7+X#%F5*7AY% zShHSZEd@?(s^luN7*8xAYZIXwZR=OGPU~GO{fxkG&<a(b5!l`tpGi(~G{M6Ilr6k; z2=tsfB``pFc7<ozmzY~>%R>ctMqnY{)H)-OhlF9!6_;8M#|2Jqva{+KwA-BXIOS2I z9TYfA-B%qHc;gAEDO5ci6u9F!ZmSOpv@;9spul?iL4jT$;G{sDg`l4lSp0=zAar-x zX#EH_b`a21UH?geZQ{6aajbLs$JLq*>&TJsR2cHxm387`z)Gn1rVbokg;!H6osm`f z`s2vJCRJ=JYv|b79aB9nX9l9pL}REH$Y7gws?fP>Ax@cYsr4p0hff5u+-?*b6m*6k zwl$B1!CdR4d!XrUs%`kyGM#!>wT`-(8XcARiE*&RH`!~Aft?i=)-7SL-Lcus??ihv zKDE4|wI{xgyaiu2VymKn@3I;Md_AvTy>A0{<8CMJb_JZoj_5c;=Ah5sfRolnZ-Q?! ztKNmr9NQ<eFRs=ly2qxv&qOJN&g}SoC>ks7Y_^Vax6_b5D^@#R#wWkpmg&_-bQ-~F zI&ZQEzfEn8@a%EnOW3gEE_|t*(P0vI*9_`kx_>koUb6esXsZ5uT@ME;@hy8}j14*h zdIKT=;{Zv3`GA#x7XZ5e#{fSAnx7Y<8^8}R0&qJZ6>vA;Z-8e3jnUj*x+KIA+@A(i z0z5AW(HhVL;0G8DxC>wftOC3O*a0{S_!-avAJ_K=3<8V>+zChp%m>^HSOwSscmuEx z@GanHfVe0`Q^1XYt^i*^1RxeL4Uh>~3V0H*8So+CD?lZnDRAxz2m(X^#sTgGqyusR zs{k(nN&trdrvV*7E3XpJSo`ws7b;#3$9_>`u!q%Kq2hR2XjPEhJ)z=D_}9L+&N_St z-$6Nx7(lx-fG@BNI3p`^eu_0VD`UDPJ6nj^B3n!s86rzq@Yh!)i8TBPVaB*~K43cj z5KK%E<Ha!1NBFti_ZNf2C=rP_^dBvvM7S6uBGj9a_#KCLkqF@<1|a1K+>KIUhoxl? z%d%Jm+&GJMVq%(2-4A!U4@*nSn9jgi!Y0y%Ripq@i!cMS@JD>jDy?RMwmSjrMj`Jw z{JDnFeB*%GXfeDFACwPb#b85chPX1ON*Z(w65gP~M=-rU2!|mK{w%;L6RsJMfnOUq zMI2**MHKKcE6ygVcgYIt*(&TzP?L?jMEo+wY%vWyUw}7BNFxir>0$<+(h-7`&s8a~ zl(e+ypQ3yc5idpDt%u9N`^Mmekv_vE!GF5)x9EAAk(*7WPk%G=%}}`#pG^EQMJ+}O ze9}>JW>7;aHLPdjZMJ%5$XUQm!`+H}Nj)Vg8!4u#Fc~5l@0cFt%AhP!<!tb&kKz+~ znSwAD;A|GXL_fSuLu$9;DH-Xd<C)wbPJBZtAU_iUS8^&{;YjIWEKOdt-|CnV3a1#P zK)m{@(q)Mo<vpOPywi~aIbcCJa%%=?H6w>i#GS6FPS*2CgR4<XUNBwFXEs6_*c&oy z<kP<@pStCWsnjfQrfu*$9QcmMGs}g%*L*Y%lUKyA?|(!tYSZCeMTdct!MD07NUFu} z0njZ*{bFe+s#>AZ!`f9>8fGPPlv@Lr>hc>P23MtL;BkHBHxGH$o#T~d=$hZ4Kan46 z66@%n$!}m)ewmO-t?cI_tt_Nz1OL*%wJU3mQ5UN@rpe&|;aip7_46wMn5RR+<|AJ# z>MS{AJW&#jQmoF+s9*hse^q{Um3Ib8mF1;rQP$@Sr5&gxEzpV7QWlj0%Yc_gNB>%K zL~NK6^?;^ZsHZ41*Vgy_UF3)OU75~oaG6?;l+RTBPgJ@~(*d)7H~l{&FEw*YQv6QT zxnR&=T@T59Y6UCwDfQ?~glEe$4b&LC)ig6XW0aAWj<-wsT)#XpRZRvd7i_cHdTS{g z=~mbC>rXckRLlUsjTE!1ur<ov8@&wX!}d8D<&vRzL#@HKG!xIfrxs`H#FkFu3|kLP zyK8YMUDdpxT(J+8do+}GGtmn!N2doq3q@Yo&;Tx{Exh5j<ohF`;s(Bl+lueuwu4*p zX{cxqHxq6LxB~7?a8`YSPbJ}o!o|{TA>ej~<M(kWFhzQYLq!+3Cl6tdP`GcyT>$rK zxOc<NgUd~$7Q*Ee#T2+Ps&24-WSvP?G*84k(yeKQaN&hNGinSan-Z+`u14W*8aPdE zGZ*y16_o-l2>;Nh1>czR3>Av)FEzCmn`zBb+?<EsU=_c14v~nb_20Uvv}0?e7NBSz zAx4M*q&XYE>>=?=(*JHlh#38knjlH=%>w<8ecc#nA-?aY-Z5@0-th|4-3XL0bqD)h z>`(F<4Vu``a(y>O>5Po3P;u~Qf6p}(tT;+8smFOm<C*;-<DPnhSD4}(`!~dq{GE>4 zh?4^0PmZ%>44y~hKHcSwhOdF6K#!HW4AaI6AEr$ljJ!2BUC)P@Xn7m?8hJ7t^I<yF z+H66nPc+<z;VH%Cc|5RXh-{a4@yI_3DX_n1#2k-MuFo;xD|?|vx^eKY`OLhD6Z2y~ zp83F@qtfOx(<AOohqy96cjpM0Jv)FS7{~^$+srYz%)D8EOT@(VOG@g88(gs{{xCp< zWx8edG>a<m(HV2A?#E2GX7F{KCDUrW471I!WdpHjTbfEE+Lo>gGAuJIMU`P<)^t^V zmT6hG#4IgLV!FCTJ_6|rq{}n~(qcM*bP<!dKp+jcSz?%FnutzJ7jcPJTUHW0a1F~! zQFr5K+Oo3sckz~_bc_Bl-lpBfWTY$KIGgS!S{YX$o<MkkZ~|cj{DoURcaQoF8hSQr z+@xu<=B5@cZ)nxJ&5do_weN6K$4)nQHh1ZIOSkSldiJ`tx7Tfb`u6kgKfuR#;Gn^N z{sDnOLxMv>!-j@OL=GE1A}V_1sF=}XV#kh)8$V%U{OyzOm^@|boe6g(PMe-&NuDt? zC3RNX?DUMxIa%3O+uV8c7u<c%!bOX7NY?+;ml+zW=3g(g$J$@b_jNywKnruNzdUi} zU(N7KMD?GWxV}Hv6qbtWzj|m7ujkK*Z~lL}>^0)AEZ3R;(-Pper0UP@IxnLH=`MAv z{;TJ9eSb#$E2;mZZ+@=^FsIh|Gjilp^?eI$7yd`C+TpK{+Uig(MD@LP=jKK^$X&A3 zo|k{`eai}#J605~ynof|zdi8aLk~al=wpvR@#LDnKlSw5XVyKt{<-Hj{NsfeUwZkK ze{S6L>T9nTZQk<6n{RD>yZD`LCEIuGeD}RwyZ7vU|AP<zwQv7{gNHsk{P8EB9{KF( z=f}P{e&XbpUwwV*n{U5!mVRG$`iCFSl>hYe*>k^~zff`U(yx`j;nbAB+7Mh_(O*|X z@V`y}|91X=ng74n5MSM2HN^kh^w-BQ2pco1s}t_=6^6PVcDXOaJ;zzRR=V6{OSr1{ zt6c6^yWIcH<^BPedmc+_q*>&0?~Xh;mP2}?DF74D`n-62N_tYpyf|y3H3fYryq}P5 z$r>{))iT{0m7biDHCuVaYjH*;W?RFiTT|v*Vly&rnJOLaSxZL5V5U8BhGl5R{CLch z$Elg|+H>N)(5vOhAr0enUcJ(7X=&Q6z(-IG&}c)Wxi=6E>b3BQjEt<$YoIsAHVka` zi@m*}rx@(*9UqI2FwAB}uIF7d@4^LRN9KH7o(O?6-8?<vc;b(b>S~aidvETNTx8&W zZ|=QIb6eN1j~w#z^HE^l-np^4%MiL(PrumsT*OBvv9Ze#(cCL{SuSD;WHWQ-Oi#~- z^D{H&WoFh$pB9190NM|_A*>CI^cm1MDGi<IYQBt5nQh6iS;Nr(O|&ManIp5ZGP2Am z>E=<1w)E*U(KpY+D2dmw#FR8klG&PJ&d9W+n=SJ#({0woX=&`7Pe|tt{gP3B=EQV! zVkQD5Av}BQD4@PBVX`cVN#^9NjM)gSqKjL)aI6>xOh=%MZikE2bj%c2bjCE`Q&sfl zIW|kyf|T?b=46G?75>>4tJTF@WLuL!PLeG%EoHhA9wQ>sh98Kp+Y^44tgO2Is_C5$ zVyqT(re@VK+p?K;&+cj2{MN>WXEQ8Tuq?%Do}Q6pF=r$jF*v^G{1&+=Fmk3PBMa^{ zjLFjBYO^}Z6F-sjGf@$=QqVY!^k&aa1kb^3W(`t%_C?wB<X!em%d|wiOiM|(1ek#o z)43vzc{5Y2mh8;L=@xThvelAh?%B_loz-tzN_sy_`rMvI#A=#V&ei45oDeW2D<gfj zCEaR-ubG!6Yj#RH*bi*LatKSGIkpTi4&~}1N>@XAyi0T~-n<m+Ocq_XH8D%2`bUy; zDHlbH&Zjzf19m99wL0O-&l-G8vZ!Kp_18sV!uVl*{Az?%IrhAzr#Vr_p3>kNv#v7g z*`+5~1=HL-C0~eLt9a|cy=Dp3$l(eZNX(jHW8r0+ds*h9cBdqpEweMN3vRu3KGPsF zdc{wq-H=tm5J(E0dA4PC28QTeMR(}eY`A9q&RoYk%q>u8{^aGs*_Jb*f^EyVxQMu* z^t;xFmHCa%9em5Dr#JoFgCDep2TWmml09W2gmJ+Xv^i{8vZrLH%+5@+B&6v&Z%R^1 zwsp!pXv@qbP5J3K#SX?iqCe&g7uAg<R_bsnP#o4><JsCFR7EhJOKSPw(W$0??f6H! zU)#USt=IPN+56i5k9%F)f5B}v{g=7mf2>caC<pK|=sV!z&-dGWL+Moc*QRe>U`_uc zF7YM&+=FWR*XG~pAvOJ7<0D(~Oh{-|-kV(RYllk;s}7gxa$g(Y))80FZ);?z*azTc z@S}G82_tLzf9OIl<MkX<)4z877su7~ug&iciP!cow$${moqyB}&0pYZgL{LH+WFj- zRx_R2{_k3A`q$3qfrZ!hFIiL5zjpeo*4Ol}&8Jas)b!s|i_b0J()<Okm^ZIZ=c`*o z#fGyCrCqO{hkHPXbLWgVSciglqqwNIj_becbpHM8blSVQE~mNA4P%9HtuHhREl<4Y z<Pm3K=QB3ZIx}9(!ISF<0=-IYR3WChaY@XmlxbO<Ox_^ERgcaXj$kmOQnqDfp?TEb zii;lci7D1$8Ch{?j?*l9N;42L-I9eyFgznYJ0r~!Zp})IM01MS>>EW`c6Q2)bUlUf z8Py1g6U>3cgrje0WFcDD!`qmQBwLzg7`n-$6K8`cvEF?w`@b$@q3VQYxX0MitSLhm zSS{l-;!~0=;WIJU{g6&kRXFtZlbCj#HE9HTj_iTg<1<H7s{4<=1fPjXSW;4!TCEi1 zJ}M(IN#_z$=tF+Gkg27Vh0nAi^q#gwPkfvRPs_+Qo<>HF8yz{y7>7i<#aXlP9|g+d zMvRINi;YqPly=p$YpKBheOeL7pp2Asbj!s4dLt}}nQA$c_(0ujOP5kK+OkkG;}>L- zXZO~UjWF?%3SUzqgqW_yM2FIrNe0JbpltL!tIOphj|u5B72lE~=TC>>0s~bP5K$8A z$(5^nyGLb5Sf<%#%&=s|f~^#cA4Mdo3C~KgVtA4khwcamzQW&qlqGSl<%;)T*NaL= z(8RQqyK8%fr6<K@rlf~w*pTk`NY|BH?L5X=(<Y>&`<NsSf|F?$NNKH1LtM)ke0$Gh zd|I}?9&9)7Ar#u0u|0eOsoK*nKB<B@1MENzdV;eoNm1z-9I;c0aTfXFB46*h)T!|^ zIUbBk!qQ^b*eGlxcK7=6z*N-&@h??!S{=n2HI+^*3ro!8eONe#<%3y{V<KaC-xxdx zmMKZ9ZecD!^l={*9+Q{}se^=o$`bc+$e&eAhz#PXNu0(;ah9plld>d|>CY!a2t}gO z9+B0<A1&SNcyW|5>+%q-s->H0v1X%2wXAPc+3^`w^;kTw)%RFSmKp)4Pls+n`9jzp zU@GHNrq9wb-L801Lr;OJ3zSSR$cA~1L;bL9MGNl4s~&M_7TCz{*YyKE;>BUDW<a`x zcwD8Zt1|HNC6{L?CWN?;{BY4D9^kgFz%sIiVPtH}LdCHtNso6MmS)SI$!vz&l9SO3 zr)?Q3J2NrMQdJu9OwomF6BDyiIK+q-hZJVxESf;ZY2lK_Br`$G5|B<kYw888an+<o z*HI|w{~umlA2Isd(5;)=Z;K##B|RWWx~t86t4B^?U2!q4+ZAuCU(lcM-|N2|xLyuW zo^Avfvcs`B?>zuqi&G!a48XB?BS1p{=YKgLN|*2Ga(xf|IA?A6F<r)`YXUG`iZ$PH z{m%_L@O>8m-wy=vnYDt?;rcU_nTj(`e;=p2)Dld85`cMQs#L|B4c82ST2X6;(9|nj zNe9E{0*Lbx-CYWowAcak&jT=j%$ciM=D+LDYvB^VX93Lbc>u$00g$GB0Q!Flpnp3s zh5R9qFTC6|r^?kItDX)2tG&OP{~rx+q+_^7{QpfC!##C%TN)~^2mZ6Twz%r0<!ip` z^`FJ-e=7B>8!<Huu5Lv8pTh7zpU+iAKyRV1Dgx&JJZ}GkIs6|Nh1mLGFe!U@K8ptK zuB8i>cF|e)+zIVw?Rw2!^3+K#5f!0}bCtUR;kU0ly3VY5U-7%-vi2%ecZ;qwe3%}7 zGs5qG=F~GC#5d14pP791^cSyHF~*`n9((l8qh^tCH1+6!E5m<u<oL;pLiAs(Va9pD zaD;mDM5uTa@E~9nU<F_qAP=w*U<ITB?gESli~@uLf&hL1Uw}8@Hb5^xH-H(?5zr3M z8qfmZ38*}dO{)N>0Stc%?lHh&z#c#e;B~+Tz_Wm-0S^Ll0aidGbUutWDGkp_fGL3S zfKh-5KoH<IKu17RK*blx2XGir0(b+k5wHR9G~iLdD!?*8E?_<&6EG8S7a$f81n>rQ z12B9$KvO{FF>Gc7I0ASVuo18U@HAirAPEo);AP;g9{!C#*2ZBqQv0jV#IrW8e$A`% zFn<Xezd>1l2VNoXlTE@zx35EM;P8L(;rG@y)vI;6>z6?*`O+19U?(M4`<%}3`ctmC z{sZk@BeL)4diBKv!5d{W3Y!`H9^~kkFT%$n{MCSE&GKj3bd76#De4!%xC}dj@hnEx zXBYav*I(oSR2(jM{9#E7h9k}4Vyu$OG1oG<aMY!RYpBZTX}qU=yaAW-4#1_q6E4ST z2$ajhX$O~MF&syo3rAgAI&Ny!!iYNFQwHv;<2@tKcM%XH9ll?7mG_Tc<^6`Myno{= z@Aq8g{gJD@ch>QqZAk^*dk%FIPB8D3Mt~@fa1*`o-gs^|%uQ^-0L^$V8SN%!f~m%H zukrBjUj2Mv0iMwVH2mi;M|h-dJfB>NXYj~)9&x{$xWgsCUhp#mLIG|<M+*0KU48rZ z6~l)Q7xD4&A|)k7*laeD%YeDL_|FxOKKiJ5{`u#{n{U1;N=iz^r=NZ*E?>S(9i>94 zz<4O<Q&VyOhq+CKY4^N&`_<!qd8RVAY300m3l}oL8Tn!5e)-`Ac<;uuCmzlqE}rMj z<Fj)=b}~@Ucq@e`e$L3sWaU3^VY%mNM3%es=Xv`*D;PgH8R_%NVfYXCCnxVm{_0t! zpPZbA_Xv~2^ef@d3t?1v#^;rG0ne4lfB!D^j7*sR3Ffb^3&<ZEGwi3)lJAIL<^GE& z@N}L56#h#qmw#CK;d!RP=gZ@!L?J+B8q&ve{kQkFzV*ou_k)CF^2hVY%S&330k|so z{9FEjmZLu0j}R*m9O?h#@&0~V0QFq)ul>(<ed$9Lmi~x$IxI+5AiA0Z0RH>djsLKs za(`|K{lOpk+k|ZumCBpp!Qav+E2Q#P{AUtQ&70xXP7+5nZ<W5njfpe8W%^a39z|v6 zlAM$7xgohibanxE+`9pkXk5jmKf}4kV>)#~4&KXL;RbLAGz6Fcoh9YG1;7mWJvsOF z^~JX+_|iEpPTYO>-3m8D##gOcC0=;p1@ZdpuPYh<<daXtH{X0yCFhx(ZrKPOx^YWG zO8PyS_sGr3+eFT`Gux79Wr!RUQSvtIZoaK70g^B)=f__XHsdDe@84h-mtT_??fquL zgbCY{NBO=8H(^%voH0@sCCJ4EJ-1DskRWp8x@|=hnBJQ!nSPFxKU}!5Q79?C2isY9 z?krn0>@0=54xk;Zs~e0k3{Nm=d?JrR6`!Dpu5oqm-d%Wkd11Yww-_>HhzJYAH~CRf zig#njjuqG|4f|A05>uy66^oOGi5W9yh}6_nF?;rGk(Gt-r=UL;Em|bj+Cs#OcMlP- zEe;g+8IfYetZ?yQMwoaaD^zS<5+GjAjS`P9nI^V8nkjbOKT;f6H%s(-M~d5aNYQ_n z6d~_QG4OpUg7!%<<zG^SAC_X|Q7OirkRlr};VUU7e<#KClTu7OEya>0OGH6IfmpqI zwRq%_N5o@~Jtm%f@=5XZ(@%@_>({ID-MDe1C@Lyay6o+@-xeS3+$fg*Bt=oV6z{$F zp4hv0ulU!${v{3`JSYwyJ}izNJu1HV;tO%+n<L_*pQZTn%P*B&l$Mr?b7#I6Utg4> zyu4goxNt$q3fWq(ALch>F{cTk@mz&@z>N?dRQBfOkW+bs7$W<N$#Se%Am@lj<!VtR zH(`CyK|`O4)`;IV7VT@M5JOgB4Z%jtKO+8&a<rAQrC5&mPa^&+h+l&EhY<giOZ*;) z9~vvf9hpK{S7Gh$Mj`%z_&dslIEeU15dS#he~tL1h<^t0&%4C$*8^)W!yxOEu^tz; zx{WI_hWv*R<vURc549BXNPi)}7%SwdIYNHFTFCNELY_ZZg@3=+h~E|Qy%9ec@naAl zX_coS{(_c5F7Geonz2IubB>VPS0l|$LVk0wIzBodu^x!u0P!(tx)J^0{m?(<=)_3# z4MGO@7jnv2A@80e<Rhzv+`LK1!w0M5i{@B6+7|ttE?7_Og=#xU?1$u+WA6mn@(v;U zX9_v?ULof^Ddg%`h1|49$b%<b;+qkF5aN$Q{Aq|kAMsZr{<Dbx8sfi$_`4Awd9FT& z_}?IYc~$(|uu5|zQb<7x_aTM#Na0<i@Fh|xZz;vk{iQfJR*Lg;q`0tJii?}1`1K$T z5Rj@p6*nP%AH)wq{Bejs9r5QP{xZaWtfdss^_SxHu~O`qBgOvJQXJbPMcKjX_@0PQ z4zxl1n-ISX;`c!O+Ympvr4+aKmtxLXDOSuuTC1hlwn>Vk2dm@PR1FE*<@z!_d}!Fv zun6^PRPSEhyLIi_V|Z17u%XdWQ4tZ*;UOVm5ea>I_3YWb+wkGHB<KMmqTr4HDBMIu zBzWD*0K<oyb^qv?@W|*8Bp(?b7BVy};Wh^7-o0xV-9IWOG%PwSJR%(NiCN#<yu5;S z92q1!Cfc}$-PEpaLSF=63f;PPG2a3tqnLhlbW})mLZ?>k+rb|Jdg%drBp`lB7!wGO zPPnO6tM;0|!m(RdGmwm`N<X1Z>sGBs4p9ksDJr|bANWTwepod8Tes>oQpasnZ=!(s z2_a!IqoboEqZ2wXf%fg%w!N`w)21Cq5l8y-<H;E0lF*?>fCRFE{^5}^QPI&ckujZX z1b~0f-YWf}F%i*`F%dDtZtl=V&jL9l+}f+pDA3RJ!&Mdr*Ajx-0R=vRe=7a{fiYll zOk{M7B0}M4@E`amMD!0O3ehn!2_1$FYt^b1h^X>U7}Ovkv|l8$7!CiMhYeFycC7Lb zH`O=!HTRB;j)(!5hjms|b{eLOM@T?e*Z_A^eeaNjn1q<9$QTVvs1WUn3illv-p|9W z@o3$Hyo!o|y3+j<{QI?N)WFTH<p^L%6l0=8AV}5zVS@*H`!sU*ydesn;X@(IzP{n% z)&2<yL&L@dHg8ye5ON4lVCqp3)%hocQ|`tDHmlb#l>Xr%5Z7oUI`~KaK)^zqv}`^m zAv`7|5VBU~4S(Yr(W0e)Oc?kW<>F2LN2m~ZKiDTc5LLz1TcwZkjgEjIMnw(`sO9aF zJ_<T2ETCp=)Q_51OpU~$Uu8*7g()}WBsv!*fLsm!N`Ec~Y19T;S6?nygw*QKUAv!R z^ykKn8>jjsi!H;e`X0~E4;IT(BE_Rw;o|kBkz(WHi^bqQ=u<$?jrdfGiRe49&oCeE z!w)|!o_OL3v1ZL0v3BiR@$9qDs=mT&uf3-FgKxd{mSA7u<C5pa6X<VjL|@_Eci$EJ z_U%)BgHvCf5MO=ul{j_klqf4J6Q@s~7C--VM)eJT`Q;b!+i$;#)fc4LgucSTUtRQU zzb<I#2BV=vy<9aN4c!7XboZm7drq{JuZ#Zj9Whq!5p(26VzoRbHpy?$epk0Mq8}Q> z*mj7I#&*?hh(8GNLlHk3@h2nx9K^p5@z)^!tBAiB@lRB>Gym<UfPMe%r~IGnr>K29 z1oo8c&;gZ5i1uohvqQV?{rdIm&G+UG9olv1(z|nu=FM+Lf4F_uUfsL*?B1_s3)8L5 z@Z6!xEj@c8Y|9p%`+4>A5*@qt?$xhT<9;m>pn0=qH+SsPy;r{`jeFg!zc8D7_3r2C z*|Znp+<HUvW*yqK?cJ}5r)T3v_3Jmi)nw}6(V#=`PE9-;^F_ZFo!c~YYuFWG`}OP8 zs6Nxbv0c4ZcxrM><3^3VFb?R_{U-O0@I{nPct-wS9b5Oj#j9UGub#jk`S<qn>gMIu z#Y@rG5f?3iUAm}8kz>OC9}N)@ePso1aO=AG-U!3+h$lL$IYEK$xws49Cd~N#OIJO_ zMvq-B<3O)nx%J^P=l_Z8YSdpVZ{pho(57?e&RyUVx&eALYSaiLAbgIZIE5}WwmAee z0~j2~?Z4$Bf0!;tH`jHMw=Dn^fAdpMJr$33XX}|WXTJUM#~;5#+w;{AKm70w+!N={ zojZeZ>8WGKj&0h#d$$9239q1_AV@w-UoE|1I$V-MKKv2>v8>rJ-_WB+k6Yl9SDaqH zo~zyD$&*6{;X>e>FpqdY#?f-ywr%pe@4l00PbKDEI6);(oH!vd{+9Fy4H9GUFPu(i zDQNxj(4j+r-@bi&&d{MleUJ{zsUx5*fJ<bE3(K{!4!kFi>Bprvod9hySK(7pQE>_P zXgIGM|MuYbe$+u<rZIT%;2y*ecq#nffB$`nIZ_Gy<Qs3iq435WlKl4DZ{>jl2PEbc zR5->#AA#>rA<k2qHf>t8Wy_XD==Me0?e;O5nVAtQSFVgjznZw+3h-*%wyh85HtrZO zU;ug7E+QhL7t_W4AHx6a*|QRTnbo)4a?3#QaOL;ke=jkoTgB)7`}fPwKKo4JiSkjn zvusYDJSji_{B!k8nhZdnN8Ll_&i(Y$PZf~6Uy-Ks(xprC=bwK*`|-ygzxnmoU!Oo; z7a0e1K7jf*5IC%4+&_vx`co2lRRQrgfP6K8WnuvFC$H!l_k1Q8bkHR}1^{Pi0Lok% zV7xQjKZF0yojX^c9J@j$@<_{$9Xk{aln=}|NtOZTnUuT`N7f0{VdZ}G(MOWNy20|G z%lg5(!#E#&@PVR%Wr+GOSq_-1=M-+$h38-KzLNf^!!+_=Z~bk5{``4~W=P4upPye3 z$}xdufO#{yb?a7%GMDHxt2)dwV3}ZEO#yM=vuBTFT{&{(h`J{Y)B%(?))STyaohZ( zloo7ZAF>apneUad-+MgAPRhO|I3M$UDPO=b=D(aj{}Jj6>;Ls!3jcTBd1rOEZrui= z55E%nQldN*4b(X-1M-#huq=o>?^*uGj~`dSd-9z8Cccyf(n7q+f6C}Hr=^VeM9R=Z z*xDOY@PlD9@Yw?z-j%X9Xy{QaW!JZ)T!~`=Dl03WydLBcM&S=#FAX661{h^wxPPXe zupUre;*U!?93R7lWB2P2(tt7;^nsKEKtuYcuy<5qzWX3f0ewe_Rr&Sek9ktc@(Ldx zpRSOFJko)3Q1lpd&?PS^N92E9bdc}lIm?K0L;0uP#h6VYGzR#O{9L19C_VxU2Cf01 z0rSZ+6Lb;(l#itB_O@0nt`~o_8Pd@Ilz+5Gl3<hvUE*)ZIpv?_LAj!A7__jCQ_d*& ztQ&^QdciC1ODRW#1|H!s4E!byL-4Vi|GzXEyipf0PcD0HQ^Bc6ujgt{{Gp3iV~&3y z%3&qz8FfotbWq-1%fyf?y5v9o*)A|H^^EH^@f7MPY4}3QD9{iI8aDpm8se(=Kf&km zs}R%v;>C*+?Mw|I4F(u=)Kw-1Ev|I@`s=Uq;G1jY`i0T*@i`&#;fzp)*d5<WIpJ$5 z$DWijhBV-O3ss*XGeJgurcOeArcUaCdcgYJ2lB)^eHnJPI%rV%qr6vO?xHL7dLC(^ zKBQ~VK$mh)xvouzAzzer%F>AsUzg9%3zF+>L*(DHgB1-VU}`D0%-3m%Jt5^N;4}g> zRMltFpx5WV)Jf2(-Jz4ZfQHU*Xu1{2EU86<!oO?Ru2uRUZ9LogE6RiQm+gU39;^?1 zHtGrShu)JVk0i+#7X-=Y<_(e0fQB`ofmb5*=M>OzJ9PZ`uW+c(iR$`H8jSi(oz#Cf z_`XxhTS)`>Z^oYWW1y#S?W+ra=zAsqsB0_PA7Y&|=rCwu8L&NYEfa$ly2PJ)vS>+| zeC3`%`2uKI4;t25HT<*BNO@NoXmH|42hhO!Oq~=Bon+K!(qPnQ(qPnQ>ZD#<75*1$ z<Ij4=_67Z{Dj*F8)TYCzE3S0#o;2{<lH)I5T^Jx=xjRt)V?Jn@J4F6c{=NJZ)tNLT zfCkvuWV}m#rcPpg4ntj_PV$3JV*709q@LSwVuFT$ZN1c<_@jTnV&K4mUC~F$BOTO> zbSX2WgMA*lq=oO;)*AgX`mw!bpMlp~x&CtVVt=^_G`tKNHh_k=AIp&E&Omss<0=K6 zvr#5~Y@b1c(Z}fdjuyE#|EVtw`40#P=)tlufc2Gl6F1^+&_dl$ea~?X^(NaYwr#xL zS?VX>1Pw)t1LVeqf$}BLP`f@q1f8^cc9>i-Yp7h75-#mC!evfUgml>MkjFngAW4I3 zA4An==p<fs;SYVU<RAE~B<{qEE^#8>tPkX~Q6|*!uKi>7he#vkf9JAbSqvK901dA% z0u87Otk0x@^_e>9G3Zs&u!=OK4wd)K1P#d%a&c0mqJem_kHPlY=wl2-`-bZZ`KQic z8^(SFVZ(+E^2HZll<b!pV3Y^lYt<9X%gO_PPn6s3gXP;xKm+Q+YoOtudVQu&T5AiI zYqEmnqnRP{!Sqmhe_EJyfQEZP!&1<&2sH4j-N(2SbpzKG`iJ;K7L@!$uJcICz4zWL zUwY{!MUO!P-K)_-nkZY0>pb|H+>tj}mVkz>ph4AV&_JDJ)aR$6lb*~9k&k4C$_GHh zO3<(zG~`2$mRKSbqSQ%YE`5yGQ15YFq5p}$A^(Aafjx)=@x-c-DjHZWu5?_BmfwD> zlwWRtT)wv=TyC@b$*p>QrcN^I^Rv)Nq~QsjhQC3MR?Z5O1t}U0L{#-L(BB>fSOa}^ zS;`M;$vz+3v&_-{uEsis==AjT_lYa(BkRE8#fudUuJTozmfB^)XX*sjh2OhAefO2B zJ_hS^p<bVB#k*$zhxoJXM~oQ3a*+S{$3Ilxi+vi*56HQ5=T^~hEjq4MCd7w2>2>O) z->c7{fma>8uIp8M@(F8gwnKNyo;`cYgoFf%wHcEAy6o(1X|-DAiWMtVy~dP}(mU)6 z)kO<=&$fZOihUvWM>!tg#rnMeIh(A!gz?6@xvG73?PENq*XLEJ3%u$=)_8}x3KRPJ z<MFKU@6)HxAS~@k$5yvx=trw^c;=aB<d`vIB-R$m!oorco05F+!3PyS9N&}Qq=9V# z+X>1QfnylbKz&L%WLrocz3YgOhn^??=jHp)&aLiapf0eF!TL;{^!WT3qW`<&FU<WF zz!bWK@&j34jdA}#tb=(8by&hrVox%OIwAQya^y(W@4<Q)r9X)~ab+2i1_Stx{HE-2 zoWs5y%YyZRbz0SDlmpvmqdrq7xz^_ow>-su;1dR~ujTst`#*>^J!&3=dFypqVvQnC zaFm$SlDFP^t3=;g;X*vv-*5%eV1PjfU8YB%Oc`lYxBhF*H2HRZDB5SOkHPl&#YN$A z%L6my=O1jA=YRR-Bb4`b&p%)-rOeCAJBu|+a_Q2gzua-h9WpH~P4OM$N+nCAf%Ss( zKE#c5)TV`V5NwAj_v|CFu5dnL8^)7-$37C<3DQ!>1r}U9&hq-B^FK@rb@yq^QJ%Qx zo_j76PplhNz&dTv(7ShUiM4C09N1=1=Gpf#=peqtpE6H6IX0ln`oKEE`e2j^UCJQ) zCPv%Cu{X!hke5F+|H-;V`G+j6#d@*Btf#Pu%Y_RUs&XI=)T@|Vmbc%2yL!(uAPokP z24mdIF(v!hlzZYymoh}!4Ef@F_NmzChA#OV=AH&&o#Fi)L;M;1Dfa}*66c#q6LI65 zGuGaz`Wqe|E<-~@C03`Xa-cus7&Oo|<jN=$qn@yS5O>3+9C6G*xne(%WoOK90Dqd> zngXupQu-5guYd`lD|nd4`dnOGtY{#AIB$shp=d}<Oq8QWjZ(4&o4mrGye7{{3-M+> zp#I@|ju9w7>}zjBJzyPRonX4u!NC18(#dPru3ad~{Ta+VIe|27KD6sx&!zegh77X* zWAK&uoH%hp;e)c3=v#1Av8oR!ZwYx*GQc*9d}eq8pGgDtD0xc#|LUu+%2!@_MYVzd z{O3PaJkAk-PfqBzsc0h?0{0zwcOQ_Z-Q#-gH|>cp`#;qGsE;f8%=$)`xUk%*7a*sq zF9AD=(ygfLs(qubp?p*3h(GHA>m|#Ca>6p;d=~wUi}y^IWyJDedk%Wn18?e0+6k}s zQurHkO4n6}NrM5zjdW3lSQqZQ?>-5gCD~59Uc}7+#-W~}F5*S`;h2a(+)39{Pd&vs z#;5Ta&mYB|G%Ea!{y+GgM;Z*hXwYKNK$rZcZbI9w#tD=uwzaPOC9ZrX{wy1#4?(*Q z<({%cp0f@?XFLi#{tWI__`AwKb%bkq)Kw;=i*xK#rc9Aom#gI4;JK^IaFiv=I^VMm zAnt~J1Y@K%e*t%eKl3ogzi4|_QZCsBkq*{D@`?I`x{mFUYnhO@n>TNkk3asnl4tVU z0Mbp_VclWBiO-Z7rpLAbI`esa>h)*&PTYC5CqAz2BJnqXG#GHLGGQ866Rpyrj4=*r zBfgZaZP1;h#lRi?)93!AylYrj|El>P)GsyuMf;scTF8I81|4(_I_Q$8)Gw?H1eOio zu^gy7Sx;GJ)J3!<&;~_X$am!NXY@=p#x?I0{)YUcuh4^hB3!FX*uQ80hjh^{N1$xc z-L-3%(!1mV>nr7*__H2B9-l?_e^q8&DQHiA8uOpf6IJs+q=9WG`!CdglmoU$Y&*$g zjycJDmIM0&Mmg}AI-k0hdJJO<W!C`B|8Cq#hmwC+*{Ch&#<NjxU0upLpBaW_L769? zNh4()a&#Ge1SiUh?JCz;{E@ba`2F5>0|Iaj!haH&2iHDuoyK3jWG)()ZS&?;iiYxX z$h>(c@qJFY=HgC0|NC5bJv}$w#n&&$57%FGjr5H4UGUCj@^~)M-IIUC&C&6cn(L;! z?z-DhcTKw6S$9KpH%E7+=DN}C1$@kaP{5yDr^WR>?B5b7&sXg$qNJAqFbgiv16(gY z)1p#)J`l;(c`>hc7z=u%&5yQNEMw8%kHDON7~XpW*ynBosFG8r{Y8b8b7AWl@rh<* z<6JOp3Ikx<nS#0DPkvS?T?+@&+7Y|4560MT4(fCT^%?q{zd+xXqAfTLy>t})^Jg$m zmWn=b1j6?RbVYyT%naB#XeZ-bXej1yY4fJN`0!aN_hVKL-y`w*5#g_Pb%G9Ghde8& zKdB=*ULp<z!-k>v`7cASo`uf+2zv7^CQO?t?Txfs)4swvaoUGIJ}2b?(0(1Z-p<t1 zm{&-|+|xwjz`hg5o@^hf*Vz_PSF<n6ehU3~&ucPlRkV51)<zo-?VYqy(Y`~wKW%Kh zu0}lGcjg!XW6*Sr7gE{&vR&gim-(_EO`hoVtG<(#qV`LB*&Ud>rM-`~ve(O9ee1lZ z5zAE`RQ?<fvX4L@4g~6V0(rvr>xXZS%IED9m0g1K;k>5(0DIT>n%y)GIMD9PH4vQJ zr_I-pN7{R7XAFY-aZQ=*%r*t%*F^MlClU_>7nVQ!z{G{^&(_Cgt2u4joH-|N<WC&# z1P-)&(tfVw5jfD+MjH?1kv1yYI%y}IggSz2k6tF7*^Xo0B^}@2rLt`%7&x%cL7uR0 z{mSBSW$UAThVzKLm^Xp8SK5zh^K+F)u4SQ(hPFQ1m?)24#VYD~BY*aT4ErM6Rrb@2 z{+oddV{l%XbAjtHpGli9zNM2(P{&+xpgc~jC68FYuj&NX(oi02+37knf7nwJF|RPu z6%Xc3Ij75u_BPr`XfLFlYV#wRziTu6{t`|?KLML3aNv3#)(P5dc^UMxUx72v(sOch zQrQP37<h2rguLLz`E}ZwXyc%*jCLm4H)toLjfu7m+Q?{MS~y*UhnJ>E;-KUac2~pp z&GcOJrw$;nZ$og!gSfE#x8D~cY43U!IB-srbK|tJP#$ULqJ4$7MrGsD^Iw!Sj9IBV zVaVeU@Bvp<`Lk~ZJ47PByPQZ}!0|r&=cJpskOy=RtxHjML)xooyQR&Lw&$mGdm-xt z?IW}m=E6p0@PL`Q>S)?-aaGAb>lVK4O^5zZWnHA+;kbZfJMx6Ohx|C_{7k<8K&-M8 zaDJNdNE<%qrj0s5I}>evw3FrNI54x=6Pg`=3i3X7fp4mGP-pfpDTAzs?DNwl9t84( zKs?ANmczBKk9Pc1*-UAx%L5Lym)5$j(0|O|;cz7W{qKLDNZSzm<HUnJ=eU|<YR;Py z5AuTgh<?0izvVgrqfXQ%j|`{FT3t?O_OUTvk&gM6+2q6h_usGd9`!EUKk9$V0{KB% zWZuMu7wg22Umcb|eDw+HL@jwlouEAOsw-nd{y84!JO}4=$zzVMP#4vBi*=JY8Rg?z zHY|(xR>#WnQ-|f5uRp1lN7M=0uPKjDES|*d>ump_TiM_4%=}@C_%bAfy}EhIHjO<M z<nraq)%cD$Q7^I{5D)Tz<wM?_bsm-b*3Ob|+QZaZ07D+1Sujk#`cS4UJB7|kwXD@( zLvV1g59WIpkPg@}Gp0?Owj1AX%UQE#sd-?mkyLXR#@L5ECqKx4j_)W7<OlJueKAdh zI|SKsZEI`f&j;AWCZOJ{aUk1z+GS{4LO)Al-M6CK7=IBD0{KBaYL^Z1W4lG&!Eq^) z9|U0k?pjx8jzQ7?_@1^z+9mLvspR}CahNk_j^aD@0oy^QZO8!gqFylSD%y!k*kxuw zmb1}Ex{OS@=IQswRGrBy@O~8z;n_tS59jFd!M|i#(7uLtS>?n20Qt`R3G9=xk7l@N zt1f|`_aLpOV6XTAd2=Z6dzX?w)<LGlz8(3^xm?O1=hA7{VErJT#@rRlfO>)Phzof^ zy-l4-JhyGzc0V$1{(G6jU)6uuZxity-9+ZiG+EBX0s90<>?<Hgj~=aXBMt<HVI5#N z$_@KT)E8Wrh`I2!NS9-U>$#NvrT)P>`c$TO0(0_g^Qm)aTfm+L%ErukLHu};55^oX z`^&Vcu-^_Eo<yeCn>X=O`5W>~z7mKBf%&mL!X61qH*l>gX{XGwyvS?PO`VLnm*@Uq z-YS3Q16`x^e_ePOePDcZAo0DUnk#0%kaJFy$G?!b%AfQa?Js4C^fFBXbsp;+>o)16 zjB))A*IwYe0Hq)PB;CxLS7*{+oA0jtXBiNvd#U?a&e#)z^7jMg!wQfF=TH9Z#cxeo z{7GQ_`aS)2RlF)Y<C|T#s_%6>=YkgiH-NYfU^pXAXG9@{;GF?ExF^WmI`&}6z2duF zv$)!YwOUNO&I|Gw{?t=Xy$&1AdFZGgu`c9q&pr2C4ZQ;!z!{{G@xlu)sP_otv2NYE zD9mTS^YY6ttMWA3FqSiP`X{cL(Vm9&&zxud6=|G={GDSx<k*<<`U=J%ap>1^U1JEw zR!?9Yh--_H2E$UO*@rXwGe(`FE=$0;iDM?tAsj-t#uw{4aT)z%LHhyoVqK$NB2Zo# zmscW&CmaKB(Yj>no&NI++|ATYtVhI^eFw_+fw!NPt24B|;dFic#_=P^uN*6Itm2Ka z(qq7jwpNbGi96+=`Tk>Zl<MQ0#Te`f;LJ2Q7U$TDa}gZ(aop*LaVO`f*{34j)LXnb zhT$0MwTI?Nrr~;(LB(=Thw}&=vyp!+C$>TC2l3i^Z=~vPas0ut2gg3_>vFvD(vt;} zX>c4q0(h|eu=k9zb5n<r4=3MUD>vs3QR7MW-Pv#FxPfD*MV8?zkGK<3Zos$}-+9ZN zoE)`AgmyKSCFRB7zY2_>1KT&Me*Yqjee{dO7Lk8w7nI(jO^)ja7}t=wO^bu&_a{G6 z{NxxaKSkw#&X6C<9(6tS4$BhXt}C8WSF<dS?|4SOx^%c&&%I{;NcsL-&olcXBR;-e zQGGS)FUk$|Hv3#G59(7_TzJp6+=xq;;f?Yq?~H!e3AB^UpY0LH2~3-M8Et=#YkcZy z;>~o(3;3)0#5SArNsP;JHrsC4Vrs-?I*S{=6xISD+;tFeuLedKh9{U9)(sPxW;4!( zg|g(1Yi<HN=&C2~w^k2+eCMflTXTn>_Qbu`Jg}n?pUi5fwfcHUJRwX2J)~Lfver-p zC1z*i{PDB}=J~VJ(zAzjwPmFTWKW-InVp#3XLic;tc>i8WNRNBZ5EK2J-hGR{$0&D zbT1{@l5L%cgA8zD$B?f5`+9c`Zr0dr4zgz90CS#6ah<98Xz>s;8)quwsEY+E9W$<= zEDO#%#OV!5u~{i|anivIOLmo~t9PV2juD8A!uf4!<~05e>6(}wl|DCPmL;pJ*_IME zeL9YE8PYX5F)iEDH8`kWRoXQpSEcU~;)>jZ`qjWSs9zP)h#u6>;Ae1bSZr8CMAYcv zx8JVc{P+3a#}D>CsBG$cH}Sr~yR&x>Z!hmq?^y5Y-p_dN@c!7l(z`+boBRLVf82ms z16~}kb-<nhKM%M(pt(<k&m<p<&te~k&sv{%d_ML$?PKz7?K{YKr0-1MeBTFspYeUi zcen2szNdVD^u6TUXkhb!=7D_&`V72p;Nt`L4)hrmJSbsM{-EQ7P7i7|IAU<j;PHb~ z2ImicV(_8C=La|N8|k;$Z?E48zbyZU{9p6m=^q;Kb3jFaTcBrP@4%-5pAUR1@V&tI z1CIrM8(0?DFsNlv&!7Q8qk`gt5`r><Y(e)1Z425PbSCJ0P>UgLhYTH3I^@g{x8Qq% z?ZJ-*uM2)R1Qi;mGzl@=`$<r_$@{(j@dLXL8ZxM8@U6)84S&CY(15W4Qv+-P`vY19 zIf6DKz1=~FgH8sW4*EIBV@Ok^dgqYoLuL<oXNY(3px~h3p}`}9M+Z*`o)SDgI5l`q z@ciJM;QNB_4}Jvsy%fADcuVm1;P-<+4*oLu+u-xTzXrR7Gz{q!(k;X*q<_fBkUK(V zgk*=<Lzag;7P3C%)sRm@oFV5!fFQIF)Q@Q5-Nrl6JKcMc_r2aPcz@>Y^j<&U(*frP zwDFnm^Mp^a&mN!4KFxjoe4~6P`cCzo?VID9=X==qTi;y+4-EWb;7x<N4(c~(;GnEQ zD+g^F^zNXa1~nf%ZE%oZgx?gud4Bu+e(`hjZyMkanxg}z1Y`#+3Aiudg@8=~?*|+Y zI2G_ifC&8m+PnUrs>(PF6Acv$4Ga99VxgkGU(Px2Iqz4Th-fs?X}XE&4E1Ut*wom> zb!CL8=){<!q23r0GL~p&WXkRc4V^A6GjsSQ!?dzAXKKW<&&59@?k{({+d1$1JfG)z zK0ABQJ~v)uiUx5>+z@ecsEh}$89b&>kkh3fxZWbalb2<Tic`bXNR_CtGAf|<s{@MZ z6yRi`_5l}L^e!C$E)MB0I=Q&0TXmcM71-#|J<anb&WtdVfC;||nv-y1_|SBi&>>bl z;O~b<gCb9(-_av99y9F6MYsZgi1*_I_y|6Rzr?5Td3*_9!8h?AxE(*i5u_J+mc)=a zGL*y<N~Vx$WH!klnPe$hK~|Hsq=b}`9V9@4<RrOD!f7OprhfV!-9mTMAU#1((;umA zaci!%0Q9`cDz#i&+0*Q7dmU)_Z#&8v;w*C3I_sTEr`D-=8lC&j6DNjE0&YKMt*pD- z*PZRobC<XsuIHtDL4Kb17O`TuK*AFf#XF)vl!$%efM^0050*3JBH;196slI8Qd&>d z^K_2hsJ8)c2SGbO>%00d{jct3`WeqG1ih>`--a}j9u^illp2nfp+>Y07<q+EAT!7& zQfeKwKDVRUi|nHN#O=+8^9KG4UoPX-ICVq)seF2so@!>A2PQPsVJqB&piESPuHz{r zhpZxdNgMf%gwe@#I?bnL^boyBdswkninY|rvFfek;O<A(D0{lS#@XZScg{EiS%Ev( z%l2BmIG(`Y;;Xrzm+}f&_W>U+=8L6bou~!ZM#yXOrqudXJrf*Kt*`3adX%w@Hq$@> zu#w!(nX+L6@EA<7hc!;d^-$?=ptdQ1Z86zEwv$RyOAe7na*Nz0?PLHQLC4d@G>5LC zhrtu4V6V?v1L5_zS=Jj+!EM$KYoE0O)Stm}*cKLGpRf~9rIBtsA0%dpd{H5)#c|Mh zcX>!As#3LE_1ELI3w}PT@8}5A8&n!=2AN@IipepXO_?b-6((S+OpU2C^`_l~9-KnC z5{4pBB#J_BgJa9lUQ~r@P#ro8>K%m<wy=vOP6AA+I1O(HB?oX7uEDWn2x$g1_sL@t zN&C<t^ktez9V%%GO{1^V`E(he%cBK!GdTVR?Vx^8;%57x-EP0{yveSxFn6b0D7VWR zc~qY1OsW@Dg5oL-(kfRKs4`Wp8q{eODs~!dGaPo-1Zk3nGx0`TY3;N}vuw7L9c8<{ zp0W?*YJV9g2g{e_NV!+m$rJJ?IaEznmz4+Z?a+5ZwF*4dUw_D_R(ymM(a-2vNTadV zX{*DEw=3-)&M0T1lj#&WUpuj^iJfIDAlY~D0<lXpimzbaAB>yp)L(Cuf;Zq#@%K1L z$3SLLhdIJAaP?$ouCv^E*Qs)@fzNue(QGZ-#~RsX_Ka(}#?5xuxP@-Bd(rLZF)!K6 z^7eSuUYmD`U*WfSUxCFEu|kB)1eqbT<Tz!iBsE24s1MXf>WFGm*}7T(pd-y#^G^s< z5N4&oS2*f}l2Hci>NQB1b9fAyL#jy*EwZcZhjur}Rn8``Tz56BzRukStHVX-p8f~z z0^rn#vv4lXhrGG~>D0#WfDbx&goqL`Vi2TiqOgP%$s$e66d91QSz;yVun=+q?sNU= z5RoVo4f<+<jsU;ids??hlz>u^4;7+fP*w|SgBnKS1W;Bw&cJ!N442~uSn)Av%7r~= z5`SmXT?aQ0qe-A9AI!lB4~v0pjYhF3!A`W1ZP~6Z?Ib(dPPNnQJTH&ugMSNoF)!g; zc^NMUCkJ>Hui<sPo*xERALBvZ%v<;wevV(@mv}3`4jtn*;JgP&9|P7f5dl3rN<;(V zSin3C($5kupiTnZsen8ku+IVX3jn_l7{~<<@_+?D@K6j)Y!zjq9K0D2RiZ}JiF$Du zdeJcv6wRVVoDt{51?Wt!OqFw_Pv*%AP=6hC?8CA_9+N@UtX$~NNje!ibec|w#F+zK p+NZO0u3ia!I$!&Bp)Q8rR25QU*QbktE(W?7=whIYf&T>q{{c%Cm0JJ+ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/w64.exe b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/w64.exe new file mode 100644 index 0000000000000000000000000000000000000000..c41bd0a011fd760ce20ba795d9e535e0d2c39876 GIT binary patch literal 99328 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 B=L-M; literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distlib/wheel.py b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/wheel.py new file mode 100644 index 0000000..7737223 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/distlib/wheel.py @@ -0,0 +1,984 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013-2017 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +from __future__ import unicode_literals + +import base64 +import codecs +import datetime +import distutils.util +from email import message_from_file +import hashlib +import imp +import json +import logging +import os +import posixpath +import re +import shutil +import sys +import tempfile +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 .util import (FileOperator, convert_path, CSVReader, CSVWriter, Cache, + cached_property, get_cache_base, read_exports, tempdir) +from .version import NormalizedVersion, UnsupportedVersionError + +logger = logging.getLogger(__name__) + +cache = None # created when needed + +if hasattr(sys, 'pypy_version_info'): # pragma: no cover + IMP_PREFIX = 'pp' +elif sys.platform.startswith('java'): # pragma: no cover + IMP_PREFIX = 'jy' +elif sys.platform == 'cli': # pragma: no cover + IMP_PREFIX = 'ip' +else: + IMP_PREFIX = 'cp' + +VER_SUFFIX = sysconfig.get_config_var('py_version_nodot') +if not VER_SUFFIX: # pragma: no cover + VER_SUFFIX = '%s%s' % sys.version_info[:2] +PYVER = 'py' + VER_SUFFIX +IMPVER = IMP_PREFIX + VER_SUFFIX + +ARCH = distutils.util.get_platform().replace('-', '_').replace('.', '_') + +ABI = sysconfig.get_config_var('SOABI') +if ABI and ABI.startswith('cpython-'): + ABI = ABI.replace('cpython-', 'cp') +else: + def _derive_abi(): + parts = ['cp', VER_SUFFIX] + if sysconfig.get_config_var('Py_DEBUG'): + parts.append('d') + if sysconfig.get_config_var('WITH_PYMALLOC'): + parts.append('m') + if sysconfig.get_config_var('Py_UNICODE_SIZE') == 4: + parts.append('u') + return ''.join(parts) + ABI = _derive_abi() + del _derive_abi + +FILENAME_RE = re.compile(r''' +(?P<nm>[^-]+) +-(?P<vn>\d+[^-]*) +(-(?P<bn>\d+[^-]*))? +-(?P<py>\w+\d+(\.\w+\d+)*) +-(?P<bi>\w+) +-(?P<ar>\w+(\.\w+)*) +\.whl$ +''', re.IGNORECASE | re.VERBOSE) + +NAME_VERSION_RE = re.compile(r''' +(?P<nm>[^-]+) +-(?P<vn>\d+[^-]*) +(-(?P<bn>\d+[^-]*))?$ +''', re.IGNORECASE | re.VERBOSE) + +SHEBANG_RE = re.compile(br'\s*#![^\r\n]*') +SHEBANG_DETAIL_RE = re.compile(br'^(\s*#!("[^"]+"|\S+))\s+(.*)$') +SHEBANG_PYTHON = b'#!python' +SHEBANG_PYTHONW = b'#!pythonw' + +if os.sep == '/': + to_posix = lambda o: o +else: + to_posix = lambda o: o.replace(os.sep, '/') + + +class Mounter(object): + def __init__(self): + self.impure_wheels = {} + self.libs = {} + + def add(self, pathname, extensions): + self.impure_wheels[pathname] = extensions + self.libs.update(extensions) + + def remove(self, pathname): + extensions = self.impure_wheels.pop(pathname) + for k, v in extensions: + if k in self.libs: + del self.libs[k] + + def find_module(self, fullname, path=None): + if fullname in self.libs: + result = self + else: + result = None + return result + + def load_module(self, fullname): + if fullname in sys.modules: + result = sys.modules[fullname] + else: + if fullname not in self.libs: + raise ImportError('unable to find extension for %s' % fullname) + result = imp.load_dynamic(fullname, self.libs[fullname]) + result.__loader__ = self + parts = fullname.rsplit('.', 1) + if len(parts) > 1: + result.__package__ = parts[0] + return result + +_hook = Mounter() + + +class Wheel(object): + """ + Class to build and install from Wheel files (PEP 427). + """ + + wheel_version = (1, 1) + hash_kind = 'sha256' + + def __init__(self, filename=None, sign=False, verify=False): + """ + Initialise an instance using a (valid) filename. + """ + self.sign = sign + self.should_verify = verify + self.buildver = '' + self.pyver = [PYVER] + self.abi = ['none'] + self.arch = ['any'] + self.dirname = os.getcwd() + if filename is None: + self.name = 'dummy' + self.version = '0.1' + self._filename = self.filename + else: + m = NAME_VERSION_RE.match(filename) + if m: + info = m.groupdict('') + self.name = info['nm'] + # Reinstate the local version separator + self.version = info['vn'].replace('_', '-') + self.buildver = info['bn'] + self._filename = self.filename + else: + dirname, filename = os.path.split(filename) + m = FILENAME_RE.match(filename) + if not m: + raise DistlibException('Invalid name or ' + 'filename: %r' % filename) + if dirname: + self.dirname = os.path.abspath(dirname) + self._filename = filename + info = m.groupdict('') + self.name = info['nm'] + self.version = info['vn'] + self.buildver = info['bn'] + self.pyver = info['py'].split('.') + self.abi = info['bi'].split('.') + self.arch = info['ar'].split('.') + + @property + def filename(self): + """ + Build and return a filename from the various components. + """ + if self.buildver: + buildver = '-' + self.buildver + else: + buildver = '' + pyver = '.'.join(self.pyver) + abi = '.'.join(self.abi) + arch = '.'.join(self.arch) + # replace - with _ as a local version separator + version = self.version.replace('-', '_') + return '%s-%s%s-%s-%s-%s.whl' % (self.name, version, buildver, + pyver, abi, arch) + + @property + def exists(self): + path = os.path.join(self.dirname, self.filename) + return os.path.isfile(path) + + @property + def tags(self): + for pyver in self.pyver: + for abi in self.abi: + for arch in self.arch: + yield pyver, abi, arch + + @cached_property + def metadata(self): + pathname = os.path.join(self.dirname, self.filename) + name_ver = '%s-%s' % (self.name, self.version) + info_dir = '%s.dist-info' % name_ver + wrapper = codecs.getreader('utf-8') + with ZipFile(pathname, 'r') as zf: + 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] + result = None + for fn in fns: + try: + metadata_filename = posixpath.join(info_dir, fn) + with zf.open(metadata_filename) as bf: + wf = wrapper(bf) + result = Metadata(fileobj=wf) + if result: + break + except KeyError: + pass + if not result: + raise ValueError('Invalid wheel, because metadata is ' + 'missing: looked in %s' % ', '.join(fns)) + return result + + def get_wheel_metadata(self, zf): + name_ver = '%s-%s' % (self.name, self.version) + info_dir = '%s.dist-info' % name_ver + metadata_filename = posixpath.join(info_dir, 'WHEEL') + with zf.open(metadata_filename) as bf: + wf = codecs.getreader('utf-8')(bf) + message = message_from_file(wf) + return dict(message) + + @cached_property + def info(self): + pathname = os.path.join(self.dirname, self.filename) + with ZipFile(pathname, 'r') as zf: + result = self.get_wheel_metadata(zf) + return result + + def process_shebang(self, data): + m = SHEBANG_RE.match(data) + if m: + end = m.end() + shebang, data_after_shebang = data[:end], data[end:] + # Preserve any arguments after the interpreter + if b'pythonw' in shebang.lower(): + shebang_python = SHEBANG_PYTHONW + else: + shebang_python = SHEBANG_PYTHON + m = SHEBANG_DETAIL_RE.match(shebang) + if m: + args = b' ' + m.groups()[-1] + else: + args = b'' + shebang = shebang_python + args + data = shebang + data_after_shebang + else: + cr = data.find(b'\r') + lf = data.find(b'\n') + if cr < 0 or cr > lf: + term = b'\n' + else: + if data[cr:cr + 2] == b'\r\n': + term = b'\r\n' + else: + term = b'\r' + data = SHEBANG_PYTHON + term + data + return data + + def get_hash(self, data, hash_kind=None): + if hash_kind is None: + hash_kind = self.hash_kind + try: + hasher = getattr(hashlib, hash_kind) + except AttributeError: + raise DistlibException('Unsupported hash algorithm: %r' % hash_kind) + result = hasher(data).digest() + result = base64.urlsafe_b64encode(result).rstrip(b'=').decode('ascii') + return hash_kind, result + + def write_record(self, records, record_path, base): + records = list(records) # make a copy for sorting + 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) + + def write_records(self, info, libdir, archive_paths): + records = [] + distinfo, info_dir = info + hasher = getattr(hashlib, self.hash_kind) + for ap, p in archive_paths: + with open(p, 'rb') as f: + data = f.read() + digest = '%s=%s' % self.get_hash(data) + size = os.path.getsize(p) + records.append((ap, digest, size)) + + p = os.path.join(distinfo, 'RECORD') + self.write_record(records, p, libdir) + ap = to_posix(os.path.join(info_dir, 'RECORD')) + archive_paths.append((ap, p)) + + def build_zip(self, pathname, archive_paths): + with ZipFile(pathname, 'w', zipfile.ZIP_DEFLATED) as zf: + for ap, p in archive_paths: + logger.debug('Wrote %s to %s in wheel', p, ap) + zf.write(p, ap) + + def build(self, paths, tags=None, wheel_version=None): + """ + Build a wheel from files in specified paths, and use any specified tags + when determining the name of the wheel. + """ + if tags is None: + tags = {} + + libkey = list(filter(lambda o: o in paths, ('purelib', 'platlib')))[0] + if libkey == 'platlib': + is_pure = 'false' + default_pyver = [IMPVER] + default_abi = [ABI] + default_arch = [ARCH] + else: + is_pure = 'true' + default_pyver = [PYVER] + default_abi = ['none'] + default_arch = ['any'] + + self.pyver = tags.get('pyver', default_pyver) + self.abi = tags.get('abi', default_abi) + self.arch = tags.get('arch', default_arch) + + libdir = paths[libkey] + + name_ver = '%s-%s' % (self.name, self.version) + data_dir = '%s.data' % name_ver + info_dir = '%s.dist-info' % name_ver + + archive_paths = [] + + # First, stuff which is not in site-packages + for key in ('data', 'headers', 'scripts'): + if key not in paths: + continue + path = paths[key] + if os.path.isdir(path): + for root, dirs, files in os.walk(path): + for fn in files: + p = fsdecode(os.path.join(root, fn)) + rp = os.path.relpath(p, path) + ap = to_posix(os.path.join(data_dir, key, rp)) + archive_paths.append((ap, p)) + if key == 'scripts' and not p.endswith('.exe'): + with open(p, 'rb') as f: + data = f.read() + data = self.process_shebang(data) + with open(p, 'wb') as f: + f.write(data) + + # Now, stuff which is in site-packages, other than the + # distinfo stuff. + path = libdir + distinfo = None + for root, dirs, files in os.walk(path): + if root == path: + # At the top level only, save distinfo for later + # and skip it for now + for i, dn in enumerate(dirs): + dn = fsdecode(dn) + if dn.endswith('.dist-info'): + distinfo = os.path.join(root, dn) + del dirs[i] + break + assert distinfo, '.dist-info directory expected, not found' + + for fn in files: + # comment out next suite to leave .pyc files in + if fsdecode(fn).endswith(('.pyc', '.pyo')): + continue + p = os.path.join(root, fn) + rp = to_posix(os.path.relpath(p, path)) + archive_paths.append((rp, p)) + + # Now distinfo. Assumed to be flat, i.e. os.listdir is enough. + files = os.listdir(distinfo) + for fn in files: + if fn not in ('RECORD', 'INSTALLER', 'SHARED', 'WHEEL'): + p = fsdecode(os.path.join(distinfo, fn)) + ap = to_posix(os.path.join(info_dir, fn)) + archive_paths.append((ap, p)) + + wheel_metadata = [ + 'Wheel-Version: %d.%d' % (wheel_version or self.wheel_version), + 'Generator: distlib %s' % __version__, + 'Root-Is-Purelib: %s' % is_pure, + ] + for pyver, abi, arch in self.tags: + wheel_metadata.append('Tag: %s-%s-%s' % (pyver, abi, arch)) + p = os.path.join(distinfo, 'WHEEL') + with open(p, 'w') as f: + f.write('\n'.join(wheel_metadata)) + ap = to_posix(os.path.join(info_dir, 'WHEEL')) + archive_paths.append((ap, p)) + + # Now, at last, RECORD. + # Paths in here are archive paths - nothing else makes sense. + self.write_records((distinfo, info_dir), libdir, archive_paths) + # Now, ready to build the zip file + pathname = os.path.join(self.dirname, self.filename) + self.build_zip(pathname, archive_paths) + return pathname + + def install(self, paths, maker, **kwargs): + """ + Install a wheel to the specified paths. If kwarg ``warner`` is + specified, it should be a callable, which will be called with two + tuples indicating the wheel version of this software and the wheel + version in the file, if there is a discrepancy in the versions. + This can be used to issue any warnings to raise any exceptions. + If kwarg ``lib_only`` is True, only the purelib/platlib files are + installed, and the headers, scripts, data and dist-info metadata are + not written. + + The return value is a :class:`InstalledDistribution` instance unless + ``options.lib_only`` is True, in which case the return value is ``None``. + """ + + dry_run = maker.dry_run + warner = kwargs.get('warner') + lib_only = kwargs.get('lib_only', False) + + pathname = os.path.join(self.dirname, self.filename) + name_ver = '%s-%s' % (self.name, self.version) + data_dir = '%s.data' % name_ver + info_dir = '%s.dist-info' % name_ver + + metadata_name = posixpath.join(info_dir, METADATA_FILENAME) + wheel_metadata_name = posixpath.join(info_dir, 'WHEEL') + record_name = posixpath.join(info_dir, 'RECORD') + + wrapper = codecs.getreader('utf-8') + + with ZipFile(pathname, 'r') as zf: + with zf.open(wheel_metadata_name) as bwf: + wf = wrapper(bwf) + message = message_from_file(wf) + wv = message['Wheel-Version'].split('.', 1) + file_version = tuple([int(i) for i in wv]) + if (file_version != self.wheel_version) and warner: + warner(self.wheel_version, file_version) + + if message['Root-Is-Purelib'] == 'true': + libdir = paths['purelib'] + else: + libdir = paths['platlib'] + + records = {} + with zf.open(record_name) as bf: + with CSVReader(stream=bf) as reader: + for row in reader: + p = row[0] + records[p] = row + + data_pfx = posixpath.join(data_dir, '') + info_pfx = posixpath.join(info_dir, '') + script_pfx = posixpath.join(data_dir, 'scripts', '') + + # make a new instance rather than a copy of maker's, + # as we mutate it + fileop = FileOperator(dry_run=dry_run) + fileop.record = True # so we can rollback if needed + + bc = not sys.dont_write_bytecode # Double negatives. Lovely! + + outfiles = [] # for RECORD writing + + # for script copying/shebang processing + workdir = tempfile.mkdtemp() + # set target dir later + # we default add_launchers to False, as the + # Python Launcher should be used instead + maker.source_dir = workdir + maker.target_dir = None + try: + for zinfo in zf.infolist(): + arcname = zinfo.filename + if isinstance(arcname, text_type): + u_arcname = arcname + else: + u_arcname = arcname.decode('utf-8') + # The signature file won't be in RECORD, + # and we don't currently don't do anything with it + if u_arcname.endswith('/RECORD.jws'): + continue + row = records[u_arcname] + if row[2] and str(zinfo.file_size) != row[2]: + raise DistlibException('size mismatch for ' + '%s' % u_arcname) + if row[1]: + kind, value = row[1].split('=', 1) + with zf.open(arcname) as bf: + data = bf.read() + _, digest = self.get_hash(data, kind) + if digest != value: + raise DistlibException('digest mismatch for ' + '%s' % arcname) + + if lib_only and u_arcname.startswith((info_pfx, data_pfx)): + logger.debug('lib_only: skipping %s', u_arcname) + continue + is_script = (u_arcname.startswith(script_pfx) + and not u_arcname.endswith('.exe')) + + if u_arcname.startswith(data_pfx): + _, where, rp = u_arcname.split('/', 2) + outfile = os.path.join(paths[where], convert_path(rp)) + else: + # meant for site-packages. + if u_arcname in (wheel_metadata_name, record_name): + continue + outfile = os.path.join(libdir, convert_path(u_arcname)) + if not is_script: + with zf.open(arcname) as bf: + fileop.copy_stream(bf, outfile) + outfiles.append(outfile) + # Double check the digest of the written file + if not dry_run and row[1]: + with open(outfile, 'rb') as bf: + data = bf.read() + _, newdigest = self.get_hash(data, kind) + if newdigest != digest: + raise DistlibException('digest mismatch ' + 'on write for ' + '%s' % outfile) + if bc and outfile.endswith('.py'): + try: + pyc = fileop.byte_compile(outfile) + outfiles.append(pyc) + except Exception: + # Don't give up if byte-compilation fails, + # but log it and perhaps warn the user + logger.warning('Byte-compilation failed', + exc_info=True) + else: + fn = os.path.basename(convert_path(arcname)) + workname = os.path.join(workdir, fn) + with zf.open(arcname) as bf: + fileop.copy_stream(bf, workname) + + dn, fn = os.path.split(outfile) + maker.target_dir = dn + filenames = maker.make(fn) + fileop.set_executable_mode(filenames) + outfiles.extend(filenames) + + if lib_only: + logger.debug('lib_only: returning None') + dist = None + else: + # Generate scripts + + # Try to get pydist.json so we can see if there are + # any commands to generate. If this fails (e.g. because + # of a legacy wheel), log a warning but don't give up. + commands = None + file_version = self.info['Wheel-Version'] + if file_version == '1.0': + # Use legacy info + ep = posixpath.join(info_dir, 'entry_points.txt') + try: + with zf.open(ep) as bwf: + epdata = read_exports(bwf) + commands = {} + for key in ('console', 'gui'): + k = '%s_scripts' % key + if k in epdata: + commands['wrap_%s' % key] = d = {} + for v in epdata[k].values(): + s = '%s:%s' % (v.prefix, v.suffix) + if v.flags: + s += ' %s' % v.flags + d[v.name] = s + except Exception: + logger.warning('Unable to read legacy script ' + 'metadata, so cannot generate ' + 'scripts') + else: + try: + with zf.open(metadata_name) as bwf: + wf = wrapper(bwf) + commands = json.load(wf).get('extensions') + if commands: + commands = commands.get('python.commands') + except Exception: + logger.warning('Unable to read JSON metadata, so ' + 'cannot generate scripts') + if commands: + console_scripts = commands.get('wrap_console', {}) + gui_scripts = commands.get('wrap_gui', {}) + if console_scripts or gui_scripts: + script_dir = paths.get('scripts', '') + if not os.path.isdir(script_dir): + raise ValueError('Valid script path not ' + 'specified') + maker.target_dir = script_dir + for k, v in console_scripts.items(): + script = '%s = %s' % (k, v) + filenames = maker.make(script) + fileop.set_executable_mode(filenames) + + if gui_scripts: + options = {'gui': True } + for k, v in gui_scripts.items(): + script = '%s = %s' % (k, v) + filenames = maker.make(script, options) + fileop.set_executable_mode(filenames) + + p = os.path.join(libdir, info_dir) + dist = InstalledDistribution(p) + + # Write SHARED + paths = dict(paths) # don't change passed in dict + del paths['purelib'] + del paths['platlib'] + paths['lib'] = libdir + p = dist.write_shared_locations(paths, dry_run) + if p: + outfiles.append(p) + + # Write RECORD + dist.write_installed_files(outfiles, paths['prefix'], + dry_run) + return dist + except Exception: # pragma: no cover + logger.exception('installation failed.') + fileop.rollback() + raise + finally: + shutil.rmtree(workdir) + + def _get_dylib_cache(self): + global cache + 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]) + cache = Cache(base) + return cache + + def _get_extensions(self): + pathname = os.path.join(self.dirname, self.filename) + name_ver = '%s-%s' % (self.name, self.version) + info_dir = '%s.dist-info' % name_ver + arcname = posixpath.join(info_dir, 'EXTENSIONS') + wrapper = codecs.getreader('utf-8') + result = [] + with ZipFile(pathname, 'r') as zf: + try: + with zf.open(arcname) as bf: + wf = wrapper(bf) + extensions = json.load(wf) + cache = self._get_dylib_cache() + prefix = cache.prefix_to_dir(pathname) + cache_base = os.path.join(cache.base, prefix) + if not os.path.isdir(cache_base): + os.makedirs(cache_base) + for name, relpath in extensions.items(): + dest = os.path.join(cache_base, convert_path(relpath)) + if not os.path.exists(dest): + extract = True + else: + file_time = os.stat(dest).st_mtime + file_time = datetime.datetime.fromtimestamp(file_time) + info = zf.getinfo(relpath) + wheel_time = datetime.datetime(*info.date_time) + extract = wheel_time > file_time + if extract: + zf.extract(relpath, cache_base) + result.append((name, dest)) + except KeyError: + pass + return result + + def is_compatible(self): + """ + Determine if a wheel is compatible with the running system. + """ + return is_compatible(self) + + def is_mountable(self): + """ + Determine if a wheel is asserted as mountable by its metadata. + """ + return True # for now - metadata details TBD + + def mount(self, append=False): + pathname = os.path.abspath(os.path.join(self.dirname, self.filename)) + if not self.is_compatible(): + msg = 'Wheel %s not compatible with this Python.' % pathname + raise DistlibException(msg) + if not self.is_mountable(): + msg = 'Wheel %s is marked as not mountable.' % pathname + raise DistlibException(msg) + if pathname in sys.path: + logger.debug('%s already in path', pathname) + else: + if append: + sys.path.append(pathname) + else: + sys.path.insert(0, pathname) + extensions = self._get_extensions() + if extensions: + if _hook not in sys.meta_path: + sys.meta_path.append(_hook) + _hook.add(pathname, extensions) + + def unmount(self): + pathname = os.path.abspath(os.path.join(self.dirname, self.filename)) + if pathname not in sys.path: + logger.debug('%s not in path', pathname) + else: + sys.path.remove(pathname) + if pathname in _hook.impure_wheels: + _hook.remove(pathname) + if not _hook.impure_wheels: + if _hook in sys.meta_path: + sys.meta_path.remove(_hook) + + def verify(self): + pathname = os.path.join(self.dirname, self.filename) + name_ver = '%s-%s' % (self.name, self.version) + data_dir = '%s.data' % name_ver + info_dir = '%s.dist-info' % name_ver + + metadata_name = posixpath.join(info_dir, METADATA_FILENAME) + wheel_metadata_name = posixpath.join(info_dir, 'WHEEL') + record_name = posixpath.join(info_dir, 'RECORD') + + wrapper = codecs.getreader('utf-8') + + with ZipFile(pathname, 'r') as zf: + with zf.open(wheel_metadata_name) as bwf: + wf = wrapper(bwf) + message = message_from_file(wf) + wv = message['Wheel-Version'].split('.', 1) + file_version = tuple([int(i) for i in wv]) + # TODO version verification + + records = {} + with zf.open(record_name) as bf: + with CSVReader(stream=bf) as reader: + for row in reader: + p = row[0] + records[p] = row + + for zinfo in zf.infolist(): + arcname = zinfo.filename + if isinstance(arcname, text_type): + u_arcname = arcname + else: + u_arcname = arcname.decode('utf-8') + if '..' in u_arcname: + raise DistlibException('invalid entry in ' + 'wheel: %r' % u_arcname) + + # The signature file won't be in RECORD, + # and we don't currently don't do anything with it + if u_arcname.endswith('/RECORD.jws'): + continue + row = records[u_arcname] + if row[2] and str(zinfo.file_size) != row[2]: + raise DistlibException('size mismatch for ' + '%s' % u_arcname) + if row[1]: + kind, value = row[1].split('=', 1) + with zf.open(arcname) as bf: + data = bf.read() + _, digest = self.get_hash(data, kind) + if digest != value: + raise DistlibException('digest mismatch for ' + '%s' % arcname) + + def update(self, modifier, dest_dir=None, **kwargs): + """ + Update the contents of a wheel in a generic way. The modifier should + be a callable which expects a dictionary argument: its keys are + archive-entry paths, and its values are absolute filesystem paths + where the contents the corresponding archive entries can be found. The + modifier is free to change the contents of the files pointed to, add + new entries and remove entries, before returning. This method will + extract the entire contents of the wheel to a temporary location, call + the modifier, and then use the passed (and possibly updated) + dictionary to write a new wheel. If ``dest_dir`` is specified, the new + wheel is written there -- otherwise, the original wheel is overwritten. + + The modifier should return True if it updated the wheel, else False. + This method returns the same value the modifier returns. + """ + + def get_version(path_map, info_dir): + version = path = None + key = '%s/%s' % (info_dir, METADATA_FILENAME) + if key not in path_map: + key = '%s/PKG-INFO' % info_dir + if key in path_map: + path = path_map[key] + version = Metadata(path=path).version + return version, path + + def update_version(version, path): + updated = None + try: + v = NormalizedVersion(version) + i = version.find('-') + if i < 0: + updated = '%s+1' % version + else: + parts = [int(s) for s in version[i + 1:].split('.')] + parts[-1] += 1 + updated = '%s+%s' % (version[:i], + '.'.join(str(i) for i in parts)) + except UnsupportedVersionError: + logger.debug('Cannot update non-compliant (PEP-440) ' + 'version %r', version) + if updated: + md = Metadata(path=path) + md.version = updated + legacy = not path.endswith(METADATA_FILENAME) + md.write(path=path, legacy=legacy) + logger.debug('Version updated from %r to %r', version, + updated) + + pathname = os.path.join(self.dirname, self.filename) + name_ver = '%s-%s' % (self.name, self.version) + info_dir = '%s.dist-info' % name_ver + record_name = posixpath.join(info_dir, 'RECORD') + with tempdir() as workdir: + with ZipFile(pathname, 'r') as zf: + path_map = {} + for zinfo in zf.infolist(): + arcname = zinfo.filename + if isinstance(arcname, text_type): + u_arcname = arcname + else: + u_arcname = arcname.decode('utf-8') + if u_arcname == record_name: + continue + if '..' in u_arcname: + raise DistlibException('invalid entry in ' + 'wheel: %r' % u_arcname) + zf.extract(zinfo, workdir) + path = os.path.join(workdir, convert_path(u_arcname)) + path_map[u_arcname] = path + + # Remember the version. + original_version, _ = get_version(path_map, info_dir) + # Files extracted. Call the modifier. + modified = modifier(path_map, **kwargs) + if modified: + # Something changed - need to build a new wheel. + current_version, path = get_version(path_map, info_dir) + if current_version and (current_version == original_version): + # Add or update local version to signify changes. + update_version(current_version, path) + # Decide where the new wheel goes. + if dest_dir is None: + fd, newpath = tempfile.mkstemp(suffix='.whl', + prefix='wheel-update-', + dir=workdir) + os.close(fd) + else: + if not os.path.isdir(dest_dir): + raise DistlibException('Not a directory: %r' % dest_dir) + newpath = os.path.join(dest_dir, self.filename) + archive_paths = list(path_map.items()) + distinfo = os.path.join(workdir, info_dir) + info = distinfo, info_dir + self.write_records(info, workdir, archive_paths) + self.build_zip(newpath, archive_paths) + if dest_dir is None: + shutil.copyfile(newpath, pathname) + return modified + +def compatible_tags(): + """ + Return (pyver, abi, arch) tuples compatible with this Python. + """ + versions = [VER_SUFFIX] + major = VER_SUFFIX[0] + for minor in range(sys.version_info[1] - 1, - 1, -1): + versions.append(''.join([major, str(minor)])) + + abis = [] + for suffix, _, _ in imp.get_suffixes(): + if suffix.startswith('.abi'): + abis.append(suffix.split('.', 2)[1]) + abis.sort() + if ABI != 'none': + abis.insert(0, ABI) + abis.append('none') + result = [] + + arches = [ARCH] + if sys.platform == 'darwin': + m = re.match(r'(\w+)_(\d+)_(\d+)_(\w+)$', ARCH) + if m: + name, major, minor, arch = m.groups() + minor = int(minor) + matches = [arch] + if arch in ('i386', 'ppc'): + matches.append('fat') + if arch in ('i386', 'ppc', 'x86_64'): + matches.append('fat3') + if arch in ('ppc64', 'x86_64'): + matches.append('fat64') + if arch in ('i386', 'x86_64'): + matches.append('intel') + if arch in ('i386', 'x86_64', 'intel', 'ppc', 'ppc64'): + matches.append('universal') + while minor >= 0: + for match in matches: + s = '%s_%s_%s_%s' % (name, major, minor, match) + if s != ARCH: # already there + arches.append(s) + minor -= 1 + + # Most specific - our Python version, ABI and arch + for abi in abis: + for arch in arches: + result.append((''.join((IMP_PREFIX, versions[0])), abi, arch)) + + # where no ABI / arch dependency, but IMP_PREFIX dependency + for i, version in enumerate(versions): + result.append((''.join((IMP_PREFIX, version)), 'none', 'any')) + if i == 0: + result.append((''.join((IMP_PREFIX, version[0])), 'none', 'any')) + + # no IMP_PREFIX, ABI or arch dependency + for i, version in enumerate(versions): + result.append((''.join(('py', version)), 'none', 'any')) + if i == 0: + result.append((''.join(('py', version[0])), 'none', 'any')) + return set(result) + + +COMPATIBLE_TAGS = compatible_tags() + +del compatible_tags + + +def is_compatible(wheel, tags=None): + if not isinstance(wheel, Wheel): + wheel = Wheel(wheel) # assume it's a filename + result = False + if tags is None: + tags = COMPATIBLE_TAGS + for ver, abi, arch in tags: + if ver in wheel.pyver and abi in wheel.abi and arch in wheel.arch: + result = True + break + return result diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/distro.py b/venv/lib/python3.7/site-packages/pip/_vendor/distro.py new file mode 100644 index 0000000..aa4defc --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/distro.py @@ -0,0 +1,1197 @@ +# Copyright 2015,2016,2017 Nir Cohen +# +# 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. + +""" +The ``distro`` package (``distro`` stands for Linux Distribution) provides +information about the Linux distribution it runs on, such as a reliable +machine-readable distro ID, or version information. + +It is a renewed alternative implementation for Python's original +:py:func:`platform.linux_distribution` function, but it provides much more +functionality. An alternative implementation became necessary because Python +3.5 deprecated this function, and Python 3.7 is expected to remove it +altogether. Its predecessor function :py:func:`platform.dist` was already +deprecated since Python 2.6 and is also expected to be removed in Python 3.7. +Still, there are many cases in which access to OS distribution information +is needed. See `Python issue 1322 <https://bugs.python.org/issue1322>`_ for +more information. +""" + +import os +import re +import sys +import json +import shlex +import logging +import argparse +import subprocess + + +_UNIXCONFDIR = os.environ.get('UNIXCONFDIR', '/etc') +_OS_RELEASE_BASENAME = 'os-release' + +#: Translation table for normalizing the "ID" attribute defined in os-release +#: files, for use by the :func:`distro.id` method. +#: +#: * Key: Value as defined in the os-release file, translated to lower case, +#: with blanks translated to underscores. +#: +#: * Value: Normalized value. +NORMALIZED_OS_ID = {} + +#: Translation table for normalizing the "Distributor ID" attribute returned by +#: the lsb_release command, for use by the :func:`distro.id` method. +#: +#: * Key: Value as returned by the lsb_release command, translated to lower +#: case, with blanks translated to underscores. +#: +#: * Value: Normalized value. +NORMALIZED_LSB_ID = { + 'enterpriseenterprise': 'oracle', # Oracle Enterprise Linux + 'redhatenterpriseworkstation': 'rhel', # RHEL 6, 7 Workstation + 'redhatenterpriseserver': 'rhel', # RHEL 6, 7 Server +} + +#: Translation table for normalizing the distro ID derived from the file name +#: of distro release files, for use by the :func:`distro.id` method. +#: +#: * Key: Value as derived from the file name of a distro release file, +#: translated to lower case, with blanks translated to underscores. +#: +#: * Value: Normalized value. +NORMALIZED_DISTRO_ID = { + 'redhat': 'rhel', # RHEL 6.x, 7.x +} + +# Pattern for content of distro release file (reversed) +_DISTRO_RELEASE_CONTENT_REVERSED_PATTERN = re.compile( + r'(?:[^)]*\)(.*)\()? *(?:STL )?([\d.+\-a-z]*\d) *(?:esaeler *)?(.+)') + +# Pattern for base file name of distro release file +_DISTRO_RELEASE_BASENAME_PATTERN = re.compile( + r'(\w+)[-_](release|version)$') + +# Base file names to be ignored when searching for distro release file +_DISTRO_RELEASE_IGNORE_BASENAMES = ( + 'debian_version', + 'lsb-release', + 'oem-release', + _OS_RELEASE_BASENAME, + 'system-release' +) + + +def linux_distribution(full_distribution_name=True): + """ + Return information about the current OS distribution as a tuple + ``(id_name, version, codename)`` with items as follows: + + * ``id_name``: If *full_distribution_name* is false, the result of + :func:`distro.id`. Otherwise, the result of :func:`distro.name`. + + * ``version``: The result of :func:`distro.version`. + + * ``codename``: The result of :func:`distro.codename`. + + The interface of this function is compatible with the original + :py:func:`platform.linux_distribution` function, supporting a subset of + its parameters. + + The data it returns may not exactly be the same, because it uses more data + sources than the original function, and that may lead to different data if + the OS distribution is not consistent across multiple data sources it + provides (there are indeed such distributions ...). + + Another reason for differences is the fact that the :func:`distro.id` + method normalizes the distro ID string to a reliable machine-readable value + for a number of popular OS distributions. + """ + return _distro.linux_distribution(full_distribution_name) + + +def id(): + """ + Return the distro ID of the current distribution, as a + machine-readable string. + + For a number of OS distributions, the returned distro ID value is + *reliable*, in the sense that it is documented and that it does not change + across releases of the distribution. + + This package maintains the following reliable distro ID values: + + ============== ========================================= + Distro ID Distribution + ============== ========================================= + "ubuntu" Ubuntu + "debian" Debian + "rhel" RedHat Enterprise Linux + "centos" CentOS + "fedora" Fedora + "sles" SUSE Linux Enterprise Server + "opensuse" openSUSE + "amazon" Amazon Linux + "arch" Arch Linux + "cloudlinux" CloudLinux OS + "exherbo" Exherbo Linux + "gentoo" GenToo Linux + "ibm_powerkvm" IBM PowerKVM + "kvmibm" KVM for IBM z Systems + "linuxmint" Linux Mint + "mageia" Mageia + "mandriva" Mandriva Linux + "parallels" Parallels + "pidora" Pidora + "raspbian" Raspbian + "oracle" Oracle Linux (and Oracle Enterprise Linux) + "scientific" Scientific Linux + "slackware" Slackware + "xenserver" XenServer + "openbsd" OpenBSD + "netbsd" NetBSD + "freebsd" FreeBSD + ============== ========================================= + + If you have a need to get distros for reliable IDs added into this set, + or if you find that the :func:`distro.id` function returns a different + distro ID for one of the listed distros, please create an issue in the + `distro issue tracker`_. + + **Lookup hierarchy and transformations:** + + First, the ID is obtained from the following sources, in the specified + order. The first available and non-empty value is used: + + * the value of the "ID" attribute of the os-release file, + + * the value of the "Distributor ID" attribute returned by the lsb_release + command, + + * the first part of the file name of the distro release file, + + The so determined ID value then passes the following transformations, + before it is returned by this method: + + * it is translated to lower case, + + * blanks (which should not be there anyway) are translated to underscores, + + * a normalization of the ID is performed, based upon + `normalization tables`_. The purpose of this normalization is to ensure + that the ID is as reliable as possible, even across incompatible changes + in the OS distributions. A common reason for an incompatible change is + the addition of an os-release file, or the addition of the lsb_release + command, with ID values that differ from what was previously determined + from the distro release file name. + """ + return _distro.id() + + +def name(pretty=False): + """ + Return the name of the current OS distribution, as a human-readable + string. + + If *pretty* is false, the name is returned without version or codename. + (e.g. "CentOS Linux") + + If *pretty* is true, the version and codename are appended. + (e.g. "CentOS Linux 7.1.1503 (Core)") + + **Lookup hierarchy:** + + The name is obtained from the following sources, in the specified order. + The first available and non-empty value is used: + + * If *pretty* is false: + + - the value of the "NAME" attribute of the os-release file, + + - the value of the "Distributor ID" attribute returned by the lsb_release + command, + + - the value of the "<name>" field of the distro release file. + + * If *pretty* is true: + + - the value of the "PRETTY_NAME" attribute of the os-release file, + + - the value of the "Description" attribute returned by the lsb_release + command, + + - the value of the "<name>" field of the distro release file, appended + with the value of the pretty version ("<version_id>" and "<codename>" + fields) of the distro release file, if available. + """ + return _distro.name(pretty) + + +def version(pretty=False, best=False): + """ + Return the version of the current OS distribution, as a human-readable + string. + + If *pretty* is false, the version is returned without codename (e.g. + "7.0"). + + If *pretty* is true, the codename in parenthesis is appended, if the + codename is non-empty (e.g. "7.0 (Maipo)"). + + Some distributions provide version numbers with different precisions in + the different sources of distribution information. Examining the different + sources in a fixed priority order does not always yield the most precise + version (e.g. for Debian 8.2, or CentOS 7.1). + + The *best* parameter can be used to control the approach for the returned + version: + + If *best* is false, the first non-empty version number in priority order of + the examined sources is returned. + + If *best* is true, the most precise version number out of all examined + sources is returned. + + **Lookup hierarchy:** + + In all cases, the version number is obtained from the following sources. + If *best* is false, this order represents the priority order: + + * the value of the "VERSION_ID" attribute of the os-release file, + * the value of the "Release" attribute returned by the lsb_release + command, + * the version number parsed from the "<version_id>" field of the first line + of the distro release file, + * the version number parsed from the "PRETTY_NAME" attribute of the + os-release file, if it follows the format of the distro release files. + * the version number parsed from the "Description" attribute returned by + the lsb_release command, if it follows the format of the distro release + files. + """ + return _distro.version(pretty, best) + + +def version_parts(best=False): + """ + Return the version of the current OS distribution as a tuple + ``(major, minor, build_number)`` with items as follows: + + * ``major``: The result of :func:`distro.major_version`. + + * ``minor``: The result of :func:`distro.minor_version`. + + * ``build_number``: The result of :func:`distro.build_number`. + + For a description of the *best* parameter, see the :func:`distro.version` + method. + """ + return _distro.version_parts(best) + + +def major_version(best=False): + """ + Return the major version of the current OS distribution, as a string, + if provided. + Otherwise, the empty string is returned. The major version is the first + part of the dot-separated version string. + + For a description of the *best* parameter, see the :func:`distro.version` + method. + """ + return _distro.major_version(best) + + +def minor_version(best=False): + """ + Return the minor version of the current OS distribution, as a string, + if provided. + Otherwise, the empty string is returned. The minor version is the second + part of the dot-separated version string. + + For a description of the *best* parameter, see the :func:`distro.version` + method. + """ + return _distro.minor_version(best) + + +def build_number(best=False): + """ + Return the build number of the current OS distribution, as a string, + if provided. + Otherwise, the empty string is returned. The build number is the third part + of the dot-separated version string. + + For a description of the *best* parameter, see the :func:`distro.version` + method. + """ + return _distro.build_number(best) + + +def like(): + """ + Return a space-separated list of distro IDs of distributions that are + closely related to the current OS distribution in regards to packaging + and programming interfaces, for example distributions the current + distribution is a derivative from. + + **Lookup hierarchy:** + + This information item is only provided by the os-release file. + For details, see the description of the "ID_LIKE" attribute in the + `os-release man page + <http://www.freedesktop.org/software/systemd/man/os-release.html>`_. + """ + return _distro.like() + + +def codename(): + """ + Return the codename for the release of the current OS distribution, + as a string. + + If the distribution does not have a codename, an empty string is returned. + + Note that the returned codename is not always really a codename. For + example, openSUSE returns "x86_64". This function does not handle such + cases in any special way and just returns the string it finds, if any. + + **Lookup hierarchy:** + + * the codename within the "VERSION" attribute of the os-release file, if + provided, + + * the value of the "Codename" attribute returned by the lsb_release + command, + + * the value of the "<codename>" field of the distro release file. + """ + return _distro.codename() + + +def info(pretty=False, best=False): + """ + Return certain machine-readable information items about the current OS + distribution in a dictionary, as shown in the following example: + + .. sourcecode:: python + + { + 'id': 'rhel', + 'version': '7.0', + 'version_parts': { + 'major': '7', + 'minor': '0', + 'build_number': '' + }, + 'like': 'fedora', + 'codename': 'Maipo' + } + + The dictionary structure and keys are always the same, regardless of which + information items are available in the underlying data sources. The values + for the various keys are as follows: + + * ``id``: The result of :func:`distro.id`. + + * ``version``: The result of :func:`distro.version`. + + * ``version_parts -> major``: The result of :func:`distro.major_version`. + + * ``version_parts -> minor``: The result of :func:`distro.minor_version`. + + * ``version_parts -> build_number``: The result of + :func:`distro.build_number`. + + * ``like``: The result of :func:`distro.like`. + + * ``codename``: The result of :func:`distro.codename`. + + For a description of the *pretty* and *best* parameters, see the + :func:`distro.version` method. + """ + return _distro.info(pretty, best) + + +def os_release_info(): + """ + Return a dictionary containing key-value pairs for the information items + from the os-release file data source of the current OS distribution. + + See `os-release file`_ for details about these information items. + """ + return _distro.os_release_info() + + +def lsb_release_info(): + """ + Return a dictionary containing key-value pairs for the information items + from the lsb_release command data source of the current OS distribution. + + See `lsb_release command output`_ for details about these information + items. + """ + return _distro.lsb_release_info() + + +def distro_release_info(): + """ + Return a dictionary containing key-value pairs for the information items + from the distro release file data source of the current OS distribution. + + See `distro release file`_ for details about these information items. + """ + return _distro.distro_release_info() + + +def uname_info(): + """ + Return a dictionary containing key-value pairs for the information items + from the distro release file data source of the current OS distribution. + """ + return _distro.uname_info() + + +def os_release_attr(attribute): + """ + Return a single named information item from the os-release file data source + of the current OS distribution. + + Parameters: + + * ``attribute`` (string): Key of the information item. + + Returns: + + * (string): Value of the information item, if the item exists. + The empty string, if the item does not exist. + + See `os-release file`_ for details about these information items. + """ + return _distro.os_release_attr(attribute) + + +def lsb_release_attr(attribute): + """ + Return a single named information item from the lsb_release command output + data source of the current OS distribution. + + Parameters: + + * ``attribute`` (string): Key of the information item. + + Returns: + + * (string): Value of the information item, if the item exists. + The empty string, if the item does not exist. + + See `lsb_release command output`_ for details about these information + items. + """ + return _distro.lsb_release_attr(attribute) + + +def distro_release_attr(attribute): + """ + Return a single named information item from the distro release file + data source of the current OS distribution. + + Parameters: + + * ``attribute`` (string): Key of the information item. + + Returns: + + * (string): Value of the information item, if the item exists. + The empty string, if the item does not exist. + + See `distro release file`_ for details about these information items. + """ + return _distro.distro_release_attr(attribute) + + +def uname_attr(attribute): + """ + Return a single named information item from the distro release file + data source of the current OS distribution. + + Parameters: + + * ``attribute`` (string): Key of the information item. + + Returns: + + * (string): Value of the information item, if the item exists. + The empty string, if the item does not exist. + """ + return _distro.uname_attr(attribute) + + +class cached_property(object): + """A version of @property which caches the value. On access, it calls the + underlying function and sets the value in `__dict__` so future accesses + will not re-call the property. + """ + def __init__(self, f): + self._fname = f.__name__ + self._f = f + + def __get__(self, obj, owner): + assert obj is not None, 'call {} on an instance'.format(self._fname) + ret = obj.__dict__[self._fname] = self._f(obj) + return ret + + +class LinuxDistribution(object): + """ + Provides information about a OS distribution. + + This package creates a private module-global instance of this class with + default initialization arguments, that is used by the + `consolidated accessor functions`_ and `single source accessor functions`_. + By using default initialization arguments, that module-global instance + returns data about the current OS distribution (i.e. the distro this + package runs on). + + Normally, it is not necessary to create additional instances of this class. + However, in situations where control is needed over the exact data sources + that are used, instances of this class can be created with a specific + distro release file, or a specific os-release file, or without invoking the + lsb_release command. + """ + + def __init__(self, + include_lsb=True, + os_release_file='', + distro_release_file='', + include_uname=True): + """ + The initialization method of this class gathers information from the + available data sources, and stores that in private instance attributes. + Subsequent access to the information items uses these private instance + attributes, so that the data sources are read only once. + + Parameters: + + * ``include_lsb`` (bool): Controls whether the + `lsb_release command output`_ is included as a data source. + + If the lsb_release command is not available in the program execution + path, the data source for the lsb_release command will be empty. + + * ``os_release_file`` (string): The path name of the + `os-release file`_ that is to be used as a data source. + + An empty string (the default) will cause the default path name to + be used (see `os-release file`_ for details). + + If the specified or defaulted os-release file does not exist, the + data source for the os-release file will be empty. + + * ``distro_release_file`` (string): The path name of the + `distro release file`_ that is to be used as a data source. + + An empty string (the default) will cause a default search algorithm + to be used (see `distro release file`_ for details). + + If the specified distro release file does not exist, or if no default + 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 + 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. + + Public instance attributes: + + * ``os_release_file`` (string): The path name of the + `os-release file`_ that is actually used as a data source. The + empty string if no distro release file is used as a data source. + + * ``distro_release_file`` (string): The path name of the + `distro release file`_ that is actually used as a data source. The + empty string if no distro release file is used as a data source. + + * ``include_lsb`` (bool): The result of the ``include_lsb`` parameter. + This controls whether the lsb information will be loaded. + + * ``include_uname`` (bool): The result of the ``include_uname`` + parameter. This controls whether the uname information will + be loaded. + + Raises: + + * :py:exc:`IOError`: Some I/O issue with an os-release file or distro + release file. + + * :py:exc:`subprocess.CalledProcessError`: The lsb_release command had + some issue (other than not being available in the program execution + path). + + * :py:exc:`UnicodeError`: A data source has unexpected characters or + uses an unexpected encoding. + """ + self.os_release_file = os_release_file or \ + os.path.join(_UNIXCONFDIR, _OS_RELEASE_BASENAME) + self.distro_release_file = distro_release_file or '' # updated later + self.include_lsb = include_lsb + self.include_uname = include_uname + + def __repr__(self): + """Return repr of all info + """ + return \ + "LinuxDistribution(" \ + "os_release_file={self.os_release_file!r}, " \ + "distro_release_file={self.distro_release_file!r}, " \ + "include_lsb={self.include_lsb!r}, " \ + "include_uname={self.include_uname!r}, " \ + "_os_release_info={self._os_release_info!r}, " \ + "_lsb_release_info={self._lsb_release_info!r}, " \ + "_distro_release_info={self._distro_release_info!r}, " \ + "_uname_info={self._uname_info!r})".format( + self=self) + + def linux_distribution(self, full_distribution_name=True): + """ + Return information about the OS distribution that is compatible + with Python's :func:`platform.linux_distribution`, supporting a subset + of its parameters. + + For details, see :func:`distro.linux_distribution`. + """ + return ( + self.name() if full_distribution_name else self.id(), + self.version(), + self.codename() + ) + + def id(self): + """Return the distro ID of the OS distribution, as a string. + + For details, see :func:`distro.id`. + """ + def normalize(distro_id, table): + distro_id = distro_id.lower().replace(' ', '_') + return table.get(distro_id, distro_id) + + distro_id = self.os_release_attr('id') + if distro_id: + return normalize(distro_id, NORMALIZED_OS_ID) + + distro_id = self.lsb_release_attr('distributor_id') + if distro_id: + return normalize(distro_id, NORMALIZED_LSB_ID) + + distro_id = self.distro_release_attr('id') + if distro_id: + return normalize(distro_id, NORMALIZED_DISTRO_ID) + + distro_id = self.uname_attr('id') + if distro_id: + return normalize(distro_id, NORMALIZED_DISTRO_ID) + + return '' + + def name(self, pretty=False): + """ + Return the name of the OS distribution, as a string. + + For details, see :func:`distro.name`. + """ + name = self.os_release_attr('name') \ + or self.lsb_release_attr('distributor_id') \ + or self.distro_release_attr('name') \ + or self.uname_attr('name') + if pretty: + name = self.os_release_attr('pretty_name') \ + or self.lsb_release_attr('description') + if not name: + name = self.distro_release_attr('name') \ + or self.uname_attr('name') + version = self.version(pretty=True) + if version: + name = name + ' ' + version + return name or '' + + def version(self, pretty=False, best=False): + """ + Return the version of the OS distribution, as a string. + + For details, see :func:`distro.version`. + """ + versions = [ + self.os_release_attr('version_id'), + self.lsb_release_attr('release'), + self.distro_release_attr('version_id'), + self._parse_distro_release_content( + self.os_release_attr('pretty_name')).get('version_id', ''), + self._parse_distro_release_content( + self.lsb_release_attr('description')).get('version_id', ''), + self.uname_attr('release') + ] + version = '' + if best: + # This algorithm uses the last version in priority order that has + # the best precision. If the versions are not in conflict, that + # does not matter; otherwise, using the last one instead of the + # first one might be considered a surprise. + for v in versions: + if v.count(".") > version.count(".") or version == '': + version = v + else: + for v in versions: + if v != '': + version = v + break + if pretty and version and self.codename(): + version = u'{0} ({1})'.format(version, self.codename()) + return version + + def version_parts(self, best=False): + """ + Return the version of the OS distribution, as a tuple of version + numbers. + + For details, see :func:`distro.version_parts`. + """ + version_str = self.version(best=best) + if version_str: + version_regex = re.compile(r'(\d+)\.?(\d+)?\.?(\d+)?') + matches = version_regex.match(version_str) + if matches: + major, minor, build_number = matches.groups() + return major, minor or '', build_number or '' + return '', '', '' + + def major_version(self, best=False): + """ + Return the major version number of the current distribution. + + For details, see :func:`distro.major_version`. + """ + return self.version_parts(best)[0] + + def minor_version(self, best=False): + """ + Return the minor version number of the current distribution. + + For details, see :func:`distro.minor_version`. + """ + return self.version_parts(best)[1] + + def build_number(self, best=False): + """ + Return the build number of the current distribution. + + For details, see :func:`distro.build_number`. + """ + return self.version_parts(best)[2] + + def like(self): + """ + Return the IDs of distributions that are like the OS distribution. + + For details, see :func:`distro.like`. + """ + return self.os_release_attr('id_like') or '' + + def codename(self): + """ + Return the codename of the OS distribution. + + For details, see :func:`distro.codename`. + """ + return self.os_release_attr('codename') \ + or self.lsb_release_attr('codename') \ + or self.distro_release_attr('codename') \ + or '' + + def info(self, pretty=False, best=False): + """ + Return certain machine-readable information about the OS + distribution. + + For details, see :func:`distro.info`. + """ + return dict( + id=self.id(), + version=self.version(pretty, best), + version_parts=dict( + major=self.major_version(best), + minor=self.minor_version(best), + build_number=self.build_number(best) + ), + like=self.like(), + codename=self.codename(), + ) + + def os_release_info(self): + """ + Return a dictionary containing key-value pairs for the information + items from the os-release file data source of the OS distribution. + + For details, see :func:`distro.os_release_info`. + """ + return self._os_release_info + + def lsb_release_info(self): + """ + Return a dictionary containing key-value pairs for the information + items from the lsb_release command data source of the OS + distribution. + + For details, see :func:`distro.lsb_release_info`. + """ + return self._lsb_release_info + + def distro_release_info(self): + """ + Return a dictionary containing key-value pairs for the information + items from the distro release file data source of the OS + distribution. + + For details, see :func:`distro.distro_release_info`. + """ + return self._distro_release_info + + def uname_info(self): + """ + Return a dictionary containing key-value pairs for the information + items from the uname command data source of the OS distribution. + + For details, see :func:`distro.uname_info`. + """ + + def os_release_attr(self, attribute): + """ + Return a single named information item from the os-release file data + source of the OS distribution. + + For details, see :func:`distro.os_release_attr`. + """ + return self._os_release_info.get(attribute, '') + + def lsb_release_attr(self, attribute): + """ + Return a single named information item from the lsb_release command + output data source of the OS distribution. + + For details, see :func:`distro.lsb_release_attr`. + """ + return self._lsb_release_info.get(attribute, '') + + def distro_release_attr(self, attribute): + """ + Return a single named information item from the distro release file + data source of the OS distribution. + + For details, see :func:`distro.distro_release_attr`. + """ + return self._distro_release_info.get(attribute, '') + + def uname_attr(self, attribute): + """ + Return a single named information item from the uname command + output data source of the OS distribution. + + For details, see :func:`distro.uname_release_attr`. + """ + return self._uname_info.get(attribute, '') + + @cached_property + def _os_release_info(self): + """ + Get the information items from the specified os-release file. + + Returns: + A dictionary containing all information items. + """ + if os.path.isfile(self.os_release_file): + with open(self.os_release_file) as release_file: + return self._parse_os_release_content(release_file) + return {} + + @staticmethod + def _parse_os_release_content(lines): + """ + Parse the lines of an os-release file. + + Parameters: + + * lines: Iterable through the lines in the os-release file. + Each line must be a unicode string or a UTF-8 encoded byte + string. + + Returns: + A dictionary containing all information items. + """ + props = {} + lexer = shlex.shlex(lines, posix=True) + lexer.whitespace_split = True + + # The shlex module defines its `wordchars` variable using literals, + # making it dependent on the encoding of the Python source file. + # In Python 2.6 and 2.7, the shlex source file is encoded in + # 'iso-8859-1', and the `wordchars` variable is defined as a byte + # string. This causes a UnicodeDecodeError to be raised when the + # parsed content is a unicode object. The following fix resolves that + # (... but it should be fixed in shlex...): + if sys.version_info[0] == 2 and isinstance(lexer.wordchars, bytes): + lexer.wordchars = lexer.wordchars.decode('iso-8859-1') + + tokens = list(lexer) + for token in tokens: + # At this point, all shell-like parsing has been done (i.e. + # comments processed, quotes and backslash escape sequences + # processed, multi-line values assembled, trailing newlines + # stripped, etc.), so the tokens are now either: + # * variable assignments: var=value + # * 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 + if k == 'VERSION': + # this handles cases in which the codename is in + # the `(CODENAME)` (rhel, centos, fedora) format + # or in the `, CODENAME` format (Ubuntu). + codename = re.search(r'(\(\D+\))|,(\s+)?\D+', v) + if codename: + codename = codename.group() + codename = codename.strip('()') + codename = codename.strip(',') + codename = codename.strip() + # codename appears within paranthese. + props['codename'] = codename + else: + props['codename'] = '' + else: + # Ignore any tokens that are not variable assignments + pass + return props + + @cached_property + def _lsb_release_info(self): + """ + Get the information items from the lsb_release command output. + + Returns: + A dictionary containing all information items. + """ + if not self.include_lsb: + return {} + with open(os.devnull, 'w') as devnull: + try: + cmd = ('lsb_release', '-a') + stdout = subprocess.check_output(cmd, stderr=devnull) + except OSError: # Command not found + return {} + content = stdout.decode(sys.getfilesystemencoding()).splitlines() + return self._parse_lsb_release_content(content) + + @staticmethod + def _parse_lsb_release_content(lines): + """ + Parse the output of the lsb_release command. + + Parameters: + + * lines: Iterable through the lines of the lsb_release output. + Each line must be a unicode string or a UTF-8 encoded byte + string. + + Returns: + A dictionary containing all information items. + """ + props = {} + for line in lines: + kv = line.strip('\n').split(':', 1) + if len(kv) != 2: + # Ignore lines without colon. + continue + k, v = kv + props.update({k.replace(' ', '_').lower(): v.strip()}) + return props + + @cached_property + def _uname_info(self): + with open(os.devnull, 'w') as devnull: + try: + cmd = ('uname', '-rs') + stdout = subprocess.check_output(cmd, stderr=devnull) + except OSError: + return {} + content = stdout.decode(sys.getfilesystemencoding()).splitlines() + return self._parse_uname_content(content) + + @staticmethod + def _parse_uname_content(lines): + props = {} + match = re.search(r'^([^\s]+)\s+([\d\.]+)', lines[0].strip()) + if match: + name, version = match.groups() + + # This is to prevent the Linux kernel version from + # appearing as the 'best' version on otherwise + # identifiable distributions. + if name == 'Linux': + return {} + props['id'] = name.lower() + props['name'] = name + props['release'] = version + return props + + @cached_property + def _distro_release_info(self): + """ + Get the information items from the specified distro release file. + + Returns: + A dictionary containing all information items. + """ + if self.distro_release_file: + # If it was specified, we use it and parse what we can, even if + # its file name or content does not match the expected pattern. + distro_info = self._parse_distro_release_file( + self.distro_release_file) + basename = os.path.basename(self.distro_release_file) + # The file name pattern for user-specified distro release files + # is somewhat more tolerant (compared to when searching for the + # file), because we want to use what was specified as best as + # possible. + match = _DISTRO_RELEASE_BASENAME_PATTERN.match(basename) + if match: + distro_info['id'] = match.group(1) + return distro_info + else: + try: + basenames = os.listdir(_UNIXCONFDIR) + # We sort for repeatability in cases where there are multiple + # distro specific files; e.g. CentOS, Oracle, Enterprise all + # containing `redhat-release` on top of their own. + basenames.sort() + except OSError: + # This may occur when /etc is not readable but we can't be + # sure about the *-release files. Check common entries of + # /etc for information. If they turn out to not be there the + # error is handled in `_parse_distro_release_file()`. + basenames = ['SuSE-release', + 'arch-release', + 'base-release', + 'centos-release', + 'fedora-release', + 'gentoo-release', + 'mageia-release', + 'mandrake-release', + 'mandriva-release', + 'mandrivalinux-release', + 'manjaro-release', + 'oracle-release', + 'redhat-release', + 'sl-release', + 'slackware-version'] + for basename in basenames: + if basename in _DISTRO_RELEASE_IGNORE_BASENAMES: + continue + match = _DISTRO_RELEASE_BASENAME_PATTERN.match(basename) + if match: + filepath = os.path.join(_UNIXCONFDIR, basename) + distro_info = self._parse_distro_release_file(filepath) + if 'name' in distro_info: + # The name is always present if the pattern matches + self.distro_release_file = filepath + distro_info['id'] = match.group(1) + return distro_info + return {} + + def _parse_distro_release_file(self, filepath): + """ + Parse a distro release file. + + Parameters: + + * filepath: Path name of the distro release file. + + Returns: + A dictionary containing all information items. + """ + try: + with open(filepath) as fp: + # Only parse the first line. For instance, on SLES there + # are multiple lines. We don't want them... + return self._parse_distro_release_content(fp.readline()) + except (OSError, IOError): + # Ignore not being able to read a specific, seemingly version + # related file. + # See https://github.com/nir0s/distro/issues/162 + return {} + + @staticmethod + def _parse_distro_release_content(line): + """ + Parse a line from a distro release file. + + Parameters: + * line: Line from the distro release file. Must be a unicode string + or a UTF-8 encoded byte string. + + 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 = {} + if matches: + # regexp ensures non-None + distro_info['name'] = matches.group(3)[::-1] + if matches.group(2): + distro_info['version_id'] = matches.group(2)[::-1] + if matches.group(1): + distro_info['codename'] = matches.group(1)[::-1] + elif line: + distro_info['name'] = line.strip() + return distro_info + + +_distro = LinuxDistribution() + + +def main(): + logger = logging.getLogger(__name__) + logger.setLevel(logging.DEBUG) + logger.addHandler(logging.StreamHandler(sys.stdout)) + + parser = argparse.ArgumentParser(description="OS distro info tool") + parser.add_argument( + '--json', + '-j', + help="Output in machine readable format", + action="store_true") + args = parser.parse_args() + + if args.json: + logger.info(json.dumps(info(), indent=4, sort_keys=True)) + else: + logger.info('Name: %s', name(pretty=True)) + distribution_version = version(pretty=True) + logger.info('Version: %s', distribution_version) + distribution_codename = codename() + logger.info('Codename: %s', distribution_codename) + + +if __name__ == '__main__': + main() diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__init__.py new file mode 100644 index 0000000..0491234 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__init__.py @@ -0,0 +1,35 @@ +""" +HTML parsing library based on the `WHATWG HTML specification +<https://whatwg.org/html>`_. The parser is designed to be compatible with +existing HTML found in the wild and implements well-defined error recovery that +is largely compatible with modern desktop web browsers. + +Example usage:: + + from pip._vendor import html5lib + with open("my_document.html", "rb") as f: + tree = html5lib.parse(f) + +For convenience, this module re-exports the following names: + +* :func:`~.html5parser.parse` +* :func:`~.html5parser.parseFragment` +* :class:`~.html5parser.HTMLParser` +* :func:`~.treebuilders.getTreeBuilder` +* :func:`~.treewalkers.getTreeWalker` +* :func:`~.serializer.serialize` +""" + +from __future__ import absolute_import, division, unicode_literals + +from .html5parser import HTMLParser, parse, parseFragment +from .treebuilders import getTreeBuilder +from .treewalkers import getTreeWalker +from .serializer import serialize + +__all__ = ["HTMLParser", "parse", "parseFragment", "getTreeBuilder", + "getTreeWalker", "serialize"] + +# this has to be at the top level, see how setup.py parses this +#: Distribution version number. +__version__ = "1.0.1" diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7c73b809984eeb8f76bd40fe05106f2dff8098f5 GIT binary patch literal 1321 zcmaJ>&2HQ_5Z3;9cdgyE9l$;1Lim&|V##jc7Fi@g6QF4hZBd{L7!V3@DUs5$CPjgy zR`wqH07YITK%Yq0p7IJkbx1jG>;k2r5jh&o_syT)%;#YM>;2>O*FT0q@RvJ$S|iwe z3%A*Tpg|JQ9_@>s>?eIWNCtA440{0`(4p9qqhut<$yiR3iP!CkeHkX9-;cyp&XSqm zkHuUbBnPmc(0v-xDV@=IF-i{UL2^V7e+d>x<j;N(gzr{A{(vf?4KE8Mc&drMK`Ake zB2^;0VQ78%?)B>Od*m%m#WJ4rj99M9@Wsa3$}Ho!*$~?lk<vxHu~NKR;|Q(bTj!W* z#0{d%@S+5-R-u%kOvws-q=KP_+fB%>xv`FdN6A%PQp7v_h6{>_JIhKi$x3Tb!-P1c zEa%Q6(^_eyS*ErO$XnnN0-_+gVB+Q>6q1TET{=QnR#o6CMX6Q|@H9~ves@hA45|$& z*m4<$2v)9@L=~?hyk#W?FrcEeMK0D0NSZftaUfN(^2v$3!Bl0n;~F`elc(rJrzZ<U z49b_@+PSrwG4%4zOXRclBwvK#TfoRv322;^8G8yrK}5j325Op}vTKKLe0_2yglb&w zN+Ov7%3q>oUYFT&{kuoM=&I1UU;pphx0)1=wYSOyG3KEYSD&AKRquInp`<lb%4M-& zb_M4*-T6Ou4G~wLnO*whJu9dMCxY*oj_$VW@FR>zuo$$5BsEIZmf@}p?S%3zH_(vn zQC;#3>Wc-pOcP-~_PTF;pLe|5J)e(u?jN5bUi8|7`@BIjztwaUL9u^FN4u%jV<#p~ z>^tFRTu(vl_RgcT==`U}qjrp4FJRn;80WREHN#lL<OO=*1pEwwcIq3+^U)6+x3kYv z>tWidQ{86KW47VHyga@`B|-q|6hqI#bgL5M4}m^*m`?ny<4W@_u`J#a9YYhj(#3KU zXXh1uzI*=LS@SHXJM;Ckt^VrT?&KM)qKsED48kcdjRk<yi*M4+Rh<@2>F?VK@xK8# m8ZpMa<QC(ox@jjbx)y%*1u!s2Acp<p{&8>SuKuJq8U6!2E1&iN literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/_ihatexml.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/_ihatexml.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..554675519487fc9abc3c6f46b4d3db93aebf2e8b GIT binary patch literal 13768 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 H)%*SrM3LPp literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/_inputstream.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/_inputstream.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2cec2e9190e8e146ea9b2c74b351cffb8e0d9470 GIT binary patch literal 22659 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/_tokenizer.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/_tokenizer.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6893c88789884be8e422ea1494f382eb2f0cfb51 GIT binary patch literal 41560 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 VE&Jj*{s#y4fG@FDOnzq){}24JYl8p) literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/_utils.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/_utils.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c8533d4597eee536543d6054939188a6745d4c97 GIT binary patch literal 3313 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/constants.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/constants.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8618ccb2c7c7851c4fbcc8567ae9d16c6a9ead4b GIT binary patch literal 66225 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�pXYAA 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/html5parser.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/html5parser.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..05e3cb9c6403eeeccbed3163e1ad8d14eb56ae18 GIT binary patch literal 97822 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/serializer.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/serializer.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..afe1fbbf7053f1592039499cc42114020f3af2e5 GIT binary patch literal 10838 zcmb_iOLHX0aqjMU4+ew5V*%`w4J@(1kh=h%q6uPQE_bnfm|W5X_!^NKG^PqbFM4`r zt9ur}#DD?`ijo`-YJIRp^B@l*91hFj2>Tx>f(M;=^g+=FhX^@r^TLZAI_$|`R?QOw zt{e^z(A8C0RaseCSy@?`{X&0#Qp4}h&#t}y*;P&Z9Tl3tFfz~M@jlcwjcH7Gw4$EV zi$=~UhH@dDV1^SeMsg9E4>{3X6tJ)pE5>v2Vj`CSJi?+*ve=jFE2eU(Vt=k*!eW4> zbLrwhZlIXSWh5-_3>JrSL&f3Tu*8>eMvA9$r;tz9M|uCD&icl*+!&A6$61PxjcKfZ zOgq$br#m2N2{~hHxwHHn8#vHeWXs5%-}#VV-~;uC4z&aQhW3H`zL7I?6a2jRH-3&! z$W~$RD}LVleWRS&3X9+0`HD}l!L5+^ss%Of>0+D@*C+V|MxJov{37)St_gm2D|S!! zp5SKv;X@65On#P6ENFMWdPieJZ1@u`H^t*@gijq9nA15n%Ems?bC+J!*f=}=iN;Rz z>4Q*i2IVvCEXrqj7Uf4+Xj#ji|Atm28wv)jHLv7Ue4e+9<&yA&IJ58Co?UW-OvSYe zCC2lP?Q>x{URDnhKHu^4{%)Dy${Imh@D1BTWu6OB62bUR(J5?NLhyCL%Z^pxs>1sQ zD^8=O?v`w}<nSVQeJ>bXE0r8>xz~JO*lVD{3kJM0dR+$&s{p(n`lLmHS-#ck6-Qs& zx6!x{!!0!mpr+3koNrss7WxIze8smV$x-eVtTGR@YIJh?>cZmcef|6Q^$#j};(%_1 z!jWh!o=Enk`qKlM!J*-iQ=?<!r_Y={cmBdd=G^L+^{>C!|GNI!*Y%$r?e8D$e{{6} z@zMUl(f%h#`#(C`|MY18$4C1=Ioki}(f*$u?f?DJ{x6UA|LN$Xzxmz%{s$Ej`Tzde zuYUE7fy{mVQi1qDKiVY;JlFAflYshKP4ji%ST_zxCPp{3Jspq1^u5r|PyA3#yB)?8 z!4v(Fak?dUd*QuEEhKJIyE{+SWScQ<FY3qYaoH#8C#X*?%8W5>!#L2X_n|KCp+!=) zP<0Bv7h|ElkQ?{=YLNqdFIF?^saot%*R?xOy`$~?pk_ec-`<P+{q=M$eyHyyY6<b5 zHNBo<VQNLWT0-U$^#K++)V+U~wa5X-KgxX6&(z}BB?i-I)KSnwb&%^=eXyn<>O}Fn zv8?$+HOzDwngKE!zjafb0>4(oDAN1-bJggji#t=^b7BbP>~N5T+`67`xdk2!y`_YA z$t4k9lHz%)0b3E4>p7O+04KOxDMG+~9z;uPw|T)2BEW*Z5aKQq86Xb^Y;U;&BpYb; zhGmN&RJ7e--0Os`l&)i_a>;hlvm{s$waR5+2!`@pQh^sFcQ;?O%0Xy@W3Qps+qV79 zAhgMMg79th6)~Dj5@YWaf{=iiCus%}trvv7ExR1(cAyu6i0v};O0=p2qkua8OHDjU z4D#p7!oCZF=k8i!ZoT9%Y>c_$=3L?Na{k%sv$r4HesY~vz3)AFS3I%fSBsC~x8csM z%$4o(70F4*x$^WgYnxk@wG9HwCw~`Im&DwrUv!>!?6o<M3)^z+Di^cm-C&&HYNFjb z;1ST|J%&WnGkRG5nKCu>q&}&S>ro@Fr;$$rN@-G085i`7A)ZE`V6X>o5aG1r3n9XZ zUlb2*xIe+;J&eTH>N-i&UKsmItA#$(u~#DX5bcr!y=ELj!m_&cIX35Va}J*AZ*tRi z%N5`BOIzGEJq%(M%?e~|LsoiaUa;3~&dj#LNhVGF<}I<I`p(OiT?qV=+2T}3bHdSR z-BMo|8RPMeR#JdKfNI$+^|ot`Ao8WM@6DT*yK5o`eU6!x%(CUlHzp}5mQ<H_=L-%h z=2x3*I@`uG`_js5ueR7DRxvTlHzB>ASpZ{v&KhJ2?pK71A&G%BtM+u6X?dnaoWvAV z^Q9fDSa$flDlIN9n(LxeG+PA7OxY43#8f8}Xh%s>-P^oPZ?km^(&`~sBi~rgs|wxB z^a72vxUg1YyNe6u#h2`fg}L(L!khv~DPNq<wve>Y&UB)?Y?g|)Pb>$cEhq0=8{XBM zI5N5F*&Jn)TMW3>>%l`R#$>}{0FoT^gW)US={xdx3)0<-5<~^|Bp2BzDFujb5T*qn z{Q~6xp5t6?3b+!CAgT_^K=-7wP{~s?RHD^XZY0`O+Boe-aSgcw6`McWdC%kVK19N` zoX)hI!Sq~+8M!bE<sx{Zcw#J^i{qWZJBg<cd7Kxye!SCo58%nLNN$itSqyf~5R0<} z-oq@(`tTlMBdnjLVcnc!r`Q0?AU6tohpZqyH^x%f$7AAI5D`QjzF`%1@9UE*H?!$r z@J^)!+s1;0k-uv>6;h`PM0QFrj9r#r<DQ@I01ox8WpEbi-Y!DN<r_AOMA<M}MhJ^9 zEZYIA^Dw7uR`G)K(v$)A^^!QDdPtcidB@M&uEgdA{SBD1c!CVHf62KEBdTffj9E^3 z(^})cU4WF)tQsT?+b$hk`6BnNJWb8R@sgnpSI%#5!hVy)1aZ%DVLMfM%Mc-jNydm= z>nbuZMDzol%#qu8kHZA<jT+1bro)7N!pGA3VLw8U1AP=~^kbccYWh}GJkOw3^U<9d z>Ioy^!d}Ra)u489<i~3vGDB*i11Q}CnEH2KdPm#97<q^T(moc!5=N~TK+4NRp*&B_ zZYftgqC?O2%y`~>XOlzy2(u(iw?rBo>X@2Ir9{jz8_bz)V<U_=__|ebpwrM}b#+Bl z`08p$6RFsHM5#R-ddXU|wIrsJHl;0D$({CF`j*BM{7%IdT=s&{m}StcB-dOMrEP3M zbB%9WcWq2$W_5K^)lIIhW-puDo7_DK88g>*<vhs*VwPaCC!JQRA5dA&wzca?xXMyZ z$2@yk(H^;@SqD3ao%7~f9yd2^7zPbC5L6oQCWOC(Da0g9w*%D)Bd)Guigsbs+_oKu z&OwuvDr=5n7Wd4G>u{W6Emn8&LbBZ~lw99}1%pGUv+rd{Lj!lg0$w`O+juR}J`;&7 zjLbSHm6Pt>v~3}1%baQjL0Z6EFysSB^*ToA<%K*#dL^+-O|%Js6gEa~@t@2Y9M>)< zYo!F4>SC5^&A@1X6J)w2QM4SBH|}Rmu+m0tuvfv_SY8(<&);?U|79x2Rb1C>8kMGN z6+wS%Qf5;h%E@)nK^C_Ki@{YJp;QqCWsJ<4D=<smeeG4VEI8xqwhN3cJeM5*IrGwn z|6CWcOE6IYCZWa4Dwn+HOb7`C&{|)IQUM0J<7^M6j{gS*`(&+hTt^>cK(Ta}45^}p zBLF(z*)@x}F-y7ix|g7>=4Z{Bl}!*;C>1eT&%>TUPZIpbIY6QSb4*FUJQ=#?jhhEA z`_1KFT?G=zVD>>8^E(9f0jK7?xx5K~1IH$99I5SXBGoYIlP<DuS3IT1TiZz~*~?PN z@P<LzuqbISso#P!=9%qTP$KN=WHUFp*gc~)4u)}W{tsa|*6n|Dbev=$%$qN}1*gJj zb<BcO^7s{)jV3Op9=4a7DXcoPv`(_z#R+*kHK{c!$)(cXoHM*w_IKOm?M)ztpkw=^ zx!o-?P|j;MW8BTonoF}Av!t;$#oS_-#vv|t&+$7J`+@e(y!i(CgJ`a@9n5s>X&d(k zh_teix~52%2x1Ckw80Y6qjD1JCWd^&;xZc+mzqNt7C9eNPRM*y9l0JRdD3!R?b)8a z6Ypsv&xEE;1&JnmOYXIb>sjlZ%#ez^<(9TxI+C!}D+SmX@}^U&_%PIGyU1O}rD^_z z+t|A8kTYzyIg*&YDIuLEN-wqFu}r<z?Y#LqZZEi=!RIm85S7NkLF%q~t9hV$KbbY( zVXn?&G2kG9k<;4Ba?7vL%^Un{+qmE$nmusj-f0T*vQ?kR!?4DsEI*SqH((1|F4ltY zz#JmQy~TI8fgAdK1I{1UH>an(X|aTkH*aNAK>}-3g>Hfs9cx^lgAm*rL1G2IPvuSu z0~>By<Qx?@(J_djIZa4R$r7$?R0^WfISQ8~srrJS4a1AWo%JBPwT;o?^K6rqmw>QD zLOz_1YgxQGogV}4k;hAWeMnE~BYIqq;(Y;Wb*$TBo^AFikpGc>^d^)4Iv$TaGGy-i z`hnr4edA;DyM@Fg40iG(hL}zsl3LUMX513rLyv4kjN>IDNP_e=94~@yy^<#aK7ZW7 zl)Ecyi1%fY=Iw4AyJw0u)cqEZ7e}JO^Apw6M)lOO87Nf$U-W+;BX!a*EC3|YlAH#` zqCn7N{7)%LXp0y8|3HIoy3d|Sw`zT>5JG$U(Xx?$j|T9*#X{5!+<p)W*$c_r5S&ut zF|ZyfoTDKpR1EKh;ZzORP;+4H(E>%pE3z)yu7jhNYGQ)Pns`r5LVPG|l07wj;&WM( z>aMvL-nmu7E$&|UgB#>DW8u?qD#KBX@CV$}t1Jpwj9j;H5l2}3v?l(w7GnvOAJv`# z+|8hrM9sIT=_80LqyH-^SMO&jgkk!(B7i;Cf~8xqM`~I<%?8Ll%+h;tH_TFdabSb{ zShcRj*F$PFKnLX*T77^V)^BULW!6FQ&{h=Ke~sKQ(e71iA(a1FroRA|k<%LJIMo{S z7jn!|>B83PGzYX$_}mfHW&A+}JAiAkHOd%931Oy^D{zW~3N~I#kZYUT)Dk|?VF<cc z58pF9glFJp&wvU;WaNlvXvBN^&gTu9Mh-RbU;p6K_l@_Bz2sisUaHo&*I!HRr6u;W z4a_uO1heEQ+U--o_hGHyAFYpJ%<%*5&_Ec;5T=5$b6qf^@_eiBX?6h|GQ7X_&(zYm z@%K|n`~xT*aGwX=r`bai@@xNW{alS!N!v=G?qOMH%DN-}d{<rEzrZHQOHfPKA7Yd2 z;-NwG-!{Rmq=Y@prX*|tkS|a(ffd$nPone&OV`qpuYbf+$i)Cd4sw8iU86>|p&I1S zGtSbWBP2E@?likZxLvfy=qWa>MhC|bx=<X$3S%aXd<%{qwDygfd&V8}9a_VSlA7Ow zzK1aey{GX07r7oY3XAMHz_Klz88)c$QW_rtb?~FK<V49uSY${CNO=fjtw`#nJV?xs zw&h6TxGZt_N>27NwG8C<N<)6b;s>(#Y(str*qmzDlthW)F^S<fZ7SH~2pSF62K`Im za#;MG#PNh07t*WUo(A+w)X&KJFa1lkL1=`G8)r{aD^Njlm}$)vGf?9a9e3&o?NA8k zDTHuH-6N71RVEBPl{ip?*o{(wGS$?=#EsXlue|rhk~xKN2i^RFcp2A!yYMorrp!0q zdg0ZVubY!o-Xy$Py9hoO0gsu>?=7z^y(Z{flgIykeY$#WS=O62EL`7Shq=-63#^s= z&E^FN&XO)KLHnZV0r8YafA{r8L>QCTn|=+P+RNRMO5tMYAWWgks<ALv9et~9Y%I)? zU32}$wUukY5?>}mYsK0K;!9+#BUcSAOnEESM?3lyHf^V6*OQ%ZDFjW^{=RO?xYvFC zDgsT?uLHXR){S@pgjD~y$6I9<>HY*0tK{NYpEsvfuj$L?H1)$9=IXTaG)>DGTQwrD z!1wiqYM8FbC|`W?S&F;KJ8{)8=kDusL3GJwG>OQ<+?2N%#IBcM+q-_%xN@aB+$gkJ z4`5<p;>wjN@5+@$>Ps;(F-Am>s{(i~y>|i^vJDsBN`~PP=gVf*QJtejex2BTwrLrk z;Qkbxn%$yi7n;pFP0P0FDc+z)L(N9*d$Rabsu*lmw9IeuBEd(R@TP%`8x}+st_2pP zTTXOk7cq2@CWaWKT#Axc2}uOzW6={Y5rF)#%65$S6$D4b4FarCvti|+zSi{kE@Q!9 zP{P+y*bGh`t9(_uz=P!5<nWf`2eC#hPLQ8hnz_<s6%>OOFH`agCH<7VMoAh;c1Rg; zNeU*Yc!4tT;_z6@puFU95Rst}v5qc5jH!*R#@Hl~o(~el?7ZB}Ntu;yx<KCw^t(-m zJi$eYI)q@HA2YvX?BQEfdcQ%U8BxRtqXr^`dNNGbZ#*PZX$dQPIBuk28B+`~t`8wc z`4Rjj(J!ozQmhgEGx`}ohKy0<<0uUQLllq;XcI<XV3xg7Xh$Pt=rQ6Fo|0{;K8lB8 zmTAE0FKrCTF{w<W(AWy^P-C1VC?Gi1q|r7>^n|M8$E?Vf6tyf!vLwlZBt_>vfdm%g z8K&3q@c=ZiL3ScM?66D_G&kDNLwM^Yj6VJdTQ2Sa%gu-oUG?B&!XhKgDetCKZm&6X zm+}`$GrsLJk(b|gvv%N5i3&NHTJ#_5C2eWk2~;0-KY)`$1*@ndZs;9dx<ZRBoGSj> zZq^-Ar2BABoUj=jl%d4S6vbR=1=U(N@t$5C(a<J>?se+w+8Gx#PYg547~=`?#U{xO z{$1^+Z)RGCyBo2{X4@7w1jg#7YNq$5-x-ta#W1U)h%;*Zt^j9N#WAVRcgHe&=ha@E z|AMG$^1!;44T%{Pg0O>chvdcvgl>xBr<BkY^7!tb2W%U+dQV0pM`-`{+!Ph@_s8FT z_g!=8%{O0v(|m1ddHLFlOXjVmr5j5(y6%v)jpP<OgAB}@#+L%p)G@@UA3|7*3>N(s zBCztjxkzNu{V_<lc8=7o%}XPxuH$rn1lYY6-OvWOqo40yrM7S>Y#5RL#b2Roc09nf zpVVePA0+enVu@88%BS*B`Ie(<)G<M>3#HTPa8d_KTd_;EPX~_D?sO{36I333@|Y9L z1Y4zqZstOsSl1{=%ojA1j@ik}F@=j|)Rok{cNs}ML~1jv(&oEaGQzR=d+}I2mi(cX zOrDlK3+UAPfl=D?cs%;#raPRBr3i_i0}LC1zU3i%swMhL5ztC~juzstDft3P5X<Lr z9Od&T5>D8DPHPiJCJwSCeyrv*DBsFHN(^7G;F|_8TtHuHf`mp;>tFyM!^}25gqij1 z9pwx$1im1G4&wz+kf6#>dFcBb`B9SZsnb@T@_ke-tpIuC(rGI<hm7{CPmVJ9x(yz` z9eU)qY|3<yTW9>(iBIML*`{6)gAcoG!*=+DP<~3u!<0xXBA&Ose5K$$CH|6NA5(IV zlE0v2f|5xjLCp4?(l!_J%Nw~v#W|{!5%$EA3=hENBN=uQZ-e-P64gaoQf~pt2pz;m s#-Jk@hbRtb9C~^@fkPIXIRlu1!!WImYa<nkUr2_M=QBUleyBbEKVjMaC;$Ke literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_ihatexml.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_ihatexml.py new file mode 100644 index 0000000..4c77717 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_ihatexml.py @@ -0,0 +1,288 @@ +from __future__ import absolute_import, division, unicode_literals + +import re +import warnings + +from .constants import DataLossWarning + +baseChar = """ +[#x0041-#x005A] | [#x0061-#x007A] | [#x00C0-#x00D6] | [#x00D8-#x00F6] | +[#x00F8-#x00FF] | [#x0100-#x0131] | [#x0134-#x013E] | [#x0141-#x0148] | +[#x014A-#x017E] | [#x0180-#x01C3] | [#x01CD-#x01F0] | [#x01F4-#x01F5] | +[#x01FA-#x0217] | [#x0250-#x02A8] | [#x02BB-#x02C1] | #x0386 | +[#x0388-#x038A] | #x038C | [#x038E-#x03A1] | [#x03A3-#x03CE] | +[#x03D0-#x03D6] | #x03DA | #x03DC | #x03DE | #x03E0 | [#x03E2-#x03F3] | +[#x0401-#x040C] | [#x040E-#x044F] | [#x0451-#x045C] | [#x045E-#x0481] | +[#x0490-#x04C4] | [#x04C7-#x04C8] | [#x04CB-#x04CC] | [#x04D0-#x04EB] | +[#x04EE-#x04F5] | [#x04F8-#x04F9] | [#x0531-#x0556] | #x0559 | +[#x0561-#x0586] | [#x05D0-#x05EA] | [#x05F0-#x05F2] | [#x0621-#x063A] | +[#x0641-#x064A] | [#x0671-#x06B7] | [#x06BA-#x06BE] | [#x06C0-#x06CE] | +[#x06D0-#x06D3] | #x06D5 | [#x06E5-#x06E6] | [#x0905-#x0939] | #x093D | +[#x0958-#x0961] | [#x0985-#x098C] | [#x098F-#x0990] | [#x0993-#x09A8] | +[#x09AA-#x09B0] | #x09B2 | [#x09B6-#x09B9] | [#x09DC-#x09DD] | +[#x09DF-#x09E1] | [#x09F0-#x09F1] | [#x0A05-#x0A0A] | [#x0A0F-#x0A10] | +[#x0A13-#x0A28] | [#x0A2A-#x0A30] | [#x0A32-#x0A33] | [#x0A35-#x0A36] | +[#x0A38-#x0A39] | [#x0A59-#x0A5C] | #x0A5E | [#x0A72-#x0A74] | +[#x0A85-#x0A8B] | #x0A8D | [#x0A8F-#x0A91] | [#x0A93-#x0AA8] | +[#x0AAA-#x0AB0] | [#x0AB2-#x0AB3] | [#x0AB5-#x0AB9] | #x0ABD | #x0AE0 | +[#x0B05-#x0B0C] | [#x0B0F-#x0B10] | [#x0B13-#x0B28] | [#x0B2A-#x0B30] | +[#x0B32-#x0B33] | [#x0B36-#x0B39] | #x0B3D | [#x0B5C-#x0B5D] | +[#x0B5F-#x0B61] | [#x0B85-#x0B8A] | [#x0B8E-#x0B90] | [#x0B92-#x0B95] | +[#x0B99-#x0B9A] | #x0B9C | [#x0B9E-#x0B9F] | [#x0BA3-#x0BA4] | +[#x0BA8-#x0BAA] | [#x0BAE-#x0BB5] | [#x0BB7-#x0BB9] | [#x0C05-#x0C0C] | +[#x0C0E-#x0C10] | [#x0C12-#x0C28] | [#x0C2A-#x0C33] | [#x0C35-#x0C39] | +[#x0C60-#x0C61] | [#x0C85-#x0C8C] | [#x0C8E-#x0C90] | [#x0C92-#x0CA8] | +[#x0CAA-#x0CB3] | [#x0CB5-#x0CB9] | #x0CDE | [#x0CE0-#x0CE1] | +[#x0D05-#x0D0C] | [#x0D0E-#x0D10] | [#x0D12-#x0D28] | [#x0D2A-#x0D39] | +[#x0D60-#x0D61] | [#x0E01-#x0E2E] | #x0E30 | [#x0E32-#x0E33] | +[#x0E40-#x0E45] | [#x0E81-#x0E82] | #x0E84 | [#x0E87-#x0E88] | #x0E8A | +#x0E8D | [#x0E94-#x0E97] | [#x0E99-#x0E9F] | [#x0EA1-#x0EA3] | #x0EA5 | +#x0EA7 | [#x0EAA-#x0EAB] | [#x0EAD-#x0EAE] | #x0EB0 | [#x0EB2-#x0EB3] | +#x0EBD | [#x0EC0-#x0EC4] | [#x0F40-#x0F47] | [#x0F49-#x0F69] | +[#x10A0-#x10C5] | [#x10D0-#x10F6] | #x1100 | [#x1102-#x1103] | +[#x1105-#x1107] | #x1109 | [#x110B-#x110C] | [#x110E-#x1112] | #x113C | +#x113E | #x1140 | #x114C | #x114E | #x1150 | [#x1154-#x1155] | #x1159 | +[#x115F-#x1161] | #x1163 | #x1165 | #x1167 | #x1169 | [#x116D-#x116E] | +[#x1172-#x1173] | #x1175 | #x119E | #x11A8 | #x11AB | [#x11AE-#x11AF] | +[#x11B7-#x11B8] | #x11BA | [#x11BC-#x11C2] | #x11EB | #x11F0 | #x11F9 | +[#x1E00-#x1E9B] | [#x1EA0-#x1EF9] | [#x1F00-#x1F15] | [#x1F18-#x1F1D] | +[#x1F20-#x1F45] | [#x1F48-#x1F4D] | [#x1F50-#x1F57] | #x1F59 | #x1F5B | +#x1F5D | [#x1F5F-#x1F7D] | [#x1F80-#x1FB4] | [#x1FB6-#x1FBC] | #x1FBE | +[#x1FC2-#x1FC4] | [#x1FC6-#x1FCC] | [#x1FD0-#x1FD3] | [#x1FD6-#x1FDB] | +[#x1FE0-#x1FEC] | [#x1FF2-#x1FF4] | [#x1FF6-#x1FFC] | #x2126 | +[#x212A-#x212B] | #x212E | [#x2180-#x2182] | [#x3041-#x3094] | +[#x30A1-#x30FA] | [#x3105-#x312C] | [#xAC00-#xD7A3]""" + +ideographic = """[#x4E00-#x9FA5] | #x3007 | [#x3021-#x3029]""" + +combiningCharacter = """ +[#x0300-#x0345] | [#x0360-#x0361] | [#x0483-#x0486] | [#x0591-#x05A1] | +[#x05A3-#x05B9] | [#x05BB-#x05BD] | #x05BF | [#x05C1-#x05C2] | #x05C4 | +[#x064B-#x0652] | #x0670 | [#x06D6-#x06DC] | [#x06DD-#x06DF] | +[#x06E0-#x06E4] | [#x06E7-#x06E8] | [#x06EA-#x06ED] | [#x0901-#x0903] | +#x093C | [#x093E-#x094C] | #x094D | [#x0951-#x0954] | [#x0962-#x0963] | +[#x0981-#x0983] | #x09BC | #x09BE | #x09BF | [#x09C0-#x09C4] | +[#x09C7-#x09C8] | [#x09CB-#x09CD] | #x09D7 | [#x09E2-#x09E3] | #x0A02 | +#x0A3C | #x0A3E | #x0A3F | [#x0A40-#x0A42] | [#x0A47-#x0A48] | +[#x0A4B-#x0A4D] | [#x0A70-#x0A71] | [#x0A81-#x0A83] | #x0ABC | +[#x0ABE-#x0AC5] | [#x0AC7-#x0AC9] | [#x0ACB-#x0ACD] | [#x0B01-#x0B03] | +#x0B3C | [#x0B3E-#x0B43] | [#x0B47-#x0B48] | [#x0B4B-#x0B4D] | +[#x0B56-#x0B57] | [#x0B82-#x0B83] | [#x0BBE-#x0BC2] | [#x0BC6-#x0BC8] | +[#x0BCA-#x0BCD] | #x0BD7 | [#x0C01-#x0C03] | [#x0C3E-#x0C44] | +[#x0C46-#x0C48] | [#x0C4A-#x0C4D] | [#x0C55-#x0C56] | [#x0C82-#x0C83] | +[#x0CBE-#x0CC4] | [#x0CC6-#x0CC8] | [#x0CCA-#x0CCD] | [#x0CD5-#x0CD6] | +[#x0D02-#x0D03] | [#x0D3E-#x0D43] | [#x0D46-#x0D48] | [#x0D4A-#x0D4D] | +#x0D57 | #x0E31 | [#x0E34-#x0E3A] | [#x0E47-#x0E4E] | #x0EB1 | +[#x0EB4-#x0EB9] | [#x0EBB-#x0EBC] | [#x0EC8-#x0ECD] | [#x0F18-#x0F19] | +#x0F35 | #x0F37 | #x0F39 | #x0F3E | #x0F3F | [#x0F71-#x0F84] | +[#x0F86-#x0F8B] | [#x0F90-#x0F95] | #x0F97 | [#x0F99-#x0FAD] | +[#x0FB1-#x0FB7] | #x0FB9 | [#x20D0-#x20DC] | #x20E1 | [#x302A-#x302F] | +#x3099 | #x309A""" + +digit = """ +[#x0030-#x0039] | [#x0660-#x0669] | [#x06F0-#x06F9] | [#x0966-#x096F] | +[#x09E6-#x09EF] | [#x0A66-#x0A6F] | [#x0AE6-#x0AEF] | [#x0B66-#x0B6F] | +[#x0BE7-#x0BEF] | [#x0C66-#x0C6F] | [#x0CE6-#x0CEF] | [#x0D66-#x0D6F] | +[#x0E50-#x0E59] | [#x0ED0-#x0ED9] | [#x0F20-#x0F29]""" + +extender = """ +#x00B7 | #x02D0 | #x02D1 | #x0387 | #x0640 | #x0E46 | #x0EC6 | #x3005 | +#[#x3031-#x3035] | [#x309D-#x309E] | [#x30FC-#x30FE]""" + +letter = " | ".join([baseChar, ideographic]) + +# Without the +name = " | ".join([letter, digit, ".", "-", "_", combiningCharacter, + extender]) +nameFirst = " | ".join([letter, "_"]) + +reChar = re.compile(r"#x([\d|A-F]{4,4})") +reCharRange = re.compile(r"\[#x([\d|A-F]{4,4})-#x([\d|A-F]{4,4})\]") + + +def charStringToList(chars): + charRanges = [item.strip() for item in chars.split(" | ")] + rv = [] + for item in charRanges: + foundMatch = False + for regexp in (reChar, reCharRange): + match = regexp.match(item) + if match is not None: + rv.append([hexToInt(item) for item in match.groups()]) + if len(rv[-1]) == 1: + rv[-1] = rv[-1] * 2 + foundMatch = True + break + if not foundMatch: + assert len(item) == 1 + + rv.append([ord(item)] * 2) + rv = normaliseCharList(rv) + return rv + + +def normaliseCharList(charList): + charList = sorted(charList) + for item in charList: + assert item[1] >= item[0] + rv = [] + i = 0 + while i < len(charList): + j = 1 + rv.append(charList[i]) + while i + j < len(charList) and charList[i + j][0] <= rv[-1][1] + 1: + rv[-1][1] = charList[i + j][1] + j += 1 + i += j + return rv + +# We don't really support characters above the BMP :( +max_unicode = int("FFFF", 16) + + +def missingRanges(charList): + rv = [] + if charList[0] != 0: + rv.append([0, charList[0][0] - 1]) + for i, item in enumerate(charList[:-1]): + rv.append([item[1] + 1, charList[i + 1][0] - 1]) + if charList[-1][1] != max_unicode: + rv.append([charList[-1][1] + 1, max_unicode]) + return rv + + +def listToRegexpStr(charList): + rv = [] + for item in charList: + if item[0] == item[1]: + rv.append(escapeRegexp(chr(item[0]))) + else: + rv.append(escapeRegexp(chr(item[0])) + "-" + + escapeRegexp(chr(item[1]))) + return "[%s]" % "".join(rv) + + +def hexToInt(hex_str): + return int(hex_str, 16) + + +def escapeRegexp(string): + specialCharacters = (".", "^", "$", "*", "+", "?", "{", "}", + "[", "]", "|", "(", ")", "-") + for char in specialCharacters: + string = string.replace(char, "\\" + char) + + return string + +# output from the above +nonXmlNameBMPRegexp = re.compile('[\x00-,/:-@\\[-\\^`\\{-\xb6\xb8-\xbf\xd7\xf7\u0132-\u0133\u013f-\u0140\u0149\u017f\u01c4-\u01cc\u01f1-\u01f3\u01f6-\u01f9\u0218-\u024f\u02a9-\u02ba\u02c2-\u02cf\u02d2-\u02ff\u0346-\u035f\u0362-\u0385\u038b\u038d\u03a2\u03cf\u03d7-\u03d9\u03db\u03dd\u03df\u03e1\u03f4-\u0400\u040d\u0450\u045d\u0482\u0487-\u048f\u04c5-\u04c6\u04c9-\u04ca\u04cd-\u04cf\u04ec-\u04ed\u04f6-\u04f7\u04fa-\u0530\u0557-\u0558\u055a-\u0560\u0587-\u0590\u05a2\u05ba\u05be\u05c0\u05c3\u05c5-\u05cf\u05eb-\u05ef\u05f3-\u0620\u063b-\u063f\u0653-\u065f\u066a-\u066f\u06b8-\u06b9\u06bf\u06cf\u06d4\u06e9\u06ee-\u06ef\u06fa-\u0900\u0904\u093a-\u093b\u094e-\u0950\u0955-\u0957\u0964-\u0965\u0970-\u0980\u0984\u098d-\u098e\u0991-\u0992\u09a9\u09b1\u09b3-\u09b5\u09ba-\u09bb\u09bd\u09c5-\u09c6\u09c9-\u09ca\u09ce-\u09d6\u09d8-\u09db\u09de\u09e4-\u09e5\u09f2-\u0a01\u0a03-\u0a04\u0a0b-\u0a0e\u0a11-\u0a12\u0a29\u0a31\u0a34\u0a37\u0a3a-\u0a3b\u0a3d\u0a43-\u0a46\u0a49-\u0a4a\u0a4e-\u0a58\u0a5d\u0a5f-\u0a65\u0a75-\u0a80\u0a84\u0a8c\u0a8e\u0a92\u0aa9\u0ab1\u0ab4\u0aba-\u0abb\u0ac6\u0aca\u0ace-\u0adf\u0ae1-\u0ae5\u0af0-\u0b00\u0b04\u0b0d-\u0b0e\u0b11-\u0b12\u0b29\u0b31\u0b34-\u0b35\u0b3a-\u0b3b\u0b44-\u0b46\u0b49-\u0b4a\u0b4e-\u0b55\u0b58-\u0b5b\u0b5e\u0b62-\u0b65\u0b70-\u0b81\u0b84\u0b8b-\u0b8d\u0b91\u0b96-\u0b98\u0b9b\u0b9d\u0ba0-\u0ba2\u0ba5-\u0ba7\u0bab-\u0bad\u0bb6\u0bba-\u0bbd\u0bc3-\u0bc5\u0bc9\u0bce-\u0bd6\u0bd8-\u0be6\u0bf0-\u0c00\u0c04\u0c0d\u0c11\u0c29\u0c34\u0c3a-\u0c3d\u0c45\u0c49\u0c4e-\u0c54\u0c57-\u0c5f\u0c62-\u0c65\u0c70-\u0c81\u0c84\u0c8d\u0c91\u0ca9\u0cb4\u0cba-\u0cbd\u0cc5\u0cc9\u0cce-\u0cd4\u0cd7-\u0cdd\u0cdf\u0ce2-\u0ce5\u0cf0-\u0d01\u0d04\u0d0d\u0d11\u0d29\u0d3a-\u0d3d\u0d44-\u0d45\u0d49\u0d4e-\u0d56\u0d58-\u0d5f\u0d62-\u0d65\u0d70-\u0e00\u0e2f\u0e3b-\u0e3f\u0e4f\u0e5a-\u0e80\u0e83\u0e85-\u0e86\u0e89\u0e8b-\u0e8c\u0e8e-\u0e93\u0e98\u0ea0\u0ea4\u0ea6\u0ea8-\u0ea9\u0eac\u0eaf\u0eba\u0ebe-\u0ebf\u0ec5\u0ec7\u0ece-\u0ecf\u0eda-\u0f17\u0f1a-\u0f1f\u0f2a-\u0f34\u0f36\u0f38\u0f3a-\u0f3d\u0f48\u0f6a-\u0f70\u0f85\u0f8c-\u0f8f\u0f96\u0f98\u0fae-\u0fb0\u0fb8\u0fba-\u109f\u10c6-\u10cf\u10f7-\u10ff\u1101\u1104\u1108\u110a\u110d\u1113-\u113b\u113d\u113f\u1141-\u114b\u114d\u114f\u1151-\u1153\u1156-\u1158\u115a-\u115e\u1162\u1164\u1166\u1168\u116a-\u116c\u116f-\u1171\u1174\u1176-\u119d\u119f-\u11a7\u11a9-\u11aa\u11ac-\u11ad\u11b0-\u11b6\u11b9\u11bb\u11c3-\u11ea\u11ec-\u11ef\u11f1-\u11f8\u11fa-\u1dff\u1e9c-\u1e9f\u1efa-\u1eff\u1f16-\u1f17\u1f1e-\u1f1f\u1f46-\u1f47\u1f4e-\u1f4f\u1f58\u1f5a\u1f5c\u1f5e\u1f7e-\u1f7f\u1fb5\u1fbd\u1fbf-\u1fc1\u1fc5\u1fcd-\u1fcf\u1fd4-\u1fd5\u1fdc-\u1fdf\u1fed-\u1ff1\u1ff5\u1ffd-\u20cf\u20dd-\u20e0\u20e2-\u2125\u2127-\u2129\u212c-\u212d\u212f-\u217f\u2183-\u3004\u3006\u3008-\u3020\u3030\u3036-\u3040\u3095-\u3098\u309b-\u309c\u309f-\u30a0\u30fb\u30ff-\u3104\u312d-\u4dff\u9fa6-\uabff\ud7a4-\uffff]') # noqa + +nonXmlNameFirstBMPRegexp = re.compile('[\x00-@\\[-\\^`\\{-\xbf\xd7\xf7\u0132-\u0133\u013f-\u0140\u0149\u017f\u01c4-\u01cc\u01f1-\u01f3\u01f6-\u01f9\u0218-\u024f\u02a9-\u02ba\u02c2-\u0385\u0387\u038b\u038d\u03a2\u03cf\u03d7-\u03d9\u03db\u03dd\u03df\u03e1\u03f4-\u0400\u040d\u0450\u045d\u0482-\u048f\u04c5-\u04c6\u04c9-\u04ca\u04cd-\u04cf\u04ec-\u04ed\u04f6-\u04f7\u04fa-\u0530\u0557-\u0558\u055a-\u0560\u0587-\u05cf\u05eb-\u05ef\u05f3-\u0620\u063b-\u0640\u064b-\u0670\u06b8-\u06b9\u06bf\u06cf\u06d4\u06d6-\u06e4\u06e7-\u0904\u093a-\u093c\u093e-\u0957\u0962-\u0984\u098d-\u098e\u0991-\u0992\u09a9\u09b1\u09b3-\u09b5\u09ba-\u09db\u09de\u09e2-\u09ef\u09f2-\u0a04\u0a0b-\u0a0e\u0a11-\u0a12\u0a29\u0a31\u0a34\u0a37\u0a3a-\u0a58\u0a5d\u0a5f-\u0a71\u0a75-\u0a84\u0a8c\u0a8e\u0a92\u0aa9\u0ab1\u0ab4\u0aba-\u0abc\u0abe-\u0adf\u0ae1-\u0b04\u0b0d-\u0b0e\u0b11-\u0b12\u0b29\u0b31\u0b34-\u0b35\u0b3a-\u0b3c\u0b3e-\u0b5b\u0b5e\u0b62-\u0b84\u0b8b-\u0b8d\u0b91\u0b96-\u0b98\u0b9b\u0b9d\u0ba0-\u0ba2\u0ba5-\u0ba7\u0bab-\u0bad\u0bb6\u0bba-\u0c04\u0c0d\u0c11\u0c29\u0c34\u0c3a-\u0c5f\u0c62-\u0c84\u0c8d\u0c91\u0ca9\u0cb4\u0cba-\u0cdd\u0cdf\u0ce2-\u0d04\u0d0d\u0d11\u0d29\u0d3a-\u0d5f\u0d62-\u0e00\u0e2f\u0e31\u0e34-\u0e3f\u0e46-\u0e80\u0e83\u0e85-\u0e86\u0e89\u0e8b-\u0e8c\u0e8e-\u0e93\u0e98\u0ea0\u0ea4\u0ea6\u0ea8-\u0ea9\u0eac\u0eaf\u0eb1\u0eb4-\u0ebc\u0ebe-\u0ebf\u0ec5-\u0f3f\u0f48\u0f6a-\u109f\u10c6-\u10cf\u10f7-\u10ff\u1101\u1104\u1108\u110a\u110d\u1113-\u113b\u113d\u113f\u1141-\u114b\u114d\u114f\u1151-\u1153\u1156-\u1158\u115a-\u115e\u1162\u1164\u1166\u1168\u116a-\u116c\u116f-\u1171\u1174\u1176-\u119d\u119f-\u11a7\u11a9-\u11aa\u11ac-\u11ad\u11b0-\u11b6\u11b9\u11bb\u11c3-\u11ea\u11ec-\u11ef\u11f1-\u11f8\u11fa-\u1dff\u1e9c-\u1e9f\u1efa-\u1eff\u1f16-\u1f17\u1f1e-\u1f1f\u1f46-\u1f47\u1f4e-\u1f4f\u1f58\u1f5a\u1f5c\u1f5e\u1f7e-\u1f7f\u1fb5\u1fbd\u1fbf-\u1fc1\u1fc5\u1fcd-\u1fcf\u1fd4-\u1fd5\u1fdc-\u1fdf\u1fed-\u1ff1\u1ff5\u1ffd-\u2125\u2127-\u2129\u212c-\u212d\u212f-\u217f\u2183-\u3006\u3008-\u3020\u302a-\u3040\u3095-\u30a0\u30fb-\u3104\u312d-\u4dff\u9fa6-\uabff\ud7a4-\uffff]') # noqa + +# Simpler things +nonPubidCharRegexp = re.compile("[^\x20\x0D\x0Aa-zA-Z0-9\\-'()+,./:=?;!*#@$_%]") + + +class InfosetFilter(object): + replacementRegexp = re.compile(r"U[\dA-F]{5,5}") + + def __init__(self, + dropXmlnsLocalName=False, + dropXmlnsAttrNs=False, + preventDoubleDashComments=False, + preventDashAtCommentEnd=False, + replaceFormFeedCharacters=True, + preventSingleQuotePubid=False): + + self.dropXmlnsLocalName = dropXmlnsLocalName + self.dropXmlnsAttrNs = dropXmlnsAttrNs + + self.preventDoubleDashComments = preventDoubleDashComments + self.preventDashAtCommentEnd = preventDashAtCommentEnd + + self.replaceFormFeedCharacters = replaceFormFeedCharacters + + self.preventSingleQuotePubid = preventSingleQuotePubid + + self.replaceCache = {} + + def coerceAttribute(self, name, namespace=None): + if self.dropXmlnsLocalName and name.startswith("xmlns:"): + warnings.warn("Attributes cannot begin with xmlns", DataLossWarning) + return None + elif (self.dropXmlnsAttrNs and + namespace == "http://www.w3.org/2000/xmlns/"): + warnings.warn("Attributes cannot be in the xml namespace", DataLossWarning) + return None + else: + return self.toXmlName(name) + + def coerceElement(self, name): + return self.toXmlName(name) + + def coerceComment(self, data): + if self.preventDoubleDashComments: + while "--" in data: + warnings.warn("Comments cannot contain adjacent dashes", DataLossWarning) + data = data.replace("--", "- -") + if data.endswith("-"): + warnings.warn("Comments cannot end in a dash", DataLossWarning) + data += " " + return data + + def coerceCharacters(self, data): + if self.replaceFormFeedCharacters: + for _ in range(data.count("\x0C")): + warnings.warn("Text cannot contain U+000C", DataLossWarning) + data = data.replace("\x0C", " ") + # Other non-xml characters + return data + + def coercePubid(self, data): + dataOutput = data + for char in nonPubidCharRegexp.findall(data): + warnings.warn("Coercing non-XML pubid", DataLossWarning) + replacement = self.getReplacementCharacter(char) + dataOutput = dataOutput.replace(char, replacement) + if self.preventSingleQuotePubid and dataOutput.find("'") >= 0: + warnings.warn("Pubid cannot contain single quote", DataLossWarning) + dataOutput = dataOutput.replace("'", self.getReplacementCharacter("'")) + return dataOutput + + def toXmlName(self, name): + nameFirst = name[0] + nameRest = name[1:] + m = nonXmlNameFirstBMPRegexp.match(nameFirst) + if m: + warnings.warn("Coercing non-XML name", DataLossWarning) + nameFirstOutput = self.getReplacementCharacter(nameFirst) + else: + nameFirstOutput = nameFirst + + nameRestOutput = nameRest + replaceChars = set(nonXmlNameBMPRegexp.findall(nameRest)) + for char in replaceChars: + warnings.warn("Coercing non-XML name", DataLossWarning) + replacement = self.getReplacementCharacter(char) + nameRestOutput = nameRestOutput.replace(char, replacement) + return nameFirstOutput + nameRestOutput + + def getReplacementCharacter(self, char): + if char in self.replaceCache: + replacement = self.replaceCache[char] + else: + replacement = self.escapeChar(char) + return replacement + + def fromXmlName(self, name): + for item in set(self.replacementRegexp.findall(name)): + name = name.replace(item, self.unescapeChar(item)) + return name + + def escapeChar(self, char): + replacement = "U%05X" % ord(char) + self.replaceCache[char] = replacement + return replacement + + def unescapeChar(self, charcode): + return chr(int(charcode[1:], 16)) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_inputstream.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_inputstream.py new file mode 100644 index 0000000..a65e55f --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_inputstream.py @@ -0,0 +1,923 @@ +from __future__ import absolute_import, division, unicode_literals + +from pip._vendor.six import text_type, binary_type +from pip._vendor.six.moves import http_client, urllib + +import codecs +import re + +from pip._vendor import webencodings + +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]) +asciiUppercaseBytes = frozenset([item.encode("ascii") for item in asciiUppercase]) +spacesAngleBrackets = spaceCharactersBytes | frozenset([b">", b"<"]) + + +invalid_unicode_no_surrogate = "[\u0001-\u0008\u000B\u000E-\u001F\u007F-\u009F\uFDD0-\uFDEF\uFFFE\uFFFF\U0001FFFE\U0001FFFF\U0002FFFE\U0002FFFF\U0003FFFE\U0003FFFF\U0004FFFE\U0004FFFF\U0005FFFE\U0005FFFF\U0006FFFE\U0006FFFF\U0007FFFE\U0007FFFF\U0008FFFE\U0008FFFF\U0009FFFE\U0009FFFF\U000AFFFE\U000AFFFF\U000BFFFE\U000BFFFF\U000CFFFE\U000CFFFF\U000DFFFE\U000DFFFF\U000EFFFE\U000EFFFF\U000FFFFE\U000FFFFF\U0010FFFE\U0010FFFF]" # noqa + +if _utils.supports_lone_surrogates: + # Use one extra step of indirection and create surrogates with + # eval. Not using this indirection would introduce an illegal + # unicode literal on platforms not supporting such lone + # surrogates. + assert invalid_unicode_no_surrogate[-1] == "]" and invalid_unicode_no_surrogate.count("]") == 1 + invalid_unicode_re = re.compile(invalid_unicode_no_surrogate[:-1] + + eval('"\\uD800-\\uDFFF"') + # pylint:disable=eval-used + "]") +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]) + +ascii_punctuation_re = re.compile("[\u0009-\u000D\u0020-\u002F\u003A-\u0040\u005C\u005B-\u0060\u007B-\u007E]") + +# Cache for charsUntil() +charsUntilRegEx = {} + + +class BufferedStream(object): + """Buffering for streams that do not have buffering of their own + + The buffer is implemented as a list of chunks on the assumption that + joining many strings will be slow since it is O(n**2) + """ + + def __init__(self, stream): + self.stream = stream + self.buffer = [] + self.position = [-1, 0] # chunk number, offset + + def tell(self): + pos = 0 + for chunk in self.buffer[:self.position[0]]: + pos += len(chunk) + pos += self.position[1] + return pos + + def seek(self, pos): + assert pos <= self._bufferedBytes() + offset = pos + i = 0 + while len(self.buffer[i]) < offset: + offset -= len(self.buffer[i]) + i += 1 + self.position = [i, offset] + + def read(self, bytes): + if not self.buffer: + return self._readStream(bytes) + elif (self.position[0] == len(self.buffer) and + self.position[1] == len(self.buffer[-1])): + return self._readStream(bytes) + else: + return self._readFromBuffer(bytes) + + def _bufferedBytes(self): + return sum([len(item) for item in self.buffer]) + + def _readStream(self, bytes): + data = self.stream.read(bytes) + self.buffer.append(data) + self.position[0] += 1 + self.position[1] = len(data) + return data + + def _readFromBuffer(self, bytes): + remainingBytes = bytes + rv = [] + bufferIndex = self.position[0] + bufferOffset = self.position[1] + while bufferIndex < len(self.buffer) and remainingBytes != 0: + assert remainingBytes > 0 + bufferedData = self.buffer[bufferIndex] + + if remainingBytes <= len(bufferedData) - bufferOffset: + bytesToRead = remainingBytes + self.position = [bufferIndex, bufferOffset + bytesToRead] + else: + bytesToRead = len(bufferedData) - bufferOffset + self.position = [bufferIndex, len(bufferedData)] + bufferIndex += 1 + rv.append(bufferedData[bufferOffset:bufferOffset + bytesToRead]) + remainingBytes -= bytesToRead + + bufferOffset = 0 + + if remainingBytes: + rv.append(self._readStream(remainingBytes)) + + return b"".join(rv) + + +def HTMLInputStream(source, **kwargs): + # Work around Python bug #20007: read(0) closes the connection. + # http://bugs.python.org/issue20007 + if (isinstance(source, http_client.HTTPResponse) or + # Also check for addinfourl wrapping HTTPResponse + (isinstance(source, urllib.response.addbase) and + isinstance(source.fp, http_client.HTTPResponse))): + isUnicode = False + elif hasattr(source, "read"): + isUnicode = isinstance(source.read(0), text_type) + else: + isUnicode = isinstance(source, text_type) + + if isUnicode: + encodings = [x for x in kwargs if x.endswith("_encoding")] + if encodings: + raise TypeError("Cannot set an encoding with a unicode input, set %r" % encodings) + + return HTMLUnicodeInputStream(source, **kwargs) + else: + return HTMLBinaryInputStream(source, **kwargs) + + +class HTMLUnicodeInputStream(object): + """Provides a unicode stream of characters to the HTMLTokenizer. + + This class takes care of character encoding and removing or replacing + incorrect byte-sequences and also provides column and line tracking. + + """ + + _defaultChunkSize = 10240 + + def __init__(self, source): + """Initialises the HTMLInputStream. + + HTMLInputStream(source, [encoding]) -> Normalized stream from source + for use by html5lib. + + source can be either a file-object, local filename or a string. + + The optional encoding parameter must be a string that indicates + the encoding. If specified, that encoding will be used, + regardless of any BOM or later declaration (such as in a meta + element) + + """ + + if not _utils.supports_lone_surrogates: + # Such platforms will have already checked for such + # surrogate errors, so no need to do this checking. + self.reportCharacterErrors = None + elif len("\U0010FFFF") == 1: + self.reportCharacterErrors = self.characterErrorsUCS4 + else: + self.reportCharacterErrors = self.characterErrorsUCS2 + + # List of where new lines occur + self.newLines = [0] + + self.charEncoding = (lookupEncoding("utf-8"), "certain") + self.dataStream = self.openStream(source) + + self.reset() + + def reset(self): + self.chunk = "" + self.chunkSize = 0 + self.chunkOffset = 0 + self.errors = [] + + # number of (complete) lines in previous chunks + self.prevNumLines = 0 + # number of columns in the last line of the previous chunk + self.prevNumCols = 0 + + # Deal with CR LF and surrogates split over chunk boundaries + self._bufferedCharacter = None + + def openStream(self, source): + """Produces a file object from source. + + source can be either a file object, local filename or a string. + + """ + # Already a file object + if hasattr(source, 'read'): + stream = source + else: + stream = StringIO(source) + + return stream + + def _position(self, offset): + chunk = self.chunk + nLines = chunk.count('\n', 0, offset) + positionLine = self.prevNumLines + nLines + lastLinePos = chunk.rfind('\n', 0, offset) + if lastLinePos == -1: + positionColumn = self.prevNumCols + offset + else: + positionColumn = offset - (lastLinePos + 1) + return (positionLine, positionColumn) + + def position(self): + """Returns (line, col) of the current position in the stream.""" + line, col = self._position(self.chunkOffset) + return (line + 1, col) + + def char(self): + """ Read one character from the stream or queue if available. Return + EOF when EOF is reached. + """ + # Read a new chunk from the input stream if necessary + if self.chunkOffset >= self.chunkSize: + if not self.readChunk(): + return EOF + + chunkOffset = self.chunkOffset + char = self.chunk[chunkOffset] + self.chunkOffset = chunkOffset + 1 + + return char + + def readChunk(self, chunkSize=None): + if chunkSize is None: + chunkSize = self._defaultChunkSize + + self.prevNumLines, self.prevNumCols = self._position(self.chunkSize) + + self.chunk = "" + self.chunkSize = 0 + self.chunkOffset = 0 + + data = self.dataStream.read(chunkSize) + + # Deal with CR LF and surrogates broken across chunks + if self._bufferedCharacter: + data = self._bufferedCharacter + data + self._bufferedCharacter = None + elif not data: + # We have no more data, bye-bye stream + return False + + if len(data) > 1: + lastv = ord(data[-1]) + if lastv == 0x0D or 0xD800 <= lastv <= 0xDBFF: + self._bufferedCharacter = data[-1] + data = data[:-1] + + if self.reportCharacterErrors: + self.reportCharacterErrors(data) + + # Replace invalid characters + data = data.replace("\r\n", "\n") + data = data.replace("\r", "\n") + + self.chunk = data + self.chunkSize = len(data) + + return True + + def characterErrorsUCS4(self, data): + for _ in range(len(invalid_unicode_re.findall(data))): + self.errors.append("invalid-codepoint") + + def characterErrorsUCS2(self, data): + # Someone picked the wrong compile option + # You lose + skip = False + for match in invalid_unicode_re.finditer(data): + if skip: + continue + codepoint = ord(match.group()) + pos = match.start() + # Pretty sure there should be endianness issues here + if _utils.isSurrogatePair(data[pos:pos + 2]): + # We have a surrogate pair! + char_val = _utils.surrogatePairToCodepoint(data[pos:pos + 2]) + if char_val in non_bmp_invalid_codepoints: + self.errors.append("invalid-codepoint") + skip = True + elif (codepoint >= 0xD800 and codepoint <= 0xDFFF and + pos == len(data) - 1): + self.errors.append("invalid-codepoint") + else: + skip = False + self.errors.append("invalid-codepoint") + + def charsUntil(self, characters, opposite=False): + """ Returns a string of characters from the stream up to but not + including any character in 'characters' or EOF. 'characters' must be + a container that supports the 'in' method and iteration over its + characters. + """ + + # Use a cache of regexps to find the required characters + try: + chars = charsUntilRegEx[(characters, opposite)] + except KeyError: + if __debug__: + for c in characters: + assert(ord(c) < 128) + regex = "".join(["\\x%02x" % ord(c) for c in characters]) + if not opposite: + regex = "^%s" % regex + chars = charsUntilRegEx[(characters, opposite)] = re.compile("[%s]+" % regex) + + rv = [] + + while True: + # Find the longest matching prefix + m = chars.match(self.chunk, self.chunkOffset) + if m is None: + # If nothing matched, and it wasn't because we ran out of chunk, + # then stop + if self.chunkOffset != self.chunkSize: + break + else: + end = m.end() + # If not the whole chunk matched, return everything + # up to the part that didn't match + if end != self.chunkSize: + rv.append(self.chunk[self.chunkOffset:end]) + self.chunkOffset = end + break + # If the whole remainder of the chunk matched, + # use it all and read the next chunk + rv.append(self.chunk[self.chunkOffset:]) + if not self.readChunk(): + # Reached EOF + break + + r = "".join(rv) + return r + + 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 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 + # called char and charsUntil. + # So, just prepend the ungotten character onto the current + # chunk: + self.chunk = char + self.chunk + self.chunkSize += 1 + else: + self.chunkOffset -= 1 + assert self.chunk[self.chunkOffset] == char + + +class HTMLBinaryInputStream(HTMLUnicodeInputStream): + """Provides a unicode stream of characters to the HTMLTokenizer. + + This class takes care of character encoding and removing or replacing + incorrect byte-sequences and also provides column and line tracking. + + """ + + def __init__(self, source, override_encoding=None, transport_encoding=None, + same_origin_parent_encoding=None, likely_encoding=None, + default_encoding="windows-1252", useChardet=True): + """Initialises the HTMLInputStream. + + HTMLInputStream(source, [encoding]) -> Normalized stream from source + for use by html5lib. + + source can be either a file-object, local filename or a string. + + The optional encoding parameter must be a string that indicates + the encoding. If specified, that encoding will be used, + regardless of any BOM or later declaration (such as in a meta + element) + + """ + # Raw Stream - for unicode objects this will encode to utf-8 and set + # self.charEncoding as appropriate + self.rawStream = self.openStream(source) + + HTMLUnicodeInputStream.__init__(self, self.rawStream) + + # Encoding Information + # Number of bytes to use when looking for a meta element with + # encoding information + self.numBytesMeta = 1024 + # Number of bytes to use when using detecting encoding using chardet + self.numBytesChardet = 100 + # Things from args + self.override_encoding = override_encoding + self.transport_encoding = transport_encoding + self.same_origin_parent_encoding = same_origin_parent_encoding + self.likely_encoding = likely_encoding + self.default_encoding = default_encoding + + # Determine encoding + self.charEncoding = self.determineEncoding(useChardet) + assert self.charEncoding[0] is not None + + # Call superclass + self.reset() + + def reset(self): + self.dataStream = self.charEncoding[0].codec_info.streamreader(self.rawStream, 'replace') + HTMLUnicodeInputStream.reset(self) + + def openStream(self, source): + """Produces a file object from source. + + source can be either a file object, local filename or a string. + + """ + # Already a file object + if hasattr(source, 'read'): + stream = source + else: + stream = BytesIO(source) + + try: + stream.seek(stream.tell()) + except: # pylint:disable=bare-except + stream = BufferedStream(stream) + + return stream + + def determineEncoding(self, chardet=True): + # BOMs take precedence over everything + # This will also read past the BOM if present + charEncoding = self.detectBOM(), "certain" + if charEncoding[0] is not None: + return charEncoding + + # If we've been overriden, we've been overriden + charEncoding = lookupEncoding(self.override_encoding), "certain" + if charEncoding[0] is not None: + return charEncoding + + # Now check the transport layer + charEncoding = lookupEncoding(self.transport_encoding), "certain" + if charEncoding[0] is not None: + return charEncoding + + # Look for meta elements with encoding information + charEncoding = self.detectEncodingMeta(), "tentative" + if charEncoding[0] is not None: + return charEncoding + + # Parent document encoding + charEncoding = lookupEncoding(self.same_origin_parent_encoding), "tentative" + if charEncoding[0] is not None and not charEncoding[0].name.startswith("utf-16"): + return charEncoding + + # "likely" encoding + charEncoding = lookupEncoding(self.likely_encoding), "tentative" + if charEncoding[0] is not None: + return charEncoding + + # Guess with chardet, if available + if chardet: + try: + from pip._vendor.chardet.universaldetector import UniversalDetector + except ImportError: + pass + else: + buffers = [] + detector = UniversalDetector() + while not detector.done: + buffer = self.rawStream.read(self.numBytesChardet) + assert isinstance(buffer, bytes) + if not buffer: + break + buffers.append(buffer) + detector.feed(buffer) + detector.close() + encoding = lookupEncoding(detector.result['encoding']) + self.rawStream.seek(0) + if encoding is not None: + return encoding, "tentative" + + # Try the default encoding + charEncoding = lookupEncoding(self.default_encoding), "tentative" + if charEncoding[0] is not None: + return charEncoding + + # Fallback to html5lib's default if even that hasn't worked + return lookupEncoding("windows-1252"), "tentative" + + def changeEncoding(self, newEncoding): + assert self.charEncoding[1] != "certain" + newEncoding = lookupEncoding(newEncoding) + if newEncoding is None: + return + if newEncoding.name in ("utf-16be", "utf-16le"): + newEncoding = lookupEncoding("utf-8") + assert newEncoding is not None + elif newEncoding == self.charEncoding[0]: + self.charEncoding = (self.charEncoding[0], "certain") + else: + self.rawStream.seek(0) + self.charEncoding = (newEncoding, "certain") + self.reset() + raise _ReparseException("Encoding changed from %s to %s" % (self.charEncoding[0], newEncoding)) + + def detectBOM(self): + """Attempts to detect at BOM at the start of the stream. If + an encoding can be determined from the BOM return the name of the + encoding otherwise return None""" + bomDict = { + codecs.BOM_UTF8: 'utf-8', + codecs.BOM_UTF16_LE: 'utf-16le', codecs.BOM_UTF16_BE: 'utf-16be', + codecs.BOM_UTF32_LE: 'utf-32le', codecs.BOM_UTF32_BE: 'utf-32be' + } + + # Go to beginning of file and read in 4 bytes + string = self.rawStream.read(4) + assert isinstance(string, bytes) + + # Try detecting the BOM using bytes from the string + encoding = bomDict.get(string[:3]) # UTF-8 + seek = 3 + if not encoding: + # Need to detect UTF-32 before UTF-16 + encoding = bomDict.get(string) # UTF-32 + seek = 4 + if not encoding: + encoding = bomDict.get(string[:2]) # UTF-16 + seek = 2 + + # Set the read position past the BOM if one was found, otherwise + # set it to the start of the stream + if encoding: + self.rawStream.seek(seek) + return lookupEncoding(encoding) + else: + self.rawStream.seek(0) + return None + + def detectEncodingMeta(self): + """Report the encoding declared by the meta element + """ + buffer = self.rawStream.read(self.numBytesMeta) + assert isinstance(buffer, bytes) + parser = EncodingParser(buffer) + self.rawStream.seek(0) + encoding = parser.getEncoding() + + if encoding is not None and encoding.name in ("utf-16be", "utf-16le"): + encoding = lookupEncoding("utf-8") + + return encoding + + +class EncodingBytes(bytes): + """String-like object with an associated position and various extra methods + If the position is ever greater than the string length then an exception is + raised""" + def __new__(self, value): + assert isinstance(value, bytes) + return bytes.__new__(self, value.lower()) + + def __init__(self, value): + # pylint:disable=unused-argument + self._position = -1 + + def __iter__(self): + return self + + def __next__(self): + p = self._position = self._position + 1 + if p >= len(self): + raise StopIteration + elif p < 0: + raise TypeError + return self[p:p + 1] + + def next(self): + # Py2 compat + return self.__next__() + + def previous(self): + p = self._position + if p >= len(self): + raise StopIteration + elif p < 0: + raise TypeError + self._position = p = p - 1 + return self[p:p + 1] + + def setPosition(self, position): + if self._position >= len(self): + raise StopIteration + self._position = position + + def getPosition(self): + if self._position >= len(self): + raise StopIteration + if self._position >= 0: + return self._position + else: + return None + + position = property(getPosition, setPosition) + + def getCurrentByte(self): + return self[self.position:self.position + 1] + + currentByte = property(getCurrentByte) + + def skip(self, chars=spaceCharactersBytes): + """Skip past a list of characters""" + p = self.position # use property for the error-checking + while p < len(self): + c = self[p:p + 1] + if c not in chars: + self._position = p + return c + p += 1 + self._position = p + return None + + def skipUntil(self, chars): + p = self.position + while p < len(self): + c = self[p:p + 1] + if c in chars: + self._position = p + return c + p += 1 + self._position = p + return None + + def matchBytes(self, 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) + if rv: + self.position += len(bytes) + return rv + + 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: + raise StopIteration + + +class EncodingParser(object): + """Mini parser for detecting character encoding from meta elements""" + + def __init__(self, data): + """string - the data to work on for encoding detection""" + self.data = EncodingBytes(data) + self.encoding = None + + def getEncoding(self): + methodDispatch = ( + (b"<!--", self.handleComment), + (b"<meta", self.handleMeta), + (b"</", self.handlePossibleEndTag), + (b"<!", self.handleOther), + (b"<?", self.handleOther), + (b"<", self.handlePossibleStartTag)) + for _ in self.data: + keepParsing = True + for key, method in methodDispatch: + if self.data.matchBytes(key): + try: + keepParsing = method() + break + except StopIteration: + keepParsing = False + break + if not keepParsing: + break + + return self.encoding + + def handleComment(self): + """Skip over comments""" + return self.data.jumpTo(b"-->") + + def handleMeta(self): + if self.data.currentByte not in spaceCharactersBytes: + # if we have <meta not followed by a space so just keep going + return True + # We have a valid meta element we want to search for attributes + hasPragma = False + pendingEncoding = None + while True: + # Try to find the next attribute after the current position + attr = self.getAttribute() + if attr is None: + return True + else: + if attr[0] == b"http-equiv": + hasPragma = attr[1] == b"content-type" + if hasPragma and pendingEncoding is not None: + self.encoding = pendingEncoding + return False + elif attr[0] == b"charset": + tentativeEncoding = attr[1] + codec = lookupEncoding(tentativeEncoding) + if codec is not None: + self.encoding = codec + return False + elif attr[0] == b"content": + contentParser = ContentAttrParser(EncodingBytes(attr[1])) + tentativeEncoding = contentParser.parse() + if tentativeEncoding is not None: + codec = lookupEncoding(tentativeEncoding) + if codec is not None: + if hasPragma: + self.encoding = codec + return False + else: + pendingEncoding = codec + + def handlePossibleStartTag(self): + return self.handlePossibleTag(False) + + def handlePossibleEndTag(self): + next(self.data) + return self.handlePossibleTag(True) + + def handlePossibleTag(self, endTag): + data = self.data + if data.currentByte not in asciiLettersBytes: + # If the next byte is not an ascii letter either ignore this + # fragment (possible start tag case) or treat it according to + # handleOther + if endTag: + data.previous() + self.handleOther() + return True + + c = data.skipUntil(spacesAngleBrackets) + if c == b"<": + # return to the first step in the overall "two step" algorithm + # reprocessing the < byte + data.previous() + else: + # Read all attributes + attr = self.getAttribute() + while attr is not None: + attr = self.getAttribute() + return True + + def handleOther(self): + return self.data.jumpTo(b">") + + def getAttribute(self): + """Return a name,value pair for the next attribute in the stream, + if one is found, or None""" + data = self.data + # Step 1 (skip chars) + c = data.skip(spaceCharactersBytes | frozenset([b"/"])) + assert c is None or len(c) == 1 + # Step 2 + if c in (b">", None): + return None + # Step 3 + attrName = [] + attrValue = [] + # Step 4 attribute name + while True: + if c == b"=" and attrName: + break + elif c in spaceCharactersBytes: + # Step 6! + c = data.skip() + break + elif c in (b"/", b">"): + return b"".join(attrName), b"" + elif c in asciiUppercaseBytes: + attrName.append(c.lower()) + elif c is None: + return None + else: + attrName.append(c) + # Step 5 + c = next(data) + # Step 7 + if c != b"=": + data.previous() + return b"".join(attrName), b"" + # Step 8 + next(data) + # Step 9 + c = data.skip() + # Step 10 + if c in (b"'", b'"'): + # 10.1 + quoteChar = c + while True: + # 10.2 + c = next(data) + # 10.3 + if c == quoteChar: + next(data) + return b"".join(attrName), b"".join(attrValue) + # 10.4 + elif c in asciiUppercaseBytes: + attrValue.append(c.lower()) + # 10.5 + else: + attrValue.append(c) + elif c == b">": + return b"".join(attrName), b"" + elif c in asciiUppercaseBytes: + attrValue.append(c.lower()) + elif c is None: + return None + else: + attrValue.append(c) + # Step 11 + while True: + c = next(data) + if c in spacesAngleBrackets: + return b"".join(attrName), b"".join(attrValue) + elif c in asciiUppercaseBytes: + attrValue.append(c.lower()) + elif c is None: + return None + else: + attrValue.append(c) + + +class ContentAttrParser(object): + def __init__(self, data): + assert isinstance(data, bytes) + self.data = data + + def parse(self): + try: + # Check if the attr name is charset + # otherwise return + self.data.jumpTo(b"charset") + self.data.position += 1 + self.data.skip() + if not self.data.currentByte == b"=": + # If there is no = sign keep looking for attrs + return None + self.data.position += 1 + self.data.skip() + # Look for an encoding between matching quote marks + if self.data.currentByte in (b'"', b"'"): + quoteMark = self.data.currentByte + self.data.position += 1 + oldPosition = self.data.position + if self.data.jumpTo(quoteMark): + return self.data[oldPosition:self.data.position] + else: + return None + else: + # Unquoted value + oldPosition = self.data.position + try: + self.data.skipUntil(spaceCharactersBytes) + return self.data[oldPosition:self.data.position] + except StopIteration: + # Return the whole remaining value + return self.data[oldPosition:] + except StopIteration: + return None + + +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): + try: + encoding = encoding.decode("ascii") + except UnicodeDecodeError: + return None + + if encoding is not None: + try: + return webencodings.lookup(encoding) + except AttributeError: + return None + else: + return None diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_tokenizer.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_tokenizer.py new file mode 100644 index 0000000..178f6e7 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_tokenizer.py @@ -0,0 +1,1721 @@ +from __future__ import absolute_import, division, unicode_literals + +from pip._vendor.six import unichr as chr + +from collections import deque + +from .constants import spaceCharacters +from .constants import entities +from .constants import asciiLetters, asciiUpper2Lower +from .constants import digits, hexDigits, EOF +from .constants import tokenTypes, tagTokenTypes +from .constants import replacementCharacters + +from ._inputstream import HTMLInputStream + +from ._trie import Trie + +entitiesTrie = Trie(entities) + + +class HTMLTokenizer(object): + """ This class takes care of tokenizing HTML. + + * self.currentToken + Holds the token that is currently being processed. + + * self.state + Holds a reference to the method to be invoked... XXX + + * self.stream + Points to HTMLInputStream object. + """ + + def __init__(self, stream, parser=None, **kwargs): + + self.stream = HTMLInputStream(stream, **kwargs) + self.parser = parser + + # Setup the initial tokenizer state + self.escapeFlag = False + self.lastFourChars = [] + self.state = self.dataState + self.escape = False + + # The current token being created + self.currentToken = None + super(HTMLTokenizer, self).__init__() + + def __iter__(self): + """ This is where the magic happens. + + We do our usually processing through the states and when we have a token + to return we yield the token which pauses processing until the next token + is requested. + """ + self.tokenQueue = deque([]) + # Start processing. When EOF is reached self.state will return False + # instead of True and the loop will terminate. + while self.state(): + while self.stream.errors: + yield {"type": tokenTypes["ParseError"], "data": self.stream.errors.pop(0)} + while self.tokenQueue: + yield self.tokenQueue.popleft() + + def consumeNumberEntity(self, isHex): + """This function returns either U+FFFD or the character based on the + decimal or hexadecimal representation. It also discards ";" if present. + If not present self.tokenQueue.append({"type": tokenTypes["ParseError"]}) is invoked. + """ + + allowed = digits + radix = 10 + if isHex: + allowed = hexDigits + radix = 16 + + charStack = [] + + # Consume all the characters that are in range while making sure we + # don't hit an EOF. + c = self.stream.char() + while c in allowed and c is not EOF: + charStack.append(c) + c = self.stream.char() + + # Convert the set of characters consumed to an int. + charAsInt = int("".join(charStack), radix) + + # Certain characters get replaced with others + if charAsInt in replacementCharacters: + char = replacementCharacters[charAsInt] + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "illegal-codepoint-for-numeric-entity", + "datavars": {"charAsInt": charAsInt}}) + elif ((0xD800 <= charAsInt <= 0xDFFF) or + (charAsInt > 0x10FFFF)): + char = "\uFFFD" + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "illegal-codepoint-for-numeric-entity", + "datavars": {"charAsInt": charAsInt}}) + else: + # Should speed up this check somehow (e.g. move the set to a constant) + if ((0x0001 <= charAsInt <= 0x0008) or + (0x000E <= charAsInt <= 0x001F) or + (0x007F <= charAsInt <= 0x009F) or + (0xFDD0 <= charAsInt <= 0xFDEF) or + charAsInt in frozenset([0x000B, 0xFFFE, 0xFFFF, 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])): + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": + "illegal-codepoint-for-numeric-entity", + "datavars": {"charAsInt": charAsInt}}) + try: + # Try/except needed as UCS-2 Python builds' unichar only works + # within the BMP. + char = chr(charAsInt) + except ValueError: + v = charAsInt - 0x10000 + char = chr(0xD800 | (v >> 10)) + chr(0xDC00 | (v & 0x3FF)) + + # Discard the ; if present. Otherwise, put it back on the queue and + # invoke parseError on parser. + if c != ";": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "numeric-entity-without-semicolon"}) + self.stream.unget(c) + + return char + + def consumeEntity(self, allowedChar=None, fromAttribute=False): + # Initialise to the default output for when no entity is matched + output = "&" + + charStack = [self.stream.char()] + if (charStack[0] in spaceCharacters or charStack[0] in (EOF, "<", "&") or + (allowedChar is not None and allowedChar == charStack[0])): + self.stream.unget(charStack[0]) + + elif charStack[0] == "#": + # Read the next character to see if it's hex or decimal + hex = False + charStack.append(self.stream.char()) + if charStack[-1] in ("x", "X"): + hex = True + charStack.append(self.stream.char()) + + # charStack[-1] should be the first digit + if (hex and charStack[-1] in hexDigits) \ + or (not hex and charStack[-1] in digits): + # At least one digit found, so consume the whole number + self.stream.unget(charStack[-1]) + output = self.consumeNumberEntity(hex) + else: + # No digits found + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "expected-numeric-entity"}) + self.stream.unget(charStack.pop()) + output = "&" + "".join(charStack) + + else: + # At this point in the process might have named entity. Entities + # are stored in the global variable "entities". + # + # Consume characters and compare to these to a substring of the + # entity names in the list until the substring no longer matches. + while (charStack[-1] is not EOF): + if not entitiesTrie.has_keys_with_prefix("".join(charStack)): + break + charStack.append(self.stream.char()) + + # At this point we have a string that starts with some characters + # that may match an entity + # Try to find the longest entity the string will match to take care + # of ¬i for instance. + try: + entityName = entitiesTrie.longest_prefix("".join(charStack[:-1])) + entityLength = len(entityName) + except KeyError: + entityName = None + + if entityName is not None: + if entityName[-1] != ";": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "named-entity-without-semicolon"}) + if (entityName[-1] != ";" and fromAttribute and + (charStack[entityLength] in asciiLetters or + charStack[entityLength] in digits or + charStack[entityLength] == "=")): + self.stream.unget(charStack.pop()) + output = "&" + "".join(charStack) + else: + output = entities[entityName] + self.stream.unget(charStack.pop()) + output += "".join(charStack[entityLength:]) + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-named-entity"}) + self.stream.unget(charStack.pop()) + output = "&" + "".join(charStack) + + if fromAttribute: + self.currentToken["data"][-1][1] += output + else: + if output in spaceCharacters: + tokenType = "SpaceCharacters" + else: + tokenType = "Characters" + self.tokenQueue.append({"type": tokenTypes[tokenType], "data": output}) + + def processEntityInAttribute(self, allowedChar): + """This method replaces the need for "entityInAttributeValueState". + """ + self.consumeEntity(allowedChar=allowedChar, fromAttribute=True) + + def emitCurrentToken(self): + """This method is a generic handler for emitting the tags. It also sets + the state to "data" because that's what's needed after a token has been + emitted. + """ + token = self.currentToken + # Add token to the queue to be yielded + if (token["type"] in tagTokenTypes): + token["name"] = token["name"].translate(asciiUpper2Lower) + if token["type"] == tokenTypes["EndTag"]: + if token["data"]: + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "attributes-in-end-tag"}) + if token["selfClosing"]: + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "self-closing-flag-on-end-tag"}) + self.tokenQueue.append(token) + self.state = self.dataState + + # Below are the various tokenizer states worked out. + def dataState(self): + data = self.stream.char() + if data == "&": + self.state = self.entityDataState + elif data == "<": + self.state = self.tagOpenState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\u0000"}) + elif data is EOF: + # Tokenization ends. + return False + elif data in spaceCharacters: + # Directly after emitting a token you switch back to the "data + # state". At that point spaceCharacters are important so they are + # emitted separately. + self.tokenQueue.append({"type": tokenTypes["SpaceCharacters"], "data": + data + self.stream.charsUntil(spaceCharacters, True)}) + # No need to update lastFourChars here, since the first space will + # have already been appended to lastFourChars and will have broken + # any <!-- or --> sequences + else: + chars = self.stream.charsUntil(("&", "<", "\u0000")) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + chars}) + return True + + def entityDataState(self): + self.consumeEntity() + self.state = self.dataState + return True + + def rcdataState(self): + data = self.stream.char() + if data == "&": + self.state = self.characterReferenceInRcdata + elif data == "<": + self.state = self.rcdataLessThanSignState + elif data == EOF: + # Tokenization ends. + return False + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + elif data in spaceCharacters: + # Directly after emitting a token you switch back to the "data + # state". At that point spaceCharacters are important so they are + # emitted separately. + self.tokenQueue.append({"type": tokenTypes["SpaceCharacters"], "data": + data + self.stream.charsUntil(spaceCharacters, True)}) + # No need to update lastFourChars here, since the first space will + # have already been appended to lastFourChars and will have broken + # any <!-- or --> sequences + else: + chars = self.stream.charsUntil(("&", "<", "\u0000")) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + chars}) + return True + + def characterReferenceInRcdata(self): + self.consumeEntity() + self.state = self.rcdataState + return True + + def rawtextState(self): + data = self.stream.char() + if data == "<": + self.state = self.rawtextLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + elif data == EOF: + # Tokenization ends. + return False + else: + chars = self.stream.charsUntil(("<", "\u0000")) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + chars}) + return True + + def scriptDataState(self): + data = self.stream.char() + if data == "<": + self.state = self.scriptDataLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + elif data == EOF: + # Tokenization ends. + return False + else: + chars = self.stream.charsUntil(("<", "\u0000")) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + chars}) + return True + + def plaintextState(self): + data = self.stream.char() + if data == EOF: + # Tokenization ends. + return False + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + self.stream.charsUntil("\u0000")}) + return True + + def tagOpenState(self): + data = self.stream.char() + if data == "!": + self.state = self.markupDeclarationOpenState + elif data == "/": + self.state = self.closeTagOpenState + elif data in asciiLetters: + self.currentToken = {"type": tokenTypes["StartTag"], + "name": data, "data": [], + "selfClosing": False, + "selfClosingAcknowledged": False} + self.state = self.tagNameState + elif data == ">": + # XXX In theory it could be something besides a tag name. But + # do we really care? + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-tag-name-but-got-right-bracket"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<>"}) + self.state = self.dataState + elif data == "?": + # XXX In theory it could be something besides a tag name. But + # do we really care? + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-tag-name-but-got-question-mark"}) + self.stream.unget(data) + self.state = self.bogusCommentState + else: + # XXX + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-tag-name"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.stream.unget(data) + self.state = self.dataState + return True + + def closeTagOpenState(self): + data = self.stream.char() + if data in asciiLetters: + self.currentToken = {"type": tokenTypes["EndTag"], "name": data, + "data": [], "selfClosing": False} + self.state = self.tagNameState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-closing-tag-but-got-right-bracket"}) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-closing-tag-but-got-eof"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "</"}) + self.state = self.dataState + else: + # XXX data can be _'_... + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-closing-tag-but-got-char", + "datavars": {"data": data}}) + self.stream.unget(data) + self.state = self.bogusCommentState + return True + + def tagNameState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeAttributeNameState + elif data == ">": + self.emitCurrentToken() + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-tag-name"}) + self.state = self.dataState + elif data == "/": + self.state = self.selfClosingStartTagState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["name"] += "\uFFFD" + else: + self.currentToken["name"] += data + # (Don't use charsUntil here, because tag names are + # very short and it's faster to not do anything fancy) + return True + + def rcdataLessThanSignState(self): + data = self.stream.char() + if data == "/": + self.temporaryBuffer = "" + self.state = self.rcdataEndTagOpenState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.stream.unget(data) + self.state = self.rcdataState + return True + + def rcdataEndTagOpenState(self): + data = self.stream.char() + if data in asciiLetters: + self.temporaryBuffer += data + self.state = self.rcdataEndTagNameState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "</"}) + self.stream.unget(data) + self.state = self.rcdataState + return True + + def rcdataEndTagNameState(self): + appropriate = self.currentToken and self.currentToken["name"].lower() == self.temporaryBuffer.lower() + data = self.stream.char() + if data in spaceCharacters and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.beforeAttributeNameState + elif data == "/" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.selfClosingStartTagState + elif data == ">" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.emitCurrentToken() + self.state = self.dataState + elif data in asciiLetters: + self.temporaryBuffer += data + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "</" + self.temporaryBuffer}) + self.stream.unget(data) + self.state = self.rcdataState + return True + + def rawtextLessThanSignState(self): + data = self.stream.char() + if data == "/": + self.temporaryBuffer = "" + self.state = self.rawtextEndTagOpenState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.stream.unget(data) + self.state = self.rawtextState + return True + + def rawtextEndTagOpenState(self): + data = self.stream.char() + if data in asciiLetters: + self.temporaryBuffer += data + self.state = self.rawtextEndTagNameState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "</"}) + self.stream.unget(data) + self.state = self.rawtextState + return True + + def rawtextEndTagNameState(self): + appropriate = self.currentToken and self.currentToken["name"].lower() == self.temporaryBuffer.lower() + data = self.stream.char() + if data in spaceCharacters and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.beforeAttributeNameState + elif data == "/" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.selfClosingStartTagState + elif data == ">" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.emitCurrentToken() + self.state = self.dataState + elif data in asciiLetters: + self.temporaryBuffer += data + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "</" + self.temporaryBuffer}) + self.stream.unget(data) + self.state = self.rawtextState + return True + + def scriptDataLessThanSignState(self): + data = self.stream.char() + if data == "/": + self.temporaryBuffer = "" + self.state = self.scriptDataEndTagOpenState + elif data == "!": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<!"}) + self.state = self.scriptDataEscapeStartState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.stream.unget(data) + self.state = self.scriptDataState + return True + + def scriptDataEndTagOpenState(self): + data = self.stream.char() + if data in asciiLetters: + self.temporaryBuffer += data + self.state = self.scriptDataEndTagNameState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "</"}) + self.stream.unget(data) + self.state = self.scriptDataState + return True + + def scriptDataEndTagNameState(self): + appropriate = self.currentToken and self.currentToken["name"].lower() == self.temporaryBuffer.lower() + data = self.stream.char() + if data in spaceCharacters and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.beforeAttributeNameState + elif data == "/" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.selfClosingStartTagState + elif data == ">" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.emitCurrentToken() + self.state = self.dataState + elif data in asciiLetters: + self.temporaryBuffer += data + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "</" + self.temporaryBuffer}) + self.stream.unget(data) + self.state = self.scriptDataState + return True + + def scriptDataEscapeStartState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataEscapeStartDashState + else: + self.stream.unget(data) + self.state = self.scriptDataState + return True + + def scriptDataEscapeStartDashState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataEscapedDashDashState + else: + self.stream.unget(data) + self.state = self.scriptDataState + return True + + def scriptDataEscapedState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataEscapedDashState + elif data == "<": + self.state = self.scriptDataEscapedLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + elif data == EOF: + self.state = self.dataState + else: + chars = self.stream.charsUntil(("<", "-", "\u0000")) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + chars}) + return True + + def scriptDataEscapedDashState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataEscapedDashDashState + elif data == "<": + self.state = self.scriptDataEscapedLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + self.state = self.scriptDataEscapedState + elif data == EOF: + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.state = self.scriptDataEscapedState + return True + + def scriptDataEscapedDashDashState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + elif data == "<": + self.state = self.scriptDataEscapedLessThanSignState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": ">"}) + self.state = self.scriptDataState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + self.state = self.scriptDataEscapedState + elif data == EOF: + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.state = self.scriptDataEscapedState + return True + + def scriptDataEscapedLessThanSignState(self): + data = self.stream.char() + if data == "/": + self.temporaryBuffer = "" + self.state = self.scriptDataEscapedEndTagOpenState + elif data in asciiLetters: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<" + data}) + self.temporaryBuffer = data + self.state = self.scriptDataDoubleEscapeStartState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.stream.unget(data) + self.state = self.scriptDataEscapedState + return True + + def scriptDataEscapedEndTagOpenState(self): + data = self.stream.char() + if data in asciiLetters: + self.temporaryBuffer = data + self.state = self.scriptDataEscapedEndTagNameState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "</"}) + self.stream.unget(data) + self.state = self.scriptDataEscapedState + return True + + def scriptDataEscapedEndTagNameState(self): + appropriate = self.currentToken and self.currentToken["name"].lower() == self.temporaryBuffer.lower() + data = self.stream.char() + if data in spaceCharacters and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.beforeAttributeNameState + elif data == "/" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.selfClosingStartTagState + elif data == ">" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.emitCurrentToken() + self.state = self.dataState + elif data in asciiLetters: + self.temporaryBuffer += data + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "</" + self.temporaryBuffer}) + self.stream.unget(data) + self.state = self.scriptDataEscapedState + return True + + def scriptDataDoubleEscapeStartState(self): + data = self.stream.char() + if data in (spaceCharacters | frozenset(("/", ">"))): + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + if self.temporaryBuffer.lower() == "script": + self.state = self.scriptDataDoubleEscapedState + else: + self.state = self.scriptDataEscapedState + elif data in asciiLetters: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.temporaryBuffer += data + else: + self.stream.unget(data) + self.state = self.scriptDataEscapedState + return True + + def scriptDataDoubleEscapedState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataDoubleEscapedDashState + elif data == "<": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.state = self.scriptDataDoubleEscapedLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + elif data == EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-script-in-script"}) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + return True + + def scriptDataDoubleEscapedDashState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataDoubleEscapedDashDashState + elif data == "<": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.state = self.scriptDataDoubleEscapedLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + self.state = self.scriptDataDoubleEscapedState + elif data == EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-script-in-script"}) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.state = self.scriptDataDoubleEscapedState + return True + + def scriptDataDoubleEscapedDashDashState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + elif data == "<": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.state = self.scriptDataDoubleEscapedLessThanSignState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": ">"}) + self.state = self.scriptDataState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + self.state = self.scriptDataDoubleEscapedState + elif data == EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-script-in-script"}) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.state = self.scriptDataDoubleEscapedState + return True + + def scriptDataDoubleEscapedLessThanSignState(self): + data = self.stream.char() + if data == "/": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "/"}) + self.temporaryBuffer = "" + self.state = self.scriptDataDoubleEscapeEndState + else: + self.stream.unget(data) + self.state = self.scriptDataDoubleEscapedState + return True + + def scriptDataDoubleEscapeEndState(self): + data = self.stream.char() + if data in (spaceCharacters | frozenset(("/", ">"))): + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + if self.temporaryBuffer.lower() == "script": + self.state = self.scriptDataEscapedState + else: + self.state = self.scriptDataDoubleEscapedState + elif data in asciiLetters: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.temporaryBuffer += data + else: + self.stream.unget(data) + self.state = self.scriptDataDoubleEscapedState + return True + + def beforeAttributeNameState(self): + data = self.stream.char() + if data in spaceCharacters: + self.stream.charsUntil(spaceCharacters, True) + elif data in asciiLetters: + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + elif data == ">": + self.emitCurrentToken() + elif data == "/": + self.state = self.selfClosingStartTagState + elif data in ("'", '"', "=", "<"): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "invalid-character-in-attribute-name"}) + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"].append(["\uFFFD", ""]) + self.state = self.attributeNameState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-attribute-name-but-got-eof"}) + self.state = self.dataState + else: + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + return True + + def attributeNameState(self): + data = self.stream.char() + leavingThisState = True + emitToken = False + if data == "=": + self.state = self.beforeAttributeValueState + elif data in asciiLetters: + self.currentToken["data"][-1][0] += data +\ + self.stream.charsUntil(asciiLetters, True) + leavingThisState = False + elif data == ">": + # XXX If we emit here the attributes are converted to a dict + # without being checked and when the code below runs we error + # because data is a dict not a list + emitToken = True + elif data in spaceCharacters: + self.state = self.afterAttributeNameState + elif data == "/": + self.state = self.selfClosingStartTagState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"][-1][0] += "\uFFFD" + leavingThisState = False + elif data in ("'", '"', "<"): + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": + "invalid-character-in-attribute-name"}) + self.currentToken["data"][-1][0] += data + leavingThisState = False + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "eof-in-attribute-name"}) + self.state = self.dataState + else: + self.currentToken["data"][-1][0] += data + leavingThisState = False + + if leavingThisState: + # Attributes are not dropped at this stage. That happens when the + # start tag token is emitted so values can still be safely appended + # to attributes, but we do want to report the parse error in time. + self.currentToken["data"][-1][0] = ( + self.currentToken["data"][-1][0].translate(asciiUpper2Lower)) + for name, _ in self.currentToken["data"][:-1]: + if self.currentToken["data"][-1][0] == name: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "duplicate-attribute"}) + break + # XXX Fix for above XXX + if emitToken: + self.emitCurrentToken() + return True + + def afterAttributeNameState(self): + data = self.stream.char() + if data in spaceCharacters: + self.stream.charsUntil(spaceCharacters, True) + elif data == "=": + self.state = self.beforeAttributeValueState + elif data == ">": + self.emitCurrentToken() + elif data in asciiLetters: + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + elif data == "/": + self.state = self.selfClosingStartTagState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"].append(["\uFFFD", ""]) + self.state = self.attributeNameState + elif data in ("'", '"', "<"): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "invalid-character-after-attribute-name"}) + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-end-of-tag-but-got-eof"}) + self.state = self.dataState + else: + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + return True + + def beforeAttributeValueState(self): + data = self.stream.char() + if data in spaceCharacters: + self.stream.charsUntil(spaceCharacters, True) + elif data == "\"": + self.state = self.attributeValueDoubleQuotedState + elif data == "&": + self.state = self.attributeValueUnQuotedState + self.stream.unget(data) + elif data == "'": + self.state = self.attributeValueSingleQuotedState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-attribute-value-but-got-right-bracket"}) + self.emitCurrentToken() + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"][-1][1] += "\uFFFD" + self.state = self.attributeValueUnQuotedState + elif data in ("=", "<", "`"): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "equals-in-unquoted-attribute-value"}) + self.currentToken["data"][-1][1] += data + self.state = self.attributeValueUnQuotedState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-attribute-value-but-got-eof"}) + self.state = self.dataState + else: + self.currentToken["data"][-1][1] += data + self.state = self.attributeValueUnQuotedState + return True + + def attributeValueDoubleQuotedState(self): + data = self.stream.char() + if data == "\"": + self.state = self.afterAttributeValueState + elif data == "&": + self.processEntityInAttribute('"') + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"][-1][1] += "\uFFFD" + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-attribute-value-double-quote"}) + self.state = self.dataState + else: + self.currentToken["data"][-1][1] += data +\ + self.stream.charsUntil(("\"", "&", "\u0000")) + return True + + def attributeValueSingleQuotedState(self): + data = self.stream.char() + if data == "'": + self.state = self.afterAttributeValueState + elif data == "&": + self.processEntityInAttribute("'") + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"][-1][1] += "\uFFFD" + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-attribute-value-single-quote"}) + self.state = self.dataState + else: + self.currentToken["data"][-1][1] += data +\ + self.stream.charsUntil(("'", "&", "\u0000")) + return True + + def attributeValueUnQuotedState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeAttributeNameState + elif data == "&": + self.processEntityInAttribute(">") + elif data == ">": + self.emitCurrentToken() + elif data in ('"', "'", "=", "<", "`"): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-character-in-unquoted-attribute-value"}) + self.currentToken["data"][-1][1] += data + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"][-1][1] += "\uFFFD" + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-attribute-value-no-quotes"}) + self.state = self.dataState + else: + self.currentToken["data"][-1][1] += data + self.stream.charsUntil( + frozenset(("&", ">", '"', "'", "=", "<", "`", "\u0000")) | spaceCharacters) + return True + + def afterAttributeValueState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeAttributeNameState + elif data == ">": + self.emitCurrentToken() + elif data == "/": + self.state = self.selfClosingStartTagState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-EOF-after-attribute-value"}) + self.stream.unget(data) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-character-after-attribute-value"}) + self.stream.unget(data) + self.state = self.beforeAttributeNameState + return True + + def selfClosingStartTagState(self): + data = self.stream.char() + if data == ">": + self.currentToken["selfClosing"] = True + self.emitCurrentToken() + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": + "unexpected-EOF-after-solidus-in-tag"}) + self.stream.unget(data) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-character-after-solidus-in-tag"}) + self.stream.unget(data) + self.state = self.beforeAttributeNameState + return True + + def bogusCommentState(self): + # Make a new comment token and give it as value all the characters + # until the first > or EOF (charsUntil checks for EOF automatically) + # and emit it. + data = self.stream.charsUntil(">") + data = data.replace("\u0000", "\uFFFD") + self.tokenQueue.append( + {"type": tokenTypes["Comment"], "data": data}) + + # Eat the character directly after the bogus comment which is either a + # ">" or an EOF. + self.stream.char() + self.state = self.dataState + return True + + def markupDeclarationOpenState(self): + charStack = [self.stream.char()] + if charStack[-1] == "-": + charStack.append(self.stream.char()) + if charStack[-1] == "-": + self.currentToken = {"type": tokenTypes["Comment"], "data": ""} + self.state = self.commentStartState + return True + elif charStack[-1] in ('d', 'D'): + matched = True + for expected in (('o', 'O'), ('c', 'C'), ('t', 'T'), + ('y', 'Y'), ('p', 'P'), ('e', 'E')): + charStack.append(self.stream.char()) + if charStack[-1] not in expected: + matched = False + break + if matched: + self.currentToken = {"type": tokenTypes["Doctype"], + "name": "", + "publicId": None, "systemId": None, + "correct": True} + self.state = self.doctypeState + return True + elif (charStack[-1] == "[" and + self.parser is not None and + self.parser.tree.openElements and + self.parser.tree.openElements[-1].namespace != self.parser.tree.defaultNamespace): + matched = True + for expected in ["C", "D", "A", "T", "A", "["]: + charStack.append(self.stream.char()) + if charStack[-1] != expected: + matched = False + break + if matched: + self.state = self.cdataSectionState + return True + + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-dashes-or-doctype"}) + + while charStack: + self.stream.unget(charStack.pop()) + self.state = self.bogusCommentState + return True + + def commentStartState(self): + data = self.stream.char() + if data == "-": + self.state = self.commentStartDashState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "incorrect-comment"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-comment"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["data"] += data + self.state = self.commentState + return True + + def commentStartDashState(self): + data = self.stream.char() + if data == "-": + self.state = self.commentEndState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "-\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "incorrect-comment"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-comment"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["data"] += "-" + data + self.state = self.commentState + return True + + def commentState(self): + data = self.stream.char() + if data == "-": + self.state = self.commentEndDashState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "\uFFFD" + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "eof-in-comment"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["data"] += data + \ + self.stream.charsUntil(("-", "\u0000")) + return True + + def commentEndDashState(self): + data = self.stream.char() + if data == "-": + self.state = self.commentEndState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "-\uFFFD" + self.state = self.commentState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-comment-end-dash"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["data"] += "-" + data + self.state = self.commentState + return True + + def commentEndState(self): + data = self.stream.char() + if data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "--\uFFFD" + self.state = self.commentState + elif data == "!": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-bang-after-double-dash-in-comment"}) + self.state = self.commentEndBangState + elif data == "-": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-dash-after-double-dash-in-comment"}) + self.currentToken["data"] += data + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-comment-double-dash"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + # XXX + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-comment"}) + self.currentToken["data"] += "--" + data + self.state = self.commentState + return True + + def commentEndBangState(self): + data = self.stream.char() + if data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == "-": + self.currentToken["data"] += "--!" + self.state = self.commentEndDashState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "--!\uFFFD" + self.state = self.commentState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-comment-end-bang-state"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["data"] += "--!" + data + self.state = self.commentState + return True + + def doctypeState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeDoctypeNameState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-doctype-name-but-got-eof"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "need-space-after-doctype"}) + self.stream.unget(data) + self.state = self.beforeDoctypeNameState + return True + + def beforeDoctypeNameState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-doctype-name-but-got-right-bracket"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["name"] = "\uFFFD" + self.state = self.doctypeNameState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-doctype-name-but-got-eof"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["name"] = data + self.state = self.doctypeNameState + return True + + def doctypeNameState(self): + data = self.stream.char() + if data in spaceCharacters: + self.currentToken["name"] = self.currentToken["name"].translate(asciiUpper2Lower) + self.state = self.afterDoctypeNameState + elif data == ">": + self.currentToken["name"] = self.currentToken["name"].translate(asciiUpper2Lower) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["name"] += "\uFFFD" + self.state = self.doctypeNameState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype-name"}) + self.currentToken["correct"] = False + self.currentToken["name"] = self.currentToken["name"].translate(asciiUpper2Lower) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["name"] += data + return True + + def afterDoctypeNameState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.currentToken["correct"] = False + self.stream.unget(data) + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + if data in ("p", "P"): + matched = True + for expected in (("u", "U"), ("b", "B"), ("l", "L"), + ("i", "I"), ("c", "C")): + data = self.stream.char() + if data not in expected: + matched = False + break + if matched: + self.state = self.afterDoctypePublicKeywordState + return True + elif data in ("s", "S"): + matched = True + for expected in (("y", "Y"), ("s", "S"), ("t", "T"), + ("e", "E"), ("m", "M")): + data = self.stream.char() + if data not in expected: + matched = False + break + if matched: + self.state = self.afterDoctypeSystemKeywordState + return True + + # All the characters read before the current 'data' will be + # [a-zA-Z], so they're garbage in the bogus doctype and can be + # discarded; only the latest character might be '>' or EOF + # and needs to be ungetted + self.stream.unget(data) + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-space-or-right-bracket-in-doctype", "datavars": + {"data": data}}) + self.currentToken["correct"] = False + self.state = self.bogusDoctypeState + + return True + + def afterDoctypePublicKeywordState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeDoctypePublicIdentifierState + elif data in ("'", '"'): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.stream.unget(data) + self.state = self.beforeDoctypePublicIdentifierState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.stream.unget(data) + self.state = self.beforeDoctypePublicIdentifierState + return True + + def beforeDoctypePublicIdentifierState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == "\"": + self.currentToken["publicId"] = "" + self.state = self.doctypePublicIdentifierDoubleQuotedState + elif data == "'": + self.currentToken["publicId"] = "" + self.state = self.doctypePublicIdentifierSingleQuotedState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-end-of-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["correct"] = False + self.state = self.bogusDoctypeState + return True + + def doctypePublicIdentifierDoubleQuotedState(self): + data = self.stream.char() + if data == "\"": + self.state = self.afterDoctypePublicIdentifierState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["publicId"] += "\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-end-of-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["publicId"] += data + return True + + def doctypePublicIdentifierSingleQuotedState(self): + data = self.stream.char() + if data == "'": + self.state = self.afterDoctypePublicIdentifierState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["publicId"] += "\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-end-of-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["publicId"] += data + return True + + def afterDoctypePublicIdentifierState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.betweenDoctypePublicAndSystemIdentifiersState + elif data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == '"': + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierDoubleQuotedState + elif data == "'": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierSingleQuotedState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["correct"] = False + self.state = self.bogusDoctypeState + return True + + def betweenDoctypePublicAndSystemIdentifiersState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == '"': + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierDoubleQuotedState + elif data == "'": + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierSingleQuotedState + elif data == EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["correct"] = False + self.state = self.bogusDoctypeState + return True + + def afterDoctypeSystemKeywordState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeDoctypeSystemIdentifierState + elif data in ("'", '"'): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.stream.unget(data) + self.state = self.beforeDoctypeSystemIdentifierState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.stream.unget(data) + self.state = self.beforeDoctypeSystemIdentifierState + return True + + def beforeDoctypeSystemIdentifierState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == "\"": + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierDoubleQuotedState + elif data == "'": + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierSingleQuotedState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["correct"] = False + self.state = self.bogusDoctypeState + return True + + def doctypeSystemIdentifierDoubleQuotedState(self): + data = self.stream.char() + if data == "\"": + self.state = self.afterDoctypeSystemIdentifierState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["systemId"] += "\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-end-of-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["systemId"] += data + return True + + def doctypeSystemIdentifierSingleQuotedState(self): + data = self.stream.char() + if data == "'": + self.state = self.afterDoctypeSystemIdentifierState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["systemId"] += "\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-end-of-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["systemId"] += data + return True + + def afterDoctypeSystemIdentifierState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.state = self.bogusDoctypeState + return True + + def bogusDoctypeState(self): + data = self.stream.char() + if data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + # XXX EMIT + self.stream.unget(data) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + pass + return True + + def cdataSectionState(self): + data = [] + while True: + data.append(self.stream.charsUntil("]")) + data.append(self.stream.charsUntil(">")) + char = self.stream.char() + if char == EOF: + break + else: + assert char == ">" + if data[-1][-2:] == "]]": + data[-1] = data[-1][:-2] + break + else: + data.append(char) + + data = "".join(data) # pylint:disable=redefined-variable-type + # Deal with null here rather than in the parser + nullCount = data.count("\u0000") + if nullCount > 0: + for _ in range(nullCount): + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + data = data.replace("\u0000", "\uFFFD") + if data: + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": data}) + self.state = self.dataState + return True diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__init__.py new file mode 100644 index 0000000..a5ba4bf --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__init__.py @@ -0,0 +1,14 @@ +from __future__ import absolute_import, division, unicode_literals + +from .py import Trie as PyTrie + +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 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d9d8a0c22113c02c234f77f0738b2e359092d40c GIT binary patch literal 434 zcmXw!OHRWu5QfK28bWz>!HyNnE{b^wP$h%_fdm_bpb`)vSqXNj!A_!y6KK!CMYvM7 zthfRz>`MIBe4hFJ8lSDKbiwI!BYWB;0N=j&SL~7#7uBtU06{buk`O}^YJwynAgBm* zXgWzmKt@St+M7EI&WQ=!L%tq@Tzu=|B>_JkA&(wF#z{wnchK+rxO<@=v}<Wr6}q;P zD^nI|+gPYZRjSC_UY)DwLP)Nam6+=4$8`yP(uN~c^19z`yPS_}TchM0sawOqBXnqK zImO5)(aqFvPa=`p`Fwur>vrjC{@w**fnR`2{-nq62P;uEsg<lrk&O#2Bv#B!*z-=w zhqK}9_WRyg%&LRE26sQ~%xpWo<ZQ%BRSr~M*;MPn{$VzGtFsqx&Vx5H7X`A3HF{sG njB(!%<6Py+a=ukg+xW;7qSo@*|Fc?kSf|T03@GW5RT9xZ8Dn%m literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__pycache__/_base.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__pycache__/_base.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c14b5b3ea5467846fa42e7de64aa76872a3da0a0 GIT binary patch literal 1517 zcmZux&u`l{6ecOzmK`VUl3;7Lt}w7(bf}%J>xLFVupixa80Jd?6c9ELvPj2TC`%z} z*D=(~oS{AJw7($PZU2(4JM~}aY46cV77ro7CyIRJd*Amx@|*Sb7J>H1M}wdL@(B3{ zf3BJjgRh{Q&%p>Hs3IASXvQLzd67qPjwwH@MKwx(Ai@*=84<p$Exf2MY6m2&zlEJ7 z^r}1Yz~pLTB~P;=*R~2oI!#TQkE^?rahl{pa+O-CV`V~GHGYbVA{`$kxc#bOI@ruJ zFp@-6kcbHyd1CD~8B!O%8Tq0n>SrXXiG~Q^TNh2yf^XwB@ktawQtiq=)Tx|*{Pn<C z9VfOkh>h$dDmJDw%yq}Ys_7@pMI!`gx$b5cek`%HBnx)VF32nP252}A^aJaaY(Wo* z%Y_Pd7L@Ec!I{wOC-m|#JhTRV3%dCb%!riam(5qSr03)fxuDuF>7VSxKOlb-V4`Jg ztgU&O+EK_V*4?e>45sUamcw+W8*swANw3i9G`6xgjdgFBD<QS%Wusp5X~Cb)pZ>c0 z^6^m2%@>cS`m>pxXS>jj#=XN{krt2AF@#X+(UUI+qvOfo2q#_VQ#ls7?u~4wo~U%t z<48=8BU|0#^j&k$NSowYv40oAAhJ4{-$!n{$MV#4_f(#Mp8MTv$I!28W>QG4>)>7a z=vH}f43vm(q#EiqnAdl}0LUiiP87~Vx?E^qtu|p`0x*Pauz&_^-n@>xA{-XYx9I#3 z%<Mr)&dCLNj*PRCodfH@cuRmtC#@Gy%}%Vt??dKt&=?`~^n37e2~-|r>_}f4%%|EO z#fBpijw<n`GMlinOptES7ACmk61>g#_Jj}Ngc9oPxUSnJBshC!;R-_K(FGOs1E@cM z@ep9ZJt)~4`JL@RDS>zA<_rMqydW057W6mp1c0pn7ON2`ujzPvBr8wJaTWY1PruVT z*DH8w`hT<=Du+GBUgF$AoJa$q0rlBEx=A<Le9K{7^;|)Tcgo4~J`7M46apnF0m}{< zq7bwXvf~w5$*7@jl>QABwpOEYcucZSV6$=021qc!cS};v4I?$Hfb(&jNzSVl=UFZ$ z3de2EPbRUtTxoDF@`Uqcb!@}&E<t@CM%DUdxh7I6aKWqT44}Yj(5`r~?y(zuc9F4- zX3z*)?mqOx2F4yv>_kIsjW<doQyMW;Ye}w@Oe{Q_M&ldeHvJdp1{uNL62LwR?HJf* GZSP-CJz!w~ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__pycache__/datrie.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__pycache__/datrie.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..61dd14b687a5b2bb0400741009d19915da360948 GIT binary patch literal 2036 zcmb7FOK%%D5GMDfl`Pwe?F4qyhx<f@HdfjoEm8zUoTMlU6u#7`0l@{a5@~DgeaIxG z$in&(``BO5lYQ)8;<cyzg`PUYm0Z~{(wYknxkK)J-#o~DK0jY0(0;$)+5N*K<S%@g zHh3q`psSxjaKdRqQrf1e({@s~?NZb^iI@8Az|P&Il7{UN<{s#)ps!K#BjG*|&Ik`g z?bL1iyz&cahHt<kX}V@H>Zm*!Xu;yNpG$2*9uH#`=b32?vbdXb!ID@D86~Pojkhgh z0b^B*k!Je1FWyiv)J1F4=ECF|boDC;LE4m)w!<lR&PdzkF85&cN>0dzhwvWoDzCv< z;VZn(=g(+6<O_TeG*#Z<cVMjXCB6*f9G?UJccl-;yAB9!0d!QnfUbrhG&v<F&gi>> zp3@8RlKi%D;%cXGwR`HQ&$P$sDSb^x_X-!*7EZjvIrj_if>Lty<qkP&><}Gr=e$xl z7qGJ+EF8TLwyM_F(ynvjp7@1dkb|&rpOT~99Y_Vxa<|5-n@O^MD2~;7I#7DOBi5Cc zakj4vY1WLZgf<>7n;JwpQ##7JLLz@t-G*@fAZ0F%8*y%emzx-E;~nI2W_-pY9T^{T zk*a23JSCDn<CV&8FOtf*VAps!H~uh62I5a5SHbe%!&YC$!$^zPFp{mkJmEsBR@!TI zzv{Cm<0l6XUp?C6WA)9Wq5OKJ$LT|8`&nzd)sOoREXyQ$@c7$K?{LuBN2Tp-C^DYQ zR!^tN<0S617<ejLKnaG8{;>%ei?diWh9$0+KoA<x1zMva^d+Z3m*{vNo!pr2yi6&k z7Q0O;eqTTu4#;5uVWwM6DjT3{IufnQyC~4rQmnzu)EVpMnT~)yWA{L#Y_-twoeAK- zt6i*NY&c#4)dWDH0!mQFxQWP0WLhF$1FbLyI~YR-Q@r{F&n{enLbyx+uw-AuS(*4} zmbY^KQ`%2NDl#p&Eevqm`g;u(;|xcXv3F-+FXL)g-V#@cYC+egxc?c~ImY&d#xi8= zgBiTW#Ldgatt*&#D_CFaFu_co(}G@118Y$wrg@T56ZECni$~Y8YPWnegIcwyc%W{J zW>$KUV)!L{73&@=@un5^Az)m`M%+(lu-7d1O;&ErWg*G4eWCRKVDT|9_<V-NvSo4g z`&;8LU;Q4-DScZgJ^=z>%#c{UfkbHp&T1Vmf-Fh}W2VMfn)5+|b2y<#gD5Fi<U3$a z-be8s3M?(TjsmMfV(cZlE)jYrGxjLpakGDfDopG}6Vk9Ay5&=|qg~%>&LM@pfgVVp zAn~wEEKQ03TKEmwyUT8s3!pKJaM^84F1if`^=PkZpLHT7Ol9-=3v~P@IwpKtI{H1H PautGDaq6`0)ZKpo0HwZ% literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__pycache__/py.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__pycache__/py.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..26c485a27dbc516cf22114e39f09574682e4898d GIT binary patch literal 2239 zcma)7OK%%D5GJ_~tz_9&($tBOHdRryg^ET>8zeyhBgmsofg<pwMhgfjh?PiLYwxaP zl5%8Wb*XafkBE=`1N||)_LNiaIdz6>DX|d*<zk2Aa5zJL^Wfw4^%{Zp=k?z6e?vn4 z!O61uFn9>Reg;GkK~s{^F3nh%WnR~#$YZIW1>L}ny)?`!-3p9-5u{O8?bayyiHJ~C zUJ_A}wT0KMis%>8s=fw|q~+PoxTi<y#7LfG<B>8p63KC*lTmIPlRW8<gyd;rq>5AB zqPA+})Npe$mM~fCC0h0kPvyY8rl^lve@`W{kII+LgTX`i^-~~{bg3X+Ca7R9N!Jse z@S%s}iV*rhR73=QD5|0ceMK}xU97*P-AHVRP2g0;8XW(Uia=SP0l|hnV)X=m{WA~) zSfPP}zM`k(2eP0Gs&5!3yaoM(7PKJTGk&?cz*!)CprHs%r2yFhgIOd9m<o6Mcr|QG zGaAPF8jyng-k4JZW(-}hUkN2g%x$8(EoN%~W3Ek{_oWIz8d$7-%hKszMAc#bMs>z2 zIgX9&9LK6N7^Olg-N}ZX{&!=3e|G=i){EN%G1GT%AFJ=DW|rN8wx4(QI^$$~)9Fsr zn|JQ@hKG~hJ~G|Uk7X`KsxvfMdM8bK9d5uUo$*O~eDbEcvoCWw9jgaxc#HB%vnG12 z&3Te1hV%ALI_iVJAGBA(vulsiw0S5`bTgZ1)9lHn2CezNwnRDCSFIPPsr6CDR`(!6 zepG6tY`{fqVjF4*E-7GI3h;j1A4<?+y;SD5Ue3p(BsUs>^0iC{*2k?5tCFn4k!`d* zCgzPsAPL=~5ew-C4e4zC+*Qtn2wv8O2=2rnI3R~1xEQ=e)knZ<F|`ey_27&b&DJ^Z zk8%?O?3|;p!;a9|r89$XS62apz??G*p+XKIzDlD^T?K*CGIf?O8m(|huAK9&ckI>A z?74;iZOZzX#2>PSxPl1h2*L7lD>U882hap83%ZR7a}iDT30@NY^o|qPINz5B>}8ze z`qEzG>~gEc-IdJ>h+!Hz5B?2<0xHR2q_?1_hYWf+gKiq<SA-bS8`Ai|JEiIw^!{@; zXLHX4C<oqWg}3m1GWX{}-dJ)MtmHsGlX+P9CPe84=vStISebt7b_d%8bW_m$st8|I zmb_C+Nf8KkkIaLk<KNH<6q>>>0#{Ic)X?&F)h3)?;eA?>`WQOvX=!W?YK1cTMPh~u z9j>s%D0mZyixbE%AzGC(Lc_6=gJf!1I<jn-*ud?zG*OpO{yf@__Zjf@4Ir2;HCCrJ zy2TnUYkYQ@HfSBjH8!g{4`7n6kVn*4$P1V(b4P865@*Dm0UCFq_s(#Jf_e}vai05m z9SW}FEZE#XLpE^8?g<9o!Zjaoh4Org3F7VUJ%#IHs;MuKT)+f@bHKEMGIzd2##czb zM$$rZ9teA77;9I6IHJr;5buJZz6^u_CcZ=FGOM!<7|*sH8t>bMabCk>l*gIm+}1eH zMq-lU7;44QBu>i}bsZ1#DH4QVHIaOd#JTDl9KAiJ8)2PuFI*J{dILyAqiW=pU+t<} z+ik6((ZR$_6c|-lXq1NppF+C{&q4d_DQN3t>YgAQmQS{eDyYT1SWBnORvtZmf_Hu2 WQEaqRUhM%EG>uR16$lsjy#D~DXX?)Y literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/_base.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/_base.py new file mode 100644 index 0000000..a1158bb --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/_base.py @@ -0,0 +1,37 @@ +from __future__ import absolute_import, division, unicode_literals + +from collections import Mapping + + +class Trie(Mapping): + """Abstract base class for tries""" + + def keys(self, prefix=None): + # pylint:disable=arguments-differ + keys = super(Trie, self).keys() + + if prefix is None: + return set(keys) + + return {x for x in keys if x.startswith(prefix)} + + def has_keys_with_prefix(self, prefix): + for key in self.keys(): + if key.startswith(prefix): + return True + + return False + + def longest_prefix(self, prefix): + if prefix in self: + return prefix + + for i in range(1, len(prefix) + 1): + if prefix[:-i] in self: + return prefix[:-i] + + raise KeyError(prefix) + + def longest_prefix_item(self, prefix): + lprefix = self.longest_prefix(prefix) + return (lprefix, self[lprefix]) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/datrie.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/datrie.py new file mode 100644 index 0000000..e2e5f86 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/datrie.py @@ -0,0 +1,44 @@ +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.7/site-packages/pip/_vendor/html5lib/_trie/py.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/py.py new file mode 100644 index 0000000..c178b21 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/py.py @@ -0,0 +1,67 @@ +from __future__ import absolute_import, division, unicode_literals +from pip._vendor.six import text_type + +from bisect import bisect_left + +from ._base import Trie as ABCTrie + + +class Trie(ABCTrie): + def __init__(self, data): + if not all(isinstance(x, text_type) for x in data.keys()): + raise TypeError("All keys must be strings") + + self._data = data + self._keys = sorted(data.keys()) + self._cachestr = "" + self._cachepoints = (0, len(data)) + + def __contains__(self, key): + return key in self._data + + def __len__(self): + return len(self._data) + + def __iter__(self): + return iter(self._data) + + def __getitem__(self, key): + return self._data[key] + + def keys(self, prefix=None): + if prefix is None or prefix == "" or not self._keys: + return set(self._keys) + + if prefix.startswith(self._cachestr): + lo, hi = self._cachepoints + start = i = bisect_left(self._keys, prefix, lo, hi) + else: + start = i = bisect_left(self._keys, prefix) + + keys = set() + if start == len(self._keys): + return keys + + while self._keys[i].startswith(prefix): + keys.add(self._keys[i]) + i += 1 + + self._cachestr = prefix + self._cachepoints = (start, i) + + return keys + + def has_keys_with_prefix(self, prefix): + if prefix in self._data: + return True + + if prefix.startswith(self._cachestr): + lo, hi = self._cachepoints + i = bisect_left(self._keys, prefix, lo, hi) + else: + i = bisect_left(self._keys, prefix) + + if i == len(self._keys): + return False + + return self._keys[i].startswith(prefix) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_utils.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_utils.py new file mode 100644 index 0000000..0703afb --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_utils.py @@ -0,0 +1,124 @@ +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 +except ImportError: + import xml.etree.ElementTree as default_etree + + +__all__ = ["default_etree", "MethodDispatcher", "isSurrogatePair", + "surrogatePairToCodepoint", "moduleFactoryFactory", + "supports_lone_surrogates"] + + +# Platforms not supporting lone surrogates (\uD800-\uDFFF) should be +# caught by the below test. In general this would be any platform +# using UTF-16 as its encoding of unicode strings, such as +# Jython. This is because UTF-16 itself is based on the use of such +# surrogates, and there is no mechanism to further escape such +# escapes. +try: + _x = eval('"\\uD800"') # pylint:disable=eval-used + if not isinstance(_x, text_type): + # 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 + supports_lone_surrogates = False +else: + supports_lone_surrogates = True + + +class MethodDispatcher(dict): + """Dict with 2 special properties: + + On initiation, keys that are lists, sets or tuples are converted to + multiple keys so accessing any one of the items in the original + list-like object returns the matching value + + md = MethodDispatcher({("foo", "bar"):"baz"}) + md["foo"] == "baz" + + A default value which can be set through the default attribute. + """ + + 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)): + for item in name: + _dictEntries.append((item, value)) + else: + _dictEntries.append((name, value)) + dict.__init__(self, _dictEntries) + assert len(self) == len(_dictEntries) + self.default = None + + def __getitem__(self, key): + return dict.get(self, key, self.default) + + +# Some utility functions to deal with weirdness around UCS2 vs UCS4 +# python builds + +def isSurrogatePair(data): + return (len(data) == 2 and + ord(data[0]) >= 0xD800 and ord(data[0]) <= 0xDBFF and + ord(data[1]) >= 0xDC00 and ord(data[1]) <= 0xDFFF) + + +def surrogatePairToCodepoint(data): + char_val = (0x10000 + (ord(data[0]) - 0xD800) * 0x400 + + (ord(data[1]) - 0xDC00)) + return char_val + +# Module Factory Factory (no, this isn't Java, I know) +# Here to stop this being duplicated all over the place. + + +def moduleFactoryFactory(factory): + moduleCache = {} + + def moduleFactory(baseModule, *args, **kwargs): + if isinstance(ModuleType.__name__, type("")): + name = "_%s_factory" % baseModule.__name__ + else: + name = b"_%s_factory" % baseModule.__name__ + + kwargs_tuple = tuple(kwargs.items()) + + try: + return moduleCache[name][args][kwargs_tuple] + except KeyError: + mod = ModuleType(name) + objs = factory(baseModule, *args, **kwargs) + mod.__dict__.update(objs) + if "name" not in moduleCache: + moduleCache[name] = {} + if "args" not in moduleCache[name]: + moduleCache[name][args] = {} + if "kwargs" not in moduleCache[name][args]: + moduleCache[name][args][kwargs_tuple] = {} + moduleCache[name][args][kwargs_tuple] = mod + return mod + + return moduleFactory + + +def memoize(func): + cache = {} + + def wrapped(*args, **kwargs): + key = (tuple(args), tuple(kwargs.items())) + if key not in cache: + cache[key] = func(*args, **kwargs) + return cache[key] + + return wrapped diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/constants.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/constants.py new file mode 100644 index 0000000..1ff8041 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/constants.py @@ -0,0 +1,2947 @@ +from __future__ import absolute_import, division, unicode_literals + +import string + +EOF = None + +E = { + "null-character": + "Null character in input stream, replaced with U+FFFD.", + "invalid-codepoint": + "Invalid codepoint in stream.", + "incorrectly-placed-solidus": + "Solidus (/) incorrectly placed in tag.", + "incorrect-cr-newline-entity": + "Incorrect CR newline entity, replaced with LF.", + "illegal-windows-1252-entity": + "Entity used with illegal number (windows-1252 reference).", + "cant-convert-numeric-entity": + "Numeric entity couldn't be converted to character " + "(codepoint U+%(charAsInt)08x).", + "illegal-codepoint-for-numeric-entity": + "Numeric entity represents an illegal codepoint: " + "U+%(charAsInt)08x.", + "numeric-entity-without-semicolon": + "Numeric entity didn't end with ';'.", + "expected-numeric-entity-but-got-eof": + "Numeric entity expected. Got end of file instead.", + "expected-numeric-entity": + "Numeric entity expected but none found.", + "named-entity-without-semicolon": + "Named entity didn't end with ';'.", + "expected-named-entity": + "Named entity expected. Got none.", + "attributes-in-end-tag": + "End tag contains unexpected attributes.", + 'self-closing-flag-on-end-tag': + "End tag contains unexpected self-closing flag.", + "expected-tag-name-but-got-right-bracket": + "Expected tag name. Got '>' instead.", + "expected-tag-name-but-got-question-mark": + "Expected tag name. Got '?' instead. (HTML doesn't " + "support processing instructions.)", + "expected-tag-name": + "Expected tag name. Got something else instead", + "expected-closing-tag-but-got-right-bracket": + "Expected closing tag. Got '>' instead. Ignoring '</>'.", + "expected-closing-tag-but-got-eof": + "Expected closing tag. Unexpected end of file.", + "expected-closing-tag-but-got-char": + "Expected closing tag. Unexpected character '%(data)s' found.", + "eof-in-tag-name": + "Unexpected end of file in the tag name.", + "expected-attribute-name-but-got-eof": + "Unexpected end of file. Expected attribute name instead.", + "eof-in-attribute-name": + "Unexpected end of file in attribute name.", + "invalid-character-in-attribute-name": + "Invalid character in attribute name", + "duplicate-attribute": + "Dropped duplicate attribute on tag.", + "expected-end-of-tag-name-but-got-eof": + "Unexpected end of file. Expected = or end of tag.", + "expected-attribute-value-but-got-eof": + "Unexpected end of file. Expected attribute value.", + "expected-attribute-value-but-got-right-bracket": + "Expected attribute value. Got '>' instead.", + 'equals-in-unquoted-attribute-value': + "Unexpected = in unquoted attribute", + 'unexpected-character-in-unquoted-attribute-value': + "Unexpected character in unquoted attribute", + "invalid-character-after-attribute-name": + "Unexpected character after attribute name.", + "unexpected-character-after-attribute-value": + "Unexpected character after attribute value.", + "eof-in-attribute-value-double-quote": + "Unexpected end of file in attribute value (\").", + "eof-in-attribute-value-single-quote": + "Unexpected end of file in attribute value (').", + "eof-in-attribute-value-no-quotes": + "Unexpected end of file in attribute value.", + "unexpected-EOF-after-solidus-in-tag": + "Unexpected end of file in tag. Expected >", + "unexpected-character-after-solidus-in-tag": + "Unexpected character after / in tag. Expected >", + "expected-dashes-or-doctype": + "Expected '--' or 'DOCTYPE'. Not found.", + "unexpected-bang-after-double-dash-in-comment": + "Unexpected ! after -- in comment", + "unexpected-space-after-double-dash-in-comment": + "Unexpected space after -- in comment", + "incorrect-comment": + "Incorrect comment.", + "eof-in-comment": + "Unexpected end of file in comment.", + "eof-in-comment-end-dash": + "Unexpected end of file in comment (-)", + "unexpected-dash-after-double-dash-in-comment": + "Unexpected '-' after '--' found in comment.", + "eof-in-comment-double-dash": + "Unexpected end of file in comment (--).", + "eof-in-comment-end-space-state": + "Unexpected end of file in comment.", + "eof-in-comment-end-bang-state": + "Unexpected end of file in comment.", + "unexpected-char-in-comment": + "Unexpected character in comment found.", + "need-space-after-doctype": + "No space after literal string 'DOCTYPE'.", + "expected-doctype-name-but-got-right-bracket": + "Unexpected > character. Expected DOCTYPE name.", + "expected-doctype-name-but-got-eof": + "Unexpected end of file. Expected DOCTYPE name.", + "eof-in-doctype-name": + "Unexpected end of file in DOCTYPE name.", + "eof-in-doctype": + "Unexpected end of file in DOCTYPE.", + "expected-space-or-right-bracket-in-doctype": + "Expected space or '>'. Got '%(data)s'", + "unexpected-end-of-doctype": + "Unexpected end of DOCTYPE.", + "unexpected-char-in-doctype": + "Unexpected character in DOCTYPE.", + "eof-in-innerhtml": + "XXX innerHTML EOF", + "unexpected-doctype": + "Unexpected DOCTYPE. Ignored.", + "non-html-root": + "html needs to be the first start tag.", + "expected-doctype-but-got-eof": + "Unexpected End of file. Expected DOCTYPE.", + "unknown-doctype": + "Erroneous DOCTYPE.", + "expected-doctype-but-got-chars": + "Unexpected non-space characters. Expected DOCTYPE.", + "expected-doctype-but-got-start-tag": + "Unexpected start tag (%(name)s). Expected DOCTYPE.", + "expected-doctype-but-got-end-tag": + "Unexpected end tag (%(name)s). Expected DOCTYPE.", + "end-tag-after-implied-root": + "Unexpected end tag (%(name)s) after the (implied) root element.", + "expected-named-closing-tag-but-got-eof": + "Unexpected end of file. Expected end tag (%(name)s).", + "two-heads-are-not-better-than-one": + "Unexpected start tag head in existing head. Ignored.", + "unexpected-end-tag": + "Unexpected end tag (%(name)s). Ignored.", + "unexpected-start-tag-out-of-my-head": + "Unexpected start tag (%(name)s) that can be in head. Moved.", + "unexpected-start-tag": + "Unexpected start tag (%(name)s).", + "missing-end-tag": + "Missing end tag (%(name)s).", + "missing-end-tags": + "Missing end tags (%(name)s).", + "unexpected-start-tag-implies-end-tag": + "Unexpected start tag (%(startName)s) " + "implies end tag (%(endName)s).", + "unexpected-start-tag-treated-as": + "Unexpected start tag (%(originalName)s). Treated as %(newName)s.", + "deprecated-tag": + "Unexpected start tag %(name)s. Don't use it!", + "unexpected-start-tag-ignored": + "Unexpected start tag %(name)s. Ignored.", + "expected-one-end-tag-but-got-another": + "Unexpected end tag (%(gotName)s). " + "Missing end tag (%(expectedName)s).", + "end-tag-too-early": + "End tag (%(name)s) seen too early. Expected other end tag.", + "end-tag-too-early-named": + "Unexpected end tag (%(gotName)s). Expected end tag (%(expectedName)s).", + "end-tag-too-early-ignored": + "End tag (%(name)s) seen too early. Ignored.", + "adoption-agency-1.1": + "End tag (%(name)s) violates step 1, " + "paragraph 1 of the adoption agency algorithm.", + "adoption-agency-1.2": + "End tag (%(name)s) violates step 1, " + "paragraph 2 of the adoption agency algorithm.", + "adoption-agency-1.3": + "End tag (%(name)s) violates step 1, " + "paragraph 3 of the adoption agency algorithm.", + "adoption-agency-4.4": + "End tag (%(name)s) violates step 4, " + "paragraph 4 of the adoption agency algorithm.", + "unexpected-end-tag-treated-as": + "Unexpected end tag (%(originalName)s). Treated as %(newName)s.", + "no-end-tag": + "This element (%(name)s) has no end tag.", + "unexpected-implied-end-tag-in-table": + "Unexpected implied end tag (%(name)s) in the table phase.", + "unexpected-implied-end-tag-in-table-body": + "Unexpected implied end tag (%(name)s) in the table body phase.", + "unexpected-char-implies-table-voodoo": + "Unexpected non-space characters in " + "table context caused voodoo mode.", + "unexpected-hidden-input-in-table": + "Unexpected input with type hidden in table context.", + "unexpected-form-in-table": + "Unexpected form in table context.", + "unexpected-start-tag-implies-table-voodoo": + "Unexpected start tag (%(name)s) in " + "table context caused voodoo mode.", + "unexpected-end-tag-implies-table-voodoo": + "Unexpected end tag (%(name)s) in " + "table context caused voodoo mode.", + "unexpected-cell-in-table-body": + "Unexpected table cell start tag (%(name)s) " + "in the table body phase.", + "unexpected-cell-end-tag": + "Got table cell end tag (%(name)s) " + "while required end tags are missing.", + "unexpected-end-tag-in-table-body": + "Unexpected end tag (%(name)s) in the table body phase. Ignored.", + "unexpected-implied-end-tag-in-table-row": + "Unexpected implied end tag (%(name)s) in the table row phase.", + "unexpected-end-tag-in-table-row": + "Unexpected end tag (%(name)s) in the table row phase. Ignored.", + "unexpected-select-in-select": + "Unexpected select start tag in the select phase " + "treated as select end tag.", + "unexpected-input-in-select": + "Unexpected input start tag in the select phase.", + "unexpected-start-tag-in-select": + "Unexpected start tag token (%(name)s in the select phase. " + "Ignored.", + "unexpected-end-tag-in-select": + "Unexpected end tag (%(name)s) in the select phase. Ignored.", + "unexpected-table-element-start-tag-in-select-in-table": + "Unexpected table element start tag (%(name)s) in the select in table phase.", + "unexpected-table-element-end-tag-in-select-in-table": + "Unexpected table element end tag (%(name)s) in the select in table phase.", + "unexpected-char-after-body": + "Unexpected non-space characters in the after body phase.", + "unexpected-start-tag-after-body": + "Unexpected start tag token (%(name)s)" + " in the after body phase.", + "unexpected-end-tag-after-body": + "Unexpected end tag token (%(name)s)" + " in the after body phase.", + "unexpected-char-in-frameset": + "Unexpected characters in the frameset phase. Characters ignored.", + "unexpected-start-tag-in-frameset": + "Unexpected start tag token (%(name)s)" + " in the frameset phase. Ignored.", + "unexpected-frameset-in-frameset-innerhtml": + "Unexpected end tag token (frameset) " + "in the frameset phase (innerHTML).", + "unexpected-end-tag-in-frameset": + "Unexpected end tag token (%(name)s)" + " in the frameset phase. Ignored.", + "unexpected-char-after-frameset": + "Unexpected non-space characters in the " + "after frameset phase. Ignored.", + "unexpected-start-tag-after-frameset": + "Unexpected start tag (%(name)s)" + " in the after frameset phase. Ignored.", + "unexpected-end-tag-after-frameset": + "Unexpected end tag (%(name)s)" + " in the after frameset phase. Ignored.", + "unexpected-end-tag-after-body-innerhtml": + "Unexpected end tag after body(innerHtml)", + "expected-eof-but-got-char": + "Unexpected non-space characters. Expected end of file.", + "expected-eof-but-got-start-tag": + "Unexpected start tag (%(name)s)" + ". Expected end of file.", + "expected-eof-but-got-end-tag": + "Unexpected end tag (%(name)s)" + ". Expected end of file.", + "eof-in-table": + "Unexpected end of file. Expected table content.", + "eof-in-select": + "Unexpected end of file. Expected select content.", + "eof-in-frameset": + "Unexpected end of file. Expected frameset content.", + "eof-in-script-in-script": + "Unexpected end of file. Expected script content.", + "eof-in-foreign-lands": + "Unexpected end of file. Expected foreign content", + "non-void-element-with-trailing-solidus": + "Trailing solidus not allowed on element %(name)s", + "unexpected-html-element-in-foreign-content": + "Element %(name)s not allowed in a non-html context", + "unexpected-end-tag-before-html": + "Unexpected end tag (%(name)s) before html.", + "unexpected-inhead-noscript-tag": + "Element %(name)s not allowed in a inhead-noscript context", + "eof-in-head-noscript": + "Unexpected end of file. Expected inhead-noscript content", + "char-in-head-noscript": + "Unexpected non-space character. Expected inhead-noscript content", + "XXX-undefined-error": + "Undefined error (this sucks and should be fixed)", +} + +namespaces = { + "html": "http://www.w3.org/1999/xhtml", + "mathml": "http://www.w3.org/1998/Math/MathML", + "svg": "http://www.w3.org/2000/svg", + "xlink": "http://www.w3.org/1999/xlink", + "xml": "http://www.w3.org/XML/1998/namespace", + "xmlns": "http://www.w3.org/2000/xmlns/" +} + +scopingElements = frozenset([ + (namespaces["html"], "applet"), + (namespaces["html"], "caption"), + (namespaces["html"], "html"), + (namespaces["html"], "marquee"), + (namespaces["html"], "object"), + (namespaces["html"], "table"), + (namespaces["html"], "td"), + (namespaces["html"], "th"), + (namespaces["mathml"], "mi"), + (namespaces["mathml"], "mo"), + (namespaces["mathml"], "mn"), + (namespaces["mathml"], "ms"), + (namespaces["mathml"], "mtext"), + (namespaces["mathml"], "annotation-xml"), + (namespaces["svg"], "foreignObject"), + (namespaces["svg"], "desc"), + (namespaces["svg"], "title"), +]) + +formattingElements = frozenset([ + (namespaces["html"], "a"), + (namespaces["html"], "b"), + (namespaces["html"], "big"), + (namespaces["html"], "code"), + (namespaces["html"], "em"), + (namespaces["html"], "font"), + (namespaces["html"], "i"), + (namespaces["html"], "nobr"), + (namespaces["html"], "s"), + (namespaces["html"], "small"), + (namespaces["html"], "strike"), + (namespaces["html"], "strong"), + (namespaces["html"], "tt"), + (namespaces["html"], "u") +]) + +specialElements = frozenset([ + (namespaces["html"], "address"), + (namespaces["html"], "applet"), + (namespaces["html"], "area"), + (namespaces["html"], "article"), + (namespaces["html"], "aside"), + (namespaces["html"], "base"), + (namespaces["html"], "basefont"), + (namespaces["html"], "bgsound"), + (namespaces["html"], "blockquote"), + (namespaces["html"], "body"), + (namespaces["html"], "br"), + (namespaces["html"], "button"), + (namespaces["html"], "caption"), + (namespaces["html"], "center"), + (namespaces["html"], "col"), + (namespaces["html"], "colgroup"), + (namespaces["html"], "command"), + (namespaces["html"], "dd"), + (namespaces["html"], "details"), + (namespaces["html"], "dir"), + (namespaces["html"], "div"), + (namespaces["html"], "dl"), + (namespaces["html"], "dt"), + (namespaces["html"], "embed"), + (namespaces["html"], "fieldset"), + (namespaces["html"], "figure"), + (namespaces["html"], "footer"), + (namespaces["html"], "form"), + (namespaces["html"], "frame"), + (namespaces["html"], "frameset"), + (namespaces["html"], "h1"), + (namespaces["html"], "h2"), + (namespaces["html"], "h3"), + (namespaces["html"], "h4"), + (namespaces["html"], "h5"), + (namespaces["html"], "h6"), + (namespaces["html"], "head"), + (namespaces["html"], "header"), + (namespaces["html"], "hr"), + (namespaces["html"], "html"), + (namespaces["html"], "iframe"), + # Note that image is commented out in the spec as "this isn't an + # element that can end up on the stack, so it doesn't matter," + (namespaces["html"], "image"), + (namespaces["html"], "img"), + (namespaces["html"], "input"), + (namespaces["html"], "isindex"), + (namespaces["html"], "li"), + (namespaces["html"], "link"), + (namespaces["html"], "listing"), + (namespaces["html"], "marquee"), + (namespaces["html"], "menu"), + (namespaces["html"], "meta"), + (namespaces["html"], "nav"), + (namespaces["html"], "noembed"), + (namespaces["html"], "noframes"), + (namespaces["html"], "noscript"), + (namespaces["html"], "object"), + (namespaces["html"], "ol"), + (namespaces["html"], "p"), + (namespaces["html"], "param"), + (namespaces["html"], "plaintext"), + (namespaces["html"], "pre"), + (namespaces["html"], "script"), + (namespaces["html"], "section"), + (namespaces["html"], "select"), + (namespaces["html"], "style"), + (namespaces["html"], "table"), + (namespaces["html"], "tbody"), + (namespaces["html"], "td"), + (namespaces["html"], "textarea"), + (namespaces["html"], "tfoot"), + (namespaces["html"], "th"), + (namespaces["html"], "thead"), + (namespaces["html"], "title"), + (namespaces["html"], "tr"), + (namespaces["html"], "ul"), + (namespaces["html"], "wbr"), + (namespaces["html"], "xmp"), + (namespaces["svg"], "foreignObject") +]) + +htmlIntegrationPointElements = frozenset([ + (namespaces["mathml"], "annotation-xml"), + (namespaces["svg"], "foreignObject"), + (namespaces["svg"], "desc"), + (namespaces["svg"], "title") +]) + +mathmlTextIntegrationPointElements = frozenset([ + (namespaces["mathml"], "mi"), + (namespaces["mathml"], "mo"), + (namespaces["mathml"], "mn"), + (namespaces["mathml"], "ms"), + (namespaces["mathml"], "mtext") +]) + +adjustSVGAttributes = { + "attributename": "attributeName", + "attributetype": "attributeType", + "basefrequency": "baseFrequency", + "baseprofile": "baseProfile", + "calcmode": "calcMode", + "clippathunits": "clipPathUnits", + "contentscripttype": "contentScriptType", + "contentstyletype": "contentStyleType", + "diffuseconstant": "diffuseConstant", + "edgemode": "edgeMode", + "externalresourcesrequired": "externalResourcesRequired", + "filterres": "filterRes", + "filterunits": "filterUnits", + "glyphref": "glyphRef", + "gradienttransform": "gradientTransform", + "gradientunits": "gradientUnits", + "kernelmatrix": "kernelMatrix", + "kernelunitlength": "kernelUnitLength", + "keypoints": "keyPoints", + "keysplines": "keySplines", + "keytimes": "keyTimes", + "lengthadjust": "lengthAdjust", + "limitingconeangle": "limitingConeAngle", + "markerheight": "markerHeight", + "markerunits": "markerUnits", + "markerwidth": "markerWidth", + "maskcontentunits": "maskContentUnits", + "maskunits": "maskUnits", + "numoctaves": "numOctaves", + "pathlength": "pathLength", + "patterncontentunits": "patternContentUnits", + "patterntransform": "patternTransform", + "patternunits": "patternUnits", + "pointsatx": "pointsAtX", + "pointsaty": "pointsAtY", + "pointsatz": "pointsAtZ", + "preservealpha": "preserveAlpha", + "preserveaspectratio": "preserveAspectRatio", + "primitiveunits": "primitiveUnits", + "refx": "refX", + "refy": "refY", + "repeatcount": "repeatCount", + "repeatdur": "repeatDur", + "requiredextensions": "requiredExtensions", + "requiredfeatures": "requiredFeatures", + "specularconstant": "specularConstant", + "specularexponent": "specularExponent", + "spreadmethod": "spreadMethod", + "startoffset": "startOffset", + "stddeviation": "stdDeviation", + "stitchtiles": "stitchTiles", + "surfacescale": "surfaceScale", + "systemlanguage": "systemLanguage", + "tablevalues": "tableValues", + "targetx": "targetX", + "targety": "targetY", + "textlength": "textLength", + "viewbox": "viewBox", + "viewtarget": "viewTarget", + "xchannelselector": "xChannelSelector", + "ychannelselector": "yChannelSelector", + "zoomandpan": "zoomAndPan" +} + +adjustMathMLAttributes = {"definitionurl": "definitionURL"} + +adjustForeignAttributes = { + "xlink:actuate": ("xlink", "actuate", namespaces["xlink"]), + "xlink:arcrole": ("xlink", "arcrole", namespaces["xlink"]), + "xlink:href": ("xlink", "href", namespaces["xlink"]), + "xlink:role": ("xlink", "role", namespaces["xlink"]), + "xlink:show": ("xlink", "show", namespaces["xlink"]), + "xlink:title": ("xlink", "title", namespaces["xlink"]), + "xlink:type": ("xlink", "type", namespaces["xlink"]), + "xml:base": ("xml", "base", namespaces["xml"]), + "xml:lang": ("xml", "lang", namespaces["xml"]), + "xml:space": ("xml", "space", namespaces["xml"]), + "xmlns": (None, "xmlns", namespaces["xmlns"]), + "xmlns:xlink": ("xmlns", "xlink", namespaces["xmlns"]) +} + +unadjustForeignAttributes = dict([((ns, local), qname) for qname, (prefix, local, ns) in + adjustForeignAttributes.items()]) + +spaceCharacters = frozenset([ + "\t", + "\n", + "\u000C", + " ", + "\r" +]) + +tableInsertModeElements = frozenset([ + "table", + "tbody", + "tfoot", + "thead", + "tr" +]) + +asciiLowercase = frozenset(string.ascii_lowercase) +asciiUppercase = frozenset(string.ascii_uppercase) +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]) + +# Heading elements need to be ordered +headingElements = ( + "h1", + "h2", + "h3", + "h4", + "h5", + "h6" +) + +voidElements = frozenset([ + "base", + "command", + "event-source", + "link", + "meta", + "hr", + "br", + "img", + "embed", + "param", + "area", + "col", + "input", + "source", + "track" +]) + +cdataElements = frozenset(['title', 'textarea']) + +rcdataElements = frozenset([ + 'style', + 'script', + 'xmp', + 'iframe', + 'noembed', + 'noframes', + 'noscript' +]) + +booleanAttributes = { + "": frozenset(["irrelevant", "itemscope"]), + "style": frozenset(["scoped"]), + "img": frozenset(["ismap"]), + "audio": frozenset(["autoplay", "controls"]), + "video": frozenset(["autoplay", "controls"]), + "script": frozenset(["defer", "async"]), + "details": frozenset(["open"]), + "datagrid": frozenset(["multiple", "disabled"]), + "command": frozenset(["hidden", "disabled", "checked", "default"]), + "hr": frozenset(["noshade"]), + "menu": frozenset(["autosubmit"]), + "fieldset": frozenset(["disabled", "readonly"]), + "option": frozenset(["disabled", "readonly", "selected"]), + "optgroup": frozenset(["disabled", "readonly"]), + "button": frozenset(["disabled", "autofocus"]), + "input": frozenset(["disabled", "readonly", "required", "autofocus", "checked", "ismap"]), + "select": frozenset(["disabled", "readonly", "autofocus", "multiple"]), + "output": frozenset(["disabled", "readonly"]), + "iframe": frozenset(["seamless"]), +} + +# entitiesWindows1252 has to be _ordered_ and needs to have an index. It +# therefore can't be a frozenset. +entitiesWindows1252 = ( + 8364, # 0x80 0x20AC EURO SIGN + 65533, # 0x81 UNDEFINED + 8218, # 0x82 0x201A SINGLE LOW-9 QUOTATION MARK + 402, # 0x83 0x0192 LATIN SMALL LETTER F WITH HOOK + 8222, # 0x84 0x201E DOUBLE LOW-9 QUOTATION MARK + 8230, # 0x85 0x2026 HORIZONTAL ELLIPSIS + 8224, # 0x86 0x2020 DAGGER + 8225, # 0x87 0x2021 DOUBLE DAGGER + 710, # 0x88 0x02C6 MODIFIER LETTER CIRCUMFLEX ACCENT + 8240, # 0x89 0x2030 PER MILLE SIGN + 352, # 0x8A 0x0160 LATIN CAPITAL LETTER S WITH CARON + 8249, # 0x8B 0x2039 SINGLE LEFT-POINTING ANGLE QUOTATION MARK + 338, # 0x8C 0x0152 LATIN CAPITAL LIGATURE OE + 65533, # 0x8D UNDEFINED + 381, # 0x8E 0x017D LATIN CAPITAL LETTER Z WITH CARON + 65533, # 0x8F UNDEFINED + 65533, # 0x90 UNDEFINED + 8216, # 0x91 0x2018 LEFT SINGLE QUOTATION MARK + 8217, # 0x92 0x2019 RIGHT SINGLE QUOTATION MARK + 8220, # 0x93 0x201C LEFT DOUBLE QUOTATION MARK + 8221, # 0x94 0x201D RIGHT DOUBLE QUOTATION MARK + 8226, # 0x95 0x2022 BULLET + 8211, # 0x96 0x2013 EN DASH + 8212, # 0x97 0x2014 EM DASH + 732, # 0x98 0x02DC SMALL TILDE + 8482, # 0x99 0x2122 TRADE MARK SIGN + 353, # 0x9A 0x0161 LATIN SMALL LETTER S WITH CARON + 8250, # 0x9B 0x203A SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + 339, # 0x9C 0x0153 LATIN SMALL LIGATURE OE + 65533, # 0x9D UNDEFINED + 382, # 0x9E 0x017E LATIN SMALL LETTER Z WITH CARON + 376 # 0x9F 0x0178 LATIN CAPITAL LETTER Y WITH DIAERESIS +) + +xmlEntities = frozenset(['lt;', 'gt;', 'amp;', 'apos;', 'quot;']) + +entities = { + "AElig": "\xc6", + "AElig;": "\xc6", + "AMP": "&", + "AMP;": "&", + "Aacute": "\xc1", + "Aacute;": "\xc1", + "Abreve;": "\u0102", + "Acirc": "\xc2", + "Acirc;": "\xc2", + "Acy;": "\u0410", + "Afr;": "\U0001d504", + "Agrave": "\xc0", + "Agrave;": "\xc0", + "Alpha;": "\u0391", + "Amacr;": "\u0100", + "And;": "\u2a53", + "Aogon;": "\u0104", + "Aopf;": "\U0001d538", + "ApplyFunction;": "\u2061", + "Aring": "\xc5", + "Aring;": "\xc5", + "Ascr;": "\U0001d49c", + "Assign;": "\u2254", + "Atilde": "\xc3", + "Atilde;": "\xc3", + "Auml": "\xc4", + "Auml;": "\xc4", + "Backslash;": "\u2216", + "Barv;": "\u2ae7", + "Barwed;": "\u2306", + "Bcy;": "\u0411", + "Because;": "\u2235", + "Bernoullis;": "\u212c", + "Beta;": "\u0392", + "Bfr;": "\U0001d505", + "Bopf;": "\U0001d539", + "Breve;": "\u02d8", + "Bscr;": "\u212c", + "Bumpeq;": "\u224e", + "CHcy;": "\u0427", + "COPY": "\xa9", + "COPY;": "\xa9", + "Cacute;": "\u0106", + "Cap;": "\u22d2", + "CapitalDifferentialD;": "\u2145", + "Cayleys;": "\u212d", + "Ccaron;": "\u010c", + "Ccedil": "\xc7", + "Ccedil;": "\xc7", + "Ccirc;": "\u0108", + "Cconint;": "\u2230", + "Cdot;": "\u010a", + "Cedilla;": "\xb8", + "CenterDot;": "\xb7", + "Cfr;": "\u212d", + "Chi;": "\u03a7", + "CircleDot;": "\u2299", + "CircleMinus;": "\u2296", + "CirclePlus;": "\u2295", + "CircleTimes;": "\u2297", + "ClockwiseContourIntegral;": "\u2232", + "CloseCurlyDoubleQuote;": "\u201d", + "CloseCurlyQuote;": "\u2019", + "Colon;": "\u2237", + "Colone;": "\u2a74", + "Congruent;": "\u2261", + "Conint;": "\u222f", + "ContourIntegral;": "\u222e", + "Copf;": "\u2102", + "Coproduct;": "\u2210", + "CounterClockwiseContourIntegral;": "\u2233", + "Cross;": "\u2a2f", + "Cscr;": "\U0001d49e", + "Cup;": "\u22d3", + "CupCap;": "\u224d", + "DD;": "\u2145", + "DDotrahd;": "\u2911", + "DJcy;": "\u0402", + "DScy;": "\u0405", + "DZcy;": "\u040f", + "Dagger;": "\u2021", + "Darr;": "\u21a1", + "Dashv;": "\u2ae4", + "Dcaron;": "\u010e", + "Dcy;": "\u0414", + "Del;": "\u2207", + "Delta;": "\u0394", + "Dfr;": "\U0001d507", + "DiacriticalAcute;": "\xb4", + "DiacriticalDot;": "\u02d9", + "DiacriticalDoubleAcute;": "\u02dd", + "DiacriticalGrave;": "`", + "DiacriticalTilde;": "\u02dc", + "Diamond;": "\u22c4", + "DifferentialD;": "\u2146", + "Dopf;": "\U0001d53b", + "Dot;": "\xa8", + "DotDot;": "\u20dc", + "DotEqual;": "\u2250", + "DoubleContourIntegral;": "\u222f", + "DoubleDot;": "\xa8", + "DoubleDownArrow;": "\u21d3", + "DoubleLeftArrow;": "\u21d0", + "DoubleLeftRightArrow;": "\u21d4", + "DoubleLeftTee;": "\u2ae4", + "DoubleLongLeftArrow;": "\u27f8", + "DoubleLongLeftRightArrow;": "\u27fa", + "DoubleLongRightArrow;": "\u27f9", + "DoubleRightArrow;": "\u21d2", + "DoubleRightTee;": "\u22a8", + "DoubleUpArrow;": "\u21d1", + "DoubleUpDownArrow;": "\u21d5", + "DoubleVerticalBar;": "\u2225", + "DownArrow;": "\u2193", + "DownArrowBar;": "\u2913", + "DownArrowUpArrow;": "\u21f5", + "DownBreve;": "\u0311", + "DownLeftRightVector;": "\u2950", + "DownLeftTeeVector;": "\u295e", + "DownLeftVector;": "\u21bd", + "DownLeftVectorBar;": "\u2956", + "DownRightTeeVector;": "\u295f", + "DownRightVector;": "\u21c1", + "DownRightVectorBar;": "\u2957", + "DownTee;": "\u22a4", + "DownTeeArrow;": "\u21a7", + "Downarrow;": "\u21d3", + "Dscr;": "\U0001d49f", + "Dstrok;": "\u0110", + "ENG;": "\u014a", + "ETH": "\xd0", + "ETH;": "\xd0", + "Eacute": "\xc9", + "Eacute;": "\xc9", + "Ecaron;": "\u011a", + "Ecirc": "\xca", + "Ecirc;": "\xca", + "Ecy;": "\u042d", + "Edot;": "\u0116", + "Efr;": "\U0001d508", + "Egrave": "\xc8", + "Egrave;": "\xc8", + "Element;": "\u2208", + "Emacr;": "\u0112", + "EmptySmallSquare;": "\u25fb", + "EmptyVerySmallSquare;": "\u25ab", + "Eogon;": "\u0118", + "Eopf;": "\U0001d53c", + "Epsilon;": "\u0395", + "Equal;": "\u2a75", + "EqualTilde;": "\u2242", + "Equilibrium;": "\u21cc", + "Escr;": "\u2130", + "Esim;": "\u2a73", + "Eta;": "\u0397", + "Euml": "\xcb", + "Euml;": "\xcb", + "Exists;": "\u2203", + "ExponentialE;": "\u2147", + "Fcy;": "\u0424", + "Ffr;": "\U0001d509", + "FilledSmallSquare;": "\u25fc", + "FilledVerySmallSquare;": "\u25aa", + "Fopf;": "\U0001d53d", + "ForAll;": "\u2200", + "Fouriertrf;": "\u2131", + "Fscr;": "\u2131", + "GJcy;": "\u0403", + "GT": ">", + "GT;": ">", + "Gamma;": "\u0393", + "Gammad;": "\u03dc", + "Gbreve;": "\u011e", + "Gcedil;": "\u0122", + "Gcirc;": "\u011c", + "Gcy;": "\u0413", + "Gdot;": "\u0120", + "Gfr;": "\U0001d50a", + "Gg;": "\u22d9", + "Gopf;": "\U0001d53e", + "GreaterEqual;": "\u2265", + "GreaterEqualLess;": "\u22db", + "GreaterFullEqual;": "\u2267", + "GreaterGreater;": "\u2aa2", + "GreaterLess;": "\u2277", + "GreaterSlantEqual;": "\u2a7e", + "GreaterTilde;": "\u2273", + "Gscr;": "\U0001d4a2", + "Gt;": "\u226b", + "HARDcy;": "\u042a", + "Hacek;": "\u02c7", + "Hat;": "^", + "Hcirc;": "\u0124", + "Hfr;": "\u210c", + "HilbertSpace;": "\u210b", + "Hopf;": "\u210d", + "HorizontalLine;": "\u2500", + "Hscr;": "\u210b", + "Hstrok;": "\u0126", + "HumpDownHump;": "\u224e", + "HumpEqual;": "\u224f", + "IEcy;": "\u0415", + "IJlig;": "\u0132", + "IOcy;": "\u0401", + "Iacute": "\xcd", + "Iacute;": "\xcd", + "Icirc": "\xce", + "Icirc;": "\xce", + "Icy;": "\u0418", + "Idot;": "\u0130", + "Ifr;": "\u2111", + "Igrave": "\xcc", + "Igrave;": "\xcc", + "Im;": "\u2111", + "Imacr;": "\u012a", + "ImaginaryI;": "\u2148", + "Implies;": "\u21d2", + "Int;": "\u222c", + "Integral;": "\u222b", + "Intersection;": "\u22c2", + "InvisibleComma;": "\u2063", + "InvisibleTimes;": "\u2062", + "Iogon;": "\u012e", + "Iopf;": "\U0001d540", + "Iota;": "\u0399", + "Iscr;": "\u2110", + "Itilde;": "\u0128", + "Iukcy;": "\u0406", + "Iuml": "\xcf", + "Iuml;": "\xcf", + "Jcirc;": "\u0134", + "Jcy;": "\u0419", + "Jfr;": "\U0001d50d", + "Jopf;": "\U0001d541", + "Jscr;": "\U0001d4a5", + "Jsercy;": "\u0408", + "Jukcy;": "\u0404", + "KHcy;": "\u0425", + "KJcy;": "\u040c", + "Kappa;": "\u039a", + "Kcedil;": "\u0136", + "Kcy;": "\u041a", + "Kfr;": "\U0001d50e", + "Kopf;": "\U0001d542", + "Kscr;": "\U0001d4a6", + "LJcy;": "\u0409", + "LT": "<", + "LT;": "<", + "Lacute;": "\u0139", + "Lambda;": "\u039b", + "Lang;": "\u27ea", + "Laplacetrf;": "\u2112", + "Larr;": "\u219e", + "Lcaron;": "\u013d", + "Lcedil;": "\u013b", + "Lcy;": "\u041b", + "LeftAngleBracket;": "\u27e8", + "LeftArrow;": "\u2190", + "LeftArrowBar;": "\u21e4", + "LeftArrowRightArrow;": "\u21c6", + "LeftCeiling;": "\u2308", + "LeftDoubleBracket;": "\u27e6", + "LeftDownTeeVector;": "\u2961", + "LeftDownVector;": "\u21c3", + "LeftDownVectorBar;": "\u2959", + "LeftFloor;": "\u230a", + "LeftRightArrow;": "\u2194", + "LeftRightVector;": "\u294e", + "LeftTee;": "\u22a3", + "LeftTeeArrow;": "\u21a4", + "LeftTeeVector;": "\u295a", + "LeftTriangle;": "\u22b2", + "LeftTriangleBar;": "\u29cf", + "LeftTriangleEqual;": "\u22b4", + "LeftUpDownVector;": "\u2951", + "LeftUpTeeVector;": "\u2960", + "LeftUpVector;": "\u21bf", + "LeftUpVectorBar;": "\u2958", + "LeftVector;": "\u21bc", + "LeftVectorBar;": "\u2952", + "Leftarrow;": "\u21d0", + "Leftrightarrow;": "\u21d4", + "LessEqualGreater;": "\u22da", + "LessFullEqual;": "\u2266", + "LessGreater;": "\u2276", + "LessLess;": "\u2aa1", + "LessSlantEqual;": "\u2a7d", + "LessTilde;": "\u2272", + "Lfr;": "\U0001d50f", + "Ll;": "\u22d8", + "Lleftarrow;": "\u21da", + "Lmidot;": "\u013f", + "LongLeftArrow;": "\u27f5", + "LongLeftRightArrow;": "\u27f7", + "LongRightArrow;": "\u27f6", + "Longleftarrow;": "\u27f8", + "Longleftrightarrow;": "\u27fa", + "Longrightarrow;": "\u27f9", + "Lopf;": "\U0001d543", + "LowerLeftArrow;": "\u2199", + "LowerRightArrow;": "\u2198", + "Lscr;": "\u2112", + "Lsh;": "\u21b0", + "Lstrok;": "\u0141", + "Lt;": "\u226a", + "Map;": "\u2905", + "Mcy;": "\u041c", + "MediumSpace;": "\u205f", + "Mellintrf;": "\u2133", + "Mfr;": "\U0001d510", + "MinusPlus;": "\u2213", + "Mopf;": "\U0001d544", + "Mscr;": "\u2133", + "Mu;": "\u039c", + "NJcy;": "\u040a", + "Nacute;": "\u0143", + "Ncaron;": "\u0147", + "Ncedil;": "\u0145", + "Ncy;": "\u041d", + "NegativeMediumSpace;": "\u200b", + "NegativeThickSpace;": "\u200b", + "NegativeThinSpace;": "\u200b", + "NegativeVeryThinSpace;": "\u200b", + "NestedGreaterGreater;": "\u226b", + "NestedLessLess;": "\u226a", + "NewLine;": "\n", + "Nfr;": "\U0001d511", + "NoBreak;": "\u2060", + "NonBreakingSpace;": "\xa0", + "Nopf;": "\u2115", + "Not;": "\u2aec", + "NotCongruent;": "\u2262", + "NotCupCap;": "\u226d", + "NotDoubleVerticalBar;": "\u2226", + "NotElement;": "\u2209", + "NotEqual;": "\u2260", + "NotEqualTilde;": "\u2242\u0338", + "NotExists;": "\u2204", + "NotGreater;": "\u226f", + "NotGreaterEqual;": "\u2271", + "NotGreaterFullEqual;": "\u2267\u0338", + "NotGreaterGreater;": "\u226b\u0338", + "NotGreaterLess;": "\u2279", + "NotGreaterSlantEqual;": "\u2a7e\u0338", + "NotGreaterTilde;": "\u2275", + "NotHumpDownHump;": "\u224e\u0338", + "NotHumpEqual;": "\u224f\u0338", + "NotLeftTriangle;": "\u22ea", + "NotLeftTriangleBar;": "\u29cf\u0338", + "NotLeftTriangleEqual;": "\u22ec", + "NotLess;": "\u226e", + "NotLessEqual;": "\u2270", + "NotLessGreater;": "\u2278", + "NotLessLess;": "\u226a\u0338", + "NotLessSlantEqual;": "\u2a7d\u0338", + "NotLessTilde;": "\u2274", + "NotNestedGreaterGreater;": "\u2aa2\u0338", + "NotNestedLessLess;": "\u2aa1\u0338", + "NotPrecedes;": "\u2280", + "NotPrecedesEqual;": "\u2aaf\u0338", + "NotPrecedesSlantEqual;": "\u22e0", + "NotReverseElement;": "\u220c", + "NotRightTriangle;": "\u22eb", + "NotRightTriangleBar;": "\u29d0\u0338", + "NotRightTriangleEqual;": "\u22ed", + "NotSquareSubset;": "\u228f\u0338", + "NotSquareSubsetEqual;": "\u22e2", + "NotSquareSuperset;": "\u2290\u0338", + "NotSquareSupersetEqual;": "\u22e3", + "NotSubset;": "\u2282\u20d2", + "NotSubsetEqual;": "\u2288", + "NotSucceeds;": "\u2281", + "NotSucceedsEqual;": "\u2ab0\u0338", + "NotSucceedsSlantEqual;": "\u22e1", + "NotSucceedsTilde;": "\u227f\u0338", + "NotSuperset;": "\u2283\u20d2", + "NotSupersetEqual;": "\u2289", + "NotTilde;": "\u2241", + "NotTildeEqual;": "\u2244", + "NotTildeFullEqual;": "\u2247", + "NotTildeTilde;": "\u2249", + "NotVerticalBar;": "\u2224", + "Nscr;": "\U0001d4a9", + "Ntilde": "\xd1", + "Ntilde;": "\xd1", + "Nu;": "\u039d", + "OElig;": "\u0152", + "Oacute": "\xd3", + "Oacute;": "\xd3", + "Ocirc": "\xd4", + "Ocirc;": "\xd4", + "Ocy;": "\u041e", + "Odblac;": "\u0150", + "Ofr;": "\U0001d512", + "Ograve": "\xd2", + "Ograve;": "\xd2", + "Omacr;": "\u014c", + "Omega;": "\u03a9", + "Omicron;": "\u039f", + "Oopf;": "\U0001d546", + "OpenCurlyDoubleQuote;": "\u201c", + "OpenCurlyQuote;": "\u2018", + "Or;": "\u2a54", + "Oscr;": "\U0001d4aa", + "Oslash": "\xd8", + "Oslash;": "\xd8", + "Otilde": "\xd5", + "Otilde;": "\xd5", + "Otimes;": "\u2a37", + "Ouml": "\xd6", + "Ouml;": "\xd6", + "OverBar;": "\u203e", + "OverBrace;": "\u23de", + "OverBracket;": "\u23b4", + "OverParenthesis;": "\u23dc", + "PartialD;": "\u2202", + "Pcy;": "\u041f", + "Pfr;": "\U0001d513", + "Phi;": "\u03a6", + "Pi;": "\u03a0", + "PlusMinus;": "\xb1", + "Poincareplane;": "\u210c", + "Popf;": "\u2119", + "Pr;": "\u2abb", + "Precedes;": "\u227a", + "PrecedesEqual;": "\u2aaf", + "PrecedesSlantEqual;": "\u227c", + "PrecedesTilde;": "\u227e", + "Prime;": "\u2033", + "Product;": "\u220f", + "Proportion;": "\u2237", + "Proportional;": "\u221d", + "Pscr;": "\U0001d4ab", + "Psi;": "\u03a8", + "QUOT": "\"", + "QUOT;": "\"", + "Qfr;": "\U0001d514", + "Qopf;": "\u211a", + "Qscr;": "\U0001d4ac", + "RBarr;": "\u2910", + "REG": "\xae", + "REG;": "\xae", + "Racute;": "\u0154", + "Rang;": "\u27eb", + "Rarr;": "\u21a0", + "Rarrtl;": "\u2916", + "Rcaron;": "\u0158", + "Rcedil;": "\u0156", + "Rcy;": "\u0420", + "Re;": "\u211c", + "ReverseElement;": "\u220b", + "ReverseEquilibrium;": "\u21cb", + "ReverseUpEquilibrium;": "\u296f", + "Rfr;": "\u211c", + "Rho;": "\u03a1", + "RightAngleBracket;": "\u27e9", + "RightArrow;": "\u2192", + "RightArrowBar;": "\u21e5", + "RightArrowLeftArrow;": "\u21c4", + "RightCeiling;": "\u2309", + "RightDoubleBracket;": "\u27e7", + "RightDownTeeVector;": "\u295d", + "RightDownVector;": "\u21c2", + "RightDownVectorBar;": "\u2955", + "RightFloor;": "\u230b", + "RightTee;": "\u22a2", + "RightTeeArrow;": "\u21a6", + "RightTeeVector;": "\u295b", + "RightTriangle;": "\u22b3", + "RightTriangleBar;": "\u29d0", + "RightTriangleEqual;": "\u22b5", + "RightUpDownVector;": "\u294f", + "RightUpTeeVector;": "\u295c", + "RightUpVector;": "\u21be", + "RightUpVectorBar;": "\u2954", + "RightVector;": "\u21c0", + "RightVectorBar;": "\u2953", + "Rightarrow;": "\u21d2", + "Ropf;": "\u211d", + "RoundImplies;": "\u2970", + "Rrightarrow;": "\u21db", + "Rscr;": "\u211b", + "Rsh;": "\u21b1", + "RuleDelayed;": "\u29f4", + "SHCHcy;": "\u0429", + "SHcy;": "\u0428", + "SOFTcy;": "\u042c", + "Sacute;": "\u015a", + "Sc;": "\u2abc", + "Scaron;": "\u0160", + "Scedil;": "\u015e", + "Scirc;": "\u015c", + "Scy;": "\u0421", + "Sfr;": "\U0001d516", + "ShortDownArrow;": "\u2193", + "ShortLeftArrow;": "\u2190", + "ShortRightArrow;": "\u2192", + "ShortUpArrow;": "\u2191", + "Sigma;": "\u03a3", + "SmallCircle;": "\u2218", + "Sopf;": "\U0001d54a", + "Sqrt;": "\u221a", + "Square;": "\u25a1", + "SquareIntersection;": "\u2293", + "SquareSubset;": "\u228f", + "SquareSubsetEqual;": "\u2291", + "SquareSuperset;": "\u2290", + "SquareSupersetEqual;": "\u2292", + "SquareUnion;": "\u2294", + "Sscr;": "\U0001d4ae", + "Star;": "\u22c6", + "Sub;": "\u22d0", + "Subset;": "\u22d0", + "SubsetEqual;": "\u2286", + "Succeeds;": "\u227b", + "SucceedsEqual;": "\u2ab0", + "SucceedsSlantEqual;": "\u227d", + "SucceedsTilde;": "\u227f", + "SuchThat;": "\u220b", + "Sum;": "\u2211", + "Sup;": "\u22d1", + "Superset;": "\u2283", + "SupersetEqual;": "\u2287", + "Supset;": "\u22d1", + "THORN": "\xde", + "THORN;": "\xde", + "TRADE;": "\u2122", + "TSHcy;": "\u040b", + "TScy;": "\u0426", + "Tab;": "\t", + "Tau;": "\u03a4", + "Tcaron;": "\u0164", + "Tcedil;": "\u0162", + "Tcy;": "\u0422", + "Tfr;": "\U0001d517", + "Therefore;": "\u2234", + "Theta;": "\u0398", + "ThickSpace;": "\u205f\u200a", + "ThinSpace;": "\u2009", + "Tilde;": "\u223c", + "TildeEqual;": "\u2243", + "TildeFullEqual;": "\u2245", + "TildeTilde;": "\u2248", + "Topf;": "\U0001d54b", + "TripleDot;": "\u20db", + "Tscr;": "\U0001d4af", + "Tstrok;": "\u0166", + "Uacute": "\xda", + "Uacute;": "\xda", + "Uarr;": "\u219f", + "Uarrocir;": "\u2949", + "Ubrcy;": "\u040e", + "Ubreve;": "\u016c", + "Ucirc": "\xdb", + "Ucirc;": "\xdb", + "Ucy;": "\u0423", + "Udblac;": "\u0170", + "Ufr;": "\U0001d518", + "Ugrave": "\xd9", + "Ugrave;": "\xd9", + "Umacr;": "\u016a", + "UnderBar;": "_", + "UnderBrace;": "\u23df", + "UnderBracket;": "\u23b5", + "UnderParenthesis;": "\u23dd", + "Union;": "\u22c3", + "UnionPlus;": "\u228e", + "Uogon;": "\u0172", + "Uopf;": "\U0001d54c", + "UpArrow;": "\u2191", + "UpArrowBar;": "\u2912", + "UpArrowDownArrow;": "\u21c5", + "UpDownArrow;": "\u2195", + "UpEquilibrium;": "\u296e", + "UpTee;": "\u22a5", + "UpTeeArrow;": "\u21a5", + "Uparrow;": "\u21d1", + "Updownarrow;": "\u21d5", + "UpperLeftArrow;": "\u2196", + "UpperRightArrow;": "\u2197", + "Upsi;": "\u03d2", + "Upsilon;": "\u03a5", + "Uring;": "\u016e", + "Uscr;": "\U0001d4b0", + "Utilde;": "\u0168", + "Uuml": "\xdc", + "Uuml;": "\xdc", + "VDash;": "\u22ab", + "Vbar;": "\u2aeb", + "Vcy;": "\u0412", + "Vdash;": "\u22a9", + "Vdashl;": "\u2ae6", + "Vee;": "\u22c1", + "Verbar;": "\u2016", + "Vert;": "\u2016", + "VerticalBar;": "\u2223", + "VerticalLine;": "|", + "VerticalSeparator;": "\u2758", + "VerticalTilde;": "\u2240", + "VeryThinSpace;": "\u200a", + "Vfr;": "\U0001d519", + "Vopf;": "\U0001d54d", + "Vscr;": "\U0001d4b1", + "Vvdash;": "\u22aa", + "Wcirc;": "\u0174", + "Wedge;": "\u22c0", + "Wfr;": "\U0001d51a", + "Wopf;": "\U0001d54e", + "Wscr;": "\U0001d4b2", + "Xfr;": "\U0001d51b", + "Xi;": "\u039e", + "Xopf;": "\U0001d54f", + "Xscr;": "\U0001d4b3", + "YAcy;": "\u042f", + "YIcy;": "\u0407", + "YUcy;": "\u042e", + "Yacute": "\xdd", + "Yacute;": "\xdd", + "Ycirc;": "\u0176", + "Ycy;": "\u042b", + "Yfr;": "\U0001d51c", + "Yopf;": "\U0001d550", + "Yscr;": "\U0001d4b4", + "Yuml;": "\u0178", + "ZHcy;": "\u0416", + "Zacute;": "\u0179", + "Zcaron;": "\u017d", + "Zcy;": "\u0417", + "Zdot;": "\u017b", + "ZeroWidthSpace;": "\u200b", + "Zeta;": "\u0396", + "Zfr;": "\u2128", + "Zopf;": "\u2124", + "Zscr;": "\U0001d4b5", + "aacute": "\xe1", + "aacute;": "\xe1", + "abreve;": "\u0103", + "ac;": "\u223e", + "acE;": "\u223e\u0333", + "acd;": "\u223f", + "acirc": "\xe2", + "acirc;": "\xe2", + "acute": "\xb4", + "acute;": "\xb4", + "acy;": "\u0430", + "aelig": "\xe6", + "aelig;": "\xe6", + "af;": "\u2061", + "afr;": "\U0001d51e", + "agrave": "\xe0", + "agrave;": "\xe0", + "alefsym;": "\u2135", + "aleph;": "\u2135", + "alpha;": "\u03b1", + "amacr;": "\u0101", + "amalg;": "\u2a3f", + "amp": "&", + "amp;": "&", + "and;": "\u2227", + "andand;": "\u2a55", + "andd;": "\u2a5c", + "andslope;": "\u2a58", + "andv;": "\u2a5a", + "ang;": "\u2220", + "ange;": "\u29a4", + "angle;": "\u2220", + "angmsd;": "\u2221", + "angmsdaa;": "\u29a8", + "angmsdab;": "\u29a9", + "angmsdac;": "\u29aa", + "angmsdad;": "\u29ab", + "angmsdae;": "\u29ac", + "angmsdaf;": "\u29ad", + "angmsdag;": "\u29ae", + "angmsdah;": "\u29af", + "angrt;": "\u221f", + "angrtvb;": "\u22be", + "angrtvbd;": "\u299d", + "angsph;": "\u2222", + "angst;": "\xc5", + "angzarr;": "\u237c", + "aogon;": "\u0105", + "aopf;": "\U0001d552", + "ap;": "\u2248", + "apE;": "\u2a70", + "apacir;": "\u2a6f", + "ape;": "\u224a", + "apid;": "\u224b", + "apos;": "'", + "approx;": "\u2248", + "approxeq;": "\u224a", + "aring": "\xe5", + "aring;": "\xe5", + "ascr;": "\U0001d4b6", + "ast;": "*", + "asymp;": "\u2248", + "asympeq;": "\u224d", + "atilde": "\xe3", + "atilde;": "\xe3", + "auml": "\xe4", + "auml;": "\xe4", + "awconint;": "\u2233", + "awint;": "\u2a11", + "bNot;": "\u2aed", + "backcong;": "\u224c", + "backepsilon;": "\u03f6", + "backprime;": "\u2035", + "backsim;": "\u223d", + "backsimeq;": "\u22cd", + "barvee;": "\u22bd", + "barwed;": "\u2305", + "barwedge;": "\u2305", + "bbrk;": "\u23b5", + "bbrktbrk;": "\u23b6", + "bcong;": "\u224c", + "bcy;": "\u0431", + "bdquo;": "\u201e", + "becaus;": "\u2235", + "because;": "\u2235", + "bemptyv;": "\u29b0", + "bepsi;": "\u03f6", + "bernou;": "\u212c", + "beta;": "\u03b2", + "beth;": "\u2136", + "between;": "\u226c", + "bfr;": "\U0001d51f", + "bigcap;": "\u22c2", + "bigcirc;": "\u25ef", + "bigcup;": "\u22c3", + "bigodot;": "\u2a00", + "bigoplus;": "\u2a01", + "bigotimes;": "\u2a02", + "bigsqcup;": "\u2a06", + "bigstar;": "\u2605", + "bigtriangledown;": "\u25bd", + "bigtriangleup;": "\u25b3", + "biguplus;": "\u2a04", + "bigvee;": "\u22c1", + "bigwedge;": "\u22c0", + "bkarow;": "\u290d", + "blacklozenge;": "\u29eb", + "blacksquare;": "\u25aa", + "blacktriangle;": "\u25b4", + "blacktriangledown;": "\u25be", + "blacktriangleleft;": "\u25c2", + "blacktriangleright;": "\u25b8", + "blank;": "\u2423", + "blk12;": "\u2592", + "blk14;": "\u2591", + "blk34;": "\u2593", + "block;": "\u2588", + "bne;": "=\u20e5", + "bnequiv;": "\u2261\u20e5", + "bnot;": "\u2310", + "bopf;": "\U0001d553", + "bot;": "\u22a5", + "bottom;": "\u22a5", + "bowtie;": "\u22c8", + "boxDL;": "\u2557", + "boxDR;": "\u2554", + "boxDl;": "\u2556", + "boxDr;": "\u2553", + "boxH;": "\u2550", + "boxHD;": "\u2566", + "boxHU;": "\u2569", + "boxHd;": "\u2564", + "boxHu;": "\u2567", + "boxUL;": "\u255d", + "boxUR;": "\u255a", + "boxUl;": "\u255c", + "boxUr;": "\u2559", + "boxV;": "\u2551", + "boxVH;": "\u256c", + "boxVL;": "\u2563", + "boxVR;": "\u2560", + "boxVh;": "\u256b", + "boxVl;": "\u2562", + "boxVr;": "\u255f", + "boxbox;": "\u29c9", + "boxdL;": "\u2555", + "boxdR;": "\u2552", + "boxdl;": "\u2510", + "boxdr;": "\u250c", + "boxh;": "\u2500", + "boxhD;": "\u2565", + "boxhU;": "\u2568", + "boxhd;": "\u252c", + "boxhu;": "\u2534", + "boxminus;": "\u229f", + "boxplus;": "\u229e", + "boxtimes;": "\u22a0", + "boxuL;": "\u255b", + "boxuR;": "\u2558", + "boxul;": "\u2518", + "boxur;": "\u2514", + "boxv;": "\u2502", + "boxvH;": "\u256a", + "boxvL;": "\u2561", + "boxvR;": "\u255e", + "boxvh;": "\u253c", + "boxvl;": "\u2524", + "boxvr;": "\u251c", + "bprime;": "\u2035", + "breve;": "\u02d8", + "brvbar": "\xa6", + "brvbar;": "\xa6", + "bscr;": "\U0001d4b7", + "bsemi;": "\u204f", + "bsim;": "\u223d", + "bsime;": "\u22cd", + "bsol;": "\\", + "bsolb;": "\u29c5", + "bsolhsub;": "\u27c8", + "bull;": "\u2022", + "bullet;": "\u2022", + "bump;": "\u224e", + "bumpE;": "\u2aae", + "bumpe;": "\u224f", + "bumpeq;": "\u224f", + "cacute;": "\u0107", + "cap;": "\u2229", + "capand;": "\u2a44", + "capbrcup;": "\u2a49", + "capcap;": "\u2a4b", + "capcup;": "\u2a47", + "capdot;": "\u2a40", + "caps;": "\u2229\ufe00", + "caret;": "\u2041", + "caron;": "\u02c7", + "ccaps;": "\u2a4d", + "ccaron;": "\u010d", + "ccedil": "\xe7", + "ccedil;": "\xe7", + "ccirc;": "\u0109", + "ccups;": "\u2a4c", + "ccupssm;": "\u2a50", + "cdot;": "\u010b", + "cedil": "\xb8", + "cedil;": "\xb8", + "cemptyv;": "\u29b2", + "cent": "\xa2", + "cent;": "\xa2", + "centerdot;": "\xb7", + "cfr;": "\U0001d520", + "chcy;": "\u0447", + "check;": "\u2713", + "checkmark;": "\u2713", + "chi;": "\u03c7", + "cir;": "\u25cb", + "cirE;": "\u29c3", + "circ;": "\u02c6", + "circeq;": "\u2257", + "circlearrowleft;": "\u21ba", + "circlearrowright;": "\u21bb", + "circledR;": "\xae", + "circledS;": "\u24c8", + "circledast;": "\u229b", + "circledcirc;": "\u229a", + "circleddash;": "\u229d", + "cire;": "\u2257", + "cirfnint;": "\u2a10", + "cirmid;": "\u2aef", + "cirscir;": "\u29c2", + "clubs;": "\u2663", + "clubsuit;": "\u2663", + "colon;": ":", + "colone;": "\u2254", + "coloneq;": "\u2254", + "comma;": ",", + "commat;": "@", + "comp;": "\u2201", + "compfn;": "\u2218", + "complement;": "\u2201", + "complexes;": "\u2102", + "cong;": "\u2245", + "congdot;": "\u2a6d", + "conint;": "\u222e", + "copf;": "\U0001d554", + "coprod;": "\u2210", + "copy": "\xa9", + "copy;": "\xa9", + "copysr;": "\u2117", + "crarr;": "\u21b5", + "cross;": "\u2717", + "cscr;": "\U0001d4b8", + "csub;": "\u2acf", + "csube;": "\u2ad1", + "csup;": "\u2ad0", + "csupe;": "\u2ad2", + "ctdot;": "\u22ef", + "cudarrl;": "\u2938", + "cudarrr;": "\u2935", + "cuepr;": "\u22de", + "cuesc;": "\u22df", + "cularr;": "\u21b6", + "cularrp;": "\u293d", + "cup;": "\u222a", + "cupbrcap;": "\u2a48", + "cupcap;": "\u2a46", + "cupcup;": "\u2a4a", + "cupdot;": "\u228d", + "cupor;": "\u2a45", + "cups;": "\u222a\ufe00", + "curarr;": "\u21b7", + "curarrm;": "\u293c", + "curlyeqprec;": "\u22de", + "curlyeqsucc;": "\u22df", + "curlyvee;": "\u22ce", + "curlywedge;": "\u22cf", + "curren": "\xa4", + "curren;": "\xa4", + "curvearrowleft;": "\u21b6", + "curvearrowright;": "\u21b7", + "cuvee;": "\u22ce", + "cuwed;": "\u22cf", + "cwconint;": "\u2232", + "cwint;": "\u2231", + "cylcty;": "\u232d", + "dArr;": "\u21d3", + "dHar;": "\u2965", + "dagger;": "\u2020", + "daleth;": "\u2138", + "darr;": "\u2193", + "dash;": "\u2010", + "dashv;": "\u22a3", + "dbkarow;": "\u290f", + "dblac;": "\u02dd", + "dcaron;": "\u010f", + "dcy;": "\u0434", + "dd;": "\u2146", + "ddagger;": "\u2021", + "ddarr;": "\u21ca", + "ddotseq;": "\u2a77", + "deg": "\xb0", + "deg;": "\xb0", + "delta;": "\u03b4", + "demptyv;": "\u29b1", + "dfisht;": "\u297f", + "dfr;": "\U0001d521", + "dharl;": "\u21c3", + "dharr;": "\u21c2", + "diam;": "\u22c4", + "diamond;": "\u22c4", + "diamondsuit;": "\u2666", + "diams;": "\u2666", + "die;": "\xa8", + "digamma;": "\u03dd", + "disin;": "\u22f2", + "div;": "\xf7", + "divide": "\xf7", + "divide;": "\xf7", + "divideontimes;": "\u22c7", + "divonx;": "\u22c7", + "djcy;": "\u0452", + "dlcorn;": "\u231e", + "dlcrop;": "\u230d", + "dollar;": "$", + "dopf;": "\U0001d555", + "dot;": "\u02d9", + "doteq;": "\u2250", + "doteqdot;": "\u2251", + "dotminus;": "\u2238", + "dotplus;": "\u2214", + "dotsquare;": "\u22a1", + "doublebarwedge;": "\u2306", + "downarrow;": "\u2193", + "downdownarrows;": "\u21ca", + "downharpoonleft;": "\u21c3", + "downharpoonright;": "\u21c2", + "drbkarow;": "\u2910", + "drcorn;": "\u231f", + "drcrop;": "\u230c", + "dscr;": "\U0001d4b9", + "dscy;": "\u0455", + "dsol;": "\u29f6", + "dstrok;": "\u0111", + "dtdot;": "\u22f1", + "dtri;": "\u25bf", + "dtrif;": "\u25be", + "duarr;": "\u21f5", + "duhar;": "\u296f", + "dwangle;": "\u29a6", + "dzcy;": "\u045f", + "dzigrarr;": "\u27ff", + "eDDot;": "\u2a77", + "eDot;": "\u2251", + "eacute": "\xe9", + "eacute;": "\xe9", + "easter;": "\u2a6e", + "ecaron;": "\u011b", + "ecir;": "\u2256", + "ecirc": "\xea", + "ecirc;": "\xea", + "ecolon;": "\u2255", + "ecy;": "\u044d", + "edot;": "\u0117", + "ee;": "\u2147", + "efDot;": "\u2252", + "efr;": "\U0001d522", + "eg;": "\u2a9a", + "egrave": "\xe8", + "egrave;": "\xe8", + "egs;": "\u2a96", + "egsdot;": "\u2a98", + "el;": "\u2a99", + "elinters;": "\u23e7", + "ell;": "\u2113", + "els;": "\u2a95", + "elsdot;": "\u2a97", + "emacr;": "\u0113", + "empty;": "\u2205", + "emptyset;": "\u2205", + "emptyv;": "\u2205", + "emsp13;": "\u2004", + "emsp14;": "\u2005", + "emsp;": "\u2003", + "eng;": "\u014b", + "ensp;": "\u2002", + "eogon;": "\u0119", + "eopf;": "\U0001d556", + "epar;": "\u22d5", + "eparsl;": "\u29e3", + "eplus;": "\u2a71", + "epsi;": "\u03b5", + "epsilon;": "\u03b5", + "epsiv;": "\u03f5", + "eqcirc;": "\u2256", + "eqcolon;": "\u2255", + "eqsim;": "\u2242", + "eqslantgtr;": "\u2a96", + "eqslantless;": "\u2a95", + "equals;": "=", + "equest;": "\u225f", + "equiv;": "\u2261", + "equivDD;": "\u2a78", + "eqvparsl;": "\u29e5", + "erDot;": "\u2253", + "erarr;": "\u2971", + "escr;": "\u212f", + "esdot;": "\u2250", + "esim;": "\u2242", + "eta;": "\u03b7", + "eth": "\xf0", + "eth;": "\xf0", + "euml": "\xeb", + "euml;": "\xeb", + "euro;": "\u20ac", + "excl;": "!", + "exist;": "\u2203", + "expectation;": "\u2130", + "exponentiale;": "\u2147", + "fallingdotseq;": "\u2252", + "fcy;": "\u0444", + "female;": "\u2640", + "ffilig;": "\ufb03", + "fflig;": "\ufb00", + "ffllig;": "\ufb04", + "ffr;": "\U0001d523", + "filig;": "\ufb01", + "fjlig;": "fj", + "flat;": "\u266d", + "fllig;": "\ufb02", + "fltns;": "\u25b1", + "fnof;": "\u0192", + "fopf;": "\U0001d557", + "forall;": "\u2200", + "fork;": "\u22d4", + "forkv;": "\u2ad9", + "fpartint;": "\u2a0d", + "frac12": "\xbd", + "frac12;": "\xbd", + "frac13;": "\u2153", + "frac14": "\xbc", + "frac14;": "\xbc", + "frac15;": "\u2155", + "frac16;": "\u2159", + "frac18;": "\u215b", + "frac23;": "\u2154", + "frac25;": "\u2156", + "frac34": "\xbe", + "frac34;": "\xbe", + "frac35;": "\u2157", + "frac38;": "\u215c", + "frac45;": "\u2158", + "frac56;": "\u215a", + "frac58;": "\u215d", + "frac78;": "\u215e", + "frasl;": "\u2044", + "frown;": "\u2322", + "fscr;": "\U0001d4bb", + "gE;": "\u2267", + "gEl;": "\u2a8c", + "gacute;": "\u01f5", + "gamma;": "\u03b3", + "gammad;": "\u03dd", + "gap;": "\u2a86", + "gbreve;": "\u011f", + "gcirc;": "\u011d", + "gcy;": "\u0433", + "gdot;": "\u0121", + "ge;": "\u2265", + "gel;": "\u22db", + "geq;": "\u2265", + "geqq;": "\u2267", + "geqslant;": "\u2a7e", + "ges;": "\u2a7e", + "gescc;": "\u2aa9", + "gesdot;": "\u2a80", + "gesdoto;": "\u2a82", + "gesdotol;": "\u2a84", + "gesl;": "\u22db\ufe00", + "gesles;": "\u2a94", + "gfr;": "\U0001d524", + "gg;": "\u226b", + "ggg;": "\u22d9", + "gimel;": "\u2137", + "gjcy;": "\u0453", + "gl;": "\u2277", + "glE;": "\u2a92", + "gla;": "\u2aa5", + "glj;": "\u2aa4", + "gnE;": "\u2269", + "gnap;": "\u2a8a", + "gnapprox;": "\u2a8a", + "gne;": "\u2a88", + "gneq;": "\u2a88", + "gneqq;": "\u2269", + "gnsim;": "\u22e7", + "gopf;": "\U0001d558", + "grave;": "`", + "gscr;": "\u210a", + "gsim;": "\u2273", + "gsime;": "\u2a8e", + "gsiml;": "\u2a90", + "gt": ">", + "gt;": ">", + "gtcc;": "\u2aa7", + "gtcir;": "\u2a7a", + "gtdot;": "\u22d7", + "gtlPar;": "\u2995", + "gtquest;": "\u2a7c", + "gtrapprox;": "\u2a86", + "gtrarr;": "\u2978", + "gtrdot;": "\u22d7", + "gtreqless;": "\u22db", + "gtreqqless;": "\u2a8c", + "gtrless;": "\u2277", + "gtrsim;": "\u2273", + "gvertneqq;": "\u2269\ufe00", + "gvnE;": "\u2269\ufe00", + "hArr;": "\u21d4", + "hairsp;": "\u200a", + "half;": "\xbd", + "hamilt;": "\u210b", + "hardcy;": "\u044a", + "harr;": "\u2194", + "harrcir;": "\u2948", + "harrw;": "\u21ad", + "hbar;": "\u210f", + "hcirc;": "\u0125", + "hearts;": "\u2665", + "heartsuit;": "\u2665", + "hellip;": "\u2026", + "hercon;": "\u22b9", + "hfr;": "\U0001d525", + "hksearow;": "\u2925", + "hkswarow;": "\u2926", + "hoarr;": "\u21ff", + "homtht;": "\u223b", + "hookleftarrow;": "\u21a9", + "hookrightarrow;": "\u21aa", + "hopf;": "\U0001d559", + "horbar;": "\u2015", + "hscr;": "\U0001d4bd", + "hslash;": "\u210f", + "hstrok;": "\u0127", + "hybull;": "\u2043", + "hyphen;": "\u2010", + "iacute": "\xed", + "iacute;": "\xed", + "ic;": "\u2063", + "icirc": "\xee", + "icirc;": "\xee", + "icy;": "\u0438", + "iecy;": "\u0435", + "iexcl": "\xa1", + "iexcl;": "\xa1", + "iff;": "\u21d4", + "ifr;": "\U0001d526", + "igrave": "\xec", + "igrave;": "\xec", + "ii;": "\u2148", + "iiiint;": "\u2a0c", + "iiint;": "\u222d", + "iinfin;": "\u29dc", + "iiota;": "\u2129", + "ijlig;": "\u0133", + "imacr;": "\u012b", + "image;": "\u2111", + "imagline;": "\u2110", + "imagpart;": "\u2111", + "imath;": "\u0131", + "imof;": "\u22b7", + "imped;": "\u01b5", + "in;": "\u2208", + "incare;": "\u2105", + "infin;": "\u221e", + "infintie;": "\u29dd", + "inodot;": "\u0131", + "int;": "\u222b", + "intcal;": "\u22ba", + "integers;": "\u2124", + "intercal;": "\u22ba", + "intlarhk;": "\u2a17", + "intprod;": "\u2a3c", + "iocy;": "\u0451", + "iogon;": "\u012f", + "iopf;": "\U0001d55a", + "iota;": "\u03b9", + "iprod;": "\u2a3c", + "iquest": "\xbf", + "iquest;": "\xbf", + "iscr;": "\U0001d4be", + "isin;": "\u2208", + "isinE;": "\u22f9", + "isindot;": "\u22f5", + "isins;": "\u22f4", + "isinsv;": "\u22f3", + "isinv;": "\u2208", + "it;": "\u2062", + "itilde;": "\u0129", + "iukcy;": "\u0456", + "iuml": "\xef", + "iuml;": "\xef", + "jcirc;": "\u0135", + "jcy;": "\u0439", + "jfr;": "\U0001d527", + "jmath;": "\u0237", + "jopf;": "\U0001d55b", + "jscr;": "\U0001d4bf", + "jsercy;": "\u0458", + "jukcy;": "\u0454", + "kappa;": "\u03ba", + "kappav;": "\u03f0", + "kcedil;": "\u0137", + "kcy;": "\u043a", + "kfr;": "\U0001d528", + "kgreen;": "\u0138", + "khcy;": "\u0445", + "kjcy;": "\u045c", + "kopf;": "\U0001d55c", + "kscr;": "\U0001d4c0", + "lAarr;": "\u21da", + "lArr;": "\u21d0", + "lAtail;": "\u291b", + "lBarr;": "\u290e", + "lE;": "\u2266", + "lEg;": "\u2a8b", + "lHar;": "\u2962", + "lacute;": "\u013a", + "laemptyv;": "\u29b4", + "lagran;": "\u2112", + "lambda;": "\u03bb", + "lang;": "\u27e8", + "langd;": "\u2991", + "langle;": "\u27e8", + "lap;": "\u2a85", + "laquo": "\xab", + "laquo;": "\xab", + "larr;": "\u2190", + "larrb;": "\u21e4", + "larrbfs;": "\u291f", + "larrfs;": "\u291d", + "larrhk;": "\u21a9", + "larrlp;": "\u21ab", + "larrpl;": "\u2939", + "larrsim;": "\u2973", + "larrtl;": "\u21a2", + "lat;": "\u2aab", + "latail;": "\u2919", + "late;": "\u2aad", + "lates;": "\u2aad\ufe00", + "lbarr;": "\u290c", + "lbbrk;": "\u2772", + "lbrace;": "{", + "lbrack;": "[", + "lbrke;": "\u298b", + "lbrksld;": "\u298f", + "lbrkslu;": "\u298d", + "lcaron;": "\u013e", + "lcedil;": "\u013c", + "lceil;": "\u2308", + "lcub;": "{", + "lcy;": "\u043b", + "ldca;": "\u2936", + "ldquo;": "\u201c", + "ldquor;": "\u201e", + "ldrdhar;": "\u2967", + "ldrushar;": "\u294b", + "ldsh;": "\u21b2", + "le;": "\u2264", + "leftarrow;": "\u2190", + "leftarrowtail;": "\u21a2", + "leftharpoondown;": "\u21bd", + "leftharpoonup;": "\u21bc", + "leftleftarrows;": "\u21c7", + "leftrightarrow;": "\u2194", + "leftrightarrows;": "\u21c6", + "leftrightharpoons;": "\u21cb", + "leftrightsquigarrow;": "\u21ad", + "leftthreetimes;": "\u22cb", + "leg;": "\u22da", + "leq;": "\u2264", + "leqq;": "\u2266", + "leqslant;": "\u2a7d", + "les;": "\u2a7d", + "lescc;": "\u2aa8", + "lesdot;": "\u2a7f", + "lesdoto;": "\u2a81", + "lesdotor;": "\u2a83", + "lesg;": "\u22da\ufe00", + "lesges;": "\u2a93", + "lessapprox;": "\u2a85", + "lessdot;": "\u22d6", + "lesseqgtr;": "\u22da", + "lesseqqgtr;": "\u2a8b", + "lessgtr;": "\u2276", + "lesssim;": "\u2272", + "lfisht;": "\u297c", + "lfloor;": "\u230a", + "lfr;": "\U0001d529", + "lg;": "\u2276", + "lgE;": "\u2a91", + "lhard;": "\u21bd", + "lharu;": "\u21bc", + "lharul;": "\u296a", + "lhblk;": "\u2584", + "ljcy;": "\u0459", + "ll;": "\u226a", + "llarr;": "\u21c7", + "llcorner;": "\u231e", + "llhard;": "\u296b", + "lltri;": "\u25fa", + "lmidot;": "\u0140", + "lmoust;": "\u23b0", + "lmoustache;": "\u23b0", + "lnE;": "\u2268", + "lnap;": "\u2a89", + "lnapprox;": "\u2a89", + "lne;": "\u2a87", + "lneq;": "\u2a87", + "lneqq;": "\u2268", + "lnsim;": "\u22e6", + "loang;": "\u27ec", + "loarr;": "\u21fd", + "lobrk;": "\u27e6", + "longleftarrow;": "\u27f5", + "longleftrightarrow;": "\u27f7", + "longmapsto;": "\u27fc", + "longrightarrow;": "\u27f6", + "looparrowleft;": "\u21ab", + "looparrowright;": "\u21ac", + "lopar;": "\u2985", + "lopf;": "\U0001d55d", + "loplus;": "\u2a2d", + "lotimes;": "\u2a34", + "lowast;": "\u2217", + "lowbar;": "_", + "loz;": "\u25ca", + "lozenge;": "\u25ca", + "lozf;": "\u29eb", + "lpar;": "(", + "lparlt;": "\u2993", + "lrarr;": "\u21c6", + "lrcorner;": "\u231f", + "lrhar;": "\u21cb", + "lrhard;": "\u296d", + "lrm;": "\u200e", + "lrtri;": "\u22bf", + "lsaquo;": "\u2039", + "lscr;": "\U0001d4c1", + "lsh;": "\u21b0", + "lsim;": "\u2272", + "lsime;": "\u2a8d", + "lsimg;": "\u2a8f", + "lsqb;": "[", + "lsquo;": "\u2018", + "lsquor;": "\u201a", + "lstrok;": "\u0142", + "lt": "<", + "lt;": "<", + "ltcc;": "\u2aa6", + "ltcir;": "\u2a79", + "ltdot;": "\u22d6", + "lthree;": "\u22cb", + "ltimes;": "\u22c9", + "ltlarr;": "\u2976", + "ltquest;": "\u2a7b", + "ltrPar;": "\u2996", + "ltri;": "\u25c3", + "ltrie;": "\u22b4", + "ltrif;": "\u25c2", + "lurdshar;": "\u294a", + "luruhar;": "\u2966", + "lvertneqq;": "\u2268\ufe00", + "lvnE;": "\u2268\ufe00", + "mDDot;": "\u223a", + "macr": "\xaf", + "macr;": "\xaf", + "male;": "\u2642", + "malt;": "\u2720", + "maltese;": "\u2720", + "map;": "\u21a6", + "mapsto;": "\u21a6", + "mapstodown;": "\u21a7", + "mapstoleft;": "\u21a4", + "mapstoup;": "\u21a5", + "marker;": "\u25ae", + "mcomma;": "\u2a29", + "mcy;": "\u043c", + "mdash;": "\u2014", + "measuredangle;": "\u2221", + "mfr;": "\U0001d52a", + "mho;": "\u2127", + "micro": "\xb5", + "micro;": "\xb5", + "mid;": "\u2223", + "midast;": "*", + "midcir;": "\u2af0", + "middot": "\xb7", + "middot;": "\xb7", + "minus;": "\u2212", + "minusb;": "\u229f", + "minusd;": "\u2238", + "minusdu;": "\u2a2a", + "mlcp;": "\u2adb", + "mldr;": "\u2026", + "mnplus;": "\u2213", + "models;": "\u22a7", + "mopf;": "\U0001d55e", + "mp;": "\u2213", + "mscr;": "\U0001d4c2", + "mstpos;": "\u223e", + "mu;": "\u03bc", + "multimap;": "\u22b8", + "mumap;": "\u22b8", + "nGg;": "\u22d9\u0338", + "nGt;": "\u226b\u20d2", + "nGtv;": "\u226b\u0338", + "nLeftarrow;": "\u21cd", + "nLeftrightarrow;": "\u21ce", + "nLl;": "\u22d8\u0338", + "nLt;": "\u226a\u20d2", + "nLtv;": "\u226a\u0338", + "nRightarrow;": "\u21cf", + "nVDash;": "\u22af", + "nVdash;": "\u22ae", + "nabla;": "\u2207", + "nacute;": "\u0144", + "nang;": "\u2220\u20d2", + "nap;": "\u2249", + "napE;": "\u2a70\u0338", + "napid;": "\u224b\u0338", + "napos;": "\u0149", + "napprox;": "\u2249", + "natur;": "\u266e", + "natural;": "\u266e", + "naturals;": "\u2115", + "nbsp": "\xa0", + "nbsp;": "\xa0", + "nbump;": "\u224e\u0338", + "nbumpe;": "\u224f\u0338", + "ncap;": "\u2a43", + "ncaron;": "\u0148", + "ncedil;": "\u0146", + "ncong;": "\u2247", + "ncongdot;": "\u2a6d\u0338", + "ncup;": "\u2a42", + "ncy;": "\u043d", + "ndash;": "\u2013", + "ne;": "\u2260", + "neArr;": "\u21d7", + "nearhk;": "\u2924", + "nearr;": "\u2197", + "nearrow;": "\u2197", + "nedot;": "\u2250\u0338", + "nequiv;": "\u2262", + "nesear;": "\u2928", + "nesim;": "\u2242\u0338", + "nexist;": "\u2204", + "nexists;": "\u2204", + "nfr;": "\U0001d52b", + "ngE;": "\u2267\u0338", + "nge;": "\u2271", + "ngeq;": "\u2271", + "ngeqq;": "\u2267\u0338", + "ngeqslant;": "\u2a7e\u0338", + "nges;": "\u2a7e\u0338", + "ngsim;": "\u2275", + "ngt;": "\u226f", + "ngtr;": "\u226f", + "nhArr;": "\u21ce", + "nharr;": "\u21ae", + "nhpar;": "\u2af2", + "ni;": "\u220b", + "nis;": "\u22fc", + "nisd;": "\u22fa", + "niv;": "\u220b", + "njcy;": "\u045a", + "nlArr;": "\u21cd", + "nlE;": "\u2266\u0338", + "nlarr;": "\u219a", + "nldr;": "\u2025", + "nle;": "\u2270", + "nleftarrow;": "\u219a", + "nleftrightarrow;": "\u21ae", + "nleq;": "\u2270", + "nleqq;": "\u2266\u0338", + "nleqslant;": "\u2a7d\u0338", + "nles;": "\u2a7d\u0338", + "nless;": "\u226e", + "nlsim;": "\u2274", + "nlt;": "\u226e", + "nltri;": "\u22ea", + "nltrie;": "\u22ec", + "nmid;": "\u2224", + "nopf;": "\U0001d55f", + "not": "\xac", + "not;": "\xac", + "notin;": "\u2209", + "notinE;": "\u22f9\u0338", + "notindot;": "\u22f5\u0338", + "notinva;": "\u2209", + "notinvb;": "\u22f7", + "notinvc;": "\u22f6", + "notni;": "\u220c", + "notniva;": "\u220c", + "notnivb;": "\u22fe", + "notnivc;": "\u22fd", + "npar;": "\u2226", + "nparallel;": "\u2226", + "nparsl;": "\u2afd\u20e5", + "npart;": "\u2202\u0338", + "npolint;": "\u2a14", + "npr;": "\u2280", + "nprcue;": "\u22e0", + "npre;": "\u2aaf\u0338", + "nprec;": "\u2280", + "npreceq;": "\u2aaf\u0338", + "nrArr;": "\u21cf", + "nrarr;": "\u219b", + "nrarrc;": "\u2933\u0338", + "nrarrw;": "\u219d\u0338", + "nrightarrow;": "\u219b", + "nrtri;": "\u22eb", + "nrtrie;": "\u22ed", + "nsc;": "\u2281", + "nsccue;": "\u22e1", + "nsce;": "\u2ab0\u0338", + "nscr;": "\U0001d4c3", + "nshortmid;": "\u2224", + "nshortparallel;": "\u2226", + "nsim;": "\u2241", + "nsime;": "\u2244", + "nsimeq;": "\u2244", + "nsmid;": "\u2224", + "nspar;": "\u2226", + "nsqsube;": "\u22e2", + "nsqsupe;": "\u22e3", + "nsub;": "\u2284", + "nsubE;": "\u2ac5\u0338", + "nsube;": "\u2288", + "nsubset;": "\u2282\u20d2", + "nsubseteq;": "\u2288", + "nsubseteqq;": "\u2ac5\u0338", + "nsucc;": "\u2281", + "nsucceq;": "\u2ab0\u0338", + "nsup;": "\u2285", + "nsupE;": "\u2ac6\u0338", + "nsupe;": "\u2289", + "nsupset;": "\u2283\u20d2", + "nsupseteq;": "\u2289", + "nsupseteqq;": "\u2ac6\u0338", + "ntgl;": "\u2279", + "ntilde": "\xf1", + "ntilde;": "\xf1", + "ntlg;": "\u2278", + "ntriangleleft;": "\u22ea", + "ntrianglelefteq;": "\u22ec", + "ntriangleright;": "\u22eb", + "ntrianglerighteq;": "\u22ed", + "nu;": "\u03bd", + "num;": "#", + "numero;": "\u2116", + "numsp;": "\u2007", + "nvDash;": "\u22ad", + "nvHarr;": "\u2904", + "nvap;": "\u224d\u20d2", + "nvdash;": "\u22ac", + "nvge;": "\u2265\u20d2", + "nvgt;": ">\u20d2", + "nvinfin;": "\u29de", + "nvlArr;": "\u2902", + "nvle;": "\u2264\u20d2", + "nvlt;": "<\u20d2", + "nvltrie;": "\u22b4\u20d2", + "nvrArr;": "\u2903", + "nvrtrie;": "\u22b5\u20d2", + "nvsim;": "\u223c\u20d2", + "nwArr;": "\u21d6", + "nwarhk;": "\u2923", + "nwarr;": "\u2196", + "nwarrow;": "\u2196", + "nwnear;": "\u2927", + "oS;": "\u24c8", + "oacute": "\xf3", + "oacute;": "\xf3", + "oast;": "\u229b", + "ocir;": "\u229a", + "ocirc": "\xf4", + "ocirc;": "\xf4", + "ocy;": "\u043e", + "odash;": "\u229d", + "odblac;": "\u0151", + "odiv;": "\u2a38", + "odot;": "\u2299", + "odsold;": "\u29bc", + "oelig;": "\u0153", + "ofcir;": "\u29bf", + "ofr;": "\U0001d52c", + "ogon;": "\u02db", + "ograve": "\xf2", + "ograve;": "\xf2", + "ogt;": "\u29c1", + "ohbar;": "\u29b5", + "ohm;": "\u03a9", + "oint;": "\u222e", + "olarr;": "\u21ba", + "olcir;": "\u29be", + "olcross;": "\u29bb", + "oline;": "\u203e", + "olt;": "\u29c0", + "omacr;": "\u014d", + "omega;": "\u03c9", + "omicron;": "\u03bf", + "omid;": "\u29b6", + "ominus;": "\u2296", + "oopf;": "\U0001d560", + "opar;": "\u29b7", + "operp;": "\u29b9", + "oplus;": "\u2295", + "or;": "\u2228", + "orarr;": "\u21bb", + "ord;": "\u2a5d", + "order;": "\u2134", + "orderof;": "\u2134", + "ordf": "\xaa", + "ordf;": "\xaa", + "ordm": "\xba", + "ordm;": "\xba", + "origof;": "\u22b6", + "oror;": "\u2a56", + "orslope;": "\u2a57", + "orv;": "\u2a5b", + "oscr;": "\u2134", + "oslash": "\xf8", + "oslash;": "\xf8", + "osol;": "\u2298", + "otilde": "\xf5", + "otilde;": "\xf5", + "otimes;": "\u2297", + "otimesas;": "\u2a36", + "ouml": "\xf6", + "ouml;": "\xf6", + "ovbar;": "\u233d", + "par;": "\u2225", + "para": "\xb6", + "para;": "\xb6", + "parallel;": "\u2225", + "parsim;": "\u2af3", + "parsl;": "\u2afd", + "part;": "\u2202", + "pcy;": "\u043f", + "percnt;": "%", + "period;": ".", + "permil;": "\u2030", + "perp;": "\u22a5", + "pertenk;": "\u2031", + "pfr;": "\U0001d52d", + "phi;": "\u03c6", + "phiv;": "\u03d5", + "phmmat;": "\u2133", + "phone;": "\u260e", + "pi;": "\u03c0", + "pitchfork;": "\u22d4", + "piv;": "\u03d6", + "planck;": "\u210f", + "planckh;": "\u210e", + "plankv;": "\u210f", + "plus;": "+", + "plusacir;": "\u2a23", + "plusb;": "\u229e", + "pluscir;": "\u2a22", + "plusdo;": "\u2214", + "plusdu;": "\u2a25", + "pluse;": "\u2a72", + "plusmn": "\xb1", + "plusmn;": "\xb1", + "plussim;": "\u2a26", + "plustwo;": "\u2a27", + "pm;": "\xb1", + "pointint;": "\u2a15", + "popf;": "\U0001d561", + "pound": "\xa3", + "pound;": "\xa3", + "pr;": "\u227a", + "prE;": "\u2ab3", + "prap;": "\u2ab7", + "prcue;": "\u227c", + "pre;": "\u2aaf", + "prec;": "\u227a", + "precapprox;": "\u2ab7", + "preccurlyeq;": "\u227c", + "preceq;": "\u2aaf", + "precnapprox;": "\u2ab9", + "precneqq;": "\u2ab5", + "precnsim;": "\u22e8", + "precsim;": "\u227e", + "prime;": "\u2032", + "primes;": "\u2119", + "prnE;": "\u2ab5", + "prnap;": "\u2ab9", + "prnsim;": "\u22e8", + "prod;": "\u220f", + "profalar;": "\u232e", + "profline;": "\u2312", + "profsurf;": "\u2313", + "prop;": "\u221d", + "propto;": "\u221d", + "prsim;": "\u227e", + "prurel;": "\u22b0", + "pscr;": "\U0001d4c5", + "psi;": "\u03c8", + "puncsp;": "\u2008", + "qfr;": "\U0001d52e", + "qint;": "\u2a0c", + "qopf;": "\U0001d562", + "qprime;": "\u2057", + "qscr;": "\U0001d4c6", + "quaternions;": "\u210d", + "quatint;": "\u2a16", + "quest;": "?", + "questeq;": "\u225f", + "quot": "\"", + "quot;": "\"", + "rAarr;": "\u21db", + "rArr;": "\u21d2", + "rAtail;": "\u291c", + "rBarr;": "\u290f", + "rHar;": "\u2964", + "race;": "\u223d\u0331", + "racute;": "\u0155", + "radic;": "\u221a", + "raemptyv;": "\u29b3", + "rang;": "\u27e9", + "rangd;": "\u2992", + "range;": "\u29a5", + "rangle;": "\u27e9", + "raquo": "\xbb", + "raquo;": "\xbb", + "rarr;": "\u2192", + "rarrap;": "\u2975", + "rarrb;": "\u21e5", + "rarrbfs;": "\u2920", + "rarrc;": "\u2933", + "rarrfs;": "\u291e", + "rarrhk;": "\u21aa", + "rarrlp;": "\u21ac", + "rarrpl;": "\u2945", + "rarrsim;": "\u2974", + "rarrtl;": "\u21a3", + "rarrw;": "\u219d", + "ratail;": "\u291a", + "ratio;": "\u2236", + "rationals;": "\u211a", + "rbarr;": "\u290d", + "rbbrk;": "\u2773", + "rbrace;": "}", + "rbrack;": "]", + "rbrke;": "\u298c", + "rbrksld;": "\u298e", + "rbrkslu;": "\u2990", + "rcaron;": "\u0159", + "rcedil;": "\u0157", + "rceil;": "\u2309", + "rcub;": "}", + "rcy;": "\u0440", + "rdca;": "\u2937", + "rdldhar;": "\u2969", + "rdquo;": "\u201d", + "rdquor;": "\u201d", + "rdsh;": "\u21b3", + "real;": "\u211c", + "realine;": "\u211b", + "realpart;": "\u211c", + "reals;": "\u211d", + "rect;": "\u25ad", + "reg": "\xae", + "reg;": "\xae", + "rfisht;": "\u297d", + "rfloor;": "\u230b", + "rfr;": "\U0001d52f", + "rhard;": "\u21c1", + "rharu;": "\u21c0", + "rharul;": "\u296c", + "rho;": "\u03c1", + "rhov;": "\u03f1", + "rightarrow;": "\u2192", + "rightarrowtail;": "\u21a3", + "rightharpoondown;": "\u21c1", + "rightharpoonup;": "\u21c0", + "rightleftarrows;": "\u21c4", + "rightleftharpoons;": "\u21cc", + "rightrightarrows;": "\u21c9", + "rightsquigarrow;": "\u219d", + "rightthreetimes;": "\u22cc", + "ring;": "\u02da", + "risingdotseq;": "\u2253", + "rlarr;": "\u21c4", + "rlhar;": "\u21cc", + "rlm;": "\u200f", + "rmoust;": "\u23b1", + "rmoustache;": "\u23b1", + "rnmid;": "\u2aee", + "roang;": "\u27ed", + "roarr;": "\u21fe", + "robrk;": "\u27e7", + "ropar;": "\u2986", + "ropf;": "\U0001d563", + "roplus;": "\u2a2e", + "rotimes;": "\u2a35", + "rpar;": ")", + "rpargt;": "\u2994", + "rppolint;": "\u2a12", + "rrarr;": "\u21c9", + "rsaquo;": "\u203a", + "rscr;": "\U0001d4c7", + "rsh;": "\u21b1", + "rsqb;": "]", + "rsquo;": "\u2019", + "rsquor;": "\u2019", + "rthree;": "\u22cc", + "rtimes;": "\u22ca", + "rtri;": "\u25b9", + "rtrie;": "\u22b5", + "rtrif;": "\u25b8", + "rtriltri;": "\u29ce", + "ruluhar;": "\u2968", + "rx;": "\u211e", + "sacute;": "\u015b", + "sbquo;": "\u201a", + "sc;": "\u227b", + "scE;": "\u2ab4", + "scap;": "\u2ab8", + "scaron;": "\u0161", + "sccue;": "\u227d", + "sce;": "\u2ab0", + "scedil;": "\u015f", + "scirc;": "\u015d", + "scnE;": "\u2ab6", + "scnap;": "\u2aba", + "scnsim;": "\u22e9", + "scpolint;": "\u2a13", + "scsim;": "\u227f", + "scy;": "\u0441", + "sdot;": "\u22c5", + "sdotb;": "\u22a1", + "sdote;": "\u2a66", + "seArr;": "\u21d8", + "searhk;": "\u2925", + "searr;": "\u2198", + "searrow;": "\u2198", + "sect": "\xa7", + "sect;": "\xa7", + "semi;": ";", + "seswar;": "\u2929", + "setminus;": "\u2216", + "setmn;": "\u2216", + "sext;": "\u2736", + "sfr;": "\U0001d530", + "sfrown;": "\u2322", + "sharp;": "\u266f", + "shchcy;": "\u0449", + "shcy;": "\u0448", + "shortmid;": "\u2223", + "shortparallel;": "\u2225", + "shy": "\xad", + "shy;": "\xad", + "sigma;": "\u03c3", + "sigmaf;": "\u03c2", + "sigmav;": "\u03c2", + "sim;": "\u223c", + "simdot;": "\u2a6a", + "sime;": "\u2243", + "simeq;": "\u2243", + "simg;": "\u2a9e", + "simgE;": "\u2aa0", + "siml;": "\u2a9d", + "simlE;": "\u2a9f", + "simne;": "\u2246", + "simplus;": "\u2a24", + "simrarr;": "\u2972", + "slarr;": "\u2190", + "smallsetminus;": "\u2216", + "smashp;": "\u2a33", + "smeparsl;": "\u29e4", + "smid;": "\u2223", + "smile;": "\u2323", + "smt;": "\u2aaa", + "smte;": "\u2aac", + "smtes;": "\u2aac\ufe00", + "softcy;": "\u044c", + "sol;": "/", + "solb;": "\u29c4", + "solbar;": "\u233f", + "sopf;": "\U0001d564", + "spades;": "\u2660", + "spadesuit;": "\u2660", + "spar;": "\u2225", + "sqcap;": "\u2293", + "sqcaps;": "\u2293\ufe00", + "sqcup;": "\u2294", + "sqcups;": "\u2294\ufe00", + "sqsub;": "\u228f", + "sqsube;": "\u2291", + "sqsubset;": "\u228f", + "sqsubseteq;": "\u2291", + "sqsup;": "\u2290", + "sqsupe;": "\u2292", + "sqsupset;": "\u2290", + "sqsupseteq;": "\u2292", + "squ;": "\u25a1", + "square;": "\u25a1", + "squarf;": "\u25aa", + "squf;": "\u25aa", + "srarr;": "\u2192", + "sscr;": "\U0001d4c8", + "ssetmn;": "\u2216", + "ssmile;": "\u2323", + "sstarf;": "\u22c6", + "star;": "\u2606", + "starf;": "\u2605", + "straightepsilon;": "\u03f5", + "straightphi;": "\u03d5", + "strns;": "\xaf", + "sub;": "\u2282", + "subE;": "\u2ac5", + "subdot;": "\u2abd", + "sube;": "\u2286", + "subedot;": "\u2ac3", + "submult;": "\u2ac1", + "subnE;": "\u2acb", + "subne;": "\u228a", + "subplus;": "\u2abf", + "subrarr;": "\u2979", + "subset;": "\u2282", + "subseteq;": "\u2286", + "subseteqq;": "\u2ac5", + "subsetneq;": "\u228a", + "subsetneqq;": "\u2acb", + "subsim;": "\u2ac7", + "subsub;": "\u2ad5", + "subsup;": "\u2ad3", + "succ;": "\u227b", + "succapprox;": "\u2ab8", + "succcurlyeq;": "\u227d", + "succeq;": "\u2ab0", + "succnapprox;": "\u2aba", + "succneqq;": "\u2ab6", + "succnsim;": "\u22e9", + "succsim;": "\u227f", + "sum;": "\u2211", + "sung;": "\u266a", + "sup1": "\xb9", + "sup1;": "\xb9", + "sup2": "\xb2", + "sup2;": "\xb2", + "sup3": "\xb3", + "sup3;": "\xb3", + "sup;": "\u2283", + "supE;": "\u2ac6", + "supdot;": "\u2abe", + "supdsub;": "\u2ad8", + "supe;": "\u2287", + "supedot;": "\u2ac4", + "suphsol;": "\u27c9", + "suphsub;": "\u2ad7", + "suplarr;": "\u297b", + "supmult;": "\u2ac2", + "supnE;": "\u2acc", + "supne;": "\u228b", + "supplus;": "\u2ac0", + "supset;": "\u2283", + "supseteq;": "\u2287", + "supseteqq;": "\u2ac6", + "supsetneq;": "\u228b", + "supsetneqq;": "\u2acc", + "supsim;": "\u2ac8", + "supsub;": "\u2ad4", + "supsup;": "\u2ad6", + "swArr;": "\u21d9", + "swarhk;": "\u2926", + "swarr;": "\u2199", + "swarrow;": "\u2199", + "swnwar;": "\u292a", + "szlig": "\xdf", + "szlig;": "\xdf", + "target;": "\u2316", + "tau;": "\u03c4", + "tbrk;": "\u23b4", + "tcaron;": "\u0165", + "tcedil;": "\u0163", + "tcy;": "\u0442", + "tdot;": "\u20db", + "telrec;": "\u2315", + "tfr;": "\U0001d531", + "there4;": "\u2234", + "therefore;": "\u2234", + "theta;": "\u03b8", + "thetasym;": "\u03d1", + "thetav;": "\u03d1", + "thickapprox;": "\u2248", + "thicksim;": "\u223c", + "thinsp;": "\u2009", + "thkap;": "\u2248", + "thksim;": "\u223c", + "thorn": "\xfe", + "thorn;": "\xfe", + "tilde;": "\u02dc", + "times": "\xd7", + "times;": "\xd7", + "timesb;": "\u22a0", + "timesbar;": "\u2a31", + "timesd;": "\u2a30", + "tint;": "\u222d", + "toea;": "\u2928", + "top;": "\u22a4", + "topbot;": "\u2336", + "topcir;": "\u2af1", + "topf;": "\U0001d565", + "topfork;": "\u2ada", + "tosa;": "\u2929", + "tprime;": "\u2034", + "trade;": "\u2122", + "triangle;": "\u25b5", + "triangledown;": "\u25bf", + "triangleleft;": "\u25c3", + "trianglelefteq;": "\u22b4", + "triangleq;": "\u225c", + "triangleright;": "\u25b9", + "trianglerighteq;": "\u22b5", + "tridot;": "\u25ec", + "trie;": "\u225c", + "triminus;": "\u2a3a", + "triplus;": "\u2a39", + "trisb;": "\u29cd", + "tritime;": "\u2a3b", + "trpezium;": "\u23e2", + "tscr;": "\U0001d4c9", + "tscy;": "\u0446", + "tshcy;": "\u045b", + "tstrok;": "\u0167", + "twixt;": "\u226c", + "twoheadleftarrow;": "\u219e", + "twoheadrightarrow;": "\u21a0", + "uArr;": "\u21d1", + "uHar;": "\u2963", + "uacute": "\xfa", + "uacute;": "\xfa", + "uarr;": "\u2191", + "ubrcy;": "\u045e", + "ubreve;": "\u016d", + "ucirc": "\xfb", + "ucirc;": "\xfb", + "ucy;": "\u0443", + "udarr;": "\u21c5", + "udblac;": "\u0171", + "udhar;": "\u296e", + "ufisht;": "\u297e", + "ufr;": "\U0001d532", + "ugrave": "\xf9", + "ugrave;": "\xf9", + "uharl;": "\u21bf", + "uharr;": "\u21be", + "uhblk;": "\u2580", + "ulcorn;": "\u231c", + "ulcorner;": "\u231c", + "ulcrop;": "\u230f", + "ultri;": "\u25f8", + "umacr;": "\u016b", + "uml": "\xa8", + "uml;": "\xa8", + "uogon;": "\u0173", + "uopf;": "\U0001d566", + "uparrow;": "\u2191", + "updownarrow;": "\u2195", + "upharpoonleft;": "\u21bf", + "upharpoonright;": "\u21be", + "uplus;": "\u228e", + "upsi;": "\u03c5", + "upsih;": "\u03d2", + "upsilon;": "\u03c5", + "upuparrows;": "\u21c8", + "urcorn;": "\u231d", + "urcorner;": "\u231d", + "urcrop;": "\u230e", + "uring;": "\u016f", + "urtri;": "\u25f9", + "uscr;": "\U0001d4ca", + "utdot;": "\u22f0", + "utilde;": "\u0169", + "utri;": "\u25b5", + "utrif;": "\u25b4", + "uuarr;": "\u21c8", + "uuml": "\xfc", + "uuml;": "\xfc", + "uwangle;": "\u29a7", + "vArr;": "\u21d5", + "vBar;": "\u2ae8", + "vBarv;": "\u2ae9", + "vDash;": "\u22a8", + "vangrt;": "\u299c", + "varepsilon;": "\u03f5", + "varkappa;": "\u03f0", + "varnothing;": "\u2205", + "varphi;": "\u03d5", + "varpi;": "\u03d6", + "varpropto;": "\u221d", + "varr;": "\u2195", + "varrho;": "\u03f1", + "varsigma;": "\u03c2", + "varsubsetneq;": "\u228a\ufe00", + "varsubsetneqq;": "\u2acb\ufe00", + "varsupsetneq;": "\u228b\ufe00", + "varsupsetneqq;": "\u2acc\ufe00", + "vartheta;": "\u03d1", + "vartriangleleft;": "\u22b2", + "vartriangleright;": "\u22b3", + "vcy;": "\u0432", + "vdash;": "\u22a2", + "vee;": "\u2228", + "veebar;": "\u22bb", + "veeeq;": "\u225a", + "vellip;": "\u22ee", + "verbar;": "|", + "vert;": "|", + "vfr;": "\U0001d533", + "vltri;": "\u22b2", + "vnsub;": "\u2282\u20d2", + "vnsup;": "\u2283\u20d2", + "vopf;": "\U0001d567", + "vprop;": "\u221d", + "vrtri;": "\u22b3", + "vscr;": "\U0001d4cb", + "vsubnE;": "\u2acb\ufe00", + "vsubne;": "\u228a\ufe00", + "vsupnE;": "\u2acc\ufe00", + "vsupne;": "\u228b\ufe00", + "vzigzag;": "\u299a", + "wcirc;": "\u0175", + "wedbar;": "\u2a5f", + "wedge;": "\u2227", + "wedgeq;": "\u2259", + "weierp;": "\u2118", + "wfr;": "\U0001d534", + "wopf;": "\U0001d568", + "wp;": "\u2118", + "wr;": "\u2240", + "wreath;": "\u2240", + "wscr;": "\U0001d4cc", + "xcap;": "\u22c2", + "xcirc;": "\u25ef", + "xcup;": "\u22c3", + "xdtri;": "\u25bd", + "xfr;": "\U0001d535", + "xhArr;": "\u27fa", + "xharr;": "\u27f7", + "xi;": "\u03be", + "xlArr;": "\u27f8", + "xlarr;": "\u27f5", + "xmap;": "\u27fc", + "xnis;": "\u22fb", + "xodot;": "\u2a00", + "xopf;": "\U0001d569", + "xoplus;": "\u2a01", + "xotime;": "\u2a02", + "xrArr;": "\u27f9", + "xrarr;": "\u27f6", + "xscr;": "\U0001d4cd", + "xsqcup;": "\u2a06", + "xuplus;": "\u2a04", + "xutri;": "\u25b3", + "xvee;": "\u22c1", + "xwedge;": "\u22c0", + "yacute": "\xfd", + "yacute;": "\xfd", + "yacy;": "\u044f", + "ycirc;": "\u0177", + "ycy;": "\u044b", + "yen": "\xa5", + "yen;": "\xa5", + "yfr;": "\U0001d536", + "yicy;": "\u0457", + "yopf;": "\U0001d56a", + "yscr;": "\U0001d4ce", + "yucy;": "\u044e", + "yuml": "\xff", + "yuml;": "\xff", + "zacute;": "\u017a", + "zcaron;": "\u017e", + "zcy;": "\u0437", + "zdot;": "\u017c", + "zeetrf;": "\u2128", + "zeta;": "\u03b6", + "zfr;": "\U0001d537", + "zhcy;": "\u0436", + "zigrarr;": "\u21dd", + "zopf;": "\U0001d56b", + "zscr;": "\U0001d4cf", + "zwj;": "\u200d", + "zwnj;": "\u200c", +} + +replacementCharacters = { + 0x0: "\uFFFD", + 0x0d: "\u000D", + 0x80: "\u20AC", + 0x81: "\u0081", + 0x82: "\u201A", + 0x83: "\u0192", + 0x84: "\u201E", + 0x85: "\u2026", + 0x86: "\u2020", + 0x87: "\u2021", + 0x88: "\u02C6", + 0x89: "\u2030", + 0x8A: "\u0160", + 0x8B: "\u2039", + 0x8C: "\u0152", + 0x8D: "\u008D", + 0x8E: "\u017D", + 0x8F: "\u008F", + 0x90: "\u0090", + 0x91: "\u2018", + 0x92: "\u2019", + 0x93: "\u201C", + 0x94: "\u201D", + 0x95: "\u2022", + 0x96: "\u2013", + 0x97: "\u2014", + 0x98: "\u02DC", + 0x99: "\u2122", + 0x9A: "\u0161", + 0x9B: "\u203A", + 0x9C: "\u0153", + 0x9D: "\u009D", + 0x9E: "\u017E", + 0x9F: "\u0178", +} + +tokenTypes = { + "Doctype": 0, + "Characters": 1, + "SpaceCharacters": 2, + "StartTag": 3, + "EndTag": 4, + "EmptyTag": 5, + "Comment": 6, + "ParseError": 7 +} + +tagTokenTypes = frozenset([tokenTypes["StartTag"], tokenTypes["EndTag"], + tokenTypes["EmptyTag"]]) + + +prefixes = dict([(v, k) for k, v in namespaces.items()]) +prefixes["http://www.w3.org/1998/Math/MathML"] = "math" + + +class DataLossWarning(UserWarning): + """Raised when the current tree is unable to represent the input data""" + pass + + +class _ReparseException(Exception): + pass diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2c8cb5ba434b8af2c929208f14d5250a0a516f17 GIT binary patch literal 209 zcmZ?b<>g`kf*$Fl7!ds!M8E(ekl_Ht#VkM~g&~+hlhJP_LlH<ALHw%HFDS|^ODsv% zFH0=aPs`6qNi8bY&&|+JHY|v@tg_59C^t?^sVX)zE-NysD5=Ud0D|;9{Sf_v%mUra zyyB9?oE%+K^Q4UI(xh~dAQ;D&rRJsN7wKn|<mQ;>WG3mSW#*KCOpcGw%*!l^kJl@x Vyv1RYo1apelWGTYQ!x-T003pyIIjQz literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/alphabeticalattributes.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/alphabeticalattributes.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f898360b335692c2d59026006b0cd3d73205fb5a GIT binary patch literal 1325 zcmZux&2L;a5VzmQ?%T~KjS5IqaPR@CM51}6RY64&YN3F{VUcLnNKY*<-e<qvm-v0e z_HMGP&8a<bfHT+j$iL((r~V0WV#dj~92mVBkH_}R_&4MC&Gz<?0R8sS<k=q~A%Edy zLlGzsfX$B}1QAq`nr5^PvY-yLkP;DyP(^i|#h?=rsb1aB`k=?6_mX7E4@C4u@{))| z#>ayfVKxwh$7FB#2K<q|&|Tvb)2g|Zc~y6<wk{FXqB2$6xZQbE6|IoDs;typnKu;A zP!~<OkuYxkq=nQ{JgN#?;2IK+a0~J+u=yCo8nV9Ox!V!J)hxV0$^i0+R)7C2?OZpE z!`F4X?R3ShWG8aT%2s=`wYr)>ir!!#$*P$ShYaZ9X34M_Ur5GT!)s|eUPxwV+_D1P zP9&3+ok`7(j>c^xkB%5RW(M3g(|vX*y)W2$6ArX>$2Fb?K5OA{!RN-$mp8#Ks<MPT zH<sCDC(UQfwCqg6v1TE)^^V>~u`Q-A>&`B(g0ZsF#_nGxuMsLobPU6v9#;<6(F2%z z@z1X*fUy8H(goLP*(yNWr1dN<KJW7TtNX{d&+e9DWxlw((09)5s=f_0ZPF)cS9Q0l z##pY@t$SZiW+(H>6pfzqg=|Et)0wT+JylK8vQkiBlXBI~_(a;O;0jampqu?}=>|E@ zb0|sz*_i+YN%RP0f$E0P{s7o~2ttyK3X%naW+8SdbYmnUsCn#q-}{KGPabX}uB2h_ zLi$2WC2PRhyzMN+2^m8g0pk1@OOEL)=&9HA5qUnoplj-TEja1vr#5^+E`sw<Z3I^6 zw^#9NVtXR`J%GKt&w`8aB3ei5U>zQi)2|K*Xt3{qtm#u|;?tc&cu$z^*hN_Cy}%`p zE!Xx5pSt8bEGlY|;FiN%2mzbDzV1O<dK-jG@*JN{p6fnNd)T*9xEPGJ@z4Pfk&&u& zv29Oe<6;EBxCmR=#S5<H@?A6NE%f{zh!23xE(k)e(-G~_9l8r+LRZ%=Vcp+E9zz63 z1O4T>8|Hc4in&64l;@{&uC7-4c`n)lGDY|Q3F$l0$Hg1rqQU=BLL=($INlqg*K!UI z7`$pMzYbC0HjS;~0dZSJtCTD({8fyH!{6Wg_`h&2Ik?R9YkVOF{k$KHf>D@k{R_r_ BT(bZG literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/base.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/base.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d4e9a3518a31cc5416465af8af4a9666111624c0 GIT binary patch literal 859 zcmZuvO>fjN5VhlMHuOV9h#L|o4&>0LP!&`Op$a6p^#Z2|$x34Ht{3M6+X=AR+xEyG z;V<RNiNC;!8K+xq5hKlv9Y4>TH_n^G!#x7_<5BVHF(u>|ZnhS};u73Gg&>Hanp8BS zRgeW0%NQl^i3kL{CW6Uu!?KA8Kagbd8_*<S!%<$?Mt4qfRke+ALo8IUtZM4vepjoq z5t3`=q{+1{@y^x)SX_eJClDmbs32J&s0gk}#sm`~<WNjR1bHH+z!?wGJEfsiiFeU3 zqrU~WC~-~Kgo6q|)2oCIk!?Ct$|M*<EA`AofcZ&G4Czmwwnp{2lWCuubk=AgjZLdX zT0U#}#p+^t`t@ukR`$hNZ=Qd1tLhYNUZ)?^R<*~fwl3HD`21zD_}mq9{OFzcvKEa= z7p~IhS{3Qc_iWQ5xALU@KE#}>S~<=q*tM5JS4X3=lkHgv&*TmB9f^*t$&zm9C=rC= zaJ{gEnkk^Yx-r~?t>*&>=cxKWeE#gtNErbANDp8!@~!D6*fLJ%(&f(GkOrP~2<yC( z|5ERBeuL$Fe~10St=ik;t0clsu?pwI9_LjfI*scC&cAfI9#0IuvcbO05eC$>6Hu_h zx#C}K@wH<bvzYmBNCAaso$Cw~HaJ#;S`DIys414RbRN1>(ld;Md^Ps;8sEeZ@*(>R D7W~2( literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/inject_meta_charset.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/inject_meta_charset.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6563ea299508656fc9680a8151af61483c97d196 GIT binary patch literal 1879 zcmZuyOK%%D5GJ`#DYC7`k2=j|5ugVh9HkACBB>Jubsh*%r~wir#UjCaEmG3T`w~eh zwy-)BO>aH;&_hw=U>|!cdi1$Jpyxg0(o_CIQ4}3=<-|2YfwLs%o8ioGX7ts<LLI^Q z@#4<&@6I9gm)e{R6Bc)1it9iqqBuqg_Hjadk{G^$5hc`!&BXF8j2<9rQtK6>7PE%- z_l9p%`!Q-cZ$TEdjB+X55m`KzEQpdk<Fa&VG>Jr%rDb!RM%|3EAdV#CVJzNaC4)<I zClsu!6r2nKi#srd2ZSLXQ{)qheM6b@3i)Pbgl|=sm-hWA2A$Je57Qy*O5ts9ZzfEJ zUUv|3!Q`!bovm-~KI}ZWy}j+pu<u2w%)9{$sh9OUnsvtsOJ&!9+tg5B6_qWRVjYM? zLwraIRNy0mQ30#KpcwonQ@O=iD4Fm=uQH-u_vYhf$orni#=OgJdUC+#YfomoEcJv0 z!Q>2@r4XSg?N|7d9Y}cK#d~b0WpW$r;tr6~4T30*WDu0@i3GfaDOlVq?dpDB1K_WS zH{kR45AB>s6EM0x33<Dh#guW;P6qAnXL)dAdSiIy<<%aYitAS={PR6IO|HP`r|l>0 zJjyqsRLC%nH?DoLGuR#P^wpuB!GxtW<L!Y=;%jlV)9&d<5$#AnN}wJjm_Nwne4o2u zi<&}(8o7&jx>QB*@`*oPl^|-U<W>H5VTw0!O7RRAXb9=L>&{3Y&5Q%Q_lLwoa%dFj z2;W5q_{HxtvoI;SfM!-<QDc|zN3b_9phNQr5*YShQ+tLFa5@COvr7)}{}3)9{-w2< zz4r#>>L6zwp}XkC)92(lnK?6eRx2E^pvHe16{DhXwcc|eb*yZwWD2Kndt?*Q#*92d z3Pl$HQ4}?eUQ}z~*`wkaDs27_U8>}E)w-$ltj#sirAkYB#tX3exB%P5F*T@FNz;#B z8&46Gu0vgVUTKN&yR&6#(UsRk^TDdoCGG#R_Wu~<Pen-UhS<Ul#-UADkFb)`xBdJf z-FxeWLjQIeeSk;5Jk$QuHFz~lZGF?9fN=`*2xBz5RG3Qd=n~)%l-0)_-_1D-RE3tN z+|OC*K9(VuPr`m_reVTLQ}KK!N-L0iFUjS;W~)5AUz#+OVd>2C?a8!0kTTz3qj5Bu zHo93Vq2M=^<`(GytU8#kO139;27mdkcYG>Z2495C<4r|YfPf5Ng>Px!ODSC1BBuZ< zY5iKB38_tMxw`ny)GKr=s8=h_UNT-<&=3<*8hMtNc9`c-N3A+nNnct}Y?AqPT|B*P zoYK-!eCQFSr5lO9*}pglMW9>^w2Q&qp+Lv3rXnWtu*<Xyr8NoTG1JYUA`5U8SB-8N zruY^J!X~a`ldNGEeogF>I&KmZe*!xbH}H9&CSHN_Cai6;4!lJ;X#x*8fL<pJZ0i%Z zLc>{uoUU;lgHFp<4NO@G0jUQ;lF@Oj){P(-jl+1(ae@H)bP(vap=~{7ziMk-JE0n) z>J&l|WvY8lH_1-RQObK`IflFnxcZ0Ts?T%PeM<EHc|N4JbT=!rZmY-D4QquojQ;?E CKI1O{ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/lint.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/lint.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ca55149bb4c3da9c717dec68268861296f6aff49 GIT binary patch literal 2643 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 bl@#JBoOenG-^GR{5!t-agh0>1tebxW{1(7! literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/optionaltags.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/optionaltags.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b1108a9dbcbea2ad33b8ddfd7d5c327bd90ff449 GIT binary patch literal 2770 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 C>zzyh literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/sanitizer.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/sanitizer.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9cd9568a7184153427d1c46f0b74e99beed94b73 GIT binary patch literal 16445 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/whitespace.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/whitespace.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3079598a6b02476aac9a301bf83148ce1594ba57 GIT binary patch literal 1363 zcmZ8h&2JM&6rY)0uXi0gj-mif;b5uaU^TE5M1cxbh1BI1MGb1vwrI898OQ6)elRmO z!E#PPJ@v$)XZP5DqJPL-d&<ASsqd{ZLCosC-FYALzJ9Y$JDnDR_2>2B@Bg}l{D+(M zf<5^GNEg63;Z%~GMl@#;%bm!fC}Yx%T<&mJHgYfWK-S=%Z03IC=Rp*}zPW6P;BOiQ z!d-4~Uj$bP?Ap%=4|wY>;Vt1!I_FN*;TydDmPDJJ9g%+L0%DTBW4p;vmvU-EoaI%i zjP-do%XC&2c57N>X~{(_Gb2<Y^}z*2Cu-ecqQwQn4YQjn<%vlKQskmA+IDr7q+)-Z zs3ZkHZOOdx+fDuQ>l8z-*T>@bKq5#)If)pjkt1BrxO2=zLwM)(8aby?le@eDsr%f6 z)SK4(DU)#W{K<YPWm0LOd#}fkV;#6BPE%2tURLxfCH8tooSH<5WUrSLyr)x@fl{oK zb->2@Ynv47!-d%)Vaj?5jMFoE`j;USx?~Gz@Q>u>A7^aAINK#>&cfl&2~$rOR6hin zyGs^i;+%LW;f)96j24Gr<AKeK1x4bGhba9HJZ7M2f@TJu{w`579^ltwQrrOTJJ7a3 z`_8y4{W)D}7wi{8$*b*O0VdFujRS?rTi3j)prRwF**s5<ty?6yPz_XhgMy=|d-U0W zT%6x~+Ow_8sr4Jm11GhCo_-u71mf6Use62=gcfQhE@z&8m_%Ibb>FqF7IGB%(BInB zHcWXU3bhI6{X^7sc)eeQmC9y`5#cOR;i!}x;1cHJF#V>AAI%?4?!3M?;&c7&y_vdu zYUcSJSjR>9Jgl<nR#s?}NO|l2gW>pOIy^>UP4P?=yj0=X<nq4EhT*7&iw-YAa=Ut? zu0jf1K>ABygt~N_`tWSi7Hb3TFnn*Zd3S}j+v^@2^aE@N_7xh^isQWGQ;Fa0IDR!v z<OfYNj(M4aI2fsNE($G-b!DcF@*$qOh75D4d+`aofii4+8%X02d`NDG)v}KW#bF~t z_t6L~4Ovo70h@Te*@4;t8QjkH(czQ*!BPD4;Mw4Xb@X(I_ZI>GdB`uo;U=Dj_nJ_J z`+gS-98JwsL4gW2%0Y&qEmK0_@2y6P4bl=P0>6M&fdQJhlQJu8GcEHflR|xk)>vD8 g`X?D69u!t?{l}|*evcJugv$=|aS||-O=o-ef2@&Sr2qf` literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/alphabeticalattributes.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/alphabeticalattributes.py new file mode 100644 index 0000000..5ba926e --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/alphabeticalattributes.py @@ -0,0 +1,29 @@ +from __future__ import absolute_import, division, unicode_literals + +from . import base + +from collections import OrderedDict + + +def _attr_key(attr): + """Return an appropriate key for an attribute for sorting + + Attributes have a namespace that can be either ``None`` or a string. We + can't compare the two because they're different types, so we convert + ``None`` to an empty string first. + + """ + return (attr[0][0] or ''), attr[0][1] + + +class Filter(base.Filter): + """Alphabetizes attributes for elements""" + def __iter__(self): + for token in base.Filter.__iter__(self): + if token["type"] in ("StartTag", "EmptyTag"): + attrs = OrderedDict() + for name, value in sorted(token["data"].items(), + key=_attr_key): + attrs[name] = value + token["data"] = attrs + yield token diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/base.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/base.py new file mode 100644 index 0000000..c7dbaed --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/base.py @@ -0,0 +1,12 @@ +from __future__ import absolute_import, division, unicode_literals + + +class Filter(object): + def __init__(self, source): + self.source = source + + def __iter__(self): + return iter(self.source) + + def __getattr__(self, name): + return getattr(self.source, name) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/inject_meta_charset.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/inject_meta_charset.py new file mode 100644 index 0000000..aefb5c8 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/inject_meta_charset.py @@ -0,0 +1,73 @@ +from __future__ import absolute_import, division, unicode_literals + +from . import base + + +class Filter(base.Filter): + """Injects ``<meta charset=ENCODING>`` tag into head of document""" + def __init__(self, source, encoding): + """Creates a Filter + + :arg source: the source token stream + + :arg encoding: the encoding to set + + """ + base.Filter.__init__(self, source) + self.encoding = encoding + + def __iter__(self): + state = "pre_head" + meta_found = (self.encoding is None) + pending = [] + + for token in base.Filter.__iter__(self): + type = token["type"] + if type == "StartTag": + if token["name"].lower() == "head": + state = "in_head" + + elif type == "EmptyTag": + if token["name"].lower() == "meta": + # replace charset with actual encoding + has_http_equiv_content_type = False + for (namespace, name), value in token["data"].items(): + if namespace is not None: + continue + elif name.lower() == 'charset': + token["data"][(namespace, name)] = self.encoding + meta_found = True + break + elif name == 'http-equiv' and value.lower() == 'content-type': + has_http_equiv_content_type = True + else: + if has_http_equiv_content_type and (None, "content") in token["data"]: + token["data"][(None, "content")] = 'text/html; charset=%s' % self.encoding + meta_found = True + + elif token["name"].lower() == "head" and not meta_found: + # insert meta into empty head + yield {"type": "StartTag", "name": "head", + "data": token["data"]} + yield {"type": "EmptyTag", "name": "meta", + "data": {(None, "charset"): self.encoding}} + yield {"type": "EndTag", "name": "head"} + meta_found = True + continue + + elif type == "EndTag": + if token["name"].lower() == "head" and pending: + # insert meta into head (if necessary) and flush pending queue + yield pending.pop(0) + if not meta_found: + yield {"type": "EmptyTag", "name": "meta", + "data": {(None, "charset"): self.encoding}} + while pending: + yield pending.pop(0) + meta_found = True + state = "post_head" + + if state == "in_head": + pending.append(token) + else: + yield token diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/lint.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/lint.py new file mode 100644 index 0000000..fcc07ee --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/lint.py @@ -0,0 +1,93 @@ +from __future__ import absolute_import, division, unicode_literals + +from pip._vendor.six import text_type + +from . import base +from ..constants import namespaces, voidElements + +from ..constants import spaceCharacters +spaceCharacters = "".join(spaceCharacters) + + +class Filter(base.Filter): + """Lints the token stream for errors + + If it finds any errors, it'll raise an ``AssertionError``. + + """ + def __init__(self, source, require_matching_tags=True): + """Creates a Filter + + :arg source: the source token stream + + :arg require_matching_tags: whether or not to require matching tags + + """ + super(Filter, self).__init__(source) + self.require_matching_tags = require_matching_tags + + def __iter__(self): + open_elements = [] + for token in base.Filter.__iter__(self): + type = token["type"] + if type in ("StartTag", "EmptyTag"): + namespace = token["namespace"] + name = token["name"] + assert namespace is None or isinstance(namespace, text_type) + assert namespace != "" + assert isinstance(name, text_type) + assert name != "" + assert isinstance(token["data"], dict) + if (not namespace or namespace == namespaces["html"]) and name in voidElements: + assert type == "EmptyTag" + else: + assert type == "StartTag" + if type == "StartTag" and self.require_matching_tags: + open_elements.append((namespace, name)) + for (namespace, name), value in token["data"].items(): + assert namespace is None or isinstance(namespace, text_type) + assert namespace != "" + assert isinstance(name, text_type) + assert name != "" + assert isinstance(value, text_type) + + elif type == "EndTag": + namespace = token["namespace"] + name = token["name"] + assert namespace is None or isinstance(namespace, text_type) + assert namespace != "" + assert isinstance(name, text_type) + assert name != "" + if (not namespace or namespace == namespaces["html"]) and name in voidElements: + assert False, "Void element reported as EndTag token: %(tag)s" % {"tag": name} + elif self.require_matching_tags: + start = open_elements.pop() + assert start == (namespace, name) + + elif type == "Comment": + data = token["data"] + assert isinstance(data, text_type) + + elif type in ("Characters", "SpaceCharacters"): + data = token["data"] + assert isinstance(data, text_type) + assert data != "" + if type == "SpaceCharacters": + assert data.strip(spaceCharacters) == "" + + elif type == "Doctype": + name = token["name"] + assert name is None or isinstance(name, text_type) + assert token["publicId"] is None or isinstance(name, text_type) + assert token["systemId"] is None or isinstance(name, text_type) + + elif type == "Entity": + assert isinstance(token["name"], text_type) + + elif type == "SerializerError": + assert isinstance(token["data"], text_type) + + else: + assert False, "Unknown token type: %(type)s" % {"type": type} + + yield token diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/optionaltags.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/optionaltags.py new file mode 100644 index 0000000..4a86501 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/optionaltags.py @@ -0,0 +1,207 @@ +from __future__ import absolute_import, division, unicode_literals + +from . import base + + +class Filter(base.Filter): + """Removes optional tags from the token stream""" + def slider(self): + previous1 = previous2 = None + for token in self.source: + if previous1 is not None: + yield previous2, previous1, token + previous2 = previous1 + previous1 = token + if previous1 is not None: + yield previous2, previous1, None + + def __iter__(self): + for previous, token, next in self.slider(): + type = token["type"] + if type == "StartTag": + if (token["data"] or + not self.is_optional_start(token["name"], previous, next)): + yield token + elif type == "EndTag": + if not self.is_optional_end(token["name"], next): + yield token + else: + yield token + + def is_optional_start(self, tagname, previous, next): + type = next and next["type"] or None + if tagname in 'html': + # An html element's start tag may be omitted if the first thing + # inside the html element is not a space character or a comment. + return type not in ("Comment", "SpaceCharacters") + elif tagname == 'head': + # A head element's start tag may be omitted if the first thing + # inside the head element is an element. + # XXX: we also omit the start tag if the head element is empty + if type in ("StartTag", "EmptyTag"): + return True + elif type == "EndTag": + return next["name"] == "head" + elif tagname == 'body': + # A body element's start tag may be omitted if the first thing + # inside the body element is not a space character or a comment, + # except if the first thing inside the body element is a script + # or style element and the node immediately preceding the body + # element is a head element whose end tag has been omitted. + if type in ("Comment", "SpaceCharacters"): + return False + elif type == "StartTag": + # XXX: we do not look at the preceding event, so we never omit + # the body element's start tag if it's followed by a script or + # a style element. + return next["name"] not in ('script', 'style') + else: + return True + elif tagname == 'colgroup': + # A colgroup element's start tag may be omitted if the first thing + # inside the colgroup element is a col element, and if the element + # is not immediately preceded by another colgroup element whose + # end tag has been omitted. + if type in ("StartTag", "EmptyTag"): + # XXX: we do not look at the preceding event, so instead we never + # omit the colgroup element's end tag when it is immediately + # followed by another colgroup element. See is_optional_end. + return next["name"] == "col" + else: + return False + elif tagname == 'tbody': + # A tbody element's start tag may be omitted if the first thing + # inside the tbody element is a tr element, and if the element is + # not immediately preceded by a tbody, thead, or tfoot element + # whose end tag has been omitted. + if type == "StartTag": + # omit the thead and tfoot elements' end tag when they are + # immediately followed by a tbody element. See is_optional_end. + if previous and previous['type'] == 'EndTag' and \ + previous['name'] in ('tbody', 'thead', 'tfoot'): + return False + return next["name"] == 'tr' + else: + return False + return False + + def is_optional_end(self, tagname, next): + type = next and next["type"] or None + if tagname in ('html', 'head', 'body'): + # An html element's end tag may be omitted if the html element + # is not immediately followed by a space character or a comment. + return type not in ("Comment", "SpaceCharacters") + elif tagname in ('li', 'optgroup', 'tr'): + # A li element's end tag may be omitted if the li element is + # immediately followed by another li element or if there is + # no more content in the parent element. + # An optgroup element's end tag may be omitted if the optgroup + # element is immediately followed by another optgroup element, + # or if there is no more content in the parent element. + # A tr element's end tag may be omitted if the tr element is + # immediately followed by another tr element, or if there is + # no more content in the parent element. + if type == "StartTag": + return next["name"] == tagname + else: + return type == "EndTag" or type is None + elif tagname in ('dt', 'dd'): + # A dt element's end tag may be omitted if the dt element is + # immediately followed by another dt element or a dd element. + # A dd element's end tag may be omitted if the dd element is + # immediately followed by another dd element or a dt element, + # or if there is no more content in the parent element. + if type == "StartTag": + return next["name"] in ('dt', 'dd') + elif tagname == 'dd': + return type == "EndTag" or type is None + else: + return False + elif tagname == 'p': + # A p element's end tag may be omitted if the p element is + # immediately followed by an address, article, aside, + # blockquote, datagrid, dialog, dir, div, dl, fieldset, + # footer, form, h1, h2, h3, h4, h5, h6, header, hr, menu, + # nav, ol, p, pre, section, table, or ul, element, or if + # there is no more content in the parent element. + if type in ("StartTag", "EmptyTag"): + return next["name"] in ('address', 'article', 'aside', + 'blockquote', 'datagrid', 'dialog', + 'dir', 'div', 'dl', 'fieldset', 'footer', + 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', + 'header', 'hr', 'menu', 'nav', 'ol', + 'p', 'pre', 'section', 'table', 'ul') + else: + return type == "EndTag" or type is None + elif tagname == 'option': + # An option element's end tag may be omitted if the option + # element is immediately followed by another option element, + # or if it is immediately followed by an <code>optgroup</code> + # element, or if there is no more content in the parent + # element. + if type == "StartTag": + return next["name"] in ('option', 'optgroup') + else: + return type == "EndTag" or type is None + elif tagname in ('rt', 'rp'): + # An rt element's end tag may be omitted if the rt element is + # immediately followed by an rt or rp element, or if there is + # no more content in the parent element. + # An rp element's end tag may be omitted if the rp element is + # immediately followed by an rt or rp element, or if there is + # no more content in the parent element. + if type == "StartTag": + return next["name"] in ('rt', 'rp') + else: + return type == "EndTag" or type is None + elif tagname == 'colgroup': + # A colgroup element's end tag may be omitted if the colgroup + # element is not immediately followed by a space character or + # a comment. + if type in ("Comment", "SpaceCharacters"): + return False + elif type == "StartTag": + # XXX: we also look for an immediately following colgroup + # element. See is_optional_start. + return next["name"] != 'colgroup' + else: + return True + elif tagname in ('thead', 'tbody'): + # A thead element's end tag may be omitted if the thead element + # is immediately followed by a tbody or tfoot element. + # A tbody element's end tag may be omitted if the tbody element + # is immediately followed by a tbody or tfoot element, or if + # there is no more content in the parent element. + # A tfoot element's end tag may be omitted if the tfoot element + # is immediately followed by a tbody element, or if there is no + # more content in the parent element. + # XXX: we never omit the end tag when the following element is + # a tbody. See is_optional_start. + if type == "StartTag": + return next["name"] in ['tbody', 'tfoot'] + elif tagname == 'tbody': + return type == "EndTag" or type is None + else: + return False + elif tagname == 'tfoot': + # A tfoot element's end tag may be omitted if the tfoot element + # is immediately followed by a tbody element, or if there is no + # more content in the parent element. + # XXX: we never omit the end tag when the following element is + # a tbody. See is_optional_start. + if type == "StartTag": + return next["name"] == 'tbody' + else: + return type == "EndTag" or type is None + elif tagname in ('td', 'th'): + # A td element's end tag may be omitted if the td element is + # immediately followed by a td or th element, or if there is + # no more content in the parent element. + # A th element's end tag may be omitted if the th element is + # immediately followed by a td or th element, or if there is + # no more content in the parent element. + if type == "StartTag": + return next["name"] in ('td', 'th') + else: + return type == "EndTag" or type is None + return False diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/sanitizer.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/sanitizer.py new file mode 100644 index 0000000..af8e77b --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/sanitizer.py @@ -0,0 +1,896 @@ +from __future__ import absolute_import, division, unicode_literals + +import re +from xml.sax.saxutils import escape, unescape + +from pip._vendor.six.moves import urllib_parse as urlparse + +from . import base +from ..constants import namespaces, prefixes + +__all__ = ["Filter"] + + +allowed_elements = frozenset(( + (namespaces['html'], 'a'), + (namespaces['html'], 'abbr'), + (namespaces['html'], 'acronym'), + (namespaces['html'], 'address'), + (namespaces['html'], 'area'), + (namespaces['html'], 'article'), + (namespaces['html'], 'aside'), + (namespaces['html'], 'audio'), + (namespaces['html'], 'b'), + (namespaces['html'], 'big'), + (namespaces['html'], 'blockquote'), + (namespaces['html'], 'br'), + (namespaces['html'], 'button'), + (namespaces['html'], 'canvas'), + (namespaces['html'], 'caption'), + (namespaces['html'], 'center'), + (namespaces['html'], 'cite'), + (namespaces['html'], 'code'), + (namespaces['html'], 'col'), + (namespaces['html'], 'colgroup'), + (namespaces['html'], 'command'), + (namespaces['html'], 'datagrid'), + (namespaces['html'], 'datalist'), + (namespaces['html'], 'dd'), + (namespaces['html'], 'del'), + (namespaces['html'], 'details'), + (namespaces['html'], 'dfn'), + (namespaces['html'], 'dialog'), + (namespaces['html'], 'dir'), + (namespaces['html'], 'div'), + (namespaces['html'], 'dl'), + (namespaces['html'], 'dt'), + (namespaces['html'], 'em'), + (namespaces['html'], 'event-source'), + (namespaces['html'], 'fieldset'), + (namespaces['html'], 'figcaption'), + (namespaces['html'], 'figure'), + (namespaces['html'], 'footer'), + (namespaces['html'], 'font'), + (namespaces['html'], 'form'), + (namespaces['html'], 'header'), + (namespaces['html'], 'h1'), + (namespaces['html'], 'h2'), + (namespaces['html'], 'h3'), + (namespaces['html'], 'h4'), + (namespaces['html'], 'h5'), + (namespaces['html'], 'h6'), + (namespaces['html'], 'hr'), + (namespaces['html'], 'i'), + (namespaces['html'], 'img'), + (namespaces['html'], 'input'), + (namespaces['html'], 'ins'), + (namespaces['html'], 'keygen'), + (namespaces['html'], 'kbd'), + (namespaces['html'], 'label'), + (namespaces['html'], 'legend'), + (namespaces['html'], 'li'), + (namespaces['html'], 'm'), + (namespaces['html'], 'map'), + (namespaces['html'], 'menu'), + (namespaces['html'], 'meter'), + (namespaces['html'], 'multicol'), + (namespaces['html'], 'nav'), + (namespaces['html'], 'nextid'), + (namespaces['html'], 'ol'), + (namespaces['html'], 'output'), + (namespaces['html'], 'optgroup'), + (namespaces['html'], 'option'), + (namespaces['html'], 'p'), + (namespaces['html'], 'pre'), + (namespaces['html'], 'progress'), + (namespaces['html'], 'q'), + (namespaces['html'], 's'), + (namespaces['html'], 'samp'), + (namespaces['html'], 'section'), + (namespaces['html'], 'select'), + (namespaces['html'], 'small'), + (namespaces['html'], 'sound'), + (namespaces['html'], 'source'), + (namespaces['html'], 'spacer'), + (namespaces['html'], 'span'), + (namespaces['html'], 'strike'), + (namespaces['html'], 'strong'), + (namespaces['html'], 'sub'), + (namespaces['html'], 'sup'), + (namespaces['html'], 'table'), + (namespaces['html'], 'tbody'), + (namespaces['html'], 'td'), + (namespaces['html'], 'textarea'), + (namespaces['html'], 'time'), + (namespaces['html'], 'tfoot'), + (namespaces['html'], 'th'), + (namespaces['html'], 'thead'), + (namespaces['html'], 'tr'), + (namespaces['html'], 'tt'), + (namespaces['html'], 'u'), + (namespaces['html'], 'ul'), + (namespaces['html'], 'var'), + (namespaces['html'], 'video'), + (namespaces['mathml'], 'maction'), + (namespaces['mathml'], 'math'), + (namespaces['mathml'], 'merror'), + (namespaces['mathml'], 'mfrac'), + (namespaces['mathml'], 'mi'), + (namespaces['mathml'], 'mmultiscripts'), + (namespaces['mathml'], 'mn'), + (namespaces['mathml'], 'mo'), + (namespaces['mathml'], 'mover'), + (namespaces['mathml'], 'mpadded'), + (namespaces['mathml'], 'mphantom'), + (namespaces['mathml'], 'mprescripts'), + (namespaces['mathml'], 'mroot'), + (namespaces['mathml'], 'mrow'), + (namespaces['mathml'], 'mspace'), + (namespaces['mathml'], 'msqrt'), + (namespaces['mathml'], 'mstyle'), + (namespaces['mathml'], 'msub'), + (namespaces['mathml'], 'msubsup'), + (namespaces['mathml'], 'msup'), + (namespaces['mathml'], 'mtable'), + (namespaces['mathml'], 'mtd'), + (namespaces['mathml'], 'mtext'), + (namespaces['mathml'], 'mtr'), + (namespaces['mathml'], 'munder'), + (namespaces['mathml'], 'munderover'), + (namespaces['mathml'], 'none'), + (namespaces['svg'], 'a'), + (namespaces['svg'], 'animate'), + (namespaces['svg'], 'animateColor'), + (namespaces['svg'], 'animateMotion'), + (namespaces['svg'], 'animateTransform'), + (namespaces['svg'], 'clipPath'), + (namespaces['svg'], 'circle'), + (namespaces['svg'], 'defs'), + (namespaces['svg'], 'desc'), + (namespaces['svg'], 'ellipse'), + (namespaces['svg'], 'font-face'), + (namespaces['svg'], 'font-face-name'), + (namespaces['svg'], 'font-face-src'), + (namespaces['svg'], 'g'), + (namespaces['svg'], 'glyph'), + (namespaces['svg'], 'hkern'), + (namespaces['svg'], 'linearGradient'), + (namespaces['svg'], 'line'), + (namespaces['svg'], 'marker'), + (namespaces['svg'], 'metadata'), + (namespaces['svg'], 'missing-glyph'), + (namespaces['svg'], 'mpath'), + (namespaces['svg'], 'path'), + (namespaces['svg'], 'polygon'), + (namespaces['svg'], 'polyline'), + (namespaces['svg'], 'radialGradient'), + (namespaces['svg'], 'rect'), + (namespaces['svg'], 'set'), + (namespaces['svg'], 'stop'), + (namespaces['svg'], 'svg'), + (namespaces['svg'], 'switch'), + (namespaces['svg'], 'text'), + (namespaces['svg'], 'title'), + (namespaces['svg'], 'tspan'), + (namespaces['svg'], 'use'), +)) + +allowed_attributes = frozenset(( + # HTML attributes + (None, 'abbr'), + (None, 'accept'), + (None, 'accept-charset'), + (None, 'accesskey'), + (None, 'action'), + (None, 'align'), + (None, 'alt'), + (None, 'autocomplete'), + (None, 'autofocus'), + (None, 'axis'), + (None, 'background'), + (None, 'balance'), + (None, 'bgcolor'), + (None, 'bgproperties'), + (None, 'border'), + (None, 'bordercolor'), + (None, 'bordercolordark'), + (None, 'bordercolorlight'), + (None, 'bottompadding'), + (None, 'cellpadding'), + (None, 'cellspacing'), + (None, 'ch'), + (None, 'challenge'), + (None, 'char'), + (None, 'charoff'), + (None, 'choff'), + (None, 'charset'), + (None, 'checked'), + (None, 'cite'), + (None, 'class'), + (None, 'clear'), + (None, 'color'), + (None, 'cols'), + (None, 'colspan'), + (None, 'compact'), + (None, 'contenteditable'), + (None, 'controls'), + (None, 'coords'), + (None, 'data'), + (None, 'datafld'), + (None, 'datapagesize'), + (None, 'datasrc'), + (None, 'datetime'), + (None, 'default'), + (None, 'delay'), + (None, 'dir'), + (None, 'disabled'), + (None, 'draggable'), + (None, 'dynsrc'), + (None, 'enctype'), + (None, 'end'), + (None, 'face'), + (None, 'for'), + (None, 'form'), + (None, 'frame'), + (None, 'galleryimg'), + (None, 'gutter'), + (None, 'headers'), + (None, 'height'), + (None, 'hidefocus'), + (None, 'hidden'), + (None, 'high'), + (None, 'href'), + (None, 'hreflang'), + (None, 'hspace'), + (None, 'icon'), + (None, 'id'), + (None, 'inputmode'), + (None, 'ismap'), + (None, 'keytype'), + (None, 'label'), + (None, 'leftspacing'), + (None, 'lang'), + (None, 'list'), + (None, 'longdesc'), + (None, 'loop'), + (None, 'loopcount'), + (None, 'loopend'), + (None, 'loopstart'), + (None, 'low'), + (None, 'lowsrc'), + (None, 'max'), + (None, 'maxlength'), + (None, 'media'), + (None, 'method'), + (None, 'min'), + (None, 'multiple'), + (None, 'name'), + (None, 'nohref'), + (None, 'noshade'), + (None, 'nowrap'), + (None, 'open'), + (None, 'optimum'), + (None, 'pattern'), + (None, 'ping'), + (None, 'point-size'), + (None, 'poster'), + (None, 'pqg'), + (None, 'preload'), + (None, 'prompt'), + (None, 'radiogroup'), + (None, 'readonly'), + (None, 'rel'), + (None, 'repeat-max'), + (None, 'repeat-min'), + (None, 'replace'), + (None, 'required'), + (None, 'rev'), + (None, 'rightspacing'), + (None, 'rows'), + (None, 'rowspan'), + (None, 'rules'), + (None, 'scope'), + (None, 'selected'), + (None, 'shape'), + (None, 'size'), + (None, 'span'), + (None, 'src'), + (None, 'start'), + (None, 'step'), + (None, 'style'), + (None, 'summary'), + (None, 'suppress'), + (None, 'tabindex'), + (None, 'target'), + (None, 'template'), + (None, 'title'), + (None, 'toppadding'), + (None, 'type'), + (None, 'unselectable'), + (None, 'usemap'), + (None, 'urn'), + (None, 'valign'), + (None, 'value'), + (None, 'variable'), + (None, 'volume'), + (None, 'vspace'), + (None, 'vrml'), + (None, 'width'), + (None, 'wrap'), + (namespaces['xml'], 'lang'), + # MathML attributes + (None, 'actiontype'), + (None, 'align'), + (None, 'columnalign'), + (None, 'columnalign'), + (None, 'columnalign'), + (None, 'columnlines'), + (None, 'columnspacing'), + (None, 'columnspan'), + (None, 'depth'), + (None, 'display'), + (None, 'displaystyle'), + (None, 'equalcolumns'), + (None, 'equalrows'), + (None, 'fence'), + (None, 'fontstyle'), + (None, 'fontweight'), + (None, 'frame'), + (None, 'height'), + (None, 'linethickness'), + (None, 'lspace'), + (None, 'mathbackground'), + (None, 'mathcolor'), + (None, 'mathvariant'), + (None, 'mathvariant'), + (None, 'maxsize'), + (None, 'minsize'), + (None, 'other'), + (None, 'rowalign'), + (None, 'rowalign'), + (None, 'rowalign'), + (None, 'rowlines'), + (None, 'rowspacing'), + (None, 'rowspan'), + (None, 'rspace'), + (None, 'scriptlevel'), + (None, 'selection'), + (None, 'separator'), + (None, 'stretchy'), + (None, 'width'), + (None, 'width'), + (namespaces['xlink'], 'href'), + (namespaces['xlink'], 'show'), + (namespaces['xlink'], 'type'), + # SVG attributes + (None, 'accent-height'), + (None, 'accumulate'), + (None, 'additive'), + (None, 'alphabetic'), + (None, 'arabic-form'), + (None, 'ascent'), + (None, 'attributeName'), + (None, 'attributeType'), + (None, 'baseProfile'), + (None, 'bbox'), + (None, 'begin'), + (None, 'by'), + (None, 'calcMode'), + (None, 'cap-height'), + (None, 'class'), + (None, 'clip-path'), + (None, 'color'), + (None, 'color-rendering'), + (None, 'content'), + (None, 'cx'), + (None, 'cy'), + (None, 'd'), + (None, 'dx'), + (None, 'dy'), + (None, 'descent'), + (None, 'display'), + (None, 'dur'), + (None, 'end'), + (None, 'fill'), + (None, 'fill-opacity'), + (None, 'fill-rule'), + (None, 'font-family'), + (None, 'font-size'), + (None, 'font-stretch'), + (None, 'font-style'), + (None, 'font-variant'), + (None, 'font-weight'), + (None, 'from'), + (None, 'fx'), + (None, 'fy'), + (None, 'g1'), + (None, 'g2'), + (None, 'glyph-name'), + (None, 'gradientUnits'), + (None, 'hanging'), + (None, 'height'), + (None, 'horiz-adv-x'), + (None, 'horiz-origin-x'), + (None, 'id'), + (None, 'ideographic'), + (None, 'k'), + (None, 'keyPoints'), + (None, 'keySplines'), + (None, 'keyTimes'), + (None, 'lang'), + (None, 'marker-end'), + (None, 'marker-mid'), + (None, 'marker-start'), + (None, 'markerHeight'), + (None, 'markerUnits'), + (None, 'markerWidth'), + (None, 'mathematical'), + (None, 'max'), + (None, 'min'), + (None, 'name'), + (None, 'offset'), + (None, 'opacity'), + (None, 'orient'), + (None, 'origin'), + (None, 'overline-position'), + (None, 'overline-thickness'), + (None, 'panose-1'), + (None, 'path'), + (None, 'pathLength'), + (None, 'points'), + (None, 'preserveAspectRatio'), + (None, 'r'), + (None, 'refX'), + (None, 'refY'), + (None, 'repeatCount'), + (None, 'repeatDur'), + (None, 'requiredExtensions'), + (None, 'requiredFeatures'), + (None, 'restart'), + (None, 'rotate'), + (None, 'rx'), + (None, 'ry'), + (None, 'slope'), + (None, 'stemh'), + (None, 'stemv'), + (None, 'stop-color'), + (None, 'stop-opacity'), + (None, 'strikethrough-position'), + (None, 'strikethrough-thickness'), + (None, 'stroke'), + (None, 'stroke-dasharray'), + (None, 'stroke-dashoffset'), + (None, 'stroke-linecap'), + (None, 'stroke-linejoin'), + (None, 'stroke-miterlimit'), + (None, 'stroke-opacity'), + (None, 'stroke-width'), + (None, 'systemLanguage'), + (None, 'target'), + (None, 'text-anchor'), + (None, 'to'), + (None, 'transform'), + (None, 'type'), + (None, 'u1'), + (None, 'u2'), + (None, 'underline-position'), + (None, 'underline-thickness'), + (None, 'unicode'), + (None, 'unicode-range'), + (None, 'units-per-em'), + (None, 'values'), + (None, 'version'), + (None, 'viewBox'), + (None, 'visibility'), + (None, 'width'), + (None, 'widths'), + (None, 'x'), + (None, 'x-height'), + (None, 'x1'), + (None, 'x2'), + (namespaces['xlink'], 'actuate'), + (namespaces['xlink'], 'arcrole'), + (namespaces['xlink'], 'href'), + (namespaces['xlink'], 'role'), + (namespaces['xlink'], 'show'), + (namespaces['xlink'], 'title'), + (namespaces['xlink'], 'type'), + (namespaces['xml'], 'base'), + (namespaces['xml'], 'lang'), + (namespaces['xml'], 'space'), + (None, 'y'), + (None, 'y1'), + (None, 'y2'), + (None, 'zoomAndPan'), +)) + +attr_val_is_uri = frozenset(( + (None, 'href'), + (None, 'src'), + (None, 'cite'), + (None, 'action'), + (None, 'longdesc'), + (None, 'poster'), + (None, 'background'), + (None, 'datasrc'), + (None, 'dynsrc'), + (None, 'lowsrc'), + (None, 'ping'), + (namespaces['xlink'], 'href'), + (namespaces['xml'], 'base'), +)) + +svg_attr_val_allows_ref = frozenset(( + (None, 'clip-path'), + (None, 'color-profile'), + (None, 'cursor'), + (None, 'fill'), + (None, 'filter'), + (None, 'marker'), + (None, 'marker-start'), + (None, 'marker-mid'), + (None, 'marker-end'), + (None, 'mask'), + (None, 'stroke'), +)) + +svg_allow_local_href = frozenset(( + (None, 'altGlyph'), + (None, 'animate'), + (None, 'animateColor'), + (None, 'animateMotion'), + (None, 'animateTransform'), + (None, 'cursor'), + (None, 'feImage'), + (None, 'filter'), + (None, 'linearGradient'), + (None, 'pattern'), + (None, 'radialGradient'), + (None, 'textpath'), + (None, 'tref'), + (None, 'set'), + (None, 'use') +)) + +allowed_css_properties = frozenset(( + 'azimuth', + 'background-color', + 'border-bottom-color', + 'border-collapse', + 'border-color', + 'border-left-color', + 'border-right-color', + 'border-top-color', + 'clear', + 'color', + 'cursor', + 'direction', + 'display', + 'elevation', + 'float', + 'font', + 'font-family', + 'font-size', + 'font-style', + 'font-variant', + 'font-weight', + 'height', + 'letter-spacing', + 'line-height', + 'overflow', + 'pause', + 'pause-after', + 'pause-before', + 'pitch', + 'pitch-range', + 'richness', + 'speak', + 'speak-header', + 'speak-numeral', + 'speak-punctuation', + 'speech-rate', + 'stress', + 'text-align', + 'text-decoration', + 'text-indent', + 'unicode-bidi', + 'vertical-align', + 'voice-family', + 'volume', + 'white-space', + 'width', +)) + +allowed_css_keywords = frozenset(( + 'auto', + 'aqua', + 'black', + 'block', + 'blue', + 'bold', + 'both', + 'bottom', + 'brown', + 'center', + 'collapse', + 'dashed', + 'dotted', + 'fuchsia', + 'gray', + 'green', + '!important', + 'italic', + 'left', + 'lime', + 'maroon', + 'medium', + 'none', + 'navy', + 'normal', + 'nowrap', + 'olive', + 'pointer', + 'purple', + 'red', + 'right', + 'solid', + 'silver', + 'teal', + 'top', + 'transparent', + 'underline', + 'white', + 'yellow', +)) + +allowed_svg_properties = frozenset(( + 'fill', + 'fill-opacity', + 'fill-rule', + 'stroke', + 'stroke-width', + 'stroke-linecap', + 'stroke-linejoin', + 'stroke-opacity', +)) + +allowed_protocols = frozenset(( + 'ed2k', + 'ftp', + 'http', + 'https', + 'irc', + 'mailto', + 'news', + 'gopher', + 'nntp', + 'telnet', + 'webcal', + 'xmpp', + 'callto', + 'feed', + 'urn', + 'aim', + 'rsync', + 'tag', + 'ssh', + 'sftp', + 'rtsp', + 'afs', + 'data', +)) + +allowed_content_types = frozenset(( + 'image/png', + 'image/jpeg', + 'image/gif', + 'image/webp', + 'image/bmp', + 'text/plain', +)) + + +data_content_type = re.compile(r''' + ^ + # Match a content type <application>/<type> + (?P<content_type>[-a-zA-Z0-9.]+/[-a-zA-Z0-9.]+) + # Match any character set and encoding + (?:(?:;charset=(?:[-a-zA-Z0-9]+)(?:;(?:base64))?) + |(?:;(?:base64))?(?:;charset=(?:[-a-zA-Z0-9]+))?) + # Assume the rest is data + ,.* + $ + ''', + re.VERBOSE) + + +class Filter(base.Filter): + """Sanitizes token stream of XHTML+MathML+SVG and of inline style attributes""" + def __init__(self, + source, + allowed_elements=allowed_elements, + allowed_attributes=allowed_attributes, + allowed_css_properties=allowed_css_properties, + allowed_css_keywords=allowed_css_keywords, + allowed_svg_properties=allowed_svg_properties, + allowed_protocols=allowed_protocols, + allowed_content_types=allowed_content_types, + attr_val_is_uri=attr_val_is_uri, + svg_attr_val_allows_ref=svg_attr_val_allows_ref, + svg_allow_local_href=svg_allow_local_href): + """Creates a Filter + + :arg allowed_elements: set of elements to allow--everything else will + be escaped + + :arg allowed_attributes: set of attributes to allow in + elements--everything else will be stripped + + :arg allowed_css_properties: set of CSS properties to allow--everything + else will be stripped + + :arg allowed_css_keywords: set of CSS keywords to allow--everything + else will be stripped + + :arg allowed_svg_properties: set of SVG properties to allow--everything + else will be removed + + :arg allowed_protocols: set of allowed protocols for URIs + + :arg allowed_content_types: set of allowed content types for ``data`` URIs. + + :arg attr_val_is_uri: set of attributes that have URI values--values + that have a scheme not listed in ``allowed_protocols`` are removed + + :arg svg_attr_val_allows_ref: set of SVG attributes that can have + references + + :arg svg_allow_local_href: set of SVG elements that can have local + hrefs--these are removed + + """ + super(Filter, self).__init__(source) + self.allowed_elements = allowed_elements + self.allowed_attributes = allowed_attributes + self.allowed_css_properties = allowed_css_properties + self.allowed_css_keywords = allowed_css_keywords + self.allowed_svg_properties = allowed_svg_properties + self.allowed_protocols = allowed_protocols + self.allowed_content_types = allowed_content_types + self.attr_val_is_uri = attr_val_is_uri + self.svg_attr_val_allows_ref = svg_attr_val_allows_ref + self.svg_allow_local_href = svg_allow_local_href + + def __iter__(self): + for token in base.Filter.__iter__(self): + token = self.sanitize_token(token) + if token: + yield token + + # Sanitize the +html+, escaping all elements not in ALLOWED_ELEMENTS, and + # stripping out all attributes not in ALLOWED_ATTRIBUTES. Style attributes + # are parsed, and a restricted set, specified by ALLOWED_CSS_PROPERTIES and + # ALLOWED_CSS_KEYWORDS, are allowed through. attributes in ATTR_VAL_IS_URI + # are scanned, and only URI schemes specified in ALLOWED_PROTOCOLS are + # allowed. + # + # sanitize_html('<script> do_nasty_stuff() </script>') + # => <script> do_nasty_stuff() </script> + # sanitize_html('<a href="javascript: sucker();">Click here for $100</a>') + # => <a>Click here for $100</a> + def sanitize_token(self, token): + + # accommodate filters which use token_type differently + token_type = token["type"] + if token_type in ("StartTag", "EndTag", "EmptyTag"): + name = token["name"] + namespace = token["namespace"] + if ((namespace, name) in self.allowed_elements or + (namespace is None and + (namespaces["html"], name) in self.allowed_elements)): + return self.allowed_token(token) + else: + return self.disallowed_token(token) + elif token_type == "Comment": + pass + else: + return token + + def allowed_token(self, token): + if "data" in token: + attrs = token["data"] + attr_names = set(attrs.keys()) + + # Remove forbidden attributes + for to_remove in (attr_names - self.allowed_attributes): + del token["data"][to_remove] + attr_names.remove(to_remove) + + # Remove attributes with disallowed URL values + for attr in (attr_names & self.attr_val_is_uri): + assert attr in attrs + # I don't have a clue where this regexp comes from or why it matches those + # characters, nor why we call unescape. I just know it's always been here. + # Should you be worried by this comment in a sanitizer? Yes. On the other hand, all + # this will do is remove *more* than it otherwise would. + val_unescaped = re.sub("[`\x00-\x20\x7f-\xa0\\s]+", '', + unescape(attrs[attr])).lower() + # remove replacement characters from unescaped characters + val_unescaped = val_unescaped.replace("\ufffd", "") + try: + uri = urlparse.urlparse(val_unescaped) + except ValueError: + uri = None + del attrs[attr] + if uri and uri.scheme: + if uri.scheme not in self.allowed_protocols: + del attrs[attr] + if uri.scheme == 'data': + m = data_content_type.match(uri.path) + if not m: + del attrs[attr] + elif m.group('content_type') not in self.allowed_content_types: + del attrs[attr] + + for attr in self.svg_attr_val_allows_ref: + if attr in attrs: + attrs[attr] = re.sub(r'url\s*\(\s*[^#\s][^)]+?\)', + ' ', + unescape(attrs[attr])) + if (token["name"] in self.svg_allow_local_href and + (namespaces['xlink'], 'href') in attrs and re.search(r'^\s*[^#\s].*', + attrs[(namespaces['xlink'], 'href')])): + del attrs[(namespaces['xlink'], 'href')] + if (None, 'style') in attrs: + attrs[(None, 'style')] = self.sanitize_css(attrs[(None, 'style')]) + token["data"] = attrs + return token + + def disallowed_token(self, token): + token_type = token["type"] + if token_type == "EndTag": + token["data"] = "</%s>" % token["name"] + elif token["data"]: + assert token_type in ("StartTag", "EmptyTag") + attrs = [] + for (ns, name), v in token["data"].items(): + attrs.append(' %s="%s"' % (name if ns is None else "%s:%s" % (prefixes[ns], name), escape(v))) + token["data"] = "<%s%s>" % (token["name"], ''.join(attrs)) + else: + token["data"] = "<%s>" % token["name"] + if token.get("selfClosing"): + token["data"] = token["data"][:-1] + "/>" + + token["type"] = "Characters" + + del token["name"] + return token + + def sanitize_css(self, style): + # disallow urls + style = re.compile(r'url\s*\(\s*[^\s)]+?\s*\)\s*').sub(' ', style) + + # gauntlet + if not re.match(r"""^([:,;#%.\sa-zA-Z0-9!]|\w-\w|'[\s\w]+'|"[\s\w]+"|\([\d,\s]+\))*$""", style): + return '' + if not re.match(r"^\s*([-\w]+\s*:[^:;]*(;\s*|$))*$", style): + return '' + + clean = [] + for prop, value in re.findall(r"([-\w]+)\s*:\s*([^:;]*)", style): + if not value: + continue + if prop.lower() in self.allowed_css_properties: + clean.append(prop + ': ' + value + ';') + elif prop.split('-')[0].lower() in ['background', 'border', 'margin', + 'padding']: + for keyword in value.split(): + if keyword not in self.allowed_css_keywords and \ + not re.match(r"^(#[0-9a-fA-F]+|rgb\(\d+%?,\d*%?,?\d*%?\)?|\d{0,2}\.?\d{0,2}(cm|em|ex|in|mm|pc|pt|px|%|,|\))?)$", keyword): # noqa + break + else: + clean.append(prop + ': ' + value + ';') + elif prop.lower() in self.allowed_svg_properties: + clean.append(prop + ': ' + value + ';') + + return ' '.join(clean) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/whitespace.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/whitespace.py new file mode 100644 index 0000000..0d12584 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/whitespace.py @@ -0,0 +1,38 @@ +from __future__ import absolute_import, division, unicode_literals + +import re + +from . import base +from ..constants import rcdataElements, spaceCharacters +spaceCharacters = "".join(spaceCharacters) + +SPACES_REGEX = re.compile("[%s]+" % spaceCharacters) + + +class Filter(base.Filter): + """Collapses whitespace except in pre, textarea, and script elements""" + spacePreserveElements = frozenset(["pre", "textarea"] + list(rcdataElements)) + + def __iter__(self): + preserve = 0 + for token in base.Filter.__iter__(self): + type = token["type"] + if type == "StartTag" \ + and (preserve or token["name"] in self.spacePreserveElements): + preserve += 1 + + elif type == "EndTag" and preserve: + preserve -= 1 + + elif not preserve and type == "SpaceCharacters" and token["data"]: + # Test on token["data"] above to not introduce spaces where there were not + token["data"] = " " + + elif not preserve and type == "Characters": + token["data"] = collapse_spaces(token["data"]) + + yield token + + +def collapse_spaces(text): + return SPACES_REGEX.sub(' ', text) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/html5parser.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/html5parser.py new file mode 100644 index 0000000..ae41a13 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/html5parser.py @@ -0,0 +1,2791 @@ +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 + +from . import treebuilders +from .treebuilders.base import Marker + +from . import _utils +from .constants import ( + spaceCharacters, asciiUpper2Lower, + specialElements, headingElements, cdataElements, rcdataElements, + tokenTypes, tagTokenTypes, + namespaces, + htmlIntegrationPointElements, mathmlTextIntegrationPointElements, + adjustForeignAttributes as adjustForeignAttributesMap, + adjustMathMLAttributes, adjustSVGAttributes, + E, + _ReparseException +) + + +def parse(doc, treebuilder="etree", namespaceHTMLElements=True, **kwargs): + """Parse an HTML document as a string or file-like object into a tree + + :arg doc: the document to parse as a string or file-like object + + :arg treebuilder: the treebuilder to use when parsing + + :arg namespaceHTMLElements: whether or not to namespace HTML elements + + :returns: parsed tree + + Example: + + >>> from html5lib.html5parser import parse + >>> parse('<html><body><p>This is a doc</p></body></html>') + <Element u'{http://www.w3.org/1999/xhtml}html' at 0x7feac4909db0> + + """ + tb = treebuilders.getTreeBuilder(treebuilder) + p = HTMLParser(tb, namespaceHTMLElements=namespaceHTMLElements) + return p.parse(doc, **kwargs) + + +def parseFragment(doc, container="div", treebuilder="etree", namespaceHTMLElements=True, **kwargs): + """Parse an HTML fragment as a string or file-like object into a tree + + :arg doc: the fragment to parse as a string or file-like object + + :arg container: the container context to parse the fragment in + + :arg treebuilder: the treebuilder to use when parsing + + :arg namespaceHTMLElements: whether or not to namespace HTML elements + + :returns: parsed tree + + Example: + + >>> from html5lib.html5libparser import parseFragment + >>> parseFragment('<b>this is a fragment</b>') + <Element u'DOCUMENT_FRAGMENT' at 0x7feac484b090> + + """ + tb = treebuilders.getTreeBuilder(treebuilder) + p = HTMLParser(tb, namespaceHTMLElements=namespaceHTMLElements) + return p.parseFragment(doc, container=container, **kwargs) + + +def method_decorator_metaclass(function): + class Decorated(type): + def __new__(meta, classname, bases, classDict): + for attributeName, attribute in classDict.items(): + if isinstance(attribute, types.FunctionType): + attribute = function(attribute) + + classDict[attributeName] = attribute + return type.__new__(meta, classname, bases, classDict) + return Decorated + + +class HTMLParser(object): + """HTML parser + + Generates a tree structure from a stream of (possibly malformed) HTML. + + """ + + def __init__(self, tree=None, strict=False, namespaceHTMLElements=True, debug=False): + """ + :arg tree: a treebuilder class controlling the type of tree that will be + returned. Built in treebuilders can be accessed through + html5lib.treebuilders.getTreeBuilder(treeType) + + :arg strict: raise an exception when a parse error is encountered + + :arg namespaceHTMLElements: whether or not to namespace HTML elements + + :arg debug: whether or not to enable debug mode which logs things + + Example: + + >>> from html5lib.html5parser import HTMLParser + >>> parser = HTMLParser() # generates parser with etree builder + >>> parser = HTMLParser('lxml', strict=True) # generates parser with lxml builder which is strict + + """ + + # Raise an exception on the first error encountered + self.strict = strict + + if tree is None: + tree = treebuilders.getTreeBuilder("etree") + self.tree = tree(namespaceHTMLElements) + self.errors = [] + + self.phases = dict([(name, cls(self, self.tree)) for name, cls in + getPhases(debug).items()]) + + def _parse(self, stream, innerHTML=False, container="div", scripting=False, **kwargs): + + self.innerHTMLMode = innerHTML + self.container = container + self.scripting = scripting + self.tokenizer = _tokenizer.HTMLTokenizer(stream, parser=self, **kwargs) + self.reset() + + try: + self.mainLoop() + except _ReparseException: + self.reset() + self.mainLoop() + + def reset(self): + self.tree.reset() + self.firstStartTag = False + self.errors = [] + self.log = [] # only used with debug mode + # "quirks" / "limited quirks" / "no quirks" + self.compatMode = "no quirks" + + if self.innerHTMLMode: + self.innerHTML = self.container.lower() + + if self.innerHTML in cdataElements: + self.tokenizer.state = self.tokenizer.rcdataState + elif self.innerHTML in rcdataElements: + self.tokenizer.state = self.tokenizer.rawtextState + elif self.innerHTML == 'plaintext': + self.tokenizer.state = self.tokenizer.plaintextState + else: + # state already is data state + # self.tokenizer.state = self.tokenizer.dataState + pass + self.phase = self.phases["beforeHtml"] + self.phase.insertHtmlElement() + self.resetInsertionMode() + else: + self.innerHTML = False # pylint:disable=redefined-variable-type + self.phase = self.phases["initial"] + + self.lastPhase = None + + self.beforeRCDataPhase = None + + self.framesetOK = True + + @property + def documentEncoding(self): + """Name of the character encoding that was used to decode the input stream, or + :obj:`None` if that is not determined yet + + """ + if not hasattr(self, 'tokenizer'): + return None + return self.tokenizer.stream.charEncoding[0].name + + def isHTMLIntegrationPoint(self, element): + if (element.name == "annotation-xml" and + element.namespace == namespaces["mathml"]): + return ("encoding" in element.attributes and + element.attributes["encoding"].translate( + asciiUpper2Lower) in + ("text/html", "application/xhtml+xml")) + else: + return (element.namespace, element.name) in htmlIntegrationPointElements + + def isMathMLTextIntegrationPoint(self, element): + return (element.namespace, element.name) in mathmlTextIntegrationPointElements + + def mainLoop(self): + CharactersToken = tokenTypes["Characters"] + SpaceCharactersToken = tokenTypes["SpaceCharacters"] + StartTagToken = tokenTypes["StartTag"] + EndTagToken = tokenTypes["EndTag"] + CommentToken = tokenTypes["Comment"] + DoctypeToken = tokenTypes["Doctype"] + ParseErrorToken = tokenTypes["ParseError"] + + for token in self.normalizedTokens(): + prev_token = None + new_token = token + while new_token is not None: + prev_token = new_token + currentNode = self.tree.openElements[-1] if self.tree.openElements else None + currentNodeNamespace = currentNode.namespace if currentNode else None + currentNodeName = currentNode.name if currentNode else None + + type = new_token["type"] + + if type == ParseErrorToken: + self.parseError(new_token["data"], new_token.get("datavars", {})) + new_token = None + else: + if (len(self.tree.openElements) == 0 or + currentNodeNamespace == self.tree.defaultNamespace or + (self.isMathMLTextIntegrationPoint(currentNode) and + ((type == StartTagToken and + token["name"] not in frozenset(["mglyph", "malignmark"])) or + type in (CharactersToken, SpaceCharactersToken))) or + (currentNodeNamespace == namespaces["mathml"] and + currentNodeName == "annotation-xml" and + type == StartTagToken and + token["name"] == "svg") or + (self.isHTMLIntegrationPoint(currentNode) and + type in (StartTagToken, CharactersToken, SpaceCharactersToken))): + phase = self.phase + else: + phase = self.phases["inForeignContent"] + + if type == CharactersToken: + new_token = phase.processCharacters(new_token) + elif type == SpaceCharactersToken: + new_token = phase.processSpaceCharacters(new_token) + elif type == StartTagToken: + new_token = phase.processStartTag(new_token) + elif type == EndTagToken: + new_token = phase.processEndTag(new_token) + elif type == CommentToken: + new_token = phase.processComment(new_token) + elif type == DoctypeToken: + new_token = phase.processDoctype(new_token) + + if (type == StartTagToken and prev_token["selfClosing"] and + not prev_token["selfClosingAcknowledged"]): + self.parseError("non-void-element-with-trailing-solidus", + {"name": prev_token["name"]}) + + # When the loop finishes it's EOF + reprocess = True + phases = [] + while reprocess: + phases.append(self.phase) + reprocess = self.phase.processEOF() + if reprocess: + assert self.phase not in phases + + def 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 + + :arg stream: a file-like object or string containing the HTML to be parsed + + The optional encoding parameter must be a string that indicates + the encoding. If specified, that encoding will be used, + regardless of any BOM or later declaration (such as in a meta + element). + + :arg scripting: treat noscript elements as if JavaScript was turned on + + :returns: parsed tree + + Example: + + >>> from html5lib.html5parser import HTMLParser + >>> parser = HTMLParser() + >>> parser.parse('<html><body><p>This is a doc</p></body></html>') + <Element u'{http://www.w3.org/1999/xhtml}html' at 0x7feac4909db0> + + """ + self._parse(stream, False, None, *args, **kwargs) + return self.tree.getDocument() + + def parseFragment(self, stream, *args, **kwargs): + """Parse a HTML fragment into a well-formed tree fragment + + :arg container: name of the element we're setting the innerHTML + property if set to None, default to 'div' + + :arg stream: a file-like object or string containing the HTML to be parsed + + The optional encoding parameter must be a string that indicates + the encoding. If specified, that encoding will be used, + regardless of any BOM or later declaration (such as in a meta + element) + + :arg scripting: treat noscript elements as if JavaScript was turned on + + :returns: parsed tree + + Example: + + >>> from html5lib.html5libparser import HTMLParser + >>> parser = HTMLParser() + >>> parser.parseFragment('<b>this is a fragment</b>') + <Element u'DOCUMENT_FRAGMENT' at 0x7feac484b090> + + """ + self._parse(stream, True, *args, **kwargs) + return self.tree.getFragment() + + def parseError(self, errorcode="XXX-undefined-error", datavars=None): + # XXX The idea is to make errorcode mandatory. + if datavars is None: + datavars = {} + self.errors.append((self.tokenizer.stream.position(), errorcode, datavars)) + if self.strict: + raise ParseError(E[errorcode] % datavars) + + def 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) + + def adjustSVGAttributes(self, token): + adjust_attributes(token, adjustSVGAttributes) + + def adjustForeignAttributes(self, token): + adjust_attributes(token, adjustForeignAttributesMap) + + def reparseTokenNormal(self, token): + # pylint:disable=unused-argument + self.parser.phase() + + def resetInsertionMode(self): + # The name of this method is mostly historical. (It's also used in the + # specification.) + last = False + newModes = { + "select": "inSelect", + "td": "inCell", + "th": "inCell", + "tr": "inRow", + "tbody": "inTableBody", + "thead": "inTableBody", + "tfoot": "inTableBody", + "caption": "inCaption", + "colgroup": "inColumnGroup", + "table": "inTable", + "head": "inBody", + "body": "inBody", + "frameset": "inFrameset", + "html": "beforeHead" + } + for node in self.tree.openElements[::-1]: + nodeName = node.name + new_phase = None + if node == self.tree.openElements[0]: + assert self.innerHTML + last = True + nodeName = self.innerHTML + # Check for conditions that should only happen in the innerHTML + # case + if nodeName in ("select", "colgroup", "head", "html"): + assert self.innerHTML + + if not last and node.namespace != self.tree.defaultNamespace: + continue + + if nodeName in newModes: + new_phase = self.phases[newModes[nodeName]] + break + elif last: + new_phase = self.phases["inBody"] + break + + self.phase = new_phase + + def parseRCDataRawtext(self, token, contentType): + # Generic RCDATA/RAWTEXT Parsing algorithm + assert contentType in ("RAWTEXT", "RCDATA") + + self.tree.insertElement(token) + + if contentType == "RAWTEXT": + self.tokenizer.state = self.tokenizer.rawtextState + else: + self.tokenizer.state = self.tokenizer.rcdataState + + self.originalPhase = self.phase + + self.phase = self.phases["text"] + + +@_utils.memoize +def getPhases(debug): + def log(function): + """Logger that records which phase processes each token""" + type_names = dict((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 + if token['type'] in tagTokenTypes: + info["name"] = token['name'] + + self.parser.log.append((self.parser.tokenizer.state.__name__, + self.parser.phase.__class__.__name__, + self.__class__.__name__, + function.__name__, + info)) + return function(self, *args, **kwargs) + else: + return function(self, *args, **kwargs) + return wrapped + + def getMetaclass(use_metaclass, metaclass_func): + if use_metaclass: + return method_decorator_metaclass(metaclass_func) + else: + return type + + # pylint:disable=unused-argument + class Phase(with_metaclass(getMetaclass(debug, log))): + """Base class for helper object that implements each phase of processing + """ + + def __init__(self, parser, tree): + self.parser = parser + self.tree = tree + + def processEOF(self): + raise NotImplementedError + + def processComment(self, token): + # For most phases the following is correct. Where it's not it will be + # overridden. + self.tree.insertComment(token, self.tree.openElements[-1]) + + def processDoctype(self, token): + self.parser.parseError("unexpected-doctype") + + def processCharacters(self, token): + self.tree.insertText(token["data"]) + + def processSpaceCharacters(self, token): + self.tree.insertText(token["data"]) + + def processStartTag(self, token): + return self.startTagHandler[token["name"]](token) + + def startTagHtml(self, token): + if not self.parser.firstStartTag and token["name"] == "html": + self.parser.parseError("non-html-root") + # XXX Need a check here to see if the first start tag token emitted is + # this token... If it's not, invoke self.parser.parseError(). + for attr, value in token["data"].items(): + if attr not in self.tree.openElements[0].attributes: + self.tree.openElements[0].attributes[attr] = value + self.parser.firstStartTag = False + + def processEndTag(self, token): + return self.endTagHandler[token["name"]](token) + + class InitialPhase(Phase): + def processSpaceCharacters(self, token): + pass + + def processComment(self, token): + self.tree.insertComment(token, self.tree.document) + + def processDoctype(self, token): + name = token["name"] + publicId = token["publicId"] + systemId = token["systemId"] + correct = token["correct"] + + if (name != "html" or publicId is not None or + systemId is not None and systemId != "about:legacy-compat"): + self.parser.parseError("unknown-doctype") + + if publicId is None: + publicId = "" + + self.tree.insertDoctype(token) + + if publicId != "": + publicId = publicId.translate(asciiUpper2Lower) + + if (not correct or token["name"] != "html" or + publicId.startswith( + ("+//silmaril//dtd html pro v0r11 19970101//", + "-//advasoft ltd//dtd html 3.0 aswedit + extensions//", + "-//as//dtd html 3.0 aswedit + extensions//", + "-//ietf//dtd html 2.0 level 1//", + "-//ietf//dtd html 2.0 level 2//", + "-//ietf//dtd html 2.0 strict level 1//", + "-//ietf//dtd html 2.0 strict level 2//", + "-//ietf//dtd html 2.0 strict//", + "-//ietf//dtd html 2.0//", + "-//ietf//dtd html 2.1e//", + "-//ietf//dtd html 3.0//", + "-//ietf//dtd html 3.2 final//", + "-//ietf//dtd html 3.2//", + "-//ietf//dtd html 3//", + "-//ietf//dtd html level 0//", + "-//ietf//dtd html level 1//", + "-//ietf//dtd html level 2//", + "-//ietf//dtd html level 3//", + "-//ietf//dtd html strict level 0//", + "-//ietf//dtd html strict level 1//", + "-//ietf//dtd html strict level 2//", + "-//ietf//dtd html strict level 3//", + "-//ietf//dtd html strict//", + "-//ietf//dtd html//", + "-//metrius//dtd metrius presentational//", + "-//microsoft//dtd internet explorer 2.0 html strict//", + "-//microsoft//dtd internet explorer 2.0 html//", + "-//microsoft//dtd internet explorer 2.0 tables//", + "-//microsoft//dtd internet explorer 3.0 html strict//", + "-//microsoft//dtd internet explorer 3.0 html//", + "-//microsoft//dtd internet explorer 3.0 tables//", + "-//netscape comm. corp.//dtd html//", + "-//netscape comm. corp.//dtd strict html//", + "-//o'reilly and associates//dtd html 2.0//", + "-//o'reilly and associates//dtd html extended 1.0//", + "-//o'reilly and associates//dtd html extended relaxed 1.0//", + "-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//", + "-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//", + "-//spyglass//dtd html 2.0 extended//", + "-//sq//dtd html 2.0 hotmetal + extensions//", + "-//sun microsystems corp.//dtd hotjava html//", + "-//sun microsystems corp.//dtd hotjava strict html//", + "-//w3c//dtd html 3 1995-03-24//", + "-//w3c//dtd html 3.2 draft//", + "-//w3c//dtd html 3.2 final//", + "-//w3c//dtd html 3.2//", + "-//w3c//dtd html 3.2s draft//", + "-//w3c//dtd html 4.0 frameset//", + "-//w3c//dtd html 4.0 transitional//", + "-//w3c//dtd html experimental 19960712//", + "-//w3c//dtd html experimental 970421//", + "-//w3c//dtd w3 html//", + "-//w3o//dtd w3 html 3.0//", + "-//webtechs//dtd mozilla html 2.0//", + "-//webtechs//dtd mozilla html//")) or + publicId in ("-//w3o//dtd w3 html strict 3.0//en//", + "-/w3c/dtd html 4.0 transitional/en", + "html") or + publicId.startswith( + ("-//w3c//dtd html 4.01 frameset//", + "-//w3c//dtd html 4.01 transitional//")) and + systemId is None or + systemId and systemId.lower() == "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd"): + self.parser.compatMode = "quirks" + elif (publicId.startswith( + ("-//w3c//dtd xhtml 1.0 frameset//", + "-//w3c//dtd xhtml 1.0 transitional//")) or + publicId.startswith( + ("-//w3c//dtd html 4.01 frameset//", + "-//w3c//dtd html 4.01 transitional//")) and + systemId is not None): + self.parser.compatMode = "limited quirks" + + self.parser.phase = self.parser.phases["beforeHtml"] + + def anythingElse(self): + self.parser.compatMode = "quirks" + self.parser.phase = self.parser.phases["beforeHtml"] + + def processCharacters(self, token): + self.parser.parseError("expected-doctype-but-got-chars") + self.anythingElse() + return token + + def processStartTag(self, token): + self.parser.parseError("expected-doctype-but-got-start-tag", + {"name": token["name"]}) + self.anythingElse() + return token + + def processEndTag(self, token): + self.parser.parseError("expected-doctype-but-got-end-tag", + {"name": token["name"]}) + self.anythingElse() + return token + + def processEOF(self): + self.parser.parseError("expected-doctype-but-got-eof") + self.anythingElse() + return True + + class BeforeHtmlPhase(Phase): + # helper methods + def insertHtmlElement(self): + self.tree.insertRoot(impliedTagToken("html", "StartTag")) + self.parser.phase = self.parser.phases["beforeHead"] + + # other + def processEOF(self): + self.insertHtmlElement() + return True + + def processComment(self, token): + self.tree.insertComment(token, self.tree.document) + + def processSpaceCharacters(self, token): + pass + + def processCharacters(self, token): + self.insertHtmlElement() + return token + + def processStartTag(self, token): + if token["name"] == "html": + self.parser.firstStartTag = True + self.insertHtmlElement() + return token + + def processEndTag(self, token): + if token["name"] not in ("head", "body", "html", "br"): + self.parser.parseError("unexpected-end-tag-before-html", + {"name": token["name"]}) + else: + self.insertHtmlElement() + return token + + class BeforeHeadPhase(Phase): + 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 + + def processEOF(self): + self.startTagHead(impliedTagToken("head", "StartTag")) + return True + + def processSpaceCharacters(self, token): + pass + + def processCharacters(self, token): + self.startTagHead(impliedTagToken("head", "StartTag")) + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagHead(self, token): + self.tree.insertElement(token) + self.tree.headPointer = self.tree.openElements[-1] + self.parser.phase = self.parser.phases["inHead"] + + def startTagOther(self, token): + self.startTagHead(impliedTagToken("head", "StartTag")) + return token + + def endTagImplyHead(self, token): + self.startTagHead(impliedTagToken("head", "StartTag")) + return token + + def endTagOther(self, token): + self.parser.parseError("end-tag-after-implied-root", + {"name": token["name"]}) + + 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 + + # the real thing + def processEOF(self): + self.anythingElse() + return True + + def processCharacters(self, token): + self.anythingElse() + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagHead(self, token): + self.parser.parseError("two-heads-are-not-better-than-one") + + def startTagBaseLinkCommand(self, token): + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def startTagMeta(self, token): + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + attributes = token["data"] + if self.parser.tokenizer.stream.charEncoding[1] == "tentative": + if "charset" in attributes: + self.parser.tokenizer.stream.changeEncoding(attributes["charset"]) + elif ("content" in attributes and + "http-equiv" in attributes and + attributes["http-equiv"].lower() == "content-type"): + # Encoding it as UTF-8 here is a hack, as really we should pass + # the abstract Unicode string, and just use the + # ContentAttrParser on that, but using UTF-8 allows all chars + # to be encoded and as a ASCII-superset works. + data = _inputstream.EncodingBytes(attributes["content"].encode("utf-8")) + parser = _inputstream.ContentAttrParser(data) + codec = parser.parse() + self.parser.tokenizer.stream.changeEncoding(codec) + + def startTagTitle(self, token): + self.parser.parseRCDataRawtext(token, "RCDATA") + + def startTagNoFramesStyle(self, token): + # Need to decide whether to implement the scripting-disabled case + self.parser.parseRCDataRawtext(token, "RAWTEXT") + + def startTagNoscript(self, token): + if self.parser.scripting: + self.parser.parseRCDataRawtext(token, "RAWTEXT") + else: + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inHeadNoscript"] + + def startTagScript(self, token): + self.tree.insertElement(token) + self.parser.tokenizer.state = self.parser.tokenizer.scriptDataState + self.parser.originalPhase = self.parser.phase + self.parser.phase = self.parser.phases["text"] + + def startTagOther(self, token): + self.anythingElse() + return token + + def endTagHead(self, token): + node = self.parser.tree.openElements.pop() + assert node.name == "head", "Expected head got %s" % node.name + self.parser.phase = self.parser.phases["afterHead"] + + def endTagHtmlBodyBr(self, token): + self.anythingElse() + return token + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def anythingElse(self): + self.endTagHead(impliedTagToken("head")) + + 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 + + def processEOF(self): + self.parser.parseError("eof-in-head-noscript") + self.anythingElse() + return True + + def processComment(self, token): + return self.parser.phases["inHead"].processComment(token) + + def processCharacters(self, token): + self.parser.parseError("char-in-head-noscript") + self.anythingElse() + return token + + def processSpaceCharacters(self, token): + return self.parser.phases["inHead"].processSpaceCharacters(token) + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagBaseLinkCommand(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagHeadNoscript(self, token): + self.parser.parseError("unexpected-start-tag", {"name": token["name"]}) + + def startTagOther(self, token): + self.parser.parseError("unexpected-inhead-noscript-tag", {"name": token["name"]}) + self.anythingElse() + return token + + def endTagNoscript(self, token): + node = self.parser.tree.openElements.pop() + assert node.name == "noscript", "Expected noscript got %s" % node.name + self.parser.phase = self.parser.phases["inHead"] + + def endTagBr(self, token): + self.parser.parseError("unexpected-inhead-noscript-tag", {"name": token["name"]}) + self.anythingElse() + return token + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def anythingElse(self): + # Caller must raise parse error first! + self.endTagNoscript(impliedTagToken("noscript")) + + class AfterHeadPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + 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 + + def processEOF(self): + self.anythingElse() + return True + + def processCharacters(self, token): + self.anythingElse() + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagBody(self, token): + self.parser.framesetOK = False + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inBody"] + + def startTagFrameset(self, token): + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inFrameset"] + + def startTagFromHead(self, token): + self.parser.parseError("unexpected-start-tag-out-of-my-head", + {"name": token["name"]}) + self.tree.openElements.append(self.tree.headPointer) + self.parser.phases["inHead"].processStartTag(token) + for node in self.tree.openElements[::-1]: + if node.name == "head": + self.tree.openElements.remove(node) + break + + def startTagHead(self, token): + self.parser.parseError("unexpected-start-tag", {"name": token["name"]}) + + def startTagOther(self, token): + self.anythingElse() + return token + + def endTagHtmlBodyBr(self, token): + self.anythingElse() + return token + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def anythingElse(self): + self.tree.insertElement(impliedTagToken("body", "StartTag")) + self.parser.phase = self.parser.phases["inBody"] + self.parser.framesetOK = True + + 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) + + # 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 + node1.attributes == node2.attributes) + + # helper + def addFormattingElement(self, token): + self.tree.insertElement(token) + element = self.tree.openElements[-1] + + matchingElements = [] + for node in self.tree.activeFormattingElements[::-1]: + if node is Marker: + break + elif self.isMatchingFormattingElement(node, element): + matchingElements.append(node) + + assert len(matchingElements) <= 3 + if len(matchingElements) == 3: + self.tree.activeFormattingElements.remove(matchingElements[-1]) + self.tree.activeFormattingElements.append(element) + + # the real deal + def processEOF(self): + allowed_elements = frozenset(("dd", "dt", "li", "p", "tbody", "td", + "tfoot", "th", "thead", "tr", "body", + "html")) + for node in self.tree.openElements[::-1]: + if node.name not in allowed_elements: + self.parser.parseError("expected-closing-tag-but-got-eof") + break + # Stop parsing + + def processSpaceCharactersDropNewline(self, token): + # Sometimes (start of <pre>, <listing>, and <textarea> blocks) we + # want to drop leading newlines + data = token["data"] + self.processSpaceCharacters = self.processSpaceCharactersNonPre + if (data.startswith("\n") and + self.tree.openElements[-1].name in ("pre", "listing", "textarea") and + not self.tree.openElements[-1].hasContent()): + data = data[1:] + if data: + self.tree.reconstructActiveFormattingElements() + self.tree.insertText(data) + + def processCharacters(self, token): + if token["data"] == "\u0000": + # The tokenizer should always emit null on its own + return + self.tree.reconstructActiveFormattingElements() + self.tree.insertText(token["data"]) + # This must be bad for performance + if (self.parser.framesetOK and + any([char not in spaceCharacters + for char in token["data"]])): + self.parser.framesetOK = False + + def processSpaceCharactersNonPre(self, token): + self.tree.reconstructActiveFormattingElements() + self.tree.insertText(token["data"]) + + def startTagProcessInHead(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagBody(self, token): + self.parser.parseError("unexpected-start-tag", {"name": "body"}) + if (len(self.tree.openElements) == 1 or + self.tree.openElements[1].name != "body"): + assert self.parser.innerHTML + else: + self.parser.framesetOK = False + for attr, value in token["data"].items(): + if attr not in self.tree.openElements[1].attributes: + self.tree.openElements[1].attributes[attr] = value + + def startTagFrameset(self, token): + self.parser.parseError("unexpected-start-tag", {"name": "frameset"}) + if (len(self.tree.openElements) == 1 or self.tree.openElements[1].name != "body"): + assert self.parser.innerHTML + elif not self.parser.framesetOK: + pass + else: + if self.tree.openElements[1].parent: + self.tree.openElements[1].parent.removeChild(self.tree.openElements[1]) + while self.tree.openElements[-1].name != "html": + self.tree.openElements.pop() + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inFrameset"] + + def startTagCloseP(self, token): + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + self.tree.insertElement(token) + + def startTagPreListing(self, token): + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + self.tree.insertElement(token) + self.parser.framesetOK = False + self.processSpaceCharacters = self.processSpaceCharactersDropNewline + + def startTagForm(self, token): + if self.tree.formPointer: + self.parser.parseError("unexpected-start-tag", {"name": "form"}) + else: + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + self.tree.insertElement(token) + self.tree.formPointer = self.tree.openElements[-1] + + def startTagListItem(self, token): + self.parser.framesetOK = False + + stopNamesMap = {"li": ["li"], + "dt": ["dt", "dd"], + "dd": ["dt", "dd"]} + stopNames = stopNamesMap[token["name"]] + for node in reversed(self.tree.openElements): + if node.name in stopNames: + self.parser.phase.processEndTag( + impliedTagToken(node.name, "EndTag")) + break + if (node.nameTuple in specialElements and + node.name not in ("address", "div", "p")): + break + + if self.tree.elementInScope("p", variant="button"): + self.parser.phase.processEndTag( + impliedTagToken("p", "EndTag")) + + self.tree.insertElement(token) + + def startTagPlaintext(self, token): + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + self.tree.insertElement(token) + self.parser.tokenizer.state = self.parser.tokenizer.plaintextState + + def startTagHeading(self, token): + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + if self.tree.openElements[-1].name in headingElements: + self.parser.parseError("unexpected-start-tag", {"name": token["name"]}) + self.tree.openElements.pop() + self.tree.insertElement(token) + + def startTagA(self, token): + afeAElement = self.tree.elementInActiveFormattingElements("a") + if afeAElement: + self.parser.parseError("unexpected-start-tag-implies-end-tag", + {"startName": "a", "endName": "a"}) + self.endTagFormatting(impliedTagToken("a")) + if afeAElement in self.tree.openElements: + self.tree.openElements.remove(afeAElement) + if afeAElement in self.tree.activeFormattingElements: + self.tree.activeFormattingElements.remove(afeAElement) + self.tree.reconstructActiveFormattingElements() + self.addFormattingElement(token) + + def startTagFormatting(self, token): + self.tree.reconstructActiveFormattingElements() + self.addFormattingElement(token) + + def startTagNobr(self, token): + self.tree.reconstructActiveFormattingElements() + if self.tree.elementInScope("nobr"): + self.parser.parseError("unexpected-start-tag-implies-end-tag", + {"startName": "nobr", "endName": "nobr"}) + self.processEndTag(impliedTagToken("nobr")) + # XXX Need tests that trigger the following + self.tree.reconstructActiveFormattingElements() + self.addFormattingElement(token) + + def startTagButton(self, token): + if self.tree.elementInScope("button"): + self.parser.parseError("unexpected-start-tag-implies-end-tag", + {"startName": "button", "endName": "button"}) + self.processEndTag(impliedTagToken("button")) + return token + else: + self.tree.reconstructActiveFormattingElements() + self.tree.insertElement(token) + self.parser.framesetOK = False + + def startTagAppletMarqueeObject(self, token): + self.tree.reconstructActiveFormattingElements() + self.tree.insertElement(token) + self.tree.activeFormattingElements.append(Marker) + self.parser.framesetOK = False + + def startTagXmp(self, token): + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + self.tree.reconstructActiveFormattingElements() + self.parser.framesetOK = False + self.parser.parseRCDataRawtext(token, "RAWTEXT") + + def startTagTable(self, token): + if self.parser.compatMode != "quirks": + if self.tree.elementInScope("p", variant="button"): + self.processEndTag(impliedTagToken("p")) + self.tree.insertElement(token) + self.parser.framesetOK = False + self.parser.phase = self.parser.phases["inTable"] + + def startTagVoidFormatting(self, token): + self.tree.reconstructActiveFormattingElements() + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + self.parser.framesetOK = False + + def startTagInput(self, token): + framesetOK = self.parser.framesetOK + self.startTagVoidFormatting(token) + if ("type" in token["data"] and + token["data"]["type"].translate(asciiUpper2Lower) == "hidden"): + # input type=hidden doesn't change framesetOK + self.parser.framesetOK = framesetOK + + def startTagParamSource(self, token): + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def startTagHr(self, token): + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + self.parser.framesetOK = False + + def startTagImage(self, token): + # No really... + self.parser.parseError("unexpected-start-tag-treated-as", + {"originalName": "image", "newName": "img"}) + self.processStartTag(impliedTagToken("img", "StartTag", + attributes=token["data"], + selfClosing=token["selfClosing"])) + + def startTagIsIndex(self, token): + self.parser.parseError("deprecated-tag", {"name": "isindex"}) + if self.tree.formPointer: + return + form_attrs = {} + if "action" in token["data"]: + form_attrs["action"] = token["data"]["action"] + self.processStartTag(impliedTagToken("form", "StartTag", + attributes=form_attrs)) + self.processStartTag(impliedTagToken("hr", "StartTag")) + self.processStartTag(impliedTagToken("label", "StartTag")) + # XXX Localization ... + if "prompt" in token["data"]: + prompt = token["data"]["prompt"] + else: + prompt = "This is a searchable index. Enter search keywords: " + self.processCharacters( + {"type": tokenTypes["Characters"], "data": prompt}) + attributes = token["data"].copy() + if "action" in attributes: + del attributes["action"] + if "prompt" in attributes: + del attributes["prompt"] + attributes["name"] = "isindex" + self.processStartTag(impliedTagToken("input", "StartTag", + attributes=attributes, + selfClosing=token["selfClosing"])) + self.processEndTag(impliedTagToken("label")) + self.processStartTag(impliedTagToken("hr", "StartTag")) + self.processEndTag(impliedTagToken("form")) + + def startTagTextarea(self, token): + self.tree.insertElement(token) + self.parser.tokenizer.state = self.parser.tokenizer.rcdataState + self.processSpaceCharacters = self.processSpaceCharactersDropNewline + self.parser.framesetOK = False + + def startTagIFrame(self, token): + self.parser.framesetOK = False + self.startTagRawtext(token) + + def startTagNoscript(self, token): + if self.parser.scripting: + self.startTagRawtext(token) + else: + self.startTagOther(token) + + def startTagRawtext(self, token): + """iframe, noembed noframes, noscript(if scripting enabled)""" + self.parser.parseRCDataRawtext(token, "RAWTEXT") + + def startTagOpt(self, token): + if self.tree.openElements[-1].name == "option": + self.parser.phase.processEndTag(impliedTagToken("option")) + self.tree.reconstructActiveFormattingElements() + self.parser.tree.insertElement(token) + + def startTagSelect(self, token): + self.tree.reconstructActiveFormattingElements() + self.tree.insertElement(token) + self.parser.framesetOK = False + if self.parser.phase in (self.parser.phases["inTable"], + self.parser.phases["inCaption"], + self.parser.phases["inColumnGroup"], + self.parser.phases["inTableBody"], + self.parser.phases["inRow"], + self.parser.phases["inCell"]): + self.parser.phase = self.parser.phases["inSelectInTable"] + else: + self.parser.phase = self.parser.phases["inSelect"] + + def startTagRpRt(self, token): + if self.tree.elementInScope("ruby"): + self.tree.generateImpliedEndTags() + if self.tree.openElements[-1].name != "ruby": + self.parser.parseError() + self.tree.insertElement(token) + + def startTagMath(self, token): + self.tree.reconstructActiveFormattingElements() + self.parser.adjustMathMLAttributes(token) + self.parser.adjustForeignAttributes(token) + token["namespace"] = namespaces["mathml"] + self.tree.insertElement(token) + # Need to get the parse error right for the case where the token + # has a namespace not equal to the xmlns attribute + if token["selfClosing"]: + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def startTagSvg(self, token): + self.tree.reconstructActiveFormattingElements() + self.parser.adjustSVGAttributes(token) + self.parser.adjustForeignAttributes(token) + token["namespace"] = namespaces["svg"] + self.tree.insertElement(token) + # Need to get the parse error right for the case where the token + # has a namespace not equal to the xmlns attribute + if token["selfClosing"]: + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def startTagMisplaced(self, token): + """ Elements that should be children of other elements that have a + different insertion mode; here they are ignored + "caption", "col", "colgroup", "frame", "frameset", "head", + "option", "optgroup", "tbody", "td", "tfoot", "th", "thead", + "tr", "noscript" + """ + self.parser.parseError("unexpected-start-tag-ignored", {"name": token["name"]}) + + def startTagOther(self, token): + self.tree.reconstructActiveFormattingElements() + self.tree.insertElement(token) + + def endTagP(self, token): + if not self.tree.elementInScope("p", variant="button"): + self.startTagCloseP(impliedTagToken("p", "StartTag")) + self.parser.parseError("unexpected-end-tag", {"name": "p"}) + self.endTagP(impliedTagToken("p", "EndTag")) + else: + self.tree.generateImpliedEndTags("p") + if self.tree.openElements[-1].name != "p": + self.parser.parseError("unexpected-end-tag", {"name": "p"}) + node = self.tree.openElements.pop() + while node.name != "p": + node = self.tree.openElements.pop() + + def endTagBody(self, token): + if not self.tree.elementInScope("body"): + self.parser.parseError() + return + elif self.tree.openElements[-1].name != "body": + for node in self.tree.openElements[2:]: + if node.name not in frozenset(("dd", "dt", "li", "optgroup", + "option", "p", "rp", "rt", + "tbody", "td", "tfoot", + "th", "thead", "tr", "body", + "html")): + # Not sure this is the correct name for the parse error + self.parser.parseError( + "expected-one-end-tag-but-got-another", + {"gotName": "body", "expectedName": node.name}) + break + self.parser.phase = self.parser.phases["afterBody"] + + def endTagHtml(self, token): + # We repeat the test for the body end tag token being ignored here + if self.tree.elementInScope("body"): + self.endTagBody(impliedTagToken("body")) + return token + + def endTagBlock(self, token): + # Put us back in the right whitespace handling mode + if token["name"] == "pre": + self.processSpaceCharacters = self.processSpaceCharactersNonPre + inScope = self.tree.elementInScope(token["name"]) + if inScope: + self.tree.generateImpliedEndTags() + if self.tree.openElements[-1].name != token["name"]: + self.parser.parseError("end-tag-too-early", {"name": token["name"]}) + if inScope: + node = self.tree.openElements.pop() + while node.name != token["name"]: + node = self.tree.openElements.pop() + + def endTagForm(self, token): + node = self.tree.formPointer + self.tree.formPointer = None + if node is None or not self.tree.elementInScope(node): + self.parser.parseError("unexpected-end-tag", + {"name": "form"}) + else: + self.tree.generateImpliedEndTags() + if self.tree.openElements[-1] != node: + self.parser.parseError("end-tag-too-early-ignored", + {"name": "form"}) + self.tree.openElements.remove(node) + + def endTagListItem(self, token): + if token["name"] == "li": + variant = "list" + else: + variant = None + if not self.tree.elementInScope(token["name"], variant=variant): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + else: + self.tree.generateImpliedEndTags(exclude=token["name"]) + if self.tree.openElements[-1].name != token["name"]: + self.parser.parseError( + "end-tag-too-early", + {"name": token["name"]}) + node = self.tree.openElements.pop() + while node.name != token["name"]: + node = self.tree.openElements.pop() + + def endTagHeading(self, token): + for item in headingElements: + if self.tree.elementInScope(item): + self.tree.generateImpliedEndTags() + break + if self.tree.openElements[-1].name != token["name"]: + self.parser.parseError("end-tag-too-early", {"name": token["name"]}) + + for item in headingElements: + if self.tree.elementInScope(item): + item = self.tree.openElements.pop() + while item.name not in headingElements: + item = self.tree.openElements.pop() + break + + def endTagFormatting(self, token): + """The much-feared adoption agency algorithm""" + # http://svn.whatwg.org/webapps/complete.html#adoptionAgency revision 7867 + # XXX Better parseError messages appreciated. + + # Step 1 + outerLoopCounter = 0 + + # Step 2 + while outerLoopCounter < 8: + + # Step 3 + outerLoopCounter += 1 + + # Step 4: + + # Let the formatting element be the last element in + # the list of active formatting elements that: + # - is between the end of the list and the last scope + # marker in the list, if any, or the start of the list + # otherwise, and + # - has the same tag name as the token. + formattingElement = self.tree.elementInActiveFormattingElements( + token["name"]) + if (not formattingElement or + (formattingElement in self.tree.openElements and + not self.tree.elementInScope(formattingElement.name))): + # If there is no such node, then abort these steps + # and instead act as described in the "any other + # end tag" entry below. + self.endTagOther(token) + return + + # Otherwise, if there is such a node, but that node is + # not in the stack of open elements, then this is a + # parse error; remove the element from the list, and + # abort these steps. + elif formattingElement not in self.tree.openElements: + self.parser.parseError("adoption-agency-1.2", {"name": token["name"]}) + self.tree.activeFormattingElements.remove(formattingElement) + return + + # Otherwise, if there is such a node, and that node is + # also in the stack of open elements, but the element + # is not in scope, then this is a parse error; ignore + # the token, and abort these steps. + elif not self.tree.elementInScope(formattingElement.name): + self.parser.parseError("adoption-agency-4.4", {"name": token["name"]}) + return + + # Otherwise, there is a formatting element and that + # element is in the stack and is in scope. If the + # element is not the current node, this is a parse + # error. In any case, proceed with the algorithm as + # written in the following steps. + else: + if formattingElement != self.tree.openElements[-1]: + self.parser.parseError("adoption-agency-1.3", {"name": token["name"]}) + + # Step 5: + + # Let the furthest block be the topmost node in the + # stack of open elements that is lower in the stack + # than the formatting element, and is an element in + # the special category. There might not be one. + afeIndex = self.tree.openElements.index(formattingElement) + furthestBlock = None + for element in self.tree.openElements[afeIndex:]: + if element.nameTuple in specialElements: + furthestBlock = element + break + + # Step 6: + + # If there is no furthest block, then the UA must + # first pop all the nodes from the bottom of the stack + # of open elements, from the current node up to and + # including the formatting element, then remove the + # formatting element from the list of active + # formatting elements, and finally abort these steps. + if furthestBlock is None: + element = self.tree.openElements.pop() + while element != formattingElement: + element = self.tree.openElements.pop() + self.tree.activeFormattingElements.remove(element) + return + + # Step 7 + commonAncestor = self.tree.openElements[afeIndex - 1] + + # Step 8: + # The bookmark is supposed to help us identify where to reinsert + # nodes in step 15. We have to ensure that we reinsert nodes after + # the node before the active formatting element. Note the bookmark + # can move in step 9.7 + bookmark = self.tree.activeFormattingElements.index(formattingElement) + + # Step 9 + lastNode = node = furthestBlock + innerLoopCounter = 0 + + index = self.tree.openElements.index(node) + while innerLoopCounter < 3: + innerLoopCounter += 1 + # Node is element before node in open elements + index -= 1 + node = self.tree.openElements[index] + if node not in self.tree.activeFormattingElements: + self.tree.openElements.remove(node) + continue + # Step 9.6 + if node == formattingElement: + break + # Step 9.7 + if lastNode == furthestBlock: + bookmark = self.tree.activeFormattingElements.index(node) + 1 + # Step 9.8 + clone = node.cloneNode() + # Replace node with clone + self.tree.activeFormattingElements[ + self.tree.activeFormattingElements.index(node)] = clone + self.tree.openElements[ + self.tree.openElements.index(node)] = clone + node = clone + # Step 9.9 + # Remove lastNode from its parents, if any + if lastNode.parent: + lastNode.parent.removeChild(lastNode) + node.appendChild(lastNode) + # Step 9.10 + lastNode = node + + # Step 10 + # Foster parent lastNode if commonAncestor is a + # table, tbody, tfoot, thead, or tr we need to foster + # parent the lastNode + if lastNode.parent: + lastNode.parent.removeChild(lastNode) + + if commonAncestor.name in frozenset(("table", "tbody", "tfoot", "thead", "tr")): + parent, insertBefore = self.tree.getTableMisnestedNodePosition() + parent.insertBefore(lastNode, insertBefore) + else: + commonAncestor.appendChild(lastNode) + + # Step 11 + clone = formattingElement.cloneNode() + + # Step 12 + furthestBlock.reparentChildren(clone) + + # Step 13 + furthestBlock.appendChild(clone) + + # Step 14 + self.tree.activeFormattingElements.remove(formattingElement) + self.tree.activeFormattingElements.insert(bookmark, clone) + + # Step 15 + self.tree.openElements.remove(formattingElement) + self.tree.openElements.insert( + self.tree.openElements.index(furthestBlock) + 1, clone) + + def endTagAppletMarqueeObject(self, token): + if self.tree.elementInScope(token["name"]): + self.tree.generateImpliedEndTags() + if self.tree.openElements[-1].name != token["name"]: + self.parser.parseError("end-tag-too-early", {"name": token["name"]}) + + if self.tree.elementInScope(token["name"]): + element = self.tree.openElements.pop() + while element.name != token["name"]: + element = self.tree.openElements.pop() + self.tree.clearActiveFormattingElements() + + def endTagBr(self, token): + self.parser.parseError("unexpected-end-tag-treated-as", + {"originalName": "br", "newName": "br element"}) + self.tree.reconstructActiveFormattingElements() + self.tree.insertElement(impliedTagToken("br", "StartTag")) + self.tree.openElements.pop() + + def endTagOther(self, token): + for node in self.tree.openElements[::-1]: + if node.name == token["name"]: + self.tree.generateImpliedEndTags(exclude=token["name"]) + if self.tree.openElements[-1].name != token["name"]: + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + while self.tree.openElements.pop() != node: + pass + break + else: + if node.nameTuple in specialElements: + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + break + + 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 + + def processCharacters(self, token): + self.tree.insertText(token["data"]) + + def processEOF(self): + self.parser.parseError("expected-named-closing-tag-but-got-eof", + {"name": self.tree.openElements[-1].name}) + self.tree.openElements.pop() + self.parser.phase = self.parser.originalPhase + return True + + def startTagOther(self, token): + assert False, "Tried to process start tag %s in RCDATA/RAWTEXT mode" % token['name'] + + def endTagScript(self, token): + node = self.tree.openElements.pop() + assert node.name == "script" + self.parser.phase = self.parser.originalPhase + # The rest of this method is all stuff that only happens if + # document.write works + + def endTagOther(self, token): + self.tree.openElements.pop() + self.parser.phase = self.parser.originalPhase + + 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 + + # helper methods + def clearStackToTableContext(self): + # "clear the stack back to a table context" + while self.tree.openElements[-1].name not in ("table", "html"): + # self.parser.parseError("unexpected-implied-end-tag-in-table", + # {"name": self.tree.openElements[-1].name}) + self.tree.openElements.pop() + # When the current node is <html> it's an innerHTML case + + # processing methods + def processEOF(self): + if self.tree.openElements[-1].name != "html": + self.parser.parseError("eof-in-table") + else: + assert self.parser.innerHTML + # Stop parsing + + def processSpaceCharacters(self, token): + originalPhase = self.parser.phase + self.parser.phase = self.parser.phases["inTableText"] + self.parser.phase.originalPhase = originalPhase + self.parser.phase.processSpaceCharacters(token) + + def processCharacters(self, token): + originalPhase = self.parser.phase + self.parser.phase = self.parser.phases["inTableText"] + self.parser.phase.originalPhase = originalPhase + self.parser.phase.processCharacters(token) + + def insertText(self, token): + # If we get here there must be at least one non-whitespace character + # Do the table magic! + self.tree.insertFromTable = True + self.parser.phases["inBody"].processCharacters(token) + self.tree.insertFromTable = False + + def startTagCaption(self, token): + self.clearStackToTableContext() + self.tree.activeFormattingElements.append(Marker) + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inCaption"] + + def startTagColgroup(self, token): + self.clearStackToTableContext() + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inColumnGroup"] + + def startTagCol(self, token): + self.startTagColgroup(impliedTagToken("colgroup", "StartTag")) + return token + + def startTagRowGroup(self, token): + self.clearStackToTableContext() + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inTableBody"] + + def startTagImplyTbody(self, token): + self.startTagRowGroup(impliedTagToken("tbody", "StartTag")) + return token + + def startTagTable(self, token): + self.parser.parseError("unexpected-start-tag-implies-end-tag", + {"startName": "table", "endName": "table"}) + self.parser.phase.processEndTag(impliedTagToken("table")) + if not self.parser.innerHTML: + return token + + def startTagStyleScript(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagInput(self, token): + if ("type" in token["data"] and + token["data"]["type"].translate(asciiUpper2Lower) == "hidden"): + self.parser.parseError("unexpected-hidden-input-in-table") + self.tree.insertElement(token) + # XXX associate with form + self.tree.openElements.pop() + else: + self.startTagOther(token) + + def startTagForm(self, token): + self.parser.parseError("unexpected-form-in-table") + if self.tree.formPointer is None: + self.tree.insertElement(token) + self.tree.formPointer = self.tree.openElements[-1] + self.tree.openElements.pop() + + def startTagOther(self, token): + self.parser.parseError("unexpected-start-tag-implies-table-voodoo", {"name": token["name"]}) + # Do the table magic! + self.tree.insertFromTable = True + self.parser.phases["inBody"].processStartTag(token) + self.tree.insertFromTable = False + + def endTagTable(self, token): + if self.tree.elementInScope("table", variant="table"): + self.tree.generateImpliedEndTags() + if self.tree.openElements[-1].name != "table": + self.parser.parseError("end-tag-too-early-named", + {"gotName": "table", + "expectedName": self.tree.openElements[-1].name}) + while self.tree.openElements[-1].name != "table": + self.tree.openElements.pop() + self.tree.openElements.pop() + self.parser.resetInsertionMode() + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def endTagIgnore(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag-implies-table-voodoo", {"name": token["name"]}) + # Do the table magic! + self.tree.insertFromTable = True + self.parser.phases["inBody"].processEndTag(token) + self.tree.insertFromTable = False + + class InTableTextPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + self.originalPhase = None + self.characterTokens = [] + + def flushCharacters(self): + data = "".join([item["data"] for item in self.characterTokens]) + if any([item not in spaceCharacters for item in data]): + token = {"type": tokenTypes["Characters"], "data": data} + self.parser.phases["inTable"].insertText(token) + elif data: + self.tree.insertText(data) + self.characterTokens = [] + + def processComment(self, token): + self.flushCharacters() + self.parser.phase = self.originalPhase + return token + + def processEOF(self): + self.flushCharacters() + self.parser.phase = self.originalPhase + return True + + def processCharacters(self, token): + if token["data"] == "\u0000": + return + self.characterTokens.append(token) + + def processSpaceCharacters(self, token): + # pretty sure we should never reach here + self.characterTokens.append(token) + # assert False + + def processStartTag(self, token): + self.flushCharacters() + self.parser.phase = self.originalPhase + return token + + def processEndTag(self, token): + self.flushCharacters() + self.parser.phase = self.originalPhase + return token + + 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 + + def ignoreEndTagCaption(self): + return not self.tree.elementInScope("caption", variant="table") + + def processEOF(self): + self.parser.phases["inBody"].processEOF() + + def processCharacters(self, token): + return self.parser.phases["inBody"].processCharacters(token) + + def startTagTableElement(self, token): + self.parser.parseError() + # XXX Have to duplicate logic here to find out if the tag is ignored + ignoreEndTag = self.ignoreEndTagCaption() + self.parser.phase.processEndTag(impliedTagToken("caption")) + if not ignoreEndTag: + return token + + def startTagOther(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def endTagCaption(self, token): + if not self.ignoreEndTagCaption(): + # AT this code is quite similar to endTagTable in "InTable" + self.tree.generateImpliedEndTags() + if self.tree.openElements[-1].name != "caption": + self.parser.parseError("expected-one-end-tag-but-got-another", + {"gotName": "caption", + "expectedName": self.tree.openElements[-1].name}) + while self.tree.openElements[-1].name != "caption": + self.tree.openElements.pop() + self.tree.openElements.pop() + self.tree.clearActiveFormattingElements() + self.parser.phase = self.parser.phases["inTable"] + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def endTagTable(self, token): + self.parser.parseError() + ignoreEndTag = self.ignoreEndTagCaption() + self.parser.phase.processEndTag(impliedTagToken("caption")) + if not ignoreEndTag: + return token + + def endTagIgnore(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def endTagOther(self, token): + return self.parser.phases["inBody"].processEndTag(token) + + 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 + + def ignoreEndTagColgroup(self): + return self.tree.openElements[-1].name == "html" + + def processEOF(self): + if self.tree.openElements[-1].name == "html": + assert self.parser.innerHTML + return + else: + ignoreEndTag = self.ignoreEndTagColgroup() + self.endTagColgroup(impliedTagToken("colgroup")) + if not ignoreEndTag: + return True + + def processCharacters(self, token): + ignoreEndTag = self.ignoreEndTagColgroup() + self.endTagColgroup(impliedTagToken("colgroup")) + if not ignoreEndTag: + return token + + def startTagCol(self, token): + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def startTagOther(self, token): + ignoreEndTag = self.ignoreEndTagColgroup() + self.endTagColgroup(impliedTagToken("colgroup")) + if not ignoreEndTag: + return token + + def endTagColgroup(self, token): + if self.ignoreEndTagColgroup(): + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + else: + self.tree.openElements.pop() + self.parser.phase = self.parser.phases["inTable"] + + def endTagCol(self, token): + self.parser.parseError("no-end-tag", {"name": "col"}) + + def endTagOther(self, token): + ignoreEndTag = self.ignoreEndTagColgroup() + self.endTagColgroup(impliedTagToken("colgroup")) + if not ignoreEndTag: + return token + + 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 + + # helper methods + def clearStackToTableBodyContext(self): + while self.tree.openElements[-1].name not in ("tbody", "tfoot", + "thead", "html"): + # self.parser.parseError("unexpected-implied-end-tag-in-table", + # {"name": self.tree.openElements[-1].name}) + self.tree.openElements.pop() + if self.tree.openElements[-1].name == "html": + assert self.parser.innerHTML + + # the rest + def processEOF(self): + self.parser.phases["inTable"].processEOF() + + def processSpaceCharacters(self, token): + return self.parser.phases["inTable"].processSpaceCharacters(token) + + def processCharacters(self, token): + return self.parser.phases["inTable"].processCharacters(token) + + def startTagTr(self, token): + self.clearStackToTableBodyContext() + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inRow"] + + def startTagTableCell(self, token): + self.parser.parseError("unexpected-cell-in-table-body", + {"name": token["name"]}) + self.startTagTr(impliedTagToken("tr", "StartTag")) + return token + + def startTagTableOther(self, token): + # XXX AT Any ideas on how to share this with endTagTable? + if (self.tree.elementInScope("tbody", variant="table") or + self.tree.elementInScope("thead", variant="table") or + self.tree.elementInScope("tfoot", variant="table")): + self.clearStackToTableBodyContext() + self.endTagTableRowGroup( + impliedTagToken(self.tree.openElements[-1].name)) + return token + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def startTagOther(self, token): + return self.parser.phases["inTable"].processStartTag(token) + + def endTagTableRowGroup(self, token): + if self.tree.elementInScope(token["name"], variant="table"): + self.clearStackToTableBodyContext() + self.tree.openElements.pop() + self.parser.phase = self.parser.phases["inTable"] + else: + self.parser.parseError("unexpected-end-tag-in-table-body", + {"name": token["name"]}) + + def endTagTable(self, token): + if (self.tree.elementInScope("tbody", variant="table") or + self.tree.elementInScope("thead", variant="table") or + self.tree.elementInScope("tfoot", variant="table")): + self.clearStackToTableBodyContext() + self.endTagTableRowGroup( + impliedTagToken(self.tree.openElements[-1].name)) + return token + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def endTagIgnore(self, token): + self.parser.parseError("unexpected-end-tag-in-table-body", + {"name": token["name"]}) + + def endTagOther(self, token): + return self.parser.phases["inTable"].processEndTag(token) + + 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 + + # helper methods (XXX unify this with other table helper methods) + def clearStackToTableRowContext(self): + while self.tree.openElements[-1].name not in ("tr", "html"): + self.parser.parseError("unexpected-implied-end-tag-in-table-row", + {"name": self.tree.openElements[-1].name}) + self.tree.openElements.pop() + + def ignoreEndTagTr(self): + return not self.tree.elementInScope("tr", variant="table") + + # the rest + def processEOF(self): + self.parser.phases["inTable"].processEOF() + + def processSpaceCharacters(self, token): + return self.parser.phases["inTable"].processSpaceCharacters(token) + + def processCharacters(self, token): + return self.parser.phases["inTable"].processCharacters(token) + + def startTagTableCell(self, token): + self.clearStackToTableRowContext() + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inCell"] + self.tree.activeFormattingElements.append(Marker) + + def startTagTableOther(self, token): + ignoreEndTag = self.ignoreEndTagTr() + self.endTagTr(impliedTagToken("tr")) + # XXX how are we sure it's always ignored in the innerHTML case? + if not ignoreEndTag: + return token + + def startTagOther(self, token): + return self.parser.phases["inTable"].processStartTag(token) + + def endTagTr(self, token): + if not self.ignoreEndTagTr(): + self.clearStackToTableRowContext() + self.tree.openElements.pop() + self.parser.phase = self.parser.phases["inTableBody"] + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def endTagTable(self, token): + ignoreEndTag = self.ignoreEndTagTr() + self.endTagTr(impliedTagToken("tr")) + # Reprocess the current tag if the tr end tag was not ignored + # XXX how are we sure it's always ignored in the innerHTML case? + if not ignoreEndTag: + return token + + def endTagTableRowGroup(self, token): + if self.tree.elementInScope(token["name"], variant="table"): + self.endTagTr(impliedTagToken("tr")) + return token + else: + self.parser.parseError() + + def endTagIgnore(self, token): + self.parser.parseError("unexpected-end-tag-in-table-row", + {"name": token["name"]}) + + def endTagOther(self, token): + return self.parser.phases["inTable"].processEndTag(token) + + 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 + + # helper + def closeCell(self): + if self.tree.elementInScope("td", variant="table"): + self.endTagTableCell(impliedTagToken("td")) + elif self.tree.elementInScope("th", variant="table"): + self.endTagTableCell(impliedTagToken("th")) + + # the rest + def processEOF(self): + self.parser.phases["inBody"].processEOF() + + def processCharacters(self, token): + return self.parser.phases["inBody"].processCharacters(token) + + def startTagTableOther(self, token): + if (self.tree.elementInScope("td", variant="table") or + self.tree.elementInScope("th", variant="table")): + self.closeCell() + return token + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def startTagOther(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def endTagTableCell(self, token): + if self.tree.elementInScope(token["name"], variant="table"): + self.tree.generateImpliedEndTags(token["name"]) + if self.tree.openElements[-1].name != token["name"]: + self.parser.parseError("unexpected-cell-end-tag", + {"name": token["name"]}) + while True: + node = self.tree.openElements.pop() + if node.name == token["name"]: + break + else: + self.tree.openElements.pop() + self.tree.clearActiveFormattingElements() + self.parser.phase = self.parser.phases["inRow"] + else: + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def endTagIgnore(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def endTagImply(self, token): + if self.tree.elementInScope(token["name"], variant="table"): + self.closeCell() + return token + else: + # sometimes innerHTML case + self.parser.parseError() + + def endTagOther(self, token): + return self.parser.phases["inBody"].processEndTag(token) + + 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 + + # http://www.whatwg.org/specs/web-apps/current-work/#in-select + def processEOF(self): + if self.tree.openElements[-1].name != "html": + self.parser.parseError("eof-in-select") + else: + assert self.parser.innerHTML + + def processCharacters(self, token): + if token["data"] == "\u0000": + return + self.tree.insertText(token["data"]) + + def startTagOption(self, token): + # We need to imply </option> if <option> is the current node. + if self.tree.openElements[-1].name == "option": + self.tree.openElements.pop() + self.tree.insertElement(token) + + def startTagOptgroup(self, token): + if self.tree.openElements[-1].name == "option": + self.tree.openElements.pop() + if self.tree.openElements[-1].name == "optgroup": + self.tree.openElements.pop() + self.tree.insertElement(token) + + def startTagSelect(self, token): + self.parser.parseError("unexpected-select-in-select") + self.endTagSelect(impliedTagToken("select")) + + def startTagInput(self, token): + self.parser.parseError("unexpected-input-in-select") + if self.tree.elementInScope("select", variant="select"): + self.endTagSelect(impliedTagToken("select")) + return token + else: + assert self.parser.innerHTML + + def startTagScript(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagOther(self, token): + self.parser.parseError("unexpected-start-tag-in-select", + {"name": token["name"]}) + + def endTagOption(self, token): + if self.tree.openElements[-1].name == "option": + self.tree.openElements.pop() + else: + self.parser.parseError("unexpected-end-tag-in-select", + {"name": "option"}) + + def endTagOptgroup(self, token): + # </optgroup> implicitly closes <option> + if (self.tree.openElements[-1].name == "option" and + self.tree.openElements[-2].name == "optgroup"): + self.tree.openElements.pop() + # It also closes </optgroup> + if self.tree.openElements[-1].name == "optgroup": + self.tree.openElements.pop() + # But nothing else + else: + self.parser.parseError("unexpected-end-tag-in-select", + {"name": "optgroup"}) + + def endTagSelect(self, token): + if self.tree.elementInScope("select", variant="select"): + node = self.tree.openElements.pop() + while node.name != "select": + node = self.tree.openElements.pop() + self.parser.resetInsertionMode() + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag-in-select", + {"name": token["name"]}) + + 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 + + def processEOF(self): + self.parser.phases["inSelect"].processEOF() + + def processCharacters(self, token): + return self.parser.phases["inSelect"].processCharacters(token) + + def startTagTable(self, token): + self.parser.parseError("unexpected-table-element-start-tag-in-select-in-table", {"name": token["name"]}) + self.endTagOther(impliedTagToken("select")) + return token + + def startTagOther(self, token): + return self.parser.phases["inSelect"].processStartTag(token) + + def endTagTable(self, token): + self.parser.parseError("unexpected-table-element-end-tag-in-select-in-table", {"name": token["name"]}) + if self.tree.elementInScope(token["name"], variant="table"): + self.endTagOther(impliedTagToken("select")) + return token + + def endTagOther(self, token): + return self.parser.phases["inSelect"].processEndTag(token) + + class InForeignContentPhase(Phase): + breakoutElements = frozenset(["b", "big", "blockquote", "body", "br", + "center", "code", "dd", "div", "dl", "dt", + "em", "embed", "h1", "h2", "h3", + "h4", "h5", "h6", "head", "hr", "i", "img", + "li", "listing", "menu", "meta", "nobr", + "ol", "p", "pre", "ruby", "s", "small", + "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", + "altglyphitem": "altGlyphItem", + "animatecolor": "animateColor", + "animatemotion": "animateMotion", + "animatetransform": "animateTransform", + "clippath": "clipPath", + "feblend": "feBlend", + "fecolormatrix": "feColorMatrix", + "fecomponenttransfer": "feComponentTransfer", + "fecomposite": "feComposite", + "feconvolvematrix": "feConvolveMatrix", + "fediffuselighting": "feDiffuseLighting", + "fedisplacementmap": "feDisplacementMap", + "fedistantlight": "feDistantLight", + "feflood": "feFlood", + "fefunca": "feFuncA", + "fefuncb": "feFuncB", + "fefuncg": "feFuncG", + "fefuncr": "feFuncR", + "fegaussianblur": "feGaussianBlur", + "feimage": "feImage", + "femerge": "feMerge", + "femergenode": "feMergeNode", + "femorphology": "feMorphology", + "feoffset": "feOffset", + "fepointlight": "fePointLight", + "fespecularlighting": "feSpecularLighting", + "fespotlight": "feSpotLight", + "fetile": "feTile", + "feturbulence": "feTurbulence", + "foreignobject": "foreignObject", + "glyphref": "glyphRef", + "lineargradient": "linearGradient", + "radialgradient": "radialGradient", + "textpath": "textPath"} + + if token["name"] in replacements: + token["name"] = replacements[token["name"]] + + def processCharacters(self, token): + if token["data"] == "\u0000": + token["data"] = "\uFFFD" + elif (self.parser.framesetOK and + any(char not in spaceCharacters for char in token["data"])): + self.parser.framesetOK = False + Phase.processCharacters(self, token) + + def processStartTag(self, token): + currentNode = self.tree.openElements[-1] + if (token["name"] in self.breakoutElements or + (token["name"] == "font" and + set(token["data"].keys()) & set(["color", "face", "size"]))): + self.parser.parseError("unexpected-html-element-in-foreign-content", + {"name": token["name"]}) + while (self.tree.openElements[-1].namespace != + self.tree.defaultNamespace and + not self.parser.isHTMLIntegrationPoint(self.tree.openElements[-1]) and + not self.parser.isMathMLTextIntegrationPoint(self.tree.openElements[-1])): + self.tree.openElements.pop() + return token + + else: + if currentNode.namespace == namespaces["mathml"]: + self.parser.adjustMathMLAttributes(token) + elif currentNode.namespace == namespaces["svg"]: + self.adjustSVGTagNames(token) + self.parser.adjustSVGAttributes(token) + self.parser.adjustForeignAttributes(token) + token["namespace"] = currentNode.namespace + self.tree.insertElement(token) + if token["selfClosing"]: + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def processEndTag(self, token): + nodeIndex = len(self.tree.openElements) - 1 + node = self.tree.openElements[-1] + if node.name.translate(asciiUpper2Lower) != token["name"]: + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + while True: + if node.name.translate(asciiUpper2Lower) == token["name"]: + # XXX this isn't in the spec but it seems necessary + if self.parser.phase == self.parser.phases["inTableText"]: + self.parser.phase.flushCharacters() + self.parser.phase = self.parser.phase.originalPhase + while self.tree.openElements.pop() != node: + assert self.tree.openElements + new_token = None + break + nodeIndex -= 1 + + node = self.tree.openElements[nodeIndex] + if node.namespace != self.tree.defaultNamespace: + continue + else: + new_token = self.parser.phase.processEndTag(token) + break + 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 + + def processEOF(self): + # Stop parsing + pass + + def processComment(self, token): + # This is needed because data is to be appended to the <html> element + # here and not to whatever is currently open. + self.tree.insertComment(token, self.tree.openElements[0]) + + def processCharacters(self, token): + self.parser.parseError("unexpected-char-after-body") + self.parser.phase = self.parser.phases["inBody"] + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagOther(self, token): + self.parser.parseError("unexpected-start-tag-after-body", + {"name": token["name"]}) + self.parser.phase = self.parser.phases["inBody"] + return token + + def endTagHtml(self, name): + if self.parser.innerHTML: + self.parser.parseError("unexpected-end-tag-after-body-innerhtml") + else: + self.parser.phase = self.parser.phases["afterAfterBody"] + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag-after-body", + {"name": token["name"]}) + self.parser.phase = self.parser.phases["inBody"] + return token + + 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 + + def processEOF(self): + if self.tree.openElements[-1].name != "html": + self.parser.parseError("eof-in-frameset") + else: + assert self.parser.innerHTML + + def processCharacters(self, token): + self.parser.parseError("unexpected-char-in-frameset") + + def startTagFrameset(self, token): + self.tree.insertElement(token) + + def startTagFrame(self, token): + self.tree.insertElement(token) + self.tree.openElements.pop() + + def startTagNoframes(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagOther(self, token): + self.parser.parseError("unexpected-start-tag-in-frameset", + {"name": token["name"]}) + + def endTagFrameset(self, token): + if self.tree.openElements[-1].name == "html": + # innerHTML case + self.parser.parseError("unexpected-frameset-in-frameset-innerhtml") + else: + self.tree.openElements.pop() + if (not self.parser.innerHTML and + self.tree.openElements[-1].name != "frameset"): + # If we're not in innerHTML mode and the current node is not a + # "frameset" element (anymore) then switch. + self.parser.phase = self.parser.phases["afterFrameset"] + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag-in-frameset", + {"name": token["name"]}) + + 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 + + def processEOF(self): + # Stop parsing + pass + + def processCharacters(self, token): + self.parser.parseError("unexpected-char-after-frameset") + + def startTagNoframes(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagOther(self, token): + self.parser.parseError("unexpected-start-tag-after-frameset", + {"name": token["name"]}) + + def endTagHtml(self, token): + self.parser.phase = self.parser.phases["afterAfterFrameset"] + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag-after-frameset", + {"name": token["name"]}) + + class AfterAfterBodyPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml) + ]) + self.startTagHandler.default = self.startTagOther + + def processEOF(self): + pass + + def processComment(self, token): + self.tree.insertComment(token, self.tree.document) + + def processSpaceCharacters(self, token): + return self.parser.phases["inBody"].processSpaceCharacters(token) + + def processCharacters(self, token): + self.parser.parseError("expected-eof-but-got-char") + self.parser.phase = self.parser.phases["inBody"] + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagOther(self, token): + self.parser.parseError("expected-eof-but-got-start-tag", + {"name": token["name"]}) + self.parser.phase = self.parser.phases["inBody"] + return token + + def processEndTag(self, token): + self.parser.parseError("expected-eof-but-got-end-tag", + {"name": token["name"]}) + self.parser.phase = self.parser.phases["inBody"] + return token + + class AfterAfterFramesetPhase(Phase): + 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 + + def processEOF(self): + pass + + def processComment(self, token): + self.tree.insertComment(token, self.tree.document) + + def processSpaceCharacters(self, token): + return self.parser.phases["inBody"].processSpaceCharacters(token) + + def processCharacters(self, token): + self.parser.parseError("expected-eof-but-got-char") + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagNoFrames(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagOther(self, token): + self.parser.parseError("expected-eof-but-got-start-tag", + {"name": token["name"]}) + + def processEndTag(self, token): + self.parser.parseError("expected-eof-but-got-end-tag", + {"name": token["name"]}) + # pylint:enable=unused-argument + + return { + "initial": InitialPhase, + "beforeHtml": BeforeHtmlPhase, + "beforeHead": BeforeHeadPhase, + "inHead": InHeadPhase, + "inHeadNoscript": InHeadNoscriptPhase, + "afterHead": AfterHeadPhase, + "inBody": InBodyPhase, + "text": TextPhase, + "inTable": InTablePhase, + "inTableText": InTableTextPhase, + "inCaption": InCaptionPhase, + "inColumnGroup": InColumnGroupPhase, + "inTableBody": InTableBodyPhase, + "inRow": InRowPhase, + "inCell": InCellPhase, + "inSelect": InSelectPhase, + "inSelectInTable": InSelectInTablePhase, + "inForeignContent": InForeignContentPhase, + "afterBody": AfterBodyPhase, + "inFrameset": InFramesetPhase, + "afterFrameset": AfterFramesetPhase, + "afterAfterBody": AfterAfterBodyPhase, + "afterAfterFrameset": AfterAfterFramesetPhase, + # XXX after after frameset + } + + +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()) + + +def impliedTagToken(name, type="EndTag", attributes=None, + selfClosing=False): + if attributes is None: + attributes = {} + return {"type": tokenTypes[type], "name": name, "data": attributes, + "selfClosing": selfClosing} + + +class ParseError(Exception): + """Error in parsed document""" + pass diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/serializer.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/serializer.py new file mode 100644 index 0000000..53f4d44 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/serializer.py @@ -0,0 +1,409 @@ +from __future__ import absolute_import, division, unicode_literals +from pip._vendor.six import text_type + +import re + +from codecs import register_error, xmlcharrefreplace_errors + +from .constants import voidElements, booleanAttributes, spaceCharacters +from .constants import rcdataElements, entities, xmlEntities +from . import treewalkers, _utils +from xml.sax.saxutils import escape + +_quoteAttributeSpecChars = "".join(spaceCharacters) + "\"'=<>`" +_quoteAttributeSpec = re.compile("[" + _quoteAttributeSpecChars + "]") +_quoteAttributeLegacy = re.compile("[" + _quoteAttributeSpecChars + + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n" + "\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15" + "\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" + "\x20\x2f\x60\xa0\u1680\u180e\u180f\u2000" + "\u2001\u2002\u2003\u2004\u2005\u2006\u2007" + "\u2008\u2009\u200a\u2028\u2029\u202f\u205f" + "\u3000]") + + +_encode_entity_map = {} +_is_ucs4 = len("\U0010FFFF") == 1 +for k, v in list(entities.items()): + # skip multi-character entities + if ((_is_ucs4 and len(v) > 1) or + (not _is_ucs4 and len(v) > 2)): + continue + if v != "&": + if len(v) == 2: + v = _utils.surrogatePairToCodepoint(v) + else: + v = ord(v) + if v not in _encode_entity_map or k.islower(): + # prefer < over < and similarly for &, >, etc. + _encode_entity_map[v] = k + + +def htmlentityreplace_errors(exc): + if isinstance(exc, (UnicodeEncodeError, UnicodeTranslateError)): + res = [] + codepoints = [] + skip = False + for i, c in enumerate(exc.object[exc.start:exc.end]): + if skip: + skip = False + continue + index = i + exc.start + if _utils.isSurrogatePair(exc.object[index:min([exc.end, index + 2])]): + codepoint = _utils.surrogatePairToCodepoint(exc.object[index:index + 2]) + skip = True + else: + codepoint = ord(c) + codepoints.append(codepoint) + for cp in codepoints: + e = _encode_entity_map.get(cp) + if e: + res.append("&") + res.append(e) + if not e.endswith(";"): + res.append(";") + else: + res.append("&#x%s;" % (hex(cp)[2:])) + return ("".join(res), exc.end) + else: + return xmlcharrefreplace_errors(exc) + + +register_error("htmlentityreplace", htmlentityreplace_errors) + + +def serialize(input, tree="etree", encoding=None, **serializer_opts): + """Serializes the input token stream using the specified treewalker + + :arg input: the token stream to serialize + + :arg tree: the treewalker to use + + :arg encoding: the encoding to use + + :arg serializer_opts: any options to pass to the + :py:class:`html5lib.serializer.HTMLSerializer` that gets created + + :returns: the tree serialized as a string + + Example: + + >>> from html5lib.html5parser import parse + >>> from html5lib.serializer import serialize + >>> token_stream = parse('<html><body><p>Hi!</p></body></html>') + >>> serialize(token_stream, omit_optional_tags=False) + '<html><head></head><body><p>Hi!</p></body></html>' + + """ + # XXX: Should we cache this? + walker = treewalkers.getTreeWalker(tree) + s = HTMLSerializer(**serializer_opts) + return s.render(walker(input), encoding) + + +class HTMLSerializer(object): + + # attribute quoting options + quote_attr_values = "legacy" # be secure by default + quote_char = '"' + use_best_quote_char = True + + # tag syntax options + omit_optional_tags = True + minimize_boolean_attributes = True + use_trailing_solidus = False + space_before_trailing_solidus = True + + # escaping options + escape_lt_in_attrs = False + escape_rcdata = False + resolve_entities = True + + # miscellaneous options + alphabetical_attributes = False + inject_meta_charset = True + strip_whitespace = False + sanitize = False + + options = ("quote_attr_values", "quote_char", "use_best_quote_char", + "omit_optional_tags", "minimize_boolean_attributes", + "use_trailing_solidus", "space_before_trailing_solidus", + "escape_lt_in_attrs", "escape_rcdata", "resolve_entities", + "alphabetical_attributes", "inject_meta_charset", + "strip_whitespace", "sanitize") + + def __init__(self, **kwargs): + """Initialize HTMLSerializer + + :arg inject_meta_charset: Whether or not to inject the meta charset. + + Defaults to ``True``. + + :arg quote_attr_values: Whether to quote attribute values that don't + require quoting per legacy browser behavior (``"legacy"``), when + required by the standard (``"spec"``), or always (``"always"``). + + Defaults to ``"legacy"``. + + :arg quote_char: Use given quote character for attribute quoting. + + Defaults to ``"`` which will use double quotes unless attribute + value contains a double quote, in which case single quotes are + used. + + :arg escape_lt_in_attrs: Whether or not to escape ``<`` in attribute + values. + + Defaults to ``False``. + + :arg escape_rcdata: Whether to escape characters that need to be + escaped within normal elements within rcdata elements such as + style. + + Defaults to ``False``. + + :arg resolve_entities: Whether to resolve named character entities that + appear in the source tree. The XML predefined entities < > + & " ' are unaffected by this setting. + + Defaults to ``True``. + + :arg strip_whitespace: Whether to remove semantically meaningless + whitespace. (This compresses all whitespace to a single space + except within ``pre``.) + + Defaults to ``False``. + + :arg minimize_boolean_attributes: Shortens boolean attributes to give + just the attribute value, for example:: + + <input disabled="disabled"> + + becomes:: + + <input disabled> + + Defaults to ``True``. + + :arg use_trailing_solidus: Includes a close-tag slash at the end of the + start tag of void elements (empty elements whose end tag is + forbidden). E.g. ``<hr/>``. + + Defaults to ``False``. + + :arg space_before_trailing_solidus: Places a space immediately before + the closing slash in a tag using a trailing solidus. E.g. + ``<hr />``. Requires ``use_trailing_solidus=True``. + + Defaults to ``True``. + + :arg sanitize: Strip all unsafe or unknown constructs from output. + See :py:class:`html5lib.filters.sanitizer.Filter`. + + Defaults to ``False``. + + :arg omit_optional_tags: Omit start/end tags that are optional. + + Defaults to ``True``. + + :arg alphabetical_attributes: Reorder attributes to be in alphabetical order. + + Defaults to ``False``. + + """ + unexpected_args = frozenset(kwargs) - frozenset(self.options) + if len(unexpected_args) > 0: + raise TypeError("__init__() got an unexpected keyword argument '%s'" % next(iter(unexpected_args))) + if 'quote_char' in kwargs: + self.use_best_quote_char = False + for attr in self.options: + setattr(self, attr, kwargs.get(attr, getattr(self, attr))) + self.errors = [] + self.strict = False + + def encode(self, string): + assert(isinstance(string, text_type)) + if self.encoding: + return string.encode(self.encoding, "htmlentityreplace") + else: + return string + + def encodeStrict(self, string): + assert(isinstance(string, text_type)) + if self.encoding: + return string.encode(self.encoding, "strict") + else: + return string + + def serialize(self, treewalker, encoding=None): + # pylint:disable=too-many-nested-blocks + self.encoding = encoding + in_cdata = False + self.errors = [] + + if encoding and self.inject_meta_charset: + from .filters.inject_meta_charset import Filter + treewalker = Filter(treewalker, encoding) + # Alphabetical attributes is here under the assumption that none of + # the later filters add or change order of attributes; it needs to be + # before the sanitizer so escaped elements come out correctly + if self.alphabetical_attributes: + from .filters.alphabeticalattributes import Filter + treewalker = Filter(treewalker) + # WhitespaceFilter should be used before OptionalTagFilter + # for maximum efficiently of this latter filter + if self.strip_whitespace: + from .filters.whitespace import Filter + treewalker = Filter(treewalker) + if self.sanitize: + from .filters.sanitizer import Filter + treewalker = Filter(treewalker) + if self.omit_optional_tags: + from .filters.optionaltags import Filter + treewalker = Filter(treewalker) + + for token in treewalker: + type = token["type"] + if type == "Doctype": + doctype = "<!DOCTYPE %s" % token["name"] + + if token["publicId"]: + doctype += ' PUBLIC "%s"' % token["publicId"] + elif token["systemId"]: + doctype += " SYSTEM" + if token["systemId"]: + if token["systemId"].find('"') >= 0: + if token["systemId"].find("'") >= 0: + self.serializeError("System identifer contains both single and double quote characters") + quote_char = "'" + else: + quote_char = '"' + doctype += " %s%s%s" % (quote_char, token["systemId"], quote_char) + + doctype += ">" + yield self.encodeStrict(doctype) + + elif type in ("Characters", "SpaceCharacters"): + if type == "SpaceCharacters" or in_cdata: + if in_cdata and token["data"].find("</") >= 0: + self.serializeError("Unexpected </ in CDATA") + yield self.encode(token["data"]) + else: + yield self.encode(escape(token["data"])) + + elif type in ("StartTag", "EmptyTag"): + name = token["name"] + yield self.encodeStrict("<%s" % name) + if name in rcdataElements and not self.escape_rcdata: + in_cdata = True + elif in_cdata: + self.serializeError("Unexpected child element of a CDATA element") + for (_, attr_name), attr_value in token["data"].items(): + # TODO: Add namespace support here + k = attr_name + v = attr_value + yield self.encodeStrict(' ') + + yield self.encodeStrict(k) + if not self.minimize_boolean_attributes or \ + (k not in booleanAttributes.get(name, tuple()) and + k not in booleanAttributes.get("", tuple())): + yield self.encodeStrict("=") + if self.quote_attr_values == "always" or len(v) == 0: + quote_attr = True + elif self.quote_attr_values == "spec": + quote_attr = _quoteAttributeSpec.search(v) is not None + elif self.quote_attr_values == "legacy": + quote_attr = _quoteAttributeLegacy.search(v) is not None + else: + raise ValueError("quote_attr_values must be one of: " + "'always', 'spec', or 'legacy'") + v = v.replace("&", "&") + if self.escape_lt_in_attrs: + v = v.replace("<", "<") + if quote_attr: + quote_char = self.quote_char + if self.use_best_quote_char: + if "'" in v and '"' not in v: + quote_char = '"' + elif '"' in v and "'" not in v: + quote_char = "'" + if quote_char == "'": + v = v.replace("'", "'") + else: + v = v.replace('"', """) + yield self.encodeStrict(quote_char) + yield self.encode(v) + yield self.encodeStrict(quote_char) + else: + yield self.encode(v) + if name in voidElements and self.use_trailing_solidus: + if self.space_before_trailing_solidus: + yield self.encodeStrict(" /") + else: + yield self.encodeStrict("/") + yield self.encode(">") + + elif type == "EndTag": + name = token["name"] + if name in rcdataElements: + in_cdata = False + elif in_cdata: + self.serializeError("Unexpected child element of a CDATA element") + yield self.encodeStrict("</%s>" % name) + + elif type == "Comment": + data = token["data"] + if data.find("--") >= 0: + self.serializeError("Comment contains --") + yield self.encodeStrict("<!--%s-->" % token["data"]) + + elif type == "Entity": + name = token["name"] + key = name + ";" + if key not in entities: + self.serializeError("Entity %s not recognized" % name) + if self.resolve_entities and key not in xmlEntities: + data = entities[key] + else: + data = "&%s;" % name + yield self.encodeStrict(data) + + else: + self.serializeError(token["data"]) + + def render(self, treewalker, encoding=None): + """Serializes the stream from the treewalker into a string + + :arg treewalker: the treewalker to serialize + + :arg encoding: the string encoding to use + + :returns: the serialized tree + + Example: + + >>> from html5lib import parse, getTreeWalker + >>> from html5lib.serializer import HTMLSerializer + >>> token_stream = parse('<html><body>Hi!</body></html>') + >>> walker = getTreeWalker('etree') + >>> serializer = HTMLSerializer(omit_optional_tags=False) + >>> serializer.render(walker(token_stream)) + '<html><head></head><body>Hi!</body></html>' + + """ + if encoding: + return b"".join(list(self.serialize(treewalker, encoding))) + else: + return "".join(list(self.serialize(treewalker))) + + def serializeError(self, data="XXX ERROR MESSAGE NEEDED"): + # XXX The idea is to make data mandatory. + self.errors.append(data) + if self.strict: + raise SerializeError + + +class SerializeError(Exception): + """Error in serialized tree""" + pass diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/__init__.py new file mode 100644 index 0000000..7ef5959 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/__init__.py @@ -0,0 +1,30 @@ +"""Tree adapters let you convert from one tree structure to another + +Example: + +.. code-block:: python + + from pip._vendor import html5lib + from pip._vendor.html5lib.treeadapters import genshi + + doc = '<html><body>Hi!</body></html>' + treebuilder = html5lib.getTreeBuilder('etree') + parser = html5lib.HTMLParser(tree=treebuilder) + tree = parser.parse(doc) + TreeWalker = html5lib.getTreeWalker('etree') + + genshi_tree = genshi.to_genshi(TreeWalker(tree)) + +""" +from __future__ import absolute_import, division, unicode_literals + +from . import sax + +__all__ = ["sax"] + +try: + from . import genshi # noqa +except ImportError: + pass +else: + __all__.append("genshi") diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e60e6ef3878606df80ef4ec5b0d8e1433b115c5f GIT binary patch literal 948 zcmZuvPjAyO6nD}t?Xo{qXg4nA)aI~cFb%Y-o6w|5LxKs3N`nevIknrGI&tJUW!;4@ zz=wbn;@fb}mD9cgC!UjTV-k-1^8WpP&-QyKTU$PY_4QHw;fIURZ)@DFHYhJ(=N~~Z zG(yZ_u5=Q2<R*<#BWaGB4q^?~lxvAM@<3mkI-}OI13nLY?NQr77bx9nBECNN^|^!W z_a3F2?+|Z&^I7Y=1E}^}6s*%<4njlCIi`$ehU*+lZtzkSc&yR|*9K3tO0Y^fHa0Cc zx)_^6gQ+l0m6>tv`=^&Q$t3Ulei#Cf@!eRe@x0&1+0x8Z>iZbiM48A!vfwFG8jB=T zP+(>fc_2mnznt(U7~1N$XIvqtJk4jKB4=uhk8pQj^N$CyV$0(*@puqb+90ajU0cEO z#D$QIYXIERPr0$ra8gHlU2gNbfkk9g=l7G(hOb|}sk}X#cJvQtg|Ie|*TAs)_27V2 zYzVOnD(CkZSLN%#U3FW&z9d<3)>dc~skPo6Uv-us@cnBT927Ll2Q<!=EDR_0dzEb_ z79tlaEjvXjY@dh}&~z&EYnTHRIAtTJm)fg!uP&imV4epXWs4BF1tFzR$fU4CK!}F% zMY>@{6GVwBuuY{>LfB%<jh9uYPqkLM^k|kr|9>LAZBbVI`4VMXEU4kpg6e3ZY<Kb~ znMLC#89BT<{IvIZf5NWvXZs8N^wL}<d$6WyG>l-Lc14;SsJ46XJf6*qcxs*1UJY8+ veLG>1eZ-p~iU<*@FocBJvTP3$#R|!fAHs3+4v40+<8Hd1>pC50+wt7L*cBgr literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/genshi.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/genshi.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b8e3f1c5a89c7d9464ce4e013c8674e60b753f9a GIT binary patch literal 1545 zcmah}OK%%D5GJ_~tyZ$FD5(J@4ImWAK}BP^d9;XO7)@;*0whXX3vIecAgq>@w9&py zQi`ogC+FCMd+6Oh_T2m$UVHMrr(D|MO12a9PzoFkhch2%h9CFal@%Ak`1Mxr<)1b} zf9b`=AfS8$Q#=Jh5ycUTv4>;gk=XDItZgJRW6QH*+q3hv0qcTSh#k*~i(WByJvT0S zCD=2m^%i+$YVV^);T#ZA!%%B}Po&XUvThh>DVNHj;UpAcnyAV+34@ffZWKz!{YW&3 zvc7NoF;muKDY<A^%G&Qd{-L9cR(nsGoz{zvD(pUg_N>(gW$*cJ=jZQQ0oF&sfa>xY zz`u9_)&ZL16MXn!hW5}2e)ajB%m~FbG&g1jB_o^Po8eOgHlv2lFh<GE8RkzVrsgS` z;WJFFzVRc%ISxeF5b+MY3pK<!bru@PVh#1lI+~k_w!vy{N`tzz^md7TYMwy`$M_h} zEon)6W*+02)h8GDfL$ID{*JEXnXQ2S_wpR|Kj#z{XctHaWx!e;krT`-QfC8|eYCd* z*kxH<<O#A;(>Y#)3XChigYr*k2A$)b|Mr4b;dZZ2f8R}$3FETv*Cl7HE>qA3ED^&n zH@I#c#+J_q^*4SrVtlJEhu{Xji?xmzi#$*pE_by(SYn5A3B#Ej^F(av6M!i)<@L0G zaa;lv5(`IV%A<?{jojU#&;0;sCDht}<_GKpgGqhqD<Eh4{2v(n8t?^ToPFtY+3^R; zX~mg5(poVAHVPd-wST!I=68fLwds;`2E<x0_ciApfEb_|diBLiGRJcwp^Fs34d79c ze@1~*>nO3o2DbtXAbs*1IWVE0Cf6KpUz~BSR}IWHFgzi$v8hZS9)z+cel%u(Abt~e z-p`vE4=284&56&O{WPLbZZjS>gD<o0qv@m9n{V#-=~R4mf5Pt_%4xg_V~{jE%`D9B zhKZ1V6y1IJb#FKt_XgUS&+ddJH08~qjH8E9*lX%b^QoWdZZ;QpypbKfcekTZ$RLfg zo!gL(&>s^UPjAb#yL8%)(g2?I&c>A|zYbo?ZY5N=x3HVWF-s)8<uuS&r<`oui^AXu zRgO3klEqJGyWuL^&oao07j?AxIt>%9U%Rs4%MlA+06p&(ceJKIc)SFnVJmw<H(&-k zl**Fnh$XzN9X<h}EZtX;_j4g`X>0Ma28}GXK_JJ(tJr~G1)I2vO``SnTvqW7&@U~d zN?crpomE^lOk!i+fcSP}MY-K>e+*P+-7eSd;+j6(1mTsIJquFK7NzI{7nS8j>C&$% f%OO8VTN8rkxjWl&O2-k~(IgTY<OZqWPmO;8#W0BD literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/sax.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/sax.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6e1c0e7af9cc74059f29ef790f25a9ff08d33868 GIT binary patch literal 1495 zcmah}OK)Q}6t?d>&t|G3RM=dJhsdInFryhX)u^I$I)ViiQU(=W6-7?$BzNNbi0zxE zQMzGRvfwAQ>=6G0vEm1Kg~V!Dv0}lB<C{)fq(S(~$H(V<=V@Pm(r8o>jPKqaoc!q_ z^t;)-8V)cY!;}*s6j97kf+L(*k(Jnyjg8FWPU1!`@HTb0m-vyN1W|xdjH1foedb?O zFVPe9^;;))REz3SgVm@zt%yC=U=>z-jAnbsh<eoj7DY|!_E0-`3DHp7)*ECXGhQgx zkCQwTN(VHa$1=`R-73;}m{Hc}v0{R7*~YrHuat-ffR{(T&yt+Kw2U81ze(uxLaL{k zVDUJ;LFw%x{SVdA(Ab*c!-T$|1DNsyjL-^Spi6|&B2@UoDr?(1vCge?8#MOHTG^Kt zMzhUhwD@&pD*yT1SveGMqjPuVQfq37PiNg(7kGQ>i64~FI@?IOFRXJ9e0Z>Tw-Hcp z8;z{>y7Dfe-(cf|{a=9cUxz9q8_xlte)(Ti1>*k(r~rIH2A3G}Hr7?J{$tjqHQ7}a zT7QAR!Lu&Z^SX+wE6dn@k7v%Y=}pb_hBn|Fo6DaL2<KsM|EnDyPgyw3QpHjgPDn~Q z6XAeJM#C%(m0;|Y@F~dFOSKxp*d=0oCD;wsgx$ueEG#5QvJ!BuH3A4TXF`Rsy5;67 z=B~-+I)Sy5HA*|`EN9w(k_`<5*CyyGBGfZ7*1=(tt24tnlqjMrDM^^j$&hKsu%Zr^ zLwkoQ1q@hL4<<yAA>2%<H+lwlOW+@5Ndj$ny4?ISou=6-)SpcmPzZa}uIq+0aUqYw zz;rVgY!om03CZ&~9cveEd?NK`iTa|{eZE!+7t#=c$)#Cp4>>a~j(WPzQhKwi4sY^n z?n?>Xf}iS8h)n1fAphl6*Ff?ro3^jL^$}_Rs-@anCn%aGuv^w5DkV?ghm=1e@eb_% zUUqU3&xvB4IT4*v#woO?lT13p5A*(`<)i1_)B7X3ln?LE#l3}ECS4fgwDYW!$N5g2 zLPebKJosoZnHGbw5tg$*hx9VhnW%(6;PIeiE)$_7H{I_@vbdX{X-{Q+U>lH!d<X;u z0p7$dtBM2ooRWGV@!&I>`Za9<XIU)^&{(_&mhBB)?e|B8Dg^8Ig?T1~ZHRd+qdSX) z-!(yD6_5rK<)P>bTuLY)RZ^G-r933@25{P&6J9VWLStUx*^uxfbEQl-%YbF~ZjpD5 cRq!~;Xu;VYJV;0y?3PuBG#$JJ3D@m^07nL^=>Px# literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/genshi.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/genshi.py new file mode 100644 index 0000000..61d5fb6 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/genshi.py @@ -0,0 +1,54 @@ +from __future__ import absolute_import, division, unicode_literals + +from genshi.core import QName, Attrs +from genshi.core import START, END, TEXT, COMMENT, DOCTYPE + + +def to_genshi(walker): + """Convert a tree to a genshi tree + + :arg walker: the treewalker to use to walk the tree to convert it + + :returns: generator of genshi nodes + + """ + text = [] + for token in walker: + type = token["type"] + if type in ("Characters", "SpaceCharacters"): + text.append(token["data"]) + elif text: + yield TEXT, "".join(text), (None, -1, -1) + text = [] + + if type in ("StartTag", "EmptyTag"): + if token["namespace"]: + name = "{%s}%s" % (token["namespace"], token["name"]) + else: + name = token["name"] + attrs = Attrs([(QName("{%s}%s" % attr if attr[0] is not None else attr[1]), value) + for attr, value in token["data"].items()]) + yield (START, (QName(name), attrs), (None, -1, -1)) + if type == "EmptyTag": + type = "EndTag" + + if type == "EndTag": + if token["namespace"]: + name = "{%s}%s" % (token["namespace"], token["name"]) + else: + name = token["name"] + + yield END, QName(name), (None, -1, -1) + + elif type == "Comment": + yield COMMENT, token["data"], (None, -1, -1) + + elif type == "Doctype": + yield DOCTYPE, (token["name"], token["publicId"], + token["systemId"]), (None, -1, -1) + + else: + pass # FIXME: What to do? + + if text: + yield TEXT, "".join(text), (None, -1, -1) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/sax.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/sax.py new file mode 100644 index 0000000..f4ccea5 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/sax.py @@ -0,0 +1,50 @@ +from __future__ import absolute_import, division, unicode_literals + +from xml.sax.xmlreader import AttributesNSImpl + +from ..constants import adjustForeignAttributes, unadjustForeignAttributes + +prefix_mapping = {} +for prefix, localName, namespace in adjustForeignAttributes.values(): + if prefix is not None: + prefix_mapping[prefix] = namespace + + +def to_sax(walker, handler): + """Call SAX-like content handler based on treewalker walker + + :arg walker: the treewalker to use to walk the tree to convert it + + :arg handler: SAX handler to use + + """ + handler.startDocument() + for prefix, namespace in prefix_mapping.items(): + handler.startPrefixMapping(prefix, namespace) + + for token in walker: + type = token["type"] + if type == "Doctype": + continue + elif type in ("StartTag", "EmptyTag"): + attrs = AttributesNSImpl(token["data"], + unadjustForeignAttributes) + handler.startElementNS((token["namespace"], token["name"]), + token["name"], + attrs) + if type == "EmptyTag": + handler.endElementNS((token["namespace"], token["name"]), + token["name"]) + elif type == "EndTag": + handler.endElementNS((token["namespace"], token["name"]), + token["name"]) + elif type in ("Characters", "SpaceCharacters"): + handler.characters(token["data"]) + elif type == "Comment": + pass + else: + assert False, "Unknown token type" + + for prefix, namespace in prefix_mapping.items(): + handler.endPrefixMapping(prefix) + handler.endDocument() diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__init__.py new file mode 100644 index 0000000..d44447e --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__init__.py @@ -0,0 +1,88 @@ +"""A collection of modules for building different kinds of trees from HTML +documents. + +To create a treebuilder for a new type of tree, you need to do +implement several things: + +1. A set of classes for various types of elements: Document, Doctype, Comment, + Element. These must implement the interface of ``base.treebuilders.Node`` + (although comment nodes have a different signature for their constructor, + see ``treebuilders.etree.Comment``) Textual content may also be implemented + as another node type, or not, as your tree implementation requires. + +2. A treebuilder object (called ``TreeBuilder`` by convention) that inherits + from ``treebuilders.base.TreeBuilder``. This has 4 required attributes: + + * ``documentClass`` - the class to use for the bottommost node of a document + * ``elementClass`` - the class to use for HTML Elements + * ``commentClass`` - the class to use for comments + * ``doctypeClass`` - the class to use for doctypes + + It also has one required method: + + * ``getDocument`` - Returns the root node of the complete document tree + +3. If you wish to run the unit tests, you must also create a ``testSerializer`` + method on your treebuilder which accepts a node and returns a string + containing Node and its children serialized according to the format used in + the unittests + +""" + +from __future__ import absolute_import, division, unicode_literals + +from .._utils import default_etree + +treeBuilderCache = {} + + +def getTreeBuilder(treeType, implementation=None, **kwargs): + """Get a TreeBuilder class for various types of trees with built-in support + + :arg treeType: the name of the tree type required (case-insensitive). Supported + values are: + + * "dom" - A generic builder for DOM implementations, defaulting to a + xml.dom.minidom based implementation. + * "etree" - A generic builder for tree implementations exposing an + ElementTree-like interface, defaulting to xml.etree.cElementTree if + available and xml.etree.ElementTree if not. + * "lxml" - A etree-based builder for lxml.etree, handling limitations + of lxml's implementation. + + :arg implementation: (Currently applies to the "etree" and "dom" tree + types). A module implementing the tree type e.g. xml.etree.ElementTree + or xml.etree.cElementTree. + + :arg kwargs: Any additional options to pass to the TreeBuilder when + creating it. + + Example: + + >>> from html5lib.treebuilders import getTreeBuilder + >>> builder = getTreeBuilder('etree') + + """ + + treeType = treeType.lower() + if treeType not in treeBuilderCache: + if treeType == "dom": + from . import dom + # Come up with a sane default (pref. from the stdlib) + if implementation is None: + from xml.dom import minidom + implementation = minidom + # NEVER cache here, caching is done in the dom submodule + return dom.getDomModule(implementation, **kwargs).TreeBuilder + elif treeType == "lxml": + from . import etree_lxml + treeBuilderCache[treeType] = etree_lxml.TreeBuilder + elif treeType == "etree": + from . import etree + if implementation is None: + implementation = default_etree + # NEVER cache here, caching is done in the etree submodule + return etree.getETreeModule(implementation, **kwargs).TreeBuilder + else: + raise ValueError("""Unrecognised treebuilder "%s" """ % treeType) + return treeBuilderCache.get(treeType) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f7dab8e15551b5d498e8b481cf2122f68bcf556e GIT binary patch literal 3329 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/base.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/base.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..37db749103aff111377f85af9f7a111fe737d48a GIT binary patch literal 11252 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/dom.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/dom.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b9825f2be07f2438b9dd26fa5d6ea5a0c018ad47 GIT binary patch literal 9282 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bb61348d491f5c32bc96f69f267623450f5a2c4c GIT binary patch literal 11861 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 G^8W%LtD~9# literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree_lxml.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree_lxml.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..20e1d3c2b87d71c0ecea4814c19ace1c86977520 GIT binary patch literal 11801 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 ZZ|R7TALMTpZHK3U_C#)?<i6w1|39KB+r|I@ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/base.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/base.py new file mode 100644 index 0000000..73973db --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/base.py @@ -0,0 +1,417 @@ +from __future__ import absolute_import, division, unicode_literals +from pip._vendor.six import text_type + +from ..constants import scopingElements, tableInsertModeElements, namespaces + +# The scope markers are inserted when entering object elements, +# marquees, table cells, and table captions, and are used to prevent formatting +# from "leaking" into tables, object elements, and marquees. +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), + "table": (frozenset([(namespaces["html"], "html"), + (namespaces["html"], "table")]), False), + "select": (frozenset([(namespaces["html"], "optgroup"), + (namespaces["html"], "option")]), True) +} + + +class Node(object): + """Represents an item in the tree""" + def __init__(self, name): + """Creates a Node + + :arg name: The tag name associated with the node + + """ + # The tag name assocaited with the node + self.name = name + # The parent of the current node (or None for the document node) + self.parent = None + # The value of the current node (applies to text nodes and comments) + self.value = None + # A dict holding name -> value pairs for attributes of the node + self.attributes = {} + # A list of child nodes of the current node. This must include all + # elements but not necessarily other node types. + self.childNodes = [] + # A list of miscellaneous flags that can be set on the node. + self._flags = [] + + def __str__(self): + attributesStr = " ".join(["%s=\"%s\"" % (name, value) + for name, value in + self.attributes.items()]) + if attributesStr: + return "<%s %s>" % (self.name, attributesStr) + else: + return "<%s>" % (self.name) + + def __repr__(self): + return "<%s>" % (self.name) + + def appendChild(self, node): + """Insert node as a child of the current node + + :arg node: the node to insert + + """ + raise NotImplementedError + + def insertText(self, data, insertBefore=None): + """Insert data as text in the current node, positioned before the + start of node insertBefore or to the end of the node's text. + + :arg data: the data to insert + + :arg insertBefore: True if you want to insert the text before the node + and False if you want to insert it after the node + + """ + raise NotImplementedError + + def insertBefore(self, node, refNode): + """Insert node as a child of the current node, before refNode in the + list of child nodes. Raises ValueError if refNode is not a child of + the current node + + :arg node: the node to insert + + :arg refNode: the child node to insert the node before + + """ + raise NotImplementedError + + def removeChild(self, node): + """Remove node from the children of the current node + + :arg node: the child node to remove + + """ + raise NotImplementedError + + def reparentChildren(self, newParent): + """Move all the children of the current node to newParent. + This is needed so that trees that don't store text as nodes move the + text in the correct way + + :arg newParent: the node to move all this node's children to + + """ + # XXX - should this method be made more general? + for child in self.childNodes: + newParent.appendChild(child) + self.childNodes = [] + + def cloneNode(self): + """Return a shallow copy of the current node i.e. a node with the same + name and attributes but with no parent or child nodes + """ + raise NotImplementedError + + def hasContent(self): + """Return true if the node has children or text, false otherwise + """ + raise NotImplementedError + + +class ActiveFormattingElements(list): + def append(self, node): + equalCount = 0 + if node != Marker: + for element in self[::-1]: + if element == Marker: + break + if self.nodesEqual(element, node): + equalCount += 1 + if equalCount == 3: + self.remove(element) + break + list.append(self, node) + + def nodesEqual(self, node1, node2): + if not node1.nameTuple == node2.nameTuple: + return False + + if not node1.attributes == node2.attributes: + return False + + return True + + +class TreeBuilder(object): + """Base treebuilder implementation + + * documentClass - the class to use for the bottommost node of a document + * elementClass - the class to use for HTML Elements + * commentClass - the class to use for comments + * doctypeClass - the class to use for doctypes + + """ + # pylint:disable=not-callable + + # Document class + documentClass = None + + # The class to use for creating a node + elementClass = None + + # The class to use for creating comments + commentClass = None + + # The class to use for creating doctypes + doctypeClass = None + + # Fragment class + fragmentClass = None + + def __init__(self, namespaceHTMLElements): + """Create a TreeBuilder + + :arg namespaceHTMLElements: whether or not to namespace HTML elements + + """ + if namespaceHTMLElements: + self.defaultNamespace = "http://www.w3.org/1999/xhtml" + else: + self.defaultNamespace = None + self.reset() + + def reset(self): + self.openElements = [] + self.activeFormattingElements = ActiveFormattingElements() + + # XXX - rename these to headElement, formElement + self.headPointer = None + self.formPointer = None + + self.insertFromTable = False + + self.document = self.documentClass() + + def elementInScope(self, target, variant=None): + + # If we pass a node in we match that. if we pass a string + # match any node with that name + exactNode = hasattr(target, "nameTuple") + if not exactNode: + if isinstance(target, text_type): + target = (namespaces["html"], target) + assert isinstance(target, tuple) + + listElements, invert = listElementsMap[variant] + + for node in reversed(self.openElements): + if exactNode and node == target: + return True + elif not exactNode and node.nameTuple == target: + return True + elif (invert ^ (node.nameTuple in listElements)): + return False + + assert False # We should never reach this point + + def reconstructActiveFormattingElements(self): + # Within this algorithm the order of steps described in the + # specification is not quite the same as the order of steps in the + # code. It should still do the same though. + + # Step 1: stop the algorithm when there's nothing to do. + if not self.activeFormattingElements: + return + + # Step 2 and step 3: we start with the last element. So i is -1. + i = len(self.activeFormattingElements) - 1 + entry = self.activeFormattingElements[i] + if entry == Marker or entry in self.openElements: + return + + # Step 6 + while entry != Marker and entry not in self.openElements: + if i == 0: + # This will be reset to 0 below + i = -1 + break + i -= 1 + # Step 5: let entry be one earlier in the list. + entry = self.activeFormattingElements[i] + + while True: + # Step 7 + i += 1 + + # Step 8 + entry = self.activeFormattingElements[i] + clone = entry.cloneNode() # Mainly to get a new copy of the attributes + + # Step 9 + element = self.insertElement({"type": "StartTag", + "name": clone.name, + "namespace": clone.namespace, + "data": clone.attributes}) + + # Step 10 + self.activeFormattingElements[i] = element + + # Step 11 + if element == self.activeFormattingElements[-1]: + break + + def clearActiveFormattingElements(self): + entry = self.activeFormattingElements.pop() + while self.activeFormattingElements and entry != Marker: + entry = self.activeFormattingElements.pop() + + def elementInActiveFormattingElements(self, name): + """Check if an element exists between the end of the active + formatting elements and the last marker. If it does, return it, else + return false""" + + for item in self.activeFormattingElements[::-1]: + # Check for Marker first because if it's a Marker it doesn't have a + # name attribute. + if item == Marker: + break + elif item.name == name: + return item + return False + + def insertRoot(self, token): + element = self.createElement(token) + self.openElements.append(element) + self.document.appendChild(element) + + def insertDoctype(self, token): + name = token["name"] + publicId = token["publicId"] + systemId = token["systemId"] + + doctype = self.doctypeClass(name, publicId, systemId) + self.document.appendChild(doctype) + + def insertComment(self, token, parent=None): + if parent is None: + parent = self.openElements[-1] + parent.appendChild(self.commentClass(token["data"])) + + def createElement(self, token): + """Create an element but don't insert it anywhere""" + name = token["name"] + namespace = token.get("namespace", self.defaultNamespace) + element = self.elementClass(name, namespace) + element.attributes = token["data"] + return element + + def _getInsertFromTable(self): + return self._insertFromTable + + def _setInsertFromTable(self, value): + """Switch the function used to insert an element from the + normal one to the misnested table one and back again""" + self._insertFromTable = value + if value: + self.insertElement = self.insertElementTable + else: + self.insertElement = self.insertElementNormal + + insertFromTable = property(_getInsertFromTable, _setInsertFromTable) + + def insertElementNormal(self, token): + name = token["name"] + assert isinstance(name, text_type), "Element %s not unicode" % name + namespace = token.get("namespace", self.defaultNamespace) + element = self.elementClass(name, namespace) + element.attributes = token["data"] + self.openElements[-1].appendChild(element) + self.openElements.append(element) + return element + + def insertElementTable(self, token): + """Create an element and insert it into the tree""" + element = self.createElement(token) + if self.openElements[-1].name not in tableInsertModeElements: + return self.insertElementNormal(token) + else: + # We should be in the InTable mode. This means we want to do + # special magic element rearranging + parent, insertBefore = self.getTableMisnestedNodePosition() + if insertBefore is None: + parent.appendChild(element) + else: + parent.insertBefore(element, insertBefore) + self.openElements.append(element) + return element + + def insertText(self, data, parent=None): + """Insert text data.""" + if parent is None: + parent = self.openElements[-1] + + if (not self.insertFromTable or (self.insertFromTable and + self.openElements[-1].name + not in tableInsertModeElements)): + parent.insertText(data) + else: + # We should be in the InTable mode. This means we want to do + # special magic element rearranging + parent, insertBefore = self.getTableMisnestedNodePosition() + parent.insertText(data, insertBefore) + + def getTableMisnestedNodePosition(self): + """Get the foster parent element, and sibling to insert before + (or None) when inserting a misnested table node""" + # The foster parent element is the one which comes before the most + # recently opened table element + # XXX - this is really inelegant + lastTable = None + fosterParent = None + insertBefore = None + for elm in self.openElements[::-1]: + if elm.name == "table": + lastTable = elm + break + if lastTable: + # XXX - we should really check that this parent is actually a + # node here + if lastTable.parent: + fosterParent = lastTable.parent + insertBefore = lastTable + else: + fosterParent = self.openElements[ + self.openElements.index(lastTable) - 1] + else: + fosterParent = self.openElements[0] + return fosterParent, insertBefore + + def generateImpliedEndTags(self, exclude=None): + name = self.openElements[-1].name + # XXX td, th and tr are not actually needed + if (name in frozenset(("dd", "dt", "li", "option", "optgroup", "p", "rp", "rt")) and + name != exclude): + self.openElements.pop() + # XXX This is not entirely what the specification says. We should + # investigate it more closely. + self.generateImpliedEndTags(exclude) + + def getDocument(self): + """Return the final tree""" + return self.document + + def getFragment(self): + """Return the final fragment""" + # assert self.innerHTML + fragment = self.fragmentClass() + self.openElements[0].reparentChildren(fragment) + return fragment + + def testSerializer(self, node): + """Serialize the subtree of node in the format required by unit tests + + :arg node: the node from which to start serializing + + """ + raise NotImplementedError diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/dom.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/dom.py new file mode 100644 index 0000000..dcfac22 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/dom.py @@ -0,0 +1,236 @@ +from __future__ import absolute_import, division, unicode_literals + + +from collections import MutableMapping +from xml.dom import minidom, Node +import weakref + +from . import base +from .. import constants +from ..constants import namespaces +from .._utils import moduleFactoryFactory + + +def getDomBuilder(DomImplementation): + Dom = DomImplementation + + class AttrList(MutableMapping): + def __init__(self, element): + self.element = element + + def __iter__(self): + return iter(self.element.attributes.keys()) + + def __setitem__(self, name, value): + if isinstance(name, tuple): + raise NotImplementedError + else: + attr = self.element.ownerDocument.createAttribute(name) + attr.value = value + self.element.attributes[name] = attr + + def __len__(self): + return len(self.element.attributes) + + def items(self): + return list(self.element.attributes.items()) + + def values(self): + return list(self.element.attributes.values()) + + def __getitem__(self, name): + if isinstance(name, tuple): + raise NotImplementedError + else: + return self.element.attributes[name].value + + def __delitem__(self, name): + if isinstance(name, tuple): + raise NotImplementedError + else: + del self.element.attributes[name] + + class NodeBuilder(base.Node): + def __init__(self, element): + base.Node.__init__(self, element.nodeName) + self.element = element + + namespace = property(lambda self: hasattr(self.element, "namespaceURI") and + self.element.namespaceURI or None) + + def appendChild(self, node): + node.parent = self + self.element.appendChild(node.element) + + def insertText(self, data, insertBefore=None): + text = self.element.ownerDocument.createTextNode(data) + if insertBefore: + self.element.insertBefore(text, insertBefore.element) + else: + self.element.appendChild(text) + + def insertBefore(self, node, refNode): + self.element.insertBefore(node.element, refNode.element) + node.parent = self + + def removeChild(self, node): + if node.element.parentNode == self.element: + self.element.removeChild(node.element) + node.parent = None + + def reparentChildren(self, newParent): + while self.element.hasChildNodes(): + child = self.element.firstChild + self.element.removeChild(child) + newParent.element.appendChild(child) + self.childNodes = [] + + def getAttributes(self): + return AttrList(self.element) + + def setAttributes(self, attributes): + if attributes: + for name, value in list(attributes.items()): + if isinstance(name, tuple): + if name[0] is not None: + qualifiedName = (name[0] + ":" + name[1]) + else: + qualifiedName = name[1] + self.element.setAttributeNS(name[2], qualifiedName, + value) + else: + self.element.setAttribute( + name, value) + attributes = property(getAttributes, setAttributes) + + def cloneNode(self): + return NodeBuilder(self.element.cloneNode(False)) + + def hasContent(self): + return self.element.hasChildNodes() + + def getNameTuple(self): + if self.namespace is None: + return namespaces["html"], self.name + else: + return self.namespace, self.name + + nameTuple = property(getNameTuple) + + class TreeBuilder(base.TreeBuilder): # pylint:disable=unused-variable + def documentClass(self): + self.dom = Dom.getDOMImplementation().createDocument(None, None, None) + return weakref.proxy(self) + + def insertDoctype(self, token): + name = token["name"] + publicId = token["publicId"] + systemId = token["systemId"] + + domimpl = Dom.getDOMImplementation() + doctype = domimpl.createDocumentType(name, publicId, systemId) + self.document.appendChild(NodeBuilder(doctype)) + if Dom == minidom: + doctype.ownerDocument = self.dom + + def elementClass(self, name, namespace=None): + if namespace is None and self.defaultNamespace is None: + node = self.dom.createElement(name) + else: + node = self.dom.createElementNS(namespace, name) + + return NodeBuilder(node) + + def commentClass(self, data): + return NodeBuilder(self.dom.createComment(data)) + + def fragmentClass(self): + return NodeBuilder(self.dom.createDocumentFragment()) + + def appendChild(self, node): + self.dom.appendChild(node.element) + + def testSerializer(self, element): + return testSerializer(element) + + def getDocument(self): + return self.dom + + def getFragment(self): + return base.TreeBuilder.getFragment(self).element + + def insertText(self, data, parent=None): + data = data + if parent != self: + base.TreeBuilder.insertText(self, data, parent) + else: + # HACK: allow text nodes as children of the document node + if hasattr(self.dom, '_child_node_types'): + # pylint:disable=protected-access + if Node.TEXT_NODE not in self.dom._child_node_types: + self.dom._child_node_types = list(self.dom._child_node_types) + self.dom._child_node_types.append(Node.TEXT_NODE) + self.dom.appendChild(self.dom.createTextNode(data)) + + implementation = DomImplementation + name = None + + def testSerializer(element): + element.normalize() + rv = [] + + def serializeElement(element, indent=0): + if element.nodeType == Node.DOCUMENT_TYPE_NODE: + if element.name: + if element.publicId or element.systemId: + publicId = element.publicId or "" + systemId = element.systemId or "" + rv.append("""|%s<!DOCTYPE %s "%s" "%s">""" % + (' ' * indent, element.name, publicId, systemId)) + else: + rv.append("|%s<!DOCTYPE %s>" % (' ' * indent, element.name)) + else: + rv.append("|%s<!DOCTYPE >" % (' ' * indent,)) + elif element.nodeType == Node.DOCUMENT_NODE: + rv.append("#document") + elif element.nodeType == Node.DOCUMENT_FRAGMENT_NODE: + rv.append("#document-fragment") + elif element.nodeType == Node.COMMENT_NODE: + rv.append("|%s<!-- %s -->" % (' ' * indent, element.nodeValue)) + elif element.nodeType == Node.TEXT_NODE: + rv.append("|%s\"%s\"" % (' ' * indent, element.nodeValue)) + else: + if (hasattr(element, "namespaceURI") and + element.namespaceURI is not None): + name = "%s %s" % (constants.prefixes[element.namespaceURI], + element.nodeName) + else: + name = element.nodeName + rv.append("|%s<%s>" % (' ' * indent, name)) + if element.hasAttributes(): + attributes = [] + for i in range(len(element.attributes)): + attr = element.attributes.item(i) + name = attr.nodeName + value = attr.value + ns = attr.namespaceURI + if ns: + name = "%s %s" % (constants.prefixes[ns], attr.localName) + else: + name = attr.nodeName + attributes.append((name, value)) + + for name, value in sorted(attributes): + rv.append('|%s%s="%s"' % (' ' * (indent + 2), name, value)) + indent += 2 + for child in element.childNodes: + serializeElement(child, indent) + serializeElement(element, 0) + + return "\n".join(rv) + + return locals() + + +# The actual means to get a module! +getDomModule = moduleFactoryFactory(getDomBuilder) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/etree.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/etree.py new file mode 100644 index 0000000..0dedf44 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/etree.py @@ -0,0 +1,340 @@ +from __future__ import absolute_import, division, unicode_literals +# pylint:disable=protected-access + +from pip._vendor.six import text_type + +import re + +from . import base +from .. import _ihatexml +from .. import constants +from ..constants import namespaces +from .._utils import moduleFactoryFactory + +tag_regexp = re.compile("{([^}]*)}(.*)") + + +def getETreeBuilder(ElementTreeImplementation, fullTree=False): + ElementTree = ElementTreeImplementation + ElementTreeCommentType = ElementTree.Comment("asd").tag + + class Element(base.Node): + def __init__(self, name, namespace=None): + self._name = name + self._namespace = namespace + self._element = ElementTree.Element(self._getETreeTag(name, + namespace)) + if namespace is None: + self.nameTuple = namespaces["html"], self._name + else: + self.nameTuple = self._namespace, self._name + self.parent = None + self._childNodes = [] + self._flags = [] + + def _getETreeTag(self, name, namespace): + if namespace is None: + etree_tag = name + else: + etree_tag = "{%s}%s" % (namespace, name) + return etree_tag + + def _setName(self, name): + self._name = name + self._element.tag = self._getETreeTag(self._name, self._namespace) + + def _getName(self): + return self._name + + name = property(_getName, _setName) + + def _setNamespace(self, namespace): + self._namespace = namespace + self._element.tag = self._getETreeTag(self._name, self._namespace) + + def _getNamespace(self): + return self._namespace + + namespace = property(_getNamespace, _setNamespace) + + def _getAttributes(self): + 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) + + attributes = property(_getAttributes, _setAttributes) + + def _getChildNodes(self): + return self._childNodes + + def _setChildNodes(self, value): + del self._element[:] + self._childNodes = [] + for element in value: + self.insertChild(element) + + childNodes = property(_getChildNodes, _setChildNodes) + + def hasContent(self): + """Return true if the node has children or text""" + return bool(self._element.text or len(self._element)) + + def appendChild(self, node): + self._childNodes.append(node) + self._element.append(node._element) + node.parent = self + + def insertBefore(self, node, refNode): + index = list(self._element).index(refNode._element) + self._element.insert(index, node._element) + node.parent = self + + def removeChild(self, node): + self._childNodes.remove(node) + self._element.remove(node._element) + node.parent = None + + def insertText(self, data, insertBefore=None): + if not(len(self._element)): + if not self._element.text: + self._element.text = "" + self._element.text += data + elif insertBefore is None: + # Insert the text as the tail of the last child element + if not self._element[-1].tail: + self._element[-1].tail = "" + self._element[-1].tail += data + else: + # Insert the text before the specified node + children = list(self._element) + index = children.index(insertBefore._element) + if index > 0: + if not self._element[index - 1].tail: + self._element[index - 1].tail = "" + self._element[index - 1].tail += data + else: + if not self._element.text: + self._element.text = "" + self._element.text += data + + def cloneNode(self): + element = type(self)(self.name, self.namespace) + for name, value in self.attributes.items(): + element.attributes[name] = value + return element + + def reparentChildren(self, newParent): + if newParent.childNodes: + newParent.childNodes[-1]._element.tail += self._element.text + else: + if not newParent._element.text: + newParent._element.text = "" + if self._element.text is not None: + newParent._element.text += self._element.text + self._element.text = "" + base.Node.reparentChildren(self, newParent) + + class Comment(Element): + def __init__(self, data): + # Use the superclass constructor to set all properties on the + # wrapper element + self._element = ElementTree.Comment(data) + self.parent = None + self._childNodes = [] + self._flags = [] + + def _getData(self): + return self._element.text + + def _setData(self, value): + self._element.text = value + + data = property(_getData, _setData) + + class DocumentType(Element): + def __init__(self, name, publicId, systemId): + Element.__init__(self, "<!DOCTYPE>") + self._element.text = name + self.publicId = publicId + self.systemId = systemId + + def _getPublicId(self): + return self._element.get("publicId", "") + + def _setPublicId(self, value): + if value is not None: + self._element.set("publicId", value) + + publicId = property(_getPublicId, _setPublicId) + + def _getSystemId(self): + return self._element.get("systemId", "") + + def _setSystemId(self, value): + if value is not None: + self._element.set("systemId", value) + + systemId = property(_getSystemId, _setSystemId) + + class Document(Element): + def __init__(self): + Element.__init__(self, "DOCUMENT_ROOT") + + class DocumentFragment(Element): + def __init__(self): + Element.__init__(self, "DOCUMENT_FRAGMENT") + + def testSerializer(element): + rv = [] + + def serializeElement(element, indent=0): + if not(hasattr(element, "tag")): + element = element.getroot() + if element.tag == "<!DOCTYPE>": + if element.get("publicId") or element.get("systemId"): + publicId = element.get("publicId") or "" + systemId = element.get("systemId") or "" + rv.append("""<!DOCTYPE %s "%s" "%s">""" % + (element.text, publicId, systemId)) + else: + rv.append("<!DOCTYPE %s>" % (element.text,)) + elif element.tag == "DOCUMENT_ROOT": + rv.append("#document") + if element.text is not None: + rv.append("|%s\"%s\"" % (' ' * (indent + 2), element.text)) + if element.tail is not None: + raise TypeError("Document node cannot have tail") + if hasattr(element, "attrib") and len(element.attrib): + raise TypeError("Document node cannot have attributes") + elif element.tag == ElementTreeCommentType: + rv.append("|%s<!-- %s -->" % (' ' * indent, element.text)) + else: + assert isinstance(element.tag, text_type), \ + "Expected unicode, got %s, %s" % (type(element.tag), element.tag) + nsmatch = tag_regexp.match(element.tag) + + if nsmatch is None: + name = element.tag + else: + ns, name = nsmatch.groups() + prefix = constants.prefixes[ns] + name = "%s %s" % (prefix, name) + rv.append("|%s<%s>" % (' ' * indent, name)) + + if hasattr(element, "attrib"): + attributes = [] + for name, value in element.attrib.items(): + nsmatch = tag_regexp.match(name) + if nsmatch is not None: + ns, name = nsmatch.groups() + prefix = constants.prefixes[ns] + attr_string = "%s %s" % (prefix, name) + else: + attr_string = name + attributes.append((attr_string, value)) + + for name, value in sorted(attributes): + rv.append('|%s%s="%s"' % (' ' * (indent + 2), name, value)) + if element.text: + rv.append("|%s\"%s\"" % (' ' * (indent + 2), element.text)) + indent += 2 + for child in element: + serializeElement(child, indent) + if element.tail: + rv.append("|%s\"%s\"" % (' ' * (indent - 2), element.tail)) + serializeElement(element, 0) + + return "\n".join(rv) + + def tostring(element): # pylint:disable=unused-variable + """Serialize an element and its child nodes to a string""" + rv = [] + filter = _ihatexml.InfosetFilter() + + def serializeElement(element): + if isinstance(element, ElementTree.ElementTree): + element = element.getroot() + + if element.tag == "<!DOCTYPE>": + if element.get("publicId") or element.get("systemId"): + publicId = element.get("publicId") or "" + systemId = element.get("systemId") or "" + rv.append("""<!DOCTYPE %s PUBLIC "%s" "%s">""" % + (element.text, publicId, systemId)) + else: + rv.append("<!DOCTYPE %s>" % (element.text,)) + elif element.tag == "DOCUMENT_ROOT": + if element.text is not None: + rv.append(element.text) + if element.tail is not None: + raise TypeError("Document node cannot have tail") + if hasattr(element, "attrib") and len(element.attrib): + raise TypeError("Document node cannot have attributes") + + for child in element: + serializeElement(child) + + elif element.tag == ElementTreeCommentType: + rv.append("<!--%s-->" % (element.text,)) + else: + # This is assumed to be an ordinary element + if not element.attrib: + rv.append("<%s>" % (filter.fromXmlName(element.tag),)) + else: + attr = " ".join(["%s=\"%s\"" % ( + filter.fromXmlName(name), value) + for name, value in element.attrib.items()]) + rv.append("<%s %s>" % (element.tag, attr)) + if element.text: + rv.append(element.text) + + for child in element: + serializeElement(child) + + rv.append("</%s>" % (element.tag,)) + + if element.tail: + rv.append(element.tail) + + serializeElement(element) + + return "".join(rv) + + class TreeBuilder(base.TreeBuilder): # pylint:disable=unused-variable + documentClass = Document + doctypeClass = DocumentType + elementClass = Element + commentClass = Comment + fragmentClass = DocumentFragment + implementation = ElementTreeImplementation + + def testSerializer(self, element): + return testSerializer(element) + + def getDocument(self): + if fullTree: + return self.document._element + else: + if self.defaultNamespace is not None: + return self.document._element.find( + "{%s}html" % self.defaultNamespace) + else: + return self.document._element.find("html") + + def getFragment(self): + return base.TreeBuilder.getFragment(self)._element + + return locals() + + +getETreeModule = moduleFactoryFactory(getETreeBuilder) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/etree_lxml.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/etree_lxml.py new file mode 100644 index 0000000..ca12a99 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/etree_lxml.py @@ -0,0 +1,366 @@ +"""Module for supporting the lxml.etree library. The idea here is to use as much +of the native library as possible, without using fragile hacks like custom element +names that break between releases. The downside of this is that we cannot represent +all possible trees; specifically the following are known to cause problems: + +Text or comments as siblings of the root element +Docypes with no name + +When any of these things occur, we emit a DataLossWarning +""" + +from __future__ import absolute_import, division, unicode_literals +# pylint:disable=protected-access + +import warnings +import re +import sys + +from . import base +from ..constants import DataLossWarning +from .. import constants +from . import etree as etree_builders +from .. import _ihatexml + +import lxml.etree as etree + + +fullTree = True +tag_regexp = re.compile("{([^}]*)}(.*)") + +comment_type = etree.Comment("asd").tag + + +class DocumentType(object): + def __init__(self, name, publicId, systemId): + self.name = name + self.publicId = publicId + self.systemId = systemId + + +class Document(object): + def __init__(self): + self._elementTree = None + self._childNodes = [] + + def appendChild(self, element): + self._elementTree.getroot().addnext(element._element) + + def _getChildNodes(self): + return self._childNodes + + childNodes = property(_getChildNodes) + + +def testSerializer(element): + rv = [] + infosetFilter = _ihatexml.InfosetFilter(preventDoubleDashComments=True) + + def serializeElement(element, indent=0): + if not hasattr(element, "tag"): + if hasattr(element, "getroot"): + # Full tree case + rv.append("#document") + if element.docinfo.internalDTD: + if not (element.docinfo.public_id or + element.docinfo.system_url): + dtd_str = "<!DOCTYPE %s>" % element.docinfo.root_name + else: + dtd_str = """<!DOCTYPE %s "%s" "%s">""" % ( + element.docinfo.root_name, + element.docinfo.public_id, + element.docinfo.system_url) + rv.append("|%s%s" % (' ' * (indent + 2), dtd_str)) + next_element = element.getroot() + while next_element.getprevious() is not None: + next_element = next_element.getprevious() + while next_element is not None: + serializeElement(next_element, indent + 2) + next_element = next_element.getnext() + elif isinstance(element, str) or isinstance(element, bytes): + # Text in a fragment + assert isinstance(element, str) or sys.version_info[0] == 2 + rv.append("|%s\"%s\"" % (' ' * indent, element)) + else: + # Fragment case + rv.append("#document-fragment") + for next_element in element: + serializeElement(next_element, indent + 2) + elif element.tag == comment_type: + rv.append("|%s<!-- %s -->" % (' ' * indent, element.text)) + if hasattr(element, "tail") and element.tail: + rv.append("|%s\"%s\"" % (' ' * indent, element.tail)) + else: + assert isinstance(element, etree._Element) + nsmatch = etree_builders.tag_regexp.match(element.tag) + if nsmatch is not None: + ns = nsmatch.group(1) + tag = nsmatch.group(2) + prefix = constants.prefixes[ns] + rv.append("|%s<%s %s>" % (' ' * indent, prefix, + infosetFilter.fromXmlName(tag))) + else: + rv.append("|%s<%s>" % (' ' * indent, + infosetFilter.fromXmlName(element.tag))) + + if hasattr(element, "attrib"): + attributes = [] + for name, value in element.attrib.items(): + nsmatch = tag_regexp.match(name) + if nsmatch is not None: + ns, name = nsmatch.groups() + name = infosetFilter.fromXmlName(name) + prefix = constants.prefixes[ns] + attr_string = "%s %s" % (prefix, name) + else: + attr_string = infosetFilter.fromXmlName(name) + attributes.append((attr_string, value)) + + for name, value in sorted(attributes): + rv.append('|%s%s="%s"' % (' ' * (indent + 2), name, value)) + + if element.text: + rv.append("|%s\"%s\"" % (' ' * (indent + 2), element.text)) + indent += 2 + for child in element: + serializeElement(child, indent) + if hasattr(element, "tail") and element.tail: + rv.append("|%s\"%s\"" % (' ' * (indent - 2), element.tail)) + serializeElement(element, 0) + + return "\n".join(rv) + + +def tostring(element): + """Serialize an element and its child nodes to a string""" + rv = [] + + def serializeElement(element): + if not hasattr(element, "tag"): + if element.docinfo.internalDTD: + if element.docinfo.doctype: + dtd_str = element.docinfo.doctype + else: + dtd_str = "<!DOCTYPE %s>" % element.docinfo.root_name + rv.append(dtd_str) + serializeElement(element.getroot()) + + elif element.tag == comment_type: + rv.append("<!--%s-->" % (element.text,)) + + else: + # This is assumed to be an ordinary element + if not element.attrib: + rv.append("<%s>" % (element.tag,)) + else: + attr = " ".join(["%s=\"%s\"" % (name, value) + for name, value in element.attrib.items()]) + rv.append("<%s %s>" % (element.tag, attr)) + if element.text: + rv.append(element.text) + + for child in element: + serializeElement(child) + + rv.append("</%s>" % (element.tag,)) + + if hasattr(element, "tail") and element.tail: + rv.append(element.tail) + + serializeElement(element) + + return "".join(rv) + + +class TreeBuilder(base.TreeBuilder): + documentClass = Document + doctypeClass = DocumentType + elementClass = None + commentClass = None + fragmentClass = Document + implementation = etree + + def __init__(self, namespaceHTMLElements, fullTree=False): + builder = etree_builders.getETreeModule(etree, fullTree=fullTree) + infosetFilter = self.infosetFilter = _ihatexml.InfosetFilter(preventDoubleDashComments=True) + self.namespaceHTMLElements = namespaceHTMLElements + + class Attributes(dict): + def __init__(self, element, value=None): + if value is None: + value = {} + 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) + if isinstance(key, tuple): + name = "{%s}%s" % (key[2], infosetFilter.coerceAttribute(key[1])) + else: + name = infosetFilter.coerceAttribute(key) + self._element._element.attrib[name] = value + + class Element(builder.Element): + def __init__(self, name, namespace): + name = infosetFilter.coerceElement(name) + builder.Element.__init__(self, name, namespace=namespace) + self._attributes = Attributes(self) + + def _setName(self, name): + self._name = infosetFilter.coerceElement(name) + self._element.tag = self._getETreeTag( + self._name, self._namespace) + + def _getName(self): + return infosetFilter.fromXmlName(self._name) + + name = property(_getName, _setName) + + def _getAttributes(self): + return self._attributes + + def _setAttributes(self, attributes): + self._attributes = Attributes(self, attributes) + + attributes = property(_getAttributes, _setAttributes) + + def insertText(self, data, insertBefore=None): + data = infosetFilter.coerceCharacters(data) + builder.Element.insertText(self, data, insertBefore) + + def appendChild(self, child): + builder.Element.appendChild(self, child) + + class Comment(builder.Comment): + def __init__(self, data): + data = infosetFilter.coerceComment(data) + builder.Comment.__init__(self, data) + + def _setData(self, data): + data = infosetFilter.coerceComment(data) + self._element.text = data + + def _getData(self): + return self._element.text + + data = property(_getData, _setData) + + self.elementClass = Element + self.commentClass = Comment + # self.fragmentClass = builder.DocumentFragment + base.TreeBuilder.__init__(self, namespaceHTMLElements) + + def reset(self): + base.TreeBuilder.reset(self) + self.insertComment = self.insertCommentInitial + self.initial_comments = [] + self.doctype = None + + def testSerializer(self, element): + return testSerializer(element) + + def getDocument(self): + if fullTree: + return self.document._elementTree + else: + return self.document._elementTree.getroot() + + def getFragment(self): + fragment = [] + element = self.openElements[0]._element + if element.text: + fragment.append(element.text) + fragment.extend(list(element)) + if element.tail: + fragment.append(element.tail) + return fragment + + def insertDoctype(self, token): + name = token["name"] + publicId = token["publicId"] + systemId = token["systemId"] + + if not name: + warnings.warn("lxml cannot represent empty doctype", DataLossWarning) + self.doctype = None + else: + coercedName = self.infosetFilter.coerceElement(name) + if coercedName != name: + warnings.warn("lxml cannot represent non-xml doctype", DataLossWarning) + + doctype = self.doctypeClass(coercedName, publicId, systemId) + self.doctype = doctype + + def insertCommentInitial(self, data, parent=None): + assert parent is None or parent is self.document + assert self.document._elementTree is None + self.initial_comments.append(data) + + def insertCommentMain(self, data, parent=None): + if (parent == self.document and + self.document._elementTree.getroot()[-1].tag == comment_type): + warnings.warn("lxml cannot represent adjacent comments beyond the root elements", DataLossWarning) + super(TreeBuilder, self).insertComment(data, parent) + + def insertRoot(self, token): + # Because of the way libxml2 works, it doesn't seem to be possible to + # alter information like the doctype after the tree has been parsed. + # Therefore we need to use the built-in parser to create our initial + # tree, after which we can add elements like normal + docStr = "" + if self.doctype: + assert self.doctype.name + docStr += "<!DOCTYPE %s" % self.doctype.name + if (self.doctype.publicId is not None or + self.doctype.systemId is not None): + docStr += (' PUBLIC "%s" ' % + (self.infosetFilter.coercePubid(self.doctype.publicId or ""))) + if self.doctype.systemId: + sysid = self.doctype.systemId + if sysid.find("'") >= 0 and sysid.find('"') >= 0: + warnings.warn("DOCTYPE system cannot contain single and double quotes", DataLossWarning) + sysid = sysid.replace("'", 'U00027') + if sysid.find("'") >= 0: + docStr += '"%s"' % sysid + else: + docStr += "'%s'" % sysid + else: + docStr += "''" + docStr += ">" + if self.doctype.name != token["name"]: + warnings.warn("lxml cannot represent doctype with a different name to the root element", DataLossWarning) + docStr += "<THIS_SHOULD_NEVER_APPEAR_PUBLICLY/>" + root = etree.fromstring(docStr) + + # Append the initial comments: + for comment_token in self.initial_comments: + comment = self.commentClass(comment_token["data"]) + root.addprevious(comment._element) + + # Create the root document and add the ElementTree to it + self.document = self.documentClass() + self.document._elementTree = root.getroottree() + + # Give the root element the right name + name = token["name"] + namespace = token.get("namespace", self.defaultNamespace) + if namespace is None: + etree_tag = name + else: + etree_tag = "{%s}%s" % (namespace, name) + root.tag = etree_tag + + # Add the root element to the internal child/open data structures + root_element = self.elementClass(name, namespace) + root_element._element = root + self.document._childNodes.append(root_element) + self.openElements.append(root_element) + + # Reset to the default insert comment function + self.insertComment = self.insertCommentMain diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__init__.py new file mode 100644 index 0000000..9bec207 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__init__.py @@ -0,0 +1,154 @@ +"""A collection of modules for iterating through different kinds of +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 +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. +""" + +from __future__ import absolute_import, division, unicode_literals + +from .. import constants +from .._utils import default_etree + +__all__ = ["getTreeWalker", "pprint"] + +treeWalkerCache = {} + + +def getTreeWalker(treeType, implementation=None, **kwargs): + """Get a TreeWalker class for various types of tree with built-in support + + :arg str treeType: the name of the tree type required (case-insensitive). + Supported values are: + + * "dom": The xml.dom.minidom DOM implementation + * "etree": A generic walker for tree implementations exposing an + elementtree-like interface (known to work with ElementTree, + cElementTree and lxml.etree). + * "lxml": Optimized walker for lxml.etree + * "genshi": a Genshi stream + + :arg implementation: A module implementing the tree type e.g. + xml.etree.ElementTree or cElementTree (Currently applies to the "etree" + tree type only). + + :arg kwargs: keyword arguments passed to the etree walker--for other + walkers, this has no effect + + :returns: a TreeWalker class + + """ + + treeType = treeType.lower() + if treeType not in treeWalkerCache: + if treeType == "dom": + from . import dom + treeWalkerCache[treeType] = dom.TreeWalker + elif treeType == "genshi": + from . import genshi + treeWalkerCache[treeType] = genshi.TreeWalker + elif treeType == "lxml": + from . import etree_lxml + treeWalkerCache[treeType] = etree_lxml.TreeWalker + elif treeType == "etree": + from . import etree + if implementation is None: + implementation = default_etree + # XXX: NEVER cache here, caching is done in the etree submodule + return etree.getETreeModule(implementation, **kwargs).TreeWalker + return treeWalkerCache.get(treeType) + + +def concatenateCharacterTokens(tokens): + pendingCharacters = [] + for token in tokens: + type = token["type"] + if type in ("Characters", "SpaceCharacters"): + pendingCharacters.append(token["data"]) + else: + if pendingCharacters: + yield {"type": "Characters", "data": "".join(pendingCharacters)} + pendingCharacters = [] + yield token + if pendingCharacters: + yield {"type": "Characters", "data": "".join(pendingCharacters)} + + +def pprint(walker): + """Pretty printer for tree walkers + + Takes a TreeWalker instance and pretty prints the output of walking the tree. + + :arg walker: a TreeWalker instance + + """ + output = [] + indent = 0 + for token in concatenateCharacterTokens(walker): + type = token["type"] + if type in ("StartTag", "EmptyTag"): + # tag name + if token["namespace"] and token["namespace"] != constants.namespaces["html"]: + if token["namespace"] in constants.prefixes: + ns = constants.prefixes[token["namespace"]] + else: + ns = token["namespace"] + name = "%s %s" % (ns, token["name"]) + else: + name = token["name"] + output.append("%s<%s>" % (" " * indent, name)) + indent += 2 + # attributes (sorted for consistent ordering) + attrs = token["data"] + for (namespace, localname), value in sorted(attrs.items()): + if namespace: + if namespace in constants.prefixes: + ns = constants.prefixes[namespace] + else: + ns = namespace + name = "%s %s" % (ns, localname) + else: + name = localname + output.append("%s%s=\"%s\"" % (" " * indent, name, value)) + # self-closing + if type == "EmptyTag": + indent -= 2 + + elif type == "EndTag": + indent -= 2 + + elif type == "Comment": + output.append("%s<!-- %s -->" % (" " * indent, token["data"])) + + elif type == "Doctype": + if token["name"]: + if token["publicId"]: + output.append("""%s<!DOCTYPE %s "%s" "%s">""" % + (" " * indent, + token["name"], + token["publicId"], + token["systemId"] if token["systemId"] else "")) + elif token["systemId"]: + output.append("""%s<!DOCTYPE %s "" "%s">""" % + (" " * indent, + token["name"], + token["systemId"])) + else: + output.append("%s<!DOCTYPE %s>" % (" " * indent, + token["name"])) + else: + output.append("%s<!DOCTYPE >" % (" " * indent,)) + + elif type == "Characters": + output.append("%s\"%s\"" % (" " * indent, token["data"])) + + elif type == "SpaceCharacters": + assert False, "concatenateCharacterTokens should have got rid of all Space tokens" + + else: + raise ValueError("Unknown token type, %s" % type) + + return "\n".join(output) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..97406548d158ec635c28f6d1ae7e244debbff561 GIT binary patch literal 4006 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/base.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/base.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..42dd3191d6b7e07887c43ff83a36b0ba87d2d478 GIT binary patch literal 7002 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 bK^Z;-a0J>pqRprV^p*Uex6ItPl}G*qw;aa2 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/dom.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/dom.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..17cad82307bbb6a5e751bc899e4a0c560181737c GIT binary patch literal 1731 zcma)6QEwAR5Z=8z`_9IO5ZsUuD)j-Was@FhqAe0a1jnGX<%|-ip{us1vv)5!XYXuw z&nAh&6SPnL5y@j;`!o6z_O*TCy-$7W%$e8_Rfv^lZgysF=G)nseNe5I39R3iyFdO? zAmlIHoGu51`#|~uFitp?B%zEZ7PAtY*%Wn_bdmxqfNXO|7894blsqE5z>BX4FABHs zy|h`0yPKr$y@oiXZkr2XR}bVU6G5B|2P!ijkH@i&2dSAGrEzb-MIhr$s8H%UHI5I8 z*A)MSO*hn{hk;I)1;TwGeI1w}jB>&(PPz4pFdJdP*O>rf1@3YW_C;O-KxI?zC?U2( zxhGT)<KV($7lE2U`X69Nv`;eHxArXcNoMyQ*cX6`KyKu0p4vU|DMi*^QQZTtGFZ<= z*3?>ozyFBI3v2(ItO~aC#}`h>OS(pW`uc@^M33i=>=O!--M^@Q1wMadp$v2>vhI>+ zKTmX=z_&2bY!k>+gIE`VJ_3Jwyl_II!Zhb)$oVJuES|x#1W2#sNdE@wazr;V(pB&x zh?o<o4fX3EGcSe8cMgU^L2nQ?zt(PUJ#P7(p!36%R^YeSTFOO(3kFmfCk+!}yy2)T z<K8+qo<7i-NY*(kby`n5`7dm~xwhI_4K`cN&U)LQ=o~b&66X6plq10^t?ycSD$HUW z8SBiH!z@#A7aB(!XHOhxHn$_P)l((539BFiJq&wdYh&FM#(A)k9P~ozgN3<o;+p(y zxvIJw>gH}NIR?<I(riDTWp>}}Sao`MM8p=R+lL#gkEZ_2JJlO^%m3DIZ~Jw}I9kXE ziUaXY0S^KA@$)-Tm!W?D9yEq39*3D|j6>Ck29gV<8_8~?_xUimb9kqJ^ZBiaAL=h} zjnx<X*<o@M)=t{!G=}l;Mx5#_l=8;yue!T?qwWqWa|*^H<pb5&%@TQA#@$8+-Tpl9 zcHQ8EWMz0@&O-(9+-o8WW2s93M_&U*Xoc3Sd0Me5)S)$6rbXD-K#Q6RSUmf1X*ND9 z@5Y%<6HXP5Zaz&oR@h~e{-UfL#Y$&+?dz7h1Xfi;hDDjMMUYGtVn3XEB08N9D?MC% z7r@Nv!}6a?#eTLKL$jtk?*ot*Y3BOrTL{jUVCMB<5X!?)i8Q~0_aVR%Jehia_7;FM zC73z+b=P=7fb$RprW^#xfR7}~l^}RF3gyJ2mLQnAf@~StRb;aZ$R)f5<pD#|xj?;T z&-UzG>*Grr1korPDTuG|a+Hk>-%{i5CvpYaEq_D|nLHT_{vh2Dy^+%KSj=uQkN1D+ Tjdyo~{~mUe#!jkP(2Dkd2mZ9N literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/etree.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/etree.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..713c0cec95587939ae0b4d88cbb16d6e10581866 GIT binary patch literal 3538 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/etree_lxml.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/etree_lxml.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..19b3a58979b430c8d5f6aecabeb82e868d82eda7 GIT binary patch literal 6647 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 LTPl{arRV++97}9* literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/genshi.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/genshi.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..22fc90eca384ed7e9abd6ca092d00cf292445242 GIT binary patch literal 1905 zcmZ`(UvC>l5Z~Q9-<{8A$8nvsq2-TwsAQ?F1EqyZRn?G02t?e{SWP(<9cS-3x%mD# zdu!K?&IqY}L{&dRBk{s}#Yf;n>?==w;R7Iqn7L~TLa?Wuot>GT{oT%=PwRD?!1&?( z;9;do$gj9L9Xc?#VP?;OaKdRsV(QYExh&RPjiQW2dR%cU1+M{bxJGQcW^B1uTy?9l z?b?M-2VKpr#g6O5b+;Zj+(x|QF2zl^3Hk~*qUE^dwtzRe6`hIOZaZFaS19?6@G7^T z5^e{r!__C6yUJ_3q~p8-Or)c!C4Z2m(NqRr7*A3mmBqtZn1yMgn$sj4rabVXPzJ(} zvJO?1uX=tQbSkQ{+uyj?SK4-OOVuCjeChQzcD8r#ZftHVbL-A#|LeQkO7Cw!=ywcd z6}Db)R~cZAYps-QZf*28R279K%kF-z%*{JHJKMefD~brI(g%JPykfXv%9*7h-;RPf zNMxq$1i)kye;8y#{GZc-#<yW+7k~uBrJT5oQ_h|eSK}JjVbysB-oa3IUj)IPAB_Vs z#2ay7<SH=HX~uzYvY_+pIXNU-<eN(imV?J}ReUsmD<>~#PIGp`Kw~eoT)R&wIl8z< za<-sH4y>i^x2Lw8{LA*<9{2|=v<E+^OMs&cnT~@b>*z|)f@q|yi3nz4I?Yrin8B~B zN@4I55pM&!-}CN7gfm|T-I*`Cqcq}y$hz@Cclg1?yK#KuaQ)HM5kJnZU!92$=khpS zhq0e@``t-6xf~{$^rPtVwT}k}<LO`@g~jyXDxQk&fsCVTQ8?%#wnxQNW!-(icMx8g zJXV(HVS;#G9iOWOgfN{t)S@kFQ%l43_{`tWeC5=BsG%*4222ZP@!sD<6mt4dTWAY? zQOPw)#!UQ@>krw&SeUtSNEa4Rwy1_=Vb4FwO?dfr(AE}?)bg6tpD@wSo!riAhYThi zv76**9VMLPwQ>h>smcncYv}!DZb@Toh?ny(Af9Gk%`G_195Q*4GtSnCw8mP&YilGo z#@dNqM7y5Xi)jD2N0KI-td=KFiX2FO2J9Ai|1;MM%sOIzbE}s9R@`ceKj5T|Cr=o9 zOTL41wK026#VTl=TtA_Od<61(A-^?uLDN7D;BXeNaXhC-mjKBvuv;qZ?nA~lbNv}9 z&R+!ivRslac}BM7id-F;V*_rPBo25xn``AgMK0<+rDNCymV{Ua(m5v#SX4Dihkk^G zr>bwtPub8iFpZL7Ah2@83X(Pu*9zi^eBAf<g;{LDN=Vo$1F{RnO%N+{n8sMt0{bac zK`@sB8Y(DwI+TwmfxrY2H6#uaOg4duBbI<DbDE5k^ik4jh&2?RN1>j88>NrKge#r< z(pS_|n)LTw)0a|&gA7dIPsICR?Jf_~WEKb+aPL%0$BNDbc9EjcO7aeF&jG<ZvfDri z<~e)@d^&BwuEm<H4K>h$&tWZA>e{r)Y}$a?EGTjf%CzI<e^f_V`aS5eP*{l0^OWs* zamuF=@{Z>nP0I*)o_H5-FTnf*Aoc`Npj-tGUn|3o1_&DhCB4pB^f;QzsQ`}x+oix- z6lmtwUYGVT6|aMdfiI$01_9$z#OZ&-QO1-AYzC?d?~17*vmznN)Ic2n1zA})%Rjw^ SnU^8>Hgo6&`W|ywQ~L`VX3x6- literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/base.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/base.py new file mode 100644 index 0000000..80c474c --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/base.py @@ -0,0 +1,252 @@ +from __future__ import absolute_import, division, unicode_literals + +from xml.dom import Node +from ..constants import namespaces, voidElements, spaceCharacters + +__all__ = ["DOCUMENT", "DOCTYPE", "TEXT", "ELEMENT", "COMMENT", "ENTITY", "UNKNOWN", + "TreeWalker", "NonRecursiveTreeWalker"] + +DOCUMENT = Node.DOCUMENT_NODE +DOCTYPE = Node.DOCUMENT_TYPE_NODE +TEXT = Node.TEXT_NODE +ELEMENT = Node.ELEMENT_NODE +COMMENT = Node.COMMENT_NODE +ENTITY = Node.ENTITY_NODE +UNKNOWN = "<#UNKNOWN#>" + +spaceCharacters = "".join(spaceCharacters) + + +class TreeWalker(object): + """Walks a tree yielding tokens + + Tokens are dicts that all have a ``type`` field specifying the type of the + token. + + """ + def __init__(self, tree): + """Creates a TreeWalker + + :arg tree: the tree to walk + + """ + self.tree = tree + + def __iter__(self): + raise NotImplementedError + + def error(self, msg): + """Generates an error token with the given message + + :arg msg: the error message + + :returns: SerializeError token + + """ + return {"type": "SerializeError", "data": msg} + + def emptyTag(self, namespace, name, attrs, hasChildren=False): + """Generates an EmptyTag token + + :arg namespace: the namespace of the token--can be ``None`` + + :arg name: the name of the element + + :arg attrs: the attributes of the element as a dict + + :arg hasChildren: whether or not to yield a SerializationError because + this tag shouldn't have children + + :returns: EmptyTag token + + """ + yield {"type": "EmptyTag", "name": name, + "namespace": namespace, + "data": attrs} + if hasChildren: + yield self.error("Void element has children") + + def startTag(self, namespace, name, attrs): + """Generates a StartTag token + + :arg namespace: the namespace of the token--can be ``None`` + + :arg name: the name of the element + + :arg attrs: the attributes of the element as a dict + + :returns: StartTag token + + """ + return {"type": "StartTag", + "name": name, + "namespace": namespace, + "data": attrs} + + def endTag(self, namespace, name): + """Generates an EndTag token + + :arg namespace: the namespace of the token--can be ``None`` + + :arg name: the name of the element + + :returns: EndTag token + + """ + return {"type": "EndTag", + "name": name, + "namespace": namespace} + + def text(self, data): + """Generates SpaceCharacters and Characters tokens + + Depending on what's in the data, this generates one or more + ``SpaceCharacters`` and ``Characters`` tokens. + + For example: + + >>> from html5lib.treewalkers.base import TreeWalker + >>> # Give it an empty tree just so it instantiates + >>> walker = TreeWalker([]) + >>> list(walker.text('')) + [] + >>> list(walker.text(' ')) + [{u'data': ' ', u'type': u'SpaceCharacters'}] + >>> list(walker.text(' abc ')) # doctest: +NORMALIZE_WHITESPACE + [{u'data': ' ', u'type': u'SpaceCharacters'}, + {u'data': u'abc', u'type': u'Characters'}, + {u'data': u' ', u'type': u'SpaceCharacters'}] + + :arg data: the text data + + :returns: one or more ``SpaceCharacters`` and ``Characters`` tokens + + """ + data = data + middle = data.lstrip(spaceCharacters) + left = data[:len(data) - len(middle)] + if left: + yield {"type": "SpaceCharacters", "data": left} + data = middle + middle = data.rstrip(spaceCharacters) + right = data[len(middle):] + if middle: + yield {"type": "Characters", "data": middle} + if right: + yield {"type": "SpaceCharacters", "data": right} + + def comment(self, data): + """Generates a Comment token + + :arg data: the comment + + :returns: Comment token + + """ + return {"type": "Comment", "data": data} + + def doctype(self, name, publicId=None, systemId=None): + """Generates a Doctype token + + :arg name: + + :arg publicId: + + :arg systemId: + + :returns: the Doctype token + + """ + return {"type": "Doctype", + "name": name, + "publicId": publicId, + "systemId": systemId} + + def entity(self, name): + """Generates an Entity token + + :arg name: the entity name + + :returns: an Entity token + + """ + return {"type": "Entity", "name": name} + + def unknown(self, nodeType): + """Handles unknown node types""" + return self.error("Unknown node type: " + nodeType) + + +class NonRecursiveTreeWalker(TreeWalker): + def getNodeDetails(self, node): + raise NotImplementedError + + def getFirstChild(self, node): + raise NotImplementedError + + def getNextSibling(self, node): + raise NotImplementedError + + def getParentNode(self, node): + raise NotImplementedError + + def __iter__(self): + currentNode = self.tree + while currentNode is not None: + details = self.getNodeDetails(currentNode) + type, details = details[0], details[1:] + hasChildren = False + + if type == DOCTYPE: + yield self.doctype(*details) + + elif type == TEXT: + for token in self.text(*details): + yield token + + elif type == ELEMENT: + namespace, name, attributes, hasChildren = details + if (not namespace or namespace == namespaces["html"]) and name in voidElements: + for token in self.emptyTag(namespace, name, attributes, + hasChildren): + yield token + hasChildren = False + else: + yield self.startTag(namespace, name, attributes) + + elif type == COMMENT: + yield self.comment(details[0]) + + elif type == ENTITY: + yield self.entity(details[0]) + + elif type == DOCUMENT: + hasChildren = True + + else: + yield self.unknown(details[0]) + + if hasChildren: + firstChild = self.getFirstChild(currentNode) + else: + firstChild = None + + if firstChild is not None: + currentNode = firstChild + else: + while currentNode is not None: + details = self.getNodeDetails(currentNode) + type, details = details[0], details[1:] + if type == ELEMENT: + namespace, name, attributes, hasChildren = details + if (namespace and namespace != namespaces["html"]) or name not in voidElements: + yield self.endTag(namespace, name) + if self.tree is currentNode: + currentNode = None + break + nextSibling = self.getNextSibling(currentNode) + if nextSibling is not None: + currentNode = nextSibling + break + else: + currentNode = self.getParentNode(currentNode) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/dom.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/dom.py new file mode 100644 index 0000000..b0c89b0 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/dom.py @@ -0,0 +1,43 @@ +from __future__ import absolute_import, division, unicode_literals + +from xml.dom import Node + +from . import base + + +class TreeWalker(base.NonRecursiveTreeWalker): + def getNodeDetails(self, node): + if node.nodeType == Node.DOCUMENT_TYPE_NODE: + return base.DOCTYPE, node.name, node.publicId, node.systemId + + elif node.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE): + return base.TEXT, node.nodeValue + + elif node.nodeType == Node.ELEMENT_NODE: + attrs = {} + for attr in list(node.attributes.keys()): + attr = node.getAttributeNode(attr) + if attr.namespaceURI: + attrs[(attr.namespaceURI, attr.localName)] = attr.value + else: + attrs[(None, attr.name)] = attr.value + return (base.ELEMENT, node.namespaceURI, node.nodeName, + attrs, node.hasChildNodes()) + + elif node.nodeType == Node.COMMENT_NODE: + return base.COMMENT, node.nodeValue + + elif node.nodeType in (Node.DOCUMENT_NODE, Node.DOCUMENT_FRAGMENT_NODE): + return (base.DOCUMENT,) + + else: + return base.UNKNOWN, node.nodeType + + def getFirstChild(self, node): + return node.firstChild + + def getNextSibling(self, node): + return node.nextSibling + + def getParentNode(self, node): + return node.parentNode diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/etree.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/etree.py new file mode 100644 index 0000000..95fc0c1 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/etree.py @@ -0,0 +1,130 @@ +from __future__ import absolute_import, division, unicode_literals + +from collections import OrderedDict +import re + +from pip._vendor.six import string_types + +from . import base +from .._utils import moduleFactoryFactory + +tag_regexp = re.compile("{([^}]*)}(.*)") + + +def getETreeBuilder(ElementTreeImplementation): + ElementTree = ElementTreeImplementation + ElementTreeCommentType = ElementTree.Comment("asd").tag + + class TreeWalker(base.NonRecursiveTreeWalker): # pylint:disable=unused-variable + """Given the particular ElementTree representation, this implementation, + to avoid using recursion, returns "nodes" as tuples with the following + content: + + 1. The current element + + 2. The index of the element relative to its parent + + 3. A stack of ancestor elements + + 4. A flag "text", "tail" or None to indicate if the current node is a + text node; either the text or tail of the current element (1) + """ + def getNodeDetails(self, node): + if isinstance(node, tuple): # It might be the root Element + elt, _, _, flag = node + if flag in ("text", "tail"): + return base.TEXT, getattr(elt, flag) + else: + node = elt + + if not(hasattr(node, "tag")): + node = node.getroot() + + if node.tag in ("DOCUMENT_ROOT", "DOCUMENT_FRAGMENT"): + return (base.DOCUMENT,) + + elif node.tag == "<!DOCTYPE>": + return (base.DOCTYPE, node.text, + node.get("publicId"), node.get("systemId")) + + elif node.tag == ElementTreeCommentType: + return base.COMMENT, node.text + + else: + assert isinstance(node.tag, string_types), type(node.tag) + # This is assumed to be an ordinary element + match = tag_regexp.match(node.tag) + if match: + namespace, tag = match.groups() + else: + namespace = None + tag = node.tag + attrs = OrderedDict() + for name, value in list(node.attrib.items()): + match = tag_regexp.match(name) + if match: + attrs[(match.group(1), match.group(2))] = value + else: + attrs[(None, name)] = value + return (base.ELEMENT, namespace, tag, + attrs, len(node) or node.text) + + def getFirstChild(self, node): + if isinstance(node, tuple): + element, key, parents, flag = node + else: + element, key, parents, flag = node, None, [], None + + if flag in ("text", "tail"): + return None + else: + if element.text: + return element, key, parents, "text" + elif len(element): + parents.append(element) + return element[0], 0, parents, None + else: + return None + + def getNextSibling(self, node): + if isinstance(node, tuple): + element, key, parents, flag = node + else: + return None + + if flag == "text": + if len(element): + parents.append(element) + return element[0], 0, parents, None + else: + return None + else: + if element.tail and flag != "tail": + return element, key, parents, "tail" + elif key < len(parents[-1]) - 1: + return parents[-1][key + 1], key + 1, parents, None + else: + return None + + def getParentNode(self, node): + if isinstance(node, tuple): + element, key, parents, flag = node + else: + return None + + if flag == "text": + if not parents: + return element + else: + return element, key, parents, None + else: + parent = parents.pop() + if not parents: + return parent + else: + assert list(parents[-1]).count(parent) == 1 + return parent, list(parents[-1]).index(parent), parents, None + + return locals() + +getETreeModule = moduleFactoryFactory(getETreeBuilder) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/etree_lxml.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/etree_lxml.py new file mode 100644 index 0000000..e81ddf3 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/etree_lxml.py @@ -0,0 +1,213 @@ +from __future__ import absolute_import, division, unicode_literals +from pip._vendor.six import text_type + +from lxml import etree +from ..treebuilders.etree import tag_regexp + +from . import base + +from .. import _ihatexml + + +def ensure_str(s): + if s is None: + return None + elif isinstance(s, text_type): + return s + else: + return s.decode("ascii", "strict") + + +class Root(object): + def __init__(self, et): + self.elementtree = et + self.children = [] + + try: + if et.docinfo.internalDTD: + self.children.append(Doctype(self, + ensure_str(et.docinfo.root_name), + ensure_str(et.docinfo.public_id), + ensure_str(et.docinfo.system_url))) + except AttributeError: + pass + + try: + node = et.getroot() + except AttributeError: + node = et + + while node.getprevious() is not None: + node = node.getprevious() + while node is not None: + self.children.append(node) + node = node.getnext() + + self.text = None + self.tail = None + + def __getitem__(self, key): + return self.children[key] + + def getnext(self): + return None + + def __len__(self): + return 1 + + +class Doctype(object): + def __init__(self, root_node, name, public_id, system_id): + self.root_node = root_node + self.name = name + self.public_id = public_id + self.system_id = system_id + + self.text = None + self.tail = None + + def getnext(self): + return self.root_node.children[1] + + +class FragmentRoot(Root): + def __init__(self, children): + self.children = [FragmentWrapper(self, child) for child in children] + self.text = self.tail = None + + def getnext(self): + return None + + +class FragmentWrapper(object): + def __init__(self, fragment_root, obj): + self.root_node = fragment_root + self.obj = obj + if hasattr(self.obj, 'text'): + self.text = ensure_str(self.obj.text) + else: + self.text = None + if hasattr(self.obj, 'tail'): + self.tail = ensure_str(self.obj.tail) + else: + self.tail = None + + def __getattr__(self, name): + return getattr(self.obj, name) + + def getnext(self): + siblings = self.root_node.children + idx = siblings.index(self) + if idx < len(siblings) - 1: + return siblings[idx + 1] + else: + return None + + def __getitem__(self, key): + return self.obj[key] + + def __bool__(self): + return bool(self.obj) + + def getparent(self): + return None + + def __str__(self): + return str(self.obj) + + def __unicode__(self): + return str(self.obj) + + def __len__(self): + return len(self.obj) + + +class TreeWalker(base.NonRecursiveTreeWalker): + def __init__(self, tree): + # pylint:disable=redefined-variable-type + if isinstance(tree, list): + self.fragmentChildren = set(tree) + tree = FragmentRoot(tree) + else: + self.fragmentChildren = set() + tree = Root(tree) + base.NonRecursiveTreeWalker.__init__(self, tree) + self.filter = _ihatexml.InfosetFilter() + + def getNodeDetails(self, node): + if isinstance(node, tuple): # Text node + node, key = node + assert key in ("text", "tail"), "Text nodes are text or tail, found %s" % key + return base.TEXT, ensure_str(getattr(node, key)) + + elif isinstance(node, Root): + return (base.DOCUMENT,) + + elif isinstance(node, Doctype): + return base.DOCTYPE, node.name, node.public_id, node.system_id + + elif isinstance(node, FragmentWrapper) and not hasattr(node, "tag"): + return base.TEXT, ensure_str(node.obj) + + elif node.tag == etree.Comment: + return base.COMMENT, ensure_str(node.text) + + elif node.tag == etree.Entity: + return base.ENTITY, ensure_str(node.text)[1:-1] # strip &; + + else: + # This is assumed to be an ordinary element + match = tag_regexp.match(ensure_str(node.tag)) + if match: + namespace, tag = match.groups() + else: + namespace = None + tag = ensure_str(node.tag) + attrs = {} + for name, value in list(node.attrib.items()): + name = ensure_str(name) + value = ensure_str(value) + match = tag_regexp.match(name) + if match: + attrs[(match.group(1), match.group(2))] = value + else: + attrs[(None, name)] = value + return (base.ELEMENT, namespace, self.filter.fromXmlName(tag), + attrs, len(node) > 0 or node.text) + + def getFirstChild(self, node): + assert not isinstance(node, tuple), "Text nodes have no children" + + assert len(node) or node.text, "Node has no children" + if node.text: + return (node, "text") + else: + return node[0] + + def getNextSibling(self, node): + if isinstance(node, tuple): # Text node + node, key = node + assert key in ("text", "tail"), "Text nodes are text or tail, found %s" % key + if key == "text": + # XXX: we cannot use a "bool(node) and node[0] or None" construct here + # because node[0] might evaluate to False if it has no child element + if len(node): + return node[0] + else: + return None + else: # tail + return node.getnext() + + return (node, "tail") if node.tail else node.getnext() + + def getParentNode(self, node): + if isinstance(node, tuple): # Text node + node, key = node + assert key in ("text", "tail"), "Text nodes are text or tail, found %s" % key + if key == "text": + return node + # else: fallback to "normal" processing + elif node in self.fragmentChildren: + return None + + return node.getparent() diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/genshi.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/genshi.py new file mode 100644 index 0000000..7483be2 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/genshi.py @@ -0,0 +1,69 @@ +from __future__ import absolute_import, division, unicode_literals + +from genshi.core import QName +from genshi.core import START, END, XML_NAMESPACE, DOCTYPE, TEXT +from genshi.core import START_NS, END_NS, START_CDATA, END_CDATA, PI, COMMENT + +from . import base + +from ..constants import voidElements, namespaces + + +class TreeWalker(base.TreeWalker): + def __iter__(self): + # Buffer the events so we can pass in the following one + previous = None + for event in self.tree: + if previous is not None: + for token in self.tokens(previous, event): + yield token + previous = event + + # Don't forget the final event! + if previous is not None: + for token in self.tokens(previous, None): + yield token + + def tokens(self, event, next): + kind, data, _ = event + if kind == START: + tag, attribs = data + name = tag.localname + namespace = tag.namespace + converted_attribs = {} + for k, v in attribs: + if isinstance(k, QName): + converted_attribs[(k.namespace, k.localname)] = v + else: + converted_attribs[(None, k)] = v + + if namespace == namespaces["html"] and name in voidElements: + for token in self.emptyTag(namespace, name, converted_attribs, + not next or next[0] != END or + next[1] != tag): + yield token + else: + yield self.startTag(namespace, name, converted_attribs) + + elif kind == END: + name = data.localname + namespace = data.namespace + if namespace != namespaces["html"] or name not in voidElements: + yield self.endTag(namespace, name) + + elif kind == COMMENT: + yield self.comment(data) + + elif kind == TEXT: + for token in self.text(data): + yield token + + elif kind == DOCTYPE: + yield self.doctype(*data) + + elif kind in (XML_NAMESPACE, DOCTYPE, START_NS, END_NS, + START_CDATA, END_CDATA, PI): + pass + + else: + yield self.unknown(kind) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/idna/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/idna/__init__.py new file mode 100644 index 0000000..847bf93 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/idna/__init__.py @@ -0,0 +1,2 @@ +from .package_data import __version__ +from .core import * diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d78284a321e213c259b2e82b2d0aaffb47363b24 GIT binary patch literal 266 zcmXv|(Mkg`5KOK`q_*#ZUvNU3+G0yZMEroh*e4N|+$FuH%_Sj8PrYyONBpIG^~qoG z$xXq5*`3*iVV*{#0YQ9T6|Z-=zmxe#hT;(!E^!DVs3tXip)~1CXB#4V&m`~vP<-dK zy8vjU56T(<wDfwN_qw6u<$+fc1drUO#I9djFTaRCLvtFxhB>bq9wlqIXIrZU=CFFl z${Po(cD0|r&9|Zri+ST`@3F0?h{~`HbIOgC36X0(zFii(!?CE+@kFd+g!N1b!x?}w XDgsR0M|XZ-TXEF#AvF)F)R6uGJUB=A literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/codec.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/codec.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cb85ec4bc9724110a58014b57b1b0a4db26cd44b GIT binary patch literal 3073 zcmc(h&65;06u>+EJ-xHD%ZMN!;sO_kDs~o7kt)Fzma_IT2T`eNrMh}MnW2~No+0U3 zVC<nRh9mkn%pUdZQU8&YH%^?md(rpOJ3IS@pdQRrUMDY^Bro~Bmt3En^)yJ&PON?V zysBx>u`)>(6qX^2F$k(rl4vRMNvivLYWPNK`ethR7SX6qjl}kC^>uuQIb)Zao5Zht zu2GBHPc>>Yd)*ruz6TnIx}b4EGXt6`Xe!hLjR%@p(9}RPL#v>vGStnDOn(k^v$O`f zn$pdKZl2E3`KOwHh#I%F#-SGkmf5hR&9bOVnY1Y@zhM%tu|(Sa@>^M5X?=E+^Dch@ zf6!Weuv`0P@%i^pUjF*y%ilKdM5vx50}9KK#R3SX`Gjh|4km!fPl<0(FqB$QGN}!V zs7UJu%pFNv<UEe@2>*@=zb51xki{a1LZ{@O!H?vydt*}Qn`A_ukb;O)XicscP|ppN zZ5;+STf74Q8Z3O3iGHuw<vF7Z42@X08)h_#v(Cbq@0NyV8oJcD16>;?x8Wo0c9*AN z&ULI93CkLWGzClA(xhP?!gk>(;wO#ILytf1HG4eX2y@ol2zj&JO(^4{nci(i7ka^! z!Ikx;2bbD(AU?XZ!7o0{2k8=|PS*Ug*^7JU<4ojXlAQnW^4i^d{k0A%RSq^-M!UQj z(=2S_u|$i#M`}%ImQWDtE~)7zG4(-JZQ^2ikpIUXa$L~PZR9hkz*FRiOT*x^SgxU% zLxG!DibGh!o^L^Zg=Hn0tp-u2I{8@A4T3C8SrAAs2+}U?Cs?iq!To-ilr3u0%9Tv# zR3$aB3zOpU3#84}J&&U%g1nuOgk{L$Fo<oW3Dv=u4CPCvtgmJfXDQ3zIBzO{;t`IB z2~P}TgJSs?D7=p4F>t&|h9)(KR$=n53viiZnpmMW)~R(>%j$(8l>VxQJ+P&t4Q=WS zorf0-b49yzZs->F*vzfM9l>ZsD;)l$fLL-_8#;xP+o;F#eR><>&DbgIO;T7#VHDMB zm8}KTlt)$G+@q#6sM3o+AxW~R_~0t)xXRZQByv9JXE7ok&~7dQ&ZH%JNt{bN?DfD4 zIPRmONSf>2IBQh)uq3T^oP`juRJ;<hn)5J5561ze&6(&YIrwlqfT2~NJ@m<1u-0$4 z84pSiIt3GoB@h~!xR^)4(V(WXZetByk9ee}bn`}yRLS7<ehe0OkKKYeQ%8f4c8)~x zGbj#X^KEE&7qUPCUBa>cpU7NM5&jiq{tlzRj?4mL>`3Py<mT8a8O=@tNf331D*94$ zqyuSWY*9-Qtcc~0fm#O$PN<~_cD4vsdPVSKY*7TedkA)NcL%{g1HqLof-BnuKLdiT zvA2uhO0kz<@81wCtx!a9%#XtElw2Rd5{8Tt<(VBQd$CXvJ&Txhwy5UsVAo?Hqyd*4 zKaN!l2MTF^0!sUc<|nZokDeoo{5=#4C{Cl8vVtLON^cn@KLwrm7{oTchDWM~3#@vI z*}tJ!-$(HlGTRhSBJn<o--iiztZW)#&qBjB$P<dOzKddv2+P<3Z;EMrg<D*g)mu4d zVS1a#IpZz3M)vs5bStJ4Hei?zj<@ADSpTOJe!)Vx$lq|nb1=dBjtQ~8YeKvMZeWK6 z5V^KaD9QDawr(g1F*>(%;GF6|IAFEWk|y5!4M&=IhfQxVS&ygJOc|^AE?s##TvmZJ z*tQ31+a@*8fKBk`vekn^$clP4tY+}y!AoyCkBT(>Eb4IcI2v@&*~*y?gNZtD?eRw` zbP{+98bm~$*znWUk6!{^qb|*;%Xb)4#&zWh`0(NvKu8_JzY}%SUYxMfb8uzy_;nSZ w8QmXW)mjhiu!ZhkJ8(4z8smOaz96n4kODzF2@xOO1bY2Q{dB!?*f?zb1w4P1n*aa+ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/compat.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0af6b1535101615657503fe9025d015d857566c5 GIT binary patch literal 626 zcma)4O;6iE5Z!g+#Hq@u$6kC50yYKp0|_B0aLC0M!lkN&9M1x7*So9nCeWy-!jV71 zU-Fd;{R=%Y<0w*vRH-A)yjkz;)0-K8UR!%5$nM`xzdjK@@?m8WB?sj71_clxjhHM^ z5=PLu6JH|eLQL3!9`p&jkerI);J2hFL)pmnf-^QoW;`OV6AD566t|M9Wk!`fZ3_pQ zve@KPZ5{;1RP@IvkL5fMTFrA*7tVmjT2)u7c<0Y|7rWm^*E<)ms6Xt?ar-7Lsu9_x zRTJe)zggNk<i>2i|2Vz+KAT?h$JWp1+JZw>g3VRoDxZff|D)+o+~Mibc-&=?tX4?u zQ~d8PKrg#MW@tNDh8`W8!Ni@}k_(t~#XtBb|7*GlH1}KiOM;+DMcHCwe4HJo+oRE^ z6r8S8>q0sUr73Hj+Pu;pwNE{|;0kAGnr|`}#+5g^(l%%~L3GHAsb7jqR<HSoSZQMg t*)VRpg+txMEWKz4f~*?(`Y#?{7`B}zdzFKk(fhphcH4<eqNI~_o&hiCh$8?1 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/core.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/core.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2c7e43fe7fc88757156dcbe5772d0d05c63fab5a GIT binary patch literal 9158 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 X@GR1N&drS%N;xk#mOE4!D?I%F^G;gE literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2f2faf7a0a685fbe4dbf6679843722e4d9090881 GIT binary patch literal 20590 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 Xfp6}C|GRr&kT3cM=j%V#M)&&<bC5d} literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..333490e83abaaad768612ec7f0d0a84a7e15fd05 GIT binary patch literal 1806 zcmZuxNpIXX6ecNYJdtf6OIzDWkrFOYcmQX{3)&)uvmg!9OW*=YfC5GeStD|0RBI@i zq{a(0$YI)BenfKY59&qNp8OYjao?l7q(LcgdwiR|w>({33<->Pcl&StY7z1`UM>fN z!xNZh0~SH{h@gUHbdL&8_`j1qCIZod-4k=74ZAOHh!FNbuverrAK##agg>Pdsd&t@ z)L5Pmc&e-%N^REpI2MwZ1rparc_9a7mYsBf)r{jT<Ek9@rN-ARS3|B#WkR?lxiT^- zEvWrSSCWs5(n=84ve42<Wn-J>3dQY6@<Fc0;o6$9v9_D*Tq?2IS?A4t%iXs+yxZ+| zy8QJB{Z-}&jHBpbDUDOLdK4Re%rDf3sdCS`PKT+AGxvj!SHUN4)3M|~uVwjg?Q7?E zr_&A307J5y03>bz)?^Omk1)+USS+c?j85s0Oqrll?^s)ESw&~?JtM#Nr+(!NwnQ4* z0nsliTKOvkSER2H!IsGZ(=QJ10nI~N^YRB<A=98@?>*~Rf$%^k5ES{B$c%lU6!@mz z;k{po1+E!|*!l5YaP;LRl>ZYx4p=~>B%q@bi7@L}4W;=Z<S;Ifjy4>$(Z&_lQ3HO2 z=p)?g+?2@(fQ;>b&~#cZQ-#M`a(NslHah{X+(-z+wVVrTl=7X2K;FUF!UY1(O%8EL zyP;F|(z(~DQb{hPz+W(_8fMptbdeE!XNPZZ@d|Z;iz>IsYs(^&rt7qwox?c8U}{`C zt-57$ZKbFKhePdUQq`@vC_qKM7y(FNGHTuerwL>NEQ+X}Z$u-!)vX4{I?Q5tJJP9@ zHBIZqq|_R+x>4~b(Ko^DKY6dv=_IzYH;Hv`kY@rat2Z9?lFcG|aQfi4jic>>I5ppG zPxRKYJsoer7^>duUXd2}Qw7jv+5K<7?~e}3{t$_7Mo_XM*S%DzxCc>aT<R7l^_{C* zG|>6jxr`0Od;tq-x2X@`ZF-X~Q$|0dU(z<yx8WthUV;O6oG$Md;7~zVc?4PfltA9G z-7^j}_j4Uq2QIX=2i`bRv)n?CHY{JkG)^&f_p9Q<ka#ei5d;d2JjRthAp>kq-mbm_ z^bEPq-=4qqE^N}8>Q78T^n|>Q-YQ638eM|()t_NC`!Jo+Q#fEn3p!&{X6bvV<cfV@ zQx7VW9{76KdQFusL*>rs8#eW!M*Rv@c;tZU=T!hTzN>snlrOwjq{8ZjUI5fdBYP#+ zLOH1X3GxXaelIwE_)J=<$Ekwk9`Jn#TeQyy5N(59Gv_%xT=d2!y4bk(o8x}hCACIy zUO(>y4&1ucPoeSJdcN7COb)C@1T^-t&Rp%I5sfjeTQ0+++ADHX`^X7(kq$?;rqQSH z-nvdH=<PO6)i<D`NhlW51+NW>v`l@r0BMB@ra9Vc)pJoK@+6A%GTdF3IY%3xkmn;y em;@RVr*7|zb5UmU5qfPfcYW4o?a$j@+y57P&)Et9 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..074cfad90608b3b9b1fde88b69a229973b50c0d1 GIT binary patch literal 220 zcmZ?b<>g`kf*$Fl7*Qbo7{q}AMj*ohh>JOZL<&O`LkeRsgC<iIvyq;;pC;oi?)dn! z)S}|d{Ji-1l?+8pKviJkSCM`}QD#|UNveKXVv&AYeohKdnSO4DezIXfyk(VTmO;63 zT1r*1nQ>W>QAJ5rt^p9F=jn&&7i1RbX66-_B<AGknwlqNWS1tTg9O1CXj@)Nevy7= nN?xLVL1J=tVtQ(PN@7W(UP0w84x8Nkl+v73JCLi3ftUdRK>$3Q literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/uts46data.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/uts46data.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..13cc172442bbe3a63c30011140685eb291fad37b GIT binary patch literal 175662 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 E0QOeG?*IS* literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/idna/codec.py b/venv/lib/python3.7/site-packages/pip/_vendor/idna/codec.py new file mode 100644 index 0000000..98c65ea --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/idna/codec.py @@ -0,0 +1,118 @@ +from .core import encode, decode, alabel, ulabel, IDNAError +import codecs +import re + +_unicode_dots_re = re.compile(u'[\u002e\u3002\uff0e\uff61]') + +class Codec(codecs.Codec): + + def encode(self, data, errors='strict'): + + if errors != 'strict': + raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) + + if not data: + return "", 0 + + return encode(data), len(data) + + def decode(self, data, errors='strict'): + + if errors != 'strict': + raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) + + if not data: + return u"", 0 + + return decode(data), len(data) + +class IncrementalEncoder(codecs.BufferedIncrementalEncoder): + def _buffer_encode(self, data, errors, final): + if errors != 'strict': + raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) + + if not data: + return ("", 0) + + labels = _unicode_dots_re.split(data) + trailing_dot = u'' + if labels: + if not labels[-1]: + trailing_dot = '.' + del labels[-1] + elif not final: + # Keep potentially unfinished label until the next call + del labels[-1] + if labels: + trailing_dot = '.' + + result = [] + size = 0 + for label in labels: + result.append(alabel(label)) + if size: + size += 1 + size += len(label) + + # Join with U+002E + result = ".".join(result) + trailing_dot + size += len(trailing_dot) + return (result, size) + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + def _buffer_decode(self, data, errors, final): + if errors != 'strict': + raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) + + if not data: + return (u"", 0) + + # IDNA allows decoding to operate on Unicode strings, too. + if isinstance(data, unicode): + labels = _unicode_dots_re.split(data) + else: + # Must be ASCII string + data = str(data) + unicode(data, "ascii") + labels = data.split(".") + + trailing_dot = u'' + if labels: + if not labels[-1]: + trailing_dot = u'.' + del labels[-1] + elif not final: + # Keep potentially unfinished label until the next call + del labels[-1] + if labels: + trailing_dot = u'.' + + result = [] + size = 0 + for label in labels: + result.append(ulabel(label)) + if size: + size += 1 + size += len(label) + + result = u".".join(result) + trailing_dot + size += len(trailing_dot) + return (result, size) + + +class StreamWriter(Codec, codecs.StreamWriter): + pass + +class StreamReader(Codec, codecs.StreamReader): + pass + +def getregentry(): + return codecs.CodecInfo( + name='idna', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/idna/compat.py b/venv/lib/python3.7/site-packages/pip/_vendor/idna/compat.py new file mode 100644 index 0000000..4d47f33 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/idna/compat.py @@ -0,0 +1,12 @@ +from .core import * +from .codec import * + +def ToASCII(label): + return encode(label) + +def ToUnicode(label): + return decode(label) + +def nameprep(s): + raise NotImplementedError("IDNA 2008 does not utilise nameprep protocol") + diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/idna/core.py b/venv/lib/python3.7/site-packages/pip/_vendor/idna/core.py new file mode 100644 index 0000000..090c2c1 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/idna/core.py @@ -0,0 +1,399 @@ +from . import idnadata +import bisect +import unicodedata +import re +import sys +from .intranges import intranges_contain + +_virama_combining_class = 9 +_alabel_prefix = b'xn--' +_unicode_dots_re = re.compile(u'[\u002e\u3002\uff0e\uff61]') + +if sys.version_info[0] == 3: + unicode = str + unichr = chr + +class IDNAError(UnicodeError): + """ Base exception for all IDNA-encoding related problems """ + pass + + +class IDNABidiError(IDNAError): + """ Exception when bidirectional requirements are not satisfied """ + pass + + +class InvalidCodepoint(IDNAError): + """ Exception when a disallowed or unallocated codepoint is used """ + pass + + +class InvalidCodepointContext(IDNAError): + """ Exception when the codepoint is not valid in the context it is used """ + pass + + +def _combining_class(cp): + v = unicodedata.combining(unichr(cp)) + if v == 0: + if not unicodedata.name(unichr(cp)): + raise ValueError("Unknown character in unicodedata") + return v + +def _is_script(cp, script): + return intranges_contain(ord(cp), idnadata.scripts[script]) + +def _punycode(s): + return s.encode('punycode') + +def _unot(s): + return 'U+{0:04X}'.format(s) + + +def valid_label_length(label): + + if len(label) > 63: + return False + return True + + +def valid_string_length(label, trailing_dot): + + if len(label) > (254 if trailing_dot else 253): + return False + return True + + +def check_bidi(label, check_ltr=False): + + # Bidi rules should only be applied if string contains RTL characters + bidi_label = False + for (idx, cp) in enumerate(label, 1): + direction = unicodedata.bidirectional(cp) + if direction == '': + # String likely comes from a newer version of Unicode + raise IDNABidiError('Unknown directionality in label {0} at position {1}'.format(repr(label), idx)) + if direction in ['R', 'AL', 'AN']: + bidi_label = True + if not bidi_label and not check_ltr: + return True + + # Bidi rule 1 + direction = unicodedata.bidirectional(label[0]) + if direction in ['R', 'AL']: + rtl = True + elif direction == 'L': + rtl = False + else: + raise IDNABidiError('First codepoint in label {0} must be directionality L, R or AL'.format(repr(label))) + + valid_ending = False + number_type = False + for (idx, cp) in enumerate(label, 1): + direction = unicodedata.bidirectional(cp) + + if rtl: + # Bidi rule 2 + if not direction in ['R', 'AL', 'AN', 'EN', 'ES', 'CS', 'ET', 'ON', 'BN', 'NSM']: + raise IDNABidiError('Invalid direction for codepoint at position {0} in a right-to-left label'.format(idx)) + # Bidi rule 3 + if direction in ['R', 'AL', 'EN', 'AN']: + valid_ending = True + elif direction != 'NSM': + valid_ending = False + # Bidi rule 4 + if direction in ['AN', 'EN']: + if not number_type: + number_type = direction + else: + if number_type != direction: + raise IDNABidiError('Can not mix numeral types in a right-to-left label') + else: + # Bidi rule 5 + if not direction in ['L', 'EN', 'ES', 'CS', 'ET', 'ON', 'BN', 'NSM']: + raise IDNABidiError('Invalid direction for codepoint at position {0} in a left-to-right label'.format(idx)) + # Bidi rule 6 + if direction in ['L', 'EN']: + valid_ending = True + elif direction != 'NSM': + valid_ending = False + + if not valid_ending: + raise IDNABidiError('Label ends with illegal codepoint directionality') + + return True + + +def check_initial_combiner(label): + + if unicodedata.category(label[0])[0] == 'M': + raise IDNAError('Label begins with an illegal combining character') + return True + + +def check_hyphen_ok(label): + + if label[2:4] == '--': + raise IDNAError('Label has disallowed hyphens in 3rd and 4th position') + if label[0] == '-' or label[-1] == '-': + raise IDNAError('Label must not start or end with a hyphen') + return True + + +def check_nfc(label): + + if unicodedata.normalize('NFC', label) != label: + raise IDNAError('Label must be in Normalization Form C') + + +def valid_contextj(label, pos): + + cp_value = ord(label[pos]) + + if cp_value == 0x200c: + + if pos > 0: + if _combining_class(ord(label[pos - 1])) == _virama_combining_class: + return True + + ok = False + for i in range(pos-1, -1, -1): + joining_type = idnadata.joining_types.get(ord(label[i])) + if joining_type == ord('T'): + continue + if joining_type in [ord('L'), ord('D')]: + ok = True + break + + if not ok: + return False + + ok = False + for i in range(pos+1, len(label)): + joining_type = idnadata.joining_types.get(ord(label[i])) + if joining_type == ord('T'): + continue + if joining_type in [ord('R'), ord('D')]: + ok = True + break + return ok + + if cp_value == 0x200d: + + if pos > 0: + if _combining_class(ord(label[pos - 1])) == _virama_combining_class: + return True + return False + + else: + + return False + + +def valid_contexto(label, pos, exception=False): + + cp_value = ord(label[pos]) + + if cp_value == 0x00b7: + if 0 < pos < len(label)-1: + if ord(label[pos - 1]) == 0x006c and ord(label[pos + 1]) == 0x006c: + return True + return False + + elif cp_value == 0x0375: + if pos < len(label)-1 and len(label) > 1: + return _is_script(label[pos + 1], 'Greek') + return False + + elif cp_value == 0x05f3 or cp_value == 0x05f4: + if pos > 0: + return _is_script(label[pos - 1], 'Hebrew') + return False + + elif cp_value == 0x30fb: + for cp in label: + if cp == u'\u30fb': + continue + if _is_script(cp, 'Hiragana') or _is_script(cp, 'Katakana') or _is_script(cp, 'Han'): + return True + return False + + elif 0x660 <= cp_value <= 0x669: + for cp in label: + if 0x6f0 <= ord(cp) <= 0x06f9: + return False + return True + + elif 0x6f0 <= cp_value <= 0x6f9: + for cp in label: + if 0x660 <= ord(cp) <= 0x0669: + return False + return True + + +def check_label(label): + + if isinstance(label, (bytes, bytearray)): + label = label.decode('utf-8') + if len(label) == 0: + raise IDNAError('Empty Label') + + check_nfc(label) + check_hyphen_ok(label) + check_initial_combiner(label) + + for (pos, cp) in enumerate(label): + cp_value = ord(cp) + if intranges_contain(cp_value, idnadata.codepoint_classes['PVALID']): + continue + elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTJ']): + try: + if not valid_contextj(label, pos): + raise InvalidCodepointContext('Joiner {0} not allowed at position {1} in {2}'.format( + _unot(cp_value), pos+1, repr(label))) + except ValueError: + raise IDNAError('Unknown codepoint adjacent to joiner {0} at position {1} in {2}'.format( + _unot(cp_value), pos+1, repr(label))) + elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTO']): + if not valid_contexto(label, pos): + raise InvalidCodepointContext('Codepoint {0} not allowed at position {1} in {2}'.format(_unot(cp_value), pos+1, repr(label))) + else: + raise InvalidCodepoint('Codepoint {0} at position {1} of {2} not allowed'.format(_unot(cp_value), pos+1, repr(label))) + + check_bidi(label) + + +def alabel(label): + + try: + label = label.encode('ascii') + try: + ulabel(label) + except IDNAError: + raise IDNAError('The label {0} is not a valid A-label'.format(label)) + if not valid_label_length(label): + raise IDNAError('Label too long') + return label + except UnicodeEncodeError: + pass + + if not label: + raise IDNAError('No Input') + + label = unicode(label) + check_label(label) + label = _punycode(label) + label = _alabel_prefix + label + + if not valid_label_length(label): + raise IDNAError('Label too long') + + return label + + +def ulabel(label): + + if not isinstance(label, (bytes, bytearray)): + try: + label = label.encode('ascii') + except UnicodeEncodeError: + check_label(label) + return label + + label = label.lower() + if label.startswith(_alabel_prefix): + label = label[len(_alabel_prefix):] + else: + check_label(label) + return label.decode('ascii') + + label = label.decode('punycode') + check_label(label) + return label + + +def uts46_remap(domain, std3_rules=True, transitional=False): + """Re-map the characters in the string according to UTS46 processing.""" + from .uts46data import uts46data + output = u"" + try: + for pos, char in enumerate(domain): + code_point = ord(char) + uts46row = uts46data[code_point if code_point < 256 else + bisect.bisect_left(uts46data, (code_point, "Z")) - 1] + status = uts46row[1] + replacement = uts46row[2] if len(uts46row) == 3 else None + if (status == "V" or + (status == "D" and not transitional) or + (status == "3" and not std3_rules and replacement is None)): + output += char + elif replacement is not None and (status == "M" or + (status == "3" and not std3_rules) or + (status == "D" and transitional)): + output += replacement + elif status != "I": + raise IndexError() + return unicodedata.normalize("NFC", output) + except IndexError: + raise InvalidCodepoint( + "Codepoint {0} not allowed at position {1} in {2}".format( + _unot(code_point), pos + 1, repr(domain))) + + +def encode(s, strict=False, uts46=False, std3_rules=False, transitional=False): + + if isinstance(s, (bytes, bytearray)): + s = s.decode("ascii") + if uts46: + s = uts46_remap(s, std3_rules, transitional) + trailing_dot = False + result = [] + if strict: + labels = s.split('.') + else: + labels = _unicode_dots_re.split(s) + if not labels or labels == ['']: + raise IDNAError('Empty domain') + if labels[-1] == '': + del labels[-1] + trailing_dot = True + for label in labels: + s = alabel(label) + if s: + result.append(s) + else: + raise IDNAError('Empty label') + if trailing_dot: + result.append(b'') + s = b'.'.join(result) + if not valid_string_length(s, trailing_dot): + raise IDNAError('Domain too long') + return s + + +def decode(s, strict=False, uts46=False, std3_rules=False): + + if isinstance(s, (bytes, bytearray)): + s = s.decode("ascii") + if uts46: + s = uts46_remap(s, std3_rules, False) + trailing_dot = False + result = [] + if not strict: + labels = _unicode_dots_re.split(s) + else: + labels = s.split(u'.') + if not labels or labels == ['']: + raise IDNAError('Empty domain') + if not labels[-1]: + del labels[-1] + trailing_dot = True + for label in labels: + s = ulabel(label) + if s: + result.append(s) + else: + raise IDNAError('Empty label') + if trailing_dot: + result.append(u'') + return u'.'.join(result) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/idna/idnadata.py b/venv/lib/python3.7/site-packages/pip/_vendor/idna/idnadata.py new file mode 100644 index 0000000..17974e2 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/idna/idnadata.py @@ -0,0 +1,1893 @@ +# This file is automatically generated by tools/idna-data + +__version__ = "10.0.0" +scripts = { + 'Greek': ( + 0x37000000374, + 0x37500000378, + 0x37a0000037e, + 0x37f00000380, + 0x38400000385, + 0x38600000387, + 0x3880000038b, + 0x38c0000038d, + 0x38e000003a2, + 0x3a3000003e2, + 0x3f000000400, + 0x1d2600001d2b, + 0x1d5d00001d62, + 0x1d6600001d6b, + 0x1dbf00001dc0, + 0x1f0000001f16, + 0x1f1800001f1e, + 0x1f2000001f46, + 0x1f4800001f4e, + 0x1f5000001f58, + 0x1f5900001f5a, + 0x1f5b00001f5c, + 0x1f5d00001f5e, + 0x1f5f00001f7e, + 0x1f8000001fb5, + 0x1fb600001fc5, + 0x1fc600001fd4, + 0x1fd600001fdc, + 0x1fdd00001ff0, + 0x1ff200001ff5, + 0x1ff600001fff, + 0x212600002127, + 0xab650000ab66, + 0x101400001018f, + 0x101a0000101a1, + 0x1d2000001d246, + ), + 'Han': ( + 0x2e8000002e9a, + 0x2e9b00002ef4, + 0x2f0000002fd6, + 0x300500003006, + 0x300700003008, + 0x30210000302a, + 0x30380000303c, + 0x340000004db6, + 0x4e0000009feb, + 0xf9000000fa6e, + 0xfa700000fada, + 0x200000002a6d7, + 0x2a7000002b735, + 0x2b7400002b81e, + 0x2b8200002cea2, + 0x2ceb00002ebe1, + 0x2f8000002fa1e, + ), + 'Hebrew': ( + 0x591000005c8, + 0x5d0000005eb, + 0x5f0000005f5, + 0xfb1d0000fb37, + 0xfb380000fb3d, + 0xfb3e0000fb3f, + 0xfb400000fb42, + 0xfb430000fb45, + 0xfb460000fb50, + ), + 'Hiragana': ( + 0x304100003097, + 0x309d000030a0, + 0x1b0010001b11f, + 0x1f2000001f201, + ), + 'Katakana': ( + 0x30a1000030fb, + 0x30fd00003100, + 0x31f000003200, + 0x32d0000032ff, + 0x330000003358, + 0xff660000ff70, + 0xff710000ff9e, + 0x1b0000001b001, + ), +} +joining_types = { + 0x600: 85, + 0x601: 85, + 0x602: 85, + 0x603: 85, + 0x604: 85, + 0x605: 85, + 0x608: 85, + 0x60b: 85, + 0x620: 68, + 0x621: 85, + 0x622: 82, + 0x623: 82, + 0x624: 82, + 0x625: 82, + 0x626: 68, + 0x627: 82, + 0x628: 68, + 0x629: 82, + 0x62a: 68, + 0x62b: 68, + 0x62c: 68, + 0x62d: 68, + 0x62e: 68, + 0x62f: 82, + 0x630: 82, + 0x631: 82, + 0x632: 82, + 0x633: 68, + 0x634: 68, + 0x635: 68, + 0x636: 68, + 0x637: 68, + 0x638: 68, + 0x639: 68, + 0x63a: 68, + 0x63b: 68, + 0x63c: 68, + 0x63d: 68, + 0x63e: 68, + 0x63f: 68, + 0x640: 67, + 0x641: 68, + 0x642: 68, + 0x643: 68, + 0x644: 68, + 0x645: 68, + 0x646: 68, + 0x647: 68, + 0x648: 82, + 0x649: 68, + 0x64a: 68, + 0x66e: 68, + 0x66f: 68, + 0x671: 82, + 0x672: 82, + 0x673: 82, + 0x674: 85, + 0x675: 82, + 0x676: 82, + 0x677: 82, + 0x678: 68, + 0x679: 68, + 0x67a: 68, + 0x67b: 68, + 0x67c: 68, + 0x67d: 68, + 0x67e: 68, + 0x67f: 68, + 0x680: 68, + 0x681: 68, + 0x682: 68, + 0x683: 68, + 0x684: 68, + 0x685: 68, + 0x686: 68, + 0x687: 68, + 0x688: 82, + 0x689: 82, + 0x68a: 82, + 0x68b: 82, + 0x68c: 82, + 0x68d: 82, + 0x68e: 82, + 0x68f: 82, + 0x690: 82, + 0x691: 82, + 0x692: 82, + 0x693: 82, + 0x694: 82, + 0x695: 82, + 0x696: 82, + 0x697: 82, + 0x698: 82, + 0x699: 82, + 0x69a: 68, + 0x69b: 68, + 0x69c: 68, + 0x69d: 68, + 0x69e: 68, + 0x69f: 68, + 0x6a0: 68, + 0x6a1: 68, + 0x6a2: 68, + 0x6a3: 68, + 0x6a4: 68, + 0x6a5: 68, + 0x6a6: 68, + 0x6a7: 68, + 0x6a8: 68, + 0x6a9: 68, + 0x6aa: 68, + 0x6ab: 68, + 0x6ac: 68, + 0x6ad: 68, + 0x6ae: 68, + 0x6af: 68, + 0x6b0: 68, + 0x6b1: 68, + 0x6b2: 68, + 0x6b3: 68, + 0x6b4: 68, + 0x6b5: 68, + 0x6b6: 68, + 0x6b7: 68, + 0x6b8: 68, + 0x6b9: 68, + 0x6ba: 68, + 0x6bb: 68, + 0x6bc: 68, + 0x6bd: 68, + 0x6be: 68, + 0x6bf: 68, + 0x6c0: 82, + 0x6c1: 68, + 0x6c2: 68, + 0x6c3: 82, + 0x6c4: 82, + 0x6c5: 82, + 0x6c6: 82, + 0x6c7: 82, + 0x6c8: 82, + 0x6c9: 82, + 0x6ca: 82, + 0x6cb: 82, + 0x6cc: 68, + 0x6cd: 82, + 0x6ce: 68, + 0x6cf: 82, + 0x6d0: 68, + 0x6d1: 68, + 0x6d2: 82, + 0x6d3: 82, + 0x6d5: 82, + 0x6dd: 85, + 0x6ee: 82, + 0x6ef: 82, + 0x6fa: 68, + 0x6fb: 68, + 0x6fc: 68, + 0x6ff: 68, + 0x710: 82, + 0x712: 68, + 0x713: 68, + 0x714: 68, + 0x715: 82, + 0x716: 82, + 0x717: 82, + 0x718: 82, + 0x719: 82, + 0x71a: 68, + 0x71b: 68, + 0x71c: 68, + 0x71d: 68, + 0x71e: 82, + 0x71f: 68, + 0x720: 68, + 0x721: 68, + 0x722: 68, + 0x723: 68, + 0x724: 68, + 0x725: 68, + 0x726: 68, + 0x727: 68, + 0x728: 82, + 0x729: 68, + 0x72a: 82, + 0x72b: 68, + 0x72c: 82, + 0x72d: 68, + 0x72e: 68, + 0x72f: 82, + 0x74d: 82, + 0x74e: 68, + 0x74f: 68, + 0x750: 68, + 0x751: 68, + 0x752: 68, + 0x753: 68, + 0x754: 68, + 0x755: 68, + 0x756: 68, + 0x757: 68, + 0x758: 68, + 0x759: 82, + 0x75a: 82, + 0x75b: 82, + 0x75c: 68, + 0x75d: 68, + 0x75e: 68, + 0x75f: 68, + 0x760: 68, + 0x761: 68, + 0x762: 68, + 0x763: 68, + 0x764: 68, + 0x765: 68, + 0x766: 68, + 0x767: 68, + 0x768: 68, + 0x769: 68, + 0x76a: 68, + 0x76b: 82, + 0x76c: 82, + 0x76d: 68, + 0x76e: 68, + 0x76f: 68, + 0x770: 68, + 0x771: 82, + 0x772: 68, + 0x773: 82, + 0x774: 82, + 0x775: 68, + 0x776: 68, + 0x777: 68, + 0x778: 82, + 0x779: 82, + 0x77a: 68, + 0x77b: 68, + 0x77c: 68, + 0x77d: 68, + 0x77e: 68, + 0x77f: 68, + 0x7ca: 68, + 0x7cb: 68, + 0x7cc: 68, + 0x7cd: 68, + 0x7ce: 68, + 0x7cf: 68, + 0x7d0: 68, + 0x7d1: 68, + 0x7d2: 68, + 0x7d3: 68, + 0x7d4: 68, + 0x7d5: 68, + 0x7d6: 68, + 0x7d7: 68, + 0x7d8: 68, + 0x7d9: 68, + 0x7da: 68, + 0x7db: 68, + 0x7dc: 68, + 0x7dd: 68, + 0x7de: 68, + 0x7df: 68, + 0x7e0: 68, + 0x7e1: 68, + 0x7e2: 68, + 0x7e3: 68, + 0x7e4: 68, + 0x7e5: 68, + 0x7e6: 68, + 0x7e7: 68, + 0x7e8: 68, + 0x7e9: 68, + 0x7ea: 68, + 0x7fa: 67, + 0x840: 82, + 0x841: 68, + 0x842: 68, + 0x843: 68, + 0x844: 68, + 0x845: 68, + 0x846: 82, + 0x847: 82, + 0x848: 68, + 0x849: 82, + 0x84a: 68, + 0x84b: 68, + 0x84c: 68, + 0x84d: 68, + 0x84e: 68, + 0x84f: 68, + 0x850: 68, + 0x851: 68, + 0x852: 68, + 0x853: 68, + 0x854: 82, + 0x855: 68, + 0x856: 85, + 0x857: 85, + 0x858: 85, + 0x860: 68, + 0x861: 85, + 0x862: 68, + 0x863: 68, + 0x864: 68, + 0x865: 68, + 0x866: 85, + 0x867: 82, + 0x868: 68, + 0x869: 82, + 0x86a: 82, + 0x8a0: 68, + 0x8a1: 68, + 0x8a2: 68, + 0x8a3: 68, + 0x8a4: 68, + 0x8a5: 68, + 0x8a6: 68, + 0x8a7: 68, + 0x8a8: 68, + 0x8a9: 68, + 0x8aa: 82, + 0x8ab: 82, + 0x8ac: 82, + 0x8ad: 85, + 0x8ae: 82, + 0x8af: 68, + 0x8b0: 68, + 0x8b1: 82, + 0x8b2: 82, + 0x8b3: 68, + 0x8b4: 68, + 0x8b6: 68, + 0x8b7: 68, + 0x8b8: 68, + 0x8b9: 82, + 0x8ba: 68, + 0x8bb: 68, + 0x8bc: 68, + 0x8bd: 68, + 0x8e2: 85, + 0x1806: 85, + 0x1807: 68, + 0x180a: 67, + 0x180e: 85, + 0x1820: 68, + 0x1821: 68, + 0x1822: 68, + 0x1823: 68, + 0x1824: 68, + 0x1825: 68, + 0x1826: 68, + 0x1827: 68, + 0x1828: 68, + 0x1829: 68, + 0x182a: 68, + 0x182b: 68, + 0x182c: 68, + 0x182d: 68, + 0x182e: 68, + 0x182f: 68, + 0x1830: 68, + 0x1831: 68, + 0x1832: 68, + 0x1833: 68, + 0x1834: 68, + 0x1835: 68, + 0x1836: 68, + 0x1837: 68, + 0x1838: 68, + 0x1839: 68, + 0x183a: 68, + 0x183b: 68, + 0x183c: 68, + 0x183d: 68, + 0x183e: 68, + 0x183f: 68, + 0x1840: 68, + 0x1841: 68, + 0x1842: 68, + 0x1843: 68, + 0x1844: 68, + 0x1845: 68, + 0x1846: 68, + 0x1847: 68, + 0x1848: 68, + 0x1849: 68, + 0x184a: 68, + 0x184b: 68, + 0x184c: 68, + 0x184d: 68, + 0x184e: 68, + 0x184f: 68, + 0x1850: 68, + 0x1851: 68, + 0x1852: 68, + 0x1853: 68, + 0x1854: 68, + 0x1855: 68, + 0x1856: 68, + 0x1857: 68, + 0x1858: 68, + 0x1859: 68, + 0x185a: 68, + 0x185b: 68, + 0x185c: 68, + 0x185d: 68, + 0x185e: 68, + 0x185f: 68, + 0x1860: 68, + 0x1861: 68, + 0x1862: 68, + 0x1863: 68, + 0x1864: 68, + 0x1865: 68, + 0x1866: 68, + 0x1867: 68, + 0x1868: 68, + 0x1869: 68, + 0x186a: 68, + 0x186b: 68, + 0x186c: 68, + 0x186d: 68, + 0x186e: 68, + 0x186f: 68, + 0x1870: 68, + 0x1871: 68, + 0x1872: 68, + 0x1873: 68, + 0x1874: 68, + 0x1875: 68, + 0x1876: 68, + 0x1877: 68, + 0x1880: 85, + 0x1881: 85, + 0x1882: 85, + 0x1883: 85, + 0x1884: 85, + 0x1885: 84, + 0x1886: 84, + 0x1887: 68, + 0x1888: 68, + 0x1889: 68, + 0x188a: 68, + 0x188b: 68, + 0x188c: 68, + 0x188d: 68, + 0x188e: 68, + 0x188f: 68, + 0x1890: 68, + 0x1891: 68, + 0x1892: 68, + 0x1893: 68, + 0x1894: 68, + 0x1895: 68, + 0x1896: 68, + 0x1897: 68, + 0x1898: 68, + 0x1899: 68, + 0x189a: 68, + 0x189b: 68, + 0x189c: 68, + 0x189d: 68, + 0x189e: 68, + 0x189f: 68, + 0x18a0: 68, + 0x18a1: 68, + 0x18a2: 68, + 0x18a3: 68, + 0x18a4: 68, + 0x18a5: 68, + 0x18a6: 68, + 0x18a7: 68, + 0x18a8: 68, + 0x18aa: 68, + 0x200c: 85, + 0x200d: 67, + 0x202f: 85, + 0x2066: 85, + 0x2067: 85, + 0x2068: 85, + 0x2069: 85, + 0xa840: 68, + 0xa841: 68, + 0xa842: 68, + 0xa843: 68, + 0xa844: 68, + 0xa845: 68, + 0xa846: 68, + 0xa847: 68, + 0xa848: 68, + 0xa849: 68, + 0xa84a: 68, + 0xa84b: 68, + 0xa84c: 68, + 0xa84d: 68, + 0xa84e: 68, + 0xa84f: 68, + 0xa850: 68, + 0xa851: 68, + 0xa852: 68, + 0xa853: 68, + 0xa854: 68, + 0xa855: 68, + 0xa856: 68, + 0xa857: 68, + 0xa858: 68, + 0xa859: 68, + 0xa85a: 68, + 0xa85b: 68, + 0xa85c: 68, + 0xa85d: 68, + 0xa85e: 68, + 0xa85f: 68, + 0xa860: 68, + 0xa861: 68, + 0xa862: 68, + 0xa863: 68, + 0xa864: 68, + 0xa865: 68, + 0xa866: 68, + 0xa867: 68, + 0xa868: 68, + 0xa869: 68, + 0xa86a: 68, + 0xa86b: 68, + 0xa86c: 68, + 0xa86d: 68, + 0xa86e: 68, + 0xa86f: 68, + 0xa870: 68, + 0xa871: 68, + 0xa872: 76, + 0xa873: 85, + 0x10ac0: 68, + 0x10ac1: 68, + 0x10ac2: 68, + 0x10ac3: 68, + 0x10ac4: 68, + 0x10ac5: 82, + 0x10ac6: 85, + 0x10ac7: 82, + 0x10ac8: 85, + 0x10ac9: 82, + 0x10aca: 82, + 0x10acb: 85, + 0x10acc: 85, + 0x10acd: 76, + 0x10ace: 82, + 0x10acf: 82, + 0x10ad0: 82, + 0x10ad1: 82, + 0x10ad2: 82, + 0x10ad3: 68, + 0x10ad4: 68, + 0x10ad5: 68, + 0x10ad6: 68, + 0x10ad7: 76, + 0x10ad8: 68, + 0x10ad9: 68, + 0x10ada: 68, + 0x10adb: 68, + 0x10adc: 68, + 0x10add: 82, + 0x10ade: 68, + 0x10adf: 68, + 0x10ae0: 68, + 0x10ae1: 82, + 0x10ae2: 85, + 0x10ae3: 85, + 0x10ae4: 82, + 0x10aeb: 68, + 0x10aec: 68, + 0x10aed: 68, + 0x10aee: 68, + 0x10aef: 82, + 0x10b80: 68, + 0x10b81: 82, + 0x10b82: 68, + 0x10b83: 82, + 0x10b84: 82, + 0x10b85: 82, + 0x10b86: 68, + 0x10b87: 68, + 0x10b88: 68, + 0x10b89: 82, + 0x10b8a: 68, + 0x10b8b: 68, + 0x10b8c: 82, + 0x10b8d: 68, + 0x10b8e: 82, + 0x10b8f: 82, + 0x10b90: 68, + 0x10b91: 82, + 0x10ba9: 82, + 0x10baa: 82, + 0x10bab: 82, + 0x10bac: 82, + 0x10bad: 68, + 0x10bae: 68, + 0x10baf: 85, + 0x1e900: 68, + 0x1e901: 68, + 0x1e902: 68, + 0x1e903: 68, + 0x1e904: 68, + 0x1e905: 68, + 0x1e906: 68, + 0x1e907: 68, + 0x1e908: 68, + 0x1e909: 68, + 0x1e90a: 68, + 0x1e90b: 68, + 0x1e90c: 68, + 0x1e90d: 68, + 0x1e90e: 68, + 0x1e90f: 68, + 0x1e910: 68, + 0x1e911: 68, + 0x1e912: 68, + 0x1e913: 68, + 0x1e914: 68, + 0x1e915: 68, + 0x1e916: 68, + 0x1e917: 68, + 0x1e918: 68, + 0x1e919: 68, + 0x1e91a: 68, + 0x1e91b: 68, + 0x1e91c: 68, + 0x1e91d: 68, + 0x1e91e: 68, + 0x1e91f: 68, + 0x1e920: 68, + 0x1e921: 68, + 0x1e922: 68, + 0x1e923: 68, + 0x1e924: 68, + 0x1e925: 68, + 0x1e926: 68, + 0x1e927: 68, + 0x1e928: 68, + 0x1e929: 68, + 0x1e92a: 68, + 0x1e92b: 68, + 0x1e92c: 68, + 0x1e92d: 68, + 0x1e92e: 68, + 0x1e92f: 68, + 0x1e930: 68, + 0x1e931: 68, + 0x1e932: 68, + 0x1e933: 68, + 0x1e934: 68, + 0x1e935: 68, + 0x1e936: 68, + 0x1e937: 68, + 0x1e938: 68, + 0x1e939: 68, + 0x1e93a: 68, + 0x1e93b: 68, + 0x1e93c: 68, + 0x1e93d: 68, + 0x1e93e: 68, + 0x1e93f: 68, + 0x1e940: 68, + 0x1e941: 68, + 0x1e942: 68, + 0x1e943: 68, +} +codepoint_classes = { + 'PVALID': ( + 0x2d0000002e, + 0x300000003a, + 0x610000007b, + 0xdf000000f7, + 0xf800000100, + 0x10100000102, + 0x10300000104, + 0x10500000106, + 0x10700000108, + 0x1090000010a, + 0x10b0000010c, + 0x10d0000010e, + 0x10f00000110, + 0x11100000112, + 0x11300000114, + 0x11500000116, + 0x11700000118, + 0x1190000011a, + 0x11b0000011c, + 0x11d0000011e, + 0x11f00000120, + 0x12100000122, + 0x12300000124, + 0x12500000126, + 0x12700000128, + 0x1290000012a, + 0x12b0000012c, + 0x12d0000012e, + 0x12f00000130, + 0x13100000132, + 0x13500000136, + 0x13700000139, + 0x13a0000013b, + 0x13c0000013d, + 0x13e0000013f, + 0x14200000143, + 0x14400000145, + 0x14600000147, + 0x14800000149, + 0x14b0000014c, + 0x14d0000014e, + 0x14f00000150, + 0x15100000152, + 0x15300000154, + 0x15500000156, + 0x15700000158, + 0x1590000015a, + 0x15b0000015c, + 0x15d0000015e, + 0x15f00000160, + 0x16100000162, + 0x16300000164, + 0x16500000166, + 0x16700000168, + 0x1690000016a, + 0x16b0000016c, + 0x16d0000016e, + 0x16f00000170, + 0x17100000172, + 0x17300000174, + 0x17500000176, + 0x17700000178, + 0x17a0000017b, + 0x17c0000017d, + 0x17e0000017f, + 0x18000000181, + 0x18300000184, + 0x18500000186, + 0x18800000189, + 0x18c0000018e, + 0x19200000193, + 0x19500000196, + 0x1990000019c, + 0x19e0000019f, + 0x1a1000001a2, + 0x1a3000001a4, + 0x1a5000001a6, + 0x1a8000001a9, + 0x1aa000001ac, + 0x1ad000001ae, + 0x1b0000001b1, + 0x1b4000001b5, + 0x1b6000001b7, + 0x1b9000001bc, + 0x1bd000001c4, + 0x1ce000001cf, + 0x1d0000001d1, + 0x1d2000001d3, + 0x1d4000001d5, + 0x1d6000001d7, + 0x1d8000001d9, + 0x1da000001db, + 0x1dc000001de, + 0x1df000001e0, + 0x1e1000001e2, + 0x1e3000001e4, + 0x1e5000001e6, + 0x1e7000001e8, + 0x1e9000001ea, + 0x1eb000001ec, + 0x1ed000001ee, + 0x1ef000001f1, + 0x1f5000001f6, + 0x1f9000001fa, + 0x1fb000001fc, + 0x1fd000001fe, + 0x1ff00000200, + 0x20100000202, + 0x20300000204, + 0x20500000206, + 0x20700000208, + 0x2090000020a, + 0x20b0000020c, + 0x20d0000020e, + 0x20f00000210, + 0x21100000212, + 0x21300000214, + 0x21500000216, + 0x21700000218, + 0x2190000021a, + 0x21b0000021c, + 0x21d0000021e, + 0x21f00000220, + 0x22100000222, + 0x22300000224, + 0x22500000226, + 0x22700000228, + 0x2290000022a, + 0x22b0000022c, + 0x22d0000022e, + 0x22f00000230, + 0x23100000232, + 0x2330000023a, + 0x23c0000023d, + 0x23f00000241, + 0x24200000243, + 0x24700000248, + 0x2490000024a, + 0x24b0000024c, + 0x24d0000024e, + 0x24f000002b0, + 0x2b9000002c2, + 0x2c6000002d2, + 0x2ec000002ed, + 0x2ee000002ef, + 0x30000000340, + 0x34200000343, + 0x3460000034f, + 0x35000000370, + 0x37100000372, + 0x37300000374, + 0x37700000378, + 0x37b0000037e, + 0x39000000391, + 0x3ac000003cf, + 0x3d7000003d8, + 0x3d9000003da, + 0x3db000003dc, + 0x3dd000003de, + 0x3df000003e0, + 0x3e1000003e2, + 0x3e3000003e4, + 0x3e5000003e6, + 0x3e7000003e8, + 0x3e9000003ea, + 0x3eb000003ec, + 0x3ed000003ee, + 0x3ef000003f0, + 0x3f3000003f4, + 0x3f8000003f9, + 0x3fb000003fd, + 0x43000000460, + 0x46100000462, + 0x46300000464, + 0x46500000466, + 0x46700000468, + 0x4690000046a, + 0x46b0000046c, + 0x46d0000046e, + 0x46f00000470, + 0x47100000472, + 0x47300000474, + 0x47500000476, + 0x47700000478, + 0x4790000047a, + 0x47b0000047c, + 0x47d0000047e, + 0x47f00000480, + 0x48100000482, + 0x48300000488, + 0x48b0000048c, + 0x48d0000048e, + 0x48f00000490, + 0x49100000492, + 0x49300000494, + 0x49500000496, + 0x49700000498, + 0x4990000049a, + 0x49b0000049c, + 0x49d0000049e, + 0x49f000004a0, + 0x4a1000004a2, + 0x4a3000004a4, + 0x4a5000004a6, + 0x4a7000004a8, + 0x4a9000004aa, + 0x4ab000004ac, + 0x4ad000004ae, + 0x4af000004b0, + 0x4b1000004b2, + 0x4b3000004b4, + 0x4b5000004b6, + 0x4b7000004b8, + 0x4b9000004ba, + 0x4bb000004bc, + 0x4bd000004be, + 0x4bf000004c0, + 0x4c2000004c3, + 0x4c4000004c5, + 0x4c6000004c7, + 0x4c8000004c9, + 0x4ca000004cb, + 0x4cc000004cd, + 0x4ce000004d0, + 0x4d1000004d2, + 0x4d3000004d4, + 0x4d5000004d6, + 0x4d7000004d8, + 0x4d9000004da, + 0x4db000004dc, + 0x4dd000004de, + 0x4df000004e0, + 0x4e1000004e2, + 0x4e3000004e4, + 0x4e5000004e6, + 0x4e7000004e8, + 0x4e9000004ea, + 0x4eb000004ec, + 0x4ed000004ee, + 0x4ef000004f0, + 0x4f1000004f2, + 0x4f3000004f4, + 0x4f5000004f6, + 0x4f7000004f8, + 0x4f9000004fa, + 0x4fb000004fc, + 0x4fd000004fe, + 0x4ff00000500, + 0x50100000502, + 0x50300000504, + 0x50500000506, + 0x50700000508, + 0x5090000050a, + 0x50b0000050c, + 0x50d0000050e, + 0x50f00000510, + 0x51100000512, + 0x51300000514, + 0x51500000516, + 0x51700000518, + 0x5190000051a, + 0x51b0000051c, + 0x51d0000051e, + 0x51f00000520, + 0x52100000522, + 0x52300000524, + 0x52500000526, + 0x52700000528, + 0x5290000052a, + 0x52b0000052c, + 0x52d0000052e, + 0x52f00000530, + 0x5590000055a, + 0x56100000587, + 0x591000005be, + 0x5bf000005c0, + 0x5c1000005c3, + 0x5c4000005c6, + 0x5c7000005c8, + 0x5d0000005eb, + 0x5f0000005f3, + 0x6100000061b, + 0x62000000640, + 0x64100000660, + 0x66e00000675, + 0x679000006d4, + 0x6d5000006dd, + 0x6df000006e9, + 0x6ea000006f0, + 0x6fa00000700, + 0x7100000074b, + 0x74d000007b2, + 0x7c0000007f6, + 0x8000000082e, + 0x8400000085c, + 0x8600000086b, + 0x8a0000008b5, + 0x8b6000008be, + 0x8d4000008e2, + 0x8e300000958, + 0x96000000964, + 0x96600000970, + 0x97100000984, + 0x9850000098d, + 0x98f00000991, + 0x993000009a9, + 0x9aa000009b1, + 0x9b2000009b3, + 0x9b6000009ba, + 0x9bc000009c5, + 0x9c7000009c9, + 0x9cb000009cf, + 0x9d7000009d8, + 0x9e0000009e4, + 0x9e6000009f2, + 0x9fc000009fd, + 0xa0100000a04, + 0xa0500000a0b, + 0xa0f00000a11, + 0xa1300000a29, + 0xa2a00000a31, + 0xa3200000a33, + 0xa3500000a36, + 0xa3800000a3a, + 0xa3c00000a3d, + 0xa3e00000a43, + 0xa4700000a49, + 0xa4b00000a4e, + 0xa5100000a52, + 0xa5c00000a5d, + 0xa6600000a76, + 0xa8100000a84, + 0xa8500000a8e, + 0xa8f00000a92, + 0xa9300000aa9, + 0xaaa00000ab1, + 0xab200000ab4, + 0xab500000aba, + 0xabc00000ac6, + 0xac700000aca, + 0xacb00000ace, + 0xad000000ad1, + 0xae000000ae4, + 0xae600000af0, + 0xaf900000b00, + 0xb0100000b04, + 0xb0500000b0d, + 0xb0f00000b11, + 0xb1300000b29, + 0xb2a00000b31, + 0xb3200000b34, + 0xb3500000b3a, + 0xb3c00000b45, + 0xb4700000b49, + 0xb4b00000b4e, + 0xb5600000b58, + 0xb5f00000b64, + 0xb6600000b70, + 0xb7100000b72, + 0xb8200000b84, + 0xb8500000b8b, + 0xb8e00000b91, + 0xb9200000b96, + 0xb9900000b9b, + 0xb9c00000b9d, + 0xb9e00000ba0, + 0xba300000ba5, + 0xba800000bab, + 0xbae00000bba, + 0xbbe00000bc3, + 0xbc600000bc9, + 0xbca00000bce, + 0xbd000000bd1, + 0xbd700000bd8, + 0xbe600000bf0, + 0xc0000000c04, + 0xc0500000c0d, + 0xc0e00000c11, + 0xc1200000c29, + 0xc2a00000c3a, + 0xc3d00000c45, + 0xc4600000c49, + 0xc4a00000c4e, + 0xc5500000c57, + 0xc5800000c5b, + 0xc6000000c64, + 0xc6600000c70, + 0xc8000000c84, + 0xc8500000c8d, + 0xc8e00000c91, + 0xc9200000ca9, + 0xcaa00000cb4, + 0xcb500000cba, + 0xcbc00000cc5, + 0xcc600000cc9, + 0xcca00000cce, + 0xcd500000cd7, + 0xcde00000cdf, + 0xce000000ce4, + 0xce600000cf0, + 0xcf100000cf3, + 0xd0000000d04, + 0xd0500000d0d, + 0xd0e00000d11, + 0xd1200000d45, + 0xd4600000d49, + 0xd4a00000d4f, + 0xd5400000d58, + 0xd5f00000d64, + 0xd6600000d70, + 0xd7a00000d80, + 0xd8200000d84, + 0xd8500000d97, + 0xd9a00000db2, + 0xdb300000dbc, + 0xdbd00000dbe, + 0xdc000000dc7, + 0xdca00000dcb, + 0xdcf00000dd5, + 0xdd600000dd7, + 0xdd800000de0, + 0xde600000df0, + 0xdf200000df4, + 0xe0100000e33, + 0xe3400000e3b, + 0xe4000000e4f, + 0xe5000000e5a, + 0xe8100000e83, + 0xe8400000e85, + 0xe8700000e89, + 0xe8a00000e8b, + 0xe8d00000e8e, + 0xe9400000e98, + 0xe9900000ea0, + 0xea100000ea4, + 0xea500000ea6, + 0xea700000ea8, + 0xeaa00000eac, + 0xead00000eb3, + 0xeb400000eba, + 0xebb00000ebe, + 0xec000000ec5, + 0xec600000ec7, + 0xec800000ece, + 0xed000000eda, + 0xede00000ee0, + 0xf0000000f01, + 0xf0b00000f0c, + 0xf1800000f1a, + 0xf2000000f2a, + 0xf3500000f36, + 0xf3700000f38, + 0xf3900000f3a, + 0xf3e00000f43, + 0xf4400000f48, + 0xf4900000f4d, + 0xf4e00000f52, + 0xf5300000f57, + 0xf5800000f5c, + 0xf5d00000f69, + 0xf6a00000f6d, + 0xf7100000f73, + 0xf7400000f75, + 0xf7a00000f81, + 0xf8200000f85, + 0xf8600000f93, + 0xf9400000f98, + 0xf9900000f9d, + 0xf9e00000fa2, + 0xfa300000fa7, + 0xfa800000fac, + 0xfad00000fb9, + 0xfba00000fbd, + 0xfc600000fc7, + 0x10000000104a, + 0x10500000109e, + 0x10d0000010fb, + 0x10fd00001100, + 0x120000001249, + 0x124a0000124e, + 0x125000001257, + 0x125800001259, + 0x125a0000125e, + 0x126000001289, + 0x128a0000128e, + 0x1290000012b1, + 0x12b2000012b6, + 0x12b8000012bf, + 0x12c0000012c1, + 0x12c2000012c6, + 0x12c8000012d7, + 0x12d800001311, + 0x131200001316, + 0x13180000135b, + 0x135d00001360, + 0x138000001390, + 0x13a0000013f6, + 0x14010000166d, + 0x166f00001680, + 0x16810000169b, + 0x16a0000016eb, + 0x16f1000016f9, + 0x17000000170d, + 0x170e00001715, + 0x172000001735, + 0x174000001754, + 0x17600000176d, + 0x176e00001771, + 0x177200001774, + 0x1780000017b4, + 0x17b6000017d4, + 0x17d7000017d8, + 0x17dc000017de, + 0x17e0000017ea, + 0x18100000181a, + 0x182000001878, + 0x1880000018ab, + 0x18b0000018f6, + 0x19000000191f, + 0x19200000192c, + 0x19300000193c, + 0x19460000196e, + 0x197000001975, + 0x1980000019ac, + 0x19b0000019ca, + 0x19d0000019da, + 0x1a0000001a1c, + 0x1a2000001a5f, + 0x1a6000001a7d, + 0x1a7f00001a8a, + 0x1a9000001a9a, + 0x1aa700001aa8, + 0x1ab000001abe, + 0x1b0000001b4c, + 0x1b5000001b5a, + 0x1b6b00001b74, + 0x1b8000001bf4, + 0x1c0000001c38, + 0x1c4000001c4a, + 0x1c4d00001c7e, + 0x1cd000001cd3, + 0x1cd400001cfa, + 0x1d0000001d2c, + 0x1d2f00001d30, + 0x1d3b00001d3c, + 0x1d4e00001d4f, + 0x1d6b00001d78, + 0x1d7900001d9b, + 0x1dc000001dfa, + 0x1dfb00001e00, + 0x1e0100001e02, + 0x1e0300001e04, + 0x1e0500001e06, + 0x1e0700001e08, + 0x1e0900001e0a, + 0x1e0b00001e0c, + 0x1e0d00001e0e, + 0x1e0f00001e10, + 0x1e1100001e12, + 0x1e1300001e14, + 0x1e1500001e16, + 0x1e1700001e18, + 0x1e1900001e1a, + 0x1e1b00001e1c, + 0x1e1d00001e1e, + 0x1e1f00001e20, + 0x1e2100001e22, + 0x1e2300001e24, + 0x1e2500001e26, + 0x1e2700001e28, + 0x1e2900001e2a, + 0x1e2b00001e2c, + 0x1e2d00001e2e, + 0x1e2f00001e30, + 0x1e3100001e32, + 0x1e3300001e34, + 0x1e3500001e36, + 0x1e3700001e38, + 0x1e3900001e3a, + 0x1e3b00001e3c, + 0x1e3d00001e3e, + 0x1e3f00001e40, + 0x1e4100001e42, + 0x1e4300001e44, + 0x1e4500001e46, + 0x1e4700001e48, + 0x1e4900001e4a, + 0x1e4b00001e4c, + 0x1e4d00001e4e, + 0x1e4f00001e50, + 0x1e5100001e52, + 0x1e5300001e54, + 0x1e5500001e56, + 0x1e5700001e58, + 0x1e5900001e5a, + 0x1e5b00001e5c, + 0x1e5d00001e5e, + 0x1e5f00001e60, + 0x1e6100001e62, + 0x1e6300001e64, + 0x1e6500001e66, + 0x1e6700001e68, + 0x1e6900001e6a, + 0x1e6b00001e6c, + 0x1e6d00001e6e, + 0x1e6f00001e70, + 0x1e7100001e72, + 0x1e7300001e74, + 0x1e7500001e76, + 0x1e7700001e78, + 0x1e7900001e7a, + 0x1e7b00001e7c, + 0x1e7d00001e7e, + 0x1e7f00001e80, + 0x1e8100001e82, + 0x1e8300001e84, + 0x1e8500001e86, + 0x1e8700001e88, + 0x1e8900001e8a, + 0x1e8b00001e8c, + 0x1e8d00001e8e, + 0x1e8f00001e90, + 0x1e9100001e92, + 0x1e9300001e94, + 0x1e9500001e9a, + 0x1e9c00001e9e, + 0x1e9f00001ea0, + 0x1ea100001ea2, + 0x1ea300001ea4, + 0x1ea500001ea6, + 0x1ea700001ea8, + 0x1ea900001eaa, + 0x1eab00001eac, + 0x1ead00001eae, + 0x1eaf00001eb0, + 0x1eb100001eb2, + 0x1eb300001eb4, + 0x1eb500001eb6, + 0x1eb700001eb8, + 0x1eb900001eba, + 0x1ebb00001ebc, + 0x1ebd00001ebe, + 0x1ebf00001ec0, + 0x1ec100001ec2, + 0x1ec300001ec4, + 0x1ec500001ec6, + 0x1ec700001ec8, + 0x1ec900001eca, + 0x1ecb00001ecc, + 0x1ecd00001ece, + 0x1ecf00001ed0, + 0x1ed100001ed2, + 0x1ed300001ed4, + 0x1ed500001ed6, + 0x1ed700001ed8, + 0x1ed900001eda, + 0x1edb00001edc, + 0x1edd00001ede, + 0x1edf00001ee0, + 0x1ee100001ee2, + 0x1ee300001ee4, + 0x1ee500001ee6, + 0x1ee700001ee8, + 0x1ee900001eea, + 0x1eeb00001eec, + 0x1eed00001eee, + 0x1eef00001ef0, + 0x1ef100001ef2, + 0x1ef300001ef4, + 0x1ef500001ef6, + 0x1ef700001ef8, + 0x1ef900001efa, + 0x1efb00001efc, + 0x1efd00001efe, + 0x1eff00001f08, + 0x1f1000001f16, + 0x1f2000001f28, + 0x1f3000001f38, + 0x1f4000001f46, + 0x1f5000001f58, + 0x1f6000001f68, + 0x1f7000001f71, + 0x1f7200001f73, + 0x1f7400001f75, + 0x1f7600001f77, + 0x1f7800001f79, + 0x1f7a00001f7b, + 0x1f7c00001f7d, + 0x1fb000001fb2, + 0x1fb600001fb7, + 0x1fc600001fc7, + 0x1fd000001fd3, + 0x1fd600001fd8, + 0x1fe000001fe3, + 0x1fe400001fe8, + 0x1ff600001ff7, + 0x214e0000214f, + 0x218400002185, + 0x2c3000002c5f, + 0x2c6100002c62, + 0x2c6500002c67, + 0x2c6800002c69, + 0x2c6a00002c6b, + 0x2c6c00002c6d, + 0x2c7100002c72, + 0x2c7300002c75, + 0x2c7600002c7c, + 0x2c8100002c82, + 0x2c8300002c84, + 0x2c8500002c86, + 0x2c8700002c88, + 0x2c8900002c8a, + 0x2c8b00002c8c, + 0x2c8d00002c8e, + 0x2c8f00002c90, + 0x2c9100002c92, + 0x2c9300002c94, + 0x2c9500002c96, + 0x2c9700002c98, + 0x2c9900002c9a, + 0x2c9b00002c9c, + 0x2c9d00002c9e, + 0x2c9f00002ca0, + 0x2ca100002ca2, + 0x2ca300002ca4, + 0x2ca500002ca6, + 0x2ca700002ca8, + 0x2ca900002caa, + 0x2cab00002cac, + 0x2cad00002cae, + 0x2caf00002cb0, + 0x2cb100002cb2, + 0x2cb300002cb4, + 0x2cb500002cb6, + 0x2cb700002cb8, + 0x2cb900002cba, + 0x2cbb00002cbc, + 0x2cbd00002cbe, + 0x2cbf00002cc0, + 0x2cc100002cc2, + 0x2cc300002cc4, + 0x2cc500002cc6, + 0x2cc700002cc8, + 0x2cc900002cca, + 0x2ccb00002ccc, + 0x2ccd00002cce, + 0x2ccf00002cd0, + 0x2cd100002cd2, + 0x2cd300002cd4, + 0x2cd500002cd6, + 0x2cd700002cd8, + 0x2cd900002cda, + 0x2cdb00002cdc, + 0x2cdd00002cde, + 0x2cdf00002ce0, + 0x2ce100002ce2, + 0x2ce300002ce5, + 0x2cec00002ced, + 0x2cee00002cf2, + 0x2cf300002cf4, + 0x2d0000002d26, + 0x2d2700002d28, + 0x2d2d00002d2e, + 0x2d3000002d68, + 0x2d7f00002d97, + 0x2da000002da7, + 0x2da800002daf, + 0x2db000002db7, + 0x2db800002dbf, + 0x2dc000002dc7, + 0x2dc800002dcf, + 0x2dd000002dd7, + 0x2dd800002ddf, + 0x2de000002e00, + 0x2e2f00002e30, + 0x300500003008, + 0x302a0000302e, + 0x303c0000303d, + 0x304100003097, + 0x30990000309b, + 0x309d0000309f, + 0x30a1000030fb, + 0x30fc000030ff, + 0x31050000312f, + 0x31a0000031bb, + 0x31f000003200, + 0x340000004db6, + 0x4e0000009feb, + 0xa0000000a48d, + 0xa4d00000a4fe, + 0xa5000000a60d, + 0xa6100000a62c, + 0xa6410000a642, + 0xa6430000a644, + 0xa6450000a646, + 0xa6470000a648, + 0xa6490000a64a, + 0xa64b0000a64c, + 0xa64d0000a64e, + 0xa64f0000a650, + 0xa6510000a652, + 0xa6530000a654, + 0xa6550000a656, + 0xa6570000a658, + 0xa6590000a65a, + 0xa65b0000a65c, + 0xa65d0000a65e, + 0xa65f0000a660, + 0xa6610000a662, + 0xa6630000a664, + 0xa6650000a666, + 0xa6670000a668, + 0xa6690000a66a, + 0xa66b0000a66c, + 0xa66d0000a670, + 0xa6740000a67e, + 0xa67f0000a680, + 0xa6810000a682, + 0xa6830000a684, + 0xa6850000a686, + 0xa6870000a688, + 0xa6890000a68a, + 0xa68b0000a68c, + 0xa68d0000a68e, + 0xa68f0000a690, + 0xa6910000a692, + 0xa6930000a694, + 0xa6950000a696, + 0xa6970000a698, + 0xa6990000a69a, + 0xa69b0000a69c, + 0xa69e0000a6e6, + 0xa6f00000a6f2, + 0xa7170000a720, + 0xa7230000a724, + 0xa7250000a726, + 0xa7270000a728, + 0xa7290000a72a, + 0xa72b0000a72c, + 0xa72d0000a72e, + 0xa72f0000a732, + 0xa7330000a734, + 0xa7350000a736, + 0xa7370000a738, + 0xa7390000a73a, + 0xa73b0000a73c, + 0xa73d0000a73e, + 0xa73f0000a740, + 0xa7410000a742, + 0xa7430000a744, + 0xa7450000a746, + 0xa7470000a748, + 0xa7490000a74a, + 0xa74b0000a74c, + 0xa74d0000a74e, + 0xa74f0000a750, + 0xa7510000a752, + 0xa7530000a754, + 0xa7550000a756, + 0xa7570000a758, + 0xa7590000a75a, + 0xa75b0000a75c, + 0xa75d0000a75e, + 0xa75f0000a760, + 0xa7610000a762, + 0xa7630000a764, + 0xa7650000a766, + 0xa7670000a768, + 0xa7690000a76a, + 0xa76b0000a76c, + 0xa76d0000a76e, + 0xa76f0000a770, + 0xa7710000a779, + 0xa77a0000a77b, + 0xa77c0000a77d, + 0xa77f0000a780, + 0xa7810000a782, + 0xa7830000a784, + 0xa7850000a786, + 0xa7870000a789, + 0xa78c0000a78d, + 0xa78e0000a790, + 0xa7910000a792, + 0xa7930000a796, + 0xa7970000a798, + 0xa7990000a79a, + 0xa79b0000a79c, + 0xa79d0000a79e, + 0xa79f0000a7a0, + 0xa7a10000a7a2, + 0xa7a30000a7a4, + 0xa7a50000a7a6, + 0xa7a70000a7a8, + 0xa7a90000a7aa, + 0xa7b50000a7b6, + 0xa7b70000a7b8, + 0xa7f70000a7f8, + 0xa7fa0000a828, + 0xa8400000a874, + 0xa8800000a8c6, + 0xa8d00000a8da, + 0xa8e00000a8f8, + 0xa8fb0000a8fc, + 0xa8fd0000a8fe, + 0xa9000000a92e, + 0xa9300000a954, + 0xa9800000a9c1, + 0xa9cf0000a9da, + 0xa9e00000a9ff, + 0xaa000000aa37, + 0xaa400000aa4e, + 0xaa500000aa5a, + 0xaa600000aa77, + 0xaa7a0000aac3, + 0xaadb0000aade, + 0xaae00000aaf0, + 0xaaf20000aaf7, + 0xab010000ab07, + 0xab090000ab0f, + 0xab110000ab17, + 0xab200000ab27, + 0xab280000ab2f, + 0xab300000ab5b, + 0xab600000ab66, + 0xabc00000abeb, + 0xabec0000abee, + 0xabf00000abfa, + 0xac000000d7a4, + 0xfa0e0000fa10, + 0xfa110000fa12, + 0xfa130000fa15, + 0xfa1f0000fa20, + 0xfa210000fa22, + 0xfa230000fa25, + 0xfa270000fa2a, + 0xfb1e0000fb1f, + 0xfe200000fe30, + 0xfe730000fe74, + 0x100000001000c, + 0x1000d00010027, + 0x100280001003b, + 0x1003c0001003e, + 0x1003f0001004e, + 0x100500001005e, + 0x10080000100fb, + 0x101fd000101fe, + 0x102800001029d, + 0x102a0000102d1, + 0x102e0000102e1, + 0x1030000010320, + 0x1032d00010341, + 0x103420001034a, + 0x103500001037b, + 0x103800001039e, + 0x103a0000103c4, + 0x103c8000103d0, + 0x104280001049e, + 0x104a0000104aa, + 0x104d8000104fc, + 0x1050000010528, + 0x1053000010564, + 0x1060000010737, + 0x1074000010756, + 0x1076000010768, + 0x1080000010806, + 0x1080800010809, + 0x1080a00010836, + 0x1083700010839, + 0x1083c0001083d, + 0x1083f00010856, + 0x1086000010877, + 0x108800001089f, + 0x108e0000108f3, + 0x108f4000108f6, + 0x1090000010916, + 0x109200001093a, + 0x10980000109b8, + 0x109be000109c0, + 0x10a0000010a04, + 0x10a0500010a07, + 0x10a0c00010a14, + 0x10a1500010a18, + 0x10a1900010a34, + 0x10a3800010a3b, + 0x10a3f00010a40, + 0x10a6000010a7d, + 0x10a8000010a9d, + 0x10ac000010ac8, + 0x10ac900010ae7, + 0x10b0000010b36, + 0x10b4000010b56, + 0x10b6000010b73, + 0x10b8000010b92, + 0x10c0000010c49, + 0x10cc000010cf3, + 0x1100000011047, + 0x1106600011070, + 0x1107f000110bb, + 0x110d0000110e9, + 0x110f0000110fa, + 0x1110000011135, + 0x1113600011140, + 0x1115000011174, + 0x1117600011177, + 0x11180000111c5, + 0x111ca000111cd, + 0x111d0000111db, + 0x111dc000111dd, + 0x1120000011212, + 0x1121300011238, + 0x1123e0001123f, + 0x1128000011287, + 0x1128800011289, + 0x1128a0001128e, + 0x1128f0001129e, + 0x1129f000112a9, + 0x112b0000112eb, + 0x112f0000112fa, + 0x1130000011304, + 0x113050001130d, + 0x1130f00011311, + 0x1131300011329, + 0x1132a00011331, + 0x1133200011334, + 0x113350001133a, + 0x1133c00011345, + 0x1134700011349, + 0x1134b0001134e, + 0x1135000011351, + 0x1135700011358, + 0x1135d00011364, + 0x113660001136d, + 0x1137000011375, + 0x114000001144b, + 0x114500001145a, + 0x11480000114c6, + 0x114c7000114c8, + 0x114d0000114da, + 0x11580000115b6, + 0x115b8000115c1, + 0x115d8000115de, + 0x1160000011641, + 0x1164400011645, + 0x116500001165a, + 0x11680000116b8, + 0x116c0000116ca, + 0x117000001171a, + 0x1171d0001172c, + 0x117300001173a, + 0x118c0000118ea, + 0x118ff00011900, + 0x11a0000011a3f, + 0x11a4700011a48, + 0x11a5000011a84, + 0x11a8600011a9a, + 0x11ac000011af9, + 0x11c0000011c09, + 0x11c0a00011c37, + 0x11c3800011c41, + 0x11c5000011c5a, + 0x11c7200011c90, + 0x11c9200011ca8, + 0x11ca900011cb7, + 0x11d0000011d07, + 0x11d0800011d0a, + 0x11d0b00011d37, + 0x11d3a00011d3b, + 0x11d3c00011d3e, + 0x11d3f00011d48, + 0x11d5000011d5a, + 0x120000001239a, + 0x1248000012544, + 0x130000001342f, + 0x1440000014647, + 0x1680000016a39, + 0x16a4000016a5f, + 0x16a6000016a6a, + 0x16ad000016aee, + 0x16af000016af5, + 0x16b0000016b37, + 0x16b4000016b44, + 0x16b5000016b5a, + 0x16b6300016b78, + 0x16b7d00016b90, + 0x16f0000016f45, + 0x16f5000016f7f, + 0x16f8f00016fa0, + 0x16fe000016fe2, + 0x17000000187ed, + 0x1880000018af3, + 0x1b0000001b11f, + 0x1b1700001b2fc, + 0x1bc000001bc6b, + 0x1bc700001bc7d, + 0x1bc800001bc89, + 0x1bc900001bc9a, + 0x1bc9d0001bc9f, + 0x1da000001da37, + 0x1da3b0001da6d, + 0x1da750001da76, + 0x1da840001da85, + 0x1da9b0001daa0, + 0x1daa10001dab0, + 0x1e0000001e007, + 0x1e0080001e019, + 0x1e01b0001e022, + 0x1e0230001e025, + 0x1e0260001e02b, + 0x1e8000001e8c5, + 0x1e8d00001e8d7, + 0x1e9220001e94b, + 0x1e9500001e95a, + 0x200000002a6d7, + 0x2a7000002b735, + 0x2b7400002b81e, + 0x2b8200002cea2, + 0x2ceb00002ebe1, + ), + 'CONTEXTJ': ( + 0x200c0000200e, + ), + 'CONTEXTO': ( + 0xb7000000b8, + 0x37500000376, + 0x5f3000005f5, + 0x6600000066a, + 0x6f0000006fa, + 0x30fb000030fc, + ), +} diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/idna/intranges.py b/venv/lib/python3.7/site-packages/pip/_vendor/idna/intranges.py new file mode 100644 index 0000000..fa8a735 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/idna/intranges.py @@ -0,0 +1,53 @@ +""" +Given a list of integers, made up of (hopefully) a small number of long runs +of consecutive integers, compute a representation of the form +((start1, end1), (start2, end2) ...). Then answer the question "was x present +in the original list?" in time O(log(# runs)). +""" + +import bisect + +def intranges_from_list(list_): + """Represent a list of integers as a sequence of ranges: + ((start_0, end_0), (start_1, end_1), ...), such that the original + integers are exactly those x such that start_i <= x < end_i for some i. + + Ranges are encoded as single integers (start << 32 | end), not as tuples. + """ + + sorted_list = sorted(list_) + ranges = [] + last_write = -1 + for i in range(len(sorted_list)): + if i+1 < len(sorted_list): + if sorted_list[i] == sorted_list[i+1]-1: + continue + current_range = sorted_list[last_write+1:i+1] + ranges.append(_encode_range(current_range[0], current_range[-1] + 1)) + last_write = i + + return tuple(ranges) + +def _encode_range(start, end): + return (start << 32) | end + +def _decode_range(r): + return (r >> 32), (r & ((1 << 32) - 1)) + + +def intranges_contain(int_, ranges): + """Determine if `int_` falls into one of the ranges in `ranges`.""" + tuple_ = _encode_range(int_, 0) + pos = bisect.bisect_left(ranges, tuple_) + # we could be immediately ahead of a tuple (start, end) + # with start < int_ <= end + if pos > 0: + left, right = _decode_range(ranges[pos-1]) + if left <= int_ < right: + return True + # or we could be immediately behind a tuple (int_, end) + if pos < len(ranges): + left, _ = _decode_range(ranges[pos]) + if left == int_: + return True + return False diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/idna/package_data.py b/venv/lib/python3.7/site-packages/pip/_vendor/idna/package_data.py new file mode 100644 index 0000000..39c192b --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/idna/package_data.py @@ -0,0 +1,2 @@ +__version__ = '2.7' + diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/idna/uts46data.py b/venv/lib/python3.7/site-packages/pip/_vendor/idna/uts46data.py new file mode 100644 index 0000000..79731cb --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/idna/uts46data.py @@ -0,0 +1,8179 @@ +# This file is automatically generated by tools/idna-data +# vim: set fileencoding=utf-8 : + +"""IDNA Mapping Table from UTS46.""" + + +__version__ = "10.0.0" +def _seg_0(): + return [ + (0x0, '3'), + (0x1, '3'), + (0x2, '3'), + (0x3, '3'), + (0x4, '3'), + (0x5, '3'), + (0x6, '3'), + (0x7, '3'), + (0x8, '3'), + (0x9, '3'), + (0xA, '3'), + (0xB, '3'), + (0xC, '3'), + (0xD, '3'), + (0xE, '3'), + (0xF, '3'), + (0x10, '3'), + (0x11, '3'), + (0x12, '3'), + (0x13, '3'), + (0x14, '3'), + (0x15, '3'), + (0x16, '3'), + (0x17, '3'), + (0x18, '3'), + (0x19, '3'), + (0x1A, '3'), + (0x1B, '3'), + (0x1C, '3'), + (0x1D, '3'), + (0x1E, '3'), + (0x1F, '3'), + (0x20, '3'), + (0x21, '3'), + (0x22, '3'), + (0x23, '3'), + (0x24, '3'), + (0x25, '3'), + (0x26, '3'), + (0x27, '3'), + (0x28, '3'), + (0x29, '3'), + (0x2A, '3'), + (0x2B, '3'), + (0x2C, '3'), + (0x2D, 'V'), + (0x2E, 'V'), + (0x2F, '3'), + (0x30, 'V'), + (0x31, 'V'), + (0x32, 'V'), + (0x33, 'V'), + (0x34, 'V'), + (0x35, 'V'), + (0x36, 'V'), + (0x37, 'V'), + (0x38, 'V'), + (0x39, 'V'), + (0x3A, '3'), + (0x3B, '3'), + (0x3C, '3'), + (0x3D, '3'), + (0x3E, '3'), + (0x3F, '3'), + (0x40, '3'), + (0x41, 'M', u'a'), + (0x42, 'M', u'b'), + (0x43, 'M', u'c'), + (0x44, 'M', u'd'), + (0x45, 'M', u'e'), + (0x46, 'M', u'f'), + (0x47, 'M', u'g'), + (0x48, 'M', u'h'), + (0x49, 'M', u'i'), + (0x4A, 'M', u'j'), + (0x4B, 'M', u'k'), + (0x4C, 'M', u'l'), + (0x4D, 'M', u'm'), + (0x4E, 'M', u'n'), + (0x4F, 'M', u'o'), + (0x50, 'M', u'p'), + (0x51, 'M', u'q'), + (0x52, 'M', u'r'), + (0x53, 'M', u's'), + (0x54, 'M', u't'), + (0x55, 'M', u'u'), + (0x56, 'M', u'v'), + (0x57, 'M', u'w'), + (0x58, 'M', u'x'), + (0x59, 'M', u'y'), + (0x5A, 'M', u'z'), + (0x5B, '3'), + (0x5C, '3'), + (0x5D, '3'), + (0x5E, '3'), + (0x5F, '3'), + (0x60, '3'), + (0x61, 'V'), + (0x62, 'V'), + (0x63, 'V'), + ] + +def _seg_1(): + return [ + (0x64, 'V'), + (0x65, 'V'), + (0x66, 'V'), + (0x67, 'V'), + (0x68, 'V'), + (0x69, 'V'), + (0x6A, 'V'), + (0x6B, 'V'), + (0x6C, 'V'), + (0x6D, 'V'), + (0x6E, 'V'), + (0x6F, 'V'), + (0x70, 'V'), + (0x71, 'V'), + (0x72, 'V'), + (0x73, 'V'), + (0x74, 'V'), + (0x75, 'V'), + (0x76, 'V'), + (0x77, 'V'), + (0x78, 'V'), + (0x79, 'V'), + (0x7A, 'V'), + (0x7B, '3'), + (0x7C, '3'), + (0x7D, '3'), + (0x7E, '3'), + (0x7F, '3'), + (0x80, 'X'), + (0x81, 'X'), + (0x82, 'X'), + (0x83, 'X'), + (0x84, 'X'), + (0x85, 'X'), + (0x86, 'X'), + (0x87, 'X'), + (0x88, 'X'), + (0x89, 'X'), + (0x8A, 'X'), + (0x8B, 'X'), + (0x8C, 'X'), + (0x8D, 'X'), + (0x8E, 'X'), + (0x8F, 'X'), + (0x90, 'X'), + (0x91, 'X'), + (0x92, 'X'), + (0x93, 'X'), + (0x94, 'X'), + (0x95, 'X'), + (0x96, 'X'), + (0x97, 'X'), + (0x98, 'X'), + (0x99, 'X'), + (0x9A, 'X'), + (0x9B, 'X'), + (0x9C, 'X'), + (0x9D, 'X'), + (0x9E, 'X'), + (0x9F, 'X'), + (0xA0, '3', u' '), + (0xA1, 'V'), + (0xA2, 'V'), + (0xA3, 'V'), + (0xA4, 'V'), + (0xA5, 'V'), + (0xA6, 'V'), + (0xA7, 'V'), + (0xA8, '3', u' ̈'), + (0xA9, 'V'), + (0xAA, 'M', u'a'), + (0xAB, 'V'), + (0xAC, 'V'), + (0xAD, 'I'), + (0xAE, 'V'), + (0xAF, '3', u' ̄'), + (0xB0, 'V'), + (0xB1, 'V'), + (0xB2, 'M', u'2'), + (0xB3, 'M', u'3'), + (0xB4, '3', u' ́'), + (0xB5, 'M', u'μ'), + (0xB6, 'V'), + (0xB7, 'V'), + (0xB8, '3', u' ̧'), + (0xB9, 'M', u'1'), + (0xBA, 'M', u'o'), + (0xBB, 'V'), + (0xBC, 'M', u'1⁄4'), + (0xBD, 'M', u'1⁄2'), + (0xBE, 'M', u'3⁄4'), + (0xBF, 'V'), + (0xC0, 'M', u'à'), + (0xC1, 'M', u'á'), + (0xC2, 'M', u'â'), + (0xC3, 'M', u'ã'), + (0xC4, 'M', u'ä'), + (0xC5, 'M', u'å'), + (0xC6, 'M', u'æ'), + (0xC7, 'M', u'ç'), + ] + +def _seg_2(): + return [ + (0xC8, 'M', u'è'), + (0xC9, 'M', u'é'), + (0xCA, 'M', u'ê'), + (0xCB, 'M', u'ë'), + (0xCC, 'M', u'ì'), + (0xCD, 'M', u'í'), + (0xCE, 'M', u'î'), + (0xCF, 'M', u'ï'), + (0xD0, 'M', u'ð'), + (0xD1, 'M', u'ñ'), + (0xD2, 'M', u'ò'), + (0xD3, 'M', u'ó'), + (0xD4, 'M', u'ô'), + (0xD5, 'M', u'õ'), + (0xD6, 'M', u'ö'), + (0xD7, 'V'), + (0xD8, 'M', u'ø'), + (0xD9, 'M', u'ù'), + (0xDA, 'M', u'ú'), + (0xDB, 'M', u'û'), + (0xDC, 'M', u'ü'), + (0xDD, 'M', u'ý'), + (0xDE, 'M', u'þ'), + (0xDF, 'D', u'ss'), + (0xE0, 'V'), + (0xE1, 'V'), + (0xE2, 'V'), + (0xE3, 'V'), + (0xE4, 'V'), + (0xE5, 'V'), + (0xE6, 'V'), + (0xE7, 'V'), + (0xE8, 'V'), + (0xE9, 'V'), + (0xEA, 'V'), + (0xEB, 'V'), + (0xEC, 'V'), + (0xED, 'V'), + (0xEE, 'V'), + (0xEF, 'V'), + (0xF0, 'V'), + (0xF1, 'V'), + (0xF2, 'V'), + (0xF3, 'V'), + (0xF4, 'V'), + (0xF5, 'V'), + (0xF6, 'V'), + (0xF7, 'V'), + (0xF8, 'V'), + (0xF9, 'V'), + (0xFA, 'V'), + (0xFB, 'V'), + (0xFC, 'V'), + (0xFD, 'V'), + (0xFE, 'V'), + (0xFF, 'V'), + (0x100, 'M', u'ā'), + (0x101, 'V'), + (0x102, 'M', u'ă'), + (0x103, 'V'), + (0x104, 'M', u'ą'), + (0x105, 'V'), + (0x106, 'M', u'ć'), + (0x107, 'V'), + (0x108, 'M', u'ĉ'), + (0x109, 'V'), + (0x10A, 'M', u'ċ'), + (0x10B, 'V'), + (0x10C, 'M', u'č'), + (0x10D, 'V'), + (0x10E, 'M', u'ď'), + (0x10F, 'V'), + (0x110, 'M', u'đ'), + (0x111, 'V'), + (0x112, 'M', u'ē'), + (0x113, 'V'), + (0x114, 'M', u'ĕ'), + (0x115, 'V'), + (0x116, 'M', u'ė'), + (0x117, 'V'), + (0x118, 'M', u'ę'), + (0x119, 'V'), + (0x11A, 'M', u'ě'), + (0x11B, 'V'), + (0x11C, 'M', u'ĝ'), + (0x11D, 'V'), + (0x11E, 'M', u'ğ'), + (0x11F, 'V'), + (0x120, 'M', u'ġ'), + (0x121, 'V'), + (0x122, 'M', u'ģ'), + (0x123, 'V'), + (0x124, 'M', u'ĥ'), + (0x125, 'V'), + (0x126, 'M', u'ħ'), + (0x127, 'V'), + (0x128, 'M', u'ĩ'), + (0x129, 'V'), + (0x12A, 'M', u'ī'), + (0x12B, 'V'), + ] + +def _seg_3(): + return [ + (0x12C, 'M', u'ĭ'), + (0x12D, 'V'), + (0x12E, 'M', u'į'), + (0x12F, 'V'), + (0x130, 'M', u'i̇'), + (0x131, 'V'), + (0x132, 'M', u'ij'), + (0x134, 'M', u'ĵ'), + (0x135, 'V'), + (0x136, 'M', u'ķ'), + (0x137, 'V'), + (0x139, 'M', u'ĺ'), + (0x13A, 'V'), + (0x13B, 'M', u'ļ'), + (0x13C, 'V'), + (0x13D, 'M', u'ľ'), + (0x13E, 'V'), + (0x13F, 'M', u'l·'), + (0x141, 'M', u'ł'), + (0x142, 'V'), + (0x143, 'M', u'ń'), + (0x144, 'V'), + (0x145, 'M', u'ņ'), + (0x146, 'V'), + (0x147, 'M', u'ň'), + (0x148, 'V'), + (0x149, 'M', u'ʼn'), + (0x14A, 'M', u'ŋ'), + (0x14B, 'V'), + (0x14C, 'M', u'ō'), + (0x14D, 'V'), + (0x14E, 'M', u'ŏ'), + (0x14F, 'V'), + (0x150, 'M', u'ő'), + (0x151, 'V'), + (0x152, 'M', u'œ'), + (0x153, 'V'), + (0x154, 'M', u'ŕ'), + (0x155, 'V'), + (0x156, 'M', u'ŗ'), + (0x157, 'V'), + (0x158, 'M', u'ř'), + (0x159, 'V'), + (0x15A, 'M', u'ś'), + (0x15B, 'V'), + (0x15C, 'M', u'ŝ'), + (0x15D, 'V'), + (0x15E, 'M', u'ş'), + (0x15F, 'V'), + (0x160, 'M', u'š'), + (0x161, 'V'), + (0x162, 'M', u'ţ'), + (0x163, 'V'), + (0x164, 'M', u'ť'), + (0x165, 'V'), + (0x166, 'M', u'ŧ'), + (0x167, 'V'), + (0x168, 'M', u'ũ'), + (0x169, 'V'), + (0x16A, 'M', u'ū'), + (0x16B, 'V'), + (0x16C, 'M', u'ŭ'), + (0x16D, 'V'), + (0x16E, 'M', u'ů'), + (0x16F, 'V'), + (0x170, 'M', u'ű'), + (0x171, 'V'), + (0x172, 'M', u'ų'), + (0x173, 'V'), + (0x174, 'M', u'ŵ'), + (0x175, 'V'), + (0x176, 'M', u'ŷ'), + (0x177, 'V'), + (0x178, 'M', u'ÿ'), + (0x179, 'M', u'ź'), + (0x17A, 'V'), + (0x17B, 'M', u'ż'), + (0x17C, 'V'), + (0x17D, 'M', u'ž'), + (0x17E, 'V'), + (0x17F, 'M', u's'), + (0x180, 'V'), + (0x181, 'M', u'ɓ'), + (0x182, 'M', u'ƃ'), + (0x183, 'V'), + (0x184, 'M', u'ƅ'), + (0x185, 'V'), + (0x186, 'M', u'ɔ'), + (0x187, 'M', u'ƈ'), + (0x188, 'V'), + (0x189, 'M', u'ɖ'), + (0x18A, 'M', u'ɗ'), + (0x18B, 'M', u'ƌ'), + (0x18C, 'V'), + (0x18E, 'M', u'ǝ'), + (0x18F, 'M', u'ə'), + (0x190, 'M', u'ɛ'), + (0x191, 'M', u'ƒ'), + (0x192, 'V'), + (0x193, 'M', u'ɠ'), + ] + +def _seg_4(): + return [ + (0x194, 'M', u'ɣ'), + (0x195, 'V'), + (0x196, 'M', u'ɩ'), + (0x197, 'M', u'ɨ'), + (0x198, 'M', u'ƙ'), + (0x199, 'V'), + (0x19C, 'M', u'ɯ'), + (0x19D, 'M', u'ɲ'), + (0x19E, 'V'), + (0x19F, 'M', u'ɵ'), + (0x1A0, 'M', u'ơ'), + (0x1A1, 'V'), + (0x1A2, 'M', u'ƣ'), + (0x1A3, 'V'), + (0x1A4, 'M', u'ƥ'), + (0x1A5, 'V'), + (0x1A6, 'M', u'ʀ'), + (0x1A7, 'M', u'ƨ'), + (0x1A8, 'V'), + (0x1A9, 'M', u'ʃ'), + (0x1AA, 'V'), + (0x1AC, 'M', u'ƭ'), + (0x1AD, 'V'), + (0x1AE, 'M', u'ʈ'), + (0x1AF, 'M', u'ư'), + (0x1B0, 'V'), + (0x1B1, 'M', u'ʊ'), + (0x1B2, 'M', u'ʋ'), + (0x1B3, 'M', u'ƴ'), + (0x1B4, 'V'), + (0x1B5, 'M', u'ƶ'), + (0x1B6, 'V'), + (0x1B7, 'M', u'ʒ'), + (0x1B8, 'M', u'ƹ'), + (0x1B9, 'V'), + (0x1BC, 'M', u'ƽ'), + (0x1BD, 'V'), + (0x1C4, 'M', u'dž'), + (0x1C7, 'M', u'lj'), + (0x1CA, 'M', u'nj'), + (0x1CD, 'M', u'ǎ'), + (0x1CE, 'V'), + (0x1CF, 'M', u'ǐ'), + (0x1D0, 'V'), + (0x1D1, 'M', u'ǒ'), + (0x1D2, 'V'), + (0x1D3, 'M', u'ǔ'), + (0x1D4, 'V'), + (0x1D5, 'M', u'ǖ'), + (0x1D6, 'V'), + (0x1D7, 'M', u'ǘ'), + (0x1D8, 'V'), + (0x1D9, 'M', u'ǚ'), + (0x1DA, 'V'), + (0x1DB, 'M', u'ǜ'), + (0x1DC, 'V'), + (0x1DE, 'M', u'ǟ'), + (0x1DF, 'V'), + (0x1E0, 'M', u'ǡ'), + (0x1E1, 'V'), + (0x1E2, 'M', u'ǣ'), + (0x1E3, 'V'), + (0x1E4, 'M', u'ǥ'), + (0x1E5, 'V'), + (0x1E6, 'M', u'ǧ'), + (0x1E7, 'V'), + (0x1E8, 'M', u'ǩ'), + (0x1E9, 'V'), + (0x1EA, 'M', u'ǫ'), + (0x1EB, 'V'), + (0x1EC, 'M', u'ǭ'), + (0x1ED, 'V'), + (0x1EE, 'M', u'ǯ'), + (0x1EF, 'V'), + (0x1F1, 'M', u'dz'), + (0x1F4, 'M', u'ǵ'), + (0x1F5, 'V'), + (0x1F6, 'M', u'ƕ'), + (0x1F7, 'M', u'ƿ'), + (0x1F8, 'M', u'ǹ'), + (0x1F9, 'V'), + (0x1FA, 'M', u'ǻ'), + (0x1FB, 'V'), + (0x1FC, 'M', u'ǽ'), + (0x1FD, 'V'), + (0x1FE, 'M', u'ǿ'), + (0x1FF, 'V'), + (0x200, 'M', u'ȁ'), + (0x201, 'V'), + (0x202, 'M', u'ȃ'), + (0x203, 'V'), + (0x204, 'M', u'ȅ'), + (0x205, 'V'), + (0x206, 'M', u'ȇ'), + (0x207, 'V'), + (0x208, 'M', u'ȉ'), + (0x209, 'V'), + (0x20A, 'M', u'ȋ'), + (0x20B, 'V'), + (0x20C, 'M', u'ȍ'), + ] + +def _seg_5(): + return [ + (0x20D, 'V'), + (0x20E, 'M', u'ȏ'), + (0x20F, 'V'), + (0x210, 'M', u'ȑ'), + (0x211, 'V'), + (0x212, 'M', u'ȓ'), + (0x213, 'V'), + (0x214, 'M', u'ȕ'), + (0x215, 'V'), + (0x216, 'M', u'ȗ'), + (0x217, 'V'), + (0x218, 'M', u'ș'), + (0x219, 'V'), + (0x21A, 'M', u'ț'), + (0x21B, 'V'), + (0x21C, 'M', u'ȝ'), + (0x21D, 'V'), + (0x21E, 'M', u'ȟ'), + (0x21F, 'V'), + (0x220, 'M', u'ƞ'), + (0x221, 'V'), + (0x222, 'M', u'ȣ'), + (0x223, 'V'), + (0x224, 'M', u'ȥ'), + (0x225, 'V'), + (0x226, 'M', u'ȧ'), + (0x227, 'V'), + (0x228, 'M', u'ȩ'), + (0x229, 'V'), + (0x22A, 'M', u'ȫ'), + (0x22B, 'V'), + (0x22C, 'M', u'ȭ'), + (0x22D, 'V'), + (0x22E, 'M', u'ȯ'), + (0x22F, 'V'), + (0x230, 'M', u'ȱ'), + (0x231, 'V'), + (0x232, 'M', u'ȳ'), + (0x233, 'V'), + (0x23A, 'M', u'ⱥ'), + (0x23B, 'M', u'ȼ'), + (0x23C, 'V'), + (0x23D, 'M', u'ƚ'), + (0x23E, 'M', u'ⱦ'), + (0x23F, 'V'), + (0x241, 'M', u'ɂ'), + (0x242, 'V'), + (0x243, 'M', u'ƀ'), + (0x244, 'M', u'ʉ'), + (0x245, 'M', u'ʌ'), + (0x246, 'M', u'ɇ'), + (0x247, 'V'), + (0x248, 'M', u'ɉ'), + (0x249, 'V'), + (0x24A, 'M', u'ɋ'), + (0x24B, 'V'), + (0x24C, 'M', u'ɍ'), + (0x24D, 'V'), + (0x24E, 'M', u'ɏ'), + (0x24F, 'V'), + (0x2B0, 'M', u'h'), + (0x2B1, 'M', u'ɦ'), + (0x2B2, 'M', u'j'), + (0x2B3, 'M', u'r'), + (0x2B4, 'M', u'ɹ'), + (0x2B5, 'M', u'ɻ'), + (0x2B6, 'M', u'ʁ'), + (0x2B7, 'M', u'w'), + (0x2B8, 'M', u'y'), + (0x2B9, 'V'), + (0x2D8, '3', u' ̆'), + (0x2D9, '3', u' ̇'), + (0x2DA, '3', u' ̊'), + (0x2DB, '3', u' ̨'), + (0x2DC, '3', u' ̃'), + (0x2DD, '3', u' ̋'), + (0x2DE, 'V'), + (0x2E0, 'M', u'ɣ'), + (0x2E1, 'M', u'l'), + (0x2E2, 'M', u's'), + (0x2E3, 'M', u'x'), + (0x2E4, 'M', u'ʕ'), + (0x2E5, 'V'), + (0x340, 'M', u'̀'), + (0x341, 'M', u'́'), + (0x342, 'V'), + (0x343, 'M', u'̓'), + (0x344, 'M', u'̈́'), + (0x345, 'M', u'ι'), + (0x346, 'V'), + (0x34F, 'I'), + (0x350, 'V'), + (0x370, 'M', u'ͱ'), + (0x371, 'V'), + (0x372, 'M', u'ͳ'), + (0x373, 'V'), + (0x374, 'M', u'ʹ'), + (0x375, 'V'), + (0x376, 'M', u'ͷ'), + (0x377, 'V'), + ] + +def _seg_6(): + return [ + (0x378, 'X'), + (0x37A, '3', u' ι'), + (0x37B, 'V'), + (0x37E, '3', u';'), + (0x37F, 'M', u'ϳ'), + (0x380, 'X'), + (0x384, '3', u' ́'), + (0x385, '3', u' ̈́'), + (0x386, 'M', u'ά'), + (0x387, 'M', u'·'), + (0x388, 'M', u'έ'), + (0x389, 'M', u'ή'), + (0x38A, 'M', u'ί'), + (0x38B, 'X'), + (0x38C, 'M', u'ό'), + (0x38D, 'X'), + (0x38E, 'M', u'ύ'), + (0x38F, 'M', u'ώ'), + (0x390, 'V'), + (0x391, 'M', u'α'), + (0x392, 'M', u'β'), + (0x393, 'M', u'γ'), + (0x394, 'M', u'δ'), + (0x395, 'M', u'ε'), + (0x396, 'M', u'ζ'), + (0x397, 'M', u'η'), + (0x398, 'M', u'θ'), + (0x399, 'M', u'ι'), + (0x39A, 'M', u'κ'), + (0x39B, 'M', u'λ'), + (0x39C, 'M', u'μ'), + (0x39D, 'M', u'ν'), + (0x39E, 'M', u'ξ'), + (0x39F, 'M', u'ο'), + (0x3A0, 'M', u'π'), + (0x3A1, 'M', u'ρ'), + (0x3A2, 'X'), + (0x3A3, 'M', u'σ'), + (0x3A4, 'M', u'τ'), + (0x3A5, 'M', u'υ'), + (0x3A6, 'M', u'φ'), + (0x3A7, 'M', u'χ'), + (0x3A8, 'M', u'ψ'), + (0x3A9, 'M', u'ω'), + (0x3AA, 'M', u'ϊ'), + (0x3AB, 'M', u'ϋ'), + (0x3AC, 'V'), + (0x3C2, 'D', u'σ'), + (0x3C3, 'V'), + (0x3CF, 'M', u'ϗ'), + (0x3D0, 'M', u'β'), + (0x3D1, 'M', u'θ'), + (0x3D2, 'M', u'υ'), + (0x3D3, 'M', u'ύ'), + (0x3D4, 'M', u'ϋ'), + (0x3D5, 'M', u'φ'), + (0x3D6, 'M', u'π'), + (0x3D7, 'V'), + (0x3D8, 'M', u'ϙ'), + (0x3D9, 'V'), + (0x3DA, 'M', u'ϛ'), + (0x3DB, 'V'), + (0x3DC, 'M', u'ϝ'), + (0x3DD, 'V'), + (0x3DE, 'M', u'ϟ'), + (0x3DF, 'V'), + (0x3E0, 'M', u'ϡ'), + (0x3E1, 'V'), + (0x3E2, 'M', u'ϣ'), + (0x3E3, 'V'), + (0x3E4, 'M', u'ϥ'), + (0x3E5, 'V'), + (0x3E6, 'M', u'ϧ'), + (0x3E7, 'V'), + (0x3E8, 'M', u'ϩ'), + (0x3E9, 'V'), + (0x3EA, 'M', u'ϫ'), + (0x3EB, 'V'), + (0x3EC, 'M', u'ϭ'), + (0x3ED, 'V'), + (0x3EE, 'M', u'ϯ'), + (0x3EF, 'V'), + (0x3F0, 'M', u'κ'), + (0x3F1, 'M', u'ρ'), + (0x3F2, 'M', u'σ'), + (0x3F3, 'V'), + (0x3F4, 'M', u'θ'), + (0x3F5, 'M', u'ε'), + (0x3F6, 'V'), + (0x3F7, 'M', u'ϸ'), + (0x3F8, 'V'), + (0x3F9, 'M', u'σ'), + (0x3FA, 'M', u'ϻ'), + (0x3FB, 'V'), + (0x3FD, 'M', u'ͻ'), + (0x3FE, 'M', u'ͼ'), + (0x3FF, 'M', u'ͽ'), + (0x400, 'M', u'ѐ'), + (0x401, 'M', u'ё'), + (0x402, 'M', u'ђ'), + ] + +def _seg_7(): + return [ + (0x403, 'M', u'ѓ'), + (0x404, 'M', u'є'), + (0x405, 'M', u'ѕ'), + (0x406, 'M', u'і'), + (0x407, 'M', u'ї'), + (0x408, 'M', u'ј'), + (0x409, 'M', u'љ'), + (0x40A, 'M', u'њ'), + (0x40B, 'M', u'ћ'), + (0x40C, 'M', u'ќ'), + (0x40D, 'M', u'ѝ'), + (0x40E, 'M', u'ў'), + (0x40F, 'M', u'џ'), + (0x410, 'M', u'а'), + (0x411, 'M', u'б'), + (0x412, 'M', u'в'), + (0x413, 'M', u'г'), + (0x414, 'M', u'д'), + (0x415, 'M', u'е'), + (0x416, 'M', u'ж'), + (0x417, 'M', u'з'), + (0x418, 'M', u'и'), + (0x419, 'M', u'й'), + (0x41A, 'M', u'к'), + (0x41B, 'M', u'л'), + (0x41C, 'M', u'м'), + (0x41D, 'M', u'н'), + (0x41E, 'M', u'о'), + (0x41F, 'M', u'п'), + (0x420, 'M', u'р'), + (0x421, 'M', u'с'), + (0x422, 'M', u'т'), + (0x423, 'M', u'у'), + (0x424, 'M', u'ф'), + (0x425, 'M', u'х'), + (0x426, 'M', u'ц'), + (0x427, 'M', u'ч'), + (0x428, 'M', u'ш'), + (0x429, 'M', u'щ'), + (0x42A, 'M', u'ъ'), + (0x42B, 'M', u'ы'), + (0x42C, 'M', u'ь'), + (0x42D, 'M', u'э'), + (0x42E, 'M', u'ю'), + (0x42F, 'M', u'я'), + (0x430, 'V'), + (0x460, 'M', u'ѡ'), + (0x461, 'V'), + (0x462, 'M', u'ѣ'), + (0x463, 'V'), + (0x464, 'M', u'ѥ'), + (0x465, 'V'), + (0x466, 'M', u'ѧ'), + (0x467, 'V'), + (0x468, 'M', u'ѩ'), + (0x469, 'V'), + (0x46A, 'M', u'ѫ'), + (0x46B, 'V'), + (0x46C, 'M', u'ѭ'), + (0x46D, 'V'), + (0x46E, 'M', u'ѯ'), + (0x46F, 'V'), + (0x470, 'M', u'ѱ'), + (0x471, 'V'), + (0x472, 'M', u'ѳ'), + (0x473, 'V'), + (0x474, 'M', u'ѵ'), + (0x475, 'V'), + (0x476, 'M', u'ѷ'), + (0x477, 'V'), + (0x478, 'M', u'ѹ'), + (0x479, 'V'), + (0x47A, 'M', u'ѻ'), + (0x47B, 'V'), + (0x47C, 'M', u'ѽ'), + (0x47D, 'V'), + (0x47E, 'M', u'ѿ'), + (0x47F, 'V'), + (0x480, 'M', u'ҁ'), + (0x481, 'V'), + (0x48A, 'M', u'ҋ'), + (0x48B, 'V'), + (0x48C, 'M', u'ҍ'), + (0x48D, 'V'), + (0x48E, 'M', u'ҏ'), + (0x48F, 'V'), + (0x490, 'M', u'ґ'), + (0x491, 'V'), + (0x492, 'M', u'ғ'), + (0x493, 'V'), + (0x494, 'M', u'ҕ'), + (0x495, 'V'), + (0x496, 'M', u'җ'), + (0x497, 'V'), + (0x498, 'M', u'ҙ'), + (0x499, 'V'), + (0x49A, 'M', u'қ'), + (0x49B, 'V'), + (0x49C, 'M', u'ҝ'), + (0x49D, 'V'), + ] + +def _seg_8(): + return [ + (0x49E, 'M', u'ҟ'), + (0x49F, 'V'), + (0x4A0, 'M', u'ҡ'), + (0x4A1, 'V'), + (0x4A2, 'M', u'ң'), + (0x4A3, 'V'), + (0x4A4, 'M', u'ҥ'), + (0x4A5, 'V'), + (0x4A6, 'M', u'ҧ'), + (0x4A7, 'V'), + (0x4A8, 'M', u'ҩ'), + (0x4A9, 'V'), + (0x4AA, 'M', u'ҫ'), + (0x4AB, 'V'), + (0x4AC, 'M', u'ҭ'), + (0x4AD, 'V'), + (0x4AE, 'M', u'ү'), + (0x4AF, 'V'), + (0x4B0, 'M', u'ұ'), + (0x4B1, 'V'), + (0x4B2, 'M', u'ҳ'), + (0x4B3, 'V'), + (0x4B4, 'M', u'ҵ'), + (0x4B5, 'V'), + (0x4B6, 'M', u'ҷ'), + (0x4B7, 'V'), + (0x4B8, 'M', u'ҹ'), + (0x4B9, 'V'), + (0x4BA, 'M', u'һ'), + (0x4BB, 'V'), + (0x4BC, 'M', u'ҽ'), + (0x4BD, 'V'), + (0x4BE, 'M', u'ҿ'), + (0x4BF, 'V'), + (0x4C0, 'X'), + (0x4C1, 'M', u'ӂ'), + (0x4C2, 'V'), + (0x4C3, 'M', u'ӄ'), + (0x4C4, 'V'), + (0x4C5, 'M', u'ӆ'), + (0x4C6, 'V'), + (0x4C7, 'M', u'ӈ'), + (0x4C8, 'V'), + (0x4C9, 'M', u'ӊ'), + (0x4CA, 'V'), + (0x4CB, 'M', u'ӌ'), + (0x4CC, 'V'), + (0x4CD, 'M', u'ӎ'), + (0x4CE, 'V'), + (0x4D0, 'M', u'ӑ'), + (0x4D1, 'V'), + (0x4D2, 'M', u'ӓ'), + (0x4D3, 'V'), + (0x4D4, 'M', u'ӕ'), + (0x4D5, 'V'), + (0x4D6, 'M', u'ӗ'), + (0x4D7, 'V'), + (0x4D8, 'M', u'ә'), + (0x4D9, 'V'), + (0x4DA, 'M', u'ӛ'), + (0x4DB, 'V'), + (0x4DC, 'M', u'ӝ'), + (0x4DD, 'V'), + (0x4DE, 'M', u'ӟ'), + (0x4DF, 'V'), + (0x4E0, 'M', u'ӡ'), + (0x4E1, 'V'), + (0x4E2, 'M', u'ӣ'), + (0x4E3, 'V'), + (0x4E4, 'M', u'ӥ'), + (0x4E5, 'V'), + (0x4E6, 'M', u'ӧ'), + (0x4E7, 'V'), + (0x4E8, 'M', u'ө'), + (0x4E9, 'V'), + (0x4EA, 'M', u'ӫ'), + (0x4EB, 'V'), + (0x4EC, 'M', u'ӭ'), + (0x4ED, 'V'), + (0x4EE, 'M', u'ӯ'), + (0x4EF, 'V'), + (0x4F0, 'M', u'ӱ'), + (0x4F1, 'V'), + (0x4F2, 'M', u'ӳ'), + (0x4F3, 'V'), + (0x4F4, 'M', u'ӵ'), + (0x4F5, 'V'), + (0x4F6, 'M', u'ӷ'), + (0x4F7, 'V'), + (0x4F8, 'M', u'ӹ'), + (0x4F9, 'V'), + (0x4FA, 'M', u'ӻ'), + (0x4FB, 'V'), + (0x4FC, 'M', u'ӽ'), + (0x4FD, 'V'), + (0x4FE, 'M', u'ӿ'), + (0x4FF, 'V'), + (0x500, 'M', u'ԁ'), + (0x501, 'V'), + (0x502, 'M', u'ԃ'), + ] + +def _seg_9(): + return [ + (0x503, 'V'), + (0x504, 'M', u'ԅ'), + (0x505, 'V'), + (0x506, 'M', u'ԇ'), + (0x507, 'V'), + (0x508, 'M', u'ԉ'), + (0x509, 'V'), + (0x50A, 'M', u'ԋ'), + (0x50B, 'V'), + (0x50C, 'M', u'ԍ'), + (0x50D, 'V'), + (0x50E, 'M', u'ԏ'), + (0x50F, 'V'), + (0x510, 'M', u'ԑ'), + (0x511, 'V'), + (0x512, 'M', u'ԓ'), + (0x513, 'V'), + (0x514, 'M', u'ԕ'), + (0x515, 'V'), + (0x516, 'M', u'ԗ'), + (0x517, 'V'), + (0x518, 'M', u'ԙ'), + (0x519, 'V'), + (0x51A, 'M', u'ԛ'), + (0x51B, 'V'), + (0x51C, 'M', u'ԝ'), + (0x51D, 'V'), + (0x51E, 'M', u'ԟ'), + (0x51F, 'V'), + (0x520, 'M', u'ԡ'), + (0x521, 'V'), + (0x522, 'M', u'ԣ'), + (0x523, 'V'), + (0x524, 'M', u'ԥ'), + (0x525, 'V'), + (0x526, 'M', u'ԧ'), + (0x527, 'V'), + (0x528, 'M', u'ԩ'), + (0x529, 'V'), + (0x52A, 'M', u'ԫ'), + (0x52B, 'V'), + (0x52C, 'M', u'ԭ'), + (0x52D, 'V'), + (0x52E, 'M', u'ԯ'), + (0x52F, 'V'), + (0x530, 'X'), + (0x531, 'M', u'ա'), + (0x532, 'M', u'բ'), + (0x533, 'M', u'գ'), + (0x534, 'M', u'դ'), + (0x535, 'M', u'ե'), + (0x536, 'M', u'զ'), + (0x537, 'M', u'է'), + (0x538, 'M', u'ը'), + (0x539, 'M', u'թ'), + (0x53A, 'M', u'ժ'), + (0x53B, 'M', u'ի'), + (0x53C, 'M', u'լ'), + (0x53D, 'M', u'խ'), + (0x53E, 'M', u'ծ'), + (0x53F, 'M', u'կ'), + (0x540, 'M', u'հ'), + (0x541, 'M', u'ձ'), + (0x542, 'M', u'ղ'), + (0x543, 'M', u'ճ'), + (0x544, 'M', u'մ'), + (0x545, 'M', u'յ'), + (0x546, 'M', u'ն'), + (0x547, 'M', u'շ'), + (0x548, 'M', u'ո'), + (0x549, 'M', u'չ'), + (0x54A, 'M', u'պ'), + (0x54B, 'M', u'ջ'), + (0x54C, 'M', u'ռ'), + (0x54D, 'M', u'ս'), + (0x54E, 'M', u'վ'), + (0x54F, 'M', u'տ'), + (0x550, 'M', u'ր'), + (0x551, 'M', u'ց'), + (0x552, 'M', u'ւ'), + (0x553, 'M', u'փ'), + (0x554, 'M', u'ք'), + (0x555, 'M', u'օ'), + (0x556, 'M', u'ֆ'), + (0x557, 'X'), + (0x559, 'V'), + (0x560, 'X'), + (0x561, 'V'), + (0x587, 'M', u'եւ'), + (0x588, 'X'), + (0x589, 'V'), + (0x58B, 'X'), + (0x58D, 'V'), + (0x590, 'X'), + (0x591, 'V'), + (0x5C8, 'X'), + (0x5D0, 'V'), + (0x5EB, 'X'), + (0x5F0, 'V'), + (0x5F5, 'X'), + ] + +def _seg_10(): + return [ + (0x606, 'V'), + (0x61C, 'X'), + (0x61E, 'V'), + (0x675, 'M', u'اٴ'), + (0x676, 'M', u'وٴ'), + (0x677, 'M', u'ۇٴ'), + (0x678, 'M', u'يٴ'), + (0x679, 'V'), + (0x6DD, 'X'), + (0x6DE, 'V'), + (0x70E, 'X'), + (0x710, 'V'), + (0x74B, 'X'), + (0x74D, 'V'), + (0x7B2, 'X'), + (0x7C0, 'V'), + (0x7FB, 'X'), + (0x800, 'V'), + (0x82E, 'X'), + (0x830, 'V'), + (0x83F, 'X'), + (0x840, 'V'), + (0x85C, 'X'), + (0x85E, 'V'), + (0x85F, 'X'), + (0x860, 'V'), + (0x86B, 'X'), + (0x8A0, 'V'), + (0x8B5, 'X'), + (0x8B6, 'V'), + (0x8BE, 'X'), + (0x8D4, 'V'), + (0x8E2, 'X'), + (0x8E3, 'V'), + (0x958, 'M', u'क़'), + (0x959, 'M', u'ख़'), + (0x95A, 'M', u'ग़'), + (0x95B, 'M', u'ज़'), + (0x95C, 'M', u'ड़'), + (0x95D, 'M', u'ढ़'), + (0x95E, 'M', u'फ़'), + (0x95F, 'M', u'य़'), + (0x960, 'V'), + (0x984, 'X'), + (0x985, 'V'), + (0x98D, 'X'), + (0x98F, 'V'), + (0x991, 'X'), + (0x993, 'V'), + (0x9A9, 'X'), + (0x9AA, 'V'), + (0x9B1, 'X'), + (0x9B2, 'V'), + (0x9B3, 'X'), + (0x9B6, 'V'), + (0x9BA, 'X'), + (0x9BC, 'V'), + (0x9C5, 'X'), + (0x9C7, 'V'), + (0x9C9, 'X'), + (0x9CB, 'V'), + (0x9CF, 'X'), + (0x9D7, 'V'), + (0x9D8, 'X'), + (0x9DC, 'M', u'ড়'), + (0x9DD, 'M', u'ঢ়'), + (0x9DE, 'X'), + (0x9DF, 'M', u'য়'), + (0x9E0, 'V'), + (0x9E4, 'X'), + (0x9E6, 'V'), + (0x9FE, 'X'), + (0xA01, 'V'), + (0xA04, 'X'), + (0xA05, 'V'), + (0xA0B, 'X'), + (0xA0F, 'V'), + (0xA11, 'X'), + (0xA13, 'V'), + (0xA29, 'X'), + (0xA2A, 'V'), + (0xA31, 'X'), + (0xA32, 'V'), + (0xA33, 'M', u'ਲ਼'), + (0xA34, 'X'), + (0xA35, 'V'), + (0xA36, 'M', u'ਸ਼'), + (0xA37, 'X'), + (0xA38, 'V'), + (0xA3A, 'X'), + (0xA3C, 'V'), + (0xA3D, 'X'), + (0xA3E, 'V'), + (0xA43, 'X'), + (0xA47, 'V'), + (0xA49, 'X'), + (0xA4B, 'V'), + (0xA4E, 'X'), + (0xA51, 'V'), + (0xA52, 'X'), + ] + +def _seg_11(): + return [ + (0xA59, 'M', u'ਖ਼'), + (0xA5A, 'M', u'ਗ਼'), + (0xA5B, 'M', u'ਜ਼'), + (0xA5C, 'V'), + (0xA5D, 'X'), + (0xA5E, 'M', u'ਫ਼'), + (0xA5F, 'X'), + (0xA66, 'V'), + (0xA76, 'X'), + (0xA81, 'V'), + (0xA84, 'X'), + (0xA85, 'V'), + (0xA8E, 'X'), + (0xA8F, 'V'), + (0xA92, 'X'), + (0xA93, 'V'), + (0xAA9, 'X'), + (0xAAA, 'V'), + (0xAB1, 'X'), + (0xAB2, 'V'), + (0xAB4, 'X'), + (0xAB5, 'V'), + (0xABA, 'X'), + (0xABC, 'V'), + (0xAC6, 'X'), + (0xAC7, 'V'), + (0xACA, 'X'), + (0xACB, 'V'), + (0xACE, 'X'), + (0xAD0, 'V'), + (0xAD1, 'X'), + (0xAE0, 'V'), + (0xAE4, 'X'), + (0xAE6, 'V'), + (0xAF2, 'X'), + (0xAF9, 'V'), + (0xB00, 'X'), + (0xB01, 'V'), + (0xB04, 'X'), + (0xB05, 'V'), + (0xB0D, 'X'), + (0xB0F, 'V'), + (0xB11, 'X'), + (0xB13, 'V'), + (0xB29, 'X'), + (0xB2A, 'V'), + (0xB31, 'X'), + (0xB32, 'V'), + (0xB34, 'X'), + (0xB35, 'V'), + (0xB3A, 'X'), + (0xB3C, 'V'), + (0xB45, 'X'), + (0xB47, 'V'), + (0xB49, 'X'), + (0xB4B, 'V'), + (0xB4E, 'X'), + (0xB56, 'V'), + (0xB58, 'X'), + (0xB5C, 'M', u'ଡ଼'), + (0xB5D, 'M', u'ଢ଼'), + (0xB5E, 'X'), + (0xB5F, 'V'), + (0xB64, 'X'), + (0xB66, 'V'), + (0xB78, 'X'), + (0xB82, 'V'), + (0xB84, 'X'), + (0xB85, 'V'), + (0xB8B, 'X'), + (0xB8E, 'V'), + (0xB91, 'X'), + (0xB92, 'V'), + (0xB96, 'X'), + (0xB99, 'V'), + (0xB9B, 'X'), + (0xB9C, 'V'), + (0xB9D, 'X'), + (0xB9E, 'V'), + (0xBA0, 'X'), + (0xBA3, 'V'), + (0xBA5, 'X'), + (0xBA8, 'V'), + (0xBAB, 'X'), + (0xBAE, 'V'), + (0xBBA, 'X'), + (0xBBE, 'V'), + (0xBC3, 'X'), + (0xBC6, 'V'), + (0xBC9, 'X'), + (0xBCA, 'V'), + (0xBCE, 'X'), + (0xBD0, 'V'), + (0xBD1, 'X'), + (0xBD7, 'V'), + (0xBD8, 'X'), + (0xBE6, 'V'), + (0xBFB, 'X'), + (0xC00, 'V'), + (0xC04, 'X'), + ] + +def _seg_12(): + return [ + (0xC05, 'V'), + (0xC0D, 'X'), + (0xC0E, 'V'), + (0xC11, 'X'), + (0xC12, 'V'), + (0xC29, 'X'), + (0xC2A, 'V'), + (0xC3A, 'X'), + (0xC3D, 'V'), + (0xC45, 'X'), + (0xC46, 'V'), + (0xC49, 'X'), + (0xC4A, 'V'), + (0xC4E, 'X'), + (0xC55, 'V'), + (0xC57, 'X'), + (0xC58, 'V'), + (0xC5B, 'X'), + (0xC60, 'V'), + (0xC64, 'X'), + (0xC66, 'V'), + (0xC70, 'X'), + (0xC78, 'V'), + (0xC84, 'X'), + (0xC85, 'V'), + (0xC8D, 'X'), + (0xC8E, 'V'), + (0xC91, 'X'), + (0xC92, 'V'), + (0xCA9, 'X'), + (0xCAA, 'V'), + (0xCB4, 'X'), + (0xCB5, 'V'), + (0xCBA, 'X'), + (0xCBC, 'V'), + (0xCC5, 'X'), + (0xCC6, 'V'), + (0xCC9, 'X'), + (0xCCA, 'V'), + (0xCCE, 'X'), + (0xCD5, 'V'), + (0xCD7, 'X'), + (0xCDE, 'V'), + (0xCDF, 'X'), + (0xCE0, 'V'), + (0xCE4, 'X'), + (0xCE6, 'V'), + (0xCF0, 'X'), + (0xCF1, 'V'), + (0xCF3, 'X'), + (0xD00, 'V'), + (0xD04, 'X'), + (0xD05, 'V'), + (0xD0D, 'X'), + (0xD0E, 'V'), + (0xD11, 'X'), + (0xD12, 'V'), + (0xD45, 'X'), + (0xD46, 'V'), + (0xD49, 'X'), + (0xD4A, 'V'), + (0xD50, 'X'), + (0xD54, 'V'), + (0xD64, 'X'), + (0xD66, 'V'), + (0xD80, 'X'), + (0xD82, 'V'), + (0xD84, 'X'), + (0xD85, 'V'), + (0xD97, 'X'), + (0xD9A, 'V'), + (0xDB2, 'X'), + (0xDB3, 'V'), + (0xDBC, 'X'), + (0xDBD, 'V'), + (0xDBE, 'X'), + (0xDC0, 'V'), + (0xDC7, 'X'), + (0xDCA, 'V'), + (0xDCB, 'X'), + (0xDCF, 'V'), + (0xDD5, 'X'), + (0xDD6, 'V'), + (0xDD7, 'X'), + (0xDD8, 'V'), + (0xDE0, 'X'), + (0xDE6, 'V'), + (0xDF0, 'X'), + (0xDF2, 'V'), + (0xDF5, 'X'), + (0xE01, 'V'), + (0xE33, 'M', u'ํา'), + (0xE34, 'V'), + (0xE3B, 'X'), + (0xE3F, 'V'), + (0xE5C, 'X'), + (0xE81, 'V'), + (0xE83, 'X'), + (0xE84, 'V'), + (0xE85, 'X'), + ] + +def _seg_13(): + return [ + (0xE87, 'V'), + (0xE89, 'X'), + (0xE8A, 'V'), + (0xE8B, 'X'), + (0xE8D, 'V'), + (0xE8E, 'X'), + (0xE94, 'V'), + (0xE98, 'X'), + (0xE99, 'V'), + (0xEA0, 'X'), + (0xEA1, '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'), + (0xEBE, 'X'), + (0xEC0, 'V'), + (0xEC5, 'X'), + (0xEC6, 'V'), + (0xEC7, 'X'), + (0xEC8, 'V'), + (0xECE, 'X'), + (0xED0, 'V'), + (0xEDA, 'X'), + (0xEDC, 'M', u'ຫນ'), + (0xEDD, 'M', u'ຫມ'), + (0xEDE, 'V'), + (0xEE0, 'X'), + (0xF00, 'V'), + (0xF0C, 'M', u'་'), + (0xF0D, 'V'), + (0xF43, 'M', u'གྷ'), + (0xF44, 'V'), + (0xF48, 'X'), + (0xF49, 'V'), + (0xF4D, 'M', u'ཌྷ'), + (0xF4E, 'V'), + (0xF52, 'M', u'དྷ'), + (0xF53, 'V'), + (0xF57, 'M', u'བྷ'), + (0xF58, 'V'), + (0xF5C, 'M', u'ཛྷ'), + (0xF5D, 'V'), + (0xF69, 'M', u'ཀྵ'), + (0xF6A, 'V'), + (0xF6D, 'X'), + (0xF71, 'V'), + (0xF73, 'M', u'ཱི'), + (0xF74, 'V'), + (0xF75, 'M', u'ཱུ'), + (0xF76, 'M', u'ྲྀ'), + (0xF77, 'M', u'ྲཱྀ'), + (0xF78, 'M', u'ླྀ'), + (0xF79, 'M', u'ླཱྀ'), + (0xF7A, 'V'), + (0xF81, 'M', u'ཱྀ'), + (0xF82, 'V'), + (0xF93, 'M', u'ྒྷ'), + (0xF94, 'V'), + (0xF98, 'X'), + (0xF99, 'V'), + (0xF9D, 'M', u'ྜྷ'), + (0xF9E, 'V'), + (0xFA2, 'M', u'ྡྷ'), + (0xFA3, 'V'), + (0xFA7, 'M', u'ྦྷ'), + (0xFA8, 'V'), + (0xFAC, 'M', u'ྫྷ'), + (0xFAD, 'V'), + (0xFB9, 'M', u'ྐྵ'), + (0xFBA, 'V'), + (0xFBD, 'X'), + (0xFBE, 'V'), + (0xFCD, 'X'), + (0xFCE, 'V'), + (0xFDB, 'X'), + (0x1000, 'V'), + (0x10A0, 'X'), + (0x10C7, 'M', u'ⴧ'), + (0x10C8, 'X'), + (0x10CD, 'M', u'ⴭ'), + (0x10CE, 'X'), + (0x10D0, 'V'), + (0x10FC, 'M', u'ნ'), + (0x10FD, 'V'), + (0x115F, 'X'), + (0x1161, 'V'), + (0x1249, 'X'), + (0x124A, 'V'), + (0x124E, 'X'), + (0x1250, 'V'), + (0x1257, 'X'), + ] + +def _seg_14(): + return [ + (0x1258, 'V'), + (0x1259, 'X'), + (0x125A, 'V'), + (0x125E, 'X'), + (0x1260, 'V'), + (0x1289, 'X'), + (0x128A, 'V'), + (0x128E, 'X'), + (0x1290, 'V'), + (0x12B1, 'X'), + (0x12B2, 'V'), + (0x12B6, 'X'), + (0x12B8, 'V'), + (0x12BF, 'X'), + (0x12C0, 'V'), + (0x12C1, 'X'), + (0x12C2, 'V'), + (0x12C6, 'X'), + (0x12C8, 'V'), + (0x12D7, 'X'), + (0x12D8, 'V'), + (0x1311, 'X'), + (0x1312, 'V'), + (0x1316, 'X'), + (0x1318, 'V'), + (0x135B, 'X'), + (0x135D, 'V'), + (0x137D, 'X'), + (0x1380, 'V'), + (0x139A, 'X'), + (0x13A0, 'V'), + (0x13F6, 'X'), + (0x13F8, 'M', u'Ᏸ'), + (0x13F9, 'M', u'Ᏹ'), + (0x13FA, 'M', u'Ᏺ'), + (0x13FB, 'M', u'Ᏻ'), + (0x13FC, 'M', u'Ᏼ'), + (0x13FD, 'M', u'Ᏽ'), + (0x13FE, 'X'), + (0x1400, 'V'), + (0x1680, 'X'), + (0x1681, 'V'), + (0x169D, 'X'), + (0x16A0, 'V'), + (0x16F9, 'X'), + (0x1700, 'V'), + (0x170D, 'X'), + (0x170E, 'V'), + (0x1715, 'X'), + (0x1720, 'V'), + (0x1737, 'X'), + (0x1740, 'V'), + (0x1754, 'X'), + (0x1760, 'V'), + (0x176D, 'X'), + (0x176E, 'V'), + (0x1771, 'X'), + (0x1772, 'V'), + (0x1774, 'X'), + (0x1780, 'V'), + (0x17B4, 'X'), + (0x17B6, 'V'), + (0x17DE, 'X'), + (0x17E0, 'V'), + (0x17EA, 'X'), + (0x17F0, 'V'), + (0x17FA, 'X'), + (0x1800, 'V'), + (0x1806, 'X'), + (0x1807, 'V'), + (0x180B, 'I'), + (0x180E, 'X'), + (0x1810, 'V'), + (0x181A, 'X'), + (0x1820, 'V'), + (0x1878, 'X'), + (0x1880, 'V'), + (0x18AB, 'X'), + (0x18B0, 'V'), + (0x18F6, 'X'), + (0x1900, 'V'), + (0x191F, 'X'), + (0x1920, 'V'), + (0x192C, 'X'), + (0x1930, 'V'), + (0x193C, 'X'), + (0x1940, 'V'), + (0x1941, 'X'), + (0x1944, 'V'), + (0x196E, 'X'), + (0x1970, 'V'), + (0x1975, 'X'), + (0x1980, 'V'), + (0x19AC, 'X'), + (0x19B0, 'V'), + (0x19CA, 'X'), + (0x19D0, 'V'), + (0x19DB, 'X'), + (0x19DE, 'V'), + (0x1A1C, 'X'), + ] + +def _seg_15(): + return [ + (0x1A1E, 'V'), + (0x1A5F, 'X'), + (0x1A60, 'V'), + (0x1A7D, 'X'), + (0x1A7F, 'V'), + (0x1A8A, 'X'), + (0x1A90, 'V'), + (0x1A9A, 'X'), + (0x1AA0, 'V'), + (0x1AAE, 'X'), + (0x1AB0, 'V'), + (0x1ABF, 'X'), + (0x1B00, 'V'), + (0x1B4C, 'X'), + (0x1B50, 'V'), + (0x1B7D, 'X'), + (0x1B80, 'V'), + (0x1BF4, 'X'), + (0x1BFC, 'V'), + (0x1C38, 'X'), + (0x1C3B, 'V'), + (0x1C4A, 'X'), + (0x1C4D, 'V'), + (0x1C80, 'M', u'в'), + (0x1C81, 'M', u'д'), + (0x1C82, 'M', u'о'), + (0x1C83, 'M', u'с'), + (0x1C84, 'M', u'т'), + (0x1C86, 'M', u'ъ'), + (0x1C87, 'M', u'ѣ'), + (0x1C88, 'M', u'ꙋ'), + (0x1C89, 'X'), + (0x1CC0, 'V'), + (0x1CC8, 'X'), + (0x1CD0, 'V'), + (0x1CFA, 'X'), + (0x1D00, 'V'), + (0x1D2C, 'M', u'a'), + (0x1D2D, 'M', u'æ'), + (0x1D2E, 'M', u'b'), + (0x1D2F, 'V'), + (0x1D30, 'M', u'd'), + (0x1D31, 'M', u'e'), + (0x1D32, 'M', u'ǝ'), + (0x1D33, 'M', u'g'), + (0x1D34, 'M', u'h'), + (0x1D35, 'M', u'i'), + (0x1D36, 'M', u'j'), + (0x1D37, 'M', u'k'), + (0x1D38, 'M', u'l'), + (0x1D39, 'M', u'm'), + (0x1D3A, 'M', u'n'), + (0x1D3B, 'V'), + (0x1D3C, 'M', u'o'), + (0x1D3D, 'M', u'ȣ'), + (0x1D3E, 'M', u'p'), + (0x1D3F, 'M', u'r'), + (0x1D40, 'M', u't'), + (0x1D41, 'M', u'u'), + (0x1D42, 'M', u'w'), + (0x1D43, 'M', u'a'), + (0x1D44, 'M', u'ɐ'), + (0x1D45, 'M', u'ɑ'), + (0x1D46, 'M', u'ᴂ'), + (0x1D47, 'M', u'b'), + (0x1D48, 'M', u'd'), + (0x1D49, 'M', u'e'), + (0x1D4A, 'M', u'ə'), + (0x1D4B, 'M', u'ɛ'), + (0x1D4C, 'M', u'ɜ'), + (0x1D4D, 'M', u'g'), + (0x1D4E, 'V'), + (0x1D4F, 'M', u'k'), + (0x1D50, 'M', u'm'), + (0x1D51, 'M', u'ŋ'), + (0x1D52, 'M', u'o'), + (0x1D53, 'M', u'ɔ'), + (0x1D54, 'M', u'ᴖ'), + (0x1D55, 'M', u'ᴗ'), + (0x1D56, 'M', u'p'), + (0x1D57, 'M', u't'), + (0x1D58, 'M', u'u'), + (0x1D59, 'M', u'ᴝ'), + (0x1D5A, 'M', u'ɯ'), + (0x1D5B, 'M', u'v'), + (0x1D5C, 'M', u'ᴥ'), + (0x1D5D, 'M', u'β'), + (0x1D5E, 'M', u'γ'), + (0x1D5F, 'M', u'δ'), + (0x1D60, 'M', u'φ'), + (0x1D61, 'M', u'χ'), + (0x1D62, 'M', u'i'), + (0x1D63, 'M', u'r'), + (0x1D64, 'M', u'u'), + (0x1D65, 'M', u'v'), + (0x1D66, 'M', u'β'), + (0x1D67, 'M', u'γ'), + (0x1D68, 'M', u'ρ'), + (0x1D69, 'M', u'φ'), + (0x1D6A, 'M', u'χ'), + ] + +def _seg_16(): + return [ + (0x1D6B, 'V'), + (0x1D78, 'M', u'н'), + (0x1D79, 'V'), + (0x1D9B, 'M', u'ɒ'), + (0x1D9C, 'M', u'c'), + (0x1D9D, 'M', u'ɕ'), + (0x1D9E, 'M', u'ð'), + (0x1D9F, 'M', u'ɜ'), + (0x1DA0, 'M', u'f'), + (0x1DA1, 'M', u'ɟ'), + (0x1DA2, 'M', u'ɡ'), + (0x1DA3, 'M', u'ɥ'), + (0x1DA4, 'M', u'ɨ'), + (0x1DA5, 'M', u'ɩ'), + (0x1DA6, 'M', u'ɪ'), + (0x1DA7, 'M', u'ᵻ'), + (0x1DA8, 'M', u'ʝ'), + (0x1DA9, 'M', u'ɭ'), + (0x1DAA, 'M', u'ᶅ'), + (0x1DAB, 'M', u'ʟ'), + (0x1DAC, 'M', u'ɱ'), + (0x1DAD, 'M', u'ɰ'), + (0x1DAE, 'M', u'ɲ'), + (0x1DAF, 'M', u'ɳ'), + (0x1DB0, 'M', u'ɴ'), + (0x1DB1, 'M', u'ɵ'), + (0x1DB2, 'M', u'ɸ'), + (0x1DB3, 'M', u'ʂ'), + (0x1DB4, 'M', u'ʃ'), + (0x1DB5, 'M', u'ƫ'), + (0x1DB6, 'M', u'ʉ'), + (0x1DB7, 'M', u'ʊ'), + (0x1DB8, 'M', u'ᴜ'), + (0x1DB9, 'M', u'ʋ'), + (0x1DBA, 'M', u'ʌ'), + (0x1DBB, 'M', u'z'), + (0x1DBC, 'M', u'ʐ'), + (0x1DBD, 'M', u'ʑ'), + (0x1DBE, 'M', u'ʒ'), + (0x1DBF, 'M', u'θ'), + (0x1DC0, 'V'), + (0x1DFA, 'X'), + (0x1DFB, 'V'), + (0x1E00, 'M', u'ḁ'), + (0x1E01, 'V'), + (0x1E02, 'M', u'ḃ'), + (0x1E03, 'V'), + (0x1E04, 'M', u'ḅ'), + (0x1E05, 'V'), + (0x1E06, 'M', u'ḇ'), + (0x1E07, 'V'), + (0x1E08, 'M', u'ḉ'), + (0x1E09, 'V'), + (0x1E0A, 'M', u'ḋ'), + (0x1E0B, 'V'), + (0x1E0C, 'M', u'ḍ'), + (0x1E0D, 'V'), + (0x1E0E, 'M', u'ḏ'), + (0x1E0F, 'V'), + (0x1E10, 'M', u'ḑ'), + (0x1E11, 'V'), + (0x1E12, 'M', u'ḓ'), + (0x1E13, 'V'), + (0x1E14, 'M', u'ḕ'), + (0x1E15, 'V'), + (0x1E16, 'M', u'ḗ'), + (0x1E17, 'V'), + (0x1E18, 'M', u'ḙ'), + (0x1E19, 'V'), + (0x1E1A, 'M', u'ḛ'), + (0x1E1B, 'V'), + (0x1E1C, 'M', u'ḝ'), + (0x1E1D, 'V'), + (0x1E1E, 'M', u'ḟ'), + (0x1E1F, 'V'), + (0x1E20, 'M', u'ḡ'), + (0x1E21, 'V'), + (0x1E22, 'M', u'ḣ'), + (0x1E23, 'V'), + (0x1E24, 'M', u'ḥ'), + (0x1E25, 'V'), + (0x1E26, 'M', u'ḧ'), + (0x1E27, 'V'), + (0x1E28, 'M', u'ḩ'), + (0x1E29, 'V'), + (0x1E2A, 'M', u'ḫ'), + (0x1E2B, 'V'), + (0x1E2C, 'M', u'ḭ'), + (0x1E2D, 'V'), + (0x1E2E, 'M', u'ḯ'), + (0x1E2F, 'V'), + (0x1E30, 'M', u'ḱ'), + (0x1E31, 'V'), + (0x1E32, 'M', u'ḳ'), + (0x1E33, 'V'), + (0x1E34, 'M', u'ḵ'), + (0x1E35, 'V'), + (0x1E36, 'M', u'ḷ'), + (0x1E37, 'V'), + (0x1E38, 'M', u'ḹ'), + ] + +def _seg_17(): + return [ + (0x1E39, 'V'), + (0x1E3A, 'M', u'ḻ'), + (0x1E3B, 'V'), + (0x1E3C, 'M', u'ḽ'), + (0x1E3D, 'V'), + (0x1E3E, 'M', u'ḿ'), + (0x1E3F, 'V'), + (0x1E40, 'M', u'ṁ'), + (0x1E41, 'V'), + (0x1E42, 'M', u'ṃ'), + (0x1E43, 'V'), + (0x1E44, 'M', u'ṅ'), + (0x1E45, 'V'), + (0x1E46, 'M', u'ṇ'), + (0x1E47, 'V'), + (0x1E48, 'M', u'ṉ'), + (0x1E49, 'V'), + (0x1E4A, 'M', u'ṋ'), + (0x1E4B, 'V'), + (0x1E4C, 'M', u'ṍ'), + (0x1E4D, 'V'), + (0x1E4E, 'M', u'ṏ'), + (0x1E4F, 'V'), + (0x1E50, 'M', u'ṑ'), + (0x1E51, 'V'), + (0x1E52, 'M', u'ṓ'), + (0x1E53, 'V'), + (0x1E54, 'M', u'ṕ'), + (0x1E55, 'V'), + (0x1E56, 'M', u'ṗ'), + (0x1E57, 'V'), + (0x1E58, 'M', u'ṙ'), + (0x1E59, 'V'), + (0x1E5A, 'M', u'ṛ'), + (0x1E5B, 'V'), + (0x1E5C, 'M', u'ṝ'), + (0x1E5D, 'V'), + (0x1E5E, 'M', u'ṟ'), + (0x1E5F, 'V'), + (0x1E60, 'M', u'ṡ'), + (0x1E61, 'V'), + (0x1E62, 'M', u'ṣ'), + (0x1E63, 'V'), + (0x1E64, 'M', u'ṥ'), + (0x1E65, 'V'), + (0x1E66, 'M', u'ṧ'), + (0x1E67, 'V'), + (0x1E68, 'M', u'ṩ'), + (0x1E69, 'V'), + (0x1E6A, 'M', u'ṫ'), + (0x1E6B, 'V'), + (0x1E6C, 'M', u'ṭ'), + (0x1E6D, 'V'), + (0x1E6E, 'M', u'ṯ'), + (0x1E6F, 'V'), + (0x1E70, 'M', u'ṱ'), + (0x1E71, 'V'), + (0x1E72, 'M', u'ṳ'), + (0x1E73, 'V'), + (0x1E74, 'M', u'ṵ'), + (0x1E75, 'V'), + (0x1E76, 'M', u'ṷ'), + (0x1E77, 'V'), + (0x1E78, 'M', u'ṹ'), + (0x1E79, 'V'), + (0x1E7A, 'M', u'ṻ'), + (0x1E7B, 'V'), + (0x1E7C, 'M', u'ṽ'), + (0x1E7D, 'V'), + (0x1E7E, 'M', u'ṿ'), + (0x1E7F, 'V'), + (0x1E80, 'M', u'ẁ'), + (0x1E81, 'V'), + (0x1E82, 'M', u'ẃ'), + (0x1E83, 'V'), + (0x1E84, 'M', u'ẅ'), + (0x1E85, 'V'), + (0x1E86, 'M', u'ẇ'), + (0x1E87, 'V'), + (0x1E88, 'M', u'ẉ'), + (0x1E89, 'V'), + (0x1E8A, 'M', u'ẋ'), + (0x1E8B, 'V'), + (0x1E8C, 'M', u'ẍ'), + (0x1E8D, 'V'), + (0x1E8E, 'M', u'ẏ'), + (0x1E8F, 'V'), + (0x1E90, 'M', u'ẑ'), + (0x1E91, 'V'), + (0x1E92, 'M', u'ẓ'), + (0x1E93, 'V'), + (0x1E94, 'M', u'ẕ'), + (0x1E95, 'V'), + (0x1E9A, 'M', u'aʾ'), + (0x1E9B, 'M', u'ṡ'), + (0x1E9C, 'V'), + (0x1E9E, 'M', u'ss'), + (0x1E9F, 'V'), + (0x1EA0, 'M', u'ạ'), + (0x1EA1, 'V'), + ] + +def _seg_18(): + return [ + (0x1EA2, 'M', u'ả'), + (0x1EA3, 'V'), + (0x1EA4, 'M', u'ấ'), + (0x1EA5, 'V'), + (0x1EA6, 'M', u'ầ'), + (0x1EA7, 'V'), + (0x1EA8, 'M', u'ẩ'), + (0x1EA9, 'V'), + (0x1EAA, 'M', u'ẫ'), + (0x1EAB, 'V'), + (0x1EAC, 'M', u'ậ'), + (0x1EAD, 'V'), + (0x1EAE, 'M', u'ắ'), + (0x1EAF, 'V'), + (0x1EB0, 'M', u'ằ'), + (0x1EB1, 'V'), + (0x1EB2, 'M', u'ẳ'), + (0x1EB3, 'V'), + (0x1EB4, 'M', u'ẵ'), + (0x1EB5, 'V'), + (0x1EB6, 'M', u'ặ'), + (0x1EB7, 'V'), + (0x1EB8, 'M', u'ẹ'), + (0x1EB9, 'V'), + (0x1EBA, 'M', u'ẻ'), + (0x1EBB, 'V'), + (0x1EBC, 'M', u'ẽ'), + (0x1EBD, 'V'), + (0x1EBE, 'M', u'ế'), + (0x1EBF, 'V'), + (0x1EC0, 'M', u'ề'), + (0x1EC1, 'V'), + (0x1EC2, 'M', u'ể'), + (0x1EC3, 'V'), + (0x1EC4, 'M', u'ễ'), + (0x1EC5, 'V'), + (0x1EC6, 'M', u'ệ'), + (0x1EC7, 'V'), + (0x1EC8, 'M', u'ỉ'), + (0x1EC9, 'V'), + (0x1ECA, 'M', u'ị'), + (0x1ECB, 'V'), + (0x1ECC, 'M', u'ọ'), + (0x1ECD, 'V'), + (0x1ECE, 'M', u'ỏ'), + (0x1ECF, 'V'), + (0x1ED0, 'M', u'ố'), + (0x1ED1, 'V'), + (0x1ED2, 'M', u'ồ'), + (0x1ED3, 'V'), + (0x1ED4, 'M', u'ổ'), + (0x1ED5, 'V'), + (0x1ED6, 'M', u'ỗ'), + (0x1ED7, 'V'), + (0x1ED8, 'M', u'ộ'), + (0x1ED9, 'V'), + (0x1EDA, 'M', u'ớ'), + (0x1EDB, 'V'), + (0x1EDC, 'M', u'ờ'), + (0x1EDD, 'V'), + (0x1EDE, 'M', u'ở'), + (0x1EDF, 'V'), + (0x1EE0, 'M', u'ỡ'), + (0x1EE1, 'V'), + (0x1EE2, 'M', u'ợ'), + (0x1EE3, 'V'), + (0x1EE4, 'M', u'ụ'), + (0x1EE5, 'V'), + (0x1EE6, 'M', u'ủ'), + (0x1EE7, 'V'), + (0x1EE8, 'M', u'ứ'), + (0x1EE9, 'V'), + (0x1EEA, 'M', u'ừ'), + (0x1EEB, 'V'), + (0x1EEC, 'M', u'ử'), + (0x1EED, 'V'), + (0x1EEE, 'M', u'ữ'), + (0x1EEF, 'V'), + (0x1EF0, 'M', u'ự'), + (0x1EF1, 'V'), + (0x1EF2, 'M', u'ỳ'), + (0x1EF3, 'V'), + (0x1EF4, 'M', u'ỵ'), + (0x1EF5, 'V'), + (0x1EF6, 'M', u'ỷ'), + (0x1EF7, 'V'), + (0x1EF8, 'M', u'ỹ'), + (0x1EF9, 'V'), + (0x1EFA, 'M', u'ỻ'), + (0x1EFB, 'V'), + (0x1EFC, 'M', u'ỽ'), + (0x1EFD, 'V'), + (0x1EFE, 'M', u'ỿ'), + (0x1EFF, 'V'), + (0x1F08, 'M', u'ἀ'), + (0x1F09, 'M', u'ἁ'), + (0x1F0A, 'M', u'ἂ'), + (0x1F0B, 'M', u'ἃ'), + (0x1F0C, 'M', u'ἄ'), + (0x1F0D, 'M', u'ἅ'), + ] + +def _seg_19(): + return [ + (0x1F0E, 'M', u'ἆ'), + (0x1F0F, 'M', u'ἇ'), + (0x1F10, 'V'), + (0x1F16, 'X'), + (0x1F18, 'M', u'ἐ'), + (0x1F19, 'M', u'ἑ'), + (0x1F1A, 'M', u'ἒ'), + (0x1F1B, 'M', u'ἓ'), + (0x1F1C, 'M', u'ἔ'), + (0x1F1D, 'M', u'ἕ'), + (0x1F1E, 'X'), + (0x1F20, 'V'), + (0x1F28, 'M', u'ἠ'), + (0x1F29, 'M', u'ἡ'), + (0x1F2A, 'M', u'ἢ'), + (0x1F2B, 'M', u'ἣ'), + (0x1F2C, 'M', u'ἤ'), + (0x1F2D, 'M', u'ἥ'), + (0x1F2E, 'M', u'ἦ'), + (0x1F2F, 'M', u'ἧ'), + (0x1F30, 'V'), + (0x1F38, 'M', u'ἰ'), + (0x1F39, 'M', u'ἱ'), + (0x1F3A, 'M', u'ἲ'), + (0x1F3B, 'M', u'ἳ'), + (0x1F3C, 'M', u'ἴ'), + (0x1F3D, 'M', u'ἵ'), + (0x1F3E, 'M', u'ἶ'), + (0x1F3F, 'M', u'ἷ'), + (0x1F40, 'V'), + (0x1F46, 'X'), + (0x1F48, 'M', u'ὀ'), + (0x1F49, 'M', u'ὁ'), + (0x1F4A, 'M', u'ὂ'), + (0x1F4B, 'M', u'ὃ'), + (0x1F4C, 'M', u'ὄ'), + (0x1F4D, 'M', u'ὅ'), + (0x1F4E, 'X'), + (0x1F50, 'V'), + (0x1F58, 'X'), + (0x1F59, 'M', u'ὑ'), + (0x1F5A, 'X'), + (0x1F5B, 'M', u'ὓ'), + (0x1F5C, 'X'), + (0x1F5D, 'M', u'ὕ'), + (0x1F5E, 'X'), + (0x1F5F, 'M', u'ὗ'), + (0x1F60, 'V'), + (0x1F68, 'M', u'ὠ'), + (0x1F69, 'M', u'ὡ'), + (0x1F6A, 'M', u'ὢ'), + (0x1F6B, 'M', u'ὣ'), + (0x1F6C, 'M', u'ὤ'), + (0x1F6D, 'M', u'ὥ'), + (0x1F6E, 'M', u'ὦ'), + (0x1F6F, 'M', u'ὧ'), + (0x1F70, 'V'), + (0x1F71, 'M', u'ά'), + (0x1F72, 'V'), + (0x1F73, 'M', u'έ'), + (0x1F74, 'V'), + (0x1F75, 'M', u'ή'), + (0x1F76, 'V'), + (0x1F77, 'M', u'ί'), + (0x1F78, 'V'), + (0x1F79, 'M', u'ό'), + (0x1F7A, 'V'), + (0x1F7B, 'M', u'ύ'), + (0x1F7C, 'V'), + (0x1F7D, 'M', u'ώ'), + (0x1F7E, 'X'), + (0x1F80, 'M', u'ἀι'), + (0x1F81, 'M', u'ἁι'), + (0x1F82, 'M', u'ἂι'), + (0x1F83, 'M', u'ἃι'), + (0x1F84, 'M', u'ἄι'), + (0x1F85, 'M', u'ἅι'), + (0x1F86, 'M', u'ἆι'), + (0x1F87, 'M', u'ἇι'), + (0x1F88, 'M', u'ἀι'), + (0x1F89, 'M', u'ἁι'), + (0x1F8A, 'M', u'ἂι'), + (0x1F8B, 'M', u'ἃι'), + (0x1F8C, 'M', u'ἄι'), + (0x1F8D, 'M', u'ἅι'), + (0x1F8E, 'M', u'ἆι'), + (0x1F8F, 'M', u'ἇι'), + (0x1F90, 'M', u'ἠι'), + (0x1F91, 'M', u'ἡι'), + (0x1F92, 'M', u'ἢι'), + (0x1F93, 'M', u'ἣι'), + (0x1F94, 'M', u'ἤι'), + (0x1F95, 'M', u'ἥι'), + (0x1F96, 'M', u'ἦι'), + (0x1F97, 'M', u'ἧι'), + (0x1F98, 'M', u'ἠι'), + (0x1F99, 'M', u'ἡι'), + (0x1F9A, 'M', u'ἢι'), + (0x1F9B, 'M', u'ἣι'), + (0x1F9C, 'M', u'ἤι'), + ] + +def _seg_20(): + return [ + (0x1F9D, 'M', u'ἥι'), + (0x1F9E, 'M', u'ἦι'), + (0x1F9F, 'M', u'ἧι'), + (0x1FA0, 'M', u'ὠι'), + (0x1FA1, 'M', u'ὡι'), + (0x1FA2, 'M', u'ὢι'), + (0x1FA3, 'M', u'ὣι'), + (0x1FA4, 'M', u'ὤι'), + (0x1FA5, 'M', u'ὥι'), + (0x1FA6, 'M', u'ὦι'), + (0x1FA7, 'M', u'ὧι'), + (0x1FA8, 'M', u'ὠι'), + (0x1FA9, 'M', u'ὡι'), + (0x1FAA, 'M', u'ὢι'), + (0x1FAB, 'M', u'ὣι'), + (0x1FAC, 'M', u'ὤι'), + (0x1FAD, 'M', u'ὥι'), + (0x1FAE, 'M', u'ὦι'), + (0x1FAF, 'M', u'ὧι'), + (0x1FB0, 'V'), + (0x1FB2, 'M', u'ὰι'), + (0x1FB3, 'M', u'αι'), + (0x1FB4, 'M', u'άι'), + (0x1FB5, 'X'), + (0x1FB6, 'V'), + (0x1FB7, 'M', u'ᾶι'), + (0x1FB8, 'M', u'ᾰ'), + (0x1FB9, 'M', u'ᾱ'), + (0x1FBA, 'M', u'ὰ'), + (0x1FBB, 'M', u'ά'), + (0x1FBC, 'M', u'αι'), + (0x1FBD, '3', u' ̓'), + (0x1FBE, 'M', u'ι'), + (0x1FBF, '3', u' ̓'), + (0x1FC0, '3', u' ͂'), + (0x1FC1, '3', u' ̈͂'), + (0x1FC2, 'M', u'ὴι'), + (0x1FC3, 'M', u'ηι'), + (0x1FC4, 'M', u'ήι'), + (0x1FC5, 'X'), + (0x1FC6, 'V'), + (0x1FC7, 'M', u'ῆι'), + (0x1FC8, 'M', u'ὲ'), + (0x1FC9, 'M', u'έ'), + (0x1FCA, 'M', u'ὴ'), + (0x1FCB, 'M', u'ή'), + (0x1FCC, 'M', u'ηι'), + (0x1FCD, '3', u' ̓̀'), + (0x1FCE, '3', u' ̓́'), + (0x1FCF, '3', u' ̓͂'), + (0x1FD0, 'V'), + (0x1FD3, 'M', u'ΐ'), + (0x1FD4, 'X'), + (0x1FD6, 'V'), + (0x1FD8, 'M', u'ῐ'), + (0x1FD9, 'M', u'ῑ'), + (0x1FDA, 'M', u'ὶ'), + (0x1FDB, 'M', u'ί'), + (0x1FDC, 'X'), + (0x1FDD, '3', u' ̔̀'), + (0x1FDE, '3', u' ̔́'), + (0x1FDF, '3', u' ̔͂'), + (0x1FE0, 'V'), + (0x1FE3, 'M', u'ΰ'), + (0x1FE4, 'V'), + (0x1FE8, 'M', u'ῠ'), + (0x1FE9, 'M', u'ῡ'), + (0x1FEA, 'M', u'ὺ'), + (0x1FEB, 'M', u'ύ'), + (0x1FEC, 'M', u'ῥ'), + (0x1FED, '3', u' ̈̀'), + (0x1FEE, '3', u' ̈́'), + (0x1FEF, '3', u'`'), + (0x1FF0, 'X'), + (0x1FF2, 'M', u'ὼι'), + (0x1FF3, 'M', u'ωι'), + (0x1FF4, 'M', u'ώι'), + (0x1FF5, 'X'), + (0x1FF6, 'V'), + (0x1FF7, 'M', u'ῶι'), + (0x1FF8, 'M', u'ὸ'), + (0x1FF9, 'M', u'ό'), + (0x1FFA, 'M', u'ὼ'), + (0x1FFB, 'M', u'ώ'), + (0x1FFC, 'M', u'ωι'), + (0x1FFD, '3', u' ́'), + (0x1FFE, '3', u' ̔'), + (0x1FFF, 'X'), + (0x2000, '3', u' '), + (0x200B, 'I'), + (0x200C, 'D', u''), + (0x200E, 'X'), + (0x2010, 'V'), + (0x2011, 'M', u'‐'), + (0x2012, 'V'), + (0x2017, '3', u' ̳'), + (0x2018, 'V'), + (0x2024, 'X'), + (0x2027, 'V'), + (0x2028, 'X'), + ] + +def _seg_21(): + return [ + (0x202F, '3', u' '), + (0x2030, 'V'), + (0x2033, 'M', u'′′'), + (0x2034, 'M', u'′′′'), + (0x2035, 'V'), + (0x2036, 'M', u'‵‵'), + (0x2037, 'M', u'‵‵‵'), + (0x2038, 'V'), + (0x203C, '3', u'!!'), + (0x203D, 'V'), + (0x203E, '3', u' ̅'), + (0x203F, 'V'), + (0x2047, '3', u'??'), + (0x2048, '3', u'?!'), + (0x2049, '3', u'!?'), + (0x204A, 'V'), + (0x2057, 'M', u'′′′′'), + (0x2058, 'V'), + (0x205F, '3', u' '), + (0x2060, 'I'), + (0x2061, 'X'), + (0x2064, 'I'), + (0x2065, 'X'), + (0x2070, 'M', u'0'), + (0x2071, 'M', u'i'), + (0x2072, 'X'), + (0x2074, 'M', u'4'), + (0x2075, 'M', u'5'), + (0x2076, 'M', u'6'), + (0x2077, 'M', u'7'), + (0x2078, 'M', u'8'), + (0x2079, 'M', u'9'), + (0x207A, '3', u'+'), + (0x207B, 'M', u'−'), + (0x207C, '3', u'='), + (0x207D, '3', u'('), + (0x207E, '3', u')'), + (0x207F, 'M', u'n'), + (0x2080, 'M', u'0'), + (0x2081, 'M', u'1'), + (0x2082, 'M', u'2'), + (0x2083, 'M', u'3'), + (0x2084, 'M', u'4'), + (0x2085, 'M', u'5'), + (0x2086, 'M', u'6'), + (0x2087, 'M', u'7'), + (0x2088, 'M', u'8'), + (0x2089, 'M', u'9'), + (0x208A, '3', u'+'), + (0x208B, 'M', u'−'), + (0x208C, '3', u'='), + (0x208D, '3', u'('), + (0x208E, '3', u')'), + (0x208F, 'X'), + (0x2090, 'M', u'a'), + (0x2091, 'M', u'e'), + (0x2092, 'M', u'o'), + (0x2093, 'M', u'x'), + (0x2094, 'M', u'ə'), + (0x2095, 'M', u'h'), + (0x2096, 'M', u'k'), + (0x2097, 'M', u'l'), + (0x2098, 'M', u'm'), + (0x2099, 'M', u'n'), + (0x209A, 'M', u'p'), + (0x209B, 'M', u's'), + (0x209C, 'M', u't'), + (0x209D, 'X'), + (0x20A0, 'V'), + (0x20A8, 'M', u'rs'), + (0x20A9, 'V'), + (0x20C0, 'X'), + (0x20D0, 'V'), + (0x20F1, 'X'), + (0x2100, '3', u'a/c'), + (0x2101, '3', u'a/s'), + (0x2102, 'M', u'c'), + (0x2103, 'M', u'°c'), + (0x2104, 'V'), + (0x2105, '3', u'c/o'), + (0x2106, '3', u'c/u'), + (0x2107, 'M', u'ɛ'), + (0x2108, 'V'), + (0x2109, 'M', u'°f'), + (0x210A, 'M', u'g'), + (0x210B, 'M', u'h'), + (0x210F, 'M', u'ħ'), + (0x2110, 'M', u'i'), + (0x2112, 'M', u'l'), + (0x2114, 'V'), + (0x2115, 'M', u'n'), + (0x2116, 'M', u'no'), + (0x2117, 'V'), + (0x2119, 'M', u'p'), + (0x211A, 'M', u'q'), + (0x211B, 'M', u'r'), + (0x211E, 'V'), + (0x2120, 'M', u'sm'), + (0x2121, 'M', u'tel'), + (0x2122, 'M', u'tm'), + ] + +def _seg_22(): + return [ + (0x2123, 'V'), + (0x2124, 'M', u'z'), + (0x2125, 'V'), + (0x2126, 'M', u'ω'), + (0x2127, 'V'), + (0x2128, 'M', u'z'), + (0x2129, 'V'), + (0x212A, 'M', u'k'), + (0x212B, 'M', u'å'), + (0x212C, 'M', u'b'), + (0x212D, 'M', u'c'), + (0x212E, 'V'), + (0x212F, 'M', u'e'), + (0x2131, 'M', u'f'), + (0x2132, 'X'), + (0x2133, 'M', u'm'), + (0x2134, 'M', u'o'), + (0x2135, 'M', u'א'), + (0x2136, 'M', u'ב'), + (0x2137, 'M', u'ג'), + (0x2138, 'M', u'ד'), + (0x2139, 'M', u'i'), + (0x213A, 'V'), + (0x213B, 'M', u'fax'), + (0x213C, 'M', u'π'), + (0x213D, 'M', u'γ'), + (0x213F, 'M', u'π'), + (0x2140, 'M', u'∑'), + (0x2141, 'V'), + (0x2145, 'M', u'd'), + (0x2147, 'M', u'e'), + (0x2148, 'M', u'i'), + (0x2149, 'M', u'j'), + (0x214A, 'V'), + (0x2150, 'M', u'1⁄7'), + (0x2151, 'M', u'1⁄9'), + (0x2152, 'M', u'1⁄10'), + (0x2153, 'M', u'1⁄3'), + (0x2154, 'M', u'2⁄3'), + (0x2155, 'M', u'1⁄5'), + (0x2156, 'M', u'2⁄5'), + (0x2157, 'M', u'3⁄5'), + (0x2158, 'M', u'4⁄5'), + (0x2159, 'M', u'1⁄6'), + (0x215A, 'M', u'5⁄6'), + (0x215B, 'M', u'1⁄8'), + (0x215C, 'M', u'3⁄8'), + (0x215D, 'M', u'5⁄8'), + (0x215E, 'M', u'7⁄8'), + (0x215F, 'M', u'1⁄'), + (0x2160, 'M', u'i'), + (0x2161, 'M', u'ii'), + (0x2162, 'M', u'iii'), + (0x2163, 'M', u'iv'), + (0x2164, 'M', u'v'), + (0x2165, 'M', u'vi'), + (0x2166, 'M', u'vii'), + (0x2167, 'M', u'viii'), + (0x2168, 'M', u'ix'), + (0x2169, 'M', u'x'), + (0x216A, 'M', u'xi'), + (0x216B, 'M', u'xii'), + (0x216C, 'M', u'l'), + (0x216D, 'M', u'c'), + (0x216E, 'M', u'd'), + (0x216F, 'M', u'm'), + (0x2170, 'M', u'i'), + (0x2171, 'M', u'ii'), + (0x2172, 'M', u'iii'), + (0x2173, 'M', u'iv'), + (0x2174, 'M', u'v'), + (0x2175, 'M', u'vi'), + (0x2176, 'M', u'vii'), + (0x2177, 'M', u'viii'), + (0x2178, 'M', u'ix'), + (0x2179, 'M', u'x'), + (0x217A, 'M', u'xi'), + (0x217B, 'M', u'xii'), + (0x217C, 'M', u'l'), + (0x217D, 'M', u'c'), + (0x217E, 'M', u'd'), + (0x217F, 'M', u'm'), + (0x2180, 'V'), + (0x2183, 'X'), + (0x2184, 'V'), + (0x2189, 'M', u'0⁄3'), + (0x218A, 'V'), + (0x218C, 'X'), + (0x2190, 'V'), + (0x222C, 'M', u'∫∫'), + (0x222D, 'M', u'∫∫∫'), + (0x222E, 'V'), + (0x222F, 'M', u'∮∮'), + (0x2230, 'M', u'∮∮∮'), + (0x2231, 'V'), + (0x2260, '3'), + (0x2261, 'V'), + (0x226E, '3'), + (0x2270, 'V'), + (0x2329, 'M', u'〈'), + ] + +def _seg_23(): + return [ + (0x232A, 'M', u'〉'), + (0x232B, 'V'), + (0x2427, 'X'), + (0x2440, 'V'), + (0x244B, 'X'), + (0x2460, 'M', u'1'), + (0x2461, 'M', u'2'), + (0x2462, 'M', u'3'), + (0x2463, 'M', u'4'), + (0x2464, 'M', u'5'), + (0x2465, 'M', u'6'), + (0x2466, 'M', u'7'), + (0x2467, 'M', u'8'), + (0x2468, 'M', u'9'), + (0x2469, 'M', u'10'), + (0x246A, 'M', u'11'), + (0x246B, 'M', u'12'), + (0x246C, 'M', u'13'), + (0x246D, 'M', u'14'), + (0x246E, 'M', u'15'), + (0x246F, 'M', u'16'), + (0x2470, 'M', u'17'), + (0x2471, 'M', u'18'), + (0x2472, 'M', u'19'), + (0x2473, 'M', u'20'), + (0x2474, '3', u'(1)'), + (0x2475, '3', u'(2)'), + (0x2476, '3', u'(3)'), + (0x2477, '3', u'(4)'), + (0x2478, '3', u'(5)'), + (0x2479, '3', u'(6)'), + (0x247A, '3', u'(7)'), + (0x247B, '3', u'(8)'), + (0x247C, '3', u'(9)'), + (0x247D, '3', u'(10)'), + (0x247E, '3', u'(11)'), + (0x247F, '3', u'(12)'), + (0x2480, '3', u'(13)'), + (0x2481, '3', u'(14)'), + (0x2482, '3', u'(15)'), + (0x2483, '3', u'(16)'), + (0x2484, '3', u'(17)'), + (0x2485, '3', u'(18)'), + (0x2486, '3', u'(19)'), + (0x2487, '3', u'(20)'), + (0x2488, 'X'), + (0x249C, '3', u'(a)'), + (0x249D, '3', u'(b)'), + (0x249E, '3', u'(c)'), + (0x249F, '3', u'(d)'), + (0x24A0, '3', u'(e)'), + (0x24A1, '3', u'(f)'), + (0x24A2, '3', u'(g)'), + (0x24A3, '3', u'(h)'), + (0x24A4, '3', u'(i)'), + (0x24A5, '3', u'(j)'), + (0x24A6, '3', u'(k)'), + (0x24A7, '3', u'(l)'), + (0x24A8, '3', u'(m)'), + (0x24A9, '3', u'(n)'), + (0x24AA, '3', u'(o)'), + (0x24AB, '3', u'(p)'), + (0x24AC, '3', u'(q)'), + (0x24AD, '3', u'(r)'), + (0x24AE, '3', u'(s)'), + (0x24AF, '3', u'(t)'), + (0x24B0, '3', u'(u)'), + (0x24B1, '3', u'(v)'), + (0x24B2, '3', u'(w)'), + (0x24B3, '3', u'(x)'), + (0x24B4, '3', u'(y)'), + (0x24B5, '3', u'(z)'), + (0x24B6, 'M', u'a'), + (0x24B7, 'M', u'b'), + (0x24B8, 'M', u'c'), + (0x24B9, 'M', u'd'), + (0x24BA, 'M', u'e'), + (0x24BB, 'M', u'f'), + (0x24BC, 'M', u'g'), + (0x24BD, 'M', u'h'), + (0x24BE, 'M', u'i'), + (0x24BF, 'M', u'j'), + (0x24C0, 'M', u'k'), + (0x24C1, 'M', u'l'), + (0x24C2, 'M', u'm'), + (0x24C3, 'M', u'n'), + (0x24C4, 'M', u'o'), + (0x24C5, 'M', u'p'), + (0x24C6, 'M', u'q'), + (0x24C7, 'M', u'r'), + (0x24C8, 'M', u's'), + (0x24C9, 'M', u't'), + (0x24CA, 'M', u'u'), + (0x24CB, 'M', u'v'), + (0x24CC, 'M', u'w'), + (0x24CD, 'M', u'x'), + (0x24CE, 'M', u'y'), + (0x24CF, 'M', u'z'), + (0x24D0, 'M', u'a'), + (0x24D1, 'M', u'b'), + ] + +def _seg_24(): + return [ + (0x24D2, 'M', u'c'), + (0x24D3, 'M', u'd'), + (0x24D4, 'M', u'e'), + (0x24D5, 'M', u'f'), + (0x24D6, 'M', u'g'), + (0x24D7, 'M', u'h'), + (0x24D8, 'M', u'i'), + (0x24D9, 'M', u'j'), + (0x24DA, 'M', u'k'), + (0x24DB, 'M', u'l'), + (0x24DC, 'M', u'm'), + (0x24DD, 'M', u'n'), + (0x24DE, 'M', u'o'), + (0x24DF, 'M', u'p'), + (0x24E0, 'M', u'q'), + (0x24E1, 'M', u'r'), + (0x24E2, 'M', u's'), + (0x24E3, 'M', u't'), + (0x24E4, 'M', u'u'), + (0x24E5, 'M', u'v'), + (0x24E6, 'M', u'w'), + (0x24E7, 'M', u'x'), + (0x24E8, 'M', u'y'), + (0x24E9, 'M', u'z'), + (0x24EA, 'M', u'0'), + (0x24EB, 'V'), + (0x2A0C, 'M', u'∫∫∫∫'), + (0x2A0D, 'V'), + (0x2A74, '3', u'::='), + (0x2A75, '3', u'=='), + (0x2A76, '3', u'==='), + (0x2A77, 'V'), + (0x2ADC, 'M', u'⫝̸'), + (0x2ADD, 'V'), + (0x2B74, 'X'), + (0x2B76, 'V'), + (0x2B96, 'X'), + (0x2B98, 'V'), + (0x2BBA, 'X'), + (0x2BBD, 'V'), + (0x2BC9, 'X'), + (0x2BCA, 'V'), + (0x2BD3, 'X'), + (0x2BEC, 'V'), + (0x2BF0, 'X'), + (0x2C00, 'M', u'ⰰ'), + (0x2C01, 'M', u'ⰱ'), + (0x2C02, 'M', u'ⰲ'), + (0x2C03, 'M', u'ⰳ'), + (0x2C04, 'M', u'ⰴ'), + (0x2C05, 'M', u'ⰵ'), + (0x2C06, 'M', u'ⰶ'), + (0x2C07, 'M', u'ⰷ'), + (0x2C08, 'M', u'ⰸ'), + (0x2C09, 'M', u'ⰹ'), + (0x2C0A, 'M', u'ⰺ'), + (0x2C0B, 'M', u'ⰻ'), + (0x2C0C, 'M', u'ⰼ'), + (0x2C0D, 'M', u'ⰽ'), + (0x2C0E, 'M', u'ⰾ'), + (0x2C0F, 'M', u'ⰿ'), + (0x2C10, 'M', u'ⱀ'), + (0x2C11, 'M', u'ⱁ'), + (0x2C12, 'M', u'ⱂ'), + (0x2C13, 'M', u'ⱃ'), + (0x2C14, 'M', u'ⱄ'), + (0x2C15, 'M', u'ⱅ'), + (0x2C16, 'M', u'ⱆ'), + (0x2C17, 'M', u'ⱇ'), + (0x2C18, 'M', u'ⱈ'), + (0x2C19, 'M', u'ⱉ'), + (0x2C1A, 'M', u'ⱊ'), + (0x2C1B, 'M', u'ⱋ'), + (0x2C1C, 'M', u'ⱌ'), + (0x2C1D, 'M', u'ⱍ'), + (0x2C1E, 'M', u'ⱎ'), + (0x2C1F, 'M', u'ⱏ'), + (0x2C20, 'M', u'ⱐ'), + (0x2C21, 'M', u'ⱑ'), + (0x2C22, 'M', u'ⱒ'), + (0x2C23, 'M', u'ⱓ'), + (0x2C24, 'M', u'ⱔ'), + (0x2C25, 'M', u'ⱕ'), + (0x2C26, 'M', u'ⱖ'), + (0x2C27, 'M', u'ⱗ'), + (0x2C28, 'M', u'ⱘ'), + (0x2C29, 'M', u'ⱙ'), + (0x2C2A, 'M', u'ⱚ'), + (0x2C2B, 'M', u'ⱛ'), + (0x2C2C, 'M', u'ⱜ'), + (0x2C2D, 'M', u'ⱝ'), + (0x2C2E, 'M', u'ⱞ'), + (0x2C2F, 'X'), + (0x2C30, 'V'), + (0x2C5F, 'X'), + (0x2C60, 'M', u'ⱡ'), + (0x2C61, 'V'), + (0x2C62, 'M', u'ɫ'), + (0x2C63, 'M', u'ᵽ'), + (0x2C64, 'M', u'ɽ'), + ] + +def _seg_25(): + return [ + (0x2C65, 'V'), + (0x2C67, 'M', u'ⱨ'), + (0x2C68, 'V'), + (0x2C69, 'M', u'ⱪ'), + (0x2C6A, 'V'), + (0x2C6B, 'M', u'ⱬ'), + (0x2C6C, 'V'), + (0x2C6D, 'M', u'ɑ'), + (0x2C6E, 'M', u'ɱ'), + (0x2C6F, 'M', u'ɐ'), + (0x2C70, 'M', u'ɒ'), + (0x2C71, 'V'), + (0x2C72, 'M', u'ⱳ'), + (0x2C73, 'V'), + (0x2C75, 'M', u'ⱶ'), + (0x2C76, 'V'), + (0x2C7C, 'M', u'j'), + (0x2C7D, 'M', u'v'), + (0x2C7E, 'M', u'ȿ'), + (0x2C7F, 'M', u'ɀ'), + (0x2C80, 'M', u'ⲁ'), + (0x2C81, 'V'), + (0x2C82, 'M', u'ⲃ'), + (0x2C83, 'V'), + (0x2C84, 'M', u'ⲅ'), + (0x2C85, 'V'), + (0x2C86, 'M', u'ⲇ'), + (0x2C87, 'V'), + (0x2C88, 'M', u'ⲉ'), + (0x2C89, 'V'), + (0x2C8A, 'M', u'ⲋ'), + (0x2C8B, 'V'), + (0x2C8C, 'M', u'ⲍ'), + (0x2C8D, 'V'), + (0x2C8E, 'M', u'ⲏ'), + (0x2C8F, 'V'), + (0x2C90, 'M', u'ⲑ'), + (0x2C91, 'V'), + (0x2C92, 'M', u'ⲓ'), + (0x2C93, 'V'), + (0x2C94, 'M', u'ⲕ'), + (0x2C95, 'V'), + (0x2C96, 'M', u'ⲗ'), + (0x2C97, 'V'), + (0x2C98, 'M', u'ⲙ'), + (0x2C99, 'V'), + (0x2C9A, 'M', u'ⲛ'), + (0x2C9B, 'V'), + (0x2C9C, 'M', u'ⲝ'), + (0x2C9D, 'V'), + (0x2C9E, 'M', u'ⲟ'), + (0x2C9F, 'V'), + (0x2CA0, 'M', u'ⲡ'), + (0x2CA1, 'V'), + (0x2CA2, 'M', u'ⲣ'), + (0x2CA3, 'V'), + (0x2CA4, 'M', u'ⲥ'), + (0x2CA5, 'V'), + (0x2CA6, 'M', u'ⲧ'), + (0x2CA7, 'V'), + (0x2CA8, 'M', u'ⲩ'), + (0x2CA9, 'V'), + (0x2CAA, 'M', u'ⲫ'), + (0x2CAB, 'V'), + (0x2CAC, 'M', u'ⲭ'), + (0x2CAD, 'V'), + (0x2CAE, 'M', u'ⲯ'), + (0x2CAF, 'V'), + (0x2CB0, 'M', u'ⲱ'), + (0x2CB1, 'V'), + (0x2CB2, 'M', u'ⲳ'), + (0x2CB3, 'V'), + (0x2CB4, 'M', u'ⲵ'), + (0x2CB5, 'V'), + (0x2CB6, 'M', u'ⲷ'), + (0x2CB7, 'V'), + (0x2CB8, 'M', u'ⲹ'), + (0x2CB9, 'V'), + (0x2CBA, 'M', u'ⲻ'), + (0x2CBB, 'V'), + (0x2CBC, 'M', u'ⲽ'), + (0x2CBD, 'V'), + (0x2CBE, 'M', u'ⲿ'), + (0x2CBF, 'V'), + (0x2CC0, 'M', u'ⳁ'), + (0x2CC1, 'V'), + (0x2CC2, 'M', u'ⳃ'), + (0x2CC3, 'V'), + (0x2CC4, 'M', u'ⳅ'), + (0x2CC5, 'V'), + (0x2CC6, 'M', u'ⳇ'), + (0x2CC7, 'V'), + (0x2CC8, 'M', u'ⳉ'), + (0x2CC9, 'V'), + (0x2CCA, 'M', u'ⳋ'), + (0x2CCB, 'V'), + (0x2CCC, 'M', u'ⳍ'), + (0x2CCD, 'V'), + (0x2CCE, 'M', u'ⳏ'), + (0x2CCF, 'V'), + ] + +def _seg_26(): + return [ + (0x2CD0, 'M', u'ⳑ'), + (0x2CD1, 'V'), + (0x2CD2, 'M', u'ⳓ'), + (0x2CD3, 'V'), + (0x2CD4, 'M', u'ⳕ'), + (0x2CD5, 'V'), + (0x2CD6, 'M', u'ⳗ'), + (0x2CD7, 'V'), + (0x2CD8, 'M', u'ⳙ'), + (0x2CD9, 'V'), + (0x2CDA, 'M', u'ⳛ'), + (0x2CDB, 'V'), + (0x2CDC, 'M', u'ⳝ'), + (0x2CDD, 'V'), + (0x2CDE, 'M', u'ⳟ'), + (0x2CDF, 'V'), + (0x2CE0, 'M', u'ⳡ'), + (0x2CE1, 'V'), + (0x2CE2, 'M', u'ⳣ'), + (0x2CE3, 'V'), + (0x2CEB, 'M', u'ⳬ'), + (0x2CEC, 'V'), + (0x2CED, 'M', u'ⳮ'), + (0x2CEE, 'V'), + (0x2CF2, 'M', u'ⳳ'), + (0x2CF3, 'V'), + (0x2CF4, 'X'), + (0x2CF9, 'V'), + (0x2D26, 'X'), + (0x2D27, 'V'), + (0x2D28, 'X'), + (0x2D2D, 'V'), + (0x2D2E, 'X'), + (0x2D30, 'V'), + (0x2D68, 'X'), + (0x2D6F, 'M', u'ⵡ'), + (0x2D70, 'V'), + (0x2D71, 'X'), + (0x2D7F, 'V'), + (0x2D97, 'X'), + (0x2DA0, 'V'), + (0x2DA7, 'X'), + (0x2DA8, 'V'), + (0x2DAF, 'X'), + (0x2DB0, 'V'), + (0x2DB7, 'X'), + (0x2DB8, 'V'), + (0x2DBF, 'X'), + (0x2DC0, 'V'), + (0x2DC7, 'X'), + (0x2DC8, 'V'), + (0x2DCF, 'X'), + (0x2DD0, 'V'), + (0x2DD7, 'X'), + (0x2DD8, 'V'), + (0x2DDF, 'X'), + (0x2DE0, 'V'), + (0x2E4A, 'X'), + (0x2E80, 'V'), + (0x2E9A, 'X'), + (0x2E9B, 'V'), + (0x2E9F, 'M', u'母'), + (0x2EA0, 'V'), + (0x2EF3, 'M', u'龟'), + (0x2EF4, 'X'), + (0x2F00, 'M', u'一'), + (0x2F01, 'M', u'丨'), + (0x2F02, 'M', u'丶'), + (0x2F03, 'M', u'丿'), + (0x2F04, 'M', u'乙'), + (0x2F05, 'M', u'亅'), + (0x2F06, 'M', u'二'), + (0x2F07, 'M', u'亠'), + (0x2F08, 'M', u'人'), + (0x2F09, 'M', u'儿'), + (0x2F0A, 'M', u'入'), + (0x2F0B, 'M', u'八'), + (0x2F0C, 'M', u'冂'), + (0x2F0D, 'M', u'冖'), + (0x2F0E, 'M', u'冫'), + (0x2F0F, 'M', u'几'), + (0x2F10, 'M', u'凵'), + (0x2F11, 'M', u'刀'), + (0x2F12, 'M', u'力'), + (0x2F13, 'M', u'勹'), + (0x2F14, 'M', u'匕'), + (0x2F15, 'M', u'匚'), + (0x2F16, 'M', u'匸'), + (0x2F17, 'M', u'十'), + (0x2F18, 'M', u'卜'), + (0x2F19, 'M', u'卩'), + (0x2F1A, 'M', u'厂'), + (0x2F1B, 'M', u'厶'), + (0x2F1C, 'M', u'又'), + (0x2F1D, 'M', u'口'), + (0x2F1E, 'M', u'囗'), + (0x2F1F, 'M', u'土'), + (0x2F20, 'M', u'士'), + (0x2F21, 'M', u'夂'), + (0x2F22, 'M', u'夊'), + ] + +def _seg_27(): + return [ + (0x2F23, 'M', u'夕'), + (0x2F24, 'M', u'大'), + (0x2F25, 'M', u'女'), + (0x2F26, 'M', u'子'), + (0x2F27, 'M', u'宀'), + (0x2F28, 'M', u'寸'), + (0x2F29, 'M', u'小'), + (0x2F2A, 'M', u'尢'), + (0x2F2B, 'M', u'尸'), + (0x2F2C, 'M', u'屮'), + (0x2F2D, 'M', u'山'), + (0x2F2E, 'M', u'巛'), + (0x2F2F, 'M', u'工'), + (0x2F30, 'M', u'己'), + (0x2F31, 'M', u'巾'), + (0x2F32, 'M', u'干'), + (0x2F33, 'M', u'幺'), + (0x2F34, 'M', u'广'), + (0x2F35, 'M', u'廴'), + (0x2F36, 'M', u'廾'), + (0x2F37, 'M', u'弋'), + (0x2F38, 'M', u'弓'), + (0x2F39, 'M', u'彐'), + (0x2F3A, 'M', u'彡'), + (0x2F3B, 'M', u'彳'), + (0x2F3C, 'M', u'心'), + (0x2F3D, 'M', u'戈'), + (0x2F3E, 'M', u'戶'), + (0x2F3F, 'M', u'手'), + (0x2F40, 'M', u'支'), + (0x2F41, 'M', u'攴'), + (0x2F42, 'M', u'文'), + (0x2F43, 'M', u'斗'), + (0x2F44, 'M', u'斤'), + (0x2F45, 'M', u'方'), + (0x2F46, 'M', u'无'), + (0x2F47, 'M', u'日'), + (0x2F48, 'M', u'曰'), + (0x2F49, 'M', u'月'), + (0x2F4A, 'M', u'木'), + (0x2F4B, 'M', u'欠'), + (0x2F4C, 'M', u'止'), + (0x2F4D, 'M', u'歹'), + (0x2F4E, 'M', u'殳'), + (0x2F4F, 'M', u'毋'), + (0x2F50, 'M', u'比'), + (0x2F51, 'M', u'毛'), + (0x2F52, 'M', u'氏'), + (0x2F53, 'M', u'气'), + (0x2F54, 'M', u'水'), + (0x2F55, 'M', u'火'), + (0x2F56, 'M', u'爪'), + (0x2F57, 'M', u'父'), + (0x2F58, 'M', u'爻'), + (0x2F59, 'M', u'爿'), + (0x2F5A, 'M', u'片'), + (0x2F5B, 'M', u'牙'), + (0x2F5C, 'M', u'牛'), + (0x2F5D, 'M', u'犬'), + (0x2F5E, 'M', u'玄'), + (0x2F5F, 'M', u'玉'), + (0x2F60, 'M', u'瓜'), + (0x2F61, 'M', u'瓦'), + (0x2F62, 'M', u'甘'), + (0x2F63, 'M', u'生'), + (0x2F64, 'M', u'用'), + (0x2F65, 'M', u'田'), + (0x2F66, 'M', u'疋'), + (0x2F67, 'M', u'疒'), + (0x2F68, 'M', u'癶'), + (0x2F69, 'M', u'白'), + (0x2F6A, 'M', u'皮'), + (0x2F6B, 'M', u'皿'), + (0x2F6C, 'M', u'目'), + (0x2F6D, 'M', u'矛'), + (0x2F6E, 'M', u'矢'), + (0x2F6F, 'M', u'石'), + (0x2F70, 'M', u'示'), + (0x2F71, 'M', u'禸'), + (0x2F72, 'M', u'禾'), + (0x2F73, 'M', u'穴'), + (0x2F74, 'M', u'立'), + (0x2F75, 'M', u'竹'), + (0x2F76, 'M', u'米'), + (0x2F77, 'M', u'糸'), + (0x2F78, 'M', u'缶'), + (0x2F79, 'M', u'网'), + (0x2F7A, 'M', u'羊'), + (0x2F7B, 'M', u'羽'), + (0x2F7C, 'M', u'老'), + (0x2F7D, 'M', u'而'), + (0x2F7E, 'M', u'耒'), + (0x2F7F, 'M', u'耳'), + (0x2F80, 'M', u'聿'), + (0x2F81, 'M', u'肉'), + (0x2F82, 'M', u'臣'), + (0x2F83, 'M', u'自'), + (0x2F84, 'M', u'至'), + (0x2F85, 'M', u'臼'), + (0x2F86, 'M', u'舌'), + ] + +def _seg_28(): + return [ + (0x2F87, 'M', u'舛'), + (0x2F88, 'M', u'舟'), + (0x2F89, 'M', u'艮'), + (0x2F8A, 'M', u'色'), + (0x2F8B, 'M', u'艸'), + (0x2F8C, 'M', u'虍'), + (0x2F8D, 'M', u'虫'), + (0x2F8E, 'M', u'血'), + (0x2F8F, 'M', u'行'), + (0x2F90, 'M', u'衣'), + (0x2F91, 'M', u'襾'), + (0x2F92, 'M', u'見'), + (0x2F93, 'M', u'角'), + (0x2F94, 'M', u'言'), + (0x2F95, 'M', u'谷'), + (0x2F96, 'M', u'豆'), + (0x2F97, 'M', u'豕'), + (0x2F98, 'M', u'豸'), + (0x2F99, 'M', u'貝'), + (0x2F9A, 'M', u'赤'), + (0x2F9B, 'M', u'走'), + (0x2F9C, 'M', u'足'), + (0x2F9D, 'M', u'身'), + (0x2F9E, 'M', u'車'), + (0x2F9F, 'M', u'辛'), + (0x2FA0, 'M', u'辰'), + (0x2FA1, 'M', u'辵'), + (0x2FA2, 'M', u'邑'), + (0x2FA3, 'M', u'酉'), + (0x2FA4, 'M', u'釆'), + (0x2FA5, 'M', u'里'), + (0x2FA6, 'M', u'金'), + (0x2FA7, 'M', u'長'), + (0x2FA8, 'M', u'門'), + (0x2FA9, 'M', u'阜'), + (0x2FAA, 'M', u'隶'), + (0x2FAB, 'M', u'隹'), + (0x2FAC, 'M', u'雨'), + (0x2FAD, 'M', u'靑'), + (0x2FAE, 'M', u'非'), + (0x2FAF, 'M', u'面'), + (0x2FB0, 'M', u'革'), + (0x2FB1, 'M', u'韋'), + (0x2FB2, 'M', u'韭'), + (0x2FB3, 'M', u'音'), + (0x2FB4, 'M', u'頁'), + (0x2FB5, 'M', u'風'), + (0x2FB6, 'M', u'飛'), + (0x2FB7, 'M', u'食'), + (0x2FB8, 'M', u'首'), + (0x2FB9, 'M', u'香'), + (0x2FBA, 'M', u'馬'), + (0x2FBB, 'M', u'骨'), + (0x2FBC, 'M', u'高'), + (0x2FBD, 'M', u'髟'), + (0x2FBE, 'M', u'鬥'), + (0x2FBF, 'M', u'鬯'), + (0x2FC0, 'M', u'鬲'), + (0x2FC1, 'M', u'鬼'), + (0x2FC2, 'M', u'魚'), + (0x2FC3, 'M', u'鳥'), + (0x2FC4, 'M', u'鹵'), + (0x2FC5, 'M', u'鹿'), + (0x2FC6, 'M', u'麥'), + (0x2FC7, 'M', u'麻'), + (0x2FC8, 'M', u'黃'), + (0x2FC9, 'M', u'黍'), + (0x2FCA, 'M', u'黑'), + (0x2FCB, 'M', u'黹'), + (0x2FCC, 'M', u'黽'), + (0x2FCD, 'M', u'鼎'), + (0x2FCE, 'M', u'鼓'), + (0x2FCF, 'M', u'鼠'), + (0x2FD0, 'M', u'鼻'), + (0x2FD1, 'M', u'齊'), + (0x2FD2, 'M', u'齒'), + (0x2FD3, 'M', u'龍'), + (0x2FD4, 'M', u'龜'), + (0x2FD5, 'M', u'龠'), + (0x2FD6, 'X'), + (0x3000, '3', u' '), + (0x3001, 'V'), + (0x3002, 'M', u'.'), + (0x3003, 'V'), + (0x3036, 'M', u'〒'), + (0x3037, 'V'), + (0x3038, 'M', u'十'), + (0x3039, 'M', u'卄'), + (0x303A, 'M', u'卅'), + (0x303B, 'V'), + (0x3040, 'X'), + (0x3041, 'V'), + (0x3097, 'X'), + (0x3099, 'V'), + (0x309B, '3', u' ゙'), + (0x309C, '3', u' ゚'), + (0x309D, 'V'), + (0x309F, 'M', u'より'), + (0x30A0, 'V'), + (0x30FF, 'M', u'コト'), + ] + +def _seg_29(): + return [ + (0x3100, 'X'), + (0x3105, 'V'), + (0x312F, 'X'), + (0x3131, 'M', u'ᄀ'), + (0x3132, 'M', u'ᄁ'), + (0x3133, 'M', u'ᆪ'), + (0x3134, 'M', u'ᄂ'), + (0x3135, 'M', u'ᆬ'), + (0x3136, 'M', u'ᆭ'), + (0x3137, 'M', u'ᄃ'), + (0x3138, 'M', u'ᄄ'), + (0x3139, 'M', u'ᄅ'), + (0x313A, 'M', u'ᆰ'), + (0x313B, 'M', u'ᆱ'), + (0x313C, 'M', u'ᆲ'), + (0x313D, 'M', u'ᆳ'), + (0x313E, 'M', u'ᆴ'), + (0x313F, 'M', u'ᆵ'), + (0x3140, 'M', u'ᄚ'), + (0x3141, 'M', u'ᄆ'), + (0x3142, 'M', u'ᄇ'), + (0x3143, 'M', u'ᄈ'), + (0x3144, 'M', u'ᄡ'), + (0x3145, 'M', u'ᄉ'), + (0x3146, 'M', u'ᄊ'), + (0x3147, 'M', u'ᄋ'), + (0x3148, 'M', u'ᄌ'), + (0x3149, 'M', u'ᄍ'), + (0x314A, 'M', u'ᄎ'), + (0x314B, 'M', u'ᄏ'), + (0x314C, 'M', u'ᄐ'), + (0x314D, 'M', u'ᄑ'), + (0x314E, 'M', u'ᄒ'), + (0x314F, 'M', u'ᅡ'), + (0x3150, 'M', u'ᅢ'), + (0x3151, 'M', u'ᅣ'), + (0x3152, 'M', u'ᅤ'), + (0x3153, 'M', u'ᅥ'), + (0x3154, 'M', u'ᅦ'), + (0x3155, 'M', u'ᅧ'), + (0x3156, 'M', u'ᅨ'), + (0x3157, 'M', u'ᅩ'), + (0x3158, 'M', u'ᅪ'), + (0x3159, 'M', u'ᅫ'), + (0x315A, 'M', u'ᅬ'), + (0x315B, 'M', u'ᅭ'), + (0x315C, 'M', u'ᅮ'), + (0x315D, 'M', u'ᅯ'), + (0x315E, 'M', u'ᅰ'), + (0x315F, 'M', u'ᅱ'), + (0x3160, 'M', u'ᅲ'), + (0x3161, 'M', u'ᅳ'), + (0x3162, 'M', u'ᅴ'), + (0x3163, 'M', u'ᅵ'), + (0x3164, 'X'), + (0x3165, 'M', u'ᄔ'), + (0x3166, 'M', u'ᄕ'), + (0x3167, 'M', u'ᇇ'), + (0x3168, 'M', u'ᇈ'), + (0x3169, 'M', u'ᇌ'), + (0x316A, 'M', u'ᇎ'), + (0x316B, 'M', u'ᇓ'), + (0x316C, 'M', u'ᇗ'), + (0x316D, 'M', u'ᇙ'), + (0x316E, 'M', u'ᄜ'), + (0x316F, 'M', u'ᇝ'), + (0x3170, 'M', u'ᇟ'), + (0x3171, 'M', u'ᄝ'), + (0x3172, 'M', u'ᄞ'), + (0x3173, 'M', u'ᄠ'), + (0x3174, 'M', u'ᄢ'), + (0x3175, 'M', u'ᄣ'), + (0x3176, 'M', u'ᄧ'), + (0x3177, 'M', u'ᄩ'), + (0x3178, 'M', u'ᄫ'), + (0x3179, 'M', u'ᄬ'), + (0x317A, 'M', u'ᄭ'), + (0x317B, 'M', u'ᄮ'), + (0x317C, 'M', u'ᄯ'), + (0x317D, 'M', u'ᄲ'), + (0x317E, 'M', u'ᄶ'), + (0x317F, 'M', u'ᅀ'), + (0x3180, 'M', u'ᅇ'), + (0x3181, 'M', u'ᅌ'), + (0x3182, 'M', u'ᇱ'), + (0x3183, 'M', u'ᇲ'), + (0x3184, 'M', u'ᅗ'), + (0x3185, 'M', u'ᅘ'), + (0x3186, 'M', u'ᅙ'), + (0x3187, 'M', u'ᆄ'), + (0x3188, 'M', u'ᆅ'), + (0x3189, 'M', u'ᆈ'), + (0x318A, 'M', u'ᆑ'), + (0x318B, 'M', u'ᆒ'), + (0x318C, 'M', u'ᆔ'), + (0x318D, 'M', u'ᆞ'), + (0x318E, 'M', u'ᆡ'), + (0x318F, 'X'), + (0x3190, 'V'), + (0x3192, 'M', u'一'), + ] + +def _seg_30(): + return [ + (0x3193, 'M', u'二'), + (0x3194, 'M', u'三'), + (0x3195, 'M', u'四'), + (0x3196, 'M', u'上'), + (0x3197, 'M', u'中'), + (0x3198, 'M', u'下'), + (0x3199, 'M', u'甲'), + (0x319A, 'M', u'乙'), + (0x319B, 'M', u'丙'), + (0x319C, 'M', u'丁'), + (0x319D, 'M', u'天'), + (0x319E, 'M', u'地'), + (0x319F, 'M', u'人'), + (0x31A0, 'V'), + (0x31BB, 'X'), + (0x31C0, 'V'), + (0x31E4, 'X'), + (0x31F0, 'V'), + (0x3200, '3', u'(ᄀ)'), + (0x3201, '3', u'(ᄂ)'), + (0x3202, '3', u'(ᄃ)'), + (0x3203, '3', u'(ᄅ)'), + (0x3204, '3', u'(ᄆ)'), + (0x3205, '3', u'(ᄇ)'), + (0x3206, '3', u'(ᄉ)'), + (0x3207, '3', u'(ᄋ)'), + (0x3208, '3', u'(ᄌ)'), + (0x3209, '3', u'(ᄎ)'), + (0x320A, '3', u'(ᄏ)'), + (0x320B, '3', u'(ᄐ)'), + (0x320C, '3', u'(ᄑ)'), + (0x320D, '3', u'(ᄒ)'), + (0x320E, '3', u'(가)'), + (0x320F, '3', u'(나)'), + (0x3210, '3', u'(다)'), + (0x3211, '3', u'(라)'), + (0x3212, '3', u'(마)'), + (0x3213, '3', u'(바)'), + (0x3214, '3', u'(사)'), + (0x3215, '3', u'(아)'), + (0x3216, '3', u'(자)'), + (0x3217, '3', u'(차)'), + (0x3218, '3', u'(카)'), + (0x3219, '3', u'(타)'), + (0x321A, '3', u'(파)'), + (0x321B, '3', u'(하)'), + (0x321C, '3', u'(주)'), + (0x321D, '3', u'(오전)'), + (0x321E, '3', u'(오후)'), + (0x321F, 'X'), + (0x3220, '3', u'(一)'), + (0x3221, '3', u'(二)'), + (0x3222, '3', u'(三)'), + (0x3223, '3', u'(四)'), + (0x3224, '3', u'(五)'), + (0x3225, '3', u'(六)'), + (0x3226, '3', u'(七)'), + (0x3227, '3', u'(八)'), + (0x3228, '3', u'(九)'), + (0x3229, '3', u'(十)'), + (0x322A, '3', u'(月)'), + (0x322B, '3', u'(火)'), + (0x322C, '3', u'(水)'), + (0x322D, '3', u'(木)'), + (0x322E, '3', u'(金)'), + (0x322F, '3', u'(土)'), + (0x3230, '3', u'(日)'), + (0x3231, '3', u'(株)'), + (0x3232, '3', u'(有)'), + (0x3233, '3', u'(社)'), + (0x3234, '3', u'(名)'), + (0x3235, '3', u'(特)'), + (0x3236, '3', u'(財)'), + (0x3237, '3', u'(祝)'), + (0x3238, '3', u'(労)'), + (0x3239, '3', u'(代)'), + (0x323A, '3', u'(呼)'), + (0x323B, '3', u'(学)'), + (0x323C, '3', u'(監)'), + (0x323D, '3', u'(企)'), + (0x323E, '3', u'(資)'), + (0x323F, '3', u'(協)'), + (0x3240, '3', u'(祭)'), + (0x3241, '3', u'(休)'), + (0x3242, '3', u'(自)'), + (0x3243, '3', u'(至)'), + (0x3244, 'M', u'問'), + (0x3245, 'M', u'幼'), + (0x3246, 'M', u'文'), + (0x3247, 'M', u'箏'), + (0x3248, 'V'), + (0x3250, 'M', u'pte'), + (0x3251, 'M', u'21'), + (0x3252, 'M', u'22'), + (0x3253, 'M', u'23'), + (0x3254, 'M', u'24'), + (0x3255, 'M', u'25'), + (0x3256, 'M', u'26'), + (0x3257, 'M', u'27'), + (0x3258, 'M', u'28'), + ] + +def _seg_31(): + return [ + (0x3259, 'M', u'29'), + (0x325A, 'M', u'30'), + (0x325B, 'M', u'31'), + (0x325C, 'M', u'32'), + (0x325D, 'M', u'33'), + (0x325E, 'M', u'34'), + (0x325F, 'M', u'35'), + (0x3260, 'M', u'ᄀ'), + (0x3261, 'M', u'ᄂ'), + (0x3262, 'M', u'ᄃ'), + (0x3263, 'M', u'ᄅ'), + (0x3264, 'M', u'ᄆ'), + (0x3265, 'M', u'ᄇ'), + (0x3266, 'M', u'ᄉ'), + (0x3267, 'M', u'ᄋ'), + (0x3268, 'M', u'ᄌ'), + (0x3269, 'M', u'ᄎ'), + (0x326A, 'M', u'ᄏ'), + (0x326B, 'M', u'ᄐ'), + (0x326C, 'M', u'ᄑ'), + (0x326D, 'M', u'ᄒ'), + (0x326E, 'M', u'가'), + (0x326F, 'M', u'나'), + (0x3270, 'M', u'다'), + (0x3271, 'M', u'라'), + (0x3272, 'M', u'마'), + (0x3273, 'M', u'바'), + (0x3274, 'M', u'사'), + (0x3275, 'M', u'아'), + (0x3276, 'M', u'자'), + (0x3277, 'M', u'차'), + (0x3278, 'M', u'카'), + (0x3279, 'M', u'타'), + (0x327A, 'M', u'파'), + (0x327B, 'M', u'하'), + (0x327C, 'M', u'참고'), + (0x327D, 'M', u'주의'), + (0x327E, 'M', u'우'), + (0x327F, 'V'), + (0x3280, 'M', u'一'), + (0x3281, 'M', u'二'), + (0x3282, 'M', u'三'), + (0x3283, 'M', u'四'), + (0x3284, 'M', u'五'), + (0x3285, 'M', u'六'), + (0x3286, 'M', u'七'), + (0x3287, 'M', u'八'), + (0x3288, 'M', u'九'), + (0x3289, 'M', u'十'), + (0x328A, 'M', u'月'), + (0x328B, 'M', u'火'), + (0x328C, 'M', u'水'), + (0x328D, 'M', u'木'), + (0x328E, 'M', u'金'), + (0x328F, 'M', u'土'), + (0x3290, 'M', u'日'), + (0x3291, 'M', u'株'), + (0x3292, 'M', u'有'), + (0x3293, 'M', u'社'), + (0x3294, 'M', u'名'), + (0x3295, 'M', u'特'), + (0x3296, 'M', u'財'), + (0x3297, 'M', u'祝'), + (0x3298, 'M', u'労'), + (0x3299, 'M', u'秘'), + (0x329A, 'M', u'男'), + (0x329B, 'M', u'女'), + (0x329C, 'M', u'適'), + (0x329D, 'M', u'優'), + (0x329E, 'M', u'印'), + (0x329F, 'M', u'注'), + (0x32A0, 'M', u'項'), + (0x32A1, 'M', u'休'), + (0x32A2, 'M', u'写'), + (0x32A3, 'M', u'正'), + (0x32A4, 'M', u'上'), + (0x32A5, 'M', u'中'), + (0x32A6, 'M', u'下'), + (0x32A7, 'M', u'左'), + (0x32A8, 'M', u'右'), + (0x32A9, 'M', u'医'), + (0x32AA, 'M', u'宗'), + (0x32AB, 'M', u'学'), + (0x32AC, 'M', u'監'), + (0x32AD, 'M', u'企'), + (0x32AE, 'M', u'資'), + (0x32AF, 'M', u'協'), + (0x32B0, 'M', u'夜'), + (0x32B1, 'M', u'36'), + (0x32B2, 'M', u'37'), + (0x32B3, 'M', u'38'), + (0x32B4, 'M', u'39'), + (0x32B5, 'M', u'40'), + (0x32B6, 'M', u'41'), + (0x32B7, 'M', u'42'), + (0x32B8, 'M', u'43'), + (0x32B9, 'M', u'44'), + (0x32BA, 'M', u'45'), + (0x32BB, 'M', u'46'), + (0x32BC, 'M', u'47'), + ] + +def _seg_32(): + return [ + (0x32BD, 'M', u'48'), + (0x32BE, 'M', u'49'), + (0x32BF, 'M', u'50'), + (0x32C0, 'M', u'1月'), + (0x32C1, 'M', u'2月'), + (0x32C2, 'M', u'3月'), + (0x32C3, 'M', u'4月'), + (0x32C4, 'M', u'5月'), + (0x32C5, 'M', u'6月'), + (0x32C6, 'M', u'7月'), + (0x32C7, 'M', u'8月'), + (0x32C8, 'M', u'9月'), + (0x32C9, 'M', u'10月'), + (0x32CA, 'M', u'11月'), + (0x32CB, 'M', u'12月'), + (0x32CC, 'M', u'hg'), + (0x32CD, 'M', u'erg'), + (0x32CE, 'M', u'ev'), + (0x32CF, 'M', u'ltd'), + (0x32D0, 'M', u'ア'), + (0x32D1, 'M', u'イ'), + (0x32D2, 'M', u'ウ'), + (0x32D3, 'M', u'エ'), + (0x32D4, 'M', u'オ'), + (0x32D5, 'M', u'カ'), + (0x32D6, 'M', u'キ'), + (0x32D7, 'M', u'ク'), + (0x32D8, 'M', u'ケ'), + (0x32D9, 'M', u'コ'), + (0x32DA, 'M', u'サ'), + (0x32DB, 'M', u'シ'), + (0x32DC, 'M', u'ス'), + (0x32DD, 'M', u'セ'), + (0x32DE, 'M', u'ソ'), + (0x32DF, 'M', u'タ'), + (0x32E0, 'M', u'チ'), + (0x32E1, 'M', u'ツ'), + (0x32E2, 'M', u'テ'), + (0x32E3, 'M', u'ト'), + (0x32E4, 'M', u'ナ'), + (0x32E5, 'M', u'ニ'), + (0x32E6, 'M', u'ヌ'), + (0x32E7, 'M', u'ネ'), + (0x32E8, 'M', u'ノ'), + (0x32E9, 'M', u'ハ'), + (0x32EA, 'M', u'ヒ'), + (0x32EB, 'M', u'フ'), + (0x32EC, 'M', u'ヘ'), + (0x32ED, 'M', u'ホ'), + (0x32EE, 'M', u'マ'), + (0x32EF, 'M', u'ミ'), + (0x32F0, 'M', u'ム'), + (0x32F1, 'M', u'メ'), + (0x32F2, 'M', u'モ'), + (0x32F3, 'M', u'ヤ'), + (0x32F4, 'M', u'ユ'), + (0x32F5, 'M', u'ヨ'), + (0x32F6, 'M', u'ラ'), + (0x32F7, 'M', u'リ'), + (0x32F8, 'M', u'ル'), + (0x32F9, 'M', u'レ'), + (0x32FA, 'M', u'ロ'), + (0x32FB, 'M', u'ワ'), + (0x32FC, 'M', u'ヰ'), + (0x32FD, 'M', u'ヱ'), + (0x32FE, 'M', u'ヲ'), + (0x32FF, 'X'), + (0x3300, 'M', u'アパート'), + (0x3301, 'M', u'アルファ'), + (0x3302, 'M', u'アンペア'), + (0x3303, 'M', u'アール'), + (0x3304, 'M', u'イニング'), + (0x3305, 'M', u'インチ'), + (0x3306, 'M', u'ウォン'), + (0x3307, 'M', u'エスクード'), + (0x3308, 'M', u'エーカー'), + (0x3309, 'M', u'オンス'), + (0x330A, 'M', u'オーム'), + (0x330B, 'M', u'カイリ'), + (0x330C, 'M', u'カラット'), + (0x330D, 'M', u'カロリー'), + (0x330E, 'M', u'ガロン'), + (0x330F, 'M', u'ガンマ'), + (0x3310, 'M', u'ギガ'), + (0x3311, 'M', u'ギニー'), + (0x3312, 'M', u'キュリー'), + (0x3313, 'M', u'ギルダー'), + (0x3314, 'M', u'キロ'), + (0x3315, 'M', u'キログラム'), + (0x3316, 'M', u'キロメートル'), + (0x3317, 'M', u'キロワット'), + (0x3318, 'M', u'グラム'), + (0x3319, 'M', u'グラムトン'), + (0x331A, 'M', u'クルゼイロ'), + (0x331B, 'M', u'クローネ'), + (0x331C, 'M', u'ケース'), + (0x331D, 'M', u'コルナ'), + (0x331E, 'M', u'コーポ'), + (0x331F, 'M', u'サイクル'), + (0x3320, 'M', u'サンチーム'), + ] + +def _seg_33(): + return [ + (0x3321, 'M', u'シリング'), + (0x3322, 'M', u'センチ'), + (0x3323, 'M', u'セント'), + (0x3324, 'M', u'ダース'), + (0x3325, 'M', u'デシ'), + (0x3326, 'M', u'ドル'), + (0x3327, 'M', u'トン'), + (0x3328, 'M', u'ナノ'), + (0x3329, 'M', u'ノット'), + (0x332A, 'M', u'ハイツ'), + (0x332B, 'M', u'パーセント'), + (0x332C, 'M', u'パーツ'), + (0x332D, 'M', u'バーレル'), + (0x332E, 'M', u'ピアストル'), + (0x332F, 'M', u'ピクル'), + (0x3330, 'M', u'ピコ'), + (0x3331, 'M', u'ビル'), + (0x3332, 'M', u'ファラッド'), + (0x3333, 'M', u'フィート'), + (0x3334, 'M', u'ブッシェル'), + (0x3335, 'M', u'フラン'), + (0x3336, 'M', u'ヘクタール'), + (0x3337, 'M', u'ペソ'), + (0x3338, 'M', u'ペニヒ'), + (0x3339, 'M', u'ヘルツ'), + (0x333A, 'M', u'ペンス'), + (0x333B, 'M', u'ページ'), + (0x333C, 'M', u'ベータ'), + (0x333D, 'M', u'ポイント'), + (0x333E, 'M', u'ボルト'), + (0x333F, 'M', u'ホン'), + (0x3340, 'M', u'ポンド'), + (0x3341, 'M', u'ホール'), + (0x3342, 'M', u'ホーン'), + (0x3343, 'M', u'マイクロ'), + (0x3344, 'M', u'マイル'), + (0x3345, 'M', u'マッハ'), + (0x3346, 'M', u'マルク'), + (0x3347, 'M', u'マンション'), + (0x3348, 'M', u'ミクロン'), + (0x3349, 'M', u'ミリ'), + (0x334A, 'M', u'ミリバール'), + (0x334B, 'M', u'メガ'), + (0x334C, 'M', u'メガトン'), + (0x334D, 'M', u'メートル'), + (0x334E, 'M', u'ヤード'), + (0x334F, 'M', u'ヤール'), + (0x3350, 'M', u'ユアン'), + (0x3351, 'M', u'リットル'), + (0x3352, 'M', u'リラ'), + (0x3353, 'M', u'ルピー'), + (0x3354, 'M', u'ルーブル'), + (0x3355, 'M', u'レム'), + (0x3356, 'M', u'レントゲン'), + (0x3357, 'M', u'ワット'), + (0x3358, 'M', u'0点'), + (0x3359, 'M', u'1点'), + (0x335A, 'M', u'2点'), + (0x335B, 'M', u'3点'), + (0x335C, 'M', u'4点'), + (0x335D, 'M', u'5点'), + (0x335E, 'M', u'6点'), + (0x335F, 'M', u'7点'), + (0x3360, 'M', u'8点'), + (0x3361, 'M', u'9点'), + (0x3362, 'M', u'10点'), + (0x3363, 'M', u'11点'), + (0x3364, 'M', u'12点'), + (0x3365, 'M', u'13点'), + (0x3366, 'M', u'14点'), + (0x3367, 'M', u'15点'), + (0x3368, 'M', u'16点'), + (0x3369, 'M', u'17点'), + (0x336A, 'M', u'18点'), + (0x336B, 'M', u'19点'), + (0x336C, 'M', u'20点'), + (0x336D, 'M', u'21点'), + (0x336E, 'M', u'22点'), + (0x336F, 'M', u'23点'), + (0x3370, 'M', u'24点'), + (0x3371, 'M', u'hpa'), + (0x3372, 'M', u'da'), + (0x3373, 'M', u'au'), + (0x3374, 'M', u'bar'), + (0x3375, 'M', u'ov'), + (0x3376, 'M', u'pc'), + (0x3377, 'M', u'dm'), + (0x3378, 'M', u'dm2'), + (0x3379, 'M', u'dm3'), + (0x337A, 'M', u'iu'), + (0x337B, 'M', u'平成'), + (0x337C, 'M', u'昭和'), + (0x337D, 'M', u'大正'), + (0x337E, 'M', u'明治'), + (0x337F, 'M', u'株式会社'), + (0x3380, 'M', u'pa'), + (0x3381, 'M', u'na'), + (0x3382, 'M', u'μa'), + (0x3383, 'M', u'ma'), + (0x3384, 'M', u'ka'), + ] + +def _seg_34(): + return [ + (0x3385, 'M', u'kb'), + (0x3386, 'M', u'mb'), + (0x3387, 'M', u'gb'), + (0x3388, 'M', u'cal'), + (0x3389, 'M', u'kcal'), + (0x338A, 'M', u'pf'), + (0x338B, 'M', u'nf'), + (0x338C, 'M', u'μf'), + (0x338D, 'M', u'μg'), + (0x338E, 'M', u'mg'), + (0x338F, 'M', u'kg'), + (0x3390, 'M', u'hz'), + (0x3391, 'M', u'khz'), + (0x3392, 'M', u'mhz'), + (0x3393, 'M', u'ghz'), + (0x3394, 'M', u'thz'), + (0x3395, 'M', u'μl'), + (0x3396, 'M', u'ml'), + (0x3397, 'M', u'dl'), + (0x3398, 'M', u'kl'), + (0x3399, 'M', u'fm'), + (0x339A, 'M', u'nm'), + (0x339B, 'M', u'μm'), + (0x339C, 'M', u'mm'), + (0x339D, 'M', u'cm'), + (0x339E, 'M', u'km'), + (0x339F, 'M', u'mm2'), + (0x33A0, 'M', u'cm2'), + (0x33A1, 'M', u'm2'), + (0x33A2, 'M', u'km2'), + (0x33A3, 'M', u'mm3'), + (0x33A4, 'M', u'cm3'), + (0x33A5, 'M', u'm3'), + (0x33A6, 'M', u'km3'), + (0x33A7, 'M', u'm∕s'), + (0x33A8, 'M', u'm∕s2'), + (0x33A9, 'M', u'pa'), + (0x33AA, 'M', u'kpa'), + (0x33AB, 'M', u'mpa'), + (0x33AC, 'M', u'gpa'), + (0x33AD, 'M', u'rad'), + (0x33AE, 'M', u'rad∕s'), + (0x33AF, 'M', u'rad∕s2'), + (0x33B0, 'M', u'ps'), + (0x33B1, 'M', u'ns'), + (0x33B2, 'M', u'μs'), + (0x33B3, 'M', u'ms'), + (0x33B4, 'M', u'pv'), + (0x33B5, 'M', u'nv'), + (0x33B6, 'M', u'μv'), + (0x33B7, 'M', u'mv'), + (0x33B8, 'M', u'kv'), + (0x33B9, 'M', u'mv'), + (0x33BA, 'M', u'pw'), + (0x33BB, 'M', u'nw'), + (0x33BC, 'M', u'μw'), + (0x33BD, 'M', u'mw'), + (0x33BE, 'M', u'kw'), + (0x33BF, 'M', u'mw'), + (0x33C0, 'M', u'kω'), + (0x33C1, 'M', u'mω'), + (0x33C2, 'X'), + (0x33C3, 'M', u'bq'), + (0x33C4, 'M', u'cc'), + (0x33C5, 'M', u'cd'), + (0x33C6, 'M', u'c∕kg'), + (0x33C7, 'X'), + (0x33C8, 'M', u'db'), + (0x33C9, 'M', u'gy'), + (0x33CA, 'M', u'ha'), + (0x33CB, 'M', u'hp'), + (0x33CC, 'M', u'in'), + (0x33CD, 'M', u'kk'), + (0x33CE, 'M', u'km'), + (0x33CF, 'M', u'kt'), + (0x33D0, 'M', u'lm'), + (0x33D1, 'M', u'ln'), + (0x33D2, 'M', u'log'), + (0x33D3, 'M', u'lx'), + (0x33D4, 'M', u'mb'), + (0x33D5, 'M', u'mil'), + (0x33D6, 'M', u'mol'), + (0x33D7, 'M', u'ph'), + (0x33D8, 'X'), + (0x33D9, 'M', u'ppm'), + (0x33DA, 'M', u'pr'), + (0x33DB, 'M', u'sr'), + (0x33DC, 'M', u'sv'), + (0x33DD, 'M', u'wb'), + (0x33DE, 'M', u'v∕m'), + (0x33DF, 'M', u'a∕m'), + (0x33E0, 'M', u'1日'), + (0x33E1, 'M', u'2日'), + (0x33E2, 'M', u'3日'), + (0x33E3, 'M', u'4日'), + (0x33E4, 'M', u'5日'), + (0x33E5, 'M', u'6日'), + (0x33E6, 'M', u'7日'), + (0x33E7, 'M', u'8日'), + (0x33E8, 'M', u'9日'), + ] + +def _seg_35(): + return [ + (0x33E9, 'M', u'10日'), + (0x33EA, 'M', u'11日'), + (0x33EB, 'M', u'12日'), + (0x33EC, 'M', u'13日'), + (0x33ED, 'M', u'14日'), + (0x33EE, 'M', u'15日'), + (0x33EF, 'M', u'16日'), + (0x33F0, 'M', u'17日'), + (0x33F1, 'M', u'18日'), + (0x33F2, 'M', u'19日'), + (0x33F3, 'M', u'20日'), + (0x33F4, 'M', u'21日'), + (0x33F5, 'M', u'22日'), + (0x33F6, 'M', u'23日'), + (0x33F7, 'M', u'24日'), + (0x33F8, 'M', u'25日'), + (0x33F9, 'M', u'26日'), + (0x33FA, 'M', u'27日'), + (0x33FB, 'M', u'28日'), + (0x33FC, 'M', u'29日'), + (0x33FD, 'M', u'30日'), + (0x33FE, 'M', u'31日'), + (0x33FF, 'M', u'gal'), + (0x3400, 'V'), + (0x4DB6, 'X'), + (0x4DC0, 'V'), + (0x9FEB, 'X'), + (0xA000, 'V'), + (0xA48D, 'X'), + (0xA490, 'V'), + (0xA4C7, 'X'), + (0xA4D0, 'V'), + (0xA62C, 'X'), + (0xA640, 'M', u'ꙁ'), + (0xA641, 'V'), + (0xA642, 'M', u'ꙃ'), + (0xA643, 'V'), + (0xA644, 'M', u'ꙅ'), + (0xA645, 'V'), + (0xA646, 'M', u'ꙇ'), + (0xA647, 'V'), + (0xA648, 'M', u'ꙉ'), + (0xA649, 'V'), + (0xA64A, 'M', u'ꙋ'), + (0xA64B, 'V'), + (0xA64C, 'M', u'ꙍ'), + (0xA64D, 'V'), + (0xA64E, 'M', u'ꙏ'), + (0xA64F, 'V'), + (0xA650, 'M', u'ꙑ'), + (0xA651, 'V'), + (0xA652, 'M', u'ꙓ'), + (0xA653, 'V'), + (0xA654, 'M', u'ꙕ'), + (0xA655, 'V'), + (0xA656, 'M', u'ꙗ'), + (0xA657, 'V'), + (0xA658, 'M', u'ꙙ'), + (0xA659, 'V'), + (0xA65A, 'M', u'ꙛ'), + (0xA65B, 'V'), + (0xA65C, 'M', u'ꙝ'), + (0xA65D, 'V'), + (0xA65E, 'M', u'ꙟ'), + (0xA65F, 'V'), + (0xA660, 'M', u'ꙡ'), + (0xA661, 'V'), + (0xA662, 'M', u'ꙣ'), + (0xA663, 'V'), + (0xA664, 'M', u'ꙥ'), + (0xA665, 'V'), + (0xA666, 'M', u'ꙧ'), + (0xA667, 'V'), + (0xA668, 'M', u'ꙩ'), + (0xA669, 'V'), + (0xA66A, 'M', u'ꙫ'), + (0xA66B, 'V'), + (0xA66C, 'M', u'ꙭ'), + (0xA66D, 'V'), + (0xA680, 'M', u'ꚁ'), + (0xA681, 'V'), + (0xA682, 'M', u'ꚃ'), + (0xA683, 'V'), + (0xA684, 'M', u'ꚅ'), + (0xA685, 'V'), + (0xA686, 'M', u'ꚇ'), + (0xA687, 'V'), + (0xA688, 'M', u'ꚉ'), + (0xA689, 'V'), + (0xA68A, 'M', u'ꚋ'), + (0xA68B, 'V'), + (0xA68C, 'M', u'ꚍ'), + (0xA68D, 'V'), + (0xA68E, 'M', u'ꚏ'), + (0xA68F, 'V'), + (0xA690, 'M', u'ꚑ'), + (0xA691, 'V'), + (0xA692, 'M', u'ꚓ'), + (0xA693, 'V'), + (0xA694, 'M', u'ꚕ'), + ] + +def _seg_36(): + return [ + (0xA695, 'V'), + (0xA696, 'M', u'ꚗ'), + (0xA697, 'V'), + (0xA698, 'M', u'ꚙ'), + (0xA699, 'V'), + (0xA69A, 'M', u'ꚛ'), + (0xA69B, 'V'), + (0xA69C, 'M', u'ъ'), + (0xA69D, 'M', u'ь'), + (0xA69E, 'V'), + (0xA6F8, 'X'), + (0xA700, 'V'), + (0xA722, 'M', u'ꜣ'), + (0xA723, 'V'), + (0xA724, 'M', u'ꜥ'), + (0xA725, 'V'), + (0xA726, 'M', u'ꜧ'), + (0xA727, 'V'), + (0xA728, 'M', u'ꜩ'), + (0xA729, 'V'), + (0xA72A, 'M', u'ꜫ'), + (0xA72B, 'V'), + (0xA72C, 'M', u'ꜭ'), + (0xA72D, 'V'), + (0xA72E, 'M', u'ꜯ'), + (0xA72F, 'V'), + (0xA732, 'M', u'ꜳ'), + (0xA733, 'V'), + (0xA734, 'M', u'ꜵ'), + (0xA735, 'V'), + (0xA736, 'M', u'ꜷ'), + (0xA737, 'V'), + (0xA738, 'M', u'ꜹ'), + (0xA739, 'V'), + (0xA73A, 'M', u'ꜻ'), + (0xA73B, 'V'), + (0xA73C, 'M', u'ꜽ'), + (0xA73D, 'V'), + (0xA73E, 'M', u'ꜿ'), + (0xA73F, 'V'), + (0xA740, 'M', u'ꝁ'), + (0xA741, 'V'), + (0xA742, 'M', u'ꝃ'), + (0xA743, 'V'), + (0xA744, 'M', u'ꝅ'), + (0xA745, 'V'), + (0xA746, 'M', u'ꝇ'), + (0xA747, 'V'), + (0xA748, 'M', u'ꝉ'), + (0xA749, 'V'), + (0xA74A, 'M', u'ꝋ'), + (0xA74B, 'V'), + (0xA74C, 'M', u'ꝍ'), + (0xA74D, 'V'), + (0xA74E, 'M', u'ꝏ'), + (0xA74F, 'V'), + (0xA750, 'M', u'ꝑ'), + (0xA751, 'V'), + (0xA752, 'M', u'ꝓ'), + (0xA753, 'V'), + (0xA754, 'M', u'ꝕ'), + (0xA755, 'V'), + (0xA756, 'M', u'ꝗ'), + (0xA757, 'V'), + (0xA758, 'M', u'ꝙ'), + (0xA759, 'V'), + (0xA75A, 'M', u'ꝛ'), + (0xA75B, 'V'), + (0xA75C, 'M', u'ꝝ'), + (0xA75D, 'V'), + (0xA75E, 'M', u'ꝟ'), + (0xA75F, 'V'), + (0xA760, 'M', u'ꝡ'), + (0xA761, 'V'), + (0xA762, 'M', u'ꝣ'), + (0xA763, 'V'), + (0xA764, 'M', u'ꝥ'), + (0xA765, 'V'), + (0xA766, 'M', u'ꝧ'), + (0xA767, 'V'), + (0xA768, 'M', u'ꝩ'), + (0xA769, 'V'), + (0xA76A, 'M', u'ꝫ'), + (0xA76B, 'V'), + (0xA76C, 'M', u'ꝭ'), + (0xA76D, 'V'), + (0xA76E, 'M', u'ꝯ'), + (0xA76F, 'V'), + (0xA770, 'M', u'ꝯ'), + (0xA771, 'V'), + (0xA779, 'M', u'ꝺ'), + (0xA77A, 'V'), + (0xA77B, 'M', u'ꝼ'), + (0xA77C, 'V'), + (0xA77D, 'M', u'ᵹ'), + (0xA77E, 'M', u'ꝿ'), + (0xA77F, 'V'), + (0xA780, 'M', u'ꞁ'), + (0xA781, 'V'), + (0xA782, 'M', u'ꞃ'), + ] + +def _seg_37(): + return [ + (0xA783, 'V'), + (0xA784, 'M', u'ꞅ'), + (0xA785, 'V'), + (0xA786, 'M', u'ꞇ'), + (0xA787, 'V'), + (0xA78B, 'M', u'ꞌ'), + (0xA78C, 'V'), + (0xA78D, 'M', u'ɥ'), + (0xA78E, 'V'), + (0xA790, 'M', u'ꞑ'), + (0xA791, 'V'), + (0xA792, 'M', u'ꞓ'), + (0xA793, 'V'), + (0xA796, 'M', u'ꞗ'), + (0xA797, 'V'), + (0xA798, 'M', u'ꞙ'), + (0xA799, 'V'), + (0xA79A, 'M', u'ꞛ'), + (0xA79B, 'V'), + (0xA79C, 'M', u'ꞝ'), + (0xA79D, 'V'), + (0xA79E, 'M', u'ꞟ'), + (0xA79F, 'V'), + (0xA7A0, 'M', u'ꞡ'), + (0xA7A1, 'V'), + (0xA7A2, 'M', u'ꞣ'), + (0xA7A3, 'V'), + (0xA7A4, 'M', u'ꞥ'), + (0xA7A5, 'V'), + (0xA7A6, 'M', u'ꞧ'), + (0xA7A7, 'V'), + (0xA7A8, 'M', u'ꞩ'), + (0xA7A9, 'V'), + (0xA7AA, 'M', u'ɦ'), + (0xA7AB, 'M', u'ɜ'), + (0xA7AC, 'M', u'ɡ'), + (0xA7AD, 'M', u'ɬ'), + (0xA7AE, 'M', u'ɪ'), + (0xA7AF, 'X'), + (0xA7B0, 'M', u'ʞ'), + (0xA7B1, 'M', u'ʇ'), + (0xA7B2, 'M', u'ʝ'), + (0xA7B3, 'M', u'ꭓ'), + (0xA7B4, 'M', u'ꞵ'), + (0xA7B5, 'V'), + (0xA7B6, 'M', u'ꞷ'), + (0xA7B7, 'V'), + (0xA7B8, 'X'), + (0xA7F7, 'V'), + (0xA7F8, 'M', u'ħ'), + (0xA7F9, 'M', u'œ'), + (0xA7FA, 'V'), + (0xA82C, 'X'), + (0xA830, 'V'), + (0xA83A, 'X'), + (0xA840, 'V'), + (0xA878, 'X'), + (0xA880, 'V'), + (0xA8C6, 'X'), + (0xA8CE, 'V'), + (0xA8DA, 'X'), + (0xA8E0, 'V'), + (0xA8FE, 'X'), + (0xA900, 'V'), + (0xA954, 'X'), + (0xA95F, 'V'), + (0xA97D, 'X'), + (0xA980, 'V'), + (0xA9CE, 'X'), + (0xA9CF, 'V'), + (0xA9DA, 'X'), + (0xA9DE, 'V'), + (0xA9FF, 'X'), + (0xAA00, 'V'), + (0xAA37, 'X'), + (0xAA40, 'V'), + (0xAA4E, 'X'), + (0xAA50, 'V'), + (0xAA5A, 'X'), + (0xAA5C, 'V'), + (0xAAC3, 'X'), + (0xAADB, 'V'), + (0xAAF7, 'X'), + (0xAB01, 'V'), + (0xAB07, 'X'), + (0xAB09, 'V'), + (0xAB0F, 'X'), + (0xAB11, 'V'), + (0xAB17, 'X'), + (0xAB20, 'V'), + (0xAB27, 'X'), + (0xAB28, 'V'), + (0xAB2F, 'X'), + (0xAB30, 'V'), + (0xAB5C, 'M', u'ꜧ'), + (0xAB5D, 'M', u'ꬷ'), + (0xAB5E, 'M', u'ɫ'), + (0xAB5F, 'M', u'ꭒ'), + (0xAB60, 'V'), + (0xAB66, 'X'), + ] + +def _seg_38(): + return [ + (0xAB70, 'M', u'Ꭰ'), + (0xAB71, 'M', u'Ꭱ'), + (0xAB72, 'M', u'Ꭲ'), + (0xAB73, 'M', u'Ꭳ'), + (0xAB74, 'M', u'Ꭴ'), + (0xAB75, 'M', u'Ꭵ'), + (0xAB76, 'M', u'Ꭶ'), + (0xAB77, 'M', u'Ꭷ'), + (0xAB78, 'M', u'Ꭸ'), + (0xAB79, 'M', u'Ꭹ'), + (0xAB7A, 'M', u'Ꭺ'), + (0xAB7B, 'M', u'Ꭻ'), + (0xAB7C, 'M', u'Ꭼ'), + (0xAB7D, 'M', u'Ꭽ'), + (0xAB7E, 'M', u'Ꭾ'), + (0xAB7F, 'M', u'Ꭿ'), + (0xAB80, 'M', u'Ꮀ'), + (0xAB81, 'M', u'Ꮁ'), + (0xAB82, 'M', u'Ꮂ'), + (0xAB83, 'M', u'Ꮃ'), + (0xAB84, 'M', u'Ꮄ'), + (0xAB85, 'M', u'Ꮅ'), + (0xAB86, 'M', u'Ꮆ'), + (0xAB87, 'M', u'Ꮇ'), + (0xAB88, 'M', u'Ꮈ'), + (0xAB89, 'M', u'Ꮉ'), + (0xAB8A, 'M', u'Ꮊ'), + (0xAB8B, 'M', u'Ꮋ'), + (0xAB8C, 'M', u'Ꮌ'), + (0xAB8D, 'M', u'Ꮍ'), + (0xAB8E, 'M', u'Ꮎ'), + (0xAB8F, 'M', u'Ꮏ'), + (0xAB90, 'M', u'Ꮐ'), + (0xAB91, 'M', u'Ꮑ'), + (0xAB92, 'M', u'Ꮒ'), + (0xAB93, 'M', u'Ꮓ'), + (0xAB94, 'M', u'Ꮔ'), + (0xAB95, 'M', u'Ꮕ'), + (0xAB96, 'M', u'Ꮖ'), + (0xAB97, 'M', u'Ꮗ'), + (0xAB98, 'M', u'Ꮘ'), + (0xAB99, 'M', u'Ꮙ'), + (0xAB9A, 'M', u'Ꮚ'), + (0xAB9B, 'M', u'Ꮛ'), + (0xAB9C, 'M', u'Ꮜ'), + (0xAB9D, 'M', u'Ꮝ'), + (0xAB9E, 'M', u'Ꮞ'), + (0xAB9F, 'M', u'Ꮟ'), + (0xABA0, 'M', u'Ꮠ'), + (0xABA1, 'M', u'Ꮡ'), + (0xABA2, 'M', u'Ꮢ'), + (0xABA3, 'M', u'Ꮣ'), + (0xABA4, 'M', u'Ꮤ'), + (0xABA5, 'M', u'Ꮥ'), + (0xABA6, 'M', u'Ꮦ'), + (0xABA7, 'M', u'Ꮧ'), + (0xABA8, 'M', u'Ꮨ'), + (0xABA9, 'M', u'Ꮩ'), + (0xABAA, 'M', u'Ꮪ'), + (0xABAB, 'M', u'Ꮫ'), + (0xABAC, 'M', u'Ꮬ'), + (0xABAD, 'M', u'Ꮭ'), + (0xABAE, 'M', u'Ꮮ'), + (0xABAF, 'M', u'Ꮯ'), + (0xABB0, 'M', u'Ꮰ'), + (0xABB1, 'M', u'Ꮱ'), + (0xABB2, 'M', u'Ꮲ'), + (0xABB3, 'M', u'Ꮳ'), + (0xABB4, 'M', u'Ꮴ'), + (0xABB5, 'M', u'Ꮵ'), + (0xABB6, 'M', u'Ꮶ'), + (0xABB7, 'M', u'Ꮷ'), + (0xABB8, 'M', u'Ꮸ'), + (0xABB9, 'M', u'Ꮹ'), + (0xABBA, 'M', u'Ꮺ'), + (0xABBB, 'M', u'Ꮻ'), + (0xABBC, 'M', u'Ꮼ'), + (0xABBD, 'M', u'Ꮽ'), + (0xABBE, 'M', u'Ꮾ'), + (0xABBF, 'M', u'Ꮿ'), + (0xABC0, 'V'), + (0xABEE, 'X'), + (0xABF0, 'V'), + (0xABFA, 'X'), + (0xAC00, 'V'), + (0xD7A4, 'X'), + (0xD7B0, 'V'), + (0xD7C7, 'X'), + (0xD7CB, 'V'), + (0xD7FC, 'X'), + (0xF900, 'M', u'豈'), + (0xF901, 'M', u'更'), + (0xF902, 'M', u'車'), + (0xF903, 'M', u'賈'), + (0xF904, 'M', u'滑'), + (0xF905, 'M', u'串'), + (0xF906, 'M', u'句'), + (0xF907, 'M', u'龜'), + (0xF909, 'M', u'契'), + (0xF90A, 'M', u'金'), + ] + +def _seg_39(): + return [ + (0xF90B, 'M', u'喇'), + (0xF90C, 'M', u'奈'), + (0xF90D, 'M', u'懶'), + (0xF90E, 'M', u'癩'), + (0xF90F, 'M', u'羅'), + (0xF910, 'M', u'蘿'), + (0xF911, 'M', u'螺'), + (0xF912, 'M', u'裸'), + (0xF913, 'M', u'邏'), + (0xF914, 'M', u'樂'), + (0xF915, 'M', u'洛'), + (0xF916, 'M', u'烙'), + (0xF917, 'M', u'珞'), + (0xF918, 'M', u'落'), + (0xF919, 'M', u'酪'), + (0xF91A, 'M', u'駱'), + (0xF91B, 'M', u'亂'), + (0xF91C, 'M', u'卵'), + (0xF91D, 'M', u'欄'), + (0xF91E, 'M', u'爛'), + (0xF91F, 'M', u'蘭'), + (0xF920, 'M', u'鸞'), + (0xF921, 'M', u'嵐'), + (0xF922, 'M', u'濫'), + (0xF923, 'M', u'藍'), + (0xF924, 'M', u'襤'), + (0xF925, 'M', u'拉'), + (0xF926, 'M', u'臘'), + (0xF927, 'M', u'蠟'), + (0xF928, 'M', u'廊'), + (0xF929, 'M', u'朗'), + (0xF92A, 'M', u'浪'), + (0xF92B, 'M', u'狼'), + (0xF92C, 'M', u'郎'), + (0xF92D, 'M', u'來'), + (0xF92E, 'M', u'冷'), + (0xF92F, 'M', u'勞'), + (0xF930, 'M', u'擄'), + (0xF931, 'M', u'櫓'), + (0xF932, 'M', u'爐'), + (0xF933, 'M', u'盧'), + (0xF934, 'M', u'老'), + (0xF935, 'M', u'蘆'), + (0xF936, 'M', u'虜'), + (0xF937, 'M', u'路'), + (0xF938, 'M', u'露'), + (0xF939, 'M', u'魯'), + (0xF93A, 'M', u'鷺'), + (0xF93B, 'M', u'碌'), + (0xF93C, 'M', u'祿'), + (0xF93D, 'M', u'綠'), + (0xF93E, 'M', u'菉'), + (0xF93F, 'M', u'錄'), + (0xF940, 'M', u'鹿'), + (0xF941, 'M', u'論'), + (0xF942, 'M', u'壟'), + (0xF943, 'M', u'弄'), + (0xF944, 'M', u'籠'), + (0xF945, 'M', u'聾'), + (0xF946, 'M', u'牢'), + (0xF947, 'M', u'磊'), + (0xF948, 'M', u'賂'), + (0xF949, 'M', u'雷'), + (0xF94A, 'M', u'壘'), + (0xF94B, 'M', u'屢'), + (0xF94C, 'M', u'樓'), + (0xF94D, 'M', u'淚'), + (0xF94E, 'M', u'漏'), + (0xF94F, 'M', u'累'), + (0xF950, 'M', u'縷'), + (0xF951, 'M', u'陋'), + (0xF952, 'M', u'勒'), + (0xF953, 'M', u'肋'), + (0xF954, 'M', u'凜'), + (0xF955, 'M', u'凌'), + (0xF956, 'M', u'稜'), + (0xF957, 'M', u'綾'), + (0xF958, 'M', u'菱'), + (0xF959, 'M', u'陵'), + (0xF95A, 'M', u'讀'), + (0xF95B, 'M', u'拏'), + (0xF95C, 'M', u'樂'), + (0xF95D, 'M', u'諾'), + (0xF95E, 'M', u'丹'), + (0xF95F, 'M', u'寧'), + (0xF960, 'M', u'怒'), + (0xF961, 'M', u'率'), + (0xF962, 'M', u'異'), + (0xF963, 'M', u'北'), + (0xF964, 'M', u'磻'), + (0xF965, 'M', u'便'), + (0xF966, 'M', u'復'), + (0xF967, 'M', u'不'), + (0xF968, 'M', u'泌'), + (0xF969, 'M', u'數'), + (0xF96A, 'M', u'索'), + (0xF96B, 'M', u'參'), + (0xF96C, 'M', u'塞'), + (0xF96D, 'M', u'省'), + (0xF96E, 'M', u'葉'), + ] + +def _seg_40(): + return [ + (0xF96F, 'M', u'說'), + (0xF970, 'M', u'殺'), + (0xF971, 'M', u'辰'), + (0xF972, 'M', u'沈'), + (0xF973, 'M', u'拾'), + (0xF974, 'M', u'若'), + (0xF975, 'M', u'掠'), + (0xF976, 'M', u'略'), + (0xF977, 'M', u'亮'), + (0xF978, 'M', u'兩'), + (0xF979, 'M', u'凉'), + (0xF97A, 'M', u'梁'), + (0xF97B, 'M', u'糧'), + (0xF97C, 'M', u'良'), + (0xF97D, 'M', u'諒'), + (0xF97E, 'M', u'量'), + (0xF97F, 'M', u'勵'), + (0xF980, 'M', u'呂'), + (0xF981, 'M', u'女'), + (0xF982, 'M', u'廬'), + (0xF983, 'M', u'旅'), + (0xF984, 'M', u'濾'), + (0xF985, 'M', u'礪'), + (0xF986, 'M', u'閭'), + (0xF987, 'M', u'驪'), + (0xF988, 'M', u'麗'), + (0xF989, 'M', u'黎'), + (0xF98A, 'M', u'力'), + (0xF98B, 'M', u'曆'), + (0xF98C, 'M', u'歷'), + (0xF98D, 'M', u'轢'), + (0xF98E, 'M', u'年'), + (0xF98F, 'M', u'憐'), + (0xF990, 'M', u'戀'), + (0xF991, 'M', u'撚'), + (0xF992, 'M', u'漣'), + (0xF993, 'M', u'煉'), + (0xF994, 'M', u'璉'), + (0xF995, 'M', u'秊'), + (0xF996, 'M', u'練'), + (0xF997, 'M', u'聯'), + (0xF998, 'M', u'輦'), + (0xF999, 'M', u'蓮'), + (0xF99A, 'M', u'連'), + (0xF99B, 'M', u'鍊'), + (0xF99C, 'M', u'列'), + (0xF99D, 'M', u'劣'), + (0xF99E, 'M', u'咽'), + (0xF99F, 'M', u'烈'), + (0xF9A0, 'M', u'裂'), + (0xF9A1, 'M', u'說'), + (0xF9A2, 'M', u'廉'), + (0xF9A3, 'M', u'念'), + (0xF9A4, 'M', u'捻'), + (0xF9A5, 'M', u'殮'), + (0xF9A6, 'M', u'簾'), + (0xF9A7, 'M', u'獵'), + (0xF9A8, 'M', u'令'), + (0xF9A9, 'M', u'囹'), + (0xF9AA, 'M', u'寧'), + (0xF9AB, 'M', u'嶺'), + (0xF9AC, 'M', u'怜'), + (0xF9AD, 'M', u'玲'), + (0xF9AE, 'M', u'瑩'), + (0xF9AF, 'M', u'羚'), + (0xF9B0, 'M', u'聆'), + (0xF9B1, 'M', u'鈴'), + (0xF9B2, 'M', u'零'), + (0xF9B3, 'M', u'靈'), + (0xF9B4, 'M', u'領'), + (0xF9B5, 'M', u'例'), + (0xF9B6, 'M', u'禮'), + (0xF9B7, 'M', u'醴'), + (0xF9B8, 'M', u'隸'), + (0xF9B9, 'M', u'惡'), + (0xF9BA, 'M', u'了'), + (0xF9BB, 'M', u'僚'), + (0xF9BC, 'M', u'寮'), + (0xF9BD, 'M', u'尿'), + (0xF9BE, 'M', u'料'), + (0xF9BF, 'M', u'樂'), + (0xF9C0, 'M', u'燎'), + (0xF9C1, 'M', u'療'), + (0xF9C2, 'M', u'蓼'), + (0xF9C3, 'M', u'遼'), + (0xF9C4, 'M', u'龍'), + (0xF9C5, 'M', u'暈'), + (0xF9C6, 'M', u'阮'), + (0xF9C7, 'M', u'劉'), + (0xF9C8, 'M', u'杻'), + (0xF9C9, 'M', u'柳'), + (0xF9CA, 'M', u'流'), + (0xF9CB, 'M', u'溜'), + (0xF9CC, 'M', u'琉'), + (0xF9CD, 'M', u'留'), + (0xF9CE, 'M', u'硫'), + (0xF9CF, 'M', u'紐'), + (0xF9D0, 'M', u'類'), + (0xF9D1, 'M', u'六'), + (0xF9D2, 'M', u'戮'), + ] + +def _seg_41(): + return [ + (0xF9D3, 'M', u'陸'), + (0xF9D4, 'M', u'倫'), + (0xF9D5, 'M', u'崙'), + (0xF9D6, 'M', u'淪'), + (0xF9D7, 'M', u'輪'), + (0xF9D8, 'M', u'律'), + (0xF9D9, 'M', u'慄'), + (0xF9DA, 'M', u'栗'), + (0xF9DB, 'M', u'率'), + (0xF9DC, 'M', u'隆'), + (0xF9DD, 'M', u'利'), + (0xF9DE, 'M', u'吏'), + (0xF9DF, 'M', u'履'), + (0xF9E0, 'M', u'易'), + (0xF9E1, 'M', u'李'), + (0xF9E2, 'M', u'梨'), + (0xF9E3, 'M', u'泥'), + (0xF9E4, 'M', u'理'), + (0xF9E5, 'M', u'痢'), + (0xF9E6, 'M', u'罹'), + (0xF9E7, 'M', u'裏'), + (0xF9E8, 'M', u'裡'), + (0xF9E9, 'M', u'里'), + (0xF9EA, 'M', u'離'), + (0xF9EB, 'M', u'匿'), + (0xF9EC, 'M', u'溺'), + (0xF9ED, 'M', u'吝'), + (0xF9EE, 'M', u'燐'), + (0xF9EF, 'M', u'璘'), + (0xF9F0, 'M', u'藺'), + (0xF9F1, 'M', u'隣'), + (0xF9F2, 'M', u'鱗'), + (0xF9F3, 'M', u'麟'), + (0xF9F4, 'M', u'林'), + (0xF9F5, 'M', u'淋'), + (0xF9F6, 'M', u'臨'), + (0xF9F7, 'M', u'立'), + (0xF9F8, 'M', u'笠'), + (0xF9F9, 'M', u'粒'), + (0xF9FA, 'M', u'狀'), + (0xF9FB, 'M', u'炙'), + (0xF9FC, 'M', u'識'), + (0xF9FD, 'M', u'什'), + (0xF9FE, 'M', u'茶'), + (0xF9FF, 'M', u'刺'), + (0xFA00, 'M', u'切'), + (0xFA01, 'M', u'度'), + (0xFA02, 'M', u'拓'), + (0xFA03, 'M', u'糖'), + (0xFA04, 'M', u'宅'), + (0xFA05, 'M', u'洞'), + (0xFA06, 'M', u'暴'), + (0xFA07, 'M', u'輻'), + (0xFA08, 'M', u'行'), + (0xFA09, 'M', u'降'), + (0xFA0A, 'M', u'見'), + (0xFA0B, 'M', u'廓'), + (0xFA0C, 'M', u'兀'), + (0xFA0D, 'M', u'嗀'), + (0xFA0E, 'V'), + (0xFA10, 'M', u'塚'), + (0xFA11, 'V'), + (0xFA12, 'M', u'晴'), + (0xFA13, 'V'), + (0xFA15, 'M', u'凞'), + (0xFA16, 'M', u'猪'), + (0xFA17, 'M', u'益'), + (0xFA18, 'M', u'礼'), + (0xFA19, 'M', u'神'), + (0xFA1A, 'M', u'祥'), + (0xFA1B, 'M', u'福'), + (0xFA1C, 'M', u'靖'), + (0xFA1D, 'M', u'精'), + (0xFA1E, 'M', u'羽'), + (0xFA1F, 'V'), + (0xFA20, 'M', u'蘒'), + (0xFA21, 'V'), + (0xFA22, 'M', u'諸'), + (0xFA23, 'V'), + (0xFA25, 'M', u'逸'), + (0xFA26, 'M', u'都'), + (0xFA27, 'V'), + (0xFA2A, 'M', u'飯'), + (0xFA2B, 'M', u'飼'), + (0xFA2C, 'M', u'館'), + (0xFA2D, 'M', u'鶴'), + (0xFA2E, 'M', u'郞'), + (0xFA2F, 'M', u'隷'), + (0xFA30, 'M', u'侮'), + (0xFA31, 'M', u'僧'), + (0xFA32, 'M', u'免'), + (0xFA33, 'M', u'勉'), + (0xFA34, 'M', u'勤'), + (0xFA35, 'M', u'卑'), + (0xFA36, 'M', u'喝'), + (0xFA37, 'M', u'嘆'), + (0xFA38, 'M', u'器'), + (0xFA39, 'M', u'塀'), + (0xFA3A, 'M', u'墨'), + (0xFA3B, 'M', u'層'), + ] + +def _seg_42(): + return [ + (0xFA3C, 'M', u'屮'), + (0xFA3D, 'M', u'悔'), + (0xFA3E, 'M', u'慨'), + (0xFA3F, 'M', u'憎'), + (0xFA40, 'M', u'懲'), + (0xFA41, 'M', u'敏'), + (0xFA42, 'M', u'既'), + (0xFA43, 'M', u'暑'), + (0xFA44, 'M', u'梅'), + (0xFA45, 'M', u'海'), + (0xFA46, 'M', u'渚'), + (0xFA47, 'M', u'漢'), + (0xFA48, 'M', u'煮'), + (0xFA49, 'M', u'爫'), + (0xFA4A, 'M', u'琢'), + (0xFA4B, 'M', u'碑'), + (0xFA4C, 'M', u'社'), + (0xFA4D, 'M', u'祉'), + (0xFA4E, 'M', u'祈'), + (0xFA4F, 'M', u'祐'), + (0xFA50, 'M', u'祖'), + (0xFA51, 'M', u'祝'), + (0xFA52, 'M', u'禍'), + (0xFA53, 'M', u'禎'), + (0xFA54, 'M', u'穀'), + (0xFA55, 'M', u'突'), + (0xFA56, 'M', u'節'), + (0xFA57, 'M', u'練'), + (0xFA58, 'M', u'縉'), + (0xFA59, 'M', u'繁'), + (0xFA5A, 'M', u'署'), + (0xFA5B, 'M', u'者'), + (0xFA5C, 'M', u'臭'), + (0xFA5D, 'M', u'艹'), + (0xFA5F, 'M', u'著'), + (0xFA60, 'M', u'褐'), + (0xFA61, 'M', u'視'), + (0xFA62, 'M', u'謁'), + (0xFA63, 'M', u'謹'), + (0xFA64, 'M', u'賓'), + (0xFA65, 'M', u'贈'), + (0xFA66, 'M', u'辶'), + (0xFA67, 'M', u'逸'), + (0xFA68, 'M', u'難'), + (0xFA69, 'M', u'響'), + (0xFA6A, 'M', u'頻'), + (0xFA6B, 'M', u'恵'), + (0xFA6C, 'M', u'𤋮'), + (0xFA6D, 'M', u'舘'), + (0xFA6E, 'X'), + (0xFA70, 'M', u'並'), + (0xFA71, 'M', u'况'), + (0xFA72, 'M', u'全'), + (0xFA73, 'M', u'侀'), + (0xFA74, 'M', u'充'), + (0xFA75, 'M', u'冀'), + (0xFA76, 'M', u'勇'), + (0xFA77, 'M', u'勺'), + (0xFA78, 'M', u'喝'), + (0xFA79, 'M', u'啕'), + (0xFA7A, 'M', u'喙'), + (0xFA7B, 'M', u'嗢'), + (0xFA7C, 'M', u'塚'), + (0xFA7D, 'M', u'墳'), + (0xFA7E, 'M', u'奄'), + (0xFA7F, 'M', u'奔'), + (0xFA80, 'M', u'婢'), + (0xFA81, 'M', u'嬨'), + (0xFA82, 'M', u'廒'), + (0xFA83, 'M', u'廙'), + (0xFA84, 'M', u'彩'), + (0xFA85, 'M', u'徭'), + (0xFA86, 'M', u'惘'), + (0xFA87, 'M', u'慎'), + (0xFA88, 'M', u'愈'), + (0xFA89, 'M', u'憎'), + (0xFA8A, 'M', u'慠'), + (0xFA8B, 'M', u'懲'), + (0xFA8C, 'M', u'戴'), + (0xFA8D, 'M', u'揄'), + (0xFA8E, 'M', u'搜'), + (0xFA8F, 'M', u'摒'), + (0xFA90, 'M', u'敖'), + (0xFA91, 'M', u'晴'), + (0xFA92, 'M', u'朗'), + (0xFA93, 'M', u'望'), + (0xFA94, 'M', u'杖'), + (0xFA95, 'M', u'歹'), + (0xFA96, 'M', u'殺'), + (0xFA97, 'M', u'流'), + (0xFA98, 'M', u'滛'), + (0xFA99, 'M', u'滋'), + (0xFA9A, 'M', u'漢'), + (0xFA9B, 'M', u'瀞'), + (0xFA9C, 'M', u'煮'), + (0xFA9D, 'M', u'瞧'), + (0xFA9E, 'M', u'爵'), + (0xFA9F, 'M', u'犯'), + (0xFAA0, 'M', u'猪'), + (0xFAA1, 'M', u'瑱'), + ] + +def _seg_43(): + return [ + (0xFAA2, 'M', u'甆'), + (0xFAA3, 'M', u'画'), + (0xFAA4, 'M', u'瘝'), + (0xFAA5, 'M', u'瘟'), + (0xFAA6, 'M', u'益'), + (0xFAA7, 'M', u'盛'), + (0xFAA8, 'M', u'直'), + (0xFAA9, 'M', u'睊'), + (0xFAAA, 'M', u'着'), + (0xFAAB, 'M', u'磌'), + (0xFAAC, 'M', u'窱'), + (0xFAAD, 'M', u'節'), + (0xFAAE, 'M', u'类'), + (0xFAAF, 'M', u'絛'), + (0xFAB0, 'M', u'練'), + (0xFAB1, 'M', u'缾'), + (0xFAB2, 'M', u'者'), + (0xFAB3, 'M', u'荒'), + (0xFAB4, 'M', u'華'), + (0xFAB5, 'M', u'蝹'), + (0xFAB6, 'M', u'襁'), + (0xFAB7, 'M', u'覆'), + (0xFAB8, 'M', u'視'), + (0xFAB9, 'M', u'調'), + (0xFABA, 'M', u'諸'), + (0xFABB, 'M', u'請'), + (0xFABC, 'M', u'謁'), + (0xFABD, 'M', u'諾'), + (0xFABE, 'M', u'諭'), + (0xFABF, 'M', u'謹'), + (0xFAC0, 'M', u'變'), + (0xFAC1, 'M', u'贈'), + (0xFAC2, 'M', u'輸'), + (0xFAC3, 'M', u'遲'), + (0xFAC4, 'M', u'醙'), + (0xFAC5, 'M', u'鉶'), + (0xFAC6, 'M', u'陼'), + (0xFAC7, 'M', u'難'), + (0xFAC8, 'M', u'靖'), + (0xFAC9, 'M', u'韛'), + (0xFACA, 'M', u'響'), + (0xFACB, 'M', u'頋'), + (0xFACC, 'M', u'頻'), + (0xFACD, 'M', u'鬒'), + (0xFACE, 'M', u'龜'), + (0xFACF, 'M', u'𢡊'), + (0xFAD0, 'M', u'𢡄'), + (0xFAD1, 'M', u'𣏕'), + (0xFAD2, 'M', u'㮝'), + (0xFAD3, 'M', u'䀘'), + (0xFAD4, 'M', u'䀹'), + (0xFAD5, 'M', u'𥉉'), + (0xFAD6, 'M', u'𥳐'), + (0xFAD7, 'M', u'𧻓'), + (0xFAD8, 'M', u'齃'), + (0xFAD9, 'M', u'龎'), + (0xFADA, 'X'), + (0xFB00, 'M', u'ff'), + (0xFB01, 'M', u'fi'), + (0xFB02, 'M', u'fl'), + (0xFB03, 'M', u'ffi'), + (0xFB04, 'M', u'ffl'), + (0xFB05, 'M', u'st'), + (0xFB07, 'X'), + (0xFB13, 'M', u'մն'), + (0xFB14, 'M', u'մե'), + (0xFB15, 'M', u'մի'), + (0xFB16, 'M', u'վն'), + (0xFB17, 'M', u'մխ'), + (0xFB18, 'X'), + (0xFB1D, 'M', u'יִ'), + (0xFB1E, 'V'), + (0xFB1F, 'M', u'ײַ'), + (0xFB20, 'M', u'ע'), + (0xFB21, 'M', u'א'), + (0xFB22, 'M', u'ד'), + (0xFB23, 'M', u'ה'), + (0xFB24, 'M', u'כ'), + (0xFB25, 'M', u'ל'), + (0xFB26, 'M', u'ם'), + (0xFB27, 'M', u'ר'), + (0xFB28, 'M', u'ת'), + (0xFB29, '3', u'+'), + (0xFB2A, 'M', u'שׁ'), + (0xFB2B, 'M', u'שׂ'), + (0xFB2C, 'M', u'שּׁ'), + (0xFB2D, 'M', u'שּׂ'), + (0xFB2E, 'M', u'אַ'), + (0xFB2F, 'M', u'אָ'), + (0xFB30, 'M', u'אּ'), + (0xFB31, 'M', u'בּ'), + (0xFB32, 'M', u'גּ'), + (0xFB33, 'M', u'דּ'), + (0xFB34, 'M', u'הּ'), + (0xFB35, 'M', u'וּ'), + (0xFB36, 'M', u'זּ'), + (0xFB37, 'X'), + (0xFB38, 'M', u'טּ'), + (0xFB39, 'M', u'יּ'), + (0xFB3A, 'M', u'ךּ'), + ] + +def _seg_44(): + return [ + (0xFB3B, 'M', u'כּ'), + (0xFB3C, 'M', u'לּ'), + (0xFB3D, 'X'), + (0xFB3E, 'M', u'מּ'), + (0xFB3F, 'X'), + (0xFB40, 'M', u'נּ'), + (0xFB41, 'M', u'סּ'), + (0xFB42, 'X'), + (0xFB43, 'M', u'ףּ'), + (0xFB44, 'M', u'פּ'), + (0xFB45, 'X'), + (0xFB46, 'M', u'צּ'), + (0xFB47, 'M', u'קּ'), + (0xFB48, 'M', u'רּ'), + (0xFB49, 'M', u'שּ'), + (0xFB4A, 'M', u'תּ'), + (0xFB4B, 'M', u'וֹ'), + (0xFB4C, 'M', u'בֿ'), + (0xFB4D, 'M', u'כֿ'), + (0xFB4E, 'M', u'פֿ'), + (0xFB4F, 'M', u'אל'), + (0xFB50, 'M', u'ٱ'), + (0xFB52, 'M', u'ٻ'), + (0xFB56, 'M', u'پ'), + (0xFB5A, 'M', u'ڀ'), + (0xFB5E, 'M', u'ٺ'), + (0xFB62, 'M', u'ٿ'), + (0xFB66, 'M', u'ٹ'), + (0xFB6A, 'M', u'ڤ'), + (0xFB6E, 'M', u'ڦ'), + (0xFB72, 'M', u'ڄ'), + (0xFB76, 'M', u'ڃ'), + (0xFB7A, 'M', u'چ'), + (0xFB7E, 'M', u'ڇ'), + (0xFB82, 'M', u'ڍ'), + (0xFB84, 'M', u'ڌ'), + (0xFB86, 'M', u'ڎ'), + (0xFB88, 'M', u'ڈ'), + (0xFB8A, 'M', u'ژ'), + (0xFB8C, 'M', u'ڑ'), + (0xFB8E, 'M', u'ک'), + (0xFB92, 'M', u'گ'), + (0xFB96, 'M', u'ڳ'), + (0xFB9A, 'M', u'ڱ'), + (0xFB9E, 'M', u'ں'), + (0xFBA0, 'M', u'ڻ'), + (0xFBA4, 'M', u'ۀ'), + (0xFBA6, 'M', u'ہ'), + (0xFBAA, 'M', u'ھ'), + (0xFBAE, 'M', u'ے'), + (0xFBB0, 'M', u'ۓ'), + (0xFBB2, 'V'), + (0xFBC2, 'X'), + (0xFBD3, 'M', u'ڭ'), + (0xFBD7, 'M', u'ۇ'), + (0xFBD9, 'M', u'ۆ'), + (0xFBDB, 'M', u'ۈ'), + (0xFBDD, 'M', u'ۇٴ'), + (0xFBDE, 'M', u'ۋ'), + (0xFBE0, 'M', u'ۅ'), + (0xFBE2, 'M', u'ۉ'), + (0xFBE4, 'M', u'ې'), + (0xFBE8, 'M', u'ى'), + (0xFBEA, 'M', u'ئا'), + (0xFBEC, 'M', u'ئە'), + (0xFBEE, 'M', u'ئو'), + (0xFBF0, 'M', u'ئۇ'), + (0xFBF2, 'M', u'ئۆ'), + (0xFBF4, 'M', u'ئۈ'), + (0xFBF6, 'M', u'ئې'), + (0xFBF9, 'M', u'ئى'), + (0xFBFC, 'M', u'ی'), + (0xFC00, 'M', u'ئج'), + (0xFC01, 'M', u'ئح'), + (0xFC02, 'M', u'ئم'), + (0xFC03, 'M', u'ئى'), + (0xFC04, 'M', u'ئي'), + (0xFC05, 'M', u'بج'), + (0xFC06, 'M', u'بح'), + (0xFC07, 'M', u'بخ'), + (0xFC08, 'M', u'بم'), + (0xFC09, 'M', u'بى'), + (0xFC0A, 'M', u'بي'), + (0xFC0B, 'M', u'تج'), + (0xFC0C, 'M', u'تح'), + (0xFC0D, 'M', u'تخ'), + (0xFC0E, 'M', u'تم'), + (0xFC0F, 'M', u'تى'), + (0xFC10, 'M', u'تي'), + (0xFC11, 'M', u'ثج'), + (0xFC12, 'M', u'ثم'), + (0xFC13, 'M', u'ثى'), + (0xFC14, 'M', u'ثي'), + (0xFC15, 'M', u'جح'), + (0xFC16, 'M', u'جم'), + (0xFC17, 'M', u'حج'), + (0xFC18, 'M', u'حم'), + (0xFC19, 'M', u'خج'), + (0xFC1A, 'M', u'خح'), + (0xFC1B, 'M', u'خم'), + ] + +def _seg_45(): + return [ + (0xFC1C, 'M', u'سج'), + (0xFC1D, 'M', u'سح'), + (0xFC1E, 'M', u'سخ'), + (0xFC1F, 'M', u'سم'), + (0xFC20, 'M', u'صح'), + (0xFC21, 'M', u'صم'), + (0xFC22, 'M', u'ضج'), + (0xFC23, 'M', u'ضح'), + (0xFC24, 'M', u'ضخ'), + (0xFC25, 'M', u'ضم'), + (0xFC26, 'M', u'طح'), + (0xFC27, 'M', u'طم'), + (0xFC28, 'M', u'ظم'), + (0xFC29, 'M', u'عج'), + (0xFC2A, 'M', u'عم'), + (0xFC2B, 'M', u'غج'), + (0xFC2C, 'M', u'غم'), + (0xFC2D, 'M', u'فج'), + (0xFC2E, 'M', u'فح'), + (0xFC2F, 'M', u'فخ'), + (0xFC30, 'M', u'فم'), + (0xFC31, 'M', u'فى'), + (0xFC32, 'M', u'في'), + (0xFC33, 'M', u'قح'), + (0xFC34, 'M', u'قم'), + (0xFC35, 'M', u'قى'), + (0xFC36, 'M', u'قي'), + (0xFC37, 'M', u'كا'), + (0xFC38, 'M', u'كج'), + (0xFC39, 'M', u'كح'), + (0xFC3A, 'M', u'كخ'), + (0xFC3B, 'M', u'كل'), + (0xFC3C, 'M', u'كم'), + (0xFC3D, 'M', u'كى'), + (0xFC3E, 'M', u'كي'), + (0xFC3F, 'M', u'لج'), + (0xFC40, 'M', u'لح'), + (0xFC41, 'M', u'لخ'), + (0xFC42, 'M', u'لم'), + (0xFC43, 'M', u'لى'), + (0xFC44, 'M', u'لي'), + (0xFC45, 'M', u'مج'), + (0xFC46, 'M', u'مح'), + (0xFC47, 'M', u'مخ'), + (0xFC48, 'M', u'مم'), + (0xFC49, 'M', u'مى'), + (0xFC4A, 'M', u'مي'), + (0xFC4B, 'M', u'نج'), + (0xFC4C, 'M', u'نح'), + (0xFC4D, 'M', u'نخ'), + (0xFC4E, 'M', u'نم'), + (0xFC4F, 'M', u'نى'), + (0xFC50, 'M', u'ني'), + (0xFC51, 'M', u'هج'), + (0xFC52, 'M', u'هم'), + (0xFC53, 'M', u'هى'), + (0xFC54, 'M', u'هي'), + (0xFC55, 'M', u'يج'), + (0xFC56, 'M', u'يح'), + (0xFC57, 'M', u'يخ'), + (0xFC58, 'M', u'يم'), + (0xFC59, 'M', u'يى'), + (0xFC5A, 'M', u'يي'), + (0xFC5B, 'M', u'ذٰ'), + (0xFC5C, 'M', u'رٰ'), + (0xFC5D, 'M', u'ىٰ'), + (0xFC5E, '3', u' ٌّ'), + (0xFC5F, '3', u' ٍّ'), + (0xFC60, '3', u' َّ'), + (0xFC61, '3', u' ُّ'), + (0xFC62, '3', u' ِّ'), + (0xFC63, '3', u' ّٰ'), + (0xFC64, 'M', u'ئر'), + (0xFC65, 'M', u'ئز'), + (0xFC66, 'M', u'ئم'), + (0xFC67, 'M', u'ئن'), + (0xFC68, 'M', u'ئى'), + (0xFC69, 'M', u'ئي'), + (0xFC6A, 'M', u'بر'), + (0xFC6B, 'M', u'بز'), + (0xFC6C, 'M', u'بم'), + (0xFC6D, 'M', u'بن'), + (0xFC6E, 'M', u'بى'), + (0xFC6F, 'M', u'بي'), + (0xFC70, 'M', u'تر'), + (0xFC71, 'M', u'تز'), + (0xFC72, 'M', u'تم'), + (0xFC73, 'M', u'تن'), + (0xFC74, 'M', u'تى'), + (0xFC75, 'M', u'تي'), + (0xFC76, 'M', u'ثر'), + (0xFC77, 'M', u'ثز'), + (0xFC78, 'M', u'ثم'), + (0xFC79, 'M', u'ثن'), + (0xFC7A, 'M', u'ثى'), + (0xFC7B, 'M', u'ثي'), + (0xFC7C, 'M', u'فى'), + (0xFC7D, 'M', u'في'), + (0xFC7E, 'M', u'قى'), + (0xFC7F, 'M', u'قي'), + ] + +def _seg_46(): + return [ + (0xFC80, 'M', u'كا'), + (0xFC81, 'M', u'كل'), + (0xFC82, 'M', u'كم'), + (0xFC83, 'M', u'كى'), + (0xFC84, 'M', u'كي'), + (0xFC85, 'M', u'لم'), + (0xFC86, 'M', u'لى'), + (0xFC87, 'M', u'لي'), + (0xFC88, 'M', u'ما'), + (0xFC89, 'M', u'مم'), + (0xFC8A, 'M', u'نر'), + (0xFC8B, 'M', u'نز'), + (0xFC8C, 'M', u'نم'), + (0xFC8D, 'M', u'نن'), + (0xFC8E, 'M', u'نى'), + (0xFC8F, 'M', u'ني'), + (0xFC90, 'M', u'ىٰ'), + (0xFC91, 'M', u'ير'), + (0xFC92, 'M', u'يز'), + (0xFC93, 'M', u'يم'), + (0xFC94, 'M', u'ين'), + (0xFC95, 'M', u'يى'), + (0xFC96, 'M', u'يي'), + (0xFC97, 'M', u'ئج'), + (0xFC98, 'M', u'ئح'), + (0xFC99, 'M', u'ئخ'), + (0xFC9A, 'M', u'ئم'), + (0xFC9B, 'M', u'ئه'), + (0xFC9C, 'M', u'بج'), + (0xFC9D, 'M', u'بح'), + (0xFC9E, 'M', u'بخ'), + (0xFC9F, 'M', u'بم'), + (0xFCA0, 'M', u'به'), + (0xFCA1, 'M', u'تج'), + (0xFCA2, 'M', u'تح'), + (0xFCA3, 'M', u'تخ'), + (0xFCA4, 'M', u'تم'), + (0xFCA5, 'M', u'ته'), + (0xFCA6, 'M', u'ثم'), + (0xFCA7, 'M', u'جح'), + (0xFCA8, 'M', u'جم'), + (0xFCA9, 'M', u'حج'), + (0xFCAA, 'M', u'حم'), + (0xFCAB, 'M', u'خج'), + (0xFCAC, 'M', u'خم'), + (0xFCAD, 'M', u'سج'), + (0xFCAE, 'M', u'سح'), + (0xFCAF, 'M', u'سخ'), + (0xFCB0, 'M', u'سم'), + (0xFCB1, 'M', u'صح'), + (0xFCB2, 'M', u'صخ'), + (0xFCB3, 'M', u'صم'), + (0xFCB4, 'M', u'ضج'), + (0xFCB5, 'M', u'ضح'), + (0xFCB6, 'M', u'ضخ'), + (0xFCB7, 'M', u'ضم'), + (0xFCB8, 'M', u'طح'), + (0xFCB9, 'M', u'ظم'), + (0xFCBA, 'M', u'عج'), + (0xFCBB, 'M', u'عم'), + (0xFCBC, 'M', u'غج'), + (0xFCBD, 'M', u'غم'), + (0xFCBE, 'M', u'فج'), + (0xFCBF, 'M', u'فح'), + (0xFCC0, 'M', u'فخ'), + (0xFCC1, 'M', u'فم'), + (0xFCC2, 'M', u'قح'), + (0xFCC3, 'M', u'قم'), + (0xFCC4, 'M', u'كج'), + (0xFCC5, 'M', u'كح'), + (0xFCC6, 'M', u'كخ'), + (0xFCC7, 'M', u'كل'), + (0xFCC8, 'M', u'كم'), + (0xFCC9, 'M', u'لج'), + (0xFCCA, 'M', u'لح'), + (0xFCCB, 'M', u'لخ'), + (0xFCCC, 'M', u'لم'), + (0xFCCD, 'M', u'له'), + (0xFCCE, 'M', u'مج'), + (0xFCCF, 'M', u'مح'), + (0xFCD0, 'M', u'مخ'), + (0xFCD1, 'M', u'مم'), + (0xFCD2, 'M', u'نج'), + (0xFCD3, 'M', u'نح'), + (0xFCD4, 'M', u'نخ'), + (0xFCD5, 'M', u'نم'), + (0xFCD6, 'M', u'نه'), + (0xFCD7, 'M', u'هج'), + (0xFCD8, 'M', u'هم'), + (0xFCD9, 'M', u'هٰ'), + (0xFCDA, 'M', u'يج'), + (0xFCDB, 'M', u'يح'), + (0xFCDC, 'M', u'يخ'), + (0xFCDD, 'M', u'يم'), + (0xFCDE, 'M', u'يه'), + (0xFCDF, 'M', u'ئم'), + (0xFCE0, 'M', u'ئه'), + (0xFCE1, 'M', u'بم'), + (0xFCE2, 'M', u'به'), + (0xFCE3, 'M', u'تم'), + ] + +def _seg_47(): + return [ + (0xFCE4, 'M', u'ته'), + (0xFCE5, 'M', u'ثم'), + (0xFCE6, 'M', u'ثه'), + (0xFCE7, 'M', u'سم'), + (0xFCE8, 'M', u'سه'), + (0xFCE9, 'M', u'شم'), + (0xFCEA, 'M', u'شه'), + (0xFCEB, 'M', u'كل'), + (0xFCEC, 'M', u'كم'), + (0xFCED, 'M', u'لم'), + (0xFCEE, 'M', u'نم'), + (0xFCEF, 'M', u'نه'), + (0xFCF0, 'M', u'يم'), + (0xFCF1, 'M', u'يه'), + (0xFCF2, 'M', u'ـَّ'), + (0xFCF3, 'M', u'ـُّ'), + (0xFCF4, 'M', u'ـِّ'), + (0xFCF5, 'M', u'طى'), + (0xFCF6, 'M', u'طي'), + (0xFCF7, 'M', u'عى'), + (0xFCF8, 'M', u'عي'), + (0xFCF9, 'M', u'غى'), + (0xFCFA, 'M', u'غي'), + (0xFCFB, 'M', u'سى'), + (0xFCFC, 'M', u'سي'), + (0xFCFD, 'M', u'شى'), + (0xFCFE, 'M', u'شي'), + (0xFCFF, 'M', u'حى'), + (0xFD00, 'M', u'حي'), + (0xFD01, 'M', u'جى'), + (0xFD02, 'M', u'جي'), + (0xFD03, 'M', u'خى'), + (0xFD04, 'M', u'خي'), + (0xFD05, 'M', u'صى'), + (0xFD06, 'M', u'صي'), + (0xFD07, 'M', u'ضى'), + (0xFD08, 'M', u'ضي'), + (0xFD09, 'M', u'شج'), + (0xFD0A, 'M', u'شح'), + (0xFD0B, 'M', u'شخ'), + (0xFD0C, 'M', u'شم'), + (0xFD0D, 'M', u'شر'), + (0xFD0E, 'M', u'سر'), + (0xFD0F, 'M', u'صر'), + (0xFD10, 'M', u'ضر'), + (0xFD11, 'M', u'طى'), + (0xFD12, 'M', u'طي'), + (0xFD13, 'M', u'عى'), + (0xFD14, 'M', u'عي'), + (0xFD15, 'M', u'غى'), + (0xFD16, 'M', u'غي'), + (0xFD17, 'M', u'سى'), + (0xFD18, 'M', u'سي'), + (0xFD19, 'M', u'شى'), + (0xFD1A, 'M', u'شي'), + (0xFD1B, 'M', u'حى'), + (0xFD1C, 'M', u'حي'), + (0xFD1D, 'M', u'جى'), + (0xFD1E, 'M', u'جي'), + (0xFD1F, 'M', u'خى'), + (0xFD20, 'M', u'خي'), + (0xFD21, 'M', u'صى'), + (0xFD22, 'M', u'صي'), + (0xFD23, 'M', u'ضى'), + (0xFD24, 'M', u'ضي'), + (0xFD25, 'M', u'شج'), + (0xFD26, 'M', u'شح'), + (0xFD27, 'M', u'شخ'), + (0xFD28, 'M', u'شم'), + (0xFD29, 'M', u'شر'), + (0xFD2A, 'M', u'سر'), + (0xFD2B, 'M', u'صر'), + (0xFD2C, 'M', u'ضر'), + (0xFD2D, 'M', u'شج'), + (0xFD2E, 'M', u'شح'), + (0xFD2F, 'M', u'شخ'), + (0xFD30, 'M', u'شم'), + (0xFD31, 'M', u'سه'), + (0xFD32, 'M', u'شه'), + (0xFD33, 'M', u'طم'), + (0xFD34, 'M', u'سج'), + (0xFD35, 'M', u'سح'), + (0xFD36, 'M', u'سخ'), + (0xFD37, 'M', u'شج'), + (0xFD38, 'M', u'شح'), + (0xFD39, 'M', u'شخ'), + (0xFD3A, 'M', u'طم'), + (0xFD3B, 'M', u'ظم'), + (0xFD3C, 'M', u'اً'), + (0xFD3E, 'V'), + (0xFD40, 'X'), + (0xFD50, 'M', u'تجم'), + (0xFD51, 'M', u'تحج'), + (0xFD53, 'M', u'تحم'), + (0xFD54, 'M', u'تخم'), + (0xFD55, 'M', u'تمج'), + (0xFD56, 'M', u'تمح'), + (0xFD57, 'M', u'تمخ'), + (0xFD58, 'M', u'جمح'), + (0xFD5A, 'M', u'حمي'), + ] + +def _seg_48(): + return [ + (0xFD5B, 'M', u'حمى'), + (0xFD5C, 'M', u'سحج'), + (0xFD5D, 'M', u'سجح'), + (0xFD5E, 'M', u'سجى'), + (0xFD5F, 'M', u'سمح'), + (0xFD61, 'M', u'سمج'), + (0xFD62, 'M', u'سمم'), + (0xFD64, 'M', u'صحح'), + (0xFD66, 'M', u'صمم'), + (0xFD67, 'M', u'شحم'), + (0xFD69, 'M', u'شجي'), + (0xFD6A, 'M', u'شمخ'), + (0xFD6C, 'M', u'شمم'), + (0xFD6E, 'M', u'ضحى'), + (0xFD6F, 'M', u'ضخم'), + (0xFD71, 'M', u'طمح'), + (0xFD73, 'M', u'طمم'), + (0xFD74, 'M', u'طمي'), + (0xFD75, 'M', u'عجم'), + (0xFD76, 'M', u'عمم'), + (0xFD78, 'M', u'عمى'), + (0xFD79, 'M', u'غمم'), + (0xFD7A, 'M', u'غمي'), + (0xFD7B, 'M', u'غمى'), + (0xFD7C, 'M', u'فخم'), + (0xFD7E, 'M', u'قمح'), + (0xFD7F, 'M', u'قمم'), + (0xFD80, 'M', u'لحم'), + (0xFD81, 'M', u'لحي'), + (0xFD82, 'M', u'لحى'), + (0xFD83, 'M', u'لجج'), + (0xFD85, 'M', u'لخم'), + (0xFD87, 'M', u'لمح'), + (0xFD89, 'M', u'محج'), + (0xFD8A, 'M', u'محم'), + (0xFD8B, 'M', u'محي'), + (0xFD8C, 'M', u'مجح'), + (0xFD8D, 'M', u'مجم'), + (0xFD8E, 'M', u'مخج'), + (0xFD8F, 'M', u'مخم'), + (0xFD90, 'X'), + (0xFD92, 'M', u'مجخ'), + (0xFD93, 'M', u'همج'), + (0xFD94, 'M', u'همم'), + (0xFD95, 'M', u'نحم'), + (0xFD96, 'M', u'نحى'), + (0xFD97, 'M', u'نجم'), + (0xFD99, 'M', u'نجى'), + (0xFD9A, 'M', u'نمي'), + (0xFD9B, 'M', u'نمى'), + (0xFD9C, 'M', u'يمم'), + (0xFD9E, 'M', u'بخي'), + (0xFD9F, 'M', u'تجي'), + (0xFDA0, 'M', u'تجى'), + (0xFDA1, 'M', u'تخي'), + (0xFDA2, 'M', u'تخى'), + (0xFDA3, 'M', u'تمي'), + (0xFDA4, 'M', u'تمى'), + (0xFDA5, 'M', u'جمي'), + (0xFDA6, 'M', u'جحى'), + (0xFDA7, 'M', u'جمى'), + (0xFDA8, 'M', u'سخى'), + (0xFDA9, 'M', u'صحي'), + (0xFDAA, 'M', u'شحي'), + (0xFDAB, 'M', u'ضحي'), + (0xFDAC, 'M', u'لجي'), + (0xFDAD, 'M', u'لمي'), + (0xFDAE, 'M', u'يحي'), + (0xFDAF, 'M', u'يجي'), + (0xFDB0, 'M', u'يمي'), + (0xFDB1, 'M', u'ممي'), + (0xFDB2, 'M', u'قمي'), + (0xFDB3, 'M', u'نحي'), + (0xFDB4, 'M', u'قمح'), + (0xFDB5, 'M', u'لحم'), + (0xFDB6, 'M', u'عمي'), + (0xFDB7, 'M', u'كمي'), + (0xFDB8, 'M', u'نجح'), + (0xFDB9, 'M', u'مخي'), + (0xFDBA, 'M', u'لجم'), + (0xFDBB, 'M', u'كمم'), + (0xFDBC, 'M', u'لجم'), + (0xFDBD, 'M', u'نجح'), + (0xFDBE, 'M', u'جحي'), + (0xFDBF, 'M', u'حجي'), + (0xFDC0, 'M', u'مجي'), + (0xFDC1, 'M', u'فمي'), + (0xFDC2, 'M', u'بحي'), + (0xFDC3, 'M', u'كمم'), + (0xFDC4, 'M', u'عجم'), + (0xFDC5, 'M', u'صمم'), + (0xFDC6, 'M', u'سخي'), + (0xFDC7, 'M', u'نجي'), + (0xFDC8, 'X'), + (0xFDF0, 'M', u'صلے'), + (0xFDF1, 'M', u'قلے'), + (0xFDF2, 'M', u'الله'), + (0xFDF3, 'M', u'اكبر'), + (0xFDF4, 'M', u'محمد'), + (0xFDF5, 'M', u'صلعم'), + ] + +def _seg_49(): + return [ + (0xFDF6, 'M', u'رسول'), + (0xFDF7, 'M', u'عليه'), + (0xFDF8, 'M', u'وسلم'), + (0xFDF9, 'M', u'صلى'), + (0xFDFA, '3', u'صلى الله عليه وسلم'), + (0xFDFB, '3', u'جل جلاله'), + (0xFDFC, 'M', u'ریال'), + (0xFDFD, 'V'), + (0xFDFE, 'X'), + (0xFE00, 'I'), + (0xFE10, '3', u','), + (0xFE11, 'M', u'、'), + (0xFE12, 'X'), + (0xFE13, '3', u':'), + (0xFE14, '3', u';'), + (0xFE15, '3', u'!'), + (0xFE16, '3', u'?'), + (0xFE17, 'M', u'〖'), + (0xFE18, 'M', u'〗'), + (0xFE19, 'X'), + (0xFE20, 'V'), + (0xFE30, 'X'), + (0xFE31, 'M', u'—'), + (0xFE32, 'M', u'–'), + (0xFE33, '3', u'_'), + (0xFE35, '3', u'('), + (0xFE36, '3', u')'), + (0xFE37, '3', u'{'), + (0xFE38, '3', u'}'), + (0xFE39, 'M', u'〔'), + (0xFE3A, 'M', u'〕'), + (0xFE3B, 'M', u'【'), + (0xFE3C, 'M', u'】'), + (0xFE3D, 'M', u'《'), + (0xFE3E, 'M', u'》'), + (0xFE3F, 'M', u'〈'), + (0xFE40, 'M', u'〉'), + (0xFE41, 'M', u'「'), + (0xFE42, 'M', u'」'), + (0xFE43, 'M', u'『'), + (0xFE44, 'M', u'』'), + (0xFE45, 'V'), + (0xFE47, '3', u'['), + (0xFE48, '3', u']'), + (0xFE49, '3', u' ̅'), + (0xFE4D, '3', u'_'), + (0xFE50, '3', u','), + (0xFE51, 'M', u'、'), + (0xFE52, 'X'), + (0xFE54, '3', u';'), + (0xFE55, '3', u':'), + (0xFE56, '3', u'?'), + (0xFE57, '3', u'!'), + (0xFE58, 'M', u'—'), + (0xFE59, '3', u'('), + (0xFE5A, '3', u')'), + (0xFE5B, '3', u'{'), + (0xFE5C, '3', u'}'), + (0xFE5D, 'M', u'〔'), + (0xFE5E, 'M', u'〕'), + (0xFE5F, '3', u'#'), + (0xFE60, '3', u'&'), + (0xFE61, '3', u'*'), + (0xFE62, '3', u'+'), + (0xFE63, 'M', u'-'), + (0xFE64, '3', u'<'), + (0xFE65, '3', u'>'), + (0xFE66, '3', u'='), + (0xFE67, 'X'), + (0xFE68, '3', u'\\'), + (0xFE69, '3', u'$'), + (0xFE6A, '3', u'%'), + (0xFE6B, '3', u'@'), + (0xFE6C, 'X'), + (0xFE70, '3', u' ً'), + (0xFE71, 'M', u'ـً'), + (0xFE72, '3', u' ٌ'), + (0xFE73, 'V'), + (0xFE74, '3', u' ٍ'), + (0xFE75, 'X'), + (0xFE76, '3', u' َ'), + (0xFE77, 'M', u'ـَ'), + (0xFE78, '3', u' ُ'), + (0xFE79, 'M', u'ـُ'), + (0xFE7A, '3', u' ِ'), + (0xFE7B, 'M', u'ـِ'), + (0xFE7C, '3', u' ّ'), + (0xFE7D, 'M', u'ـّ'), + (0xFE7E, '3', u' ْ'), + (0xFE7F, 'M', u'ـْ'), + (0xFE80, 'M', u'ء'), + (0xFE81, 'M', u'آ'), + (0xFE83, 'M', u'أ'), + (0xFE85, 'M', u'ؤ'), + (0xFE87, 'M', u'إ'), + (0xFE89, 'M', u'ئ'), + (0xFE8D, 'M', u'ا'), + (0xFE8F, 'M', u'ب'), + (0xFE93, 'M', u'ة'), + (0xFE95, 'M', u'ت'), + ] + +def _seg_50(): + return [ + (0xFE99, 'M', u'ث'), + (0xFE9D, 'M', u'ج'), + (0xFEA1, 'M', u'ح'), + (0xFEA5, 'M', u'خ'), + (0xFEA9, 'M', u'د'), + (0xFEAB, 'M', u'ذ'), + (0xFEAD, 'M', u'ر'), + (0xFEAF, 'M', u'ز'), + (0xFEB1, 'M', u'س'), + (0xFEB5, 'M', u'ش'), + (0xFEB9, 'M', u'ص'), + (0xFEBD, 'M', u'ض'), + (0xFEC1, 'M', u'ط'), + (0xFEC5, 'M', u'ظ'), + (0xFEC9, 'M', u'ع'), + (0xFECD, 'M', u'غ'), + (0xFED1, 'M', u'ف'), + (0xFED5, 'M', u'ق'), + (0xFED9, 'M', u'ك'), + (0xFEDD, 'M', u'ل'), + (0xFEE1, 'M', u'م'), + (0xFEE5, 'M', u'ن'), + (0xFEE9, 'M', u'ه'), + (0xFEED, 'M', u'و'), + (0xFEEF, 'M', u'ى'), + (0xFEF1, 'M', u'ي'), + (0xFEF5, 'M', u'لآ'), + (0xFEF7, 'M', u'لأ'), + (0xFEF9, 'M', u'لإ'), + (0xFEFB, 'M', u'لا'), + (0xFEFD, 'X'), + (0xFEFF, 'I'), + (0xFF00, 'X'), + (0xFF01, '3', u'!'), + (0xFF02, '3', u'"'), + (0xFF03, '3', u'#'), + (0xFF04, '3', u'$'), + (0xFF05, '3', u'%'), + (0xFF06, '3', u'&'), + (0xFF07, '3', u'\''), + (0xFF08, '3', u'('), + (0xFF09, '3', u')'), + (0xFF0A, '3', u'*'), + (0xFF0B, '3', u'+'), + (0xFF0C, '3', u','), + (0xFF0D, 'M', u'-'), + (0xFF0E, 'M', u'.'), + (0xFF0F, '3', u'/'), + (0xFF10, 'M', u'0'), + (0xFF11, 'M', u'1'), + (0xFF12, 'M', u'2'), + (0xFF13, 'M', u'3'), + (0xFF14, 'M', u'4'), + (0xFF15, 'M', u'5'), + (0xFF16, 'M', u'6'), + (0xFF17, 'M', u'7'), + (0xFF18, 'M', u'8'), + (0xFF19, 'M', u'9'), + (0xFF1A, '3', u':'), + (0xFF1B, '3', u';'), + (0xFF1C, '3', u'<'), + (0xFF1D, '3', u'='), + (0xFF1E, '3', u'>'), + (0xFF1F, '3', u'?'), + (0xFF20, '3', u'@'), + (0xFF21, 'M', u'a'), + (0xFF22, 'M', u'b'), + (0xFF23, 'M', u'c'), + (0xFF24, 'M', u'd'), + (0xFF25, 'M', u'e'), + (0xFF26, 'M', u'f'), + (0xFF27, 'M', u'g'), + (0xFF28, 'M', u'h'), + (0xFF29, 'M', u'i'), + (0xFF2A, 'M', u'j'), + (0xFF2B, 'M', u'k'), + (0xFF2C, 'M', u'l'), + (0xFF2D, 'M', u'm'), + (0xFF2E, 'M', u'n'), + (0xFF2F, 'M', u'o'), + (0xFF30, 'M', u'p'), + (0xFF31, 'M', u'q'), + (0xFF32, 'M', u'r'), + (0xFF33, 'M', u's'), + (0xFF34, 'M', u't'), + (0xFF35, 'M', u'u'), + (0xFF36, 'M', u'v'), + (0xFF37, 'M', u'w'), + (0xFF38, 'M', u'x'), + (0xFF39, 'M', u'y'), + (0xFF3A, 'M', u'z'), + (0xFF3B, '3', u'['), + (0xFF3C, '3', u'\\'), + (0xFF3D, '3', u']'), + (0xFF3E, '3', u'^'), + (0xFF3F, '3', u'_'), + (0xFF40, '3', u'`'), + (0xFF41, 'M', u'a'), + (0xFF42, 'M', u'b'), + (0xFF43, 'M', u'c'), + ] + +def _seg_51(): + return [ + (0xFF44, 'M', u'd'), + (0xFF45, 'M', u'e'), + (0xFF46, 'M', u'f'), + (0xFF47, 'M', u'g'), + (0xFF48, 'M', u'h'), + (0xFF49, 'M', u'i'), + (0xFF4A, 'M', u'j'), + (0xFF4B, 'M', u'k'), + (0xFF4C, 'M', u'l'), + (0xFF4D, 'M', u'm'), + (0xFF4E, 'M', u'n'), + (0xFF4F, 'M', u'o'), + (0xFF50, 'M', u'p'), + (0xFF51, 'M', u'q'), + (0xFF52, 'M', u'r'), + (0xFF53, 'M', u's'), + (0xFF54, 'M', u't'), + (0xFF55, 'M', u'u'), + (0xFF56, 'M', u'v'), + (0xFF57, 'M', u'w'), + (0xFF58, 'M', u'x'), + (0xFF59, 'M', u'y'), + (0xFF5A, 'M', u'z'), + (0xFF5B, '3', u'{'), + (0xFF5C, '3', u'|'), + (0xFF5D, '3', u'}'), + (0xFF5E, '3', u'~'), + (0xFF5F, 'M', u'⦅'), + (0xFF60, 'M', u'⦆'), + (0xFF61, 'M', u'.'), + (0xFF62, 'M', u'「'), + (0xFF63, 'M', u'」'), + (0xFF64, 'M', u'、'), + (0xFF65, 'M', u'・'), + (0xFF66, 'M', u'ヲ'), + (0xFF67, 'M', u'ァ'), + (0xFF68, 'M', u'ィ'), + (0xFF69, 'M', u'ゥ'), + (0xFF6A, 'M', u'ェ'), + (0xFF6B, 'M', u'ォ'), + (0xFF6C, 'M', u'ャ'), + (0xFF6D, 'M', u'ュ'), + (0xFF6E, 'M', u'ョ'), + (0xFF6F, 'M', u'ッ'), + (0xFF70, 'M', u'ー'), + (0xFF71, 'M', u'ア'), + (0xFF72, 'M', u'イ'), + (0xFF73, 'M', u'ウ'), + (0xFF74, 'M', u'エ'), + (0xFF75, 'M', u'オ'), + (0xFF76, 'M', u'カ'), + (0xFF77, 'M', u'キ'), + (0xFF78, 'M', u'ク'), + (0xFF79, 'M', u'ケ'), + (0xFF7A, 'M', u'コ'), + (0xFF7B, 'M', u'サ'), + (0xFF7C, 'M', u'シ'), + (0xFF7D, 'M', u'ス'), + (0xFF7E, 'M', u'セ'), + (0xFF7F, 'M', u'ソ'), + (0xFF80, 'M', u'タ'), + (0xFF81, 'M', u'チ'), + (0xFF82, 'M', u'ツ'), + (0xFF83, 'M', u'テ'), + (0xFF84, 'M', u'ト'), + (0xFF85, 'M', u'ナ'), + (0xFF86, 'M', u'ニ'), + (0xFF87, 'M', u'ヌ'), + (0xFF88, 'M', u'ネ'), + (0xFF89, 'M', u'ノ'), + (0xFF8A, 'M', u'ハ'), + (0xFF8B, 'M', u'ヒ'), + (0xFF8C, 'M', u'フ'), + (0xFF8D, 'M', u'ヘ'), + (0xFF8E, 'M', u'ホ'), + (0xFF8F, 'M', u'マ'), + (0xFF90, 'M', u'ミ'), + (0xFF91, 'M', u'ム'), + (0xFF92, 'M', u'メ'), + (0xFF93, 'M', u'モ'), + (0xFF94, 'M', u'ヤ'), + (0xFF95, 'M', u'ユ'), + (0xFF96, 'M', u'ヨ'), + (0xFF97, 'M', u'ラ'), + (0xFF98, 'M', u'リ'), + (0xFF99, 'M', u'ル'), + (0xFF9A, 'M', u'レ'), + (0xFF9B, 'M', u'ロ'), + (0xFF9C, 'M', u'ワ'), + (0xFF9D, 'M', u'ン'), + (0xFF9E, 'M', u'゙'), + (0xFF9F, 'M', u'゚'), + (0xFFA0, 'X'), + (0xFFA1, 'M', u'ᄀ'), + (0xFFA2, 'M', u'ᄁ'), + (0xFFA3, 'M', u'ᆪ'), + (0xFFA4, 'M', u'ᄂ'), + (0xFFA5, 'M', u'ᆬ'), + (0xFFA6, 'M', u'ᆭ'), + (0xFFA7, 'M', u'ᄃ'), + ] + +def _seg_52(): + return [ + (0xFFA8, 'M', u'ᄄ'), + (0xFFA9, 'M', u'ᄅ'), + (0xFFAA, 'M', u'ᆰ'), + (0xFFAB, 'M', u'ᆱ'), + (0xFFAC, 'M', u'ᆲ'), + (0xFFAD, 'M', u'ᆳ'), + (0xFFAE, 'M', u'ᆴ'), + (0xFFAF, 'M', u'ᆵ'), + (0xFFB0, 'M', u'ᄚ'), + (0xFFB1, 'M', u'ᄆ'), + (0xFFB2, 'M', u'ᄇ'), + (0xFFB3, 'M', u'ᄈ'), + (0xFFB4, 'M', u'ᄡ'), + (0xFFB5, 'M', u'ᄉ'), + (0xFFB6, 'M', u'ᄊ'), + (0xFFB7, 'M', u'ᄋ'), + (0xFFB8, 'M', u'ᄌ'), + (0xFFB9, 'M', u'ᄍ'), + (0xFFBA, 'M', u'ᄎ'), + (0xFFBB, 'M', u'ᄏ'), + (0xFFBC, 'M', u'ᄐ'), + (0xFFBD, 'M', u'ᄑ'), + (0xFFBE, 'M', u'ᄒ'), + (0xFFBF, 'X'), + (0xFFC2, 'M', u'ᅡ'), + (0xFFC3, 'M', u'ᅢ'), + (0xFFC4, 'M', u'ᅣ'), + (0xFFC5, 'M', u'ᅤ'), + (0xFFC6, 'M', u'ᅥ'), + (0xFFC7, 'M', u'ᅦ'), + (0xFFC8, 'X'), + (0xFFCA, 'M', u'ᅧ'), + (0xFFCB, 'M', u'ᅨ'), + (0xFFCC, 'M', u'ᅩ'), + (0xFFCD, 'M', u'ᅪ'), + (0xFFCE, 'M', u'ᅫ'), + (0xFFCF, 'M', u'ᅬ'), + (0xFFD0, 'X'), + (0xFFD2, 'M', u'ᅭ'), + (0xFFD3, 'M', u'ᅮ'), + (0xFFD4, 'M', u'ᅯ'), + (0xFFD5, 'M', u'ᅰ'), + (0xFFD6, 'M', u'ᅱ'), + (0xFFD7, 'M', u'ᅲ'), + (0xFFD8, 'X'), + (0xFFDA, 'M', u'ᅳ'), + (0xFFDB, 'M', u'ᅴ'), + (0xFFDC, 'M', u'ᅵ'), + (0xFFDD, 'X'), + (0xFFE0, 'M', u'¢'), + (0xFFE1, 'M', u'£'), + (0xFFE2, 'M', u'¬'), + (0xFFE3, '3', u' ̄'), + (0xFFE4, 'M', u'¦'), + (0xFFE5, 'M', u'¥'), + (0xFFE6, 'M', u'₩'), + (0xFFE7, 'X'), + (0xFFE8, 'M', u'│'), + (0xFFE9, 'M', u'←'), + (0xFFEA, 'M', u'↑'), + (0xFFEB, 'M', u'→'), + (0xFFEC, 'M', u'↓'), + (0xFFED, 'M', u'■'), + (0xFFEE, 'M', u'○'), + (0xFFEF, 'X'), + (0x10000, 'V'), + (0x1000C, 'X'), + (0x1000D, 'V'), + (0x10027, 'X'), + (0x10028, 'V'), + (0x1003B, 'X'), + (0x1003C, 'V'), + (0x1003E, 'X'), + (0x1003F, 'V'), + (0x1004E, 'X'), + (0x10050, 'V'), + (0x1005E, 'X'), + (0x10080, 'V'), + (0x100FB, 'X'), + (0x10100, 'V'), + (0x10103, 'X'), + (0x10107, 'V'), + (0x10134, 'X'), + (0x10137, 'V'), + (0x1018F, 'X'), + (0x10190, 'V'), + (0x1019C, 'X'), + (0x101A0, 'V'), + (0x101A1, 'X'), + (0x101D0, 'V'), + (0x101FE, 'X'), + (0x10280, 'V'), + (0x1029D, 'X'), + (0x102A0, 'V'), + (0x102D1, 'X'), + (0x102E0, 'V'), + (0x102FC, 'X'), + (0x10300, 'V'), + (0x10324, 'X'), + (0x1032D, 'V'), + ] + +def _seg_53(): + return [ + (0x1034B, 'X'), + (0x10350, 'V'), + (0x1037B, 'X'), + (0x10380, 'V'), + (0x1039E, 'X'), + (0x1039F, 'V'), + (0x103C4, 'X'), + (0x103C8, 'V'), + (0x103D6, 'X'), + (0x10400, 'M', u'𐐨'), + (0x10401, 'M', u'𐐩'), + (0x10402, 'M', u'𐐪'), + (0x10403, 'M', u'𐐫'), + (0x10404, 'M', u'𐐬'), + (0x10405, 'M', u'𐐭'), + (0x10406, 'M', u'𐐮'), + (0x10407, 'M', u'𐐯'), + (0x10408, 'M', u'𐐰'), + (0x10409, 'M', u'𐐱'), + (0x1040A, 'M', u'𐐲'), + (0x1040B, 'M', u'𐐳'), + (0x1040C, 'M', u'𐐴'), + (0x1040D, 'M', u'𐐵'), + (0x1040E, 'M', u'𐐶'), + (0x1040F, 'M', u'𐐷'), + (0x10410, 'M', u'𐐸'), + (0x10411, 'M', u'𐐹'), + (0x10412, 'M', u'𐐺'), + (0x10413, 'M', u'𐐻'), + (0x10414, 'M', u'𐐼'), + (0x10415, 'M', u'𐐽'), + (0x10416, 'M', u'𐐾'), + (0x10417, 'M', u'𐐿'), + (0x10418, 'M', u'𐑀'), + (0x10419, 'M', u'𐑁'), + (0x1041A, 'M', u'𐑂'), + (0x1041B, 'M', u'𐑃'), + (0x1041C, 'M', u'𐑄'), + (0x1041D, 'M', u'𐑅'), + (0x1041E, 'M', u'𐑆'), + (0x1041F, 'M', u'𐑇'), + (0x10420, 'M', u'𐑈'), + (0x10421, 'M', u'𐑉'), + (0x10422, 'M', u'𐑊'), + (0x10423, 'M', u'𐑋'), + (0x10424, 'M', u'𐑌'), + (0x10425, 'M', u'𐑍'), + (0x10426, 'M', u'𐑎'), + (0x10427, 'M', u'𐑏'), + (0x10428, 'V'), + (0x1049E, 'X'), + (0x104A0, 'V'), + (0x104AA, 'X'), + (0x104B0, 'M', u'𐓘'), + (0x104B1, 'M', u'𐓙'), + (0x104B2, 'M', u'𐓚'), + (0x104B3, 'M', u'𐓛'), + (0x104B4, 'M', u'𐓜'), + (0x104B5, 'M', u'𐓝'), + (0x104B6, 'M', u'𐓞'), + (0x104B7, 'M', u'𐓟'), + (0x104B8, 'M', u'𐓠'), + (0x104B9, 'M', u'𐓡'), + (0x104BA, 'M', u'𐓢'), + (0x104BB, 'M', u'𐓣'), + (0x104BC, 'M', u'𐓤'), + (0x104BD, 'M', u'𐓥'), + (0x104BE, 'M', u'𐓦'), + (0x104BF, 'M', u'𐓧'), + (0x104C0, 'M', u'𐓨'), + (0x104C1, 'M', u'𐓩'), + (0x104C2, 'M', u'𐓪'), + (0x104C3, 'M', u'𐓫'), + (0x104C4, 'M', u'𐓬'), + (0x104C5, 'M', u'𐓭'), + (0x104C6, 'M', u'𐓮'), + (0x104C7, 'M', u'𐓯'), + (0x104C8, 'M', u'𐓰'), + (0x104C9, 'M', u'𐓱'), + (0x104CA, 'M', u'𐓲'), + (0x104CB, 'M', u'𐓳'), + (0x104CC, 'M', u'𐓴'), + (0x104CD, 'M', u'𐓵'), + (0x104CE, 'M', u'𐓶'), + (0x104CF, 'M', u'𐓷'), + (0x104D0, 'M', u'𐓸'), + (0x104D1, 'M', u'𐓹'), + (0x104D2, 'M', u'𐓺'), + (0x104D3, 'M', u'𐓻'), + (0x104D4, 'X'), + (0x104D8, 'V'), + (0x104FC, 'X'), + (0x10500, 'V'), + (0x10528, 'X'), + (0x10530, 'V'), + (0x10564, 'X'), + (0x1056F, 'V'), + (0x10570, 'X'), + (0x10600, 'V'), + (0x10737, 'X'), + ] + +def _seg_54(): + return [ + (0x10740, 'V'), + (0x10756, 'X'), + (0x10760, 'V'), + (0x10768, 'X'), + (0x10800, 'V'), + (0x10806, 'X'), + (0x10808, 'V'), + (0x10809, 'X'), + (0x1080A, 'V'), + (0x10836, 'X'), + (0x10837, 'V'), + (0x10839, 'X'), + (0x1083C, 'V'), + (0x1083D, 'X'), + (0x1083F, 'V'), + (0x10856, 'X'), + (0x10857, 'V'), + (0x1089F, 'X'), + (0x108A7, 'V'), + (0x108B0, 'X'), + (0x108E0, 'V'), + (0x108F3, 'X'), + (0x108F4, 'V'), + (0x108F6, 'X'), + (0x108FB, 'V'), + (0x1091C, 'X'), + (0x1091F, 'V'), + (0x1093A, 'X'), + (0x1093F, 'V'), + (0x10940, 'X'), + (0x10980, 'V'), + (0x109B8, 'X'), + (0x109BC, 'V'), + (0x109D0, 'X'), + (0x109D2, 'V'), + (0x10A04, 'X'), + (0x10A05, 'V'), + (0x10A07, 'X'), + (0x10A0C, 'V'), + (0x10A14, 'X'), + (0x10A15, 'V'), + (0x10A18, 'X'), + (0x10A19, 'V'), + (0x10A34, 'X'), + (0x10A38, 'V'), + (0x10A3B, 'X'), + (0x10A3F, 'V'), + (0x10A48, 'X'), + (0x10A50, 'V'), + (0x10A59, 'X'), + (0x10A60, 'V'), + (0x10AA0, 'X'), + (0x10AC0, 'V'), + (0x10AE7, 'X'), + (0x10AEB, 'V'), + (0x10AF7, 'X'), + (0x10B00, 'V'), + (0x10B36, 'X'), + (0x10B39, 'V'), + (0x10B56, 'X'), + (0x10B58, 'V'), + (0x10B73, 'X'), + (0x10B78, 'V'), + (0x10B92, 'X'), + (0x10B99, 'V'), + (0x10B9D, 'X'), + (0x10BA9, 'V'), + (0x10BB0, 'X'), + (0x10C00, 'V'), + (0x10C49, 'X'), + (0x10C80, 'M', u'𐳀'), + (0x10C81, 'M', u'𐳁'), + (0x10C82, 'M', u'𐳂'), + (0x10C83, 'M', u'𐳃'), + (0x10C84, 'M', u'𐳄'), + (0x10C85, 'M', u'𐳅'), + (0x10C86, 'M', u'𐳆'), + (0x10C87, 'M', u'𐳇'), + (0x10C88, 'M', u'𐳈'), + (0x10C89, 'M', u'𐳉'), + (0x10C8A, 'M', u'𐳊'), + (0x10C8B, 'M', u'𐳋'), + (0x10C8C, 'M', u'𐳌'), + (0x10C8D, 'M', u'𐳍'), + (0x10C8E, 'M', u'𐳎'), + (0x10C8F, 'M', u'𐳏'), + (0x10C90, 'M', u'𐳐'), + (0x10C91, 'M', u'𐳑'), + (0x10C92, 'M', u'𐳒'), + (0x10C93, 'M', u'𐳓'), + (0x10C94, 'M', u'𐳔'), + (0x10C95, 'M', u'𐳕'), + (0x10C96, 'M', u'𐳖'), + (0x10C97, 'M', u'𐳗'), + (0x10C98, 'M', u'𐳘'), + (0x10C99, 'M', u'𐳙'), + (0x10C9A, 'M', u'𐳚'), + (0x10C9B, 'M', u'𐳛'), + (0x10C9C, 'M', u'𐳜'), + (0x10C9D, 'M', u'𐳝'), + ] + +def _seg_55(): + return [ + (0x10C9E, 'M', u'𐳞'), + (0x10C9F, 'M', u'𐳟'), + (0x10CA0, 'M', u'𐳠'), + (0x10CA1, 'M', u'𐳡'), + (0x10CA2, 'M', u'𐳢'), + (0x10CA3, 'M', u'𐳣'), + (0x10CA4, 'M', u'𐳤'), + (0x10CA5, 'M', u'𐳥'), + (0x10CA6, 'M', u'𐳦'), + (0x10CA7, 'M', u'𐳧'), + (0x10CA8, 'M', u'𐳨'), + (0x10CA9, 'M', u'𐳩'), + (0x10CAA, 'M', u'𐳪'), + (0x10CAB, 'M', u'𐳫'), + (0x10CAC, 'M', u'𐳬'), + (0x10CAD, 'M', u'𐳭'), + (0x10CAE, 'M', u'𐳮'), + (0x10CAF, 'M', u'𐳯'), + (0x10CB0, 'M', u'𐳰'), + (0x10CB1, 'M', u'𐳱'), + (0x10CB2, 'M', u'𐳲'), + (0x10CB3, 'X'), + (0x10CC0, 'V'), + (0x10CF3, 'X'), + (0x10CFA, 'V'), + (0x10D00, 'X'), + (0x10E60, 'V'), + (0x10E7F, 'X'), + (0x11000, 'V'), + (0x1104E, 'X'), + (0x11052, 'V'), + (0x11070, 'X'), + (0x1107F, 'V'), + (0x110BD, 'X'), + (0x110BE, 'V'), + (0x110C2, 'X'), + (0x110D0, 'V'), + (0x110E9, 'X'), + (0x110F0, 'V'), + (0x110FA, 'X'), + (0x11100, 'V'), + (0x11135, 'X'), + (0x11136, 'V'), + (0x11144, 'X'), + (0x11150, 'V'), + (0x11177, 'X'), + (0x11180, 'V'), + (0x111CE, 'X'), + (0x111D0, 'V'), + (0x111E0, 'X'), + (0x111E1, 'V'), + (0x111F5, 'X'), + (0x11200, 'V'), + (0x11212, 'X'), + (0x11213, 'V'), + (0x1123F, 'X'), + (0x11280, 'V'), + (0x11287, 'X'), + (0x11288, 'V'), + (0x11289, 'X'), + (0x1128A, 'V'), + (0x1128E, 'X'), + (0x1128F, 'V'), + (0x1129E, 'X'), + (0x1129F, 'V'), + (0x112AA, 'X'), + (0x112B0, 'V'), + (0x112EB, 'X'), + (0x112F0, 'V'), + (0x112FA, 'X'), + (0x11300, 'V'), + (0x11304, 'X'), + (0x11305, 'V'), + (0x1130D, 'X'), + (0x1130F, 'V'), + (0x11311, 'X'), + (0x11313, 'V'), + (0x11329, 'X'), + (0x1132A, 'V'), + (0x11331, 'X'), + (0x11332, 'V'), + (0x11334, 'X'), + (0x11335, 'V'), + (0x1133A, 'X'), + (0x1133C, 'V'), + (0x11345, 'X'), + (0x11347, 'V'), + (0x11349, 'X'), + (0x1134B, 'V'), + (0x1134E, 'X'), + (0x11350, 'V'), + (0x11351, 'X'), + (0x11357, 'V'), + (0x11358, 'X'), + (0x1135D, 'V'), + (0x11364, 'X'), + (0x11366, 'V'), + (0x1136D, 'X'), + (0x11370, 'V'), + (0x11375, 'X'), + ] + +def _seg_56(): + return [ + (0x11400, 'V'), + (0x1145A, 'X'), + (0x1145B, 'V'), + (0x1145C, 'X'), + (0x1145D, 'V'), + (0x1145E, 'X'), + (0x11480, 'V'), + (0x114C8, 'X'), + (0x114D0, 'V'), + (0x114DA, 'X'), + (0x11580, 'V'), + (0x115B6, 'X'), + (0x115B8, 'V'), + (0x115DE, 'X'), + (0x11600, 'V'), + (0x11645, 'X'), + (0x11650, 'V'), + (0x1165A, 'X'), + (0x11660, 'V'), + (0x1166D, 'X'), + (0x11680, 'V'), + (0x116B8, 'X'), + (0x116C0, 'V'), + (0x116CA, 'X'), + (0x11700, 'V'), + (0x1171A, 'X'), + (0x1171D, 'V'), + (0x1172C, 'X'), + (0x11730, 'V'), + (0x11740, 'X'), + (0x118A0, 'M', u'𑣀'), + (0x118A1, 'M', u'𑣁'), + (0x118A2, 'M', u'𑣂'), + (0x118A3, 'M', u'𑣃'), + (0x118A4, 'M', u'𑣄'), + (0x118A5, 'M', u'𑣅'), + (0x118A6, 'M', u'𑣆'), + (0x118A7, 'M', u'𑣇'), + (0x118A8, 'M', u'𑣈'), + (0x118A9, 'M', u'𑣉'), + (0x118AA, 'M', u'𑣊'), + (0x118AB, 'M', u'𑣋'), + (0x118AC, 'M', u'𑣌'), + (0x118AD, 'M', u'𑣍'), + (0x118AE, 'M', u'𑣎'), + (0x118AF, 'M', u'𑣏'), + (0x118B0, 'M', u'𑣐'), + (0x118B1, 'M', u'𑣑'), + (0x118B2, 'M', u'𑣒'), + (0x118B3, 'M', u'𑣓'), + (0x118B4, 'M', u'𑣔'), + (0x118B5, 'M', u'𑣕'), + (0x118B6, 'M', u'𑣖'), + (0x118B7, 'M', u'𑣗'), + (0x118B8, 'M', u'𑣘'), + (0x118B9, 'M', u'𑣙'), + (0x118BA, 'M', u'𑣚'), + (0x118BB, 'M', u'𑣛'), + (0x118BC, 'M', u'𑣜'), + (0x118BD, 'M', u'𑣝'), + (0x118BE, 'M', u'𑣞'), + (0x118BF, 'M', u'𑣟'), + (0x118C0, 'V'), + (0x118F3, 'X'), + (0x118FF, 'V'), + (0x11900, 'X'), + (0x11A00, 'V'), + (0x11A48, 'X'), + (0x11A50, 'V'), + (0x11A84, 'X'), + (0x11A86, 'V'), + (0x11A9D, 'X'), + (0x11A9E, 'V'), + (0x11AA3, 'X'), + (0x11AC0, 'V'), + (0x11AF9, 'X'), + (0x11C00, 'V'), + (0x11C09, 'X'), + (0x11C0A, 'V'), + (0x11C37, 'X'), + (0x11C38, 'V'), + (0x11C46, 'X'), + (0x11C50, 'V'), + (0x11C6D, 'X'), + (0x11C70, 'V'), + (0x11C90, 'X'), + (0x11C92, 'V'), + (0x11CA8, 'X'), + (0x11CA9, 'V'), + (0x11CB7, 'X'), + (0x11D00, 'V'), + (0x11D07, 'X'), + (0x11D08, 'V'), + (0x11D0A, 'X'), + (0x11D0B, 'V'), + (0x11D37, 'X'), + (0x11D3A, 'V'), + (0x11D3B, 'X'), + (0x11D3C, 'V'), + (0x11D3E, 'X'), + ] + +def _seg_57(): + return [ + (0x11D3F, 'V'), + (0x11D48, 'X'), + (0x11D50, 'V'), + (0x11D5A, 'X'), + (0x12000, 'V'), + (0x1239A, 'X'), + (0x12400, 'V'), + (0x1246F, 'X'), + (0x12470, 'V'), + (0x12475, 'X'), + (0x12480, 'V'), + (0x12544, 'X'), + (0x13000, 'V'), + (0x1342F, 'X'), + (0x14400, 'V'), + (0x14647, 'X'), + (0x16800, 'V'), + (0x16A39, 'X'), + (0x16A40, 'V'), + (0x16A5F, 'X'), + (0x16A60, 'V'), + (0x16A6A, 'X'), + (0x16A6E, 'V'), + (0x16A70, 'X'), + (0x16AD0, 'V'), + (0x16AEE, 'X'), + (0x16AF0, 'V'), + (0x16AF6, 'X'), + (0x16B00, 'V'), + (0x16B46, 'X'), + (0x16B50, 'V'), + (0x16B5A, 'X'), + (0x16B5B, 'V'), + (0x16B62, 'X'), + (0x16B63, 'V'), + (0x16B78, 'X'), + (0x16B7D, 'V'), + (0x16B90, 'X'), + (0x16F00, 'V'), + (0x16F45, 'X'), + (0x16F50, 'V'), + (0x16F7F, 'X'), + (0x16F8F, 'V'), + (0x16FA0, 'X'), + (0x16FE0, 'V'), + (0x16FE2, 'X'), + (0x17000, 'V'), + (0x187ED, 'X'), + (0x18800, 'V'), + (0x18AF3, 'X'), + (0x1B000, 'V'), + (0x1B11F, 'X'), + (0x1B170, 'V'), + (0x1B2FC, 'X'), + (0x1BC00, 'V'), + (0x1BC6B, 'X'), + (0x1BC70, 'V'), + (0x1BC7D, 'X'), + (0x1BC80, 'V'), + (0x1BC89, 'X'), + (0x1BC90, 'V'), + (0x1BC9A, 'X'), + (0x1BC9C, 'V'), + (0x1BCA0, 'I'), + (0x1BCA4, 'X'), + (0x1D000, 'V'), + (0x1D0F6, 'X'), + (0x1D100, 'V'), + (0x1D127, 'X'), + (0x1D129, 'V'), + (0x1D15E, 'M', u'𝅗𝅥'), + (0x1D15F, 'M', u'𝅘𝅥'), + (0x1D160, 'M', u'𝅘𝅥𝅮'), + (0x1D161, 'M', u'𝅘𝅥𝅯'), + (0x1D162, 'M', u'𝅘𝅥𝅰'), + (0x1D163, 'M', u'𝅘𝅥𝅱'), + (0x1D164, 'M', u'𝅘𝅥𝅲'), + (0x1D165, 'V'), + (0x1D173, 'X'), + (0x1D17B, 'V'), + (0x1D1BB, 'M', u'𝆹𝅥'), + (0x1D1BC, 'M', u'𝆺𝅥'), + (0x1D1BD, 'M', u'𝆹𝅥𝅮'), + (0x1D1BE, 'M', u'𝆺𝅥𝅮'), + (0x1D1BF, 'M', u'𝆹𝅥𝅯'), + (0x1D1C0, 'M', u'𝆺𝅥𝅯'), + (0x1D1C1, 'V'), + (0x1D1E9, 'X'), + (0x1D200, 'V'), + (0x1D246, 'X'), + (0x1D300, 'V'), + (0x1D357, 'X'), + (0x1D360, 'V'), + (0x1D372, 'X'), + (0x1D400, 'M', u'a'), + (0x1D401, 'M', u'b'), + (0x1D402, 'M', u'c'), + (0x1D403, 'M', u'd'), + (0x1D404, 'M', u'e'), + (0x1D405, 'M', u'f'), + ] + +def _seg_58(): + return [ + (0x1D406, 'M', u'g'), + (0x1D407, 'M', u'h'), + (0x1D408, 'M', u'i'), + (0x1D409, 'M', u'j'), + (0x1D40A, 'M', u'k'), + (0x1D40B, 'M', u'l'), + (0x1D40C, 'M', u'm'), + (0x1D40D, 'M', u'n'), + (0x1D40E, 'M', u'o'), + (0x1D40F, 'M', u'p'), + (0x1D410, 'M', u'q'), + (0x1D411, 'M', u'r'), + (0x1D412, 'M', u's'), + (0x1D413, 'M', u't'), + (0x1D414, 'M', u'u'), + (0x1D415, 'M', u'v'), + (0x1D416, 'M', u'w'), + (0x1D417, 'M', u'x'), + (0x1D418, 'M', u'y'), + (0x1D419, 'M', u'z'), + (0x1D41A, 'M', u'a'), + (0x1D41B, 'M', u'b'), + (0x1D41C, 'M', u'c'), + (0x1D41D, 'M', u'd'), + (0x1D41E, 'M', u'e'), + (0x1D41F, 'M', u'f'), + (0x1D420, 'M', u'g'), + (0x1D421, 'M', u'h'), + (0x1D422, 'M', u'i'), + (0x1D423, 'M', u'j'), + (0x1D424, 'M', u'k'), + (0x1D425, 'M', u'l'), + (0x1D426, 'M', u'm'), + (0x1D427, 'M', u'n'), + (0x1D428, 'M', u'o'), + (0x1D429, 'M', u'p'), + (0x1D42A, 'M', u'q'), + (0x1D42B, 'M', u'r'), + (0x1D42C, 'M', u's'), + (0x1D42D, 'M', u't'), + (0x1D42E, 'M', u'u'), + (0x1D42F, 'M', u'v'), + (0x1D430, 'M', u'w'), + (0x1D431, 'M', u'x'), + (0x1D432, 'M', u'y'), + (0x1D433, 'M', u'z'), + (0x1D434, 'M', u'a'), + (0x1D435, 'M', u'b'), + (0x1D436, 'M', u'c'), + (0x1D437, 'M', u'd'), + (0x1D438, 'M', u'e'), + (0x1D439, 'M', u'f'), + (0x1D43A, 'M', u'g'), + (0x1D43B, 'M', u'h'), + (0x1D43C, 'M', u'i'), + (0x1D43D, 'M', u'j'), + (0x1D43E, 'M', u'k'), + (0x1D43F, 'M', u'l'), + (0x1D440, 'M', u'm'), + (0x1D441, 'M', u'n'), + (0x1D442, 'M', u'o'), + (0x1D443, 'M', u'p'), + (0x1D444, 'M', u'q'), + (0x1D445, 'M', u'r'), + (0x1D446, 'M', u's'), + (0x1D447, 'M', u't'), + (0x1D448, 'M', u'u'), + (0x1D449, 'M', u'v'), + (0x1D44A, 'M', u'w'), + (0x1D44B, 'M', u'x'), + (0x1D44C, 'M', u'y'), + (0x1D44D, 'M', u'z'), + (0x1D44E, 'M', u'a'), + (0x1D44F, 'M', u'b'), + (0x1D450, 'M', u'c'), + (0x1D451, 'M', u'd'), + (0x1D452, 'M', u'e'), + (0x1D453, 'M', u'f'), + (0x1D454, 'M', u'g'), + (0x1D455, 'X'), + (0x1D456, 'M', u'i'), + (0x1D457, 'M', u'j'), + (0x1D458, 'M', u'k'), + (0x1D459, 'M', u'l'), + (0x1D45A, 'M', u'm'), + (0x1D45B, 'M', u'n'), + (0x1D45C, 'M', u'o'), + (0x1D45D, 'M', u'p'), + (0x1D45E, 'M', u'q'), + (0x1D45F, 'M', u'r'), + (0x1D460, 'M', u's'), + (0x1D461, 'M', u't'), + (0x1D462, 'M', u'u'), + (0x1D463, 'M', u'v'), + (0x1D464, 'M', u'w'), + (0x1D465, 'M', u'x'), + (0x1D466, 'M', u'y'), + (0x1D467, 'M', u'z'), + (0x1D468, 'M', u'a'), + (0x1D469, 'M', u'b'), + ] + +def _seg_59(): + return [ + (0x1D46A, 'M', u'c'), + (0x1D46B, 'M', u'd'), + (0x1D46C, 'M', u'e'), + (0x1D46D, 'M', u'f'), + (0x1D46E, 'M', u'g'), + (0x1D46F, 'M', u'h'), + (0x1D470, 'M', u'i'), + (0x1D471, 'M', u'j'), + (0x1D472, 'M', u'k'), + (0x1D473, 'M', u'l'), + (0x1D474, 'M', u'm'), + (0x1D475, 'M', u'n'), + (0x1D476, 'M', u'o'), + (0x1D477, 'M', u'p'), + (0x1D478, 'M', u'q'), + (0x1D479, 'M', u'r'), + (0x1D47A, 'M', u's'), + (0x1D47B, 'M', u't'), + (0x1D47C, 'M', u'u'), + (0x1D47D, 'M', u'v'), + (0x1D47E, 'M', u'w'), + (0x1D47F, 'M', u'x'), + (0x1D480, 'M', u'y'), + (0x1D481, 'M', u'z'), + (0x1D482, 'M', u'a'), + (0x1D483, 'M', u'b'), + (0x1D484, 'M', u'c'), + (0x1D485, 'M', u'd'), + (0x1D486, 'M', u'e'), + (0x1D487, 'M', u'f'), + (0x1D488, 'M', u'g'), + (0x1D489, 'M', u'h'), + (0x1D48A, 'M', u'i'), + (0x1D48B, 'M', u'j'), + (0x1D48C, 'M', u'k'), + (0x1D48D, 'M', u'l'), + (0x1D48E, 'M', u'm'), + (0x1D48F, 'M', u'n'), + (0x1D490, 'M', u'o'), + (0x1D491, 'M', u'p'), + (0x1D492, 'M', u'q'), + (0x1D493, 'M', u'r'), + (0x1D494, 'M', u's'), + (0x1D495, 'M', u't'), + (0x1D496, 'M', u'u'), + (0x1D497, 'M', u'v'), + (0x1D498, 'M', u'w'), + (0x1D499, 'M', u'x'), + (0x1D49A, 'M', u'y'), + (0x1D49B, 'M', u'z'), + (0x1D49C, 'M', u'a'), + (0x1D49D, 'X'), + (0x1D49E, 'M', u'c'), + (0x1D49F, 'M', u'd'), + (0x1D4A0, 'X'), + (0x1D4A2, 'M', u'g'), + (0x1D4A3, 'X'), + (0x1D4A5, 'M', u'j'), + (0x1D4A6, 'M', u'k'), + (0x1D4A7, 'X'), + (0x1D4A9, 'M', u'n'), + (0x1D4AA, 'M', u'o'), + (0x1D4AB, 'M', u'p'), + (0x1D4AC, 'M', u'q'), + (0x1D4AD, 'X'), + (0x1D4AE, 'M', u's'), + (0x1D4AF, 'M', u't'), + (0x1D4B0, 'M', u'u'), + (0x1D4B1, 'M', u'v'), + (0x1D4B2, 'M', u'w'), + (0x1D4B3, 'M', u'x'), + (0x1D4B4, 'M', u'y'), + (0x1D4B5, 'M', u'z'), + (0x1D4B6, 'M', u'a'), + (0x1D4B7, 'M', u'b'), + (0x1D4B8, 'M', u'c'), + (0x1D4B9, 'M', u'd'), + (0x1D4BA, 'X'), + (0x1D4BB, 'M', u'f'), + (0x1D4BC, 'X'), + (0x1D4BD, 'M', u'h'), + (0x1D4BE, 'M', u'i'), + (0x1D4BF, 'M', u'j'), + (0x1D4C0, 'M', u'k'), + (0x1D4C1, 'M', u'l'), + (0x1D4C2, 'M', u'm'), + (0x1D4C3, 'M', u'n'), + (0x1D4C4, 'X'), + (0x1D4C5, 'M', u'p'), + (0x1D4C6, 'M', u'q'), + (0x1D4C7, 'M', u'r'), + (0x1D4C8, 'M', u's'), + (0x1D4C9, 'M', u't'), + (0x1D4CA, 'M', u'u'), + (0x1D4CB, 'M', u'v'), + (0x1D4CC, 'M', u'w'), + (0x1D4CD, 'M', u'x'), + (0x1D4CE, 'M', u'y'), + (0x1D4CF, 'M', u'z'), + (0x1D4D0, 'M', u'a'), + ] + +def _seg_60(): + return [ + (0x1D4D1, 'M', u'b'), + (0x1D4D2, 'M', u'c'), + (0x1D4D3, 'M', u'd'), + (0x1D4D4, 'M', u'e'), + (0x1D4D5, 'M', u'f'), + (0x1D4D6, 'M', u'g'), + (0x1D4D7, 'M', u'h'), + (0x1D4D8, 'M', u'i'), + (0x1D4D9, 'M', u'j'), + (0x1D4DA, 'M', u'k'), + (0x1D4DB, 'M', u'l'), + (0x1D4DC, 'M', u'm'), + (0x1D4DD, 'M', u'n'), + (0x1D4DE, 'M', u'o'), + (0x1D4DF, 'M', u'p'), + (0x1D4E0, 'M', u'q'), + (0x1D4E1, 'M', u'r'), + (0x1D4E2, 'M', u's'), + (0x1D4E3, 'M', u't'), + (0x1D4E4, 'M', u'u'), + (0x1D4E5, 'M', u'v'), + (0x1D4E6, 'M', u'w'), + (0x1D4E7, 'M', u'x'), + (0x1D4E8, 'M', u'y'), + (0x1D4E9, 'M', u'z'), + (0x1D4EA, 'M', u'a'), + (0x1D4EB, 'M', u'b'), + (0x1D4EC, 'M', u'c'), + (0x1D4ED, 'M', u'd'), + (0x1D4EE, 'M', u'e'), + (0x1D4EF, 'M', u'f'), + (0x1D4F0, 'M', u'g'), + (0x1D4F1, 'M', u'h'), + (0x1D4F2, 'M', u'i'), + (0x1D4F3, 'M', u'j'), + (0x1D4F4, 'M', u'k'), + (0x1D4F5, 'M', u'l'), + (0x1D4F6, 'M', u'm'), + (0x1D4F7, 'M', u'n'), + (0x1D4F8, 'M', u'o'), + (0x1D4F9, 'M', u'p'), + (0x1D4FA, 'M', u'q'), + (0x1D4FB, 'M', u'r'), + (0x1D4FC, 'M', u's'), + (0x1D4FD, 'M', u't'), + (0x1D4FE, 'M', u'u'), + (0x1D4FF, 'M', u'v'), + (0x1D500, 'M', u'w'), + (0x1D501, 'M', u'x'), + (0x1D502, 'M', u'y'), + (0x1D503, 'M', u'z'), + (0x1D504, 'M', u'a'), + (0x1D505, 'M', u'b'), + (0x1D506, 'X'), + (0x1D507, 'M', u'd'), + (0x1D508, 'M', u'e'), + (0x1D509, 'M', u'f'), + (0x1D50A, 'M', u'g'), + (0x1D50B, 'X'), + (0x1D50D, 'M', u'j'), + (0x1D50E, 'M', u'k'), + (0x1D50F, 'M', u'l'), + (0x1D510, 'M', u'm'), + (0x1D511, 'M', u'n'), + (0x1D512, 'M', u'o'), + (0x1D513, 'M', u'p'), + (0x1D514, 'M', u'q'), + (0x1D515, 'X'), + (0x1D516, 'M', u's'), + (0x1D517, 'M', u't'), + (0x1D518, 'M', u'u'), + (0x1D519, 'M', u'v'), + (0x1D51A, 'M', u'w'), + (0x1D51B, 'M', u'x'), + (0x1D51C, 'M', u'y'), + (0x1D51D, 'X'), + (0x1D51E, 'M', u'a'), + (0x1D51F, 'M', u'b'), + (0x1D520, 'M', u'c'), + (0x1D521, 'M', u'd'), + (0x1D522, 'M', u'e'), + (0x1D523, 'M', u'f'), + (0x1D524, 'M', u'g'), + (0x1D525, 'M', u'h'), + (0x1D526, 'M', u'i'), + (0x1D527, 'M', u'j'), + (0x1D528, 'M', u'k'), + (0x1D529, 'M', u'l'), + (0x1D52A, 'M', u'm'), + (0x1D52B, 'M', u'n'), + (0x1D52C, 'M', u'o'), + (0x1D52D, 'M', u'p'), + (0x1D52E, 'M', u'q'), + (0x1D52F, 'M', u'r'), + (0x1D530, 'M', u's'), + (0x1D531, 'M', u't'), + (0x1D532, 'M', u'u'), + (0x1D533, 'M', u'v'), + (0x1D534, 'M', u'w'), + (0x1D535, 'M', u'x'), + ] + +def _seg_61(): + return [ + (0x1D536, 'M', u'y'), + (0x1D537, 'M', u'z'), + (0x1D538, 'M', u'a'), + (0x1D539, 'M', u'b'), + (0x1D53A, 'X'), + (0x1D53B, 'M', u'd'), + (0x1D53C, 'M', u'e'), + (0x1D53D, 'M', u'f'), + (0x1D53E, 'M', u'g'), + (0x1D53F, 'X'), + (0x1D540, 'M', u'i'), + (0x1D541, 'M', u'j'), + (0x1D542, 'M', u'k'), + (0x1D543, 'M', u'l'), + (0x1D544, 'M', u'm'), + (0x1D545, 'X'), + (0x1D546, 'M', u'o'), + (0x1D547, 'X'), + (0x1D54A, 'M', u's'), + (0x1D54B, 'M', u't'), + (0x1D54C, 'M', u'u'), + (0x1D54D, 'M', u'v'), + (0x1D54E, 'M', u'w'), + (0x1D54F, 'M', u'x'), + (0x1D550, 'M', u'y'), + (0x1D551, 'X'), + (0x1D552, 'M', u'a'), + (0x1D553, 'M', u'b'), + (0x1D554, 'M', u'c'), + (0x1D555, 'M', u'd'), + (0x1D556, 'M', u'e'), + (0x1D557, 'M', u'f'), + (0x1D558, 'M', u'g'), + (0x1D559, 'M', u'h'), + (0x1D55A, 'M', u'i'), + (0x1D55B, 'M', u'j'), + (0x1D55C, 'M', u'k'), + (0x1D55D, 'M', u'l'), + (0x1D55E, 'M', u'm'), + (0x1D55F, 'M', u'n'), + (0x1D560, 'M', u'o'), + (0x1D561, 'M', u'p'), + (0x1D562, 'M', u'q'), + (0x1D563, 'M', u'r'), + (0x1D564, 'M', u's'), + (0x1D565, 'M', u't'), + (0x1D566, 'M', u'u'), + (0x1D567, 'M', u'v'), + (0x1D568, 'M', u'w'), + (0x1D569, 'M', u'x'), + (0x1D56A, 'M', u'y'), + (0x1D56B, 'M', u'z'), + (0x1D56C, 'M', u'a'), + (0x1D56D, 'M', u'b'), + (0x1D56E, 'M', u'c'), + (0x1D56F, 'M', u'd'), + (0x1D570, 'M', u'e'), + (0x1D571, 'M', u'f'), + (0x1D572, 'M', u'g'), + (0x1D573, 'M', u'h'), + (0x1D574, 'M', u'i'), + (0x1D575, 'M', u'j'), + (0x1D576, 'M', u'k'), + (0x1D577, 'M', u'l'), + (0x1D578, 'M', u'm'), + (0x1D579, 'M', u'n'), + (0x1D57A, 'M', u'o'), + (0x1D57B, 'M', u'p'), + (0x1D57C, 'M', u'q'), + (0x1D57D, 'M', u'r'), + (0x1D57E, 'M', u's'), + (0x1D57F, 'M', u't'), + (0x1D580, 'M', u'u'), + (0x1D581, 'M', u'v'), + (0x1D582, 'M', u'w'), + (0x1D583, 'M', u'x'), + (0x1D584, 'M', u'y'), + (0x1D585, 'M', u'z'), + (0x1D586, 'M', u'a'), + (0x1D587, 'M', u'b'), + (0x1D588, 'M', u'c'), + (0x1D589, 'M', u'd'), + (0x1D58A, 'M', u'e'), + (0x1D58B, 'M', u'f'), + (0x1D58C, 'M', u'g'), + (0x1D58D, 'M', u'h'), + (0x1D58E, 'M', u'i'), + (0x1D58F, 'M', u'j'), + (0x1D590, 'M', u'k'), + (0x1D591, 'M', u'l'), + (0x1D592, 'M', u'm'), + (0x1D593, 'M', u'n'), + (0x1D594, 'M', u'o'), + (0x1D595, 'M', u'p'), + (0x1D596, 'M', u'q'), + (0x1D597, 'M', u'r'), + (0x1D598, 'M', u's'), + (0x1D599, 'M', u't'), + (0x1D59A, 'M', u'u'), + (0x1D59B, 'M', u'v'), + ] + +def _seg_62(): + return [ + (0x1D59C, 'M', u'w'), + (0x1D59D, 'M', u'x'), + (0x1D59E, 'M', u'y'), + (0x1D59F, 'M', u'z'), + (0x1D5A0, 'M', u'a'), + (0x1D5A1, 'M', u'b'), + (0x1D5A2, 'M', u'c'), + (0x1D5A3, 'M', u'd'), + (0x1D5A4, 'M', u'e'), + (0x1D5A5, 'M', u'f'), + (0x1D5A6, 'M', u'g'), + (0x1D5A7, 'M', u'h'), + (0x1D5A8, 'M', u'i'), + (0x1D5A9, 'M', u'j'), + (0x1D5AA, 'M', u'k'), + (0x1D5AB, 'M', u'l'), + (0x1D5AC, 'M', u'm'), + (0x1D5AD, 'M', u'n'), + (0x1D5AE, 'M', u'o'), + (0x1D5AF, 'M', u'p'), + (0x1D5B0, 'M', u'q'), + (0x1D5B1, 'M', u'r'), + (0x1D5B2, 'M', u's'), + (0x1D5B3, 'M', u't'), + (0x1D5B4, 'M', u'u'), + (0x1D5B5, 'M', u'v'), + (0x1D5B6, 'M', u'w'), + (0x1D5B7, 'M', u'x'), + (0x1D5B8, 'M', u'y'), + (0x1D5B9, 'M', u'z'), + (0x1D5BA, 'M', u'a'), + (0x1D5BB, 'M', u'b'), + (0x1D5BC, 'M', u'c'), + (0x1D5BD, 'M', u'd'), + (0x1D5BE, 'M', u'e'), + (0x1D5BF, 'M', u'f'), + (0x1D5C0, 'M', u'g'), + (0x1D5C1, 'M', u'h'), + (0x1D5C2, 'M', u'i'), + (0x1D5C3, 'M', u'j'), + (0x1D5C4, 'M', u'k'), + (0x1D5C5, 'M', u'l'), + (0x1D5C6, 'M', u'm'), + (0x1D5C7, 'M', u'n'), + (0x1D5C8, 'M', u'o'), + (0x1D5C9, 'M', u'p'), + (0x1D5CA, 'M', u'q'), + (0x1D5CB, 'M', u'r'), + (0x1D5CC, 'M', u's'), + (0x1D5CD, 'M', u't'), + (0x1D5CE, 'M', u'u'), + (0x1D5CF, 'M', u'v'), + (0x1D5D0, 'M', u'w'), + (0x1D5D1, 'M', u'x'), + (0x1D5D2, 'M', u'y'), + (0x1D5D3, 'M', u'z'), + (0x1D5D4, 'M', u'a'), + (0x1D5D5, 'M', u'b'), + (0x1D5D6, 'M', u'c'), + (0x1D5D7, 'M', u'd'), + (0x1D5D8, 'M', u'e'), + (0x1D5D9, 'M', u'f'), + (0x1D5DA, 'M', u'g'), + (0x1D5DB, 'M', u'h'), + (0x1D5DC, 'M', u'i'), + (0x1D5DD, 'M', u'j'), + (0x1D5DE, 'M', u'k'), + (0x1D5DF, 'M', u'l'), + (0x1D5E0, 'M', u'm'), + (0x1D5E1, 'M', u'n'), + (0x1D5E2, 'M', u'o'), + (0x1D5E3, 'M', u'p'), + (0x1D5E4, 'M', u'q'), + (0x1D5E5, 'M', u'r'), + (0x1D5E6, 'M', u's'), + (0x1D5E7, 'M', u't'), + (0x1D5E8, 'M', u'u'), + (0x1D5E9, 'M', u'v'), + (0x1D5EA, 'M', u'w'), + (0x1D5EB, 'M', u'x'), + (0x1D5EC, 'M', u'y'), + (0x1D5ED, 'M', u'z'), + (0x1D5EE, 'M', u'a'), + (0x1D5EF, 'M', u'b'), + (0x1D5F0, 'M', u'c'), + (0x1D5F1, 'M', u'd'), + (0x1D5F2, 'M', u'e'), + (0x1D5F3, 'M', u'f'), + (0x1D5F4, 'M', u'g'), + (0x1D5F5, 'M', u'h'), + (0x1D5F6, 'M', u'i'), + (0x1D5F7, 'M', u'j'), + (0x1D5F8, 'M', u'k'), + (0x1D5F9, 'M', u'l'), + (0x1D5FA, 'M', u'm'), + (0x1D5FB, 'M', u'n'), + (0x1D5FC, 'M', u'o'), + (0x1D5FD, 'M', u'p'), + (0x1D5FE, 'M', u'q'), + (0x1D5FF, 'M', u'r'), + ] + +def _seg_63(): + return [ + (0x1D600, 'M', u's'), + (0x1D601, 'M', u't'), + (0x1D602, 'M', u'u'), + (0x1D603, 'M', u'v'), + (0x1D604, 'M', u'w'), + (0x1D605, 'M', u'x'), + (0x1D606, 'M', u'y'), + (0x1D607, 'M', u'z'), + (0x1D608, 'M', u'a'), + (0x1D609, 'M', u'b'), + (0x1D60A, 'M', u'c'), + (0x1D60B, 'M', u'd'), + (0x1D60C, 'M', u'e'), + (0x1D60D, 'M', u'f'), + (0x1D60E, 'M', u'g'), + (0x1D60F, 'M', u'h'), + (0x1D610, 'M', u'i'), + (0x1D611, 'M', u'j'), + (0x1D612, 'M', u'k'), + (0x1D613, 'M', u'l'), + (0x1D614, 'M', u'm'), + (0x1D615, 'M', u'n'), + (0x1D616, 'M', u'o'), + (0x1D617, 'M', u'p'), + (0x1D618, 'M', u'q'), + (0x1D619, 'M', u'r'), + (0x1D61A, 'M', u's'), + (0x1D61B, 'M', u't'), + (0x1D61C, 'M', u'u'), + (0x1D61D, 'M', u'v'), + (0x1D61E, 'M', u'w'), + (0x1D61F, 'M', u'x'), + (0x1D620, 'M', u'y'), + (0x1D621, 'M', u'z'), + (0x1D622, 'M', u'a'), + (0x1D623, 'M', u'b'), + (0x1D624, 'M', u'c'), + (0x1D625, 'M', u'd'), + (0x1D626, 'M', u'e'), + (0x1D627, 'M', u'f'), + (0x1D628, 'M', u'g'), + (0x1D629, 'M', u'h'), + (0x1D62A, 'M', u'i'), + (0x1D62B, 'M', u'j'), + (0x1D62C, 'M', u'k'), + (0x1D62D, 'M', u'l'), + (0x1D62E, 'M', u'm'), + (0x1D62F, 'M', u'n'), + (0x1D630, 'M', u'o'), + (0x1D631, 'M', u'p'), + (0x1D632, 'M', u'q'), + (0x1D633, 'M', u'r'), + (0x1D634, 'M', u's'), + (0x1D635, 'M', u't'), + (0x1D636, 'M', u'u'), + (0x1D637, 'M', u'v'), + (0x1D638, 'M', u'w'), + (0x1D639, 'M', u'x'), + (0x1D63A, 'M', u'y'), + (0x1D63B, 'M', u'z'), + (0x1D63C, 'M', u'a'), + (0x1D63D, 'M', u'b'), + (0x1D63E, 'M', u'c'), + (0x1D63F, 'M', u'd'), + (0x1D640, 'M', u'e'), + (0x1D641, 'M', u'f'), + (0x1D642, 'M', u'g'), + (0x1D643, 'M', u'h'), + (0x1D644, 'M', u'i'), + (0x1D645, 'M', u'j'), + (0x1D646, 'M', u'k'), + (0x1D647, 'M', u'l'), + (0x1D648, 'M', u'm'), + (0x1D649, 'M', u'n'), + (0x1D64A, 'M', u'o'), + (0x1D64B, 'M', u'p'), + (0x1D64C, 'M', u'q'), + (0x1D64D, 'M', u'r'), + (0x1D64E, 'M', u's'), + (0x1D64F, 'M', u't'), + (0x1D650, 'M', u'u'), + (0x1D651, 'M', u'v'), + (0x1D652, 'M', u'w'), + (0x1D653, 'M', u'x'), + (0x1D654, 'M', u'y'), + (0x1D655, 'M', u'z'), + (0x1D656, 'M', u'a'), + (0x1D657, 'M', u'b'), + (0x1D658, 'M', u'c'), + (0x1D659, 'M', u'd'), + (0x1D65A, 'M', u'e'), + (0x1D65B, 'M', u'f'), + (0x1D65C, 'M', u'g'), + (0x1D65D, 'M', u'h'), + (0x1D65E, 'M', u'i'), + (0x1D65F, 'M', u'j'), + (0x1D660, 'M', u'k'), + (0x1D661, 'M', u'l'), + (0x1D662, 'M', u'm'), + (0x1D663, 'M', u'n'), + ] + +def _seg_64(): + return [ + (0x1D664, 'M', u'o'), + (0x1D665, 'M', u'p'), + (0x1D666, 'M', u'q'), + (0x1D667, 'M', u'r'), + (0x1D668, 'M', u's'), + (0x1D669, 'M', u't'), + (0x1D66A, 'M', u'u'), + (0x1D66B, 'M', u'v'), + (0x1D66C, 'M', u'w'), + (0x1D66D, 'M', u'x'), + (0x1D66E, 'M', u'y'), + (0x1D66F, 'M', u'z'), + (0x1D670, 'M', u'a'), + (0x1D671, 'M', u'b'), + (0x1D672, 'M', u'c'), + (0x1D673, 'M', u'd'), + (0x1D674, 'M', u'e'), + (0x1D675, 'M', u'f'), + (0x1D676, 'M', u'g'), + (0x1D677, 'M', u'h'), + (0x1D678, 'M', u'i'), + (0x1D679, 'M', u'j'), + (0x1D67A, 'M', u'k'), + (0x1D67B, 'M', u'l'), + (0x1D67C, 'M', u'm'), + (0x1D67D, 'M', u'n'), + (0x1D67E, 'M', u'o'), + (0x1D67F, 'M', u'p'), + (0x1D680, 'M', u'q'), + (0x1D681, 'M', u'r'), + (0x1D682, 'M', u's'), + (0x1D683, 'M', u't'), + (0x1D684, 'M', u'u'), + (0x1D685, 'M', u'v'), + (0x1D686, 'M', u'w'), + (0x1D687, 'M', u'x'), + (0x1D688, 'M', u'y'), + (0x1D689, 'M', u'z'), + (0x1D68A, 'M', u'a'), + (0x1D68B, 'M', u'b'), + (0x1D68C, 'M', u'c'), + (0x1D68D, 'M', u'd'), + (0x1D68E, 'M', u'e'), + (0x1D68F, 'M', u'f'), + (0x1D690, 'M', u'g'), + (0x1D691, 'M', u'h'), + (0x1D692, 'M', u'i'), + (0x1D693, 'M', u'j'), + (0x1D694, 'M', u'k'), + (0x1D695, 'M', u'l'), + (0x1D696, 'M', u'm'), + (0x1D697, 'M', u'n'), + (0x1D698, 'M', u'o'), + (0x1D699, 'M', u'p'), + (0x1D69A, 'M', u'q'), + (0x1D69B, 'M', u'r'), + (0x1D69C, 'M', u's'), + (0x1D69D, 'M', u't'), + (0x1D69E, 'M', u'u'), + (0x1D69F, 'M', u'v'), + (0x1D6A0, 'M', u'w'), + (0x1D6A1, 'M', u'x'), + (0x1D6A2, 'M', u'y'), + (0x1D6A3, 'M', u'z'), + (0x1D6A4, 'M', u'ı'), + (0x1D6A5, 'M', u'ȷ'), + (0x1D6A6, 'X'), + (0x1D6A8, 'M', u'α'), + (0x1D6A9, 'M', u'β'), + (0x1D6AA, 'M', u'γ'), + (0x1D6AB, 'M', u'δ'), + (0x1D6AC, 'M', u'ε'), + (0x1D6AD, 'M', u'ζ'), + (0x1D6AE, 'M', u'η'), + (0x1D6AF, 'M', u'θ'), + (0x1D6B0, 'M', u'ι'), + (0x1D6B1, 'M', u'κ'), + (0x1D6B2, 'M', u'λ'), + (0x1D6B3, 'M', u'μ'), + (0x1D6B4, 'M', u'ν'), + (0x1D6B5, 'M', u'ξ'), + (0x1D6B6, 'M', u'ο'), + (0x1D6B7, 'M', u'π'), + (0x1D6B8, 'M', u'ρ'), + (0x1D6B9, 'M', u'θ'), + (0x1D6BA, 'M', u'σ'), + (0x1D6BB, 'M', u'τ'), + (0x1D6BC, 'M', u'υ'), + (0x1D6BD, 'M', u'φ'), + (0x1D6BE, 'M', u'χ'), + (0x1D6BF, 'M', u'ψ'), + (0x1D6C0, 'M', u'ω'), + (0x1D6C1, 'M', u'∇'), + (0x1D6C2, 'M', u'α'), + (0x1D6C3, 'M', u'β'), + (0x1D6C4, 'M', u'γ'), + (0x1D6C5, 'M', u'δ'), + (0x1D6C6, 'M', u'ε'), + (0x1D6C7, 'M', u'ζ'), + (0x1D6C8, 'M', u'η'), + ] + +def _seg_65(): + return [ + (0x1D6C9, 'M', u'θ'), + (0x1D6CA, 'M', u'ι'), + (0x1D6CB, 'M', u'κ'), + (0x1D6CC, 'M', u'λ'), + (0x1D6CD, 'M', u'μ'), + (0x1D6CE, 'M', u'ν'), + (0x1D6CF, 'M', u'ξ'), + (0x1D6D0, 'M', u'ο'), + (0x1D6D1, 'M', u'π'), + (0x1D6D2, 'M', u'ρ'), + (0x1D6D3, 'M', u'σ'), + (0x1D6D5, 'M', u'τ'), + (0x1D6D6, 'M', u'υ'), + (0x1D6D7, 'M', u'φ'), + (0x1D6D8, 'M', u'χ'), + (0x1D6D9, 'M', u'ψ'), + (0x1D6DA, 'M', u'ω'), + (0x1D6DB, 'M', u'∂'), + (0x1D6DC, 'M', u'ε'), + (0x1D6DD, 'M', u'θ'), + (0x1D6DE, 'M', u'κ'), + (0x1D6DF, 'M', u'φ'), + (0x1D6E0, 'M', u'ρ'), + (0x1D6E1, 'M', u'π'), + (0x1D6E2, 'M', u'α'), + (0x1D6E3, 'M', u'β'), + (0x1D6E4, 'M', u'γ'), + (0x1D6E5, 'M', u'δ'), + (0x1D6E6, 'M', u'ε'), + (0x1D6E7, 'M', u'ζ'), + (0x1D6E8, 'M', u'η'), + (0x1D6E9, 'M', u'θ'), + (0x1D6EA, 'M', u'ι'), + (0x1D6EB, 'M', u'κ'), + (0x1D6EC, 'M', u'λ'), + (0x1D6ED, 'M', u'μ'), + (0x1D6EE, 'M', u'ν'), + (0x1D6EF, 'M', u'ξ'), + (0x1D6F0, 'M', u'ο'), + (0x1D6F1, 'M', u'π'), + (0x1D6F2, 'M', u'ρ'), + (0x1D6F3, 'M', u'θ'), + (0x1D6F4, 'M', u'σ'), + (0x1D6F5, 'M', u'τ'), + (0x1D6F6, 'M', u'υ'), + (0x1D6F7, 'M', u'φ'), + (0x1D6F8, 'M', u'χ'), + (0x1D6F9, 'M', u'ψ'), + (0x1D6FA, 'M', u'ω'), + (0x1D6FB, 'M', u'∇'), + (0x1D6FC, 'M', u'α'), + (0x1D6FD, 'M', u'β'), + (0x1D6FE, 'M', u'γ'), + (0x1D6FF, 'M', u'δ'), + (0x1D700, 'M', u'ε'), + (0x1D701, 'M', u'ζ'), + (0x1D702, 'M', u'η'), + (0x1D703, 'M', u'θ'), + (0x1D704, 'M', u'ι'), + (0x1D705, 'M', u'κ'), + (0x1D706, 'M', u'λ'), + (0x1D707, 'M', u'μ'), + (0x1D708, 'M', u'ν'), + (0x1D709, 'M', u'ξ'), + (0x1D70A, 'M', u'ο'), + (0x1D70B, 'M', u'π'), + (0x1D70C, 'M', u'ρ'), + (0x1D70D, 'M', u'σ'), + (0x1D70F, 'M', u'τ'), + (0x1D710, 'M', u'υ'), + (0x1D711, 'M', u'φ'), + (0x1D712, 'M', u'χ'), + (0x1D713, 'M', u'ψ'), + (0x1D714, 'M', u'ω'), + (0x1D715, 'M', u'∂'), + (0x1D716, 'M', u'ε'), + (0x1D717, 'M', u'θ'), + (0x1D718, 'M', u'κ'), + (0x1D719, 'M', u'φ'), + (0x1D71A, 'M', u'ρ'), + (0x1D71B, 'M', u'π'), + (0x1D71C, 'M', u'α'), + (0x1D71D, 'M', u'β'), + (0x1D71E, 'M', u'γ'), + (0x1D71F, 'M', u'δ'), + (0x1D720, 'M', u'ε'), + (0x1D721, 'M', u'ζ'), + (0x1D722, 'M', u'η'), + (0x1D723, 'M', u'θ'), + (0x1D724, 'M', u'ι'), + (0x1D725, 'M', u'κ'), + (0x1D726, 'M', u'λ'), + (0x1D727, 'M', u'μ'), + (0x1D728, 'M', u'ν'), + (0x1D729, 'M', u'ξ'), + (0x1D72A, 'M', u'ο'), + (0x1D72B, 'M', u'π'), + (0x1D72C, 'M', u'ρ'), + (0x1D72D, 'M', u'θ'), + (0x1D72E, 'M', u'σ'), + ] + +def _seg_66(): + return [ + (0x1D72F, 'M', u'τ'), + (0x1D730, 'M', u'υ'), + (0x1D731, 'M', u'φ'), + (0x1D732, 'M', u'χ'), + (0x1D733, 'M', u'ψ'), + (0x1D734, 'M', u'ω'), + (0x1D735, 'M', u'∇'), + (0x1D736, 'M', u'α'), + (0x1D737, 'M', u'β'), + (0x1D738, 'M', u'γ'), + (0x1D739, 'M', u'δ'), + (0x1D73A, 'M', u'ε'), + (0x1D73B, 'M', u'ζ'), + (0x1D73C, 'M', u'η'), + (0x1D73D, 'M', u'θ'), + (0x1D73E, 'M', u'ι'), + (0x1D73F, 'M', u'κ'), + (0x1D740, 'M', u'λ'), + (0x1D741, 'M', u'μ'), + (0x1D742, 'M', u'ν'), + (0x1D743, 'M', u'ξ'), + (0x1D744, 'M', u'ο'), + (0x1D745, 'M', u'π'), + (0x1D746, 'M', u'ρ'), + (0x1D747, 'M', u'σ'), + (0x1D749, 'M', u'τ'), + (0x1D74A, 'M', u'υ'), + (0x1D74B, 'M', u'φ'), + (0x1D74C, 'M', u'χ'), + (0x1D74D, 'M', u'ψ'), + (0x1D74E, 'M', u'ω'), + (0x1D74F, 'M', u'∂'), + (0x1D750, 'M', u'ε'), + (0x1D751, 'M', u'θ'), + (0x1D752, 'M', u'κ'), + (0x1D753, 'M', u'φ'), + (0x1D754, 'M', u'ρ'), + (0x1D755, 'M', u'π'), + (0x1D756, 'M', u'α'), + (0x1D757, 'M', u'β'), + (0x1D758, 'M', u'γ'), + (0x1D759, 'M', u'δ'), + (0x1D75A, 'M', u'ε'), + (0x1D75B, 'M', u'ζ'), + (0x1D75C, 'M', u'η'), + (0x1D75D, 'M', u'θ'), + (0x1D75E, 'M', u'ι'), + (0x1D75F, 'M', u'κ'), + (0x1D760, 'M', u'λ'), + (0x1D761, 'M', u'μ'), + (0x1D762, 'M', u'ν'), + (0x1D763, 'M', u'ξ'), + (0x1D764, 'M', u'ο'), + (0x1D765, 'M', u'π'), + (0x1D766, 'M', u'ρ'), + (0x1D767, 'M', u'θ'), + (0x1D768, 'M', u'σ'), + (0x1D769, 'M', u'τ'), + (0x1D76A, 'M', u'υ'), + (0x1D76B, 'M', u'φ'), + (0x1D76C, 'M', u'χ'), + (0x1D76D, 'M', u'ψ'), + (0x1D76E, 'M', u'ω'), + (0x1D76F, 'M', u'∇'), + (0x1D770, 'M', u'α'), + (0x1D771, 'M', u'β'), + (0x1D772, 'M', u'γ'), + (0x1D773, 'M', u'δ'), + (0x1D774, 'M', u'ε'), + (0x1D775, 'M', u'ζ'), + (0x1D776, 'M', u'η'), + (0x1D777, 'M', u'θ'), + (0x1D778, 'M', u'ι'), + (0x1D779, 'M', u'κ'), + (0x1D77A, 'M', u'λ'), + (0x1D77B, 'M', u'μ'), + (0x1D77C, 'M', u'ν'), + (0x1D77D, 'M', u'ξ'), + (0x1D77E, 'M', u'ο'), + (0x1D77F, 'M', u'π'), + (0x1D780, 'M', u'ρ'), + (0x1D781, 'M', u'σ'), + (0x1D783, 'M', u'τ'), + (0x1D784, 'M', u'υ'), + (0x1D785, 'M', u'φ'), + (0x1D786, 'M', u'χ'), + (0x1D787, 'M', u'ψ'), + (0x1D788, 'M', u'ω'), + (0x1D789, 'M', u'∂'), + (0x1D78A, 'M', u'ε'), + (0x1D78B, 'M', u'θ'), + (0x1D78C, 'M', u'κ'), + (0x1D78D, 'M', u'φ'), + (0x1D78E, 'M', u'ρ'), + (0x1D78F, 'M', u'π'), + (0x1D790, 'M', u'α'), + (0x1D791, 'M', u'β'), + (0x1D792, 'M', u'γ'), + (0x1D793, 'M', u'δ'), + (0x1D794, 'M', u'ε'), + ] + +def _seg_67(): + return [ + (0x1D795, 'M', u'ζ'), + (0x1D796, 'M', u'η'), + (0x1D797, 'M', u'θ'), + (0x1D798, 'M', u'ι'), + (0x1D799, 'M', u'κ'), + (0x1D79A, 'M', u'λ'), + (0x1D79B, 'M', u'μ'), + (0x1D79C, 'M', u'ν'), + (0x1D79D, 'M', u'ξ'), + (0x1D79E, 'M', u'ο'), + (0x1D79F, 'M', u'π'), + (0x1D7A0, 'M', u'ρ'), + (0x1D7A1, 'M', u'θ'), + (0x1D7A2, 'M', u'σ'), + (0x1D7A3, 'M', u'τ'), + (0x1D7A4, 'M', u'υ'), + (0x1D7A5, 'M', u'φ'), + (0x1D7A6, 'M', u'χ'), + (0x1D7A7, 'M', u'ψ'), + (0x1D7A8, 'M', u'ω'), + (0x1D7A9, 'M', u'∇'), + (0x1D7AA, 'M', u'α'), + (0x1D7AB, 'M', u'β'), + (0x1D7AC, 'M', u'γ'), + (0x1D7AD, 'M', u'δ'), + (0x1D7AE, 'M', u'ε'), + (0x1D7AF, 'M', u'ζ'), + (0x1D7B0, 'M', u'η'), + (0x1D7B1, 'M', u'θ'), + (0x1D7B2, 'M', u'ι'), + (0x1D7B3, 'M', u'κ'), + (0x1D7B4, 'M', u'λ'), + (0x1D7B5, 'M', u'μ'), + (0x1D7B6, 'M', u'ν'), + (0x1D7B7, 'M', u'ξ'), + (0x1D7B8, 'M', u'ο'), + (0x1D7B9, 'M', u'π'), + (0x1D7BA, 'M', u'ρ'), + (0x1D7BB, 'M', u'σ'), + (0x1D7BD, 'M', u'τ'), + (0x1D7BE, 'M', u'υ'), + (0x1D7BF, 'M', u'φ'), + (0x1D7C0, 'M', u'χ'), + (0x1D7C1, 'M', u'ψ'), + (0x1D7C2, 'M', u'ω'), + (0x1D7C3, 'M', u'∂'), + (0x1D7C4, 'M', u'ε'), + (0x1D7C5, 'M', u'θ'), + (0x1D7C6, 'M', u'κ'), + (0x1D7C7, 'M', u'φ'), + (0x1D7C8, 'M', u'ρ'), + (0x1D7C9, 'M', u'π'), + (0x1D7CA, 'M', u'ϝ'), + (0x1D7CC, 'X'), + (0x1D7CE, 'M', u'0'), + (0x1D7CF, 'M', u'1'), + (0x1D7D0, 'M', u'2'), + (0x1D7D1, 'M', u'3'), + (0x1D7D2, 'M', u'4'), + (0x1D7D3, 'M', u'5'), + (0x1D7D4, 'M', u'6'), + (0x1D7D5, 'M', u'7'), + (0x1D7D6, 'M', u'8'), + (0x1D7D7, 'M', u'9'), + (0x1D7D8, 'M', u'0'), + (0x1D7D9, 'M', u'1'), + (0x1D7DA, 'M', u'2'), + (0x1D7DB, 'M', u'3'), + (0x1D7DC, 'M', u'4'), + (0x1D7DD, 'M', u'5'), + (0x1D7DE, 'M', u'6'), + (0x1D7DF, 'M', u'7'), + (0x1D7E0, 'M', u'8'), + (0x1D7E1, 'M', u'9'), + (0x1D7E2, 'M', u'0'), + (0x1D7E3, 'M', u'1'), + (0x1D7E4, 'M', u'2'), + (0x1D7E5, 'M', u'3'), + (0x1D7E6, 'M', u'4'), + (0x1D7E7, 'M', u'5'), + (0x1D7E8, 'M', u'6'), + (0x1D7E9, 'M', u'7'), + (0x1D7EA, 'M', u'8'), + (0x1D7EB, 'M', u'9'), + (0x1D7EC, 'M', u'0'), + (0x1D7ED, 'M', u'1'), + (0x1D7EE, 'M', u'2'), + (0x1D7EF, 'M', u'3'), + (0x1D7F0, 'M', u'4'), + (0x1D7F1, 'M', u'5'), + (0x1D7F2, 'M', u'6'), + (0x1D7F3, 'M', u'7'), + (0x1D7F4, 'M', u'8'), + (0x1D7F5, 'M', u'9'), + (0x1D7F6, 'M', u'0'), + (0x1D7F7, 'M', u'1'), + (0x1D7F8, 'M', u'2'), + (0x1D7F9, 'M', u'3'), + (0x1D7FA, 'M', u'4'), + (0x1D7FB, 'M', u'5'), + ] + +def _seg_68(): + return [ + (0x1D7FC, 'M', u'6'), + (0x1D7FD, 'M', u'7'), + (0x1D7FE, 'M', u'8'), + (0x1D7FF, 'M', u'9'), + (0x1D800, 'V'), + (0x1DA8C, 'X'), + (0x1DA9B, 'V'), + (0x1DAA0, 'X'), + (0x1DAA1, 'V'), + (0x1DAB0, 'X'), + (0x1E000, 'V'), + (0x1E007, 'X'), + (0x1E008, 'V'), + (0x1E019, 'X'), + (0x1E01B, 'V'), + (0x1E022, 'X'), + (0x1E023, 'V'), + (0x1E025, 'X'), + (0x1E026, 'V'), + (0x1E02B, 'X'), + (0x1E800, 'V'), + (0x1E8C5, 'X'), + (0x1E8C7, 'V'), + (0x1E8D7, 'X'), + (0x1E900, 'M', u'𞤢'), + (0x1E901, 'M', u'𞤣'), + (0x1E902, 'M', u'𞤤'), + (0x1E903, 'M', u'𞤥'), + (0x1E904, 'M', u'𞤦'), + (0x1E905, 'M', u'𞤧'), + (0x1E906, 'M', u'𞤨'), + (0x1E907, 'M', u'𞤩'), + (0x1E908, 'M', u'𞤪'), + (0x1E909, 'M', u'𞤫'), + (0x1E90A, 'M', u'𞤬'), + (0x1E90B, 'M', u'𞤭'), + (0x1E90C, 'M', u'𞤮'), + (0x1E90D, 'M', u'𞤯'), + (0x1E90E, 'M', u'𞤰'), + (0x1E90F, 'M', u'𞤱'), + (0x1E910, 'M', u'𞤲'), + (0x1E911, 'M', u'𞤳'), + (0x1E912, 'M', u'𞤴'), + (0x1E913, 'M', u'𞤵'), + (0x1E914, 'M', u'𞤶'), + (0x1E915, 'M', u'𞤷'), + (0x1E916, 'M', u'𞤸'), + (0x1E917, 'M', u'𞤹'), + (0x1E918, 'M', u'𞤺'), + (0x1E919, 'M', u'𞤻'), + (0x1E91A, 'M', u'𞤼'), + (0x1E91B, 'M', u'𞤽'), + (0x1E91C, 'M', u'𞤾'), + (0x1E91D, 'M', u'𞤿'), + (0x1E91E, 'M', u'𞥀'), + (0x1E91F, 'M', u'𞥁'), + (0x1E920, 'M', u'𞥂'), + (0x1E921, 'M', u'𞥃'), + (0x1E922, 'V'), + (0x1E94B, 'X'), + (0x1E950, 'V'), + (0x1E95A, 'X'), + (0x1E95E, 'V'), + (0x1E960, 'X'), + (0x1EE00, 'M', u'ا'), + (0x1EE01, 'M', u'ب'), + (0x1EE02, 'M', u'ج'), + (0x1EE03, 'M', u'د'), + (0x1EE04, 'X'), + (0x1EE05, 'M', u'و'), + (0x1EE06, 'M', u'ز'), + (0x1EE07, 'M', u'ح'), + (0x1EE08, 'M', u'ط'), + (0x1EE09, 'M', u'ي'), + (0x1EE0A, 'M', u'ك'), + (0x1EE0B, 'M', u'ل'), + (0x1EE0C, 'M', u'م'), + (0x1EE0D, 'M', u'ن'), + (0x1EE0E, 'M', u'س'), + (0x1EE0F, 'M', u'ع'), + (0x1EE10, 'M', u'ف'), + (0x1EE11, 'M', u'ص'), + (0x1EE12, 'M', u'ق'), + (0x1EE13, 'M', u'ر'), + (0x1EE14, 'M', u'ش'), + (0x1EE15, 'M', u'ت'), + (0x1EE16, 'M', u'ث'), + (0x1EE17, 'M', u'خ'), + (0x1EE18, 'M', u'ذ'), + (0x1EE19, 'M', u'ض'), + (0x1EE1A, 'M', u'ظ'), + (0x1EE1B, 'M', u'غ'), + (0x1EE1C, 'M', u'ٮ'), + (0x1EE1D, 'M', u'ں'), + (0x1EE1E, 'M', u'ڡ'), + (0x1EE1F, 'M', u'ٯ'), + (0x1EE20, 'X'), + (0x1EE21, 'M', u'ب'), + (0x1EE22, 'M', u'ج'), + (0x1EE23, 'X'), + ] + +def _seg_69(): + return [ + (0x1EE24, 'M', u'ه'), + (0x1EE25, 'X'), + (0x1EE27, 'M', u'ح'), + (0x1EE28, 'X'), + (0x1EE29, 'M', u'ي'), + (0x1EE2A, 'M', u'ك'), + (0x1EE2B, 'M', u'ل'), + (0x1EE2C, 'M', u'م'), + (0x1EE2D, 'M', u'ن'), + (0x1EE2E, 'M', u'س'), + (0x1EE2F, 'M', u'ع'), + (0x1EE30, 'M', u'ف'), + (0x1EE31, 'M', u'ص'), + (0x1EE32, 'M', u'ق'), + (0x1EE33, 'X'), + (0x1EE34, 'M', u'ش'), + (0x1EE35, 'M', u'ت'), + (0x1EE36, 'M', u'ث'), + (0x1EE37, 'M', u'خ'), + (0x1EE38, 'X'), + (0x1EE39, 'M', u'ض'), + (0x1EE3A, 'X'), + (0x1EE3B, 'M', u'غ'), + (0x1EE3C, 'X'), + (0x1EE42, 'M', u'ج'), + (0x1EE43, 'X'), + (0x1EE47, 'M', u'ح'), + (0x1EE48, 'X'), + (0x1EE49, 'M', u'ي'), + (0x1EE4A, 'X'), + (0x1EE4B, 'M', u'ل'), + (0x1EE4C, 'X'), + (0x1EE4D, 'M', u'ن'), + (0x1EE4E, 'M', u'س'), + (0x1EE4F, 'M', u'ع'), + (0x1EE50, 'X'), + (0x1EE51, 'M', u'ص'), + (0x1EE52, 'M', u'ق'), + (0x1EE53, 'X'), + (0x1EE54, 'M', u'ش'), + (0x1EE55, 'X'), + (0x1EE57, 'M', u'خ'), + (0x1EE58, 'X'), + (0x1EE59, 'M', u'ض'), + (0x1EE5A, 'X'), + (0x1EE5B, 'M', u'غ'), + (0x1EE5C, 'X'), + (0x1EE5D, 'M', u'ں'), + (0x1EE5E, 'X'), + (0x1EE5F, 'M', u'ٯ'), + (0x1EE60, 'X'), + (0x1EE61, 'M', u'ب'), + (0x1EE62, 'M', u'ج'), + (0x1EE63, 'X'), + (0x1EE64, 'M', u'ه'), + (0x1EE65, 'X'), + (0x1EE67, 'M', u'ح'), + (0x1EE68, 'M', u'ط'), + (0x1EE69, 'M', u'ي'), + (0x1EE6A, 'M', u'ك'), + (0x1EE6B, 'X'), + (0x1EE6C, 'M', u'م'), + (0x1EE6D, 'M', u'ن'), + (0x1EE6E, 'M', u'س'), + (0x1EE6F, 'M', u'ع'), + (0x1EE70, 'M', u'ف'), + (0x1EE71, 'M', u'ص'), + (0x1EE72, 'M', u'ق'), + (0x1EE73, 'X'), + (0x1EE74, 'M', u'ش'), + (0x1EE75, 'M', u'ت'), + (0x1EE76, 'M', u'ث'), + (0x1EE77, 'M', u'خ'), + (0x1EE78, 'X'), + (0x1EE79, 'M', u'ض'), + (0x1EE7A, 'M', u'ظ'), + (0x1EE7B, 'M', u'غ'), + (0x1EE7C, 'M', u'ٮ'), + (0x1EE7D, 'X'), + (0x1EE7E, 'M', u'ڡ'), + (0x1EE7F, 'X'), + (0x1EE80, 'M', u'ا'), + (0x1EE81, 'M', u'ب'), + (0x1EE82, 'M', u'ج'), + (0x1EE83, 'M', u'د'), + (0x1EE84, 'M', u'ه'), + (0x1EE85, 'M', u'و'), + (0x1EE86, 'M', u'ز'), + (0x1EE87, 'M', u'ح'), + (0x1EE88, 'M', u'ط'), + (0x1EE89, 'M', u'ي'), + (0x1EE8A, 'X'), + (0x1EE8B, 'M', u'ل'), + (0x1EE8C, 'M', u'م'), + (0x1EE8D, 'M', u'ن'), + (0x1EE8E, 'M', u'س'), + (0x1EE8F, 'M', u'ع'), + (0x1EE90, 'M', u'ف'), + (0x1EE91, 'M', u'ص'), + (0x1EE92, 'M', u'ق'), + ] + +def _seg_70(): + return [ + (0x1EE93, 'M', u'ر'), + (0x1EE94, 'M', u'ش'), + (0x1EE95, 'M', u'ت'), + (0x1EE96, 'M', u'ث'), + (0x1EE97, 'M', u'خ'), + (0x1EE98, 'M', u'ذ'), + (0x1EE99, 'M', u'ض'), + (0x1EE9A, 'M', u'ظ'), + (0x1EE9B, 'M', u'غ'), + (0x1EE9C, 'X'), + (0x1EEA1, 'M', u'ب'), + (0x1EEA2, 'M', u'ج'), + (0x1EEA3, 'M', u'د'), + (0x1EEA4, 'X'), + (0x1EEA5, 'M', u'و'), + (0x1EEA6, 'M', u'ز'), + (0x1EEA7, 'M', u'ح'), + (0x1EEA8, 'M', u'ط'), + (0x1EEA9, 'M', u'ي'), + (0x1EEAA, 'X'), + (0x1EEAB, 'M', u'ل'), + (0x1EEAC, 'M', u'م'), + (0x1EEAD, 'M', u'ن'), + (0x1EEAE, 'M', u'س'), + (0x1EEAF, 'M', u'ع'), + (0x1EEB0, 'M', u'ف'), + (0x1EEB1, 'M', u'ص'), + (0x1EEB2, 'M', u'ق'), + (0x1EEB3, 'M', u'ر'), + (0x1EEB4, 'M', u'ش'), + (0x1EEB5, 'M', u'ت'), + (0x1EEB6, 'M', u'ث'), + (0x1EEB7, 'M', u'خ'), + (0x1EEB8, 'M', u'ذ'), + (0x1EEB9, 'M', u'ض'), + (0x1EEBA, 'M', u'ظ'), + (0x1EEBB, 'M', u'غ'), + (0x1EEBC, 'X'), + (0x1EEF0, 'V'), + (0x1EEF2, 'X'), + (0x1F000, 'V'), + (0x1F02C, 'X'), + (0x1F030, 'V'), + (0x1F094, 'X'), + (0x1F0A0, 'V'), + (0x1F0AF, 'X'), + (0x1F0B1, 'V'), + (0x1F0C0, 'X'), + (0x1F0C1, 'V'), + (0x1F0D0, 'X'), + (0x1F0D1, 'V'), + (0x1F0F6, 'X'), + (0x1F101, '3', u'0,'), + (0x1F102, '3', u'1,'), + (0x1F103, '3', u'2,'), + (0x1F104, '3', u'3,'), + (0x1F105, '3', u'4,'), + (0x1F106, '3', u'5,'), + (0x1F107, '3', u'6,'), + (0x1F108, '3', u'7,'), + (0x1F109, '3', u'8,'), + (0x1F10A, '3', u'9,'), + (0x1F10B, 'V'), + (0x1F10D, 'X'), + (0x1F110, '3', u'(a)'), + (0x1F111, '3', u'(b)'), + (0x1F112, '3', u'(c)'), + (0x1F113, '3', u'(d)'), + (0x1F114, '3', u'(e)'), + (0x1F115, '3', u'(f)'), + (0x1F116, '3', u'(g)'), + (0x1F117, '3', u'(h)'), + (0x1F118, '3', u'(i)'), + (0x1F119, '3', u'(j)'), + (0x1F11A, '3', u'(k)'), + (0x1F11B, '3', u'(l)'), + (0x1F11C, '3', u'(m)'), + (0x1F11D, '3', u'(n)'), + (0x1F11E, '3', u'(o)'), + (0x1F11F, '3', u'(p)'), + (0x1F120, '3', u'(q)'), + (0x1F121, '3', u'(r)'), + (0x1F122, '3', u'(s)'), + (0x1F123, '3', u'(t)'), + (0x1F124, '3', u'(u)'), + (0x1F125, '3', u'(v)'), + (0x1F126, '3', u'(w)'), + (0x1F127, '3', u'(x)'), + (0x1F128, '3', u'(y)'), + (0x1F129, '3', u'(z)'), + (0x1F12A, 'M', u'〔s〕'), + (0x1F12B, 'M', u'c'), + (0x1F12C, 'M', u'r'), + (0x1F12D, 'M', u'cd'), + (0x1F12E, 'M', u'wz'), + (0x1F12F, 'X'), + (0x1F130, 'M', u'a'), + (0x1F131, 'M', u'b'), + (0x1F132, 'M', u'c'), + (0x1F133, 'M', u'd'), + ] + +def _seg_71(): + return [ + (0x1F134, 'M', u'e'), + (0x1F135, 'M', u'f'), + (0x1F136, 'M', u'g'), + (0x1F137, 'M', u'h'), + (0x1F138, 'M', u'i'), + (0x1F139, 'M', u'j'), + (0x1F13A, 'M', u'k'), + (0x1F13B, 'M', u'l'), + (0x1F13C, 'M', u'm'), + (0x1F13D, 'M', u'n'), + (0x1F13E, 'M', u'o'), + (0x1F13F, 'M', u'p'), + (0x1F140, 'M', u'q'), + (0x1F141, 'M', u'r'), + (0x1F142, 'M', u's'), + (0x1F143, 'M', u't'), + (0x1F144, 'M', u'u'), + (0x1F145, 'M', u'v'), + (0x1F146, 'M', u'w'), + (0x1F147, 'M', u'x'), + (0x1F148, 'M', u'y'), + (0x1F149, 'M', u'z'), + (0x1F14A, 'M', u'hv'), + (0x1F14B, 'M', u'mv'), + (0x1F14C, 'M', u'sd'), + (0x1F14D, 'M', u'ss'), + (0x1F14E, 'M', u'ppv'), + (0x1F14F, 'M', u'wc'), + (0x1F150, 'V'), + (0x1F16A, 'M', u'mc'), + (0x1F16B, 'M', u'md'), + (0x1F16C, 'X'), + (0x1F170, 'V'), + (0x1F190, 'M', u'dj'), + (0x1F191, 'V'), + (0x1F1AD, 'X'), + (0x1F1E6, 'V'), + (0x1F200, 'M', u'ほか'), + (0x1F201, 'M', u'ココ'), + (0x1F202, 'M', u'サ'), + (0x1F203, 'X'), + (0x1F210, 'M', u'手'), + (0x1F211, 'M', u'字'), + (0x1F212, 'M', u'双'), + (0x1F213, 'M', u'デ'), + (0x1F214, 'M', u'二'), + (0x1F215, 'M', u'多'), + (0x1F216, 'M', u'解'), + (0x1F217, 'M', u'天'), + (0x1F218, 'M', u'交'), + (0x1F219, 'M', u'映'), + (0x1F21A, 'M', u'無'), + (0x1F21B, 'M', u'料'), + (0x1F21C, 'M', u'前'), + (0x1F21D, 'M', u'後'), + (0x1F21E, 'M', u'再'), + (0x1F21F, 'M', u'新'), + (0x1F220, 'M', u'初'), + (0x1F221, 'M', u'終'), + (0x1F222, 'M', u'生'), + (0x1F223, 'M', u'販'), + (0x1F224, 'M', u'声'), + (0x1F225, 'M', u'吹'), + (0x1F226, 'M', u'演'), + (0x1F227, 'M', u'投'), + (0x1F228, 'M', u'捕'), + (0x1F229, 'M', u'一'), + (0x1F22A, 'M', u'三'), + (0x1F22B, 'M', u'遊'), + (0x1F22C, 'M', u'左'), + (0x1F22D, 'M', u'中'), + (0x1F22E, 'M', u'右'), + (0x1F22F, 'M', u'指'), + (0x1F230, 'M', u'走'), + (0x1F231, 'M', u'打'), + (0x1F232, 'M', u'禁'), + (0x1F233, 'M', u'空'), + (0x1F234, 'M', u'合'), + (0x1F235, 'M', u'満'), + (0x1F236, 'M', u'有'), + (0x1F237, 'M', u'月'), + (0x1F238, 'M', u'申'), + (0x1F239, 'M', u'割'), + (0x1F23A, 'M', u'営'), + (0x1F23B, 'M', u'配'), + (0x1F23C, 'X'), + (0x1F240, 'M', u'〔本〕'), + (0x1F241, 'M', u'〔三〕'), + (0x1F242, 'M', u'〔二〕'), + (0x1F243, 'M', u'〔安〕'), + (0x1F244, 'M', u'〔点〕'), + (0x1F245, 'M', u'〔打〕'), + (0x1F246, 'M', u'〔盗〕'), + (0x1F247, 'M', u'〔勝〕'), + (0x1F248, 'M', u'〔敗〕'), + (0x1F249, 'X'), + (0x1F250, 'M', u'得'), + (0x1F251, 'M', u'可'), + (0x1F252, 'X'), + (0x1F260, 'V'), + ] + +def _seg_72(): + return [ + (0x1F266, 'X'), + (0x1F300, 'V'), + (0x1F6D5, 'X'), + (0x1F6E0, 'V'), + (0x1F6ED, 'X'), + (0x1F6F0, 'V'), + (0x1F6F9, 'X'), + (0x1F700, 'V'), + (0x1F774, 'X'), + (0x1F780, 'V'), + (0x1F7D5, 'X'), + (0x1F800, 'V'), + (0x1F80C, 'X'), + (0x1F810, 'V'), + (0x1F848, 'X'), + (0x1F850, 'V'), + (0x1F85A, 'X'), + (0x1F860, 'V'), + (0x1F888, 'X'), + (0x1F890, 'V'), + (0x1F8AE, 'X'), + (0x1F900, 'V'), + (0x1F90C, 'X'), + (0x1F910, 'V'), + (0x1F93F, 'X'), + (0x1F940, 'V'), + (0x1F94D, 'X'), + (0x1F950, 'V'), + (0x1F96C, 'X'), + (0x1F980, 'V'), + (0x1F998, 'X'), + (0x1F9C0, 'V'), + (0x1F9C1, 'X'), + (0x1F9D0, 'V'), + (0x1F9E7, 'X'), + (0x20000, 'V'), + (0x2A6D7, 'X'), + (0x2A700, 'V'), + (0x2B735, 'X'), + (0x2B740, 'V'), + (0x2B81E, 'X'), + (0x2B820, 'V'), + (0x2CEA2, 'X'), + (0x2CEB0, 'V'), + (0x2EBE1, 'X'), + (0x2F800, 'M', u'丽'), + (0x2F801, 'M', u'丸'), + (0x2F802, 'M', u'乁'), + (0x2F803, 'M', u'𠄢'), + (0x2F804, 'M', u'你'), + (0x2F805, 'M', u'侮'), + (0x2F806, 'M', u'侻'), + (0x2F807, 'M', u'倂'), + (0x2F808, 'M', u'偺'), + (0x2F809, 'M', u'備'), + (0x2F80A, 'M', u'僧'), + (0x2F80B, 'M', u'像'), + (0x2F80C, 'M', u'㒞'), + (0x2F80D, 'M', u'𠘺'), + (0x2F80E, 'M', u'免'), + (0x2F80F, 'M', u'兔'), + (0x2F810, 'M', u'兤'), + (0x2F811, 'M', u'具'), + (0x2F812, 'M', u'𠔜'), + (0x2F813, 'M', u'㒹'), + (0x2F814, 'M', u'內'), + (0x2F815, 'M', u'再'), + (0x2F816, 'M', u'𠕋'), + (0x2F817, 'M', u'冗'), + (0x2F818, 'M', u'冤'), + (0x2F819, 'M', u'仌'), + (0x2F81A, 'M', u'冬'), + (0x2F81B, 'M', u'况'), + (0x2F81C, 'M', u'𩇟'), + (0x2F81D, 'M', u'凵'), + (0x2F81E, 'M', u'刃'), + (0x2F81F, 'M', u'㓟'), + (0x2F820, 'M', u'刻'), + (0x2F821, 'M', u'剆'), + (0x2F822, 'M', u'割'), + (0x2F823, 'M', u'剷'), + (0x2F824, 'M', u'㔕'), + (0x2F825, 'M', u'勇'), + (0x2F826, 'M', u'勉'), + (0x2F827, 'M', u'勤'), + (0x2F828, 'M', u'勺'), + (0x2F829, 'M', u'包'), + (0x2F82A, 'M', u'匆'), + (0x2F82B, 'M', u'北'), + (0x2F82C, 'M', u'卉'), + (0x2F82D, 'M', u'卑'), + (0x2F82E, 'M', u'博'), + (0x2F82F, 'M', u'即'), + (0x2F830, 'M', u'卽'), + (0x2F831, 'M', u'卿'), + (0x2F834, 'M', u'𠨬'), + (0x2F835, 'M', u'灰'), + (0x2F836, 'M', u'及'), + (0x2F837, 'M', u'叟'), + (0x2F838, 'M', u'𠭣'), + ] + +def _seg_73(): + return [ + (0x2F839, 'M', u'叫'), + (0x2F83A, 'M', u'叱'), + (0x2F83B, 'M', u'吆'), + (0x2F83C, 'M', u'咞'), + (0x2F83D, 'M', u'吸'), + (0x2F83E, 'M', u'呈'), + (0x2F83F, 'M', u'周'), + (0x2F840, 'M', u'咢'), + (0x2F841, 'M', u'哶'), + (0x2F842, 'M', u'唐'), + (0x2F843, 'M', u'啓'), + (0x2F844, 'M', u'啣'), + (0x2F845, 'M', u'善'), + (0x2F847, 'M', u'喙'), + (0x2F848, 'M', u'喫'), + (0x2F849, 'M', u'喳'), + (0x2F84A, 'M', u'嗂'), + (0x2F84B, 'M', u'圖'), + (0x2F84C, 'M', u'嘆'), + (0x2F84D, 'M', u'圗'), + (0x2F84E, 'M', u'噑'), + (0x2F84F, 'M', u'噴'), + (0x2F850, 'M', u'切'), + (0x2F851, 'M', u'壮'), + (0x2F852, 'M', u'城'), + (0x2F853, 'M', u'埴'), + (0x2F854, 'M', u'堍'), + (0x2F855, 'M', u'型'), + (0x2F856, 'M', u'堲'), + (0x2F857, 'M', u'報'), + (0x2F858, 'M', u'墬'), + (0x2F859, 'M', u'𡓤'), + (0x2F85A, 'M', u'売'), + (0x2F85B, 'M', u'壷'), + (0x2F85C, 'M', u'夆'), + (0x2F85D, 'M', u'多'), + (0x2F85E, 'M', u'夢'), + (0x2F85F, 'M', u'奢'), + (0x2F860, 'M', u'𡚨'), + (0x2F861, 'M', u'𡛪'), + (0x2F862, 'M', u'姬'), + (0x2F863, 'M', u'娛'), + (0x2F864, 'M', u'娧'), + (0x2F865, 'M', u'姘'), + (0x2F866, 'M', u'婦'), + (0x2F867, 'M', u'㛮'), + (0x2F868, 'X'), + (0x2F869, 'M', u'嬈'), + (0x2F86A, 'M', u'嬾'), + (0x2F86C, 'M', u'𡧈'), + (0x2F86D, 'M', u'寃'), + (0x2F86E, 'M', u'寘'), + (0x2F86F, 'M', u'寧'), + (0x2F870, 'M', u'寳'), + (0x2F871, 'M', u'𡬘'), + (0x2F872, 'M', u'寿'), + (0x2F873, 'M', u'将'), + (0x2F874, 'X'), + (0x2F875, 'M', u'尢'), + (0x2F876, 'M', u'㞁'), + (0x2F877, 'M', u'屠'), + (0x2F878, 'M', u'屮'), + (0x2F879, 'M', u'峀'), + (0x2F87A, 'M', u'岍'), + (0x2F87B, 'M', u'𡷤'), + (0x2F87C, 'M', u'嵃'), + (0x2F87D, 'M', u'𡷦'), + (0x2F87E, 'M', u'嵮'), + (0x2F87F, 'M', u'嵫'), + (0x2F880, 'M', u'嵼'), + (0x2F881, 'M', u'巡'), + (0x2F882, 'M', u'巢'), + (0x2F883, 'M', u'㠯'), + (0x2F884, 'M', u'巽'), + (0x2F885, 'M', u'帨'), + (0x2F886, 'M', u'帽'), + (0x2F887, 'M', u'幩'), + (0x2F888, 'M', u'㡢'), + (0x2F889, 'M', u'𢆃'), + (0x2F88A, 'M', u'㡼'), + (0x2F88B, 'M', u'庰'), + (0x2F88C, 'M', u'庳'), + (0x2F88D, 'M', u'庶'), + (0x2F88E, 'M', u'廊'), + (0x2F88F, 'M', u'𪎒'), + (0x2F890, 'M', u'廾'), + (0x2F891, 'M', u'𢌱'), + (0x2F893, 'M', u'舁'), + (0x2F894, 'M', u'弢'), + (0x2F896, 'M', u'㣇'), + (0x2F897, 'M', u'𣊸'), + (0x2F898, 'M', u'𦇚'), + (0x2F899, 'M', u'形'), + (0x2F89A, 'M', u'彫'), + (0x2F89B, 'M', u'㣣'), + (0x2F89C, 'M', u'徚'), + (0x2F89D, 'M', u'忍'), + (0x2F89E, 'M', u'志'), + (0x2F89F, 'M', u'忹'), + (0x2F8A0, 'M', u'悁'), + ] + +def _seg_74(): + return [ + (0x2F8A1, 'M', u'㤺'), + (0x2F8A2, 'M', u'㤜'), + (0x2F8A3, 'M', u'悔'), + (0x2F8A4, 'M', u'𢛔'), + (0x2F8A5, 'M', u'惇'), + (0x2F8A6, 'M', u'慈'), + (0x2F8A7, 'M', u'慌'), + (0x2F8A8, 'M', u'慎'), + (0x2F8A9, 'M', u'慌'), + (0x2F8AA, 'M', u'慺'), + (0x2F8AB, 'M', u'憎'), + (0x2F8AC, 'M', u'憲'), + (0x2F8AD, 'M', u'憤'), + (0x2F8AE, 'M', u'憯'), + (0x2F8AF, 'M', u'懞'), + (0x2F8B0, 'M', u'懲'), + (0x2F8B1, 'M', u'懶'), + (0x2F8B2, 'M', u'成'), + (0x2F8B3, 'M', u'戛'), + (0x2F8B4, 'M', u'扝'), + (0x2F8B5, 'M', u'抱'), + (0x2F8B6, 'M', u'拔'), + (0x2F8B7, 'M', u'捐'), + (0x2F8B8, 'M', u'𢬌'), + (0x2F8B9, 'M', u'挽'), + (0x2F8BA, 'M', u'拼'), + (0x2F8BB, 'M', u'捨'), + (0x2F8BC, 'M', u'掃'), + (0x2F8BD, 'M', u'揤'), + (0x2F8BE, 'M', u'𢯱'), + (0x2F8BF, 'M', u'搢'), + (0x2F8C0, 'M', u'揅'), + (0x2F8C1, 'M', u'掩'), + (0x2F8C2, 'M', u'㨮'), + (0x2F8C3, 'M', u'摩'), + (0x2F8C4, 'M', u'摾'), + (0x2F8C5, 'M', u'撝'), + (0x2F8C6, 'M', u'摷'), + (0x2F8C7, 'M', u'㩬'), + (0x2F8C8, 'M', u'敏'), + (0x2F8C9, 'M', u'敬'), + (0x2F8CA, 'M', u'𣀊'), + (0x2F8CB, 'M', u'旣'), + (0x2F8CC, 'M', u'書'), + (0x2F8CD, 'M', u'晉'), + (0x2F8CE, 'M', u'㬙'), + (0x2F8CF, 'M', u'暑'), + (0x2F8D0, 'M', u'㬈'), + (0x2F8D1, 'M', u'㫤'), + (0x2F8D2, 'M', u'冒'), + (0x2F8D3, 'M', u'冕'), + (0x2F8D4, 'M', u'最'), + (0x2F8D5, 'M', u'暜'), + (0x2F8D6, 'M', u'肭'), + (0x2F8D7, 'M', u'䏙'), + (0x2F8D8, 'M', u'朗'), + (0x2F8D9, 'M', u'望'), + (0x2F8DA, 'M', u'朡'), + (0x2F8DB, 'M', u'杞'), + (0x2F8DC, 'M', u'杓'), + (0x2F8DD, 'M', u'𣏃'), + (0x2F8DE, 'M', u'㭉'), + (0x2F8DF, 'M', u'柺'), + (0x2F8E0, 'M', u'枅'), + (0x2F8E1, 'M', u'桒'), + (0x2F8E2, 'M', u'梅'), + (0x2F8E3, 'M', u'𣑭'), + (0x2F8E4, 'M', u'梎'), + (0x2F8E5, 'M', u'栟'), + (0x2F8E6, 'M', u'椔'), + (0x2F8E7, 'M', u'㮝'), + (0x2F8E8, 'M', u'楂'), + (0x2F8E9, 'M', u'榣'), + (0x2F8EA, 'M', u'槪'), + (0x2F8EB, 'M', u'檨'), + (0x2F8EC, 'M', u'𣚣'), + (0x2F8ED, 'M', u'櫛'), + (0x2F8EE, 'M', u'㰘'), + (0x2F8EF, 'M', u'次'), + (0x2F8F0, 'M', u'𣢧'), + (0x2F8F1, 'M', u'歔'), + (0x2F8F2, 'M', u'㱎'), + (0x2F8F3, 'M', u'歲'), + (0x2F8F4, 'M', u'殟'), + (0x2F8F5, 'M', u'殺'), + (0x2F8F6, 'M', u'殻'), + (0x2F8F7, 'M', u'𣪍'), + (0x2F8F8, 'M', u'𡴋'), + (0x2F8F9, 'M', u'𣫺'), + (0x2F8FA, 'M', u'汎'), + (0x2F8FB, 'M', u'𣲼'), + (0x2F8FC, 'M', u'沿'), + (0x2F8FD, 'M', u'泍'), + (0x2F8FE, 'M', u'汧'), + (0x2F8FF, 'M', u'洖'), + (0x2F900, 'M', u'派'), + (0x2F901, 'M', u'海'), + (0x2F902, 'M', u'流'), + (0x2F903, 'M', u'浩'), + (0x2F904, 'M', u'浸'), + ] + +def _seg_75(): + return [ + (0x2F905, 'M', u'涅'), + (0x2F906, 'M', u'𣴞'), + (0x2F907, 'M', u'洴'), + (0x2F908, 'M', u'港'), + (0x2F909, 'M', u'湮'), + (0x2F90A, 'M', u'㴳'), + (0x2F90B, 'M', u'滋'), + (0x2F90C, 'M', u'滇'), + (0x2F90D, 'M', u'𣻑'), + (0x2F90E, 'M', u'淹'), + (0x2F90F, 'M', u'潮'), + (0x2F910, 'M', u'𣽞'), + (0x2F911, 'M', u'𣾎'), + (0x2F912, 'M', u'濆'), + (0x2F913, 'M', u'瀹'), + (0x2F914, 'M', u'瀞'), + (0x2F915, 'M', u'瀛'), + (0x2F916, 'M', u'㶖'), + (0x2F917, 'M', u'灊'), + (0x2F918, 'M', u'災'), + (0x2F919, 'M', u'灷'), + (0x2F91A, 'M', u'炭'), + (0x2F91B, 'M', u'𠔥'), + (0x2F91C, 'M', u'煅'), + (0x2F91D, 'M', u'𤉣'), + (0x2F91E, 'M', u'熜'), + (0x2F91F, 'X'), + (0x2F920, 'M', u'爨'), + (0x2F921, 'M', u'爵'), + (0x2F922, 'M', u'牐'), + (0x2F923, 'M', u'𤘈'), + (0x2F924, 'M', u'犀'), + (0x2F925, 'M', u'犕'), + (0x2F926, 'M', u'𤜵'), + (0x2F927, 'M', u'𤠔'), + (0x2F928, 'M', u'獺'), + (0x2F929, 'M', u'王'), + (0x2F92A, 'M', u'㺬'), + (0x2F92B, 'M', u'玥'), + (0x2F92C, 'M', u'㺸'), + (0x2F92E, 'M', u'瑇'), + (0x2F92F, 'M', u'瑜'), + (0x2F930, 'M', u'瑱'), + (0x2F931, 'M', u'璅'), + (0x2F932, 'M', u'瓊'), + (0x2F933, 'M', u'㼛'), + (0x2F934, 'M', u'甤'), + (0x2F935, 'M', u'𤰶'), + (0x2F936, 'M', u'甾'), + (0x2F937, 'M', u'𤲒'), + (0x2F938, 'M', u'異'), + (0x2F939, 'M', u'𢆟'), + (0x2F93A, 'M', u'瘐'), + (0x2F93B, 'M', u'𤾡'), + (0x2F93C, 'M', u'𤾸'), + (0x2F93D, 'M', u'𥁄'), + (0x2F93E, 'M', u'㿼'), + (0x2F93F, 'M', u'䀈'), + (0x2F940, 'M', u'直'), + (0x2F941, 'M', u'𥃳'), + (0x2F942, 'M', u'𥃲'), + (0x2F943, 'M', u'𥄙'), + (0x2F944, 'M', u'𥄳'), + (0x2F945, 'M', u'眞'), + (0x2F946, 'M', u'真'), + (0x2F948, 'M', u'睊'), + (0x2F949, 'M', u'䀹'), + (0x2F94A, 'M', u'瞋'), + (0x2F94B, 'M', u'䁆'), + (0x2F94C, 'M', u'䂖'), + (0x2F94D, 'M', u'𥐝'), + (0x2F94E, 'M', u'硎'), + (0x2F94F, 'M', u'碌'), + (0x2F950, 'M', u'磌'), + (0x2F951, 'M', u'䃣'), + (0x2F952, 'M', u'𥘦'), + (0x2F953, 'M', u'祖'), + (0x2F954, 'M', u'𥚚'), + (0x2F955, 'M', u'𥛅'), + (0x2F956, 'M', u'福'), + (0x2F957, 'M', u'秫'), + (0x2F958, 'M', u'䄯'), + (0x2F959, 'M', u'穀'), + (0x2F95A, 'M', u'穊'), + (0x2F95B, 'M', u'穏'), + (0x2F95C, 'M', u'𥥼'), + (0x2F95D, 'M', u'𥪧'), + (0x2F95F, 'X'), + (0x2F960, 'M', u'䈂'), + (0x2F961, 'M', u'𥮫'), + (0x2F962, 'M', u'篆'), + (0x2F963, 'M', u'築'), + (0x2F964, 'M', u'䈧'), + (0x2F965, 'M', u'𥲀'), + (0x2F966, 'M', u'糒'), + (0x2F967, 'M', u'䊠'), + (0x2F968, 'M', u'糨'), + (0x2F969, 'M', u'糣'), + (0x2F96A, 'M', u'紀'), + (0x2F96B, 'M', u'𥾆'), + ] + +def _seg_76(): + return [ + (0x2F96C, 'M', u'絣'), + (0x2F96D, 'M', u'䌁'), + (0x2F96E, 'M', u'緇'), + (0x2F96F, 'M', u'縂'), + (0x2F970, 'M', u'繅'), + (0x2F971, 'M', u'䌴'), + (0x2F972, 'M', u'𦈨'), + (0x2F973, 'M', u'𦉇'), + (0x2F974, 'M', u'䍙'), + (0x2F975, 'M', u'𦋙'), + (0x2F976, 'M', u'罺'), + (0x2F977, 'M', u'𦌾'), + (0x2F978, 'M', u'羕'), + (0x2F979, 'M', u'翺'), + (0x2F97A, 'M', u'者'), + (0x2F97B, 'M', u'𦓚'), + (0x2F97C, 'M', u'𦔣'), + (0x2F97D, 'M', u'聠'), + (0x2F97E, 'M', u'𦖨'), + (0x2F97F, 'M', u'聰'), + (0x2F980, 'M', u'𣍟'), + (0x2F981, 'M', u'䏕'), + (0x2F982, 'M', u'育'), + (0x2F983, 'M', u'脃'), + (0x2F984, 'M', u'䐋'), + (0x2F985, 'M', u'脾'), + (0x2F986, 'M', u'媵'), + (0x2F987, 'M', u'𦞧'), + (0x2F988, 'M', u'𦞵'), + (0x2F989, 'M', u'𣎓'), + (0x2F98A, 'M', u'𣎜'), + (0x2F98B, 'M', u'舁'), + (0x2F98C, 'M', u'舄'), + (0x2F98D, 'M', u'辞'), + (0x2F98E, 'M', u'䑫'), + (0x2F98F, 'M', u'芑'), + (0x2F990, 'M', u'芋'), + (0x2F991, 'M', u'芝'), + (0x2F992, 'M', u'劳'), + (0x2F993, 'M', u'花'), + (0x2F994, 'M', u'芳'), + (0x2F995, 'M', u'芽'), + (0x2F996, 'M', u'苦'), + (0x2F997, 'M', u'𦬼'), + (0x2F998, 'M', u'若'), + (0x2F999, 'M', u'茝'), + (0x2F99A, 'M', u'荣'), + (0x2F99B, 'M', u'莭'), + (0x2F99C, 'M', u'茣'), + (0x2F99D, 'M', u'莽'), + (0x2F99E, 'M', u'菧'), + (0x2F99F, 'M', u'著'), + (0x2F9A0, 'M', u'荓'), + (0x2F9A1, 'M', u'菊'), + (0x2F9A2, 'M', u'菌'), + (0x2F9A3, 'M', u'菜'), + (0x2F9A4, 'M', u'𦰶'), + (0x2F9A5, 'M', u'𦵫'), + (0x2F9A6, 'M', u'𦳕'), + (0x2F9A7, 'M', u'䔫'), + (0x2F9A8, 'M', u'蓱'), + (0x2F9A9, 'M', u'蓳'), + (0x2F9AA, 'M', u'蔖'), + (0x2F9AB, 'M', u'𧏊'), + (0x2F9AC, 'M', u'蕤'), + (0x2F9AD, 'M', u'𦼬'), + (0x2F9AE, 'M', u'䕝'), + (0x2F9AF, 'M', u'䕡'), + (0x2F9B0, 'M', u'𦾱'), + (0x2F9B1, 'M', u'𧃒'), + (0x2F9B2, 'M', u'䕫'), + (0x2F9B3, 'M', u'虐'), + (0x2F9B4, 'M', u'虜'), + (0x2F9B5, 'M', u'虧'), + (0x2F9B6, 'M', u'虩'), + (0x2F9B7, 'M', u'蚩'), + (0x2F9B8, 'M', u'蚈'), + (0x2F9B9, 'M', u'蜎'), + (0x2F9BA, 'M', u'蛢'), + (0x2F9BB, 'M', u'蝹'), + (0x2F9BC, 'M', u'蜨'), + (0x2F9BD, 'M', u'蝫'), + (0x2F9BE, 'M', u'螆'), + (0x2F9BF, 'X'), + (0x2F9C0, 'M', u'蟡'), + (0x2F9C1, 'M', u'蠁'), + (0x2F9C2, 'M', u'䗹'), + (0x2F9C3, 'M', u'衠'), + (0x2F9C4, 'M', u'衣'), + (0x2F9C5, 'M', u'𧙧'), + (0x2F9C6, 'M', u'裗'), + (0x2F9C7, 'M', u'裞'), + (0x2F9C8, 'M', u'䘵'), + (0x2F9C9, 'M', u'裺'), + (0x2F9CA, 'M', u'㒻'), + (0x2F9CB, 'M', u'𧢮'), + (0x2F9CC, 'M', u'𧥦'), + (0x2F9CD, 'M', u'䚾'), + (0x2F9CE, 'M', u'䛇'), + (0x2F9CF, 'M', u'誠'), + ] + +def _seg_77(): + return [ + (0x2F9D0, 'M', u'諭'), + (0x2F9D1, 'M', u'變'), + (0x2F9D2, 'M', u'豕'), + (0x2F9D3, 'M', u'𧲨'), + (0x2F9D4, 'M', u'貫'), + (0x2F9D5, 'M', u'賁'), + (0x2F9D6, 'M', u'贛'), + (0x2F9D7, 'M', u'起'), + (0x2F9D8, 'M', u'𧼯'), + (0x2F9D9, 'M', u'𠠄'), + (0x2F9DA, 'M', u'跋'), + (0x2F9DB, 'M', u'趼'), + (0x2F9DC, 'M', u'跰'), + (0x2F9DD, 'M', u'𠣞'), + (0x2F9DE, 'M', u'軔'), + (0x2F9DF, 'M', u'輸'), + (0x2F9E0, 'M', u'𨗒'), + (0x2F9E1, 'M', u'𨗭'), + (0x2F9E2, 'M', u'邔'), + (0x2F9E3, 'M', u'郱'), + (0x2F9E4, 'M', u'鄑'), + (0x2F9E5, 'M', u'𨜮'), + (0x2F9E6, 'M', u'鄛'), + (0x2F9E7, 'M', u'鈸'), + (0x2F9E8, 'M', u'鋗'), + (0x2F9E9, 'M', u'鋘'), + (0x2F9EA, 'M', u'鉼'), + (0x2F9EB, 'M', u'鏹'), + (0x2F9EC, 'M', u'鐕'), + (0x2F9ED, 'M', u'𨯺'), + (0x2F9EE, 'M', u'開'), + (0x2F9EF, 'M', u'䦕'), + (0x2F9F0, 'M', u'閷'), + (0x2F9F1, 'M', u'𨵷'), + (0x2F9F2, 'M', u'䧦'), + (0x2F9F3, 'M', u'雃'), + (0x2F9F4, 'M', u'嶲'), + (0x2F9F5, 'M', u'霣'), + (0x2F9F6, 'M', u'𩅅'), + (0x2F9F7, 'M', u'𩈚'), + (0x2F9F8, 'M', u'䩮'), + (0x2F9F9, 'M', u'䩶'), + (0x2F9FA, 'M', u'韠'), + (0x2F9FB, 'M', u'𩐊'), + (0x2F9FC, 'M', u'䪲'), + (0x2F9FD, 'M', u'𩒖'), + (0x2F9FE, 'M', u'頋'), + (0x2FA00, 'M', u'頩'), + (0x2FA01, 'M', u'𩖶'), + (0x2FA02, 'M', u'飢'), + (0x2FA03, 'M', u'䬳'), + (0x2FA04, 'M', u'餩'), + (0x2FA05, 'M', u'馧'), + (0x2FA06, 'M', u'駂'), + (0x2FA07, 'M', u'駾'), + (0x2FA08, 'M', u'䯎'), + (0x2FA09, 'M', u'𩬰'), + (0x2FA0A, 'M', u'鬒'), + (0x2FA0B, 'M', u'鱀'), + (0x2FA0C, 'M', u'鳽'), + (0x2FA0D, 'M', u'䳎'), + (0x2FA0E, 'M', u'䳭'), + (0x2FA0F, 'M', u'鵧'), + (0x2FA10, 'M', u'𪃎'), + (0x2FA11, 'M', u'䳸'), + (0x2FA12, 'M', u'𪄅'), + (0x2FA13, 'M', u'𪈎'), + (0x2FA14, 'M', u'𪊑'), + (0x2FA15, 'M', u'麻'), + (0x2FA16, 'M', u'䵖'), + (0x2FA17, 'M', u'黹'), + (0x2FA18, 'M', u'黾'), + (0x2FA19, 'M', u'鼅'), + (0x2FA1A, 'M', u'鼏'), + (0x2FA1B, 'M', u'鼖'), + (0x2FA1C, 'M', u'鼻'), + (0x2FA1D, 'M', u'𪘀'), + (0x2FA1E, 'X'), + (0xE0100, 'I'), + (0xE01F0, 'X'), + ] + +uts46data = tuple( + _seg_0() + + _seg_1() + + _seg_2() + + _seg_3() + + _seg_4() + + _seg_5() + + _seg_6() + + _seg_7() + + _seg_8() + + _seg_9() + + _seg_10() + + _seg_11() + + _seg_12() + + _seg_13() + + _seg_14() + + _seg_15() + + _seg_16() + + _seg_17() + + _seg_18() + + _seg_19() + + _seg_20() + + _seg_21() + + _seg_22() + + _seg_23() + + _seg_24() + + _seg_25() + + _seg_26() + + _seg_27() + + _seg_28() + + _seg_29() + + _seg_30() + + _seg_31() + + _seg_32() + + _seg_33() + + _seg_34() + + _seg_35() + + _seg_36() + + _seg_37() + + _seg_38() + + _seg_39() + + _seg_40() + + _seg_41() + + _seg_42() + + _seg_43() + + _seg_44() + + _seg_45() + + _seg_46() + + _seg_47() + + _seg_48() + + _seg_49() + + _seg_50() + + _seg_51() + + _seg_52() + + _seg_53() + + _seg_54() + + _seg_55() + + _seg_56() + + _seg_57() + + _seg_58() + + _seg_59() + + _seg_60() + + _seg_61() + + _seg_62() + + _seg_63() + + _seg_64() + + _seg_65() + + _seg_66() + + _seg_67() + + _seg_68() + + _seg_69() + + _seg_70() + + _seg_71() + + _seg_72() + + _seg_73() + + _seg_74() + + _seg_75() + + _seg_76() + + _seg_77() +) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/ipaddress.py b/venv/lib/python3.7/site-packages/pip/_vendor/ipaddress.py new file mode 100644 index 0000000..f2d0766 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/ipaddress.py @@ -0,0 +1,2419 @@ +# Copyright 2007 Google Inc. +# Licensed to PSF under a Contributor Agreement. + +"""A fast, lightweight IPv4/IPv6 manipulation library in Python. + +This library is used to create/poke/manipulate IPv4 and IPv6 addresses +and networks. + +""" + +from __future__ import unicode_literals + + +import itertools +import struct + +__version__ = '1.0.22' + +# Compatibility functions +_compat_int_types = (int,) +try: + _compat_int_types = (int, long) +except NameError: + pass +try: + _compat_str = unicode +except NameError: + _compat_str = str + assert bytes != str +if b'\0'[0] == 0: # Python 3 semantics + def _compat_bytes_to_byte_vals(byt): + return byt +else: + def _compat_bytes_to_byte_vals(byt): + return [struct.unpack(b'!B', b)[0] for b in byt] +try: + _compat_int_from_byte_vals = int.from_bytes +except AttributeError: + def _compat_int_from_byte_vals(bytvals, endianess): + assert endianess == 'big' + res = 0 + for bv in bytvals: + assert isinstance(bv, _compat_int_types) + res = (res << 8) + bv + return res + + +def _compat_to_bytes(intval, length, endianess): + assert isinstance(intval, _compat_int_types) + assert endianess == 'big' + if length == 4: + if intval < 0 or intval >= 2 ** 32: + raise struct.error("integer out of range for 'I' format code") + return struct.pack(b'!I', intval) + elif length == 16: + if intval < 0 or intval >= 2 ** 128: + raise struct.error("integer out of range for 'QQ' format code") + return struct.pack(b'!QQ', intval >> 64, intval & 0xffffffffffffffff) + else: + raise NotImplementedError() + + +if hasattr(int, 'bit_length'): + # Not int.bit_length , since that won't work in 2.7 where long exists + def _compat_bit_length(i): + return i.bit_length() +else: + def _compat_bit_length(i): + for res in itertools.count(): + if i >> res == 0: + return res + + +def _compat_range(start, end, step=1): + assert step > 0 + i = start + while i < end: + yield i + i += step + + +class _TotalOrderingMixin(object): + __slots__ = () + + # Helper that derives the other comparison operations from + # __lt__ and __eq__ + # We avoid functools.total_ordering because it doesn't handle + # NotImplemented correctly yet (http://bugs.python.org/issue10042) + def __eq__(self, other): + raise NotImplementedError + + def __ne__(self, other): + equal = self.__eq__(other) + if equal is NotImplemented: + return NotImplemented + return not equal + + def __lt__(self, other): + raise NotImplementedError + + def __le__(self, other): + less = self.__lt__(other) + if less is NotImplemented or not less: + return self.__eq__(other) + return less + + def __gt__(self, other): + less = self.__lt__(other) + if less is NotImplemented: + return NotImplemented + equal = self.__eq__(other) + if equal is NotImplemented: + return NotImplemented + return not (less or equal) + + def __ge__(self, other): + less = self.__lt__(other) + if less is NotImplemented: + return NotImplemented + return not less + + +IPV4LENGTH = 32 +IPV6LENGTH = 128 + + +class AddressValueError(ValueError): + """A Value Error related to the address.""" + + +class NetmaskValueError(ValueError): + """A Value Error related to the netmask.""" + + +def ip_address(address): + """Take an IP string/int and return an object of the correct type. + + Args: + address: A string or integer, the IP address. Either IPv4 or + IPv6 addresses may be supplied; integers less than 2**32 will + be considered to be IPv4 by default. + + Returns: + An IPv4Address or IPv6Address object. + + Raises: + ValueError: if the *address* passed isn't either a v4 or a v6 + address + + """ + try: + return IPv4Address(address) + except (AddressValueError, NetmaskValueError): + pass + + try: + return IPv6Address(address) + except (AddressValueError, NetmaskValueError): + pass + + if isinstance(address, bytes): + raise AddressValueError( + '%r does not appear to be an IPv4 or IPv6 address. ' + 'Did you pass in a bytes (str in Python 2) instead of' + ' a unicode object?' % address) + + raise ValueError('%r does not appear to be an IPv4 or IPv6 address' % + address) + + +def ip_network(address, strict=True): + """Take an IP string/int and return an object of the correct type. + + Args: + address: A string or integer, the IP network. Either IPv4 or + IPv6 networks may be supplied; integers less than 2**32 will + be considered to be IPv4 by default. + + Returns: + An IPv4Network or IPv6Network object. + + Raises: + ValueError: if the string passed isn't either a v4 or a v6 + address. Or if the network has host bits set. + + """ + try: + return IPv4Network(address, strict) + except (AddressValueError, NetmaskValueError): + pass + + try: + return IPv6Network(address, strict) + except (AddressValueError, NetmaskValueError): + pass + + if isinstance(address, bytes): + raise AddressValueError( + '%r does not appear to be an IPv4 or IPv6 network. ' + 'Did you pass in a bytes (str in Python 2) instead of' + ' a unicode object?' % address) + + raise ValueError('%r does not appear to be an IPv4 or IPv6 network' % + address) + + +def ip_interface(address): + """Take an IP string/int and return an object of the correct type. + + Args: + address: A string or integer, the IP address. Either IPv4 or + IPv6 addresses may be supplied; integers less than 2**32 will + be considered to be IPv4 by default. + + Returns: + An IPv4Interface or IPv6Interface object. + + Raises: + ValueError: if the string passed isn't either a v4 or a v6 + address. + + Notes: + The IPv?Interface classes describe an Address on a particular + Network, so they're basically a combination of both the Address + and Network classes. + + """ + try: + return IPv4Interface(address) + except (AddressValueError, NetmaskValueError): + pass + + try: + return IPv6Interface(address) + except (AddressValueError, NetmaskValueError): + pass + + raise ValueError('%r does not appear to be an IPv4 or IPv6 interface' % + address) + + +def v4_int_to_packed(address): + """Represent an address as 4 packed bytes in network (big-endian) order. + + Args: + address: An integer representation of an IPv4 IP address. + + Returns: + The integer address packed as 4 bytes in network (big-endian) order. + + Raises: + ValueError: If the integer is negative or too large to be an + IPv4 IP address. + + """ + try: + return _compat_to_bytes(address, 4, 'big') + except (struct.error, OverflowError): + raise ValueError("Address negative or too large for IPv4") + + +def v6_int_to_packed(address): + """Represent an address as 16 packed bytes in network (big-endian) order. + + Args: + address: An integer representation of an IPv6 IP address. + + Returns: + The integer address packed as 16 bytes in network (big-endian) order. + + """ + try: + return _compat_to_bytes(address, 16, 'big') + except (struct.error, OverflowError): + raise ValueError("Address negative or too large for IPv6") + + +def _split_optional_netmask(address): + """Helper to split the netmask and raise AddressValueError if needed""" + addr = _compat_str(address).split('/') + if len(addr) > 2: + raise AddressValueError("Only one '/' permitted in %r" % address) + return addr + + +def _find_address_range(addresses): + """Find a sequence of sorted deduplicated IPv#Address. + + Args: + addresses: a list of IPv#Address objects. + + Yields: + A tuple containing the first and last IP addresses in the sequence. + + """ + it = iter(addresses) + first = last = next(it) + for ip in it: + if ip._ip != last._ip + 1: + yield first, last + first = ip + last = ip + yield first, last + + +def _count_righthand_zero_bits(number, bits): + """Count the number of zero bits on the right hand side. + + Args: + number: an integer. + bits: maximum number of bits to count. + + Returns: + The number of zero bits on the right hand side of the number. + + """ + if number == 0: + return bits + return min(bits, _compat_bit_length(~number & (number - 1))) + + +def summarize_address_range(first, last): + """Summarize a network range given the first and last IP addresses. + + Example: + >>> list(summarize_address_range(IPv4Address('192.0.2.0'), + ... IPv4Address('192.0.2.130'))) + ... #doctest: +NORMALIZE_WHITESPACE + [IPv4Network('192.0.2.0/25'), IPv4Network('192.0.2.128/31'), + IPv4Network('192.0.2.130/32')] + + Args: + first: the first IPv4Address or IPv6Address in the range. + last: the last IPv4Address or IPv6Address in the range. + + Returns: + An iterator of the summarized IPv(4|6) network objects. + + Raise: + TypeError: + If the first and last objects are not IP addresses. + If the first and last objects are not the same version. + ValueError: + If the last object is not greater than the first. + If the version of the first address is not 4 or 6. + + """ + if (not (isinstance(first, _BaseAddress) and + isinstance(last, _BaseAddress))): + raise TypeError('first and last must be IP addresses, not networks') + if first.version != last.version: + raise TypeError("%s and %s are not of the same version" % ( + first, last)) + if first > last: + raise ValueError('last IP address must be greater than first') + + if first.version == 4: + ip = IPv4Network + elif first.version == 6: + ip = IPv6Network + else: + raise ValueError('unknown IP version') + + ip_bits = first._max_prefixlen + first_int = first._ip + last_int = last._ip + while first_int <= last_int: + nbits = min(_count_righthand_zero_bits(first_int, ip_bits), + _compat_bit_length(last_int - first_int + 1) - 1) + net = ip((first_int, ip_bits - nbits)) + yield net + first_int += 1 << nbits + if first_int - 1 == ip._ALL_ONES: + break + + +def _collapse_addresses_internal(addresses): + """Loops through the addresses, collapsing concurrent netblocks. + + Example: + + ip1 = IPv4Network('192.0.2.0/26') + ip2 = IPv4Network('192.0.2.64/26') + ip3 = IPv4Network('192.0.2.128/26') + ip4 = IPv4Network('192.0.2.192/26') + + _collapse_addresses_internal([ip1, ip2, ip3, ip4]) -> + [IPv4Network('192.0.2.0/24')] + + This shouldn't be called directly; it is called via + collapse_addresses([]). + + Args: + addresses: A list of IPv4Network's or IPv6Network's + + Returns: + A list of IPv4Network's or IPv6Network's depending on what we were + passed. + + """ + # First merge + to_merge = list(addresses) + subnets = {} + while to_merge: + net = to_merge.pop() + supernet = net.supernet() + existing = subnets.get(supernet) + if existing is None: + subnets[supernet] = net + elif existing != net: + # Merge consecutive subnets + del subnets[supernet] + to_merge.append(supernet) + # Then iterate over resulting networks, skipping subsumed subnets + last = None + for net in sorted(subnets.values()): + if last is not None: + # Since they are sorted, + # last.network_address <= net.network_address is a given. + if last.broadcast_address >= net.broadcast_address: + continue + yield net + last = net + + +def collapse_addresses(addresses): + """Collapse a list of IP objects. + + Example: + collapse_addresses([IPv4Network('192.0.2.0/25'), + IPv4Network('192.0.2.128/25')]) -> + [IPv4Network('192.0.2.0/24')] + + Args: + addresses: An iterator of IPv4Network or IPv6Network objects. + + Returns: + An iterator of the collapsed IPv(4|6)Network objects. + + Raises: + TypeError: If passed a list of mixed version objects. + + """ + addrs = [] + ips = [] + nets = [] + + # split IP addresses and networks + for ip in addresses: + if isinstance(ip, _BaseAddress): + if ips and ips[-1]._version != ip._version: + raise TypeError("%s and %s are not of the same version" % ( + ip, ips[-1])) + ips.append(ip) + elif ip._prefixlen == ip._max_prefixlen: + if ips and ips[-1]._version != ip._version: + raise TypeError("%s and %s are not of the same version" % ( + ip, ips[-1])) + try: + ips.append(ip.ip) + except AttributeError: + ips.append(ip.network_address) + else: + if nets and nets[-1]._version != ip._version: + raise TypeError("%s and %s are not of the same version" % ( + ip, nets[-1])) + nets.append(ip) + + # sort and dedup + ips = sorted(set(ips)) + + # find consecutive address ranges in the sorted sequence and summarize them + if ips: + for first, last in _find_address_range(ips): + addrs.extend(summarize_address_range(first, last)) + + return _collapse_addresses_internal(addrs + nets) + + +def get_mixed_type_key(obj): + """Return a key suitable for sorting between networks and addresses. + + Address and Network objects are not sortable by default; they're + fundamentally different so the expression + + IPv4Address('192.0.2.0') <= IPv4Network('192.0.2.0/24') + + doesn't make any sense. There are some times however, where you may wish + to have ipaddress sort these for you anyway. If you need to do this, you + can use this function as the key= argument to sorted(). + + Args: + obj: either a Network or Address object. + Returns: + appropriate key. + + """ + if isinstance(obj, _BaseNetwork): + return obj._get_networks_key() + elif isinstance(obj, _BaseAddress): + return obj._get_address_key() + return NotImplemented + + +class _IPAddressBase(_TotalOrderingMixin): + + """The mother class.""" + + __slots__ = () + + @property + def exploded(self): + """Return the longhand version of the IP address as a string.""" + return self._explode_shorthand_ip_string() + + @property + def compressed(self): + """Return the shorthand version of the IP address as a string.""" + return _compat_str(self) + + @property + def reverse_pointer(self): + """The name of the reverse DNS pointer for the IP address, e.g.: + >>> ipaddress.ip_address("127.0.0.1").reverse_pointer + '1.0.0.127.in-addr.arpa' + >>> ipaddress.ip_address("2001:db8::1").reverse_pointer + '1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa' + + """ + return self._reverse_pointer() + + @property + def version(self): + msg = '%200s has no version specified' % (type(self),) + raise NotImplementedError(msg) + + def _check_int_address(self, address): + if address < 0: + msg = "%d (< 0) is not permitted as an IPv%d address" + raise AddressValueError(msg % (address, self._version)) + if address > self._ALL_ONES: + msg = "%d (>= 2**%d) is not permitted as an IPv%d address" + raise AddressValueError(msg % (address, self._max_prefixlen, + self._version)) + + def _check_packed_address(self, address, expected_len): + address_len = len(address) + if address_len != expected_len: + msg = ( + '%r (len %d != %d) is not permitted as an IPv%d address. ' + 'Did you pass in a bytes (str in Python 2) instead of' + ' a unicode object?') + raise AddressValueError(msg % (address, address_len, + expected_len, self._version)) + + @classmethod + def _ip_int_from_prefix(cls, prefixlen): + """Turn the prefix length into a bitwise netmask + + Args: + prefixlen: An integer, the prefix length. + + Returns: + An integer. + + """ + return cls._ALL_ONES ^ (cls._ALL_ONES >> prefixlen) + + @classmethod + def _prefix_from_ip_int(cls, ip_int): + """Return prefix length from the bitwise netmask. + + Args: + ip_int: An integer, the netmask in expanded bitwise format + + Returns: + An integer, the prefix length. + + Raises: + ValueError: If the input intermingles zeroes & ones + """ + trailing_zeroes = _count_righthand_zero_bits(ip_int, + cls._max_prefixlen) + prefixlen = cls._max_prefixlen - trailing_zeroes + leading_ones = ip_int >> trailing_zeroes + all_ones = (1 << prefixlen) - 1 + if leading_ones != all_ones: + byteslen = cls._max_prefixlen // 8 + details = _compat_to_bytes(ip_int, byteslen, 'big') + msg = 'Netmask pattern %r mixes zeroes & ones' + raise ValueError(msg % details) + return prefixlen + + @classmethod + def _report_invalid_netmask(cls, netmask_str): + msg = '%r is not a valid netmask' % netmask_str + raise NetmaskValueError(msg) + + @classmethod + def _prefix_from_prefix_string(cls, prefixlen_str): + """Return prefix length from a numeric string + + Args: + prefixlen_str: The string to be converted + + Returns: + An integer, the prefix length. + + Raises: + NetmaskValueError: If the input is not a valid netmask + """ + # int allows a leading +/- as well as surrounding whitespace, + # so we ensure that isn't the case + if not _BaseV4._DECIMAL_DIGITS.issuperset(prefixlen_str): + cls._report_invalid_netmask(prefixlen_str) + try: + prefixlen = int(prefixlen_str) + except ValueError: + cls._report_invalid_netmask(prefixlen_str) + if not (0 <= prefixlen <= cls._max_prefixlen): + cls._report_invalid_netmask(prefixlen_str) + return prefixlen + + @classmethod + def _prefix_from_ip_string(cls, ip_str): + """Turn a netmask/hostmask string into a prefix length + + Args: + ip_str: The netmask/hostmask to be converted + + Returns: + An integer, the prefix length. + + Raises: + NetmaskValueError: If the input is not a valid netmask/hostmask + """ + # Parse the netmask/hostmask like an IP address. + try: + ip_int = cls._ip_int_from_string(ip_str) + except AddressValueError: + cls._report_invalid_netmask(ip_str) + + # Try matching a netmask (this would be /1*0*/ as a bitwise regexp). + # Note that the two ambiguous cases (all-ones and all-zeroes) are + # treated as netmasks. + try: + return cls._prefix_from_ip_int(ip_int) + except ValueError: + pass + + # Invert the bits, and try matching a /0+1+/ hostmask instead. + ip_int ^= cls._ALL_ONES + try: + return cls._prefix_from_ip_int(ip_int) + except ValueError: + cls._report_invalid_netmask(ip_str) + + def __reduce__(self): + return self.__class__, (_compat_str(self),) + + +class _BaseAddress(_IPAddressBase): + + """A generic IP object. + + This IP class contains the version independent methods which are + used by single IP addresses. + """ + + __slots__ = () + + def __int__(self): + return self._ip + + def __eq__(self, other): + try: + return (self._ip == other._ip and + self._version == other._version) + except AttributeError: + return NotImplemented + + def __lt__(self, other): + if not isinstance(other, _IPAddressBase): + return NotImplemented + if not isinstance(other, _BaseAddress): + raise TypeError('%s and %s are not of the same type' % ( + self, other)) + if self._version != other._version: + raise TypeError('%s and %s are not of the same version' % ( + self, other)) + if self._ip != other._ip: + return self._ip < other._ip + return False + + # Shorthand for Integer addition and subtraction. This is not + # meant to ever support addition/subtraction of addresses. + def __add__(self, other): + if not isinstance(other, _compat_int_types): + return NotImplemented + return self.__class__(int(self) + other) + + def __sub__(self, other): + if not isinstance(other, _compat_int_types): + return NotImplemented + return self.__class__(int(self) - other) + + def __repr__(self): + return '%s(%r)' % (self.__class__.__name__, _compat_str(self)) + + def __str__(self): + return _compat_str(self._string_from_ip_int(self._ip)) + + def __hash__(self): + return hash(hex(int(self._ip))) + + def _get_address_key(self): + return (self._version, self) + + def __reduce__(self): + return self.__class__, (self._ip,) + + +class _BaseNetwork(_IPAddressBase): + + """A generic IP network object. + + This IP class contains the version independent methods which are + used by networks. + + """ + def __init__(self, address): + self._cache = {} + + def __repr__(self): + return '%s(%r)' % (self.__class__.__name__, _compat_str(self)) + + def __str__(self): + return '%s/%d' % (self.network_address, self.prefixlen) + + def hosts(self): + """Generate Iterator over usable hosts in a network. + + This is like __iter__ except it doesn't return the network + or broadcast addresses. + + """ + network = int(self.network_address) + broadcast = int(self.broadcast_address) + for x in _compat_range(network + 1, broadcast): + yield self._address_class(x) + + def __iter__(self): + network = int(self.network_address) + broadcast = int(self.broadcast_address) + for x in _compat_range(network, broadcast + 1): + yield self._address_class(x) + + def __getitem__(self, n): + network = int(self.network_address) + broadcast = int(self.broadcast_address) + if n >= 0: + if network + n > broadcast: + raise IndexError('address out of range') + return self._address_class(network + n) + else: + n += 1 + if broadcast + n < network: + raise IndexError('address out of range') + return self._address_class(broadcast + n) + + def __lt__(self, other): + if not isinstance(other, _IPAddressBase): + return NotImplemented + if not isinstance(other, _BaseNetwork): + raise TypeError('%s and %s are not of the same type' % ( + self, other)) + if self._version != other._version: + raise TypeError('%s and %s are not of the same version' % ( + self, other)) + if self.network_address != other.network_address: + return self.network_address < other.network_address + if self.netmask != other.netmask: + return self.netmask < other.netmask + return False + + def __eq__(self, other): + try: + return (self._version == other._version and + self.network_address == other.network_address and + int(self.netmask) == int(other.netmask)) + except AttributeError: + return NotImplemented + + def __hash__(self): + return hash(int(self.network_address) ^ int(self.netmask)) + + def __contains__(self, other): + # always false if one is v4 and the other is v6. + if self._version != other._version: + return False + # dealing with another network. + if isinstance(other, _BaseNetwork): + return False + # dealing with another address + else: + # address + return (int(self.network_address) <= int(other._ip) <= + int(self.broadcast_address)) + + def overlaps(self, other): + """Tell if self is partly contained in other.""" + return self.network_address in other or ( + self.broadcast_address in other or ( + other.network_address in self or ( + other.broadcast_address in self))) + + @property + def broadcast_address(self): + x = self._cache.get('broadcast_address') + if x is None: + x = self._address_class(int(self.network_address) | + int(self.hostmask)) + self._cache['broadcast_address'] = x + return x + + @property + def hostmask(self): + x = self._cache.get('hostmask') + if x is None: + x = self._address_class(int(self.netmask) ^ self._ALL_ONES) + self._cache['hostmask'] = x + return x + + @property + def with_prefixlen(self): + return '%s/%d' % (self.network_address, self._prefixlen) + + @property + def with_netmask(self): + return '%s/%s' % (self.network_address, self.netmask) + + @property + def with_hostmask(self): + return '%s/%s' % (self.network_address, self.hostmask) + + @property + def num_addresses(self): + """Number of hosts in the current subnet.""" + return int(self.broadcast_address) - int(self.network_address) + 1 + + @property + def _address_class(self): + # Returning bare address objects (rather than interfaces) allows for + # more consistent behaviour across the network address, broadcast + # address and individual host addresses. + msg = '%200s has no associated address class' % (type(self),) + raise NotImplementedError(msg) + + @property + def prefixlen(self): + return self._prefixlen + + def address_exclude(self, other): + """Remove an address from a larger block. + + For example: + + addr1 = ip_network('192.0.2.0/28') + addr2 = ip_network('192.0.2.1/32') + list(addr1.address_exclude(addr2)) = + [IPv4Network('192.0.2.0/32'), IPv4Network('192.0.2.2/31'), + IPv4Network('192.0.2.4/30'), IPv4Network('192.0.2.8/29')] + + or IPv6: + + addr1 = ip_network('2001:db8::1/32') + addr2 = ip_network('2001:db8::1/128') + list(addr1.address_exclude(addr2)) = + [ip_network('2001:db8::1/128'), + ip_network('2001:db8::2/127'), + ip_network('2001:db8::4/126'), + ip_network('2001:db8::8/125'), + ... + ip_network('2001:db8:8000::/33')] + + Args: + other: An IPv4Network or IPv6Network object of the same type. + + Returns: + An iterator of the IPv(4|6)Network objects which is self + minus other. + + Raises: + TypeError: If self and other are of differing address + versions, or if other is not a network object. + ValueError: If other is not completely contained by self. + + """ + if not self._version == other._version: + raise TypeError("%s and %s are not of the same version" % ( + self, other)) + + if not isinstance(other, _BaseNetwork): + raise TypeError("%s is not a network object" % other) + + if not other.subnet_of(self): + raise ValueError('%s not contained in %s' % (other, self)) + if other == self: + return + + # Make sure we're comparing the network of other. + other = other.__class__('%s/%s' % (other.network_address, + other.prefixlen)) + + s1, s2 = self.subnets() + while s1 != other and s2 != other: + if other.subnet_of(s1): + yield s2 + s1, s2 = s1.subnets() + elif other.subnet_of(s2): + yield s1 + s1, s2 = s2.subnets() + else: + # If we got here, there's a bug somewhere. + raise AssertionError('Error performing exclusion: ' + 's1: %s s2: %s other: %s' % + (s1, s2, other)) + if s1 == other: + yield s2 + elif s2 == other: + yield s1 + else: + # If we got here, there's a bug somewhere. + raise AssertionError('Error performing exclusion: ' + 's1: %s s2: %s other: %s' % + (s1, s2, other)) + + def compare_networks(self, other): + """Compare two IP objects. + + This is only concerned about the comparison of the integer + representation of the network addresses. This means that the + host bits aren't considered at all in this method. If you want + to compare host bits, you can easily enough do a + 'HostA._ip < HostB._ip' + + Args: + other: An IP object. + + Returns: + If the IP versions of self and other are the same, returns: + + -1 if self < other: + eg: IPv4Network('192.0.2.0/25') < IPv4Network('192.0.2.128/25') + IPv6Network('2001:db8::1000/124') < + IPv6Network('2001:db8::2000/124') + 0 if self == other + eg: IPv4Network('192.0.2.0/24') == IPv4Network('192.0.2.0/24') + IPv6Network('2001:db8::1000/124') == + IPv6Network('2001:db8::1000/124') + 1 if self > other + eg: IPv4Network('192.0.2.128/25') > IPv4Network('192.0.2.0/25') + IPv6Network('2001:db8::2000/124') > + IPv6Network('2001:db8::1000/124') + + Raises: + TypeError if the IP versions are different. + + """ + # does this need to raise a ValueError? + if self._version != other._version: + raise TypeError('%s and %s are not of the same type' % ( + self, other)) + # self._version == other._version below here: + if self.network_address < other.network_address: + return -1 + if self.network_address > other.network_address: + return 1 + # self.network_address == other.network_address below here: + if self.netmask < other.netmask: + return -1 + if self.netmask > other.netmask: + return 1 + return 0 + + def _get_networks_key(self): + """Network-only key function. + + Returns an object that identifies this address' network and + netmask. This function is a suitable "key" argument for sorted() + and list.sort(). + + """ + return (self._version, self.network_address, self.netmask) + + def subnets(self, prefixlen_diff=1, new_prefix=None): + """The subnets which join to make the current subnet. + + In the case that self contains only one IP + (self._prefixlen == 32 for IPv4 or self._prefixlen == 128 + for IPv6), yield an iterator with just ourself. + + Args: + prefixlen_diff: An integer, the amount the prefix length + should be increased by. This should not be set if + new_prefix is also set. + new_prefix: The desired new prefix length. This must be a + larger number (smaller prefix) than the existing prefix. + This should not be set if prefixlen_diff is also set. + + Returns: + An iterator of IPv(4|6) objects. + + Raises: + ValueError: The prefixlen_diff is too small or too large. + OR + prefixlen_diff and new_prefix are both set or new_prefix + is a smaller number than the current prefix (smaller + number means a larger network) + + """ + if self._prefixlen == self._max_prefixlen: + yield self + return + + if new_prefix is not None: + if new_prefix < self._prefixlen: + raise ValueError('new prefix must be longer') + if prefixlen_diff != 1: + raise ValueError('cannot set prefixlen_diff and new_prefix') + prefixlen_diff = new_prefix - self._prefixlen + + if prefixlen_diff < 0: + raise ValueError('prefix length diff must be > 0') + new_prefixlen = self._prefixlen + prefixlen_diff + + if new_prefixlen > self._max_prefixlen: + raise ValueError( + 'prefix length diff %d is invalid for netblock %s' % ( + new_prefixlen, self)) + + start = int(self.network_address) + end = int(self.broadcast_address) + 1 + step = (int(self.hostmask) + 1) >> prefixlen_diff + for new_addr in _compat_range(start, end, step): + current = self.__class__((new_addr, new_prefixlen)) + yield current + + def supernet(self, prefixlen_diff=1, new_prefix=None): + """The supernet containing the current network. + + Args: + prefixlen_diff: An integer, the amount the prefix length of + the network should be decreased by. For example, given a + /24 network and a prefixlen_diff of 3, a supernet with a + /21 netmask is returned. + + Returns: + An IPv4 network object. + + Raises: + ValueError: If self.prefixlen - prefixlen_diff < 0. I.e., you have + a negative prefix length. + OR + If prefixlen_diff and new_prefix are both set or new_prefix is a + larger number than the current prefix (larger number means a + smaller network) + + """ + if self._prefixlen == 0: + return self + + if new_prefix is not None: + if new_prefix > self._prefixlen: + raise ValueError('new prefix must be shorter') + if prefixlen_diff != 1: + raise ValueError('cannot set prefixlen_diff and new_prefix') + prefixlen_diff = self._prefixlen - new_prefix + + new_prefixlen = self.prefixlen - prefixlen_diff + if new_prefixlen < 0: + raise ValueError( + 'current prefixlen is %d, cannot have a prefixlen_diff of %d' % + (self.prefixlen, prefixlen_diff)) + return self.__class__(( + int(self.network_address) & (int(self.netmask) << prefixlen_diff), + new_prefixlen)) + + @property + def is_multicast(self): + """Test if the address is reserved for multicast use. + + Returns: + A boolean, True if the address is a multicast address. + See RFC 2373 2.7 for details. + + """ + return (self.network_address.is_multicast and + self.broadcast_address.is_multicast) + + @staticmethod + def _is_subnet_of(a, b): + 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)) + return (b.network_address <= a.network_address and + b.broadcast_address >= a.broadcast_address) + except AttributeError: + raise TypeError("Unable to test subnet containment " + "between %s and %s" % (a, b)) + + def subnet_of(self, other): + """Return True if this network is a subnet of other.""" + return self._is_subnet_of(self, other) + + def supernet_of(self, other): + """Return True if this network is a supernet of other.""" + return self._is_subnet_of(other, self) + + @property + def is_reserved(self): + """Test if the address is otherwise IETF reserved. + + Returns: + A boolean, True if the address is within one of the + reserved IPv6 Network ranges. + + """ + return (self.network_address.is_reserved and + self.broadcast_address.is_reserved) + + @property + def is_link_local(self): + """Test if the address is reserved for link-local. + + Returns: + A boolean, True if the address is reserved per RFC 4291. + + """ + return (self.network_address.is_link_local and + self.broadcast_address.is_link_local) + + @property + def is_private(self): + """Test if this address is allocated for private networks. + + Returns: + A boolean, True if the address is reserved per + iana-ipv4-special-registry or iana-ipv6-special-registry. + + """ + return (self.network_address.is_private and + self.broadcast_address.is_private) + + @property + def is_global(self): + """Test if this address is allocated for public networks. + + Returns: + A boolean, True if the address is not reserved per + iana-ipv4-special-registry or iana-ipv6-special-registry. + + """ + return not self.is_private + + @property + def is_unspecified(self): + """Test if the address is unspecified. + + Returns: + A boolean, True if this is the unspecified address as defined in + RFC 2373 2.5.2. + + """ + return (self.network_address.is_unspecified and + self.broadcast_address.is_unspecified) + + @property + def is_loopback(self): + """Test if the address is a loopback address. + + Returns: + A boolean, True if the address is a loopback address as defined in + RFC 2373 2.5.3. + + """ + return (self.network_address.is_loopback and + self.broadcast_address.is_loopback) + + +class _BaseV4(object): + + """Base IPv4 object. + + The following methods are used by IPv4 objects in both single IP + addresses and networks. + + """ + + __slots__ = () + _version = 4 + # Equivalent to 255.255.255.255 or 32 bits of 1's. + _ALL_ONES = (2 ** IPV4LENGTH) - 1 + _DECIMAL_DIGITS = frozenset('0123456789') + + # the valid octets for host and netmasks. only useful for IPv4. + _valid_mask_octets = frozenset([255, 254, 252, 248, 240, 224, 192, 128, 0]) + + _max_prefixlen = IPV4LENGTH + # There are only a handful of valid v4 netmasks, so we cache them all + # when constructed (see _make_netmask()). + _netmask_cache = {} + + def _explode_shorthand_ip_string(self): + return _compat_str(self) + + @classmethod + def _make_netmask(cls, arg): + """Make a (netmask, prefix_len) tuple from the given argument. + + Argument can be: + - an integer (the prefix length) + - a string representing the prefix length (e.g. "24") + - a string representing the prefix netmask (e.g. "255.255.255.0") + """ + if arg not in cls._netmask_cache: + if isinstance(arg, _compat_int_types): + prefixlen = arg + else: + try: + # Check for a netmask in prefix length form + prefixlen = cls._prefix_from_prefix_string(arg) + except NetmaskValueError: + # Check for a netmask or hostmask in dotted-quad form. + # This may raise NetmaskValueError. + prefixlen = cls._prefix_from_ip_string(arg) + netmask = IPv4Address(cls._ip_int_from_prefix(prefixlen)) + cls._netmask_cache[arg] = netmask, prefixlen + return cls._netmask_cache[arg] + + @classmethod + def _ip_int_from_string(cls, ip_str): + """Turn the given IP string into an integer for comparison. + + Args: + ip_str: A string, the IP ip_str. + + Returns: + The IP ip_str as an integer. + + Raises: + AddressValueError: if ip_str isn't a valid IPv4 Address. + + """ + if not ip_str: + raise AddressValueError('Address cannot be empty') + + octets = ip_str.split('.') + if len(octets) != 4: + raise AddressValueError("Expected 4 octets in %r" % ip_str) + + try: + return _compat_int_from_byte_vals( + map(cls._parse_octet, octets), 'big') + except ValueError as exc: + raise AddressValueError("%s in %r" % (exc, ip_str)) + + @classmethod + def _parse_octet(cls, octet_str): + """Convert a decimal octet into an integer. + + Args: + octet_str: A string, the number to parse. + + Returns: + The octet as an integer. + + Raises: + ValueError: if the octet isn't strictly a decimal from [0..255]. + + """ + if not octet_str: + raise ValueError("Empty octet not permitted") + # Whitelist the characters, since int() allows a lot of bizarre stuff. + if not cls._DECIMAL_DIGITS.issuperset(octet_str): + msg = "Only decimal digits permitted in %r" + raise ValueError(msg % octet_str) + # We do the length check second, since the invalid character error + # is likely to be more informative for the user + if len(octet_str) > 3: + msg = "At most 3 characters permitted in %r" + raise ValueError(msg % octet_str) + # Convert to integer (we know digits are legal) + octet_int = int(octet_str, 10) + # Any octets that look like they *might* be written in octal, + # and which don't look exactly the same in both octal and + # decimal are rejected as ambiguous + if octet_int > 7 and octet_str[0] == '0': + msg = "Ambiguous (octal/decimal) value in %r not permitted" + raise ValueError(msg % octet_str) + if octet_int > 255: + raise ValueError("Octet %d (> 255) not permitted" % octet_int) + return octet_int + + @classmethod + def _string_from_ip_int(cls, ip_int): + """Turns a 32-bit integer into dotted decimal notation. + + Args: + ip_int: An integer, the IP address. + + Returns: + The IP address as a string in dotted decimal notation. + + """ + return '.'.join(_compat_str(struct.unpack(b'!B', b)[0] + if isinstance(b, bytes) + else b) + for b in _compat_to_bytes(ip_int, 4, 'big')) + + def _is_hostmask(self, ip_str): + """Test if the IP string is a hostmask (rather than a netmask). + + Args: + ip_str: A string, the potential hostmask. + + Returns: + A boolean, True if the IP string is a hostmask. + + """ + bits = ip_str.split('.') + try: + parts = [x for x in map(int, bits) if x in self._valid_mask_octets] + except ValueError: + return False + if len(parts) != len(bits): + return False + if parts[0] < parts[-1]: + return True + return False + + def _reverse_pointer(self): + """Return the reverse DNS pointer name for the IPv4 address. + + This implements the method described in RFC1035 3.5. + + """ + reverse_octets = _compat_str(self).split('.')[::-1] + return '.'.join(reverse_octets) + '.in-addr.arpa' + + @property + def max_prefixlen(self): + return self._max_prefixlen + + @property + def version(self): + return self._version + + +class IPv4Address(_BaseV4, _BaseAddress): + + """Represent and manipulate single IPv4 Addresses.""" + + __slots__ = ('_ip', '__weakref__') + + def __init__(self, address): + + """ + Args: + address: A string or integer representing the IP + + Additionally, an integer can be passed, so + IPv4Address('192.0.2.1') == IPv4Address(3221225985). + or, more generally + IPv4Address(int(IPv4Address('192.0.2.1'))) == + IPv4Address('192.0.2.1') + + Raises: + AddressValueError: If ipaddress isn't a valid IPv4 address. + + """ + # Efficient constructor from integer. + if isinstance(address, _compat_int_types): + self._check_int_address(address) + self._ip = address + return + + # Constructing from a packed address + if isinstance(address, bytes): + self._check_packed_address(address, 4) + bvs = _compat_bytes_to_byte_vals(address) + self._ip = _compat_int_from_byte_vals(bvs, 'big') + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP string. + addr_str = _compat_str(address) + if '/' in addr_str: + raise AddressValueError("Unexpected '/' in %r" % address) + self._ip = self._ip_int_from_string(addr_str) + + @property + def packed(self): + """The binary representation of this address.""" + return v4_int_to_packed(self._ip) + + @property + def is_reserved(self): + """Test if the address is otherwise IETF reserved. + + Returns: + A boolean, True if the address is within the + reserved IPv4 Network range. + + """ + return self in self._constants._reserved_network + + @property + def is_private(self): + """Test if this address is allocated for private networks. + + Returns: + A boolean, True if the address is reserved per + iana-ipv4-special-registry. + + """ + return any(self in net for net in self._constants._private_networks) + + @property + def is_global(self): + return ( + self not in self._constants._public_network and + not self.is_private) + + @property + def is_multicast(self): + """Test if the address is reserved for multicast use. + + Returns: + A boolean, True if the address is multicast. + See RFC 3171 for details. + + """ + return self in self._constants._multicast_network + + @property + def is_unspecified(self): + """Test if the address is unspecified. + + Returns: + A boolean, True if this is the unspecified address as defined in + RFC 5735 3. + + """ + return self == self._constants._unspecified_address + + @property + def is_loopback(self): + """Test if the address is a loopback address. + + Returns: + A boolean, True if the address is a loopback per RFC 3330. + + """ + return self in self._constants._loopback_network + + @property + def is_link_local(self): + """Test if the address is reserved for link-local. + + Returns: + A boolean, True if the address is link-local per RFC 3927. + + """ + return self in self._constants._linklocal_network + + +class IPv4Interface(IPv4Address): + + def __init__(self, address): + if isinstance(address, (bytes, _compat_int_types)): + IPv4Address.__init__(self, address) + self.network = IPv4Network(self._ip) + self._prefixlen = self._max_prefixlen + return + + if isinstance(address, tuple): + IPv4Address.__init__(self, address[0]) + if len(address) > 1: + self._prefixlen = int(address[1]) + else: + self._prefixlen = self._max_prefixlen + + self.network = IPv4Network(address, strict=False) + self.netmask = self.network.netmask + self.hostmask = self.network.hostmask + return + + addr = _split_optional_netmask(address) + IPv4Address.__init__(self, addr[0]) + + self.network = IPv4Network(address, strict=False) + self._prefixlen = self.network._prefixlen + + self.netmask = self.network.netmask + self.hostmask = self.network.hostmask + + def __str__(self): + return '%s/%d' % (self._string_from_ip_int(self._ip), + self.network.prefixlen) + + def __eq__(self, other): + address_equal = IPv4Address.__eq__(self, other) + if not address_equal or address_equal is NotImplemented: + return address_equal + try: + return self.network == other.network + except AttributeError: + # An interface with an associated network is NOT the + # same as an unassociated address. That's why the hash + # takes the extra info into account. + return False + + def __lt__(self, other): + address_less = IPv4Address.__lt__(self, other) + if address_less is NotImplemented: + return NotImplemented + try: + return (self.network < other.network or + self.network == other.network and address_less) + except AttributeError: + # We *do* allow addresses and interfaces to be sorted. The + # unassociated address is considered less than all interfaces. + return False + + def __hash__(self): + return self._ip ^ self._prefixlen ^ int(self.network.network_address) + + __reduce__ = _IPAddressBase.__reduce__ + + @property + def ip(self): + return IPv4Address(self._ip) + + @property + def with_prefixlen(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self._prefixlen) + + @property + def with_netmask(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self.netmask) + + @property + def with_hostmask(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self.hostmask) + + +class IPv4Network(_BaseV4, _BaseNetwork): + + """This class represents and manipulates 32-bit IPv4 network + addresses.. + + Attributes: [examples for IPv4Network('192.0.2.0/27')] + .network_address: IPv4Address('192.0.2.0') + .hostmask: IPv4Address('0.0.0.31') + .broadcast_address: IPv4Address('192.0.2.32') + .netmask: IPv4Address('255.255.255.224') + .prefixlen: 27 + + """ + # Class to use when creating address objects + _address_class = IPv4Address + + def __init__(self, address, strict=True): + + """Instantiate a new IPv4 network object. + + Args: + address: A string or integer representing the IP [& network]. + '192.0.2.0/24' + '192.0.2.0/255.255.255.0' + '192.0.0.2/0.0.0.255' + are all functionally the same in IPv4. Similarly, + '192.0.2.1' + '192.0.2.1/255.255.255.255' + '192.0.2.1/32' + are also functionally equivalent. That is to say, failing to + provide a subnetmask will create an object with a mask of /32. + + If the mask (portion after the / in the argument) is given in + dotted quad form, it is treated as a netmask if it starts with a + non-zero field (e.g. /255.0.0.0 == /8) and as a hostmask if it + starts with a zero field (e.g. 0.255.255.255 == /8), with the + single exception of an all-zero mask which is treated as a + netmask == /0. If no mask is given, a default of /32 is used. + + Additionally, an integer can be passed, so + IPv4Network('192.0.2.1') == IPv4Network(3221225985) + or, more generally + IPv4Interface(int(IPv4Interface('192.0.2.1'))) == + IPv4Interface('192.0.2.1') + + Raises: + AddressValueError: If ipaddress isn't a valid IPv4 address. + NetmaskValueError: If the netmask isn't valid for + an IPv4 address. + ValueError: If strict is True and a network address is not + supplied. + + """ + _BaseNetwork.__init__(self, address) + + # Constructing from a packed address or integer + if isinstance(address, (_compat_int_types, bytes)): + self.network_address = IPv4Address(address) + self.netmask, self._prefixlen = self._make_netmask( + self._max_prefixlen) + # fixme: address/network test here. + return + + if isinstance(address, tuple): + if len(address) > 1: + arg = address[1] + else: + # We weren't given an address[1] + arg = self._max_prefixlen + self.network_address = IPv4Address(address[0]) + self.netmask, self._prefixlen = self._make_netmask(arg) + packed = int(self.network_address) + if packed & int(self.netmask) != packed: + if strict: + raise ValueError('%s has host bits set' % self) + else: + self.network_address = IPv4Address(packed & + int(self.netmask)) + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP prefix string. + addr = _split_optional_netmask(address) + self.network_address = IPv4Address(self._ip_int_from_string(addr[0])) + + if len(addr) == 2: + arg = addr[1] + else: + arg = self._max_prefixlen + self.netmask, self._prefixlen = self._make_netmask(arg) + + if strict: + if (IPv4Address(int(self.network_address) & int(self.netmask)) != + self.network_address): + raise ValueError('%s has host bits set' % self) + self.network_address = IPv4Address(int(self.network_address) & + int(self.netmask)) + + if self._prefixlen == (self._max_prefixlen - 1): + self.hosts = self.__iter__ + + @property + def is_global(self): + """Test if this address is allocated for public networks. + + Returns: + A boolean, True if the address is not reserved per + iana-ipv4-special-registry. + + """ + return (not (self.network_address in IPv4Network('100.64.0.0/10') and + self.broadcast_address in IPv4Network('100.64.0.0/10')) and + not self.is_private) + + +class _IPv4Constants(object): + + _linklocal_network = IPv4Network('169.254.0.0/16') + + _loopback_network = IPv4Network('127.0.0.0/8') + + _multicast_network = IPv4Network('224.0.0.0/4') + + _public_network = IPv4Network('100.64.0.0/10') + + _private_networks = [ + IPv4Network('0.0.0.0/8'), + IPv4Network('10.0.0.0/8'), + IPv4Network('127.0.0.0/8'), + IPv4Network('169.254.0.0/16'), + IPv4Network('172.16.0.0/12'), + IPv4Network('192.0.0.0/29'), + IPv4Network('192.0.0.170/31'), + IPv4Network('192.0.2.0/24'), + IPv4Network('192.168.0.0/16'), + IPv4Network('198.18.0.0/15'), + IPv4Network('198.51.100.0/24'), + IPv4Network('203.0.113.0/24'), + IPv4Network('240.0.0.0/4'), + IPv4Network('255.255.255.255/32'), + ] + + _reserved_network = IPv4Network('240.0.0.0/4') + + _unspecified_address = IPv4Address('0.0.0.0') + + +IPv4Address._constants = _IPv4Constants + + +class _BaseV6(object): + + """Base IPv6 object. + + The following methods are used by IPv6 objects in both single IP + addresses and networks. + + """ + + __slots__ = () + _version = 6 + _ALL_ONES = (2 ** IPV6LENGTH) - 1 + _HEXTET_COUNT = 8 + _HEX_DIGITS = frozenset('0123456789ABCDEFabcdef') + _max_prefixlen = IPV6LENGTH + + # There are only a bunch of valid v6 netmasks, so we cache them all + # when constructed (see _make_netmask()). + _netmask_cache = {} + + @classmethod + def _make_netmask(cls, arg): + """Make a (netmask, prefix_len) tuple from the given argument. + + Argument can be: + - an integer (the prefix length) + - a string representing the prefix length (e.g. "24") + - a string representing the prefix netmask (e.g. "255.255.255.0") + """ + if arg not in cls._netmask_cache: + if isinstance(arg, _compat_int_types): + prefixlen = arg + else: + prefixlen = cls._prefix_from_prefix_string(arg) + netmask = IPv6Address(cls._ip_int_from_prefix(prefixlen)) + cls._netmask_cache[arg] = netmask, prefixlen + return cls._netmask_cache[arg] + + @classmethod + def _ip_int_from_string(cls, ip_str): + """Turn an IPv6 ip_str into an integer. + + Args: + ip_str: A string, the IPv6 ip_str. + + Returns: + An int, the IPv6 address + + Raises: + AddressValueError: if ip_str isn't a valid IPv6 Address. + + """ + if not ip_str: + raise AddressValueError('Address cannot be empty') + + parts = ip_str.split(':') + + # An IPv6 address needs at least 2 colons (3 parts). + _min_parts = 3 + if len(parts) < _min_parts: + msg = "At least %d parts expected in %r" % (_min_parts, ip_str) + raise AddressValueError(msg) + + # If the address has an IPv4-style suffix, convert it to hexadecimal. + if '.' in parts[-1]: + try: + ipv4_int = IPv4Address(parts.pop())._ip + except AddressValueError as exc: + raise AddressValueError("%s in %r" % (exc, ip_str)) + parts.append('%x' % ((ipv4_int >> 16) & 0xFFFF)) + parts.append('%x' % (ipv4_int & 0xFFFF)) + + # An IPv6 address can't have more than 8 colons (9 parts). + # The extra colon comes from using the "::" notation for a single + # leading or trailing zero part. + _max_parts = cls._HEXTET_COUNT + 1 + if len(parts) > _max_parts: + msg = "At most %d colons permitted in %r" % ( + _max_parts - 1, ip_str) + raise AddressValueError(msg) + + # Disregarding the endpoints, find '::' with nothing in between. + # This indicates that a run of zeroes has been skipped. + skip_index = None + for i in _compat_range(1, len(parts) - 1): + if not parts[i]: + if skip_index is not None: + # Can't have more than one '::' + msg = "At most one '::' permitted in %r" % ip_str + raise AddressValueError(msg) + skip_index = i + + # parts_hi is the number of parts to copy from above/before the '::' + # parts_lo is the number of parts to copy from below/after the '::' + if skip_index is not None: + # If we found a '::', then check if it also covers the endpoints. + parts_hi = skip_index + parts_lo = len(parts) - skip_index - 1 + if not parts[0]: + parts_hi -= 1 + if parts_hi: + msg = "Leading ':' only permitted as part of '::' in %r" + raise AddressValueError(msg % ip_str) # ^: requires ^:: + if not parts[-1]: + parts_lo -= 1 + if parts_lo: + msg = "Trailing ':' only permitted as part of '::' in %r" + raise AddressValueError(msg % ip_str) # :$ requires ::$ + parts_skipped = cls._HEXTET_COUNT - (parts_hi + parts_lo) + if parts_skipped < 1: + msg = "Expected at most %d other parts with '::' in %r" + raise AddressValueError(msg % (cls._HEXTET_COUNT - 1, ip_str)) + else: + # Otherwise, allocate the entire address to parts_hi. The + # endpoints could still be empty, but _parse_hextet() will check + # for that. + if len(parts) != cls._HEXTET_COUNT: + msg = "Exactly %d parts expected without '::' in %r" + raise AddressValueError(msg % (cls._HEXTET_COUNT, ip_str)) + if not parts[0]: + msg = "Leading ':' only permitted as part of '::' in %r" + raise AddressValueError(msg % ip_str) # ^: requires ^:: + if not parts[-1]: + msg = "Trailing ':' only permitted as part of '::' in %r" + raise AddressValueError(msg % ip_str) # :$ requires ::$ + parts_hi = len(parts) + parts_lo = 0 + parts_skipped = 0 + + try: + # Now, parse the hextets into a 128-bit integer. + ip_int = 0 + for i in range(parts_hi): + ip_int <<= 16 + ip_int |= cls._parse_hextet(parts[i]) + ip_int <<= 16 * parts_skipped + for i in range(-parts_lo, 0): + ip_int <<= 16 + ip_int |= cls._parse_hextet(parts[i]) + return ip_int + except ValueError as exc: + raise AddressValueError("%s in %r" % (exc, ip_str)) + + @classmethod + def _parse_hextet(cls, hextet_str): + """Convert an IPv6 hextet string into an integer. + + Args: + hextet_str: A string, the number to parse. + + Returns: + The hextet as an integer. + + Raises: + ValueError: if the input isn't strictly a hex number from + [0..FFFF]. + + """ + # Whitelist the characters, since int() allows a lot of bizarre stuff. + if not cls._HEX_DIGITS.issuperset(hextet_str): + raise ValueError("Only hex digits permitted in %r" % hextet_str) + # We do the length check second, since the invalid character error + # is likely to be more informative for the user + if len(hextet_str) > 4: + msg = "At most 4 characters permitted in %r" + raise ValueError(msg % hextet_str) + # Length check means we can skip checking the integer value + return int(hextet_str, 16) + + @classmethod + def _compress_hextets(cls, hextets): + """Compresses a list of hextets. + + Compresses a list of strings, replacing the longest continuous + sequence of "0" in the list with "" and adding empty strings at + the beginning or at the end of the string such that subsequently + calling ":".join(hextets) will produce the compressed version of + the IPv6 address. + + Args: + hextets: A list of strings, the hextets to compress. + + Returns: + A list of strings. + + """ + best_doublecolon_start = -1 + best_doublecolon_len = 0 + doublecolon_start = -1 + doublecolon_len = 0 + for index, hextet in enumerate(hextets): + if hextet == '0': + doublecolon_len += 1 + if doublecolon_start == -1: + # Start of a sequence of zeros. + doublecolon_start = index + if doublecolon_len > best_doublecolon_len: + # This is the longest sequence of zeros so far. + best_doublecolon_len = doublecolon_len + best_doublecolon_start = doublecolon_start + else: + doublecolon_len = 0 + doublecolon_start = -1 + + if best_doublecolon_len > 1: + best_doublecolon_end = (best_doublecolon_start + + best_doublecolon_len) + # For zeros at the end of the address. + if best_doublecolon_end == len(hextets): + hextets += [''] + hextets[best_doublecolon_start:best_doublecolon_end] = [''] + # For zeros at the beginning of the address. + if best_doublecolon_start == 0: + hextets = [''] + hextets + + return hextets + + @classmethod + def _string_from_ip_int(cls, ip_int=None): + """Turns a 128-bit integer into hexadecimal notation. + + Args: + ip_int: An integer, the IP address. + + Returns: + A string, the hexadecimal representation of the address. + + Raises: + ValueError: The address is bigger than 128 bits of all ones. + + """ + if ip_int is None: + ip_int = int(cls._ip) + + if ip_int > cls._ALL_ONES: + raise ValueError('IPv6 address is too large') + + hex_str = '%032x' % ip_int + hextets = ['%x' % int(hex_str[x:x + 4], 16) for x in range(0, 32, 4)] + + hextets = cls._compress_hextets(hextets) + return ':'.join(hextets) + + def _explode_shorthand_ip_string(self): + """Expand a shortened IPv6 address. + + Args: + ip_str: A string, the IPv6 address. + + Returns: + A string, the expanded IPv6 address. + + """ + if isinstance(self, IPv6Network): + ip_str = _compat_str(self.network_address) + elif isinstance(self, IPv6Interface): + ip_str = _compat_str(self.ip) + else: + ip_str = _compat_str(self) + + ip_int = self._ip_int_from_string(ip_str) + hex_str = '%032x' % ip_int + parts = [hex_str[x:x + 4] for x in range(0, 32, 4)] + if isinstance(self, (_BaseNetwork, IPv6Interface)): + return '%s/%d' % (':'.join(parts), self._prefixlen) + return ':'.join(parts) + + def _reverse_pointer(self): + """Return the reverse DNS pointer name for the IPv6 address. + + This implements the method described in RFC3596 2.5. + + """ + reverse_chars = self.exploded[::-1].replace(':', '') + return '.'.join(reverse_chars) + '.ip6.arpa' + + @property + def max_prefixlen(self): + return self._max_prefixlen + + @property + def version(self): + return self._version + + +class IPv6Address(_BaseV6, _BaseAddress): + + """Represent and manipulate single IPv6 Addresses.""" + + __slots__ = ('_ip', '__weakref__') + + def __init__(self, address): + """Instantiate a new IPv6 address object. + + Args: + address: A string or integer representing the IP + + Additionally, an integer can be passed, so + IPv6Address('2001:db8::') == + IPv6Address(42540766411282592856903984951653826560) + or, more generally + IPv6Address(int(IPv6Address('2001:db8::'))) == + IPv6Address('2001:db8::') + + Raises: + AddressValueError: If address isn't a valid IPv6 address. + + """ + # Efficient constructor from integer. + if isinstance(address, _compat_int_types): + self._check_int_address(address) + self._ip = address + return + + # Constructing from a packed address + if isinstance(address, bytes): + self._check_packed_address(address, 16) + bvs = _compat_bytes_to_byte_vals(address) + self._ip = _compat_int_from_byte_vals(bvs, 'big') + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP string. + addr_str = _compat_str(address) + if '/' in addr_str: + raise AddressValueError("Unexpected '/' in %r" % address) + self._ip = self._ip_int_from_string(addr_str) + + @property + def packed(self): + """The binary representation of this address.""" + return v6_int_to_packed(self._ip) + + @property + def is_multicast(self): + """Test if the address is reserved for multicast use. + + Returns: + A boolean, True if the address is a multicast address. + See RFC 2373 2.7 for details. + + """ + return self in self._constants._multicast_network + + @property + def is_reserved(self): + """Test if the address is otherwise IETF reserved. + + Returns: + A boolean, True if the address is within one of the + reserved IPv6 Network ranges. + + """ + return any(self in x for x in self._constants._reserved_networks) + + @property + def is_link_local(self): + """Test if the address is reserved for link-local. + + Returns: + A boolean, True if the address is reserved per RFC 4291. + + """ + return self in self._constants._linklocal_network + + @property + def is_site_local(self): + """Test if the address is reserved for site-local. + + Note that the site-local address space has been deprecated by RFC 3879. + Use is_private to test if this address is in the space of unique local + addresses as defined by RFC 4193. + + Returns: + A boolean, True if the address is reserved per RFC 3513 2.5.6. + + """ + return self in self._constants._sitelocal_network + + @property + def is_private(self): + """Test if this address is allocated for private networks. + + Returns: + A boolean, True if the address is reserved per + iana-ipv6-special-registry. + + """ + return any(self in net for net in self._constants._private_networks) + + @property + def is_global(self): + """Test if this address is allocated for public networks. + + Returns: + A boolean, true if the address is not reserved per + iana-ipv6-special-registry. + + """ + return not self.is_private + + @property + def is_unspecified(self): + """Test if the address is unspecified. + + Returns: + A boolean, True if this is the unspecified address as defined in + RFC 2373 2.5.2. + + """ + return self._ip == 0 + + @property + def is_loopback(self): + """Test if the address is a loopback address. + + Returns: + A boolean, True if the address is a loopback address as defined in + RFC 2373 2.5.3. + + """ + return self._ip == 1 + + @property + def ipv4_mapped(self): + """Return the IPv4 mapped address. + + Returns: + If the IPv6 address is a v4 mapped address, return the + IPv4 mapped address. Return None otherwise. + + """ + if (self._ip >> 32) != 0xFFFF: + return None + return IPv4Address(self._ip & 0xFFFFFFFF) + + @property + def teredo(self): + """Tuple of embedded teredo IPs. + + Returns: + Tuple of the (server, client) IPs or None if the address + doesn't appear to be a teredo address (doesn't start with + 2001::/32) + + """ + if (self._ip >> 96) != 0x20010000: + return None + return (IPv4Address((self._ip >> 64) & 0xFFFFFFFF), + IPv4Address(~self._ip & 0xFFFFFFFF)) + + @property + def sixtofour(self): + """Return the IPv4 6to4 embedded address. + + Returns: + The IPv4 6to4-embedded address if present or None if the + address doesn't appear to contain a 6to4 embedded address. + + """ + if (self._ip >> 112) != 0x2002: + return None + return IPv4Address((self._ip >> 80) & 0xFFFFFFFF) + + +class IPv6Interface(IPv6Address): + + def __init__(self, address): + if isinstance(address, (bytes, _compat_int_types)): + IPv6Address.__init__(self, address) + self.network = IPv6Network(self._ip) + self._prefixlen = self._max_prefixlen + return + if isinstance(address, tuple): + IPv6Address.__init__(self, address[0]) + if len(address) > 1: + self._prefixlen = int(address[1]) + else: + self._prefixlen = self._max_prefixlen + self.network = IPv6Network(address, strict=False) + self.netmask = self.network.netmask + self.hostmask = self.network.hostmask + return + + addr = _split_optional_netmask(address) + IPv6Address.__init__(self, addr[0]) + self.network = IPv6Network(address, strict=False) + self.netmask = self.network.netmask + self._prefixlen = self.network._prefixlen + self.hostmask = self.network.hostmask + + def __str__(self): + return '%s/%d' % (self._string_from_ip_int(self._ip), + self.network.prefixlen) + + def __eq__(self, other): + address_equal = IPv6Address.__eq__(self, other) + if not address_equal or address_equal is NotImplemented: + return address_equal + try: + return self.network == other.network + except AttributeError: + # An interface with an associated network is NOT the + # same as an unassociated address. That's why the hash + # takes the extra info into account. + return False + + def __lt__(self, other): + address_less = IPv6Address.__lt__(self, other) + if address_less is NotImplemented: + return NotImplemented + try: + return (self.network < other.network or + self.network == other.network and address_less) + except AttributeError: + # We *do* allow addresses and interfaces to be sorted. The + # unassociated address is considered less than all interfaces. + return False + + def __hash__(self): + return self._ip ^ self._prefixlen ^ int(self.network.network_address) + + __reduce__ = _IPAddressBase.__reduce__ + + @property + def ip(self): + return IPv6Address(self._ip) + + @property + def with_prefixlen(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self._prefixlen) + + @property + def with_netmask(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self.netmask) + + @property + def with_hostmask(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self.hostmask) + + @property + def is_unspecified(self): + return self._ip == 0 and self.network.is_unspecified + + @property + def is_loopback(self): + return self._ip == 1 and self.network.is_loopback + + +class IPv6Network(_BaseV6, _BaseNetwork): + + """This class represents and manipulates 128-bit IPv6 networks. + + Attributes: [examples for IPv6('2001:db8::1000/124')] + .network_address: IPv6Address('2001:db8::1000') + .hostmask: IPv6Address('::f') + .broadcast_address: IPv6Address('2001:db8::100f') + .netmask: IPv6Address('ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff0') + .prefixlen: 124 + + """ + + # Class to use when creating address objects + _address_class = IPv6Address + + def __init__(self, address, strict=True): + """Instantiate a new IPv6 Network object. + + Args: + address: A string or integer representing the IPv6 network or the + IP and prefix/netmask. + '2001:db8::/128' + '2001:db8:0000:0000:0000:0000:0000:0000/128' + '2001:db8::' + are all functionally the same in IPv6. That is to say, + failing to provide a subnetmask will create an object with + a mask of /128. + + Additionally, an integer can be passed, so + IPv6Network('2001:db8::') == + IPv6Network(42540766411282592856903984951653826560) + or, more generally + IPv6Network(int(IPv6Network('2001:db8::'))) == + IPv6Network('2001:db8::') + + strict: A boolean. If true, ensure that we have been passed + A true network address, eg, 2001:db8::1000/124 and not an + IP address on a network, eg, 2001:db8::1/124. + + Raises: + AddressValueError: If address isn't a valid IPv6 address. + NetmaskValueError: If the netmask isn't valid for + an IPv6 address. + ValueError: If strict was True and a network address was not + supplied. + + """ + _BaseNetwork.__init__(self, address) + + # Efficient constructor from integer or packed address + if isinstance(address, (bytes, _compat_int_types)): + self.network_address = IPv6Address(address) + self.netmask, self._prefixlen = self._make_netmask( + self._max_prefixlen) + return + + if isinstance(address, tuple): + if len(address) > 1: + arg = address[1] + else: + arg = self._max_prefixlen + self.netmask, self._prefixlen = self._make_netmask(arg) + self.network_address = IPv6Address(address[0]) + packed = int(self.network_address) + if packed & int(self.netmask) != packed: + if strict: + raise ValueError('%s has host bits set' % self) + else: + self.network_address = IPv6Address(packed & + int(self.netmask)) + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP prefix string. + addr = _split_optional_netmask(address) + + self.network_address = IPv6Address(self._ip_int_from_string(addr[0])) + + if len(addr) == 2: + arg = addr[1] + else: + arg = self._max_prefixlen + self.netmask, self._prefixlen = self._make_netmask(arg) + + if strict: + if (IPv6Address(int(self.network_address) & int(self.netmask)) != + self.network_address): + raise ValueError('%s has host bits set' % self) + self.network_address = IPv6Address(int(self.network_address) & + int(self.netmask)) + + if self._prefixlen == (self._max_prefixlen - 1): + self.hosts = self.__iter__ + + def hosts(self): + """Generate Iterator over usable hosts in a network. + + This is like __iter__ except it doesn't return the + Subnet-Router anycast address. + + """ + network = int(self.network_address) + broadcast = int(self.broadcast_address) + for x in _compat_range(network + 1, broadcast + 1): + yield self._address_class(x) + + @property + def is_site_local(self): + """Test if the address is reserved for site-local. + + Note that the site-local address space has been deprecated by RFC 3879. + Use is_private to test if this address is in the space of unique local + addresses as defined by RFC 4193. + + Returns: + A boolean, True if the address is reserved per RFC 3513 2.5.6. + + """ + return (self.network_address.is_site_local and + self.broadcast_address.is_site_local) + + +class _IPv6Constants(object): + + _linklocal_network = IPv6Network('fe80::/10') + + _multicast_network = IPv6Network('ff00::/8') + + _private_networks = [ + IPv6Network('::1/128'), + IPv6Network('::/128'), + IPv6Network('::ffff:0:0/96'), + IPv6Network('100::/64'), + IPv6Network('2001::/23'), + IPv6Network('2001:2::/48'), + IPv6Network('2001:db8::/32'), + IPv6Network('2001:10::/28'), + IPv6Network('fc00::/7'), + IPv6Network('fe80::/10'), + ] + + _reserved_networks = [ + IPv6Network('::/8'), IPv6Network('100::/8'), + IPv6Network('200::/7'), IPv6Network('400::/6'), + IPv6Network('800::/5'), IPv6Network('1000::/4'), + IPv6Network('4000::/3'), IPv6Network('6000::/3'), + IPv6Network('8000::/3'), IPv6Network('A000::/3'), + IPv6Network('C000::/3'), IPv6Network('E000::/4'), + IPv6Network('F000::/5'), IPv6Network('F800::/6'), + IPv6Network('FE00::/9'), + ] + + _sitelocal_network = IPv6Network('fec0::/10') + + +IPv6Address._constants = _IPv6Constants diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/lockfile/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/lockfile/__init__.py new file mode 100644 index 0000000..a6f44a5 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/lockfile/__init__.py @@ -0,0 +1,347 @@ +# -*- 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.7/site-packages/pip/_vendor/lockfile/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f340da4151e0b46027a4acf2281073910c3fa015 GIT binary patch literal 9916 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 Hm5u)ckME(* literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/linklockfile.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/linklockfile.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bd4320fc56883c872c66b11717d49d51cc63bcbd GIT binary patch literal 2297 zcma)7&2JM&6rb5|ZyXcAqCnbeOCewhFohOGRRX0gs1h}mf&{FPR%_2Vti9`XX2yY7 z=2AHJz@e8`s$?H4_0(JcmA$r?Tsd;;d$SHCD6KluzIik6y?Jlm`_0>%i;F&i@#Av) z(Iepg!o|+8fVlym{2mA+jHV=`A*IM0sSz4_Hbaw{%u21y4(-edoy-m0%nQA&5>_%l z^eMSbn9ZCQggM-PZiWlYSR)O08%`w+S{#VmGEYZ}M@cr!g=%e66gY)<C-3xc#*!C4 za<}3n<*cZ*a)rw|``s2UiUp+il8omgRV;p)3LY~p;jDvxc7_Se4fy2eKsX60BXAE2 zcUZ(*yr7{~#v0npW!?)CI;_Hcm|eEOsxW&x`dU%FlMMPgE(mM<D{?{H>2N6nl?QRq zh3#M@lfilrt2|3O!BFHwF4R_#cY_p+&s=Pr_x%9I>gsBc;sMu!-KU;8E%S`yL8lx4 zQ}1k`9^>6PyLKy1B`@t-9Rse518eHR_Z58d1SEQ^uE>P+D5KAfsWBsz+$Vz*7Exy3 z7ndolDNz<PQ0EAFPJf^e$-sC(CXl&)MSMM>0}EvKGpd}aGb7K8xugfP*|$V*0y|e= z|LGs#%bj|75`2}Jp?&=XzWl!bl8XA=n>$@Vof+*_pP3V=O5YH_GqSeh^Hu3-V!-LI z;KapJo1z>&{;g`vhP?x2yn~urV$Rz&SRX871fM=|?lO5vhgIgy0NW4AM*08{z6SGs zJvS<?!g$giAMR=ZVs$%^V#R|~QXo{fF}dTFIr@SpaiXy5h=R_>C=tA@Z8sNSF|MDI zK_Y{=gs2vAwvDfF{g<C{{CT}`sIUMkgJNMcNH#`18pIhd>`t1)TX4U<`;8E}5H^?; zu9{=sLZ&csSy+gzqJnse5Ico?cTHOqmQ=ASJgK6A)^SF976^#K8pZ&f3bM9LIUhDG zFyLud9Kt=14_KsqINC`5MnnLD*PG3uNH!rI&COUeyLrmEkj?CIv-8O?x;nnvyYS>v zmyPA+OPk{2Q#H;mz*rwN?=^?X@LV#0n9}szXII*f`=j<cZt5@E1c$k3;x+IVO^kSF zaelZ}xbx&5gdpSvAcPvUPHVJo9HJgwqMiW*c9x79^-RmG(<<y+M%A#WPfwcT`tG-O zetujBD~bbW>=yc^U<aI#DVY&@RKZ&TG#PVry|2ukG1YHiM&+l<(QjogRp!(MT^o@# z=QYX@Uk$T0UMj&b$kiMO<K=P(Z_3%(pgmFnO50mO#v7HQlE|o(2?t^l%Sh@#3Wq;U zq>|zQ?zl*fBRK-3LB$8i2XDwnz!k3GDTnrY1s1Xjgy_80Acs}@PIl(1`)8*HrV3u{ z6uX2uqi{FcYFIk1GQyLf@gJdxk3oJNKB@Z@9Us|Knm2de-~AadEQ^z`C<?_eAq;Cq zaW%z80DRA3w2!|Xqb2aF4OjboH$<JhqaYW@P-*|XRg);rbQR#4-vm90rNHFX==j*) z$aiV(AN+@4xjT2_xFQ-&kVpK}mbtXw4HV0&3;ZuJ`fX@YeI4X&P?gyC3C8!{p7`Es zVZ|zi7wKLTMTH+lS<Xf&2fi9b8>2YIE(9w#idf!>B5?v^IE4huCsvT0MiT5L2sVKY z4nGYv&$bMI#q&JVv$dpAMTgyy8VPVA5C!5e5)Ex4FnrzcO4Mt3W7pFCN}sTw)580r Syu&I!W{Cz>!-K{USpNXEi6*H4 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/mkdirlockfile.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/mkdirlockfile.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ba3d12e8ff4aaf3345c4060dc23853e7e8214b16 GIT binary patch literal 2659 zcmb7F&2JM&6rb4-d%dv}6G8|dhZSm|ZXu?j1tFCbC{R&Bij+uDtJP}bSto1nhch$I zhvi%vjy?5OPWG{XLZzPj7jT+WrJlI<*i+w|wF!xG>8$3>%)Z&3-+S-(-aM>STmtRq zOB+8dlnMD87n5ee<UVx4Krq5+OcL6liP119u8r7in0mAtmLBbft;a&6z)WVv#l&ei zNvTmv+=iP>HKvksqnuP46-vG#%w~nxgcU;P&}>XIV~x~`@8Bd-Gt^A5A+oq9LqAHo z8JEgo(M}|yEM0v^aZ5ot&$4FcVIV@~;_OKf#UWFr)lA}YJbk{83pIsuJxao?CspM^ z%)@|bO~{&f;-r}{xer}D0uho1Wu##+3RYH`#q8G<>^#E?tOzrkIjr=WfTb>*g0aZT ztOBFMrr8XPC1!#}v#RpE!y>LB0>b_koOvyndK>#*6OhO#-Sh$vHib=@@%^Rs)h4<g z8;(WjUqctSK}a&B12UikV_=RfN~F;?ht`0!Z3ge#1?WZSPRpDpBV$1Pl6I`w7p^yM zD=RBrj3DlL$Dn<DO=L-k$gb7?&*tl%+(L(j?B0_g7U9vy{o<lnS`>?7wdQgg&@0FH zqcoDfuZ&D6s~gBIWwo;?RV9Sv<LS!T%7jdVBvf`jnB9n}sa_gw_d*{PHA`6{j9YwK z|8#P`D#|>@zY)FwntyleT^{WOGOX_eyxz)U7IINfw(8B#y8hk%-S*AhTP@ZXw{Pw6 z<vrO?ZbI8k>+AJy)V&d<LI!bs<BK~RTb<s<Ccf0&-w9Ke@j60A#PtM2JXtMu_c^2z zL2N>2mt8eoTA&u~&mZ&n(!?801NLG=Cppk{ysN<U0Z_10;^hHNG0NnCN;;$?a$t-# z%P`W8#g~B*^v>kH!|yZWz)Ytl&=+=?m&hTk_x{+g$}wL?l#-Vu{ly}(&~f=cl;9(a zLuW*ob%7jM1FKz<rMBBK_+Qd&PYug}pfaNT4I^t4WN&jk0|PL;9b@@ZPBR<!PR)}; z`V$2dGYpwIUc(nvU@x2xnllXfYUew@C)+Px5jl(JFz3)1o*e-uJZ<~MOFh;~s~ii! z=9^!!{r=TE^f1Rf>0cdZxVIZbI;mvl1<maqBvwxNR>r+W(VtrsUL?FAF9TW?vi{kY zt{@(Kq_Z-Ft;*QlsLk>7@ONb)x0IO#d%S{cTL+z2abEmx?J?&WSEkq($_e+HK=W3n z?2z*`Q-#NmUp-x0&)HfC_aY$$pMwv12?bi9Y!QcHmltquW!*4Ub~DZ(n{0j#H)#wG z@XpsbEVNOX@PEzpTwK79i(`{7!9py9Aas^Gv`QVrp#@{wFsK2mX<DXbSXp!qw3bme zE$Y&;IcHR9|J-q!j{n$1$7910OQmM%3z!VZkc@~}kibQVoiUF4WnhhwSEmsbpUVP+ ziZsyz4|U{`2QYU)Q^Gk$yJoKTt9g{tOim(nDSv}`7P9N!Mo)UEg)#~i!BwS5__>Z_ z$<*G~q2eFmQu`ZoOBH%)9Hkv)^90gXN3ce7FJsmC(3d=nL%3odz-xgyO|&Pcwf9bX zX}tGzFJUo|q)mtD0pLE^NLOoCjt`YNNMzILSon2NJ%uiGt)Tt$$7A%~_|wmyhcELe zWpk23R7}8OO>o%y?<c{a$4&>M%8?%=+S_n>JwsIb#scs3FP^~l!N&K{(1iEb+PARy z&^7$Y-Y0O)VYvfGJt99|grY}=w%&tf#2nC(fmGSP{1Pujq>(NsnmXWC=cFZhlE#pC z81Nf#AfG|81fpi>&?^fsmXpckZotjf(S{<=1@ebL^k?Zs+Fv+s>Cx7jvA&Aob@9H# z-@<+8`hJqJUX1gy?{D{lc&sV<KFgZEuP+V$DICD-C@|psCW>1qj;N_;nCpBB1kzF< zgCL8kTXC;Cj$=BO*41Y4+*VKaIGoGT?Hm)AUq*ptjC&}qfKWtV(YgZV353QTRVe+# X(@-eq%iOXRtP46#s!(e5V|dnoAHI4> literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/pidlockfile.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/pidlockfile.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5798520be847c16914fccd9f4a50849d4e3a772a GIT binary patch literal 4859 zcma)9&u`qu73PrKUG8cn%eL&ea9Rw~+Rg^DmD)+26s_YQl>-Crs<74CS+t<2omq(z zms}5LWoxkt0^8^*r=HrN1uURFw1*<60{s_y>7^$g-IGtf_tftV$<<1=ixMC?Gko(n z^S<}K_vYs8Y{SC!<=OS0|LrZy`X_bD%SGcl?o{I;td1p^up`#DJ2s=X6FD8nyxop# z-jz;8xS|qO`?XH3?{&O>y;JWuI*tBJXQtomG@13OC90zK+!8fed**azg(vFIt<Ici zh#9<(iKdvvdtNyAt=8P=BYrpOZui1S@^!fx?1afs@vuLLWM9Tw3ceEt{HJmFg#YBu zk2uMtml_<`E3DaSvFuo|o+i;yOCPfmrQ5F<eW+$0DZUw`GMl{-DH(`e8jvDu(ED}( zRU)gm6I~2b^T$Reo1vlAurHIL?$UqC%R%Eh?({Am(&{i+%@zz+Ize`M&R{3Ad)O)8 zceU7eO`J44XB|(>iDR%pUCfK)csGnC7P1*^(5ws#3vOT&2bP((N09O(2D#KQ23g&d zJi@w-k$6aAaiaP`ln=x~AJ$yo<r;E<)+$_w(fHaR(3@+yNpG0>7t)ETc{ho55XPh{ z4dV@f6os+mNsnv!L@$=#@yRTKR1Z|rm1)X>*1OnI%Lq@6>&-y(p!;YTDy)ZQ(4vby zT)TEH-@^}S4W%{Sy^tn-N!VX#ng9HsVz=8}a&fxoUB!J1cltIS+Iqpp)|d%4cJ^In zjjb(vZ269`;Ffm#cFR>XC-Zzij6?1FnM;<+W`=S2XefO$XUompR7O43G?IFgybMlN z)4A*X(Nf3p<=?}lfeLp5EthrzwbV-@AyvB6-(2c`ci?|K`grU8$5(n{lz#8Zj=KCr zkNWT9+K87{mj>bBBFwLYD7yIJ)%DHo;ra#*n%m!zu}IVs*^i8aK~c6Z4R+NG{{0=? zsWE~x&qfPVM!i&StV{7i7rkxV#zw>%nykW}F<69+F7i*MHh4h^@2R9e0na#C?m`rq zbhYg46j{T^ntT$b1})Oqs>ReC^c(Bsj}z!-UOD4E^io=i<s4pfDR5}b4&=<5NvFn& zUjWH1wx6$ihp)<1^AIju_!`AVcc>KjCEDeiG7^RN<xA&$bxM#vmy^xLu?OBu6tqDN znVZWeVXDDO#x+YFEhn>+H1~{ZF7bw4*Td8&JyI-T{rR@5qf^sRO(b5w?=zS;wq98K zR&rWn_xsdy_N{H(Ah-Wo3z&@+bWm8MjNPfN+>?5!5dUjyt7<6M)=E<xnL*Ls4|I1^ zrex-cCE{U!T`HdHgn~Vc4F;td4?G6JhTLSSQ+Q<64XNQQY5|=$n5-H4LEjh+%ySiT zrPa<Hvf7kT*LV{oDHh1Ljl;Y|gD7CTu9{;OyKoz8kHLg&-`cZ_FPHJQw_SC4jFGDt zfAXi@IZZC+JY&pyV8y?3E$wbM)IXTD=P+xe$IezoSGKC#w)#u1ZA==zDl~psX#7&w zghP5xThG{27SCx<&>D(9X4Z=tf5y9V)*5^*s{8mSBpaf3Ao+l@HQRGOcOF`wS&u$= zi2i-NX&f%#jef~*<cvEBf+>t|A*yr^+yV0+a`8nDhgU(ELMn*4R0{pDH-UK)S>0ra zaETL*WIiGJ1DxB6IA(OdNUi*F5NaUEby5oF5k)^gmyQ<Br6!N%+1q@Q;uWE{@zrnW z`s*j7lRcBjNk!M}0~1>_Y92zFOFWz{JXRs910o`w9HODDwsL=&_L5bwr8vo|%gYb% z++S67%vKdrQAr~y2Z~Y$oYat(QSE_xeWTuyPr65mtXAZ=PcSVd3btw|n8)UsXWPtX zb7(c~CZ4X{v|ZL<Z`<4+ot$>wLc{9={`=6F2YiZvM+!so%6%vg{B%*ff;_Ys)fH-! zx0+hR9sPmdlc+LM`8t0f3cDx!$<9%qfQ{9WX@@;y;t-^w^b+%nqkJI}C?`MJL^gcW zB1ZGM1CU(KkfXEtNZwoIC}DDM+vR=PZdG#{slhykdDS<l<>8UNrOb|eL&fm9(h=Uk zFtuW%KIW$6aaPR(Zgd~UsgOH_(<F)J2?@4G5~YfoN{i7`eiM$mZ32lh2L%A_XDTAe ze6K|SSu8~LR0KqxRsaFwPd!F-ax&{75Ma7Z{NRZ0cFR`emj5dmH`ZyDhGZi$f+5h_ z==8Lc9*DH;+wB%>w`QndqS^=rQ^WWBi5N!IZu<VCVGtExYQ8U$uJ4-?#SncCoPq1x zw6JsZI8P6%pr#&FC@2DiWK)VoukPB7s#o!FHMloxzE1EUz9$DTe7}wcc#?s?5kJCy zX7AbH?*;HT1Am`qsDT(5H2&zJHMS{{QX1WJcAMHAgYEZNAzgv=>O|T$($#&;9TUdR z=wE;@$o-nKos!)|p)xEpU|x&U7b=OSz%jFeSYQU_T@x6{p;CoiL(LOKI0aAzen{a2 z_=#eEC$D<S0p1Pbf}8=aFu_|CMpWseAOhb`)R1JrcY-Js^z+4XQEO}MBt|VTweEJt zRI8S`$w0<g?aoThs-~W!0|RIj=Z!(;gt5*VKMSIvEO@sYB`MX>&7wT?O_A-Om(_}) z%q0~^UEn03+`*kv@nd<eq18E7Z8p(rB223wTSZb6S0EB6Qa7$}4-Kjnaoabk<=jN- zhjZ9C86XLd+1TE9_8jyoV@KHg_MVG2K;Em2-4~R&E2k|=#^`wjy>J12W%xA|^9Pi2 z40>exqV9Pk>SbYFB0YVCdilj~q2lEizndJSj!@|YE^-@_>WCsh)s&R;Uy_q?b8ehI zy-mRv{vLTbV~<D9xwO%4)$>BEw&LHqw|rwYtFHLV4{zPgycPe!y_NRe&(tC|nN@p& z@K%ICRx!U;m(d0dU%{)>ps#)}3O3SC-LydmvePJ`?g{lF<kScBI0$nS;dDg%HSUxs zl(MG_NSk%yUq#<0pb{-j>bcwKP;ArDj-WxbUPf%&h}P?<%`h@r7_%)$J6kSlvrDo4 z6f&lEVxKdronpjt!P9>)D0s?{lQ_zG_`eE&!`Z~=!9gKq&b!3R@r5JI%?CrB@*!#* z6X+8lg-p%a7{@*>7kQfS$C8H|ILzlRg-{i!o07OJ#tpt@MxCfJtD6G3-KrD?cAg5= zH(@RHEj&>7v{#nftH=rjoO*{IM*yL8L9U(BS=aK4B8J&{B5560?_roIzc&PPf$|k0 zW7M0!s<ZUnGKXqYTA7+knN&^uoY!20qzPIBa-O3O7GhfD9+~%pJhNPzMK7fxs-!&R PXV2#D{4czByfgm+X$sem literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/sqlitelockfile.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/sqlitelockfile.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a271d1bff6d169faeb62bfe2476e65de54e10637 GIT binary patch literal 3758 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 V@<mQ>%q84G9^E}iaK7<f^M897lq&!L literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/symlinklockfile.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/symlinklockfile.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..96775a62acae8ce3ddfaaeec8967fe9400e2f99b GIT binary patch literal 2182 zcmah~&2Jnv6t_K}`;m`^&^ApdBcRZgXtt!#QVB{Z1ukVdBvN68G@4z{CX=0yjqORB z)%HSj<bb%rq1qg|azo-T;7^z<r~C_?c+WE-C0z-xY(GDHo`3$mkG(%PS0~VZSnYlH zAxMAW;<T9{Y(ke0Vc>+*m?X4IDatHnU8ZNFYjA^`v6)z1E3vzF;&h$F?Yc>=TchMl z!Yyte5pIXpGoxGQY>Tv<6R=2Hv{(pwGK+H+`cX2<gzB77+^`DwVb&ks4`f)>I+?;n z$hG*@Aufsrj@wZZX1OZnK8-~faJ>`qKH5HQ1_+zb<pUT((xsdLZVH$exyh{~+BNwF zZgU4Di@UsbM7lPw^9IZgZ}K^qT|UnjV6JfkurC!0TZc&;r9*`9MHGkQcTn<zem|7b zQ<)cd15kUpjM5!XmWQuzwAQyfedH7y&NlSVpv&tpC^DrJGNBVTF^)}26x%bV=7j87 z$CT3*G9kXj3Ea;*0w2|~1==WF-;dHr`F_DNS(u|h?G~0C#gQr+c^d8Kp`Qjx*fI-K zhVei&^+#$K2?I(URdV<%5lgW1_hEY^qJuz%?SnwH2U*NRA=}AryZ_$EzdOFWck}VB z0UyiTw+_U{6E#k5Lfc8(+wD;_x)G&P1#x`igFC(5Vcy$8rSASgnDR`tV;~B-X;-YA zuGdG00t0aly3`!8MK->Cj_CE%xAqyF!-h<_&^3*Jf-nIG4{M@1p(&C_o>E1p^q4$l z)y@XYbZCkVAe!C*{ga;#mlc~DaJr<MQSykS$|TAj*2N!`;BP{v&M^@jT~JwiURs_o zu=c#N`lE6=1534w<Qe^*rt_-K(Q>thFB;X?zrk#-l9X|9FeTrT{rA6t#M*-Sk)B(2 zM_@9H->$;kdmKaxBMKv|zn@1U^pHPqkO}Xa94}v!UL?Js%muv_@)Klr=a-+c{r*X- zDK5aeFwyIxfud7+Ld@f;h6a7~P~m*N^|=t4D4LNUBtCAy<-&nuI*0`F4xtu@;izSZ z1=MTfF1Xs)7hpu`uoAD}S*Jpc3;7ld#9pE<U8F99MwjV4bD3!@gU)14X3{$KjPa%O zK~P!gBRSY`#yHS1a1R9V6*(sIvI0*7_pI{8MbI0dUstB~QKeVb)P_?IdO;_c(HSq6 zRHm7#XdJJW8e}2l?|QvldAQp<^dPs~q83TbP{@S^2ugxhP{JfHnYQy3tA@A)nieey zJI{~^;}DA8Z8##)bEM>l&eNB9sLsyj0llfn9-U$|8pjk02ko>>jijsrb|n7?j(81> zd<<Rcbfe>y^RD>!)w4l(=Rjmvp~_*B0U#KyA^sNtEc*<Wz;84~g^MLhL&V3-W=tT* zo6yUmfjq6f1oDOOosIJ<7<iE^apeqW6%>HdnuSu}x3jSo^&Y%nsN>?ne;{5t5Ap0^ zi*0w1k~$W4EZk7o>%O04JdaUs`u=_%#MO@D`#kIWzOJ2O4K5L{<A9FS)QC4wI*T$b zVg8943>aY&$;E`L+x0hH$2DA2@3k6u?;uyXfO`c-K>7YxK`My;^C@FpN4PEvSP}Hc Xvu-ThkIGlv!-SQ1w#i(`{WbF+Kl1q> literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/lockfile/linklockfile.py b/venv/lib/python3.7/site-packages/pip/_vendor/lockfile/linklockfile.py new file mode 100644 index 0000000..2ca9be0 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/lockfile/linklockfile.py @@ -0,0 +1,73 @@ +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.7/site-packages/pip/_vendor/lockfile/mkdirlockfile.py b/venv/lib/python3.7/site-packages/pip/_vendor/lockfile/mkdirlockfile.py new file mode 100644 index 0000000..05a8c96 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/lockfile/mkdirlockfile.py @@ -0,0 +1,84 @@ +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.7/site-packages/pip/_vendor/lockfile/pidlockfile.py b/venv/lib/python3.7/site-packages/pip/_vendor/lockfile/pidlockfile.py new file mode 100644 index 0000000..069e85b --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/lockfile/pidlockfile.py @@ -0,0 +1,190 @@ +# -*- 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.7/site-packages/pip/_vendor/lockfile/sqlitelockfile.py b/venv/lib/python3.7/site-packages/pip/_vendor/lockfile/sqlitelockfile.py new file mode 100644 index 0000000..f997e24 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/lockfile/sqlitelockfile.py @@ -0,0 +1,156 @@ +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.7/site-packages/pip/_vendor/lockfile/symlinklockfile.py b/venv/lib/python3.7/site-packages/pip/_vendor/lockfile/symlinklockfile.py new file mode 100644 index 0000000..23b41f5 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/lockfile/symlinklockfile.py @@ -0,0 +1,70 @@ +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.7/site-packages/pip/_vendor/msgpack/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/msgpack/__init__.py new file mode 100644 index 0000000..2afca5a --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/msgpack/__init__.py @@ -0,0 +1,66 @@ +# 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) + + +import os +if os.environ.get('MSGPACK_PUREPYTHON'): + from pip._vendor.msgpack.fallback import Packer, unpackb, Unpacker +else: + try: + from pip._vendor.msgpack._packer import Packer + from pip._vendor.msgpack._unpacker import unpackb, Unpacker + except ImportError: + from pip._vendor.msgpack.fallback import Packer, unpackb, Unpacker + + +def pack(o, stream, **kwargs): + """ + Pack object `o` and write it to `stream` + + See :class:`Packer` for options. + """ + packer = Packer(**kwargs) + stream.write(packer.pack(o)) + + +def packb(o, **kwargs): + """ + Pack object `o` and return packed bytes + + See :class:`Packer` for options. + """ + return Packer(**kwargs).pack(o) + + +def unpack(stream, **kwargs): + """ + Unpack an object from `stream`. + + Raises `ExtraData` when `stream` contains extra bytes. + See :class:`Unpacker` for options. + """ + data = stream.read() + return unpackb(data, **kwargs) + + +# alias for compatibility to simplejson/marshal/pickle. +load = unpack +loads = unpackb + +dump = pack +dumps = packb diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c2d82a94d027bd8ede6c71f77430a34bf0095bf4 GIT binary patch literal 2078 zcmb7E-ESL35Z}E!pD!0DP23VhL(2(O0wdLKQ$cBk5EQBc6(wrZuM^Vwe7jEE+*fzk z`LJA&NTj}${td|+{6jqKD^L9wcw%PHHZ2MdthKXqv+LRU&HQF>EG+m0#*5Y7kH5Nv z{D~ja;eql6O!)^0Mi@;=Mng(bw^C~ZS39*cCv+&eMVP~ChlJHQtjs;I4(zZ7C+evi zy4-zIKk}G&Ohp%LbLm{>hkiC6&S#CVK}r7IegJkqT|m3JVLn~_Xa6C|KXeE`we5@F zD8b)JULKR&dPG=*EgX_?i7m2Iur9MDwhU{NH^b9>K0L#h!ngQxxWel9NUQk@u#pzk z^&KwcpvXa`AA#`mIO9wW%akX0WIF7LA_Gu32`M9?#b{_hCw<B+W*>T?^PD&&tbuz+ z*Kh8rjs233KA0$h;HBV_=Sl{APX!7#gFzl-a<hz+?RGM~0oNK#T;&50ij1kE2bOFq zxbcAgLcwAw8!Q*VVxfiEW9q<PwyF4(Ionj;$Sq0~l*F8`DR)c`tfTrEe2uMR8)9_t zjFysu@gN&Y74$F|HEOb0#WPE9UvViY#PI585ToWB=P&(qdF^V;)BZpXa;f4x;o1f# zdJci#6rvEiW?X3hL7Wb!COIs*5C~D%qbTRQQPi@voupDbc!72>2&lze6eVdaWfc8R z{(9Oe#b75^yt5OFPQOSQ6t0tPb&|_vbZvC)$)(*ZeKwMxT-gz8duo(jg0Y!*Hag{? zyl4VU(~BQp?QLxjdz)x9Guq)fD@12fhE5a>@_~w?cDXMWAVh2vxd?(#pL%Alz&biL zDQkO*z||h8K%OYleiUT|8>Xl?qUh-`PA5A6m=#GB8Q*$g0x;oe3brQPVnmCIWz<ij zz(iq7N(U9{P-7X*nOb0`?u5<n@7-Ge@~hj?`u)2%*B@_u^TQp;sJjll;zHMlIWnxL zz57Pt0{p)N&RUi@3yW9<kys#b;4OINZJ6>r2u1opx0m!8Q0$0~?IUYUj_EPJ2NY;z zjUM>{47@BTdQW(wf^N|b;+zG$VxWLmK=vZ&N+o!lb$xUC9_PVzQ{3y_D$H)sFGNt3 z3Yt;2%^?6`;?y<cNIM7vdW#m?t-NV>dp8!FQoFbXteT~;%H27L|2+hPsEF%RftCar zjRP@bn;EQ2pct(5CE^5(fR2tH{wF%Y)llStxtRrq=>G#8Bp+*F0s<W~Edms8LeMqz z-)q5+G$nGy`=HMtVE8i#XW(N@j>s{2W+~|NJ{<!X1LK8(Q4s)YGp$r#6xpma?JE4c z@j!AJbb;X_{u&6@4R*J9K06j9MXqA#D1666Tp_P2_Ig>TWILg-ElWE<24?67MaB|U z;IRn*&VXC-cMZ0xI@UcZF2GmoZT&9vaeLCk?dekr-{wshm@s|*q$7MU;T6^Nd{U(F z*c;vn<Vp23S%uVfp6?7qk!yRCtCR2Q$7$Mw3RT6NwNtoy(ydX&((v4gn-xrG*!gd> zvJlF=poSl&<OZ^K(jsQMh7z7jHq1(0Ln&X&nqd&W9oqY>dWSy8Oi0XGgL+oOUTJu= YL02pb<Qck1&)S~v&3O%nI+jEK2KtQ}M*si- literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/_version.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/_version.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b99aa336acdcacf4edf6cbeb8511c212595a1686 GIT binary patch literal 227 zcmZ?b<>g`kf*$Fl7!e@-7{q}AMj*ohh>JOZL<&O`LkeRsgC>(E^GhI~;Uz1GU;`3< znvA#D%TkMqGxPISG8BQt!NjjZ{eq&*vc!^9{j$U&{j~g?6rdvg+zkC>!-9CrD$6W` za^tj=s$w(avLd63lB!$-AV|;C5795kEYQu&D=taQ$<Z}6Ps+$HO-cs|f^mFVYF<iy lk$!G*dO>1xwmy&#wp*{D@)n0pZhlH>PO2Tq@x?&Q004unJm>%b literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8eafe6d495bb7b02d64b2bb10464699ca8504565 GIT binary patch literal 2183 zcmcIl%Wm676eUGUqGZdKU7(A$FlN!BQBaGCjkX9-6h;y^2nxsrnq;9A7*L#%%!VS_ zAt^hAclN67CZEw?;<kU$RnHw+56d=SFEYZ6=FH>Hz2`powAE@FXn%h`_>I|y@h^c{ zt73A1p8kp9g&_=KUZ6|k-0GXa6=4Be(gdym+oB3w)z|{Ai8^pyn$kYE`&FzsqJfo$ ztl~xuxGC0v*R;es@VaOLw`5)4aImr=HnFlP9oc}4rfC0abhdoxGjAql2k2=VgEac4 zF!~i?_AODtS*zT99VMRs?(o!?NfyLW@$++;DCv8d6kWz%r;^S0SP-R|^aRUdh6DaF z^TLqH*;OWT6+|PJYl)b3dmX!UIFG!s<h*QhK8{5m(tMrsKXNa;+^KUeVxRMW3{``g zdiXDO6BSILhdc3<JB&jiRqBq9UH@^ypA=7ie{`}x6h->o{zUDaX2tjs+9+~gxk-@h zlB&>d_uKCW$M5pNh!%C{6B&tEx#M(1hP!k1({A!!5na^N3I@m2_+~!WabUqGxU7`T zr}=Ow)lYdC_Bxg#5z3+gp|fP!)W$lkIT$F8X3r76^K*@(JUbdb_cHH}uQec@`s_8D z-~8Gw!P1@v%NsAu<)KosD!#lHEsM=rxKJ3Zl0il<e7(d7<y&h>N5WThBvudTz!w-6 z4iJ?K13_&G8~;c(IHXoK4o@@X5ko%tfg1gjh-c_JC(g_>gBxcRjK~dKGkb8QGYw)X z%Bmz8$P_!3;ZTv=6)Cu+J-L$NJcxpf^KFt$9yiRIS!~Z$=*|xK6kyb5!KQVg8^WYG z>J>ZF*B=Zz45=uCi4;gPsKEqm>FTFDrrN-jRW*=GX{I>;6nomwhFNSa>!5dgo$9Jb zHc1%yeMzEDMjfbY*w`YGq^4s!wxSguecs5L1N7S}P3xB{b>`)@$hmKwq4d41GONbi z8eU|>XQU*>0P>sgy{y<ED;6<c{B;$xAZ5x6QaJ47SVk;+pGX!DkqSwkY46dAG*6OP zp~A8OR)g&8luan7XfKcEyWM7!p<N?t@%%i+^uhb&8Aa*NoCsSHz84W&WcblUs$m$P zOpC#XYfGzi1W_hOQZ1~FVL#|mUNq7?T~_58L+tJD-ouCckH2B`x7YcYjC=wHzFK00 zaIdpQMdb3^sJ{lfW-BV4Wpm*OMRiK&gbpc9XW6<!k0OCLC0FVEF#Rt6sJ}dv)oq)8 K+jhHwvHm~$s@W0% literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6425f1af3fc1f4ae963d5cc810f3f211f62af15b GIT binary patch literal 24555 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 F{{tR?r?>zB literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/msgpack/_version.py b/venv/lib/python3.7/site-packages/pip/_vendor/msgpack/_version.py new file mode 100644 index 0000000..d28f0de --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/msgpack/_version.py @@ -0,0 +1 @@ +version = (0, 5, 6) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/msgpack/exceptions.py b/venv/lib/python3.7/site-packages/pip/_vendor/msgpack/exceptions.py new file mode 100644 index 0000000..9766881 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/msgpack/exceptions.py @@ -0,0 +1,41 @@ +class UnpackException(Exception): + """Deprecated. Use Exception instead to catch all exception during unpacking.""" + + +class BufferFull(UnpackException): + pass + + +class OutOfData(UnpackException): + pass + + +class UnpackValueError(UnpackException, ValueError): + """Deprecated. Use ValueError instead.""" + + +class ExtraData(UnpackValueError): + def __init__(self, unpacked, extra): + self.unpacked = unpacked + self.extra = extra + + def __str__(self): + return "unpack(b) received extra data." + + +class PackException(Exception): + """Deprecated. Use Exception instead to catch all exception during packing.""" + + +class PackValueError(PackException, ValueError): + """PackValueError is raised when type of input data is supported but it's value is unsupported. + + Deprecated. Use ValueError instead. + """ + + +class PackOverflowError(PackValueError, OverflowError): + """PackOverflowError is raised when integer value is out of range of msgpack support [-2**31, 2**32). + + Deprecated. Use ValueError instead. + """ diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/msgpack/fallback.py b/venv/lib/python3.7/site-packages/pip/_vendor/msgpack/fallback.py new file mode 100644 index 0000000..9418421 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/msgpack/fallback.py @@ -0,0 +1,977 @@ +"""Fallback pure Python implementation of msgpack""" + +import sys +import struct +import warnings + +if sys.version_info[0] == 3: + PY3 = True + int_types = int + Unicode = str + xrange = range + def dict_iteritems(d): + return d.items() +else: + PY3 = False + int_types = (int, long) + Unicode = unicode + def dict_iteritems(d): + return d.iteritems() + + +if hasattr(sys, 'pypy_version_info'): + # cStringIO 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''): + 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, + UnpackValueError, + PackValueError, + PackOverflowError, + ExtraData) + +from pip._vendor.msgpack import ExtType + + +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 + +DEFAULT_RECURSE_LIMIT = 511 + + +def _check_type_strict(obj, t, type=type, tuple=tuple): + if type(t) is tuple: + return type(obj) in t + else: + return type(obj) is t + + +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 not PY3: + 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) + else: + raise + 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.", + PendingDeprecationWarning) + data = stream.read() + return unpackb(data, **kwargs) + + +def unpackb(packed, **kwargs): + """ + Unpack an object from `packed`. + + Raises `ExtraData` when `packed` contains extra bytes. + See :class:`Unpacker` for options. + """ + unpacker = Unpacker(None, **kwargs) + unpacker.feed(packed) + try: + ret = unpacker._unpack() + except OutOfData: + raise UnpackValueError("Data is not enough.") + if unpacker._got_extradata(): + raise ExtraData(ret, unpacker._get_extradata()) + return ret + + +class Unpacker(object): + """Streaming unpacker. + + arguments: + + :param file_like: + File-like object having `.read(n)` method. + If specified, unpacker reads serialized data from it and :meth:`feed()` is not usable. + + :param int read_size: + Used as `file_like.read(read_size)`. (default: `min(16*1024, max_buffer_size)`) + + :param bool use_list: + If true, unpack msgpack array to Python list. + 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. + + *encoding* option which is deprecated overrides this option. + + :param callable object_hook: + When specified, it should be callable. + Unpacker calls it with a dict argument after unpacking msgpack map. + (See also simplejson) + + :param callable object_pairs_hook: + When specified, it should be callable. + 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'`) + + :param int max_buffer_size: + Limits size of data waiting unpacked. 0 means system's INT_MAX (default). + Raises `BufferFull` exception when it is insufficient. + You should set this parameter when unpacking data from untrusted source. + + :param int max_str_len: + Limits max length of str. (default: 2**31-1) + + :param int max_bin_len: + Limits max length of bin. (default: 2**31-1) + + :param int max_array_len: + Limits max length of array. (default: 2**31-1) + + :param int max_map_len: + Limits max length of map. (default: 2**31-1) + + + example of streaming deserialize from file-like object:: + + unpacker = Unpacker(file_like, raw=False) + for o in unpacker: + process(o) + + example of streaming deserialize from socket:: + + unpacker = Unpacker(raw=False) + while True: + buf = sock.recv(1024**2) + if not buf: + break + unpacker.feed(buf) + for o in unpacker: + process(o) + """ + + def __init__(self, file_like=None, read_size=0, use_list=True, raw=True, + 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=2147483647, # 2**32-1 + max_bin_len=2147483647, + max_array_len=2147483647, + max_map_len=2147483647, + max_ext_len=2147483647): + + if encoding is not None: + warnings.warn( + "encoding is deprecated, Use raw=False instead.", + PendingDeprecationWarning) + + if unicode_errors is None: + unicode_errors = 'strict' + + if file_like is None: + self._feeding = True + else: + if not callable(file_like.read): + raise TypeError("`file_like.read` must be callable") + self.file_like = file_like + self._feeding = False + + #: array of bytes fed. + self._buffer = bytearray() + # Some very old pythons don't support `struct.unpack_from()` with a + # `bytearray`. So we wrap it in a `buffer()` there. + if sys.version_info < (2, 7, 6): + self._buffer_view = buffer(self._buffer) + else: + self._buffer_view = self._buffer + #: Which position we currently reads + self._buff_i = 0 + + # When Unpacker is used as an iterable, between the calls to next(), + # the buffer is not "consumed" completely, for efficiency sake. + # Instead, it is done sloppily. To make sure we raise BufferFull at + # the correct moments, we have to keep track of how sloppy we were. + # Furthermore, when the buffer is incomplete (that is: in the case + # we raise an OutOfData) we need to rollback the buffer to the correct + # state, which _buf_checkpoint records. + self._buf_checkpoint = 0 + + self._max_buffer_size = max_buffer_size or 2**31-1 + 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._raw = bool(raw) + self._encoding = encoding + self._unicode_errors = unicode_errors + self._use_list = use_list + self._list_hook = list_hook + self._object_hook = object_hook + self._object_pairs_hook = object_pairs_hook + self._ext_hook = ext_hook + self._max_str_len = max_str_len + self._max_bin_len = max_bin_len + self._max_array_len = max_array_len + self._max_map_len = max_map_len + self._max_ext_len = max_ext_len + self._stream_offset = 0 + + if list_hook is not None and not callable(list_hook): + 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') + if object_pairs_hook is not None and not callable(object_pairs_hook): + 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") + 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): + raise BufferFull + + # Strip buffer before checkpoint before reading file. + if self._buf_checkpoint > 0: + del self._buffer[:self._buf_checkpoint] + self._buff_i -= self._buf_checkpoint + self._buf_checkpoint = 0 + + self._buffer += view + + def _consume(self): + """ Gets rid of the used parts of the buffer. """ + self._stream_offset += self._buff_i - self._buf_checkpoint + self._buf_checkpoint = self._buff_i + + def _got_extradata(self): + return self._buff_i < len(self._buffer) + + def _get_extradata(self): + return self._buffer[self._buff_i:] + + def read_bytes(self, n): + return self._read(n) + + def _read(self, n): + # (int) -> bytearray + self._reserve(n) + i = self._buff_i + self._buff_i = i+n + return self._buffer[i:i+n] + + def _reserve(self, n): + remain_bytes = len(self._buffer) - self._buff_i - n + + # Fast path: buffer has n bytes already + if remain_bytes >= 0: + return + + if self._feeding: + self._buff_i = self._buf_checkpoint + raise OutOfData + + # Strip buffer before checkpoint before reading file. + if self._buf_checkpoint > 0: + del self._buffer[:self._buf_checkpoint] + self._buff_i -= self._buf_checkpoint + self._buf_checkpoint = 0 + + # Read from file + remain_bytes = -remain_bytes + while remain_bytes > 0: + to_read_bytes = max(self._read_size, remain_bytes) + read_data = self.file_like.read(to_read_bytes) + if not read_data: + break + assert isinstance(read_data, bytes) + self._buffer += read_data + remain_bytes -= len(read_data) + + if len(self._buffer) < n + self._buff_i: + self._buff_i = 0 # rollback + raise OutOfData + + def _read_header(self, execute=EX_CONSTRUCT): + typ = TYPE_IMMEDIATE + n = 0 + obj = None + self._reserve(1) + b = self._buffer[self._buff_i] + self._buff_i += 1 + if b & 0b10000000 == 0: + obj = b + elif b & 0b11100000 == 0b11100000: + obj = -1 - (b ^ 0xff) + elif b & 0b11100000 == 0b10100000: + n = b & 0b00011111 + typ = TYPE_RAW + if n > self._max_str_len: + raise UnpackValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) + obj = self._read(n) + elif b & 0b11110000 == 0b10010000: + n = b & 0b00001111 + typ = TYPE_ARRAY + if n > self._max_array_len: + raise UnpackValueError("%s exceeds max_array_len(%s)", n, self._max_array_len) + elif b & 0b11110000 == 0b10000000: + n = b & 0b00001111 + typ = TYPE_MAP + if n > self._max_map_len: + raise UnpackValueError("%s exceeds max_map_len(%s)", n, self._max_map_len) + elif b == 0xc0: + obj = None + elif b == 0xc2: + obj = False + elif b == 0xc3: + obj = True + elif b == 0xc4: + typ = TYPE_BIN + self._reserve(1) + n = self._buffer[self._buff_i] + self._buff_i += 1 + if n > self._max_bin_len: + raise UnpackValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len)) + obj = self._read(n) + elif b == 0xc5: + typ = TYPE_BIN + self._reserve(2) + n = struct.unpack_from(">H", self._buffer_view, self._buff_i)[0] + self._buff_i += 2 + if n > self._max_bin_len: + raise UnpackValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len)) + obj = self._read(n) + elif b == 0xc6: + typ = TYPE_BIN + self._reserve(4) + n = struct.unpack_from(">I", self._buffer_view, self._buff_i)[0] + self._buff_i += 4 + if n > self._max_bin_len: + raise UnpackValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len)) + obj = self._read(n) + elif b == 0xc7: # ext 8 + typ = TYPE_EXT + self._reserve(2) + L, n = struct.unpack_from('Bb', self._buffer_view, self._buff_i) + self._buff_i += 2 + if L > self._max_ext_len: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len)) + obj = self._read(L) + elif b == 0xc8: # ext 16 + typ = TYPE_EXT + self._reserve(3) + L, n = struct.unpack_from('>Hb', self._buffer_view, self._buff_i) + self._buff_i += 3 + if L > self._max_ext_len: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len)) + obj = self._read(L) + elif b == 0xc9: # ext 32 + typ = TYPE_EXT + self._reserve(5) + L, n = struct.unpack_from('>Ib', self._buffer_view, self._buff_i) + self._buff_i += 5 + if L > self._max_ext_len: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len)) + obj = self._read(L) + elif b == 0xca: + self._reserve(4) + obj = struct.unpack_from(">f", self._buffer_view, self._buff_i)[0] + self._buff_i += 4 + elif b == 0xcb: + self._reserve(8) + obj = struct.unpack_from(">d", self._buffer_view, self._buff_i)[0] + self._buff_i += 8 + elif b == 0xcc: + self._reserve(1) + obj = self._buffer[self._buff_i] + self._buff_i += 1 + elif b == 0xcd: + self._reserve(2) + obj = struct.unpack_from(">H", self._buffer_view, self._buff_i)[0] + self._buff_i += 2 + elif b == 0xce: + self._reserve(4) + obj = struct.unpack_from(">I", self._buffer_view, self._buff_i)[0] + self._buff_i += 4 + elif b == 0xcf: + self._reserve(8) + obj = struct.unpack_from(">Q", self._buffer_view, self._buff_i)[0] + self._buff_i += 8 + elif b == 0xd0: + self._reserve(1) + obj = struct.unpack_from("b", self._buffer_view, self._buff_i)[0] + self._buff_i += 1 + elif b == 0xd1: + self._reserve(2) + obj = struct.unpack_from(">h", self._buffer_view, self._buff_i)[0] + self._buff_i += 2 + elif b == 0xd2: + self._reserve(4) + obj = struct.unpack_from(">i", self._buffer_view, self._buff_i)[0] + self._buff_i += 4 + elif b == 0xd3: + self._reserve(8) + obj = struct.unpack_from(">q", self._buffer_view, self._buff_i)[0] + self._buff_i += 8 + elif b == 0xd4: # fixext 1 + typ = TYPE_EXT + if self._max_ext_len < 1: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (1, self._max_ext_len)) + self._reserve(2) + n, obj = struct.unpack_from("b1s", self._buffer_view, self._buff_i) + self._buff_i += 2 + elif b == 0xd5: # fixext 2 + typ = TYPE_EXT + if self._max_ext_len < 2: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (2, self._max_ext_len)) + self._reserve(3) + n, obj = struct.unpack_from("b2s", self._buffer_view, self._buff_i) + self._buff_i += 3 + elif b == 0xd6: # fixext 4 + typ = TYPE_EXT + if self._max_ext_len < 4: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (4, self._max_ext_len)) + self._reserve(5) + n, obj = struct.unpack_from("b4s", self._buffer_view, self._buff_i) + self._buff_i += 5 + elif b == 0xd7: # fixext 8 + typ = TYPE_EXT + if self._max_ext_len < 8: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (8, self._max_ext_len)) + self._reserve(9) + n, obj = struct.unpack_from("b8s", self._buffer_view, self._buff_i) + self._buff_i += 9 + elif b == 0xd8: # fixext 16 + typ = TYPE_EXT + if self._max_ext_len < 16: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (16, self._max_ext_len)) + self._reserve(17) + n, obj = struct.unpack_from("b16s", self._buffer_view, self._buff_i) + self._buff_i += 17 + elif b == 0xd9: + typ = TYPE_RAW + self._reserve(1) + n = self._buffer[self._buff_i] + self._buff_i += 1 + if n > self._max_str_len: + raise UnpackValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) + obj = self._read(n) + elif b == 0xda: + typ = TYPE_RAW + self._reserve(2) + n, = struct.unpack_from(">H", self._buffer_view, self._buff_i) + self._buff_i += 2 + if n > self._max_str_len: + raise UnpackValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) + obj = self._read(n) + elif b == 0xdb: + typ = TYPE_RAW + self._reserve(4) + n, = struct.unpack_from(">I", self._buffer_view, self._buff_i) + self._buff_i += 4 + if n > self._max_str_len: + raise UnpackValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) + obj = self._read(n) + elif b == 0xdc: + typ = TYPE_ARRAY + self._reserve(2) + n, = struct.unpack_from(">H", self._buffer_view, self._buff_i) + self._buff_i += 2 + if n > self._max_array_len: + raise UnpackValueError("%s exceeds max_array_len(%s)", n, self._max_array_len) + elif b == 0xdd: + typ = TYPE_ARRAY + self._reserve(4) + n, = struct.unpack_from(">I", self._buffer_view, self._buff_i) + self._buff_i += 4 + if n > self._max_array_len: + raise UnpackValueError("%s exceeds max_array_len(%s)", n, self._max_array_len) + elif b == 0xde: + self._reserve(2) + n, = struct.unpack_from(">H", self._buffer_view, self._buff_i) + self._buff_i += 2 + if n > self._max_map_len: + raise UnpackValueError("%s exceeds max_map_len(%s)", n, self._max_map_len) + typ = TYPE_MAP + elif b == 0xdf: + self._reserve(4) + n, = struct.unpack_from(">I", self._buffer_view, self._buff_i) + self._buff_i += 4 + if n > self._max_map_len: + raise UnpackValueError("%s exceeds max_map_len(%s)", n, self._max_map_len) + typ = TYPE_MAP + else: + raise UnpackValueError("Unknown header: 0x%x" % b) + return typ, n, obj + + def _unpack(self, execute=EX_CONSTRUCT): + typ, n, obj = self._read_header(execute) + + if execute == EX_READ_ARRAY_HEADER: + if typ != TYPE_ARRAY: + raise UnpackValueError("Expected array") + return n + if execute == EX_READ_MAP_HEADER: + if typ != TYPE_MAP: + raise UnpackValueError("Expected map") + return n + # TODO should we eliminate the recursion? + if typ == TYPE_ARRAY: + if execute == EX_SKIP: + for i in xrange(n): + # TODO check whether we need to call `list_hook` + self._unpack(EX_SKIP) + return + ret = newlist_hint(n) + for i in xrange(n): + ret.append(self._unpack(EX_CONSTRUCT)) + if self._list_hook is not None: + ret = self._list_hook(ret) + # TODO is the interaction between `list_hook` and `use_list` ok? + return ret if self._use_list else tuple(ret) + if typ == TYPE_MAP: + if execute == EX_SKIP: + for i in xrange(n): + # TODO check whether we need to call hooks + self._unpack(EX_SKIP) + self._unpack(EX_SKIP) + 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)) + else: + ret = {} + for _ in xrange(n): + key = self._unpack(EX_CONSTRUCT) + ret[key] = self._unpack(EX_CONSTRUCT) + if self._object_hook is not None: + ret = self._object_hook(ret) + return ret + 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: + obj = bytes(obj) + else: + obj = obj.decode('utf_8') + return obj + if typ == TYPE_EXT: + return self._ext_hook(n, bytes(obj)) + if typ == TYPE_BIN: + return bytes(obj) + assert typ == TYPE_IMMEDIATE + return obj + + def __iter__(self): + return self + + def __next__(self): + try: + ret = self._unpack(EX_CONSTRUCT) + self._consume() + return ret + except OutOfData: + self._consume() + raise StopIteration + + next = __next__ + + def skip(self, write_bytes=None): + self._unpack(EX_SKIP) + if write_bytes is not None: + warnings.warn("`write_bytes` option is deprecated. Use `.tell()` instead.", DeprecationWarning) + write_bytes(self._buffer[self._buf_checkpoint:self._buff_i]) + self._consume() + + def unpack(self, write_bytes=None): + ret = self._unpack(EX_CONSTRUCT) + if write_bytes is not None: + warnings.warn("`write_bytes` option is deprecated. Use `.tell()` instead.", DeprecationWarning) + write_bytes(self._buffer[self._buf_checkpoint:self._buff_i]) + self._consume() + return ret + + def read_array_header(self, write_bytes=None): + ret = self._unpack(EX_READ_ARRAY_HEADER) + if write_bytes is not None: + warnings.warn("`write_bytes` option is deprecated. Use `.tell()` instead.", DeprecationWarning) + write_bytes(self._buffer[self._buf_checkpoint:self._buff_i]) + self._consume() + return ret + + def read_map_header(self, write_bytes=None): + ret = self._unpack(EX_READ_MAP_HEADER) + if write_bytes is not None: + warnings.warn("`write_bytes` option is deprecated. Use `.tell()` instead.", DeprecationWarning) + write_bytes(self._buffer[self._buf_checkpoint:self._buff_i]) + self._consume() + return ret + + def tell(self): + return self._stream_offset + + +class Packer(object): + """ + MessagePack Packer + + usage: + + packer = Packer() + astream.write(packer.pack(a)) + astream.write(packer.pack(b)) + + Packer's constructor has some keyword arguments: + + :param callable default: + Convert user type to builtin type that Packer supports. + See also simplejson's document. + + :param bool use_single_float: + Use single precision float type for float. (default: False) + + :param bool autoreset: + Reset buffer after each pack and return its content as `bytes`. (default: True). + If set this to false, use `bytes()` to get content and `.reset()` to clear buffer. + + :param bool use_bin_type: + Use bin type introduced in msgpack spec 2.0 for bytes. + It also enables str8 type for unicode. + + :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 + 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 str unicode_errors: + Error handler for encoding unicode. (default: 'strict') + """ + 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.", + PendingDeprecationWarning) + + if unicode_errors is None: + unicode_errors = 'strict' + + 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 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): + default_used = False + if self._strict_types: + check = check_type_strict + list_types = list + else: + list_types = (list, tuple) + while True: + if nest_limit < 0: + raise PackValueError("recursion limit exceeded") + if obj is None: + return self._buffer.write(b"\xc0") + if check(obj, bool): + if obj: + return self._buffer.write(b"\xc3") + return self._buffer.write(b"\xc2") + if check(obj, int_types): + if 0 <= obj < 0x80: + 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 < 0: + 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)) + 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)) + if -0x8000000000000000 <= obj < -0x80000000: + 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 + continue + raise PackOverflowError("Integer value out of range") + if check(obj, (bytes, bytearray)): + n = len(obj) + if n >= 2**32: + raise PackValueError("%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) + n = len(obj) + if n >= 2**32: + raise PackValueError("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: + raise PackValueError("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 + assert isinstance(code, int) + assert isinstance(data, bytes) + L = len(data) + if L == 1: + self._buffer.write(b'\xd4') + elif L == 2: + self._buffer.write(b'\xd5') + elif L == 4: + self._buffer.write(b'\xd6') + elif L == 8: + 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)) + else: + self._buffer.write(struct.pack(">BI", 0xc9, L)) + self._buffer.write(struct.pack("b", code)) + self._buffer.write(data) + return + if check(obj, list_types): + n = len(obj) + self._pack_array_header(n) + for i in xrange(n): + 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) + if not default_used and self._default is not None: + obj = self._default(obj) + default_used = 1 + continue + raise TypeError("Cannot serialize %r" % (obj, )) + + def pack(self, obj): + try: + self._pack(obj) + except: + self._buffer = StringIO() # force reset + raise + ret = self._buffer.getvalue() + if self._autoreset: + self._buffer = StringIO() + elif USING_STRINGBUILDER: + self._buffer = StringIO(ret) + return ret + + def pack_map_pairs(self, pairs): + self._pack_map_pairs(len(pairs), pairs) + ret = self._buffer.getvalue() + if self._autoreset: + self._buffer = StringIO() + elif USING_STRINGBUILDER: + self._buffer = StringIO(ret) + return ret + + def pack_array_header(self, n): + if n >= 2**32: + raise PackValueError + self._pack_array_header(n) + ret = self._buffer.getvalue() + if self._autoreset: + self._buffer = StringIO() + elif USING_STRINGBUILDER: + self._buffer = StringIO(ret) + return ret + + def pack_map_header(self, n): + if n >= 2**32: + raise PackValueError + self._pack_map_header(n) + ret = self._buffer.getvalue() + if self._autoreset: + self._buffer = StringIO() + elif USING_STRINGBUILDER: + self._buffer = StringIO(ret) + return ret + + def pack_ext_type(self, typecode, data): + if not isinstance(typecode, int): + raise TypeError("typecode must have int type.") + if not 0 <= typecode <= 127: + raise ValueError("typecode should be 0-127") + if not isinstance(data, bytes): + raise TypeError("data must have bytes type") + L = len(data) + if L > 0xffffffff: + raise PackValueError("Too large data") + if L == 1: + self._buffer.write(b'\xd4') + elif L == 2: + self._buffer.write(b'\xd5') + elif L == 4: + self._buffer.write(b'\xd6') + elif L == 8: + 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)) + else: + 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)) + raise PackValueError("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)) + raise PackValueError("Dict is too large") + + def _pack_map_pairs(self, n, pairs, nest_limit=DEFAULT_RECURSE_LIMIT): + self._pack_map_header(n) + for (k, v) in pairs: + self._pack(k, nest_limit - 1) + 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)) + else: + raise PackValueError('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)) + else: + raise PackValueError('Bin is too large') + + def bytes(self): + return self._buffer.getvalue() + + def reset(self): + self._buffer = StringIO() diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/packaging/__about__.py b/venv/lib/python3.7/site-packages/pip/_vendor/packaging/__about__.py new file mode 100644 index 0000000..21fc6ce --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/packaging/__about__.py @@ -0,0 +1,21 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +__all__ = [ + "__title__", "__summary__", "__uri__", "__version__", "__author__", + "__email__", "__license__", "__copyright__", +] + +__title__ = "packaging" +__summary__ = "Core utilities for Python packages" +__uri__ = "https://github.com/pypa/packaging" + +__version__ = "18.0" + +__author__ = "Donald Stufft and individual contributors" +__email__ = "donald@stufft.io" + +__license__ = "BSD or Apache License, Version 2.0" +__copyright__ = "Copyright 2014-2018 %s" % __author__ diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/packaging/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/packaging/__init__.py new file mode 100644 index 0000000..5ee6220 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/packaging/__init__.py @@ -0,0 +1,14 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +from .__about__ import ( + __author__, __copyright__, __email__, __license__, __summary__, __title__, + __uri__, __version__ +) + +__all__ = [ + "__title__", "__summary__", "__uri__", "__version__", "__author__", + "__email__", "__license__", "__copyright__", +] diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/__about__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/__about__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bfe643c89055ad898844191f83d97fe0d2a7dd59 GIT binary patch literal 728 zcmYL{&2H2%5P*}-w)@v@3sk*uF_k#1L^s<lKP^J2v^^qJsfa^_WH}ipF-`2qKMR{@ z;6->F&U@v=D{x}GtEyx9(~LEq@yz&gJRSxpKcA*we|Li5k2mh6kIDsZbAx~Y!YZi4 zB&<70r;d^+44?xMbYTm&p$B~!6#b+N!(<Ca$u{gHJs2l_*i8nomkeP)8NnkyI1G{< zczhd7p8UnA!6aJkvDB!_Sx!aWC~a4L5DQ_1lB?ZD3u$TYWM;iRpwtRmaY|PsN{y>) zrk7~+D0NzFP8VGJyJ!q4WzLpLqmDOu%|x~FsYJ%5@nOc4W~y0gQIyuZH7vVhg^)#i zbfq*W&WcJ{!41ikCO1nAC&|W%oAz00ZDZcXaUpE!(rKpZxLGzVehAY&Ih)Sf$+eQK z0&;6zo?F5s5Fve;;8;a6C9M{zvr3zGAJ(oHX6-r^sy({Ay(XCb14b=5`M7!f3-V=C zDVbw}!>ju$$b5G4@)&VOo|{jTv2R1}tkYPo#t{cP^5`Ob-&ln`(Odp#+oR{<C$9${ z{&(n+#}49Gp!dD*@z2IModvTzUN9Z!ssemZT$gcn($Mqv{M+pNX%4M<eY()|AGWP$ zD20qa$Bk%?g)|m(AHRB&mUk{K{NZ}j1(%@oLknYkWU3sFXWA@R{dctjSMm400CRvi Ph=$=X>V~*FxIDxE&hOeU literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b19e0576c9daa74bacce7780510f89445e253ff8 GIT binary patch literal 566 zcmYk2&u-K(5XPNkH-9%pNZfb<_E21?098U2;sLnOlZ7;L;%wG5P9n!n*?k6Hq_31K zr@jIwW_AT)B>&{GX1@76pUX057(ZWD--3{_UzGff6fd9fOm_&yRM0UKh`@v*G?9n` zra~2UE3+1B6N}g+A~C5*O(rsvi`*2VFdMPKx|Le1SS2b|naWksrlM4vuWVaBp)%V> z%QIO`L+4!s+KhvBORDs&Cq4Ab#b|Z!VCVbVVg3|QN4n$y(!2d&0hSV=9>#;!?cQOU z0W?PH4zC43r|YJlnsYLFW28Nti=1{Hy(a+P>T|)|Sego83!GzVId(%R2{D1zVlzU5 z__DnqFFWtNMKOy@WHutK5adNxgGXEEW@`CQ;iP|>^lu2+ksX?UWcE2#6Mjz|*Dy=h z@L5{E8#;wXx!Lpj%?LNgo9|Z-*E@Bb-e1r5?GJY}R~T*2@A#<4OWjWnH80<NsP^~1 uYU%NGU~YOfSU$@7Ubeb#Ie_jp+I>A9mh__;l<%5b`pQI~e-XZl^WYEo;F$~n literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/_compat.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/_compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a4d40a5b3ea0001d3172eb9f73e82ca6936e5dc2 GIT binary patch literal 1018 zcmah{OKTKC5bnq9BkN{!Fa$In){C%*>}Y~YAOumtTM!h%A<)cD_wG(IFS~m;?h;Q4 zBnN+l9{o#w^_0Kh$*SIDjd-x2YO1QIzpDDGU#_mU2*}sX!Qmk%<R=C<!oYa}YCeFG zMAD4pG@?0+Sk5C(F~_nX3RG}ZljI(e{Fp`cWfVZvP!0WBHHS1>De9_)Us;p&a}wQ= z>>cSft^k|#xLb<{rpzW*i8QZDZCz8Q)6}G8;X0L03oC|`BC!x3Tw!BZ&@D+Q-Uh*- z4%z@UkHEYk7vzEtnWU1PHzm8IXZ#DZ<QqL@lFJ|^-vcOLn}@9~$SbX4tGaP_5F6D^ zve=mJNovQC$(4<LqVNAq0DLJ}7RB5Lqew(0iP-JJ5tkgw1oMZ8CjMaUWn~g)X1~8o zC4q+`1iz?vK}{RXB|W8=<dmNw6g~I>c#bETaX}I1%C+n`H3Azqj>;Z$wS^xbv_?jL z=@2NK!i3>8*5R<sq|zqL$6@lM61(%=qsJ#ZLpe9kcBXp!vz_OUK}JRRKCIGeD=mzT zvux|>^TGIdG8kdftC*@nmH-|n$MGmFMxjW`yoznVnz@D$g*p-90giziBXr*TFAM$a zTL&;>6MPs@2-gxKFXbddzb(Y4Nt`WC^cvv$8GB44S9<j(p*!HYl_kHM5c)ovR3o)+ z%_@9pv7QOP-)k5b*jc4KaE~wGJTTt*w~{Z?`FpH&tmL=Z*x-5tqFx(E7*6a&!w4GL z(D-&V{^hut8P}e|O5k;iv>29-zx}w4W(N+fc5N^~ufWcXYx({9j7Rrf-7>zX=H7y_ UeJo)xwa%KnLpwo0o2<@%1H%Ra+W-In literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/_structures.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/_structures.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ebfb0a5a7ff3dd706fad280e090dcc659f88faa5 GIT binary patch literal 2870 zcmcIm&2G~`5Z<*D$4S#R{Q+7kA#o!}#f6HZN)=RqKwNU6rwD1~csGfQ<D~0NfQVaq zLc9pC<SQp$ffF;Ex+Im2!{0``WAE(lH#0l)IZv0DD+Jo-oz|OAMMA#fOVSGPa11?q z4g)8g2Bb%uv}ZJpp4l`hc}cjz&2z#{QJ9#`q9{&Cvk0>VUWD1Ap0$Jpvlh2rlX~eJ zoJ8toyy~{1elS#m`Mp73s@UfK$dCMf7_SVZA1c-!hMt0V4|gQZfQMt~(FqKKG$|)d zgHvvtlcvc{UH}Q$+yYtTC2oVXc$rr~miQ8{g0%TEUjbR>tGouX!q@mZ$R)l37H-D& ztFY~dzWU%%0KtY5`!nbf28B~tX*47RjC>(=8W$oFw50{FdiXwaz=@Hogfnub)9wdc z$jIq+9q;~t9gYuA_ulQd`8Yb*AIS&r)ws6@trI#Y&cGk+`eCHpAlQBQsMUQtY;|x_ zcQz6s?@MRkdT-s1A9frTDLM4iP>Sf@;6rRPCdEK9Rz_1XT7-_*5{K?3+BwfmSfo9x z!h<4;ek2n*K@Vx8Zp4MI8+GFX9$Tlf1Z#f!DQ$Q~P+Y?p9*_n))q2_-Sb{PwoG<jj zbwh*1#lGqac@@iIEKrQC&LFMMxQDvm!;#ByR2qt4Y&{DFbaN<ILiiCvcuFTm62b~3 zHePAyiMR|~12>8oyKpqi0CC3HwG0DLmu|oc>`){zph_-GkTvvj4Tc=l5M0~JKt<gg zYT6~9%wA%aZymU%oeUJz{Ua2x_f{4P`hxajLpkS*x`-Q%YYowHl|K?ml4aCDiLp?0 z7`qKeB_&Wx_CVcfWusojVhP<IpvM))dVM|&@VUy^+0YH98i~a#v6v)Yr^IBJn2T}) zhfN$XGvo~%E=gzlgcYfI2`e?iUAAGH^FOWkKy}%$B#)v0M_!fJ;r#57Ur_3}yqiRA znn<aXqa$<|?bVz@$J<x0=})Lm;+Ie^!H|B*`bu_lP#5I7+%nNuzc&MRBgMsq=q?`$ z6Kp>Z3JXR@8y2GcHRmlvI6A2ha)AF2*XdF^%z<8r@aDc+X@sW>_9zExA=b->LRxr| z2elaWX_Ck&1SFoPGca2zxtTDY#LtP`#^ELoe@$-4BX^)@ksIn8^%C-Hdx-yx;9n0W oti+6!`1dWg`mIypDea=>r8E|e?V~9_KgK-~66>Z}yJbQD0YRbwt^fc4 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fbe676446b52efe2aa33fe275a4b09db61330976 GIT binary patch literal 8869 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 E1J*gv9{>OV literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..84357f65a548728fcff9cb1bc9586f882e3a3711 GIT binary patch literal 3885 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 bM9r}=mIF0s=2!wXGyy(VS!3p)m9_p0gP7+y literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a0d61fabdf89a0d21e9584e9b13016a538f1f9a5 GIT binary patch literal 19796 zcmeHPTWlQHd7j%|xLQ&aMak5~@<{SUs|zK|jvYIaEX%fHrw;8{s_oFS7t5U?xzt{$ zGee17FOwot5hYFB6iwTpNDB$=OWy(%EmEKledt3U`q~1WJ{Aq&*S-`m(98GzXJ+<F ziAkLlD7wozJC`%({QrOc^Plhh=RdqOK3*{J`QCwrYwd<%{0lFVPZlQ^aRfg@;u)S< zHyY-=*|6rVhCOeayl2&&c}IRT^BMWg&S&K}H=pxt&#C7dWAkH;!h8YwZ7);b(J0Or z8{_lijfwdQ)A+LCWxd=T!^`<QZ`<>exXycHxE}KhzO%B+pSo?~{%+hacsp=^hrb)w z)3`2r<G3F8r*XZ<oA7qtG3NK;{-n1H_jk$tNBrEq8E@*oIls@_?M)-ces7Pr7rzIP z^AT?bIcKEAgPwK8DDC?cyc#7t+F4l$TJ^QiFV`BYEfq$2uXeK*)LPAGVpY|eVR><_ zSq*VL_o>NOtf&}-c(7CsH&*>1nz&U9m&*-5tW@ijAV871cYP%VjKAqGRjM1wWoEUa z0>8?NlMhS0h$EOp;v4g(XUtokId2P*b~O1$^Jb-9^RBG=)!JgsSMApeE<P_e-I{*l z2FWA$RwZy3TWd}4q`MY?1UFc2t<^nO`HQ}C!<PH@Yj3;HK6_?XikK@oQNCPmRvLb} z92LstM$22P^SoFt-&m{E<0rXt*=tqH<v%kNiIn8CwbPKz%}VH>zFASH7h81?^_^}k zpRPW=T7IGZ!pfOj&n$ZF;JIgRs<Z21yKx4erRM3Yr&nvMr)te0tkmnLzVQ6Q^7XZa zCEk>yeA91wEp>XeQoUYTf{ah6+y%3%8)^p#*hz6&Nb<H^_sP@2{fo@-8%Pp)`u2+B znVxmWxNXj7<O&KaS6R8rcv-p1$yLtF%T*p%W8RookgI}USlQw2NUvDtE^pkMxMQN! zqP#if?er$)dfY2Q$#zHMmnwmuHeQv@%@2Qhyn-Vj&7O(uR{Ila88+}cez>NZfg3LS zF4PTexT^fXZ-y1BqT5=;lUm@WMZ5Ldb>D3*toYS%*1d{nX;HBjEckte+(d2`;`fwM z3j@EtsMUi+%t>RH%*f&WZu6^MAUT3!fU<J=5i-FBF*5Bvef-YGIUdUQ<&@Zj?~1!z z36@<b|C$e_hWc*JZu)XUui6b_2FZo4v&eG!P)e`U-aAOI&QcY2kdMEk8tO(`XP4lG zR;%t;nq4VFf8ATlK4h$1aL{apBJc24t4HQ+x3n<bet}z2zU#9O4z-0PyhWK7OC4k} zTQ2)I%H_vX1~cvHK?a%Oq3o@t6#dfJqck4GqS^~CMljffg*x#d2AScZ3b!=G;6Ov6 zx1CZx+B5Lc9QZ>^qIsodV7gkje9v9j5Uos$N^R9ptC=G;atA6&>NwlO(!TyS>&f-d zhVxQluJ~avsC}O=Q;8}{A022ZwGaHf(B)~aYU6?*{*LNV@1&H!>W98+)S3`{O<Sm? z8pZ{;7WxerHm}-(6~trD<;YuWYSXZ_@NL~?9KJ7f4bU3p;}V05piNt{A<K|tc_<&h zm-2D7a-F&(gsaK|lm`ZvMDV8PF4pScQ!ISL4O-x$61uHseIw3uYq?fkP79+&cnITt zx(Tt=!XZ73MUe*;LeWTZWHn`%Q(+8Q5uKrA&hc+T6_HboGnqgV*_DNAGyzx@s!BBk zFj{VTYMPJtFyU~aW|(m@$+N0jtG)_1gq$cF_#x<12bqz^x~IJafpGLuQ%G1|z>@RU zL~bIBL%xn#%s8gxsN!Mzq3T`45!^$PfP<O=u;miL-Z6o21quM+3J3tgmEj)<cZXL5 zmdwk5Z_JO$KyS<!00E|Oe}`Yxs1s0N9Or^OaXx`_!JatZ>F->b^!5>n^2*!q9l)Er zyu;o>?@`n}<sI=3d5__2w}8K+(RBHZCc&tOfgl~|Bct1wh#Yvlf+Jvib&M6`p4l<) zo11pW4i1IDlJ{(0-!{KxcI<nOXWcjNW$qhtZtL?!t7DY29i}<Y01$EJ+A}fm?83_z z-KRc2v-wn%XIoXmmWpyWHO?*Nqik9EOa40BuA-{T0?eW;#_dKWj515AwYC~%2%GU! zW>*Es?6GSlC+?$sq_rS}H&IXuIW^|MAYN<M!gBc?vP{J@%%bU-6L!&@a@voMk{D2k zekUCjII3rGh}_QLgmUwY>tkv!<YnRtQfgYBwP|{`Tm$WenGPBbvb42?cAs>6I5_|D znZs&Rap-ODJO@D?`}k?x`1tH*=|U;1PT{^PF`;3M#xO*2vQREd=ZS2HrWD&#o23r3 zO#oOfm+`h{+umzBwqs`T-I8tnPRcgTE?F10DLc<xA?xNRY;<d`odw+=KfMV`gw&JB zQW`mQNq4T}v9^|G``{LW7l1gL0M184ss1*>FD!`_IfP&80rj%Sw|eT`s=-IVxIA7H z&fnA(o1uBzQfD?MI>tRqx{UdrapR(6g!c7<I%#5*GL6u=V!UrOCqbyF#ceCN$a|1l zrem&Tu5&I4(z8(kb4E^UnpIzMLam-=!U;<>G1m&;Xsp)#2JpM@Y5sI;k3u=xLgGc4 z6dGp1w9E;7^VD>!eP9bw4*|Ph4#U)bGOV5>fBl@Q=Xp<>?*Z)5_HX{&><O%+_VUAD zRxRyGph!hZx^BnZXTadGWuVi=a<$dK#M>`Jxj8vs!c093m8dwTy@@polKyA4RtLM^ zco{FHIq#yrMDLG`Zj9dSeV8q^*84TlP{Pn!w4hddL)hut<|ZtRmawBGJcf*lO{v&n zVj|U(yfI)Tc7ju1ReemN#r^PG$P-XXhA2<_@zJ#QzqEB<6&nfBidYqG32egyy6O|i z@dF%MRMr+oDiQy7>!sO#aJ>}G4}0nzZJJ^k^;Mg~QVNai>V`1IdT(I}Y0iJtQ=2<d z$UOr^pE{)0m~Bf7Q^qjVS8Lpls4fHTEhEW~yH)oUY~#Lk4k_5Uhr;j2dSwc*N)+k9 zaKZHdByhJ}zL(ZuwhxbFt~YldJWh#t5oL5N46u0xYrA4>0&2uC1?s+HsV6&D@Faa8 zxNjqeb07Edn~8hzW!M`^TAf1@jn{%6@SwiL2h=v{6(x;vl`tmn^mh~C{!frQC?YYe zyqR?hnS$wTg&q=7q^z+svL9D*1T+R7(AJW%32Y@y0!4Hzpa;8VZf4fM(lK8(KD@M< z1#3np3uKl9V`e9}Xm&E6nCeI;2La4O0Q0zSBX#aM%x4-mj(9e3T=rcIL^qDS2h0}S z={V}n`c%h3nFW-opWS><tBo^vS;Ta;lo3g32z>!0YS@vjtggbrR?6$?=%eX_+(ylZ z3(t#oiT|)ix<O=Jza@f&JCyEAFEKBJ>PV#impB6Ab_1Bqv8J7ZS+FLYEXJ^+<Cuj^ z9%oyOVDY5F5)36X3k);U1CtB&0?Jlrm^{m5#I!=|gD6Tqomiymq1EUJ-#yQS#BM#w zIEtrpI06?*-g2zMcz!%@<GTZ2JD({!{7yJ|yRcg^H<cp&<ZyNoM{pBKGU1?i*LUt^ zJj=Hqfvfxx1McrEj@%{VzJ)1<OhPyT;pF4TSxh$c<f9NzK6b>Dk77Le7>^y^6S2d4 zr=D`mW3mBLvOn6Xz0m0lqVmr$bm_$M*h_DpON{V^W9QFz4xjIwJKwp0v~!_UO7mR{ zj;H5*CpMrL(wlS`e(=%BFI@{tA0Bs)x>ss|LV9kFNqfaTQWt0Vk?xG*q|Afqf{Y96 zD~sjn&ry0n=}fC)G7UH8%32V*m4((C(&h$T081y`TfQqZ2G>Vn`sS9!`Ri4GH59iZ zX4#=1z~AhH8aMD8wNuqr9UfNt92*sN9lpC@ZIvqnC$}uG;#TV|z`rGzK%?p66s*Tg z!C|4v_M6NFw?(bFWl0c5LyHAvwi*qPBxTjYrzpd?NYIIjI0x&_@VhP5c0NL5wH+jn zM;Y<4MPqQc!8eGBWVEyHW8wjCLo>cHwWNG_@>TD>u{2Xu?0sCywypE$+ty(m=Wtv& z|CxF2GxNge!KVvy1mFPb5aRTL9J>eP&;^zZOC#`&ShRm*Z_=0sCdF(&HlW+H0~jbZ z+BRNH!57^W9A99NG0{sfyeT!r<3|MNT#K{O5WXihix&p$T{MvbOOflplQNFyhS@$e zf+~$cCF{0`ig9)yQHr)`Br#JdF=<18)<e*dEeT4qZ;PlDLeRV>Bkh(%&7?%7+N4$P zKYB<zwk2r;FKvs!Oah*^Mc{#yz+N5KG-Aw6+w;VhG!DPFEizM#w=FWejhl+Z?xAk$ z#!a(tizrNMIkVfQ#_bs?yKE0#Pi#wSbERDaV>~8h;!NV|Qe-JV%5er)tK;O|*WS7G z)|J<y!W&<nd+VLoUU~V-Yw9WX34sL^rh1FX+f2U3gnlA*g~?SWT`VYP;z@iB5B?E{ z9^}XARhh9ZOuF@#!@Lan9QJL+-07@={hd~Y)+Nx^?w)xUv(IlEi>53&=2L5Dcl~yW zG2${+{8~rc5y1pO@Lj-Qm?tcUqeZN_%P@-1A*aj&hdLcr=d8u1W{m7axm$`b&)dPK z5L0OZ-J0zZq<UkmhKX=IiX;s<d#>K9R_eip+4xO3V#Z|A8w*-Nl;K^@j^|0k2TUkC z=!x8rI%l>j8^Hj2fzvSeX4FS`uZko6aB_PQNAOc5zZgIwIQnsZ9#I4u9>KS|1Ls_b zrJuEkbMevQd>rQz8-Vi(oF`t|oj6atw39gB=k1qwcX<cAgYeN#`MbSGy+d+u+Miz8 z<2{yKc`lmha5UBhR~f8Nr^9<cxcbKV&H%o`_4yu*wI!}P_R@=KnO#(L709XP!KYLU zH{1ln0VZ&HO7IJChaXfct3DP};Y`&_47Y0a`iR237MCjgb-3&kxTWz_yh@xvkB!zE z)?KhPi+F-~9lr}gdT9gbV^y;33DBk|4_q^gqYwoA0kr`gVGwe?WYuQ`Z9sX1W)*N+ zbsJb?CDd9}Ei4Dci`^;vTp;plLAAA}DocKMIjl?B0$?LBRecTf9hbtx65NI?@%2k< zn5$ziokM$_FS$UsZ*ieU3rMd{k7$Y^PI@tPLeK{QYrxC+9ChD|vF#v`J&AT1fmnyi zPs(Ij8aG0|Tse|uCE(mp1P5eGK#hh@w5OlfE|g?}oxW<e*2H7YR<k7dW-E1sI(TSq z<w?_v(djFjwH-|`E*8dG1pCBbjC}F9Mh144D~MdcBhO#N8X!~}Q4ubd)JK%m?GiCw zW<%puzbUJ6TyX1WoCN4b#w-ZU-2DtSxG<_0@~FM~vM@x%s20EZ(oi-?^@B5~Uik3D z;nGXJmHMl#o;ASaiO!05uFdMx(s4XGiogR|uO3x;@@miTQ7&I>`3^IFaH@Q5_QPRn z`RrJwv(Tw_RJBv7uP);PUeyi?<Z-j+-|E*PzQNCfN)%SQb4>k$>z0P=2j|Jto?r0O z!n|-RAuuOiJQYi<Ly>F#j`6(?$nL08d`r_Z%mauSlI~IW>oAG26+_&Wi%@|+MXx|t zZ!!QxG(OSq5#@v}_>CDX0!^1CGirB3R=H7VM|w>Ii^}?TYn72ey&)orFu>YS=`s5; ze;}xz)2`MX6>1+M#cL-%sGMqx#-?&i@05;1iH~Y-N7B)6Q4*@J&0ae$Mlcm#uz`jC zb*`GvK2$II+p52YQSvy77%8r(V_Fv0WNkiP)r0~GN<!ZbUG^sg?I2*st1Tfq3Ihj) zKg3nq_b^N?ag}GZUHL}8Q32;eb_J!6qH0*}enpn$gb*3419}jKD6zm5_k;}pe#K)0 zRovtKEfDKl(zrdp|JUqJ4{LJzE3!j_)u#RMr3Z9w=o@X(sNUV*eB0?jF9Y037+MOx z0u3}Y0Ik4pwt)VCpq51hBB3{p?m1iG2Cp@ngvnuc!jXH~-*5p_Io?VYBf4Rqi5-Rz zO;}-+ASG!k+21f^E!NgYlqNWgkSR6j!N`t%Si}0>?k!+WdWry;N*yBvL&;*W7!2Ex z!3NdWM|*^;0njbLV4@fq34%3@;bdos`mKudTFs}z7`bAs@n`?nOv`bQm>SL@`k~Jw zSonYA@wtGQLCJo8#-nRS`rOck?ntXHW3I2h%;a?@Z!q}^lV3v;jaAe_4UuDNqm*x3 z-++&~-`}hlzM;N~q-|p|mU_16hT+QGD>wqWBoPi^aCQA2V(C5m4njHLQ8Dl1@C?uS zO^ZPSjFR#)&l~tPup)z1H}ShztvBU5C)c(tLgwcpb2fGSz^x%pA9|Jo1~kx_>|u?y zXtegqIULJHy7}z6$RWUtY*=16YYK=FQDMN)MO>NdJuWG6rR2}mD~$!Oa^VMwD-CY$ z)2V-f4sPvA?n<=lz)9Zy^uO?FTeHXMp{E29pyI5wYR$;0*Feh{0{}yD?~H{&lvo9U zdu<~13<axov;h}Z<H)S8=Q+x1b2&)&?h%B2i!4l`6k~@2ZyKVNtfEzL^426`mLAAb z+N?HSPW|?)xae3~(CY0_){g04L+AunmpzM(ifb#h(b(xqgJ&Rg3(d}_$jd-CM2B3n zHWA*{oIxpgh81aRB^NAr%cLU6%78sbL4Nw5kSGG(@>oBW#uINGgt4|zuT>Sc)EMe4 zlE|+6O$N7B(uL9}Bcsxg=WalP;<@}IN{ow|hF!1<_GG4*nRF)Mfy5H3)t(t4Gnsjg z7S{xdp)Qh@`<7^<_;=|deJC|=Bh%j`Dri{kgCpu5y?DSTlU~RLcK9{XWVg-h>Cyo^ z=|gM(8Z!NDPwhuW)Sh~`wZpzo2BT?6R|mF516{{|*F(b-BWQSt|34*zu4yd@Xc{#O ztt{~l)`}T?5it;^`XXb@Rv;?o<L`A#eUW+eR-n1dS0ObLuDGBd6&HXfk`DV&dD2e( zJ$a!{7!Ewzrjsq2)25Rd*|Mo@M@yBC+&*@k?Xv?WZHcv<AHnc^Kf{jhWfKhefDMgt ztKxFHT0`<szUlP;SMn`=s+VtsCJ6VBJ)~7f3xFn{<ljcP=>1p}JWJLREo}_Y^Kbd; zVN^!l1)g;9bFj3KEGLfYdTGXVNTRN#`bOPFI0?c+5Y#%!Gl^L=VfAS1ur_f$tLE?v z8>cS9recV^Z}Kb|9BD<_aaSBQ=b__xSqx^mxl%?C$Q)L<0E_{e!?3<NdtA{(U%ia@ z6Nz|bc$m7ugmFlsxQQ^H;Ehqsyo}k&k$V|9&`eoG=j81vM37(|!)ov8HW)^tSS5nK z1!ykIyn-Y6MZ>BdOQmnkmG%y-PpMxg>F+XmkIDN?zRsk(6vYmr7^wP?^{5SId6fy- zR!5j{b)_dEDo~93-Az3{j+6XHgKJb=smj~M1I42{Af>pk_!zEd<h}NxkB-G&uVVmu ziQ}#m-+MgOAda&c93narg`g&L{lx^@Amr#Iw8BKREWiz+lRDdBcsat#?*mLBNNEz+ z7;E)80+wj>tvR)TvVcG`0xP0%h8JPNrC0gXF+7a2{(6X!HOh+LD^M@-4M)cvWwG&X ztsd%#uG4rhC>##HPqD?sxB+HNBFYG<HDSuYoazP{q)G^bKf}oqz81pKzzkqTj2305 zU<a`{K#O1s>?KctB=3N!^a<YS2(I)T0uRs7s8YX!k<S6T9DHH{X98(10f=}`HwV$F z&O2k=wx&_Ll+vF!&e46Vo0qh&<T}<Tpd&uFdA`Un*xX#&#?T>&o)zHA(S)sgKUt5C za<xD_U0B^)#KS>JFX7&Elr(;g_Mu*sGYmqvS*Q9Y%6dS3&nNXs%&DS+M&=pBuu(_U z3X|(h>P$#jl*PIf;B90#D(g|Ex{S?2*z4-l{YC6WP_?DyFe>l@8xa6=qaAWfUkoxF zqP(*tfQ!2b#kTjG`{f{>ebSQDDVmD;s?3snY@A%g5qu9xy0UpF-e-bI2e+JJzlq*w zl8N`3WaCh;Tpa3^k3+r2;!v-6{ZjUuB&(O>{`krS)-SQwnQNThjJFRZ@5CA<cbJ$6 z19RgYCc6Yl9FB^q1;r*Y9d4J7auhFDWu=QKoal|S=+_8UyN^&t!Q19-Oqtd%NoeDX zo6g1*Itj-MM|T;-(Yp>h2IA=7*KzdnJd-^CI-b9e<2?gt+{UH~Y&?<eC;52$Nvb*! zy}*A_*MqoNg2H|{%_wQAtpd#F@9$VQ5WOIc2TeMGd|1P_X3s=sFwml(70z)6#L3fz zci6D3A#1cty)sF6jPxpX^44eO$<ml=<27vC@S$ZD&l5W<!Tu5-faP=5YWvW_5IbW6 ztY8H?hB%|QxfFOywsQw@V5VLjjmFXk17u6c<6ERxMn!vCVk#|j3ZdOIcERZx715?C z{X=q;X5|=?f`gGeUeJ_iXj(d059|iodaujOxn98?lU*>}LUIAtTOdFQmFdClEY6bn zu4j0+JJ87(_bl#tWHE~qL-w}}u{B~xOFCk)i|R?gp74W3i~35P6gCw5VxLIZOKCEK zy-1)~6PO<gs*{jgU?IFGQ>K{q?;xA{E|Y%RKN~x@<Tw5GRdu16D3xQhpX!xOvKhKZ zr;>MoiE1bmyQdIlhz%k?zy<Vp_i#lL@Y+bKK&aXDs47w(6KgNc&XEt?A^14maHGD! zDjrZB_uH)YRM!PxTFnOb*-)N5q`n{Fgwm9KHq$!x4>RrwxyLOJM?wU+gcfXxg&{58 zQFDokXO*$pY6bsa0ukfyW5U3*F@1(-+2*<U>6p41Kh5I|Z^+X_a)!5nZNHb^&4)P; zoMRhYyfftTD?0K3wqSuv$-R<f>_WKgURBtA&dr*a5g#Lt;$$VHg?I>s<?~<`BauYs zP;1p)CbA3Ww|Pd%N;ilK?{X*mYf81!=>T<3{VtP!W#Yzq)QP?G6#OA%;2t1;9V=^2 zS<^V<QG`ptLiGBO4#>+X=s_XfHo1(85pD9M+=HV_oebF)kQ42EPg}hhVh+%itL_)M zLC%k&c$xWV8Hi#%U?<Qc$o^e2sezkjazYqw@9u35^qryYO{t!JPCUf{m;Y0qI5Yg= zHhCJ_s?N5OzB8(?(oj91uTpK`dn%Xzn6<N{5#~WMY}-6U+%v5nR44aiGIY3nzo*hc zBcXHj)tWZmEXagf4NX*o{WQMZzbcp;MoXJ=C>{doXxI25mpsIVbBYfeUL-hJF$OI- z=T{hgwzA;rhj{+y2@|m0C;IfSXQnyYe#=-#eFq+BZfs$^NyDGA4mPhLQ`;;zo^<_s zw5mOI^>t!0nkomJNI&;xp}$DjGpxRX)5aiK+F`iu%|fz^;;+(z&Gx=Nxox>Oh*L4v z8@!1mM93p2Ey+f>yBGt$W8B4r3ikhTsE6|%^R5}3y^AqIou!K?%zoSWHYPVR(&v#Q zm#POg!Sv||@xe2!iSRK2k1ME=<$vFb^@Iq)LbI`n7z4}9z3PJVfgMGHS*SJtkZ_M6 z%VT}qCtHU`sZ2a-jG+MS)uZq=P!j*1jrB?0^G0rH>Z3<UA;o`9QUoDl?n@_MHjhyw zYcW*5zgH%trNEza!4yjU6c@6Wsb|9$T$C@ayAU;c;)i=V{a=A2Njr%=^ZRft-8iVH z{M-wLBeRa78+qT}%wkB%hM6!c4eW)vP8P#Uu8F&wIXugS*yyFg8?R$8R9=08y-=TY zoZv^D%)POAC)DfM6_uW&7AN>gC!>B6(};5nPM84*V1vs>w_~ZG<td{u$I-~)|7g*J z)_~wCbM18)+#DtG_EBDMPXai5nK?xl*ck`LZrMuoPi%$bcnC);yjNLBADgxDFA1=J z2<=j^92<Lj>CG~W*c~-VuU7wXH*zo3)Sw^g4C^Oq?%4+Q2fXCCD*s|Z5re5eWb!JL zu9ImSo1chfzDic8S$V6lCqE`}(2wK`_#zg%xJx!ZJu0ZD^eF#_)Z!ZcZ4v$fi^6+` zVh303>FO~i*O<s$oz63iS9%FcZz9g|;gd|LiAtJBy2S7EatD$q_wuDzzKS@rD69WZ zj{JuQ*>xqeE(tHzGqLyh&c{sX8<N?%hGvtz>?Z6uQU09%&sP^nX+RRDu`5u%Sg4w| bC$lpzOn%cCn|wAuhTm@*y9?a^b>P1Ne8S&> literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e6f0dcafdb4ed0849a42721f4a8010a63bfb2e2e GIT binary patch literal 1464 zcmbVM&5j#I5bo|7&)Bo}CL{|IKZgM!f!XZXAp#U>wL*al9QKkZAScmi>~7m*&mY}w z@9yBe5RQmvu#fN{JVYPi6p1I;6IH$5g+-ibyK1_ts;j^H>3-Dd1O&!UZx5f}^9cC^ z7gxi9$>%`oYhavknvt9iXwC*KcLokc8Oz*(%N_1!joce}xj*nJ5$?Ll8yh-kagX~y zl0m?myanGK&K{F)@Cy8qu48T`Lse!AE#fq<N~ukgr^{5OWnp$JnHD-8FN%?d_3<l; zTbSAXs#qpj%AX2p?fmVe_MRQY(Tn{N+Tp;j3-kq$x(!T|HRW_gHf+r{1Yoe^3wi)3 z?#82}D2sFierpj+F%hT6QH!BzWaWvFU25DS$;B^3cEHa?)dOtHM2p@sk-c%5alq2c zr@hhrDt=f$ob^v0jCrj-eXx`tpXxgA!<ZDkC%r1I4$?yDB+Cvy`D{3yFNPBoT8fvV z;HB(U$!MNT(qhtE=rmJNb!J|>0T8k5VpI$mVe%I6>#$LV6}4gi36rz7CM)uio|A7# zvF8#^=Yb3<<cEU%G5MBE$T_5C#yFij^3jT}9nRJ+N;Y&u!3re0vG%aays`E#YYO`2 zm*5v{9BV~pE#92B<j>ZF3wAB6J=nFjcIb=DpclaES8Em6bAs(TWVT~<zggXm)$LsC z+E(|w)wQjzeW~Mc)(UVyNjvoqK?vi?G*uz|mqMO}D$Ua@k)bZbZL>sith9{dd*N`Q z!)c<zvJfFuTxTNW>3A%pC`LkAUni-ahI%T(ljJN+(Y)Z9P*x;GCK3f(#UvMnj_d}B ztyjC>_s`$0{STi<{qFwzh8P;%C=y;Sh4con6?w6HPN7irC4CBo`HpeyP<jl#=Kxe_ zd=~W$J+&Qp$*=`3T89%+h|@|Q?V~TOzDw#4ZuAQz0k2AQn3d4t>L|M2bNs&$$vbdL zm&v>Ek$cGSTKo-4z7EU#Kv!^@QB^7p`KbMfizQCnec;`W^l>M=JH#|ZRgR{{OR5U) zf$_$r%oA;x6cYQ{xU(`XjK9seaVjZ{i++s*KJltTaF8c|8?I?oiPY*}*v#I4r3NEW z9|0pCqiwp&Jmxw9z2mynr3`*=H3Iq$O0I~>_rSW_HbD$;lwL>?#}czIv91yy9{DD+ y5E%w&LpA=W%&RmLvV|hNxz^D?P}*E#ZB6qqFZm)9N9avq682b=-F5<}+4u_pa%p=2 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a7b9e1d95dc453968d1e68e6b38360e00cf2d741 GIT binary patch literal 11982 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/packaging/_compat.py b/venv/lib/python3.7/site-packages/pip/_vendor/packaging/_compat.py new file mode 100644 index 0000000..210bb80 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/packaging/_compat.py @@ -0,0 +1,30 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import sys + + +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 + +# flake8: noqa + +if PY3: + string_types = str, +else: + string_types = basestring, + + +def with_metaclass(meta, *bases): + """ + 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): + def __new__(cls, name, this_bases, d): + return meta(name, bases, d) + return type.__new__(metaclass, 'temporary_class', (), {}) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/packaging/_structures.py b/venv/lib/python3.7/site-packages/pip/_vendor/packaging/_structures.py new file mode 100644 index 0000000..e9fc4a0 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/packaging/_structures.py @@ -0,0 +1,70 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + + +class Infinity(object): + + def __repr__(self): + return "Infinity" + + def __hash__(self): + return hash(repr(self)) + + def __lt__(self, other): + return False + + def __le__(self, other): + return False + + def __eq__(self, other): + return isinstance(other, self.__class__) + + def __ne__(self, other): + return not isinstance(other, self.__class__) + + def __gt__(self, other): + return True + + def __ge__(self, other): + return True + + def __neg__(self): + return NegativeInfinity + + +Infinity = Infinity() + + +class NegativeInfinity(object): + + def __repr__(self): + return "-Infinity" + + def __hash__(self): + return hash(repr(self)) + + def __lt__(self, other): + return True + + def __le__(self, other): + return True + + def __eq__(self, other): + return isinstance(other, self.__class__) + + def __ne__(self, other): + return not isinstance(other, self.__class__) + + def __gt__(self, other): + return False + + def __ge__(self, other): + return False + + def __neg__(self): + return Infinity + + +NegativeInfinity = NegativeInfinity() diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/packaging/markers.py b/venv/lib/python3.7/site-packages/pip/_vendor/packaging/markers.py new file mode 100644 index 0000000..e5834ce --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/packaging/markers.py @@ -0,0 +1,301 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import operator +import os +import platform +import sys + +from pip._vendor.pyparsing import ParseException, ParseResults, stringStart, stringEnd +from pip._vendor.pyparsing import ZeroOrMore, Group, Forward, QuotedString +from pip._vendor.pyparsing import Literal as L # noqa + +from ._compat import string_types +from .specifiers import Specifier, InvalidSpecifier + + +__all__ = [ + "InvalidMarker", "UndefinedComparison", "UndefinedEnvironmentName", + "Marker", "default_environment", +] + + +class InvalidMarker(ValueError): + """ + An invalid marker was found, users should refer to PEP 508. + """ + + +class UndefinedComparison(ValueError): + """ + An invalid operation was attempted on a value that doesn't support it. + """ + + +class UndefinedEnvironmentName(ValueError): + """ + A name was attempted to be used that does not exist inside of the + environment. + """ + + +class Node(object): + + def __init__(self, value): + self.value = value + + def __str__(self): + return str(self.value) + + def __repr__(self): + return "<{0}({1!r})>".format(self.__class__.__name__, str(self)) + + def serialize(self): + raise NotImplementedError + + +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") +) +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' +} +VARIABLE.setParseAction(lambda s, l, t: Variable(ALIASES.get(t[0], t[0]))) + +VERSION_CMP = ( + L("===") | + L("==") | + L(">=") | + L("<=") | + L("!=") | + L("~=") | + L(">") | + L("<") +) + +MARKER_OP = VERSION_CMP | L("not in") | L("in") +MARKER_OP.setParseAction(lambda s, l, t: Op(t[0])) + +MARKER_VALUE = QuotedString("'") | QuotedString('"') +MARKER_VALUE.setParseAction(lambda s, l, t: Value(t[0])) + +BOOLOP = L("and") | L("or") + +MARKER_VAR = VARIABLE | MARKER_VALUE + +MARKER_ITEM = Group(MARKER_VAR + MARKER_OP + MARKER_VAR) +MARKER_ITEM.setParseAction(lambda s, l, t: tuple(t[0])) + +LPAREN = L("(").suppress() +RPAREN = L(")").suppress() + +MARKER_EXPR = Forward() +MARKER_ATOM = MARKER_ITEM | Group(LPAREN + MARKER_EXPR + RPAREN) +MARKER_EXPR << MARKER_ATOM + ZeroOrMore(BOOLOP + MARKER_EXPR) + +MARKER = stringStart + MARKER_EXPR + stringEnd + + +def _coerce_parse_result(results): + if isinstance(results, ParseResults): + return [_coerce_parse_result(i) for i in results] + else: + return results + + +def _format_marker(marker, first=True): + assert isinstance(marker, (list, tuple, string_types)) + + # Sometimes we have a structure like [[...]] which is a single item list + # 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))): + return _format_marker(marker[0]) + + if isinstance(marker, list): + inner = (_format_marker(m, first=False) for m in marker) + if first: + return " ".join(inner) + else: + return "(" + " ".join(inner) + ")" + elif isinstance(marker, tuple): + return " ".join([m.serialize() for m in marker]) + else: + return marker + + +_operators = { + "in": lambda lhs, rhs: lhs in rhs, + "not in": lambda lhs, rhs: lhs not in rhs, + "<": operator.lt, + "<=": operator.le, + "==": operator.eq, + "!=": operator.ne, + ">=": operator.ge, + ">": operator.gt, +} + + +def _eval_op(lhs, op, rhs): + try: + spec = Specifier("".join([op.serialize(), rhs])) + except InvalidSpecifier: + pass + else: + return spec.contains(lhs) + + oper = _operators.get(op.serialize()) + if oper is None: + raise UndefinedComparison( + "Undefined {0!r} on {1!r} and {2!r}.".format(op, lhs, rhs) + ) + + return oper(lhs, rhs) + + +_undefined = object() + + +def _get_env(environment, name): + value = environment.get(name, _undefined) + + if value is _undefined: + raise UndefinedEnvironmentName( + "{0!r} does not exist in evaluation environment.".format(name) + ) + + return value + + +def _evaluate_markers(markers, environment): + groups = [[]] + + for marker in markers: + assert isinstance(marker, (list, tuple, string_types)) + + if isinstance(marker, list): + groups[-1].append(_evaluate_markers(marker, environment)) + elif isinstance(marker, tuple): + lhs, op, rhs = marker + + if isinstance(lhs, Variable): + lhs_value = _get_env(environment, lhs.value) + rhs_value = rhs.value + else: + lhs_value = lhs.value + rhs_value = _get_env(environment, rhs.value) + + groups[-1].append(_eval_op(lhs_value, op, rhs_value)) + else: + assert marker in ["and", "or"] + if marker == "or": + groups.append([]) + + return any(all(item) for item in groups) + + +def format_full_version(info): + version = '{0.major}.{0.minor}.{0.micro}'.format(info) + kind = info.releaselevel + if kind != 'final': + version += kind[0] + str(info.serial) + return version + + +def default_environment(): + if hasattr(sys, 'implementation'): + iver = format_full_version(sys.implementation.version) + implementation_name = sys.implementation.name + else: + iver = '0' + implementation_name = '' + + return { + "implementation_name": implementation_name, + "implementation_version": iver, + "os_name": os.name, + "platform_machine": platform.machine(), + "platform_release": platform.release(), + "platform_system": platform.system(), + "platform_version": platform.version(), + "python_full_version": platform.python_version(), + "platform_python_implementation": platform.python_implementation(), + "python_version": platform.python_version()[:3], + "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]) + raise InvalidMarker(err_str) + + def __str__(self): + return _format_marker(self._markers) + + def __repr__(self): + return "<Marker({0!r})>".format(str(self)) + + def evaluate(self, environment=None): + """Evaluate a marker. + + Return the boolean from evaluating the given marker against the + environment. environment is an optional argument to override all or + part of the determined environment. + + The environment is determined from the current Python process. + """ + current_environment = default_environment() + if environment is not None: + current_environment.update(environment) + + return _evaluate_markers(self._markers, current_environment) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/packaging/requirements.py b/venv/lib/python3.7/site-packages/pip/_vendor/packaging/requirements.py new file mode 100644 index 0000000..d40bd8c --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/packaging/requirements.py @@ -0,0 +1,130 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import string +import re + +from pip._vendor.pyparsing import stringStart, stringEnd, originalTextFor, ParseException +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 .markers import MARKER_EXPR, Marker +from .specifiers import LegacySpecifier, Specifier, SpecifierSet + + +class InvalidRequirement(ValueError): + """ + An invalid requirement was found, users should refer to PEP 508. + """ + + +ALPHANUM = Word(string.ascii_letters + string.digits) + +LBRACKET = L("[").suppress() +RBRACKET = L("]").suppress() +LPAREN = L("(").suppress() +RPAREN = L(")").suppress() +COMMA = L(",").suppress() +SEMICOLON = L(";").suppress() +AT = L("@").suppress() + +PUNCTUATION = Word("-_.") +IDENTIFIER_END = ALPHANUM | (ZeroOrMore(PUNCTUATION) + ALPHANUM) +IDENTIFIER = Combine(ALPHANUM + ZeroOrMore(IDENTIFIER_END)) + +NAME = IDENTIFIER("name") +EXTRA = IDENTIFIER + +URI = Regex(r'[^ ]+')("url") +URL = (AT + URI) + +EXTRAS_LIST = EXTRA + ZeroOrMore(COMMA + EXTRA) +EXTRAS = (LBRACKET + Optional(EXTRAS_LIST) + RBRACKET)("extras") + +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_SPEC = Optional(((LPAREN + VERSION_MANY + RPAREN) | VERSION_MANY)) +_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]) +) +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) + +REQUIREMENT = stringStart + NAMED_REQUIREMENT + stringEnd +# pyparsing isn't thread safe during initialization, so we do it eagerly, see +# issue #104 +REQUIREMENT.parseString("x[]") + + +class Requirement(object): + """Parse a requirement. + + Parse a given requirement string into its parts, such as name, specifier, + URL, and extras. Raises InvalidRequirement on a badly-formed requirement + string. + """ + + # TODO: Can we test whether something is contained within a requirement? + # If so how do we do that? Do we need to test against the _name_ of + # the thing as well as the version? What about the markers? + # TODO: Can we normalize the name and extra name? + + def __init__(self, requirement_string): + try: + req = REQUIREMENT.parseString(requirement_string) + except ParseException as e: + raise InvalidRequirement("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: {0}".format(req.url)) + self.url = req.url + else: + self.url = None + self.extras = set(req.extras.asList() if req.extras else []) + self.specifier = SpecifierSet(req.specifier) + self.marker = req.marker if req.marker else None + + def __str__(self): + parts = [self.name] + + if self.extras: + parts.append("[{0}]".format(",".join(sorted(self.extras)))) + + if self.specifier: + parts.append(str(self.specifier)) + + if self.url: + parts.append("@ {0}".format(self.url)) + + if self.marker: + parts.append("; {0}".format(self.marker)) + + return "".join(parts) + + def __repr__(self): + return "<Requirement({0!r})>".format(str(self)) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/packaging/specifiers.py b/venv/lib/python3.7/site-packages/pip/_vendor/packaging/specifiers.py new file mode 100644 index 0000000..4c79899 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/packaging/specifiers.py @@ -0,0 +1,774 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import abc +import functools +import itertools +import re + +from ._compat import string_types, with_metaclass +from .version import Version, LegacyVersion, parse + + +class InvalidSpecifier(ValueError): + """ + An invalid specifier was found, users should refer to PEP 440. + """ + + +class BaseSpecifier(with_metaclass(abc.ABCMeta, object)): + + @abc.abstractmethod + def __str__(self): + """ + Returns the str representation of this Specifier like object. This + should be representative of the Specifier itself. + """ + + @abc.abstractmethod + def __hash__(self): + """ + Returns a hash value for this Specifier like object. + """ + + @abc.abstractmethod + def __eq__(self, other): + """ + Returns a boolean representing whether or not the two Specifier like + objects are equal. + """ + + @abc.abstractmethod + def __ne__(self, other): + """ + Returns a boolean representing whether or not the two Specifier like + objects are not equal. + """ + + @abc.abstractproperty + def prereleases(self): + """ + Returns whether or not pre-releases as a whole are allowed by this + specifier. + """ + + @prereleases.setter + def prereleases(self, value): + """ + Sets whether or not pre-releases as a whole are allowed by this + specifier. + """ + + @abc.abstractmethod + def contains(self, item, prereleases=None): + """ + Determines if the given item is contained within this specifier. + """ + + @abc.abstractmethod + def filter(self, iterable, prereleases=None): + """ + Takes an iterable of items and filters them so that only items which + are contained within this specifier are allowed in it. + """ + + +class _IndividualSpecifier(BaseSpecifier): + + _operators = {} + + def __init__(self, spec="", prereleases=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(), + ) + + # Store whether or not this Specifier should accept prereleases + self._prereleases = prereleases + + def __repr__(self): + pre = ( + ", prereleases={0!r}".format(self.prereleases) + if self._prereleases is not None + else "" + ) + + return "<{0}({1!r}{2})>".format( + self.__class__.__name__, + str(self), + pre, + ) + + def __str__(self): + return "{0}{1}".format(*self._spec) + + def __hash__(self): + return hash(self._spec) + + def __eq__(self, other): + if isinstance(other, string_types): + try: + other = self.__class__(other) + except InvalidSpecifier: + return NotImplemented + elif not isinstance(other, self.__class__): + return NotImplemented + + return self._spec == other._spec + + def __ne__(self, other): + if isinstance(other, string_types): + try: + other = self.__class__(other) + except InvalidSpecifier: + return NotImplemented + elif not isinstance(other, self.__class__): + return NotImplemented + + return self._spec != other._spec + + def _get_operator(self, op): + return getattr(self, "_compare_{0}".format(self._operators[op])) + + def _coerce_version(self, version): + if not isinstance(version, (LegacyVersion, Version)): + version = parse(version) + return version + + @property + def operator(self): + return self._spec[0] + + @property + def version(self): + return self._spec[1] + + @property + def prereleases(self): + return self._prereleases + + @prereleases.setter + def prereleases(self, value): + self._prereleases = value + + def __contains__(self, item): + return self.contains(item) + + def contains(self, item, prereleases=None): + # 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) + + # 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: + 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) + + def filter(self, iterable, prereleases=None): + yielded = False + found_prereleases = [] + + kw = {"prereleases": prereleases if prereleases is not None else True} + + # Attempt to iterate over all the values in the iterable and if any of + # them match, yield them. + for version in iterable: + parsed_version = self._coerce_version(version) + + if self.contains(parsed_version, **kw): + # 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)): + found_prereleases.append(version) + # Either this is not a prerelease, or we should have been + # accepting prereleases from the beginning. + else: + yielded = True + yield version + + # Now that we've iterated over everything, determine if we've yielded + # any values, and if we have not and we have any prereleases stored up + # then we will go ahead and yield the prereleases. + if not yielded and found_prereleases: + for version in found_prereleases: + yield version + + +class LegacySpecifier(_IndividualSpecifier): + + _regex_str = ( + r""" + (?P<operator>(==|!=|<=|>=|<|>)) + \s* + (?P<version> + [^,;\s)]* # Since this is a "legacy" specifier, and the version + # string can be just about anything, we match everything + # except for whitespace, a semi-colon for marker support, + # a closing paren since versions can be enclosed in + # them, and a comma since it's a version separator. + ) + """ + ) + + _regex = re.compile( + r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) + + _operators = { + "==": "equal", + "!=": "not_equal", + "<=": "less_than_equal", + ">=": "greater_than_equal", + "<": "less_than", + ">": "greater_than", + } + + def _coerce_version(self, version): + if not isinstance(version, LegacyVersion): + version = LegacyVersion(str(version)) + return version + + def _compare_equal(self, prospective, spec): + return prospective == self._coerce_version(spec) + + def _compare_not_equal(self, prospective, spec): + return prospective != self._coerce_version(spec) + + def _compare_less_than_equal(self, prospective, spec): + return prospective <= self._coerce_version(spec) + + def _compare_greater_than_equal(self, prospective, spec): + return prospective >= self._coerce_version(spec) + + def _compare_less_than(self, prospective, spec): + return prospective < self._coerce_version(spec) + + def _compare_greater_than(self, prospective, spec): + return prospective > self._coerce_version(spec) + + +def _require_version_compare(fn): + @functools.wraps(fn) + def wrapped(self, prospective, spec): + if not isinstance(prospective, Version): + return False + return fn(self, prospective, spec) + return wrapped + + +class Specifier(_IndividualSpecifier): + + _regex_str = ( + r""" + (?P<operator>(~=|==|!=|<=|>=|<|>|===)) + (?P<version> + (?: + # The identity operators allow for an escape hatch that will + # do an exact string match of the version you wish to install. + # This will not be parsed by PEP 440 and we cannot determine + # any semantic meaning from it. This operator is discouraged + # but included entirely as an escape hatch. + (?<====) # Only match for the identity operator + \s* + [^\s]* # We just match everything, except for whitespace + # since we are only testing for strict identity. + ) + | + (?: + # The (non)equality operators allow for wild card and local + # versions to be specified so we have to define these two + # operators separately to enable that. + (?<===|!=) # Only match for equals and not equals + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)* # release + (?: # pre release + [-_\.]? + (a|b|c|rc|alpha|beta|pre|preview) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + + # You cannot use a wild card and a dev or local version + # together so group them with a | and make them optional. + (?: + (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + (?:\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*)? # local + | + \.\* # Wild card syntax of .* + )? + ) + | + (?: + # The compatible operator requires at least two digits in the + # release segment. + (?<=~=) # Only match for the compatible operator + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)+ # release (We have a + instead of a *) + (?: # pre release + [-_\.]? + (a|b|c|rc|alpha|beta|pre|preview) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + ) + | + (?: + # All other operators only allow a sub set of what the + # (non)equality operators do. Specifically they do not allow + # local versions to be specified nor do they allow the prefix + # matching wild cards. + (?<!==|!=|~=) # We have special cases for these + # operators so we want to make sure they + # don't match here. + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)* # release + (?: # pre release + [-_\.]? + (a|b|c|rc|alpha|beta|pre|preview) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + ) + ) + """ + ) + + _regex = re.compile( + r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) + + _operators = { + "~=": "compatible", + "==": "equal", + "!=": "not_equal", + "<=": "less_than_equal", + ">=": "greater_than_equal", + "<": "less_than", + ">": "greater_than", + "===": "arbitrary", + } + + @_require_version_compare + def _compare_compatible(self, prospective, spec): + # 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 + # implementing it ourselves. The only thing we need to do is construct + # the other specifiers. + + # We want everything but the last item in the version, but we want to + # ignore post and dev releases and we want to treat the pre-release as + # it's own separate segment. + prefix = ".".join( + list( + itertools.takewhile( + lambda x: (not x.startswith("post") and not + x.startswith("dev")), + _version_split(spec), + ) + )[:-1] + ) + + # Add the prefix notation to the end of our string + prefix += ".*" + + return (self._get_operator(">=")(prospective, spec) and + self._get_operator("==")(prospective, prefix)) + + @_require_version_compare + def _compare_equal(self, prospective, spec): + # 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 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)) + + # 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)] + + # Pad out our two sides with zeros so that they both equal the same + # length. + spec, prospective = _pad_version(spec, prospective) + else: + # Convert our spec string into a Version + spec = 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: + prospective = Version(prospective.public) + + return prospective == spec + + @_require_version_compare + def _compare_not_equal(self, prospective, spec): + return not self._compare_equal(prospective, spec) + + @_require_version_compare + def _compare_less_than_equal(self, prospective, spec): + return prospective <= Version(spec) + + @_require_version_compare + def _compare_greater_than_equal(self, prospective, spec): + return prospective >= Version(spec) + + @_require_version_compare + def _compare_less_than(self, prospective, spec): + # Convert our spec to a Version instance, since we'll want to work with + # it as a version. + spec = Version(spec) + + # 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 + # instead of doing extra unneeded work. + if not prospective < spec: + return False + + # This special case is here so that, unless the specifier itself + # includes is a pre-release version, that we do not accept pre-release + # versions for the version mentioned in the specifier (e.g. <3.1 should + # not match 3.1.dev0, but should match 3.0.dev0). + if not spec.is_prerelease and prospective.is_prerelease: + if Version(prospective.base_version) == Version(spec.base_version): + return False + + # If we've gotten to here, it means that prospective version is both + # less than the spec version *and* it's not a pre-release of the same + # version in the spec. + return True + + @_require_version_compare + def _compare_greater_than(self, prospective, spec): + # Convert our spec to a Version instance, since we'll want to work with + # it as a version. + spec = Version(spec) + + # 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 + # instead of doing extra unneeded work. + if not prospective > spec: + return False + + # This special case is here so that, unless the specifier itself + # includes is a post-release version, that we do not accept + # post-release versions for the version mentioned in the specifier + # (e.g. >3.1 should not match 3.0.post0, but should match 3.2.post0). + if not spec.is_postrelease and prospective.is_postrelease: + if Version(prospective.base_version) == Version(spec.base_version): + return False + + # Ensure that we do not allow a local version of the version mentioned + # 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 + + # If we've gotten to here, it means that prospective version is both + # greater than the spec version *and* it's not a pre-release of the + # same version in the spec. + return True + + def _compare_arbitrary(self, prospective, spec): + return str(prospective).lower() == str(spec).lower() + + @property + def prereleases(self): + # If there is an explicit prereleases set for this, then we'll just + # blindly use that. + if self._prereleases is not None: + return self._prereleases + + # Look at all of our specifiers and determine if they are inclusive + # operators, and if they are if they are including an explicit + # prerelease. + operator, version = self._spec + if operator in ["==", ">=", "<=", "~=", "==="]: + # The == specifier can include a trailing .*, if it does we + # want to remove before parsing. + if operator == "==" and version.endswith(".*"): + version = version[:-2] + + # Parse the version, and if it is a pre-release than this + # specifier allows pre-releases. + if parse(version).is_prerelease: + return True + + return False + + @prereleases.setter + def prereleases(self, value): + self._prereleases = value + + +_prefix_regex = re.compile(r"^([0-9]+)((?:a|b|c|rc)[0-9]+)$") + + +def _version_split(version): + result = [] + for item in version.split("."): + match = _prefix_regex.search(item) + if match: + result.extend(match.groups()) + else: + result.append(item) + return result + + +def _pad_version(left, right): + left_split, right_split = [], [] + + # Get the release segment of our versions + left_split.append(list(itertools.takewhile(lambda x: x.isdigit(), left))) + 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]):]) + + # 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])), + ) + + 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. + 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: + try: + parsed.add(Specifier(specifier)) + except InvalidSpecifier: + parsed.add(LegacySpecifier(specifier)) + + # Turn our parsed specifiers into a frozen set and save them for later. + self._specs = frozenset(parsed) + + # Store our prereleases value so we can use it later to determine if + # we accept prereleases or not. + self._prereleases = prereleases + + def __repr__(self): + pre = ( + ", prereleases={0!r}".format(self.prereleases) + if self._prereleases is not None + else "" + ) + + return "<SpecifierSet({0!r}{1})>".format(str(self), pre) + + def __str__(self): + return ",".join(sorted(str(s) for s in self._specs)) + + def __hash__(self): + return hash(self._specs) + + def __and__(self, other): + if isinstance(other, string_types): + other = SpecifierSet(other) + elif not isinstance(other, SpecifierSet): + return NotImplemented + + specifier = SpecifierSet() + specifier._specs = frozenset(self._specs | other._specs) + + if self._prereleases is None and other._prereleases is not None: + specifier._prereleases = other._prereleases + elif self._prereleases is not None and other._prereleases is None: + specifier._prereleases = self._prereleases + elif self._prereleases == other._prereleases: + specifier._prereleases = self._prereleases + else: + raise ValueError( + "Cannot combine SpecifierSets with True and False prerelease " + "overrides." + ) + + return specifier + + def __eq__(self, other): + if isinstance(other, string_types): + other = SpecifierSet(other) + elif isinstance(other, _IndividualSpecifier): + other = SpecifierSet(str(other)) + elif not isinstance(other, SpecifierSet): + return NotImplemented + + return self._specs == other._specs + + def __ne__(self, other): + if isinstance(other, string_types): + other = SpecifierSet(other) + elif isinstance(other, _IndividualSpecifier): + other = SpecifierSet(str(other)) + elif not isinstance(other, SpecifierSet): + return NotImplemented + + return self._specs != other._specs + + def __len__(self): + return len(self._specs) + + def __iter__(self): + return iter(self._specs) + + @property + def prereleases(self): + # If we have been given an explicit prerelease modifier, then we'll + # pass that through here. + if self._prereleases is not None: + return self._prereleases + + # If we don't have any specifiers, and we don't have a forced value, + # then we'll just return None since we don't know if this should have + # pre-releases or not. + if not self._specs: + return None + + # Otherwise we'll see if any of the given specifiers accept + # prereleases, if any of them do we'll return True, otherwise False. + return any(s.prereleases for s in self._specs) + + @prereleases.setter + def prereleases(self, value): + self._prereleases = value + + def __contains__(self, item): + return self.contains(item) + + def contains(self, item, prereleases=None): + # Ensure that our item is a Version or LegacyVersion instance. + if not isinstance(item, (LegacyVersion, Version)): + item = parse(item) + + # 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. + if prereleases is None: + prereleases = self.prereleases + + # We can determine if we're going to allow pre-releases by looking to + # see if any of the underlying items supports them. If none of them do + # and this item is a pre-release then we do not allow it and we can + # short circuit that here. + # Note: This means that 1.0.dev1 would not be contained in something + # like >=1.0.devabc however it would be in >=1.0.debabc,>0.0.dev0 + if not prereleases and item.is_prerelease: + return False + + # We simply dispatch to the underlying specs here to make sure that the + # 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 + ) + + def filter(self, iterable, prereleases=None): + # 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. + if prereleases is None: + prereleases = self.prereleases + + # If we have any specifiers, then we want to wrap our iterable in the + # filter method for each one, this will act as a logical AND amongst + # each specifier. + if self._specs: + for spec in self._specs: + iterable = spec.filter(iterable, prereleases=bool(prereleases)) + return iterable + # If we do not have any specifiers, then we need to have a rough filter + # 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 = [] + + for item in iterable: + # Ensure that we some kind of Version class for this item. + if not isinstance(item, (LegacyVersion, Version)): + parsed_version = parse(item) + else: + parsed_version = item + + # Filter out any item which is parsed as a LegacyVersion + if isinstance(parsed_version, LegacyVersion): + continue + + # Store any item which is a pre-release for later unless we've + # already found a final version or we are accepting prereleases + if parsed_version.is_prerelease and not prereleases: + if not filtered: + found_prereleases.append(item) + else: + filtered.append(item) + + # If we've found no items except for pre-releases, then we'll go + # ahead and use the pre-releases + if not filtered and found_prereleases and prereleases is None: + return found_prereleases + + return filtered diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/packaging/utils.py b/venv/lib/python3.7/site-packages/pip/_vendor/packaging/utils.py new file mode 100644 index 0000000..4b94a82 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/packaging/utils.py @@ -0,0 +1,63 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import re + +from .version import InvalidVersion, Version + + +_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.7/site-packages/pip/_vendor/packaging/version.py b/venv/lib/python3.7/site-packages/pip/_vendor/packaging/version.py new file mode 100644 index 0000000..6ed5cbb --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/packaging/version.py @@ -0,0 +1,441 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import collections +import itertools +import re + +from ._structures import Infinity + + +__all__ = [ + "parse", "Version", "LegacyVersion", "InvalidVersion", "VERSION_PATTERN" +] + + +_Version = collections.namedtuple( + "_Version", + ["epoch", "release", "dev", "pre", "post", "local"], +) + + +def parse(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 + a valid PEP 440 version or a legacy version. + """ + try: + return Version(version) + except InvalidVersion: + return LegacyVersion(version) + + +class InvalidVersion(ValueError): + """ + An invalid version was found, users should refer to PEP 440. + """ + + +class _BaseVersion(object): + + def __hash__(self): + return hash(self._key) + + def __lt__(self, other): + return self._compare(other, lambda s, o: s < o) + + def __le__(self, other): + return self._compare(other, lambda s, o: s <= o) + + def __eq__(self, other): + return self._compare(other, lambda s, o: s == o) + + def __ge__(self, other): + return self._compare(other, lambda s, o: s >= o) + + def __gt__(self, other): + return self._compare(other, lambda s, o: s > o) + + def __ne__(self, other): + return self._compare(other, lambda s, o: s != o) + + def _compare(self, other, method): + if not isinstance(other, _BaseVersion): + return NotImplemented + + return method(self._key, other._key) + + +class LegacyVersion(_BaseVersion): + + def __init__(self, version): + self._version = str(version) + self._key = _legacy_cmpkey(self._version) + + def __str__(self): + return self._version + + def __repr__(self): + return "<LegacyVersion({0})>".format(repr(str(self))) + + @property + def public(self): + return self._version + + @property + 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 + + @property + def is_prerelease(self): + return False + + @property + 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_replacement_map = { + "pre": "c", "preview": "c", "-": "final-", "rc": "c", "dev": "@", +} + + +def _parse_version_parts(s): + for part in _legacy_version_component_re.split(s): + part = _legacy_version_replacement_map.get(part, part) + + if not part or part == ".": + continue + + if part[:1] in "0123456789": + # pad for numeric comparison + yield part.zfill(8) + else: + yield "*" + part + + # ensure that alpha/beta/candidate are before final + yield "*final" + + +def _legacy_cmpkey(version): + # 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, + # as before all PEP 440 versions. + epoch = -1 + + # This scheme is taken from pkg_resources.parse_version setuptools prior to + # it's adoption of the packaging library. + parts = [] + for part in _parse_version_parts(version.lower()): + if part.startswith("*"): + # remove "-" before a prerelease tag + if part < "*final": + while parts and parts[-1] == "*final-": + parts.pop() + + # remove trailing zeros from each series of numeric parts + while parts and parts[-1] == "00000000": + parts.pop() + + parts.append(part) + parts = tuple(parts) + + 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""" + v? + (?: + (?:(?P<epoch>[0-9]+)!)? # epoch + (?P<release>[0-9]+(?:\.[0-9]+)*) # release segment + (?P<pre> # pre-release + [-_\.]? + (?P<pre_l>(a|b|c|rc|alpha|beta|pre|preview)) + [-_\.]? + (?P<pre_n>[0-9]+)? + )? + (?P<post> # post release + (?:-(?P<post_n1>[0-9]+)) + | + (?: + [-_\.]? + (?P<post_l>post|rev|r) + [-_\.]? + (?P<post_n2>[0-9]+)? + ) + )? + (?P<dev> # dev release + [-_\.]? + (?P<dev_l>dev) + [-_\.]? + (?P<dev_n>[0-9]+)? + )? + ) + (?:\+(?P<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))? # local version +""" + + +class Version(_BaseVersion): + + _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 + match = self._regex.search(version) + if not match: + raise InvalidVersion("Invalid version: '{0}'".format(version)) + + # Store the parsed out pieces of the version + 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"), + ), + 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"), + ), + local=_parse_local_version(match.group("local")), + ) + + # Generate a key which will be used for sorting + self._key = _cmpkey( + self._version.epoch, + self._version.release, + self._version.pre, + self._version.post, + self._version.dev, + self._version.local, + ) + + def __repr__(self): + return "<Version({0})>".format(repr(str(self))) + + def __str__(self): + parts = [] + + # Epoch + if self.epoch != 0: + parts.append("{0}!".format(self.epoch)) + + # Release segment + parts.append(".".join(str(x) for x in self.release)) + + # Pre-release + if self.pre is not None: + parts.append("".join(str(x) for x in self.pre)) + + # Post-release + if self.post is not None: + parts.append(".post{0}".format(self.post)) + + # Development release + if self.dev is not None: + parts.append(".dev{0}".format(self.dev)) + + # Local version segment + 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] + + @property + def base_version(self): + parts = [] + + # Epoch + if self.epoch != 0: + parts.append("{0}!".format(self.epoch)) + + # Release segment + parts.append(".".join(str(x) for x in self.release)) + + return "".join(parts) + + @property + def is_prerelease(self): + return self.dev is not None or self.pre is not None + + @property + def is_postrelease(self): + return self.post is not None + + @property + def is_devrelease(self): + return self.dev is not None + + +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. + if number is None: + number = 0 + + # We normalize any letters to their lower case form + letter = letter.lower() + + # We consider some words to be alternate spellings of other words and + # in those cases we want to normalize the spellings to our preferred + # spelling. + if letter == "alpha": + letter = "a" + elif letter == "beta": + letter = "b" + elif letter in ["c", "pre", "preview"]: + letter = "rc" + elif letter in ["rev", "r"]: + letter = "post" + + return letter, int(number) + if not letter and number: + # We assume if we are given a number, but we are not given a letter + # then this is using the implicit post release syntax (e.g. 1.0-1) + letter = "post" + + return letter, int(number) + + +_local_version_separators = re.compile(r"[\._-]") + + +def _parse_local_version(local): + """ + Takes a string like abc.1.twelve and turns it into ("abc", 1, "twelve"). + """ + if local is not None: + return tuple( + part.lower() if not part.isdigit() else int(part) + for part in _local_version_separators.split(local) + ) + + +def _cmpkey(epoch, release, pre, post, dev, local): + # 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( + 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. + # We'll do this by abusing the pre segment, but we _only_ want to do this + # 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 + # Versions without a pre-release (except as noted above) should sort after + # those with one. + elif pre is None: + pre = Infinity + + # Versions without a post segment should sort before those with one. + if post is None: + post = -Infinity + + # Versions without a development segment should sort after those with one. + if dev is None: + dev = Infinity + + if local is None: + # Versions without a local segment should sort before those with one. + local = -Infinity + else: + # Versions with a local segment need that segment parsed to implement + # the sorting rules in PEP440. + # - Alpha numeric segments sort before numeric segments + # - Alpha numeric segments sort lexicographically + # - 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 + ) + + return epoch, release, pre, post, dev, local diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/pep517/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/pep517/__init__.py new file mode 100644 index 0000000..8beedea --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/pep517/__init__.py @@ -0,0 +1,4 @@ +"""Wrappers to build Python packages using PEP 517 hooks +""" + +__version__ = '0.2' diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..34d6f18c53d401e395527553bac858ec65a103b0 GIT binary patch literal 289 zcmXv}+e*Vg5Y0tUs{I0A_O%b~rY&tLh=|~;1QiNJ7&h57S(EH8yPIh94gQF~lvn@4 zCntp-IA<;lb7mgL<B^B>zD?d=F#Zn389pWtNPC0Ay}if%z0ZSJZxVLvoncyM#uBGU z(uj(a_~;5HiDqfZ^30OP3YnAmDJHA=h7?MbcGQK@Z1Fq^`bz+=Qh@#%pv5&pNq`^E zglKh=KTWj}Epr)dnV|<&aU7#{LDRX0ZMXf1K9>jH+4ZtDi!ayJ5h9oLjcTE%LR!bF tYP#AaMcE|z&^!^{Bv*#&OygM;KuF;LX8PD)-PMXWRdyc?PY-et`~#~>Q*;0T literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/_in_process.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/_in_process.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a7eb0d3d97c03caa5ea44b67c74310810cf19e7e GIT binary patch literal 5354 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 TIb+VSsyc)~e`UiuVzK`K7^rNR literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/check.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/check.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..35b8de18155b9e391acac207c5c39450ca79587e GIT binary patch literal 4753 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 NDZ<+p=$`AD{{h&i`z8PY literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/colorlog.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/colorlog.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b682efa67ce082939008c4689145bfa2abb8ed26 GIT binary patch literal 2918 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/compat.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1b5dc6b0536fb5638d88dd3400d5315adde86e6d GIT binary patch literal 1027 zcmaKq&ubGw6vt;~C+Rk(r5+SSkUe-=Fx@t_wuK_1AVnemXhjLavdL_cO*b>k>?W}x zJ?T;H(W@T)m*(oJ|AHsqo3u4Z>x1{+zWMpx&zr|fOBDk4`F895m=W>|i*tjTJOa=6 zAPCYVf(n+>CbgM0S<L#5ptp!{4omvJ;G*=2G`T2?1;{12BHXi)#o35p`^2wIcK0GF z(%92+Bof*6pz_8#De(K*{)>i}Nbk+T)7thuPf73PQPG36VVBicPeBW5oH`KOC=iW< zFM>Y@&sQN7WNJkU=ZkZ4^Vlh9pH0cs>98sLN-22@zw?T`Chs7FB;GJ|JSh!}PHo$# z#*JlLp)%hwTxGE|yq_zGVmQcrZXDI>8=gf)&y)|xk?!V(c776Fg`0oNAk)bxD&k-i z>7b)h5$ik{^n&(!7Vb=T`fKBjj+o>RHb%Psp_mNTz`8Ox2(l!rB{DCfG_7rJwR(rc zRu>1Yhoe{urGqTaHrKa;wi>|wtJ#sMAh|e1feZNi$b!%ns+S?RDOO-e3JE;{&+kG2 zLbjcjQ1zG=^gEl<A9Vj;F8YFt#-n{lmmujf1jADm37=^^Szp6|2xegk7c63ntu~zf ztL-{emv^rYGqdh}WG8p#J13ZM5;|qyuIL~ex2(c*y>mh}lJU8AA<e|%qrXhCrH1Ox zv{vcm2t8ObLkKdj!p9nh>DD|ky#o9G15D%9H^48h_seD>425ck;f%SHALXVxf=87o p878u$tY*7&4!>=L?SZ>HP-2+I5AiMJ_$oMcsmqp`%PVD<{{igx(-8mw literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/envbuild.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/envbuild.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9db8beade742e411108a8c0f9df9341d8086b46a GIT binary patch literal 4184 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/wrappers.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/wrappers.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aaad59a64c6a9825d2a3bafc992f0f677b5a4cca GIT binary patch literal 4751 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/pep517/_in_process.py b/venv/lib/python3.7/site-packages/pip/_vendor/pep517/_in_process.py new file mode 100644 index 0000000..baa14d3 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/pep517/_in_process.py @@ -0,0 +1,182 @@ +"""This is invoked in a subprocess to call the build backend hooks. + +It expects: +- Command line args: hook_name, control_dir +- Environment variable: PEP517_BUILD_BACKEND=entry.point:spec +- control_dir/input.json: + - {"kwargs": {...}} + +Results: +- control_dir/output.json + - {"return_val": ...} +""" +from glob import glob +from importlib import import_module +import os +from os.path import join as pjoin +import re +import shutil +import sys + +# This is run as a script, not a module, so it can't do a relative import +import compat + +def _build_backend(): + """Find and load the build backend""" + ep = os.environ['PEP517_BUILD_BACKEND'] + mod_path, _, obj_path = ep.partition(':') + obj = import_module(mod_path) + if obj_path: + for path_part in obj_path.split('.'): + obj = getattr(obj, path_part) + return obj + +def get_requires_for_build_wheel(config_settings): + """Invoke the optional get_requires_for_build_wheel hook + + Returns [] if the hook is not defined. + """ + backend = _build_backend() + try: + hook = backend.get_requires_for_build_wheel + except AttributeError: + return [] + else: + return hook(config_settings) + +def prepare_metadata_for_build_wheel(metadata_directory, config_settings): + """Invoke optional prepare_metadata_for_build_wheel + + Implements a fallback by building a wheel if the hook isn't defined. + """ + backend = _build_backend() + try: + hook = backend.prepare_metadata_for_build_wheel + except AttributeError: + return _get_wheel_metadata_from_wheel(backend, metadata_directory, + config_settings) + else: + return hook(metadata_directory, config_settings) + +WHEEL_BUILT_MARKER = 'PEP517_ALREADY_BUILT_WHEEL' + +def _dist_info_files(whl_zip): + """Identify the .dist-info folder inside a wheel ZipFile.""" + res = [] + for path in whl_zip.namelist(): + m = re.match(r'[^/\\]+-[^/\\]+\.dist-info/', path) + if m: + res.append(path) + if res: + return res + raise Exception("No .dist-info folder found in wheel") + +def _get_wheel_metadata_from_wheel(backend, metadata_directory, config_settings): + """Build a wheel and extract the metadata from it. + + Fallback for when the build backend does not define the 'get_wheel_metadata' + hook. + """ + from zipfile import ZipFile + whl_basename = backend.build_wheel(metadata_directory, config_settings) + with open(os.path.join(metadata_directory, WHEEL_BUILT_MARKER), 'wb'): + pass # Touch marker file + + whl_file = os.path.join(metadata_directory, whl_basename) + with ZipFile(whl_file) as zipf: + dist_info = _dist_info_files(zipf) + zipf.extractall(path=metadata_directory, members=dist_info) + return dist_info[0].split('/')[0] + +def _find_already_built_wheel(metadata_directory): + """Check for a wheel already built during the get_wheel_metadata hook. + """ + if not metadata_directory: + return None + metadata_parent = os.path.dirname(metadata_directory) + if not os.path.isfile(pjoin(metadata_parent, WHEEL_BUILT_MARKER)): + return None + + whl_files = glob(os.path.join(metadata_parent, '*.whl')) + if not whl_files: + print('Found wheel built marker, but no .whl files') + return None + if len(whl_files) > 1: + print('Found multiple .whl files; unspecified behaviour. ' + 'Will call build_wheel.') + return None + + # Exactly one .whl file + return whl_files[0] + +def build_wheel(wheel_directory, config_settings, metadata_directory=None): + """Invoke the mandatory build_wheel hook. + + If a wheel was already built in the prepare_metadata_for_build_wheel fallback, this + will copy it rather than rebuilding the wheel. + """ + prebuilt_whl = _find_already_built_wheel(metadata_directory) + if prebuilt_whl: + shutil.copy2(prebuilt_whl, wheel_directory) + return os.path.basename(prebuilt_whl) + + return _build_backend().build_wheel(wheel_directory, config_settings, + metadata_directory) + + +def get_requires_for_build_sdist(config_settings): + """Invoke the optional get_requires_for_build_wheel hook + + Returns [] if the hook is not defined. + """ + backend = _build_backend() + try: + hook = backend.get_requires_for_build_sdist + except AttributeError: + return [] + else: + return hook(config_settings) + +class _DummyException(Exception): + """Nothing should ever raise this exception""" + +class GotUnsupportedOperation(Exception): + """For internal use when backend raises UnsupportedOperation""" + +def build_sdist(sdist_directory, config_settings): + """Invoke the mandatory build_sdist hook.""" + backend = _build_backend() + try: + return backend.build_sdist(sdist_directory, config_settings) + except getattr(backend, 'UnsupportedOperation', _DummyException): + raise GotUnsupportedOperation + +HOOK_NAMES = { + 'get_requires_for_build_wheel', + 'prepare_metadata_for_build_wheel', + 'build_wheel', + 'get_requires_for_build_sdist', + 'build_sdist', +} + +def main(): + if len(sys.argv) < 3: + sys.exit("Needs args: hook_name, control_dir") + hook_name = sys.argv[1] + control_dir = sys.argv[2] + if hook_name not in HOOK_NAMES: + sys.exit("Unknown hook: %s" % hook_name) + hook = globals()[hook_name] + + hook_input = compat.read_json(pjoin(control_dir, 'input.json')) + + json_out = {'unsupported': False, 'return_val': None} + try: + json_out['return_val'] = hook(**hook_input['kwargs']) + except GotUnsupportedOperation: + json_out['unsupported'] = True + + compat.write_json(json_out, pjoin(control_dir, 'output.json'), indent=2) + +if __name__ == '__main__': + main() diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/pep517/check.py b/venv/lib/python3.7/site-packages/pip/_vendor/pep517/check.py new file mode 100644 index 0000000..c65d51c --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/pep517/check.py @@ -0,0 +1,194 @@ +"""Check a project and backend by attempting to build using PEP 517 hooks. +""" +import argparse +import logging +import os +from os.path import isfile, join as pjoin +from pip._vendor.pytoml import TomlError, load as toml_load +import shutil +from subprocess import CalledProcessError +import sys +import tarfile +from tempfile import mkdtemp +import zipfile + +from .colorlog import enable_colourful_output +from .envbuild import BuildEnvironment +from .wrappers import Pep517HookCaller + +log = logging.getLogger(__name__) + +def check_build_sdist(hooks): + with BuildEnvironment() as env: + try: + env.pip_install(hooks.build_sys_requires) + log.info('Installed static build dependencies') + except CalledProcessError: + log.error('Failed to install static build dependencies') + return False + + try: + reqs = hooks.get_requires_for_build_sdist({}) + log.info('Got build requires: %s', reqs) + except: + log.error('Failure in get_requires_for_build_sdist', exc_info=True) + return False + + try: + env.pip_install(reqs) + log.info('Installed dynamic build dependencies') + except CalledProcessError: + log.error('Failed to install dynamic build dependencies') + return False + + td = mkdtemp() + log.info('Trying to build sdist in %s', td) + try: + try: + filename = hooks.build_sdist(td, {}) + log.info('build_sdist returned %r', filename) + except: + log.info('Failure in build_sdist', exc_info=True) + return False + + if not filename.endswith('.tar.gz'): + log.error("Filename %s doesn't have .tar.gz extension", filename) + return False + + path = pjoin(td, filename) + if isfile(path): + log.info("Output file %s exists", path) + else: + log.error("Output file %s does not exist", path) + return False + + if tarfile.is_tarfile(path): + log.info("Output file is a tar file") + else: + log.error("Output file is not a tar file") + return False + + finally: + shutil.rmtree(td) + + return True + +def check_build_wheel(hooks): + with BuildEnvironment() as env: + try: + env.pip_install(hooks.build_sys_requires) + log.info('Installed static build dependencies') + except CalledProcessError: + log.error('Failed to install static build dependencies') + return False + + try: + reqs = hooks.get_requires_for_build_wheel({}) + log.info('Got build requires: %s', reqs) + except: + log.error('Failure in get_requires_for_build_sdist', exc_info=True) + return False + + try: + env.pip_install(reqs) + log.info('Installed dynamic build dependencies') + except CalledProcessError: + log.error('Failed to install dynamic build dependencies') + return False + + td = mkdtemp() + log.info('Trying to build wheel in %s', td) + try: + try: + filename = hooks.build_wheel(td, {}) + log.info('build_wheel returned %r', filename) + except: + log.info('Failure in build_wheel', exc_info=True) + return False + + if not filename.endswith('.whl'): + log.error("Filename %s doesn't have .whl extension", filename) + return False + + path = pjoin(td, filename) + if isfile(path): + log.info("Output file %s exists", path) + else: + log.error("Output file %s does not exist", path) + return False + + if zipfile.is_zipfile(path): + log.info("Output file is a zip file") + else: + log.error("Output file is not a zip file") + return False + + finally: + shutil.rmtree(td) + + return True + + +def check(source_dir): + pyproject = pjoin(source_dir, 'pyproject.toml') + if isfile(pyproject): + log.info('Found pyproject.toml') + else: + log.error('Missing pyproject.toml') + return False + + try: + with open(pyproject) as f: + pyproject_data = toml_load(f) + # Ensure the mandatory data can be loaded + buildsys = pyproject_data['build-system'] + requires = buildsys['requires'] + backend = buildsys['build-backend'] + log.info('Loaded pyproject.toml') + except (TomlError, KeyError): + log.error("Invalid pyproject.toml", exc_info=True) + return False + + hooks = Pep517HookCaller(source_dir, backend) + + sdist_ok = check_build_sdist(hooks) + wheel_ok = check_build_wheel(hooks) + + if not sdist_ok: + log.warning('Sdist checks failed; scroll up to see') + if not wheel_ok: + log.warning('Wheel checks failed') + + return sdist_ok + + +def main(argv=None): + ap = argparse.ArgumentParser() + ap.add_argument('source_dir', + help="A directory containing pyproject.toml") + args = ap.parse_args(argv) + + enable_colourful_output() + + ok = check(args.source_dir) + + if ok: + print(ansi('Checks passed', 'green')) + else: + print(ansi('Checks failed', 'red')) + sys.exit(1) + +ansi_codes = { + 'reset': '\x1b[0m', + 'bold': '\x1b[1m', + 'red': '\x1b[31m', + 'green': '\x1b[32m', +} +def ansi(s, attr): + if os.name != 'nt' and sys.stdout.isatty(): + return ansi_codes[attr] + str(s) + ansi_codes['reset'] + else: + return str(s) + +if __name__ == '__main__': + main() diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/pep517/colorlog.py b/venv/lib/python3.7/site-packages/pip/_vendor/pep517/colorlog.py new file mode 100644 index 0000000..26cf748 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/pep517/colorlog.py @@ -0,0 +1,110 @@ +"""Nicer log formatting with colours. + +Code copied from Tornado, Apache licensed. +""" +# Copyright 2012 Facebook +# +# 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. + +import logging +import sys + +try: + import curses +except ImportError: + curses = None + +def _stderr_supports_color(): + color = False + if curses and hasattr(sys.stderr, 'isatty') and sys.stderr.isatty(): + try: + curses.setupterm() + if curses.tigetnum("colors") > 0: + color = True + except Exception: + pass + return color + +class LogFormatter(logging.Formatter): + """Log formatter with colour support + """ + DEFAULT_COLORS = { + logging.INFO: 2, # Green + logging.WARNING: 3, # Yellow + logging.ERROR: 1, # Red + logging.CRITICAL: 1, + } + + def __init__(self, color=True, datefmt=None): + r""" + :arg bool color: Enables color support. + :arg string fmt: Log message format. + It will be applied to the attributes dict of log records. The + text between ``%(color)s`` and ``%(end_color)s`` will be colored + depending on the level if color support is on. + :arg dict colors: color mappings from logging level to terminal color + code + :arg string datefmt: Datetime format. + Used for formatting ``(asctime)`` placeholder in ``prefix_fmt``. + .. versionchanged:: 3.2 + Added ``fmt`` and ``datefmt`` arguments. + """ + logging.Formatter.__init__(self, datefmt=datefmt) + self._colors = {} + if color and _stderr_supports_color(): + # The curses module has some str/bytes confusion in + # python3. Until version 3.2.3, most methods return + # bytes, but only accept strings. In addition, we want to + # output these strings with the logging module, which + # works with unicode strings. The explicit calls to + # unicode() below are harmless in python2 but will do the + # right conversion in python 3. + fg_color = (curses.tigetstr("setaf") or + curses.tigetstr("setf") or "") + if (3, 0) < sys.version_info < (3, 2, 3): + fg_color = str(fg_color, "ascii") + + for levelno, code in self.DEFAULT_COLORS.items(): + self._colors[levelno] = str(curses.tparm(fg_color, code), "ascii") + self._normal = str(curses.tigetstr("sgr0"), "ascii") + + scr = curses.initscr() + self.termwidth = scr.getmaxyx()[1] + curses.endwin() + else: + self._normal = '' + # Default width is usually 80, but too wide is worse than too narrow + self.termwidth = 70 + + def formatMessage(self, record): + l = len(record.message) + right_text = '{initial}-{name}'.format(initial=record.levelname[0], + name=record.name) + if l + len(right_text) < self.termwidth: + space = ' ' * (self.termwidth - (l + len(right_text))) + else: + space = ' ' + + if record.levelno in self._colors: + start_color = self._colors[record.levelno] + end_color = self._normal + else: + start_color = end_color = '' + + return record.message + space + start_color + right_text + end_color + +def enable_colourful_output(level=logging.INFO): + handler = logging.StreamHandler() + handler.setFormatter(LogFormatter()) + logging.root.addHandler(handler) + logging.root.setLevel(level) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/pep517/compat.py b/venv/lib/python3.7/site-packages/pip/_vendor/pep517/compat.py new file mode 100644 index 0000000..01c66fc --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/pep517/compat.py @@ -0,0 +1,23 @@ +"""Handle reading and writing JSON in UTF-8, on Python 3 and 2.""" +import json +import sys + +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) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/pep517/envbuild.py b/venv/lib/python3.7/site-packages/pip/_vendor/pep517/envbuild.py new file mode 100644 index 0000000..c264f46 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/pep517/envbuild.py @@ -0,0 +1,150 @@ +"""Build wheels/sdists by installing build deps to a temporary environment. +""" + +import os +import logging +from pip._vendor import pytoml +import shutil +from subprocess import check_call +import sys +from sysconfig import get_paths +from tempfile import mkdtemp + +from .wrappers import Pep517HookCaller + +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) + buildsys = pyproject_data['build-system'] + return buildsys['requires'], buildsys['build-backend'] + + +class BuildEnvironment(object): + """Context manager to install build deps in a simple temporary environment + + Based on code I wrote for pip, which is MIT licensed. + """ + # Copyright (c) 2008-2016 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. + + path = None + + def __init__(self, cleanup=True): + self._cleanup = cleanup + + def __enter__(self): + self.path = mkdtemp(prefix='pep517-build-env-') + log.info('Temporary build environment: %s', self.path) + + self.save_path = os.environ.get('PATH', None) + self.save_pythonpath = os.environ.get('PYTHONPATH', None) + + install_scheme = 'nt' if (os.name == 'nt') else 'posix_prefix' + install_dirs = get_paths(install_scheme, vars={ + 'base': self.path, + 'platbase': self.path, + }) + + scripts = install_dirs['scripts'] + if self.save_path: + os.environ['PATH'] = scripts + os.pathsep + self.save_path + else: + os.environ['PATH'] = scripts + os.pathsep + os.defpath + + if install_dirs['purelib'] == install_dirs['platlib']: + lib_dirs = install_dirs['purelib'] + else: + lib_dirs = install_dirs['purelib'] + os.pathsep + \ + install_dirs['platlib'] + if self.save_pythonpath: + os.environ['PYTHONPATH'] = lib_dirs + os.pathsep + \ + self.save_pythonpath + else: + os.environ['PYTHONPATH'] = lib_dirs + + return self + + def pip_install(self, reqs): + """Install dependencies into this env by calling pip in a subprocess""" + if not reqs: + return + log.info('Calling pip to install %s', reqs) + check_call([sys.executable, '-m', 'pip', 'install', '--ignore-installed', + '--prefix', self.path] + list(reqs)) + + def __exit__(self, exc_type, exc_val, exc_tb): + if self._cleanup and (self.path is not None) and os.path.isdir(self.path): + shutil.rmtree(self.path) + + if self.save_path is None: + os.environ.pop('PATH', None) + else: + os.environ['PATH'] = self.save_path + + if self.save_pythonpath is None: + os.environ.pop('PYTHONPATH', None) + else: + os.environ['PYTHONPATH'] = self.save_pythonpath + +def build_wheel(source_dir, wheel_dir, config_settings=None): + """Build a wheel from a source directory using PEP 517 hooks. + + :param str source_dir: Source directory containing pyproject.toml + :param str wheel_dir: Target directory to create wheel in + :param dict config_settings: Options to pass to build backend + + This is a blocking function which will run pip in a subprocess to install + build requirements. + """ + if config_settings is None: + config_settings = {} + requires, backend = _load_pyproject(source_dir) + hooks = Pep517HookCaller(source_dir, backend) + + with BuildEnvironment() as env: + env.pip_install(requires) + reqs = hooks.get_requires_for_build_wheel(config_settings) + env.pip_install(reqs) + return hooks.build_wheel(wheel_dir, config_settings) + + +def build_sdist(source_dir, sdist_dir, config_settings=None): + """Build an sdist from a source directory using PEP 517 hooks. + + :param str source_dir: Source directory containing pyproject.toml + :param str sdist_dir: Target directory to place sdist in + :param dict config_settings: Options to pass to build backend + + This is a blocking function which will run pip in a subprocess to install + build requirements. + """ + if config_settings is None: + config_settings = {} + requires, backend = _load_pyproject(source_dir) + hooks = Pep517HookCaller(source_dir, backend) + + with BuildEnvironment() as env: + env.pip_install(requires) + reqs = hooks.get_requires_for_build_sdist(config_settings) + env.pip_install(reqs) + return hooks.build_sdist(sdist_dir, config_settings) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/pep517/wrappers.py b/venv/lib/python3.7/site-packages/pip/_vendor/pep517/wrappers.py new file mode 100644 index 0000000..28260f3 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/pep517/wrappers.py @@ -0,0 +1,134 @@ +from contextlib import contextmanager +import os +from os.path import dirname, abspath, join as pjoin +import shutil +from subprocess import check_call +import sys +from tempfile import mkdtemp + +from . import compat + +_in_proc_script = pjoin(dirname(abspath(__file__)), '_in_process.py') + +@contextmanager +def tempdir(): + td = mkdtemp() + try: + yield td + finally: + shutil.rmtree(td) + +class UnsupportedOperation(Exception): + """May be raised by build_sdist if the backend indicates that it can't.""" + +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. + """ + def __init__(self, source_dir, build_backend): + self.source_dir = abspath(source_dir) + self.build_backend = build_backend + + def get_requires_for_build_wheel(self, config_settings=None): + """Identify packages required for building a wheel + + Returns a list of dependency specifications, e.g.: + ["wheel >= 0.25", "setuptools"] + + This does not include requirements specified in pyproject.toml. + It returns the result of calling the equivalently named hook in a + subprocess. + """ + return self._call_hook('get_requires_for_build_wheel', { + 'config_settings': config_settings + }) + + def prepare_metadata_for_build_wheel(self, metadata_directory, config_settings=None): + """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. + """ + return self._call_hook('prepare_metadata_for_build_wheel', { + 'metadata_directory': abspath(metadata_directory), + 'config_settings': config_settings, + }) + + def build_wheel(self, wheel_directory, config_settings=None, metadata_directory=None): + """Build a wheel from this project. + + Returns the name of the newly created file. + + In general, this will call the 'build_wheel' hook in the backend. + However, if that was previously called by + 'prepare_metadata_for_build_wheel', and the same metadata_directory is + used, the previously built wheel will be copied to wheel_directory. + """ + if metadata_directory is not None: + metadata_directory = abspath(metadata_directory) + return self._call_hook('build_wheel', { + 'wheel_directory': abspath(wheel_directory), + 'config_settings': config_settings, + 'metadata_directory': metadata_directory, + }) + + def get_requires_for_build_sdist(self, config_settings=None): + """Identify packages required for building a wheel + + Returns a list of dependency specifications, e.g.: + ["setuptools >= 26"] + + This does not include requirements specified in pyproject.toml. + It returns the result of calling the equivalently named hook in a + subprocess. + """ + return self._call_hook('get_requires_for_build_sdist', { + 'config_settings': config_settings + }) + + def build_sdist(self, sdist_directory, config_settings=None): + """Build an sdist from this project. + + Returns the name of the newly created file. + + This calls the 'build_sdist' backend hook in a subprocess. + """ + return self._call_hook('build_sdist', { + 'sdist_directory': abspath(sdist_directory), + 'config_settings': config_settings, + }) + + + def _call_hook(self, hook_name, kwargs): + env = os.environ.copy() + + # On Python 2, pytoml returns Unicode values (which is correct) but the + # environment passed to check_call needs to contain string values. We + # convert here by encoding using ASCII (the backend can only contain + # 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). + if sys.version_info[0] == 2: + build_backend = self.build_backend.encode('ASCII') + else: + build_backend = self.build_backend + + env['PEP517_BUILD_BACKEND'] = build_backend + with tempdir() as td: + compat.write_json({'kwargs': kwargs}, pjoin(td, 'input.json'), + indent=2) + + # Run the hook in a subprocess + check_call([sys.executable, _in_proc_script, hook_name, td], + cwd=self.source_dir, env=env) + + data = compat.read_json(pjoin(td, 'output.json')) + if data.get('unsupported'): + raise UnsupportedOperation + return data['return_val'] + diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/pkg_resources/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/pkg_resources/__init__.py new file mode 100644 index 0000000..0b432f6 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/pkg_resources/__init__.py @@ -0,0 +1,3149 @@ +# coding: utf-8 +""" +Package resource API +-------------------- + +A resource is a logical file contained within a package, or a logical +subdirectory thereof. The package resource API expects resource names +to have their path parts separated with ``/``, *not* whatever the local +path separator is. Do not use os.path operations to manipulate resource +names being passed into the API. + +The package resource API is designed to work with normal filesystem packages, +.egg files, and unpacked .egg files. It can also work in a limited way with +.zip files and with custom PEP 302 loaders that support the ``get_data()`` +method. +""" + +from __future__ import absolute_import + +import sys +import os +import io +import time +import re +import types +import zipfile +import zipimport +import warnings +import stat +import functools +import pkgutil +import operator +import platform +import collections +import plistlib +import email.parser +import errno +import tempfile +import textwrap +import itertools +import inspect +from pkgutil import get_importer + +try: + import _imp +except ImportError: + # Python 3.2 compatibility + import imp as _imp + +try: + FileExistsError +except NameError: + FileExistsError = OSError + +from pip._vendor import six +from pip._vendor.six.moves import urllib, map, filter + +# capture these to bypass sandboxing +from os import utime +try: + from os import mkdir, rename, unlink + WRITE_SUPPORT = True +except ImportError: + # no write support, probably under GAE + WRITE_SUPPORT = False + +from os import open as os_open +from os.path import isdir, split + +try: + import importlib.machinery as importlib_machinery + # access attribute to force import under delayed import mechanisms. + importlib_machinery.__name__ +except ImportError: + importlib_machinery = None + +from . import py31compat +from pip._vendor import appdirs +from pip._vendor import packaging +__import__('pip._vendor.packaging.version') +__import__('pip._vendor.packaging.specifiers') +__import__('pip._vendor.packaging.requirements') +__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 six.PY2: + # Those builtin exceptions are only defined in Python 3 + PermissionError = None + NotADirectoryError = None + +# declare some globals that will be defined later to +# satisfy the linters. +require = None +working_set = None +add_activation_listener = None +resources_stream = None +cleanup_resources = None +resource_dir = None +resource_stream = None +set_extraction_path = None +resource_isdir = None +resource_string = None +iter_entry_points = None +resource_listdir = None +resource_filename = None +resource_exists = None +_distribution_finders = None +_namespace_handlers = None +_namespace_packages = None + + +class PEP440Warning(RuntimeWarning): + """ + Used when there is an issue with a version or specifier not complying with + PEP 440. + """ + + +def parse_version(v): + try: + return packaging.version.Version(v) + except packaging.version.InvalidVersion: + return packaging.version.LegacyVersion(v) + + +_state_vars = {} + + +def _declare_state(vartype, **kw): + globals().update(kw) + _state_vars.update(dict.fromkeys(kw, vartype)) + + +def __getstate__(): + state = {} + g = globals() + for k, v in _state_vars.items(): + state[k] = g['_sget_' + v](g[k]) + return state + + +def __setstate__(state): + g = globals() + for k, v in state.items(): + g['_sset_' + _state_vars[k]](k, g[k], v) + return state + + +def _sget_dict(val): + return val.copy() + + +def _sset_dict(key, ob, state): + ob.clear() + ob.update(state) + + +def _sget_object(val): + return val.__getstate__() + + +def _sset_object(key, ob, state): + ob.__setstate__(state) + + +_sget_none = _sset_none = lambda *args: None + + +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 + 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 + current version of the OS. + + If this condition occurs for any other platform with a version in its + platform strings, this function should be extended accordingly. + """ + plat = get_build_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)) + except ValueError: + # not Mac OS X + pass + return plat + + +__all__ = [ + # Basic resource access and distribution/entry point discovery + 'require', 'run_script', 'get_provider', 'get_distribution', + 'load_entry_point', 'get_entry_map', 'get_entry_info', + 'iter_entry_points', + 'resource_string', 'resource_stream', 'resource_filename', + 'resource_listdir', 'resource_exists', 'resource_isdir', + + # Environmental control + 'declare_namespace', 'working_set', 'add_activation_listener', + 'find_distributions', 'set_extraction_path', 'cleanup_resources', + 'get_default_cache', + + # Primary implementation classes + 'Environment', 'WorkingSet', 'ResourceManager', + 'Distribution', 'Requirement', 'EntryPoint', + + # Exceptions + 'ResolutionError', 'VersionConflict', 'DistributionNotFound', + 'UnknownExtra', 'ExtractionError', + + # Warnings + 'PEP440Warning', + + # Parsing functions and string utilities + 'parse_requirements', 'parse_version', 'safe_name', 'safe_version', + 'get_platform', 'compatible_platforms', 'yield_lines', 'split_sections', + 'safe_extra', 'to_filename', 'invalid_marker', 'evaluate_marker', + + # filesystem utilities + 'ensure_directory', 'normalize_path', + + # Distribution "precedence" constants + 'EGG_DIST', 'BINARY_DIST', 'SOURCE_DIST', 'CHECKOUT_DIST', 'DEVELOP_DIST', + + # "Provider" interfaces, implementations, and registration/lookup APIs + 'IMetadataProvider', 'IResourceProvider', 'FileMetadata', + 'PathMetadata', 'EggMetadata', 'EmptyProvider', 'empty_provider', + 'NullProvider', 'EggProvider', 'DefaultProvider', 'ZipProvider', + 'register_finder', 'register_namespace_handler', 'register_loader_type', + 'fixup_namespace_packages', 'get_importer', + + # Deprecated/backward compatibility only + 'run_main', 'AvailableDistributions', +] + + +class ResolutionError(Exception): + """Abstract base for dependency resolution errors""" + + def __repr__(self): + return self.__class__.__name__ + repr(self.args) + + +class VersionConflict(ResolutionError): + """ + An already-installed version conflicts with the requested version. + + Should be initialized with the installed Distribution and the requested + Requirement. + """ + + _template = "{self.dist} is installed but {self.req} is required" + + @property + def dist(self): + return self.args[0] + + @property + def req(self): + return self.args[1] + + def report(self): + return self._template.format(**locals()) + + def with_context(self, required_by): + """ + If required_by is non-empty, return a version of self that is a + ContextualVersionConflict. + """ + if not required_by: + return self + args = self.args + (required_by,) + return ContextualVersionConflict(*args) + + +class ContextualVersionConflict(VersionConflict): + """ + A VersionConflict that accepts a third parameter, the set of the + requirements that required the installed Distribution. + """ + + _template = VersionConflict._template + ' by {self.required_by}' + + @property + def required_by(self): + return self.args[2] + + +class DistributionNotFound(ResolutionError): + """A requested distribution was not found""" + + _template = ("The '{self.req}' distribution was not found " + "and is required by {self.requirers_str}") + + @property + def req(self): + return self.args[0] + + @property + def requirers(self): + return self.args[1] + + @property + def requirers_str(self): + if not self.requirers: + return 'the application' + return ', '.join(self.requirers) + + def report(self): + return self._template.format(**locals()) + + def __str__(self): + return self.report() + + +class UnknownExtra(ResolutionError): + """Distribution doesn't have an "extra feature" of the given name""" + + +_provider_factories = {} + +PY_MAJOR = sys.version[:3] +EGG_DIST = 3 +BINARY_DIST = 2 +SOURCE_DIST = 1 +CHECKOUT_DIST = 0 +DEVELOP_DIST = -1 + + +def register_loader_type(loader_type, provider_factory): + """Register `provider_factory` to make providers for `loader_type` + + `loader_type` is the type or class of a PEP 302 ``module.__loader__``, + and `provider_factory` is a function that, passed a *module* object, + returns an ``IResourceProvider`` for that module. + """ + _provider_factories[loader_type] = provider_factory + + +def get_provider(moduleOrReq): + """Return an IResourceProvider for the named module or requirement""" + if isinstance(moduleOrReq, Requirement): + return working_set.find(moduleOrReq) or require(str(moduleOrReq))[0] + try: + module = sys.modules[moduleOrReq] + except KeyError: + __import__(moduleOrReq) + module = sys.modules[moduleOrReq] + loader = getattr(module, '__loader__', None) + return _find_adapter(_provider_factories, loader)(module) + + +def _macosx_vers(_cache=[]): + if not _cache: + version = platform.mac_ver()[0] + # fallback for MacPorts + if version == '': + plist = '/System/Library/CoreServices/SystemVersion.plist' + if os.path.exists(plist): + if hasattr(plistlib, 'readPlist'): + plist_content = plistlib.readPlist(plist) + if 'ProductVersion' in plist_content: + version = plist_content['ProductVersion'] + + _cache.append(version.split('.')) + return _cache[0] + + +def _macosx_arch(machine): + return {'PowerPC': 'ppc', 'Power_Macintosh': 'ppc'}.get(machine, machine) + + +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. + """ + from sysconfig import get_platform + + plat = get_platform() + if sys.platform == "darwin" and not plat.startswith('macosx-'): + try: + version = _macosx_vers() + machine = os.uname()[4].replace(" ", "_") + return "macosx-%d.%d-%s" % ( + int(version[0]), int(version[1]), + _macosx_arch(machine), + ) + except ValueError: + # if someone is running a non-Mac darwin system, this will fall + # through to the default implementation + pass + return plat + + +macosVersionString = re.compile(r"macosx-(\d+)\.(\d+)-(.*)") +darwinVersionString = re.compile(r"darwin-(\d+)\.(\d+)\.(\d+)-(.*)") +# XXX backward compat +get_platform = get_build_platform + + +def compatible_platforms(provided, required): + """Can code for the `provided` platform run on the `required` platform? + + Returns true if either platform is ``None``, or the platforms are equal. + + XXX Needs compatibility checks for Linux and other unixy OSes. + """ + if provided is None or required is None or provided == required: + # easy case + return True + + # Mac OS X special cases + reqMac = macosVersionString.match(required) + if reqMac: + provMac = macosVersionString.match(provided) + + # is this a Mac package? + 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. + provDarwin = darwinVersionString.match(provided) + if provDarwin: + dversion = int(provDarwin.group(1)) + macosversion = "%s.%s" % (reqMac.group(1), reqMac.group(2)) + if dversion == 7 and macosversion >= "10.3" or \ + dversion == 8 and macosversion >= "10.4": + return True + # egg isn't macosx or legacy darwin + return False + + # are they the same major version and machine type? + if provMac.group(1) != reqMac.group(1) or \ + provMac.group(3) != reqMac.group(3): + return False + + # is the required OS major update >= the provided one? + if int(provMac.group(2)) > int(reqMac.group(2)): + return False + + return True + + # XXX Linux and other platforms' special cases should go here + return False + + +def run_script(dist_spec, script_name): + """Locate distribution `dist_spec` and run its `script_name` script""" + ns = sys._getframe(1).f_globals + name = ns['__name__'] + ns.clear() + ns['__name__'] = name + require(dist_spec)[0].run_script(script_name, ns) + + +# backward compatibility +run_main = run_script + + +def get_distribution(dist): + """Return a current distribution object for a Requirement or string""" + if isinstance(dist, six.string_types): + dist = Requirement.parse(dist) + if isinstance(dist, Requirement): + dist = get_provider(dist) + if not isinstance(dist, Distribution): + raise TypeError("Expected string, Requirement, or Distribution", dist) + return dist + + +def load_entry_point(dist, group, name): + """Return `name` entry point of `group` for `dist` or raise ImportError""" + return get_distribution(dist).load_entry_point(group, name) + + +def get_entry_map(dist, group=None): + """Return the entry point map for `group`, or the full entry map""" + return get_distribution(dist).get_entry_map(group) + + +def get_entry_info(dist, group, name): + """Return the EntryPoint object for `group`+`name`, or ``None``""" + return get_distribution(dist).get_entry_info(group, name) + + +class IMetadataProvider: + def has_metadata(name): + """Does the package's distribution contain the named metadata?""" + + def get_metadata(name): + """The named metadata resource as a string""" + + def get_metadata_lines(name): + """Yield named metadata resource as list of non-blank non-comment lines + + Leading and trailing whitespace is stripped from each line, and lines + with ``#`` as the first non-blank character are omitted.""" + + def metadata_isdir(name): + """Is the named metadata a directory? (like ``os.path.isdir()``)""" + + def metadata_listdir(name): + """List of metadata names in the directory (like ``os.listdir()``)""" + + def run_script(script_name, namespace): + """Execute the named script in the supplied namespace dictionary""" + + +class IResourceProvider(IMetadataProvider): + """An object that provides access to package resources""" + + def get_resource_filename(manager, resource_name): + """Return a true filesystem path for `resource_name` + + `manager` must be an ``IResourceManager``""" + + def get_resource_stream(manager, resource_name): + """Return a readable file-like object for `resource_name` + + `manager` must be an ``IResourceManager``""" + + def get_resource_string(manager, resource_name): + """Return a string containing the contents of `resource_name` + + `manager` must be an ``IResourceManager``""" + + def has_resource(resource_name): + """Does the package contain the named resource?""" + + def resource_isdir(resource_name): + """Is the named resource a directory? (like ``os.path.isdir()``)""" + + def resource_listdir(resource_name): + """List of resource names in the directory (like ``os.listdir()``)""" + + +class WorkingSet: + """A collection of active distributions on sys.path (or a similar list)""" + + def __init__(self, entries=None): + """Create working set from list of path entries (default=sys.path)""" + self.entries = [] + self.entry_keys = {} + self.by_key = {} + self.callbacks = [] + + if entries is None: + entries = sys.path + + for entry in entries: + self.add_entry(entry) + + @classmethod + def _build_master(cls): + """ + Prepare the master working set. + """ + ws = cls() + try: + from __main__ import __requires__ + except ImportError: + # The main program does not list any requirements + return ws + + # ensure the requirements are met + try: + ws.require(__requires__) + except VersionConflict: + return cls._build_from_requirements(__requires__) + + return ws + + @classmethod + def _build_from_requirements(cls, req_spec): + """ + Build a working set from a requirement spec. Rewrites sys.path. + """ + # try it without defaults already on sys.path + # by starting with an empty path + ws = cls([]) + reqs = parse_requirements(req_spec) + dists = ws.resolve(reqs, Environment()) + for dist in dists: + ws.add(dist) + + # add any missing entries from sys.path + for entry in sys.path: + if entry not in ws.entries: + ws.add_entry(entry) + + # then copy back to sys.path + sys.path[:] = ws.entries + return ws + + def add_entry(self, entry): + """Add a path item to ``.entries``, finding any distributions on it + + ``find_distributions(entry, True)`` is used to find distributions + corresponding to the path entry, and they are added. `entry` is + always appended to ``.entries``, even if it is already present. + (This is because ``sys.path`` can contain the same value more than + once, and the ``.entries`` of the ``sys.path`` WorkingSet should always + equal ``sys.path``.) + """ + self.entry_keys.setdefault(entry, []) + self.entries.append(entry) + for dist in find_distributions(entry, True): + self.add(dist, entry, False) + + def __contains__(self, dist): + """True if `dist` is the active distribution for its project""" + return self.by_key.get(dist.key) == dist + + def find(self, req): + """Find a distribution matching requirement `req` + + If there is an active distribution for the requested project, this + returns it as long as it meets the version requirement specified by + `req`. But, if there is an active distribution for the project and it + does *not* meet the `req` requirement, ``VersionConflict`` is raised. + If there is no active distribution for the requested project, ``None`` + is returned. + """ + dist = self.by_key.get(req.key) + if dist is not None and dist not in req: + # XXX add more info + raise VersionConflict(dist, req) + return dist + + def iter_entry_points(self, group, name=None): + """Yield entry point objects from `group` matching `name` + + If `name` is None, yields all entry points in `group` from all + distributions in the working set, otherwise only ones matching + both `group` and `name` are yielded (in distribution order). + """ + return ( + entry + for dist in self + for entry in dist.get_entry_map(group).values() + if name is None or name == entry.name + ) + + def run_script(self, requires, script_name): + """Locate distribution for `requires` and run `script_name` script""" + ns = sys._getframe(1).f_globals + name = ns['__name__'] + ns.clear() + ns['__name__'] = name + self.require(requires)[0].run_script(script_name, ns) + + def __iter__(self): + """Yield distributions for non-duplicate projects in the working set + + The yield order is the order in which the items' path entries were + added to the working set. + """ + seen = {} + for item in self.entries: + if item not in self.entry_keys: + # workaround a cache issue + continue + + for key in self.entry_keys[item]: + if key not in seen: + seen[key] = 1 + yield self.by_key[key] + + def add(self, dist, entry=None, insert=True, replace=False): + """Add `dist` to working set, associated with `entry` + + If `entry` is unspecified, it defaults to the ``.location`` of `dist`. + On exit from this routine, `entry` is added to the end of the working + set's ``.entries`` (if it wasn't already present). + + `dist` is only added to the working set if it's for a project that + doesn't already have a distribution in the set, unless `replace=True`. + If it's added, any callbacks registered with the ``subscribe()`` method + will be called. + """ + if insert: + dist.insert_on(self.entries, entry, replace=replace) + + if entry is None: + entry = dist.location + keys = self.entry_keys.setdefault(entry, []) + keys2 = self.entry_keys.setdefault(dist.location, []) + if not replace and dist.key in self.by_key: + # ignore hidden distros + return + + self.by_key[dist.key] = dist + if dist.key not in keys: + keys.append(dist.key) + if dist.key not in keys2: + keys2.append(dist.key) + self._added_new(dist) + + def resolve(self, requirements, env=None, installer=None, + replace_conflicting=False, extras=None): + """List all distributions needed to (recursively) meet `requirements` + + `requirements` must be a sequence of ``Requirement`` objects. `env`, + if supplied, should be an ``Environment`` instance. If + not supplied, it defaults to all distributions available within any + entry or distribution in the working set. `installer`, if supplied, + will be invoked with each requirement that cannot be met by an + already-installed distribution; it should return a ``Distribution`` or + ``None``. + + Unless `replace_conflicting=True`, raises a VersionConflict exception + if + any requirements are found on the path that have the correct name but + the wrong version. Otherwise, if an `installer` is supplied it will be + invoked to obtain the correct version of the requirement and activate + it. + + `extras` is a list of the extras to be used with these requirements. + This is important because extra requirements may look like `my_req; + extra = "my_extra"`, which would otherwise be interpreted as a purely + optional requirement. Instead, we want to be able to assert that these + requirements are truly required. + """ + + # set up the stack + requirements = list(requirements)[::-1] + # set of processed requirements + processed = {} + # key -> dist + best = {} + to_activate = [] + + req_extras = _ReqExtras() + + # Mapping of requirement to set of distributions that required it; + # useful for reporting info about conflicts. + required_by = collections.defaultdict(set) + + while requirements: + # process dependencies breadth-first + req = requirements.pop(0) + if req in processed: + # Ignore cyclic or redundant dependencies + continue + + if not req_extras.markers_pass(req, extras): + continue + + dist = best.get(req.key) + if dist is None: + # Find the best distribution and add it to the map + dist = self.by_key.get(req.key) + if dist is None or (dist not in req and replace_conflicting): + ws = self + if env is None: + if dist is None: + env = Environment(self.entries) + else: + # Use an empty environment and workingset to avoid + # any further conflicts with the conflicting + # distribution + env = Environment([]) + ws = WorkingSet([]) + dist = best[req.key] = env.best_match( + req, ws, installer, + replace_conflicting=replace_conflicting + ) + if dist is None: + requirers = required_by.get(req, None) + raise DistributionNotFound(req, requirers) + to_activate.append(dist) + if dist not in req: + # Oops, the "best" so far conflicts with a dependency + dependent_req = required_by[req] + raise VersionConflict(dist, req).with_context(dependent_req) + + # push the new requirements onto the stack + new_requirements = dist.requires(req.extras)[::-1] + requirements.extend(new_requirements) + + # Register the new requirements needed by req + for new_requirement in new_requirements: + required_by[new_requirement].add(req.project_name) + req_extras[new_requirement] = req.extras + + processed[req] = True + + # return list of distros to activate + return to_activate + + def find_plugins( + self, plugin_env, full_env=None, installer=None, fallback=True): + """Find all activatable distributions in `plugin_env` + + Example usage:: + + distributions, errors = working_set.find_plugins( + Environment(plugin_dirlist) + ) + # add plugins+libs to sys.path + map(working_set.add, distributions) + # display errors + print('Could not load', errors) + + The `plugin_env` should be an ``Environment`` instance that contains + only distributions that are in the project's "plugin directory" or + directories. The `full_env`, if supplied, should be an ``Environment`` + contains all currently-available distributions. If `full_env` is not + supplied, one is created automatically from the ``WorkingSet`` this + method is called on, which will typically mean that every directory on + ``sys.path`` will be scanned for distributions. + + `installer` is a standard installer callback as used by the + ``resolve()`` method. The `fallback` flag indicates whether we should + attempt to resolve older versions of a plugin if the newest version + cannot be resolved. + + This method returns a 2-tuple: (`distributions`, `error_info`), where + `distributions` is a list of the distributions found in `plugin_env` + that were loadable, along with any other distributions that are needed + to resolve their dependencies. `error_info` is a dictionary mapping + unloadable plugin distributions to an exception instance describing the + error that occurred. Usually this will be a ``DistributionNotFound`` or + ``VersionConflict`` instance. + """ + + plugin_projects = list(plugin_env) + # scan project names in alphabetic order + plugin_projects.sort() + + error_info = {} + distributions = {} + + if full_env is None: + env = Environment(self.entries) + env += plugin_env + else: + env = full_env + plugin_env + + shadow_set = self.__class__([]) + # put all our entries in shadow_set + list(map(shadow_set.add, self)) + + for project_name in plugin_projects: + + for dist in plugin_env[project_name]: + + req = [dist.as_requirement()] + + try: + resolvees = shadow_set.resolve(req, env, installer) + + except ResolutionError as v: + # save error info + error_info[dist] = v + if fallback: + # try the next older version of project + continue + else: + # give up on this project, keep going + break + + else: + list(map(shadow_set.add, resolvees)) + distributions.update(dict.fromkeys(resolvees)) + + # success, no need to try any more versions of this project + break + + distributions = list(distributions) + distributions.sort() + + return distributions, error_info + + def require(self, *requirements): + """Ensure that distributions matching `requirements` are activated + + `requirements` must be a string or a (possibly-nested) sequence + thereof, specifying the distributions and versions required. The + return value is a sequence of the distributions that needed to be + activated to fulfill the requirements; all relevant distributions are + included, even if they were already activated in this working set. + """ + needed = self.resolve(parse_requirements(requirements)) + + for dist in needed: + self.add(dist) + + return needed + + def subscribe(self, callback, existing=True): + """Invoke `callback` for all distributions + + If `existing=True` (default), + call on all existing ones, as well. + """ + if callback in self.callbacks: + return + self.callbacks.append(callback) + if not existing: + return + for dist in self: + callback(dist) + + def _added_new(self, dist): + for callback in self.callbacks: + callback(dist) + + def __getstate__(self): + return ( + self.entries[:], self.entry_keys.copy(), self.by_key.copy(), + self.callbacks[:] + ) + + def __setstate__(self, e_k_b_c): + entries, keys, by_key, callbacks = e_k_b_c + self.entries = entries[:] + self.entry_keys = keys.copy() + self.by_key = by_key.copy() + self.callbacks = callbacks[:] + + +class _ReqExtras(dict): + """ + Map each requirement to the extras that demanded it. + """ + + def markers_pass(self, req, extras=None): + """ + Evaluate markers for req against each extra that + demanded it. + + Return False if the req has a marker and fails + evaluation. Otherwise, return True. + """ + extra_evals = ( + req.marker.evaluate({'extra': extra}) + for extra in self.get(req, ()) + (extras or (None,)) + ) + return not req.marker or any(extra_evals) + + +class Environment: + """Searchable snapshot of distributions on a search path""" + + def __init__( + self, search_path=None, platform=get_supported_platform(), + python=PY_MAJOR): + """Snapshot distributions available on a search path + + Any distributions found on `search_path` are added to the environment. + `search_path` should be a sequence of ``sys.path`` items. If not + supplied, ``sys.path`` is used. + + `platform` is an optional string specifying the name of the platform + that platform-specific distributions must be compatible with. If + unspecified, it defaults to the current platform. `python` is an + optional string naming the desired version of Python (e.g. ``'3.6'``); + it defaults to the current version. + + You may explicitly set `platform` (and/or `python`) to ``None`` if you + wish to map *all* distributions, not just those compatible with the + running platform or Python version. + """ + self._distmap = {} + self.platform = platform + self.python = python + self.scan(search_path) + + def can_add(self, dist): + """Is distribution `dist` acceptable for this environment? + + The distribution must match the platform and python version + requirements specified when this environment was created, or False + is returned. + """ + py_compat = ( + self.python is None + or dist.py_version is None + or dist.py_version == self.python + ) + return py_compat and compatible_platforms(dist.platform, self.platform) + + def remove(self, dist): + """Remove `dist` from the environment""" + self._distmap[dist.key].remove(dist) + + def scan(self, search_path=None): + """Scan `search_path` for distributions usable in this environment + + Any distributions found are added to the environment. + `search_path` should be a sequence of ``sys.path`` items. If not + supplied, ``sys.path`` is used. Only distributions conforming to + the platform/python version defined at initialization are added. + """ + if search_path is None: + search_path = sys.path + + for item in search_path: + for dist in find_distributions(item): + self.add(dist) + + def __getitem__(self, project_name): + """Return a newest-to-oldest list of distributions for `project_name` + + Uses case-insensitive `project_name` comparison, assuming all the + project's distributions use their project's name converted to all + lowercase as their key. + + """ + distribution_key = project_name.lower() + return self._distmap.get(distribution_key, []) + + def add(self, dist): + """Add `dist` if we ``can_add()`` it and it has not already been added + """ + if self.can_add(dist) and dist.has_version(): + dists = self._distmap.setdefault(dist.key, []) + if dist not in dists: + dists.append(dist) + dists.sort(key=operator.attrgetter('hashcmp'), reverse=True) + + def best_match( + self, req, working_set, installer=None, replace_conflicting=False): + """Find distribution best matching `req` and usable on `working_set` + + This calls the ``find(req)`` method of the `working_set` to see if a + suitable distribution is already active. (This may raise + ``VersionConflict`` if an unsuitable version of the project is already + active in the specified `working_set`.) If a suitable distribution + isn't active, this method returns the newest distribution in the + environment that meets the ``Requirement`` in `req`. If no suitable + distribution is found, and `installer` is supplied, then the result of + calling the environment's ``obtain(req, installer)`` method will be + returned. + """ + try: + dist = working_set.find(req) + except VersionConflict: + if not replace_conflicting: + raise + dist = None + if dist is not None: + return dist + for dist in self[req.key]: + if dist in req: + return dist + # try to download/install + return self.obtain(req, installer) + + def obtain(self, requirement, installer=None): + """Obtain a distribution matching `requirement` (e.g. via download) + + Obtain a distro that matches requirement (e.g. via download). In the + base ``Environment`` class, this routine just returns + ``installer(requirement)``, unless `installer` is None, in which case + None is returned instead. This method is a hook that allows subclasses + to attempt other ways of obtaining a distribution before falling back + to the `installer` argument.""" + if installer is not None: + return installer(requirement) + + def __iter__(self): + """Yield the unique project names of the available distributions""" + for key in self._distmap.keys(): + if self[key]: + yield key + + def __iadd__(self, other): + """In-place addition of a distribution or environment""" + if isinstance(other, Distribution): + self.add(other) + elif isinstance(other, Environment): + for project in other: + for dist in other[project]: + self.add(dist) + else: + raise TypeError("Can't add %r to environment" % (other,)) + return self + + def __add__(self, other): + """Add an environment or distribution to an environment""" + new = self.__class__([], platform=None, python=None) + for env in self, other: + new += env + return new + + +# XXX backward compatibility +AvailableDistributions = Environment + + +class ExtractionError(RuntimeError): + """An error occurred extracting a resource + + The following attributes are available from instances of this exception: + + manager + The resource manager that raised this exception + + cache_path + The base directory for resource extraction + + original_error + The exception instance that caused extraction to fail + """ + + +class ResourceManager: + """Manage resource extraction and packages""" + extraction_path = None + + def __init__(self): + self.cached_files = {} + + def resource_exists(self, package_or_requirement, resource_name): + """Does the named resource exist?""" + return get_provider(package_or_requirement).has_resource(resource_name) + + def resource_isdir(self, package_or_requirement, resource_name): + """Is the named resource an existing directory?""" + return get_provider(package_or_requirement).resource_isdir( + resource_name + ) + + def resource_filename(self, package_or_requirement, resource_name): + """Return a true filesystem path for specified resource""" + return get_provider(package_or_requirement).get_resource_filename( + self, resource_name + ) + + def resource_stream(self, package_or_requirement, resource_name): + """Return a readable file-like object for specified resource""" + return get_provider(package_or_requirement).get_resource_stream( + self, resource_name + ) + + def resource_string(self, package_or_requirement, resource_name): + """Return specified resource as a string""" + return get_provider(package_or_requirement).get_resource_string( + self, resource_name + ) + + def resource_listdir(self, package_or_requirement, resource_name): + """List the contents of the named resource directory""" + return get_provider(package_or_requirement).resource_listdir( + resource_name + ) + + def extraction_error(self): + """Give an error message for problems extracting file(s)""" + + old_exc = sys.exc_info()[1] + cache_path = self.extraction_path or get_default_cache() + + tmpl = textwrap.dedent(""" + Can't extract file(s) to egg cache + + The following error occurred while trying to extract file(s) + to the Python egg cache: + + {old_exc} + + The Python egg cache directory is currently set to: + + {cache_path} + + Perhaps your account does not have write access to this directory? + You can change the cache directory by setting the PYTHON_EGG_CACHE + environment variable to point to an accessible directory. + """).lstrip() + err = ExtractionError(tmpl.format(**locals())) + err.manager = self + err.cache_path = cache_path + err.original_error = old_exc + raise err + + def get_cache_path(self, archive_name, names=()): + """Return absolute location in cache for `archive_name` and `names` + + The parent directory of the resulting path will be created if it does + not already exist. `archive_name` should be the base filename of the + enclosing egg (which may not be the name of the enclosing zipfile!), + including its ".egg" extension. `names`, if provided, should be a + sequence of path name parts "under" the egg's extraction location. + + This method should only be called by resource providers that need to + obtain an extraction location, and only for names they intend to + extract, as it tracks the generated names for possible cleanup later. + """ + extract_path = self.extraction_path or get_default_cache() + target_path = os.path.join(extract_path, archive_name + '-tmp', *names) + try: + _bypass_ensure_directory(target_path) + except Exception: + self.extraction_error() + + self._warn_unsafe_extraction_path(extract_path) + + self.cached_files[target_path] = 1 + return target_path + + @staticmethod + def _warn_unsafe_extraction_path(path): + """ + If the default extraction path is overridden and set to an insecure + location, such as /tmp, it opens up an opportunity for an attacker to + replace an extracted file with an unauthorized payload. Warn the user + if a known insecure location is used. + + See Distribute #375 for more details. + """ + if os.name == 'nt' and not path.startswith(os.environ['windir']): + # On Windows, permissions are generally restrictive by default + # and temp directories are not writable by other users, so + # bypass the warning. + return + 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 " + "location (set with .set_extraction_path or the " + "PYTHON_EGG_CACHE environment variable)." % path + ) + warnings.warn(msg, UserWarning) + + def postprocess(self, tempname, filename): + """Perform any platform-specific postprocessing of `tempname` + + This is where Mac header rewrites should be done; other platforms don't + have anything special they should do. + + Resource providers should call this method ONLY after successfully + extracting a compressed resource. They must NOT call it on resources + that are already in the filesystem. + + `tempname` is the current (temporary) name of the file, and `filename` + is the name it will be renamed to by the caller after this routine + returns. + """ + + if os.name == 'posix': + # Make the resource executable + mode = ((os.stat(tempname).st_mode) | 0o555) & 0o7777 + os.chmod(tempname, mode) + + def set_extraction_path(self, path): + """Set the base path where resources will be extracted to, if needed. + + If you do not call this routine before any extractions take place, the + path defaults to the return value of ``get_default_cache()``. (Which + is based on the ``PYTHON_EGG_CACHE`` environment variable, with various + platform-specific fallbacks. See that routine's documentation for more + details.) + + Resources are extracted to subdirectories of this path based upon + information given by the ``IResourceProvider``. You may set this to a + temporary directory, but then you must call ``cleanup_resources()`` to + delete the extracted files when done. There is no guarantee that + ``cleanup_resources()`` will be able to remove all extracted files. + + (Note: you may not change the extraction path for a given resource + manager once resources have been extracted, unless you first call + ``cleanup_resources()``.) + """ + if self.cached_files: + raise ValueError( + "Can't change extraction path, files already extracted" + ) + + self.extraction_path = path + + def cleanup_resources(self, force=False): + """ + Delete all extracted resource files and directories, returning a list + of the file and directory names that could not be successfully removed. + This function does not have any concurrency protection, so it should + generally only be called when the extraction path is a temporary + directory exclusive to a single process. This method is not + automatically called; you must call it explicitly or register it as an + ``atexit`` function if you wish to ensure cleanup of a temporary + directory used for extractions. + """ + # XXX + + +def get_default_cache(): + """ + Return the ``PYTHON_EGG_CACHE`` environment variable + or a platform-relevant user cache dir for an app + named "Python-Eggs". + """ + return ( + os.environ.get('PYTHON_EGG_CACHE') + or appdirs.user_cache_dir(appname='Python-Eggs') + ) + + +def safe_name(name): + """Convert an arbitrary string to a standard distribution name + + Any runs of non-alphanumeric/. characters are replaced with a single '-'. + """ + return re.sub('[^A-Za-z0-9.]+', '-', name) + + +def safe_version(version): + """ + Convert an arbitrary string to a standard version string + """ + try: + # normalize the version + return str(packaging.version.Version(version)) + except packaging.version.InvalidVersion: + version = version.replace(' ', '.') + return re.sub('[^A-Za-z0-9.]+', '-', version) + + +def safe_extra(extra): + """Convert an arbitrary string to a standard 'extra' name + + Any runs of non-alphanumeric characters are replaced with a single '_', + and the result is always lowercased. + """ + return re.sub('[^A-Za-z0-9.-]+', '_', extra).lower() + + +def to_filename(name): + """Convert a project or version name to its filename-escaped form + + Any '-' characters are currently replaced with '_'. + """ + return name.replace('-', '_') + + +def invalid_marker(text): + """ + Validate text as a PEP 508 environment marker; return an exception + if invalid or False otherwise. + """ + try: + evaluate_marker(text) + except SyntaxError as e: + e.filename = None + e.lineno = None + return e + return False + + +def evaluate_marker(text, extra=None): + """ + Evaluate a PEP 508 environment marker. + Return a boolean indicating the marker result in this environment. + Raise SyntaxError if marker is invalid. + + This implementation uses the 'pyparsing' module. + """ + try: + marker = packaging.markers.Marker(text) + return marker.evaluate() + except packaging.markers.InvalidMarker as e: + raise SyntaxError(e) + + +class NullProvider: + """Try to implement resources and metadata for arbitrary PEP 302 loaders""" + + egg_name = None + egg_info = None + loader = None + + def __init__(self, module): + self.loader = getattr(module, '__loader__', None) + self.module_path = os.path.dirname(getattr(module, '__file__', '')) + + def get_resource_filename(self, manager, resource_name): + return self._fn(self.module_path, resource_name) + + def get_resource_stream(self, manager, resource_name): + return io.BytesIO(self.get_resource_string(manager, resource_name)) + + def get_resource_string(self, manager, resource_name): + return self._get(self._fn(self.module_path, resource_name)) + + def has_resource(self, resource_name): + return self._has(self._fn(self.module_path, resource_name)) + + def has_metadata(self, name): + return self.egg_info and self._has(self._fn(self.egg_info, name)) + + 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 + + def get_metadata_lines(self, name): + return yield_lines(self.get_metadata(name)) + + def resource_isdir(self, resource_name): + return self._isdir(self._fn(self.module_path, resource_name)) + + def metadata_isdir(self, name): + return self.egg_info and self._isdir(self._fn(self.egg_info, name)) + + def resource_listdir(self, resource_name): + return self._listdir(self._fn(self.module_path, resource_name)) + + def metadata_listdir(self, name): + if self.egg_info: + return self._listdir(self._fn(self.egg_info, name)) + return [] + + def run_script(self, script_name, namespace): + script = 'scripts/' + script_name + if not self.has_metadata(script): + raise ResolutionError( + "Script {script!r} not found in metadata at {self.egg_info!r}" + .format(**locals()), + ) + script_text = self.get_metadata(script).replace('\r\n', '\n') + script_text = script_text.replace('\r', '\n') + script_filename = self._fn(self.egg_info, script) + namespace['__file__'] = script_filename + if os.path.exists(script_filename): + source = open(script_filename).read() + code = compile(source, script_filename, 'exec') + exec(code, namespace, namespace) + else: + from linecache import cache + cache[script_filename] = ( + len(script_text), 0, script_text.split('\n'), script_filename + ) + script_code = compile(script_text, script_filename, 'exec') + exec(script_code, namespace, namespace) + + def _has(self, path): + raise NotImplementedError( + "Can't perform this operation for unregistered loader type" + ) + + def _isdir(self, path): + raise NotImplementedError( + "Can't perform this operation for unregistered loader type" + ) + + def _listdir(self, path): + raise NotImplementedError( + "Can't perform this operation for unregistered loader type" + ) + + def _fn(self, base, resource_name): + if resource_name: + return os.path.join(base, *resource_name.split('/')) + return base + + def _get(self, path): + if hasattr(self.loader, 'get_data'): + return self.loader.get_data(path) + raise NotImplementedError( + "Can't perform this operation for loaders without 'get_data()'" + ) + + +register_loader_type(object, NullProvider) + + +class EggProvider(NullProvider): + """Provider based on a virtual filesystem""" + + def __init__(self, module): + NullProvider.__init__(self, module) + 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) + + +class DefaultProvider(EggProvider): + """Provides access to package resources in the filesystem""" + + def _has(self, path): + return os.path.exists(path) + + def _isdir(self, path): + return os.path.isdir(path) + + def _listdir(self, path): + return os.listdir(path) + + def get_resource_stream(self, manager, resource_name): + return open(self._fn(self.module_path, resource_name), 'rb') + + def _get(self, path): + with open(path, 'rb') as stream: + return stream.read() + + @classmethod + def _register(cls): + loader_names = 'SourceFileLoader', 'SourcelessFileLoader', + for name in loader_names: + loader_cls = getattr(importlib_machinery, name, type(None)) + register_loader_type(loader_cls, cls) + + +DefaultProvider._register() + + +class EmptyProvider(NullProvider): + """Provider that returns nothing for all requests""" + + module_path = None + + _isdir = _has = lambda self, path: False + + def _get(self, path): + return '' + + def _listdir(self, path): + return [] + + def __init__(self): + pass + + +empty_provider = EmptyProvider() + + +class ZipManifests(dict): + """ + zip manifest builder + """ + + @classmethod + def build(cls, path): + """ + Build a dictionary similar to the zipimport directory + caches, except instead of tuples, store ZipInfo objects. + + Use a platform-specific path separator (os.sep) for the path keys + for compatibility with pypy on Windows. + """ + with zipfile.ZipFile(path) as zfile: + items = ( + ( + name.replace('/', os.sep), + zfile.getinfo(name), + ) + for name in zfile.namelist() + ) + return dict(items) + + load = build + + +class MemoizedZipManifests(ZipManifests): + """ + Memoized zipfile manifests. + """ + manifest_mod = collections.namedtuple('manifest_mod', 'manifest mtime') + + def load(self, path): + """ + Load a manifest at path or return a suitable manifest already loaded. + """ + path = os.path.normpath(path) + mtime = os.stat(path).st_mtime + + if path not in self or self[path].mtime != mtime: + manifest = self.build(path) + self[path] = self.manifest_mod(manifest, mtime) + + return self[path].manifest + + +class ZipProvider(EggProvider): + """Resource support for zips and eggs""" + + eagers = None + _zip_manifests = MemoizedZipManifests() + + def __init__(self, module): + EggProvider.__init__(self, module) + self.zip_pre = self.loader.archive + os.sep + + def _zipinfo_name(self, fspath): + # Convert a virtual filename (full path to file) into a zipfile subpath + # usable with the zipimport directory cache for our target archive + fspath = fspath.rstrip(os.sep) + if fspath == self.loader.archive: + return '' + if fspath.startswith(self.zip_pre): + return fspath[len(self.zip_pre):] + raise AssertionError( + "%s is not a subpath of %s" % (fspath, self.zip_pre) + ) + + def _parts(self, zip_path): + # Convert a zipfile subpath into an egg-relative path part list. + # pseudo-fs path + fspath = self.zip_pre + zip_path + if fspath.startswith(self.egg_root + os.sep): + return fspath[len(self.egg_root) + 1:].split(os.sep) + raise AssertionError( + "%s is not a subpath of %s" % (fspath, self.egg_root) + ) + + @property + def zipinfo(self): + return self._zip_manifests.load(self.loader.archive) + + def get_resource_filename(self, manager, resource_name): + if not self.egg_name: + raise NotImplementedError( + "resource_filename() only supported for .egg, not .zip" + ) + # no need to lock for extraction, since we use temp names + zip_path = self._resource_to_zip(resource_name) + eagers = self._get_eager_resources() + if '/'.join(self._parts(zip_path)) in eagers: + for name in eagers: + self._extract_resource(manager, self._eager_to_zip(name)) + return self._extract_resource(manager, zip_path) + + @staticmethod + def _get_date_and_size(zip_stat): + size = zip_stat.file_size + # ymdhms+wday, yday, dst + date_time = zip_stat.date_time + (0, 0, -1) + # 1980 offset already done + timestamp = time.mktime(date_time) + return timestamp, size + + def _extract_resource(self, manager, zip_path): + + if zip_path in self._index(): + for name in self._index()[zip_path]: + last = self._extract_resource( + manager, os.path.join(zip_path, name) + ) + # return the extracted directory name + return os.path.dirname(last) + + timestamp, size = self._get_date_and_size(self.zipinfo[zip_path]) + + if not WRITE_SUPPORT: + raise IOError('"os.rename" and "os.unlink" are not supported ' + 'on this platform') + try: + + real_path = manager.get_cache_path( + self.egg_name, self._parts(zip_path) + ) + + if self._is_current(real_path, zip_path): + return real_path + + outf, tmpnam = _mkstemp( + ".$extract", + dir=os.path.dirname(real_path), + ) + os.write(outf, self.loader.get_data(zip_path)) + os.close(outf) + utime(tmpnam, (timestamp, timestamp)) + manager.postprocess(tmpnam, real_path) + + try: + rename(tmpnam, real_path) + + except os.error: + if os.path.isfile(real_path): + if self._is_current(real_path, zip_path): + # the file became current since it was checked above, + # so proceed. + return real_path + # Windows, del old file and retry + elif os.name == 'nt': + unlink(real_path) + rename(tmpnam, real_path) + return real_path + raise + + except os.error: + # report a user-friendly error + manager.extraction_error() + + return real_path + + def _is_current(self, file_path, zip_path): + """ + Return True if the file_path is current for this zip_path + """ + timestamp, size = self._get_date_and_size(self.zipinfo[zip_path]) + if not os.path.isfile(file_path): + return False + stat = os.stat(file_path) + if stat.st_size != size or stat.st_mtime != timestamp: + return False + # check that the contents match + zip_contents = self.loader.get_data(zip_path) + with open(file_path, 'rb') as f: + file_contents = f.read() + return zip_contents == file_contents + + def _get_eager_resources(self): + if self.eagers is None: + eagers = [] + for name in ('native_libs.txt', 'eager_resources.txt'): + if self.has_metadata(name): + eagers.extend(self.get_metadata_lines(name)) + self.eagers = eagers + return self.eagers + + def _index(self): + try: + return self._dirindex + except AttributeError: + ind = {} + for path in self.zipinfo: + parts = path.split(os.sep) + while parts: + parent = os.sep.join(parts[:-1]) + if parent in ind: + ind[parent].append(parts[-1]) + break + else: + ind[parent] = [parts.pop()] + self._dirindex = ind + return ind + + def _has(self, fspath): + zip_path = self._zipinfo_name(fspath) + return zip_path in self.zipinfo or zip_path in self._index() + + def _isdir(self, fspath): + return self._zipinfo_name(fspath) in self._index() + + def _listdir(self, fspath): + return list(self._index().get(self._zipinfo_name(fspath), ())) + + def _eager_to_zip(self, resource_name): + return self._zipinfo_name(self._fn(self.egg_root, resource_name)) + + def _resource_to_zip(self, resource_name): + return self._zipinfo_name(self._fn(self.module_path, resource_name)) + + +register_loader_type(zipimport.zipimporter, ZipProvider) + + +class FileMetadata(EmptyProvider): + """Metadata handler for standalone PKG-INFO files + + Usage:: + + metadata = FileMetadata("/path/to/PKG-INFO") + + This provider rejects all data and metadata requests except for PKG-INFO, + which is treated as existing, and will be the contents of the file at + the provided location. + """ + + def __init__(self, path): + self.path = path + + def has_metadata(self, name): + return name == 'PKG-INFO' and os.path.isfile(self.path) + + def get_metadata(self, name): + if name != 'PKG-INFO': + raise KeyError("No metadata except PKG-INFO is available") + + with io.open(self.path, encoding='utf-8', errors="replace") as f: + metadata = f.read() + self._warn_on_replacement(metadata) + return metadata + + def _warn_on_replacement(self, metadata): + # Python 2.7 compat for: replacement_char = '�' + replacement_char = b'\xef\xbf\xbd'.decode('utf-8') + if replacement_char in metadata: + tmpl = "{self.path} could not be properly decoded in UTF-8" + msg = tmpl.format(**locals()) + warnings.warn(msg) + + def get_metadata_lines(self, name): + return yield_lines(self.get_metadata(name)) + + +class PathMetadata(DefaultProvider): + """Metadata provider for egg directories + + Usage:: + + # Development eggs: + + egg_info = "/path/to/PackageName.egg-info" + base_dir = os.path.dirname(egg_info) + metadata = PathMetadata(base_dir, egg_info) + dist_name = os.path.splitext(os.path.basename(egg_info))[0] + dist = Distribution(basedir, project_name=dist_name, metadata=metadata) + + # Unpacked egg directories: + + egg_path = "/path/to/PackageName-ver-pyver-etc.egg" + metadata = PathMetadata(egg_path, os.path.join(egg_path,'EGG-INFO')) + dist = Distribution.from_filename(egg_path, metadata=metadata) + """ + + def __init__(self, path, egg_info): + self.module_path = path + self.egg_info = egg_info + + +class EggMetadata(ZipProvider): + """Metadata provider for .egg files""" + + def __init__(self, importer): + """Create a metadata provider from a zipimporter""" + + self.zip_pre = importer.archive + os.sep + self.loader = importer + if importer.prefix: + self.module_path = os.path.join(importer.archive, importer.prefix) + else: + self.module_path = importer.archive + self._setup_prefix() + + +_declare_state('dict', _distribution_finders={}) + + +def register_finder(importer_type, distribution_finder): + """Register `distribution_finder` to find distributions in sys.path items + + `importer_type` is the type or class of a PEP 302 "Importer" (sys.path item + handler), and `distribution_finder` is a callable that, passed a path + item and the importer instance, yields ``Distribution`` instances found on + that path item. See ``pkg_resources.find_on_path`` for an example.""" + _distribution_finders[importer_type] = distribution_finder + + +def find_distributions(path_item, only=False): + """Yield distributions accessible via `path_item`""" + importer = get_importer(path_item) + finder = _find_adapter(_distribution_finders, importer) + return finder(importer, path_item, only) + + +def find_eggs_in_zip(importer, path_item, only=False): + """ + Find eggs in zip files; possibly multiple nested eggs. + """ + if importer.archive.endswith('.whl'): + # wheels are not supported with this finder + # they don't have PKG-INFO metadata, and won't ever contain eggs + return + metadata = EggMetadata(importer) + if metadata.has_metadata('PKG-INFO'): + yield Distribution.from_filename(path_item, metadata=metadata) + if only: + # don't yield nested distros + return + for subitem in metadata.resource_listdir('/'): + if _is_egg_path(subitem): + subpath = os.path.join(path_item, subitem) + dists = find_eggs_in_zip(zipimport.zipimporter(subpath), subpath) + for dist in dists: + yield dist + elif subitem.lower().endswith('.dist-info'): + subpath = os.path.join(path_item, subitem) + submeta = EggMetadata(zipimport.zipimporter(subpath)) + submeta.egg_info = subpath + yield Distribution.from_location(path_item, subitem, submeta) + + +register_finder(zipimport.zipimporter, find_eggs_in_zip) + + +def find_nothing(importer, path_item, only=False): + return () + + +register_finder(object, find_nothing) + + +def _by_version_descending(names): + """ + Given a list of filenames, return them in descending order + by version number. + + >>> names = 'bar', 'foo', 'Python-2.7.10.egg', 'Python-2.7.2.egg' + >>> _by_version_descending(names) + ['Python-2.7.10.egg', 'Python-2.7.2.egg', 'foo', 'bar'] + >>> names = 'Setuptools-1.2.3b1.egg', 'Setuptools-1.2.3.egg' + >>> _by_version_descending(names) + ['Setuptools-1.2.3.egg', 'Setuptools-1.2.3b1.egg'] + >>> names = 'Setuptools-1.2.3b1.egg', 'Setuptools-1.2.3.post1.egg' + >>> _by_version_descending(names) + ['Setuptools-1.2.3.post1.egg', 'Setuptools-1.2.3b1.egg'] + """ + def _by_version(name): + """ + Parse each component of the filename + """ + name, ext = os.path.splitext(name) + parts = itertools.chain(name.split('-'), [ext]) + return [packaging.version.parse(part) for part in parts] + + return sorted(names, key=_by_version, reverse=True) + + +def find_on_path(importer, path_item, only=False): + """Yield distributions accessible on a sys.path directory""" + path_item = _normalize_cached(path_item) + + if _is_unpacked_egg(path_item): + yield Distribution.from_filename( + path_item, metadata=PathMetadata( + path_item, os.path.join(path_item, 'EGG-INFO') + ) + ) + return + + entries = safe_listdir(path_item) + + # for performance, before sorting by version, + # screen entries for only those that will yield + # distributions + filtered = ( + entry + for entry in entries + if dist_factory(path_item, entry, only) + ) + + # scan for .egg and .egg-info in directory + path_item_entries = _by_version_descending(filtered) + for entry in path_item_entries: + fullpath = os.path.join(path_item, entry) + factory = dist_factory(path_item, entry, only) + for dist in factory(fullpath): + yield dist + + +def dist_factory(path_item, entry, only): + """ + Return a dist_factory for a path_item and entry + """ + lower = entry.lower() + is_meta = any(map(lower.endswith, ('.egg-info', '.dist-info'))) + return ( + distributions_from_metadata + if is_meta else + find_distributions + if not only and _is_egg_path(entry) else + resolve_egg_link + if not only and lower.endswith('.egg-link') else + NoDists() + ) + + +class NoDists: + """ + >>> bool(NoDists()) + False + + >>> list(NoDists()('anything')) + [] + """ + def __bool__(self): + return False + if six.PY2: + __nonzero__ = __bool__ + + def __call__(self, fullpath): + return iter(()) + + +def safe_listdir(path): + """ + Attempt to list contents of path, but suppress some exceptions. + """ + try: + return os.listdir(path) + except (PermissionError, NotADirectoryError): + pass + except OSError as e: + # Ignore the directory if does not exist, not a directory or + # permission denied + ignorable = ( + e.errno in (errno.ENOTDIR, errno.EACCES, errno.ENOENT) + # Python 2 on Windows needs to be handled this way :( + or getattr(e, "winerror", None) == 267 + ) + if not ignorable: + raise + return () + + +def distributions_from_metadata(path): + root = os.path.dirname(path) + if os.path.isdir(path): + if len(os.listdir(path)) == 0: + # empty metadata dir; skip + return + metadata = PathMetadata(root, path) + else: + metadata = FileMetadata(path) + entry = os.path.basename(path) + yield Distribution.from_location( + root, entry, metadata, precedence=DEVELOP_DIST, + ) + + +def non_empty_lines(path): + """ + Yield non-empty lines from file at path + """ + with open(path) as f: + for line in f: + line = line.strip() + if line: + yield line + + +def resolve_egg_link(path): + """ + Given a path to an .egg-link, resolve distributions + present in the referenced path. + """ + referenced_paths = non_empty_lines(path) + resolved_paths = ( + os.path.join(os.path.dirname(path), ref) + for ref in referenced_paths + ) + dist_groups = map(find_distributions, resolved_paths) + return next(dist_groups, ()) + + +register_finder(pkgutil.ImpImporter, find_on_path) + +if hasattr(importlib_machinery, 'FileFinder'): + register_finder(importlib_machinery.FileFinder, find_on_path) + +_declare_state('dict', _namespace_handlers={}) +_declare_state('dict', _namespace_packages={}) + + +def register_namespace_handler(importer_type, namespace_handler): + """Register `namespace_handler` to declare namespace packages + + `importer_type` is the type or class of a PEP 302 "Importer" (sys.path item + handler), and `namespace_handler` is a callable like this:: + + def namespace_handler(importer, path_entry, moduleName, module): + # return a path_entry to use for child packages + + Namespace handlers are only called if the importer object has already + agreed that it can handle the relevant path item, and they should only + return a subpath if the module __path__ does not already contain an + equivalent subpath. For an example namespace handler, see + ``pkg_resources.file_ns_handler``. + """ + _namespace_handlers[importer_type] = namespace_handler + + +def _handle_ns(packageName, path_item): + """Ensure that named package includes a subpath of path_item (if needed)""" + + importer = get_importer(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) + + if loader is None: + return None + module = sys.modules.get(packageName) + if module is None: + module = sys.modules[packageName] = types.ModuleType(packageName) + module.__path__ = [] + _set_parent_ns(packageName) + elif not hasattr(module, '__path__'): + raise TypeError("Not a package:", packageName) + handler = _find_adapter(_namespace_handlers, importer) + subpath = handler(importer, path_item, packageName, module) + if subpath is not None: + path = module.__path__ + path.append(subpath) + loader.load_module(packageName) + _rebuild_mod_path(path, packageName, module) + return subpath + + +def _rebuild_mod_path(orig_path, package_name, module): + """ + Rebuild module.__path__ ensuring that all entries are ordered + corresponding to their sys.path order + """ + sys_path = [_normalize_cached(p) for p in sys.path] + + def safe_sys_path_index(entry): + """ + Workaround for #520 and #513. + """ + try: + return sys_path.index(entry) + except ValueError: + return float('inf') + + def position_in_sys_path(path): + """ + Return the ordinal of the path based on its position in sys.path + """ + path_parts = path.split(os.sep) + module_parts = package_name.count('.') + 1 + parts = path_parts[:-module_parts] + return safe_sys_path_index(_normalize_cached(os.sep.join(parts))) + + new_path = sorted(orig_path, key=position_in_sys_path) + new_path = [_normalize_cached(p) for p in new_path] + + if isinstance(module.__path__, list): + module.__path__[:] = new_path + else: + module.__path__ = new_path + + +def declare_namespace(packageName): + """Declare that package 'packageName' is a namespace package""" + + _imp.acquire_lock() + try: + if packageName in _namespace_packages: + return + + path = sys.path + parent, _, _ = packageName.rpartition('.') + + if parent: + declare_namespace(parent) + if parent not in _namespace_packages: + __import__(parent) + try: + path = sys.modules[parent].__path__ + except AttributeError: + raise TypeError("Not a package:", parent) + + # Track what packages are namespaces, so when new path items are added, + # they can be updated + _namespace_packages.setdefault(parent or None, []).append(packageName) + _namespace_packages.setdefault(packageName, []) + + for path_item in path: + # Ensure all the parent's path items are reflected in the child, + # if they apply + _handle_ns(packageName, path_item) + + finally: + _imp.release_lock() + + +def fixup_namespace_packages(path_item, parent=None): + """Ensure that previously-declared namespace packages include path_item""" + _imp.acquire_lock() + try: + for package in _namespace_packages.get(parent, ()): + subpath = _handle_ns(package, path_item) + if subpath: + fixup_namespace_packages(subpath, package) + finally: + _imp.release_lock() + + +def file_ns_handler(importer, path_item, packageName, module): + """Compute an ns-package subpath for a filesystem or zipfile importer""" + + subpath = os.path.join(path_item, packageName.split('.')[-1]) + normalized = _normalize_cached(subpath) + for item in module.__path__: + if _normalize_cached(item) == normalized: + break + else: + # Only return the path if it's not already there + return subpath + + +register_namespace_handler(pkgutil.ImpImporter, file_ns_handler) +register_namespace_handler(zipimport.zipimporter, file_ns_handler) + +if hasattr(importlib_machinery, 'FileFinder'): + register_namespace_handler(importlib_machinery.FileFinder, file_ns_handler) + + +def null_ns_handler(importer, path_item, packageName, module): + return None + + +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(filename)) + + +def _normalize_cached(filename, _cache={}): + try: + return _cache[filename] + except KeyError: + _cache[filename] = result = normalize_path(filename) + return result + + +def _is_egg_path(path): + """ + Determine if given path appears to be an egg. + """ + return path.lower().endswith('.egg') + + +def _is_unpacked_egg(path): + """ + Determine if given path appears to be an unpacked egg. + """ + return ( + _is_egg_path(path) and + os.path.isfile(os.path.join(path, 'EGG-INFO', 'PKG-INFO')) + ) + + +def _set_parent_ns(packageName): + parts = packageName.split('.') + name = parts.pop() + if parts: + parent = '.'.join(parts) + setattr(sys.modules[parent], name, sys.modules[packageName]) + + +def yield_lines(strs): + """Yield non-empty/non-comment lines of a string or sequence""" + if isinstance(strs, six.string_types): + for s in strs.splitlines(): + s = s.strip() + # skip blank lines/comments + if s and not s.startswith('#'): + yield s + else: + for ss in strs: + for s in yield_lines(ss): + yield s + + +MODULE = re.compile(r"\w+(\.\w+)*$").match +EGG_NAME = re.compile( + r""" + (?P<name>[^-]+) ( + -(?P<ver>[^-]+) ( + -py(?P<pyver>[^-]+) ( + -(?P<plat>.+) + )? + )? + )? + """, + re.VERBOSE | re.IGNORECASE, +).match + + +class EntryPoint: + """Object representing an advertised importable object""" + + def __init__(self, name, module_name, attrs=(), extras=(), dist=None): + if not MODULE(module_name): + raise ValueError("Invalid module name", module_name) + self.name = name + self.module_name = module_name + self.attrs = tuple(attrs) + self.extras = tuple(extras) + self.dist = dist + + def __str__(self): + s = "%s = %s" % (self.name, self.module_name) + if self.attrs: + s += ':' + '.'.join(self.attrs) + if self.extras: + s += ' [%s]' % ','.join(self.extras) + return s + + def __repr__(self): + return "EntryPoint.parse(%r)" % str(self) + + def load(self, require=True, *args, **kwargs): + """ + Require packages for this EntryPoint, then resolve it. + """ + if not require or args or kwargs: + warnings.warn( + "Parameters to load are deprecated. Call .resolve and " + ".require separately.", + DeprecationWarning, + stacklevel=2, + ) + if require: + self.require(*args, **kwargs) + return self.resolve() + + def resolve(self): + """ + Resolve the entry point from its module and attrs. + """ + module = __import__(self.module_name, fromlist=['__name__'], level=0) + try: + return functools.reduce(getattr, self.attrs, module) + except AttributeError as exc: + raise ImportError(str(exc)) + + def require(self, env=None, installer=None): + if self.extras and not self.dist: + raise UnknownExtra("Can't require() without a distribution", self) + + # Get the requirements for this entry point with all its extras and + # then resolve them. We have to pass `extras` along when resolving so + # that the working set knows what extras we want. Otherwise, for + # dist-info distributions, the working set will assume that the + # requirements for that extra are purely optional and skip over them. + reqs = self.dist.requires(self.extras) + items = working_set.resolve(reqs, env, installer, extras=self.extras) + list(map(working_set.add, items)) + + pattern = re.compile( + r'\s*' + r'(?P<name>.+?)\s*' + r'=\s*' + r'(?P<module>[\w.]+)\s*' + r'(:\s*(?P<attr>[\w.]+))?\s*' + r'(?P<extras>\[.*\])?\s*$' + ) + + @classmethod + def parse(cls, src, dist=None): + """Parse a single entry point from string `src` + + Entry point syntax follows the form:: + + name = some.module:some.attr [extra1, extra2] + + The entry name and module name are required, but the ``:attrs`` and + ``[extras]`` parts are optional + """ + m = cls.pattern.match(src) + if not m: + msg = "EntryPoint must be in 'name=module:attrs [extras]' format" + raise ValueError(msg, src) + res = m.groupdict() + extras = cls._parse_extras(res['extras']) + attrs = res['attr'].split('.') if res['attr'] else () + return cls(res['name'], res['module'], attrs, extras, dist) + + @classmethod + def _parse_extras(cls, extras_spec): + if not extras_spec: + return () + req = Requirement.parse('x' + extras_spec) + if req.specs: + raise ValueError() + return req.extras + + @classmethod + def parse_group(cls, group, lines, dist=None): + """Parse an entry point group""" + if not MODULE(group): + raise ValueError("Invalid group name", group) + this = {} + for line in yield_lines(lines): + ep = cls.parse(line, dist) + if ep.name in this: + raise ValueError("Duplicate entry point", group, ep.name) + this[ep.name] = ep + return this + + @classmethod + def parse_map(cls, data, dist=None): + """Parse a map of entry point groups""" + if isinstance(data, dict): + data = data.items() + else: + data = split_sections(data) + maps = {} + for group, lines in data: + if group is None: + if not lines: + continue + raise ValueError("Entry points must be listed in groups") + group = group.strip() + if group in maps: + raise ValueError("Duplicate group name", group) + maps[group] = cls.parse_group(group, lines, dist) + 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 + the value of the Version field, if present, or None otherwise. + """ + def is_version_line(line): + return line.lower().startswith('version:') + version_lines = filter(is_version_line, lines) + line = next(iter(version_lines), '') + _, _, value = line.partition(':') + return safe_version(value.strip()) or None + + +class Distribution: + """Wrap an actual or potential sys.path entry w/metadata""" + PKG_INFO = 'PKG-INFO' + + def __init__( + self, location=None, metadata=None, project_name=None, + version=None, py_version=PY_MAJOR, platform=None, + precedence=EGG_DIST): + self.project_name = safe_name(project_name or 'Unknown') + if version is not None: + self._version = safe_version(version) + self.py_version = py_version + self.platform = platform + self.location = location + self.precedence = precedence + self._provider = metadata or empty_provider + + @classmethod + def from_location(cls, location, basename, metadata=None, **kw): + project_name, version, py_version, platform = [None] * 4 + basename, ext = os.path.splitext(basename) + if ext.lower() in _distributionImpl: + cls = _distributionImpl[ext.lower()] + + match = EGG_NAME(basename) + if match: + project_name, version, py_version, platform = match.group( + 'name', 'ver', 'pyver', 'plat' + ) + return cls( + location, metadata, project_name=project_name, version=version, + py_version=py_version, platform=platform, **kw + )._reload_version() + + def _reload_version(self): + return self + + @property + def hashcmp(self): + return ( + self.parsed_version, + self.precedence, + self.key, + _remove_md5_fragment(self.location), + self.py_version or '', + self.platform or '', + ) + + def __hash__(self): + return hash(self.hashcmp) + + def __lt__(self, other): + return self.hashcmp < other.hashcmp + + def __le__(self, other): + return self.hashcmp <= other.hashcmp + + def __gt__(self, other): + return self.hashcmp > other.hashcmp + + def __ge__(self, other): + return self.hashcmp >= other.hashcmp + + def __eq__(self, other): + if not isinstance(other, self.__class__): + # It's not a Distribution, so they are not equal + return False + return self.hashcmp == other.hashcmp + + def __ne__(self, other): + return not self == other + + # These properties have to be lazy so that we don't have to load any + # metadata until/unless it's actually needed. (i.e., some distributions + # may not know their name or version without loading PKG-INFO) + + @property + def key(self): + try: + return self._key + except AttributeError: + self._key = key = self.project_name.lower() + return key + + @property + def parsed_version(self): + if not hasattr(self, "_parsed_version"): + self._parsed_version = parse_version(self.version) + + return self._parsed_version + + def _warn_legacy_version(self): + LV = packaging.version.LegacyVersion + is_legacy = isinstance(self._parsed_version, LV) + if not is_legacy: + return + + # While an empty version is technically a legacy version and + # is not a valid PEP 440 version, it's also unlikely to + # actually come from someone and instead it is more likely that + # it comes from setuptools attempting to parse a filename and + # including it in the list. So for that we'll gate this warning + # on if the version is anything at all or not. + if not self.version: + return + + tmpl = textwrap.dedent(""" + '{project_name} ({version})' is being parsed as a legacy, + non PEP 440, + version. You may find odd behavior and sort order. + In particular it will be sorted as less than 0.0. It + is recommended to migrate to PEP 440 compatible + versions. + """).strip().replace('\n', ' ') + + warnings.warn(tmpl.format(**vars(self)), PEP440Warning) + + @property + def version(self): + try: + return self._version + except AttributeError: + version = _version_from_file(self._get_metadata(self.PKG_INFO)) + if version is None: + tmpl = "Missing 'Version:' header and/or %s file" + raise ValueError(tmpl % self.PKG_INFO, self) + return version + + @property + def _dep_map(self): + """ + A map of extra to its list of (direct) requirements + for this distribution, including the null extra. + """ + try: + return self.__dep_map + except AttributeError: + self.__dep_map = self._filter_extras(self._build_dep_map()) + return self.__dep_map + + @staticmethod + def _filter_extras(dm): + """ + Given a mapping of extras to dependencies, strip off + environment markers and filter out any dependencies + not matching the markers. + """ + for extra in list(filter(None, dm)): + new_extra = extra + reqs = dm.pop(extra) + new_extra, _, marker = extra.partition(':') + fails_marker = marker and ( + invalid_marker(marker) + or not evaluate_marker(marker) + ) + if fails_marker: + reqs = [] + new_extra = safe_extra(new_extra) or None + + dm.setdefault(new_extra, []).extend(reqs) + return dm + + def _build_dep_map(self): + dm = {} + for name in 'requires.txt', 'depends.txt': + for extra, reqs in split_sections(self._get_metadata(name)): + dm.setdefault(extra, []).extend(parse_requirements(reqs)) + return dm + + def requires(self, extras=()): + """List of Requirements needed for this distro if `extras` are used""" + dm = self._dep_map + deps = [] + deps.extend(dm.get(None, ())) + for ext in extras: + try: + deps.extend(dm[safe_extra(ext)]) + except KeyError: + raise UnknownExtra( + "%s has no such extra feature %r" % (self, ext) + ) + return deps + + def _get_metadata(self, name): + if self.has_metadata(name): + for line in self.get_metadata_lines(name): + yield line + + def activate(self, path=None, replace=False): + """Ensure distribution is importable on `path` (default=sys.path)""" + if path is None: + path = sys.path + self.insert_on(path, replace=replace) + if path is sys.path: + fixup_namespace_packages(self.location) + for pkg in self._get_metadata('namespace_packages.txt'): + if pkg in sys.modules: + declare_namespace(pkg) + + def egg_name(self): + """Return what this distribution's standard .egg filename should be""" + filename = "%s-%s-py%s" % ( + to_filename(self.project_name), to_filename(self.version), + self.py_version or PY_MAJOR + ) + + if self.platform: + filename += '-' + self.platform + return filename + + def __repr__(self): + if self.location: + return "%s (%s)" % (self, self.location) + else: + return str(self) + + def __str__(self): + try: + version = getattr(self, 'version', None) + except ValueError: + version = None + version = version or "[unknown version]" + return "%s %s" % (self.project_name, version) + + def __getattr__(self, attr): + """Delegate all unrecognized public attributes to .metadata provider""" + if attr.startswith('_'): + raise AttributeError(attr) + return getattr(self._provider, attr) + + def __dir__(self): + return list( + set(super(Distribution, self).__dir__()) + | set( + attr for attr in self._provider.__dir__() + if not attr.startswith('_') + ) + ) + + if not hasattr(object, '__dir__'): + # python 2.7 not supported + del __dir__ + + @classmethod + def from_filename(cls, filename, metadata=None, **kw): + return cls.from_location( + _normalize_cached(filename), os.path.basename(filename), metadata, + **kw + ) + + def as_requirement(self): + """Return a ``Requirement`` that matches this distribution exactly""" + if isinstance(self.parsed_version, packaging.version.Version): + spec = "%s==%s" % (self.project_name, self.parsed_version) + else: + spec = "%s===%s" % (self.project_name, self.parsed_version) + + return Requirement.parse(spec) + + def load_entry_point(self, group, name): + """Return the `name` entry point of `group` or raise ImportError""" + ep = self.get_entry_info(group, name) + if ep is None: + raise ImportError("Entry point %r not found" % ((group, name),)) + return ep.load() + + def get_entry_map(self, group=None): + """Return the entry point map for `group`, or the full entry map""" + try: + ep_map = self._ep_map + except AttributeError: + ep_map = self._ep_map = EntryPoint.parse_map( + self._get_metadata('entry_points.txt'), self + ) + if group is not None: + return ep_map.get(group, {}) + return ep_map + + def get_entry_info(self, group, name): + """Return the EntryPoint object for `group`+`name`, or ``None``""" + return self.get_entry_map(group).get(name) + + def insert_on(self, path, loc=None, replace=False): + """Ensure self.location is on path + + If replace=False (default): + - If location is already in path anywhere, do nothing. + - Else: + - If it's an egg and its parent directory is on path, + insert just ahead of the parent. + - Else: add to the end of path. + If replace=True: + - If location is already on path anywhere (not eggs) + or higher priority than its parent (eggs) + do nothing. + - Else: + - If it's an egg and its parent directory is on path, + insert just ahead of the parent, + removing any lower-priority entries. + - Else: add it to the front of path. + """ + + loc = loc or self.location + if not loc: + return + + nloc = _normalize_cached(loc) + bdir = os.path.dirname(nloc) + npath = [(p and _normalize_cached(p) or p) for p in path] + + for p, item in enumerate(npath): + if item == nloc: + if replace: + break + else: + # don't modify path (even removing duplicates) if + # found and not replace + return + elif item == bdir and self.precedence == EGG_DIST: + # if it's an .egg, give it precedence over its directory + # UNLESS it's already been added to sys.path and replace=False + if (not replace) and nloc in npath[p:]: + return + if path is sys.path: + self.check_version_conflict() + path.insert(p, loc) + npath.insert(p, nloc) + break + else: + if path is sys.path: + self.check_version_conflict() + if replace: + path.insert(0, loc) + else: + path.append(loc) + return + + # p is the spot where we found or inserted loc; now remove duplicates + while True: + try: + np = npath.index(nloc, p + 1) + except ValueError: + break + else: + del npath[np], path[np] + # ha! + p = np + + return + + def check_version_conflict(self): + if self.key == 'setuptools': + # ignore the inevitable setuptools self-conflicts :( + return + + nsp = dict.fromkeys(self._get_metadata('namespace_packages.txt')) + loc = normalize_path(self.location) + for modname in self._get_metadata('top_level.txt'): + if (modname not in sys.modules or modname in nsp + or modname in _namespace_packages): + continue + if modname in ('pkg_resources', 'setuptools', 'site'): + continue + fn = getattr(sys.modules[modname], '__file__', None) + if fn and (normalize_path(fn).startswith(loc) or + fn.startswith(self.location)): + continue + issue_warning( + "Module %s was already imported from %s, but %s is being added" + " to sys.path" % (modname, fn, self.location), + ) + + def has_version(self): + try: + self.version + except ValueError: + issue_warning("Unbuilt egg for " + repr(self)) + return False + return True + + def clone(self, **kw): + """Copy this distribution, substituting in any changed keyword args""" + names = 'project_name version py_version platform location precedence' + for attr in names.split(): + kw.setdefault(attr, getattr(self, attr, None)) + kw.setdefault('metadata', self._provider) + return self.__class__(**kw) + + @property + def extras(self): + return [dep for dep in self._dep_map if dep] + + +class EggInfoDistribution(Distribution): + def _reload_version(self): + """ + Packages installed by distutils (e.g. numpy or scipy), + which uses an old safe_version, and so + their version numbers can get mangled when + converted to filenames (e.g., 1.11.0.dev0+2329eae to + 1.11.0.dev0_2329eae). These distributions will not be + parsed properly + downstream by Distribution and safe_version, so + take an extra step and try to get the version number from + the metadata file itself instead of the filename. + """ + md_version = _version_from_file(self._get_metadata(self.PKG_INFO)) + if md_version: + self._version = md_version + return self + + +class DistInfoDistribution(Distribution): + """ + Wrap an actual or potential sys.path entry + w/metadata, .dist-info style. + """ + PKG_INFO = 'METADATA' + EQEQ = re.compile(r"([\(,])\s*(\d.*?)\s*([,\)])") + + @property + def _parsed_pkg_info(self): + """Parse and cache metadata""" + try: + return self._pkg_info + except AttributeError: + metadata = self.get_metadata(self.PKG_INFO) + self._pkg_info = email.parser.Parser().parsestr(metadata) + return self._pkg_info + + @property + def _dep_map(self): + try: + return self.__dep_map + except AttributeError: + self.__dep_map = self._compute_dependencies() + return self.__dep_map + + def _compute_dependencies(self): + """Recompute this distribution's dependencies.""" + dm = self.__dep_map = {None: []} + + reqs = [] + # Including any condition expressions + for req in self._parsed_pkg_info.get_all('Requires-Dist') or []: + reqs.extend(parse_requirements(req)) + + def reqs_for_extra(extra): + for req in reqs: + if not req.marker or req.marker.evaluate({'extra': extra}): + yield req + + common = frozenset(reqs_for_extra(None)) + dm[None].extend(common) + + for extra in self._parsed_pkg_info.get_all('Provides-Extra') or []: + s_extra = safe_extra(extra.strip()) + dm[s_extra] = list(frozenset(reqs_for_extra(extra)) - common) + + return dm + + +_distributionImpl = { + '.egg': Distribution, + '.egg-info': EggInfoDistribution, + '.dist-info': DistInfoDistribution, +} + + +def issue_warning(*args, **kw): + level = 1 + g = globals() + try: + # find the first stack frame that is *not* code in + # the pkg_resources module, to use for the warning + while sys._getframe(level).f_globals is g: + level += 1 + except ValueError: + pass + 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` + + `strs` must be a string, or a (possibly-nested) iterable thereof. + """ + # create a steppable iterator, so we can handle \-continuations + lines = iter(yield_lines(strs)) + + for line in lines: + # Drop comments -- a hash without a space may be in a URL. + if ' #' in line: + line = line[:line.find(' #')] + # If there is a line continuation, drop it, and append the next line. + if line.endswith('\\'): + line = line[:-2].strip() + try: + line += next(lines) + except StopIteration: + return + yield Requirement(line) + + +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)) + self.unsafe_name = self.name + project_name = safe_name(self.name) + self.project_name, self.key = project_name, project_name.lower() + self.specs = [ + (spec.operator, spec.version) for spec in self.specifier] + self.extras = tuple(map(safe_extra, self.extras)) + self.hashCmp = ( + self.key, + self.specifier, + frozenset(self.extras), + str(self.marker) if self.marker else None, + ) + self.__hash = hash(self.hashCmp) + + def __eq__(self, other): + return ( + isinstance(other, Requirement) and + self.hashCmp == other.hashCmp + ) + + def __ne__(self, other): + return not self == other + + def __contains__(self, item): + if isinstance(item, Distribution): + if item.key != self.key: + return False + + item = item.version + + # Allow prereleases always in order to match the previous behavior of + # this method. In the future this should be smarter and follow PEP 440 + # more accurately. + return self.specifier.contains(item, prereleases=True) + + def __hash__(self): + return self.__hash + + def __repr__(self): + return "Requirement.parse(%r)" % str(self) + + @staticmethod + def parse(s): + req, = parse_requirements(s) + return req + + +def _always_object(classes): + """ + Ensure object appears in the mro even + for old-style classes. + """ + if object not in classes: + return classes + (object,) + return classes + + +def _find_adapter(registry, ob): + """Return an adapter factory for `ob` from `registry`""" + types = _always_object(inspect.getmro(getattr(ob, '__class__', type(ob)))) + for t in types: + if t in registry: + return registry[t] + + +def ensure_directory(path): + """Ensure that the parent directory of `path` exists""" + dirname = os.path.dirname(path) + py31compat.makedirs(dirname, exist_ok=True) + + +def _bypass_ensure_directory(path): + """Sandbox-bypassing version of ensure_directory()""" + if not WRITE_SUPPORT: + raise IOError('"os.mkdir" not supported on this platform.') + dirname, filename = split(path) + if dirname and filename and not isdir(dirname): + _bypass_ensure_directory(dirname) + try: + mkdir(dirname, 0o755) + except FileExistsError: + pass + + +def split_sections(s): + """Split a string or iterable thereof into (section, content) pairs + + Each ``section`` is a stripped version of the section header ("[section]") + and each ``content`` is a list of stripped lines excluding blank lines and + comment-only lines. If there are any such lines before the first section + header, they're returned in a first ``section`` of ``None``. + """ + section = None + content = [] + for line in yield_lines(s): + if line.startswith("["): + if line.endswith("]"): + if section or content: + yield section, content + section = line[1:-1].strip() + content = [] + else: + raise ValueError("Invalid section heading", line) + else: + content.append(line) + + # wrap up last segment + yield section, content + + +def _mkstemp(*args, **kw): + old_open = os.open + try: + # temporarily bypass sandboxing + os.open = os_open + return tempfile.mkstemp(*args, **kw) + finally: + # and then put it back + os.open = old_open + + +# Silence the PEP440Warning by default, so that end users don't get hit by it +# randomly just because they use pkg_resources. We want to append the rule +# because we want earlier uses of filterwarnings to take precedence over this +# one. +warnings.filterwarnings("ignore", category=PEP440Warning, append=True) + + +# from jaraco.functools 1.3 +def _call_aside(f, *args, **kwargs): + f(*args, **kwargs) + return f + + +@_call_aside +def _initialize(g=globals()): + "Set up global resource manager (deliberately not state-saved)" + manager = ResourceManager() + g['_manager'] = manager + g.update( + (name, getattr(manager, name)) + for name in dir(manager) + if not name.startswith('_') + ) + + +@_call_aside +def _initialize_master_working_set(): + """ + Prepare the master working set and make the ``require()`` + API available. + + This function has explicit effects on the global state + of pkg_resources. It is intended to be invoked once at + the initialization of this module. + + Invocation by other packages is unsupported and done + at their own risk. + """ + working_set = WorkingSet._build_master() + _declare_state('object', working_set=working_set) + + require = working_set.require + iter_entry_points = working_set.iter_entry_points + add_activation_listener = working_set.subscribe + run_script = working_set.run_script + # backward compatibility + run_main = run_script + # Activate all distributions already on sys.path with replace=False and + # ensure that all distributions added to the working set in the future + # (e.g. by calling ``require()``) will get activated as well, + # with higher priority (replace=True). + tuple( + dist.activate(replace=False) + for dist in working_set + ) + add_activation_listener( + lambda dist: dist.activate(replace=True), + existing=False, + ) + working_set.entries = [] + # match order + list(map(working_set.add_entry, sys.path)) + globals().update(locals()) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cabe7344419efe206ebd49c5909c873de7255c78 GIT binary patch literal 96034 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3d16873f1fd1744acb9d703e933476135bbd4429 GIT binary patch literal 651 zcmYk3&2AGh5XZ;fO|nUoz=;Dq!5-Sp2T)Z)2o<F&5-Lckpj{y?N$fQHy&7*q5(N&3 zBM$*bUddNZc?C|47m65b{$r0V&(Gu2PNxNAUmr~04LHD0v$!>jCeO&#dlCVHCE)*w z%xBe_`<x<Atkm{x2Eq}xsC{96P1;etcq!_VM-3Y+h*^Fv8Zl%x2L`?)9eg8enJpn| z`c1*c;5PSE1uk5sEfucMW<*n&p)ick$<;Z@rdz@{wuA4C!CS~4+EDVig{KTYat7Ob zJBGa-kF3&)?AXG=XF5fcwEKx)!8K&00;nRpaBG_9N;~N!mLf!@8?VMA#2j@^B4)X+ zk49H7#+R<8?P5|cv?JG{DuX=MmR!$%03Hy~uZ>q=xSEvGTTRfL=ZTQ0ymaBs`bBWE zJ&AfBhI6r1kB2K9tjlfMBfH7GORorv!!T3jBuNe*9ZwhWa(ZKul?N-Ci5$Hmz6nsO ze2Fuuykax#&+?RTj*5+L2e<6Ou<w`_RsYF2>$1BvutPbQ?@br?wwYVlrGR%#f|&$6 zb6aTku}(tW-za@R3`c+Kqxp&I9&Nq89_aRpUKi$B5N7jScQYx4`bUALM%9)7q;2kX Zo}{^0Ci1B%stkj}Xz;exYS-C){u`X<ohJYQ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/pkg_resources/py31compat.py b/venv/lib/python3.7/site-packages/pip/_vendor/pkg_resources/py31compat.py new file mode 100644 index 0000000..a2d3007 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/pkg_resources/py31compat.py @@ -0,0 +1,23 @@ +import os +import errno +import sys + +from pip._vendor 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.7/site-packages/pip/_vendor/progress/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/progress/__init__.py new file mode 100644 index 0000000..a41f65d --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/progress/__init__.py @@ -0,0 +1,127 @@ +# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +from __future__ import division + +from collections import deque +from datetime import timedelta +from math import ceil +from sys import stderr +from time import time + + +__version__ = '1.4' + + +class Infinite(object): + file = stderr + sma_window = 10 # Simple Moving Average window + + def __init__(self, *args, **kwargs): + self.index = 0 + self.start_ts = time() + self.avg = 0 + self._ts = self.start_ts + self._xput = deque(maxlen=self.sma_window) + for key, val in kwargs.items(): + setattr(self, key, val) + + def __getitem__(self, key): + if key.startswith('_'): + return None + return getattr(self, key, None) + + @property + def elapsed(self): + return int(time() - self.start_ts) + + @property + def elapsed_td(self): + return timedelta(seconds=self.elapsed) + + def update_avg(self, n, dt): + if n > 0: + self._xput.append(dt / n) + self.avg = sum(self._xput) / len(self._xput) + + def update(self): + pass + + def start(self): + pass + + def finish(self): + pass + + def next(self, n=1): + now = time() + dt = now - self._ts + self.update_avg(n, dt) + self._ts = now + self.index = self.index + n + self.update() + + def iter(self, it): + try: + for x in it: + yield x + self.next() + finally: + self.finish() + + +class Progress(Infinite): + def __init__(self, *args, **kwargs): + super(Progress, self).__init__(*args, **kwargs) + self.max = kwargs.get('max', 100) + + @property + def eta(self): + return int(ceil(self.avg * self.remaining)) + + @property + def eta_td(self): + return timedelta(seconds=self.eta) + + @property + def percent(self): + return self.progress * 100 + + @property + def progress(self): + return min(1, self.index / self.max) + + @property + def remaining(self): + return max(self.max - self.index, 0) + + def start(self): + self.update() + + def goto(self, index): + incr = index - self.index + self.next(incr) + + def iter(self, it): + try: + self.max = len(it) + except TypeError: + pass + + try: + for x in it: + yield x + self.next() + finally: + self.finish() diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f03b65358a6d4623cd21f634d218f7e13678112f GIT binary patch literal 3919 zcmbtX-E!N;72d@HAV`rEB`b*&&9rW&Y0EYi?bu1`PMWGsI-O2ul+4tv6HYQ1m<vgu z0FYiR^~0gBq?z0_eFp2Yue7(l@+<VJ-&qh4t;kmaXV0F+F7})~f8X*?olcA4`PcT- zZ*-fn|I(m(Trj(6#S}y`$y1i`A?L(9sgsGJu)Ij!%o}=^cT+!W3>%jB(jaRNo0j*} zR@NG}z&D0#e_=9^%?l=*ar;~hI~cd*8pdmJ2ji}6|DE+aFCmrnxd~))oD|6<2k*)F z*(?Ur)JYc0IMopb?kG-D^nRgbtQ5VW>AASS^KeAFRF43&i&o?yF&lEphE6PouH-{c zI#OJ)p)XzOp>M>2^kw6Mo%3N6yww<dtJHP4Cfl-ub#2*|>*zbOCpXY{<!yOOZe8%< zx_m>vi8np@7S8jw3I3YzCwZddmt^x12cgGXwlB~ZUxG-!U?J1|oS}E@NG#ac!N}Df zIA1#7)0)QVorUuvxMZKRZ@0d2o{Q(MZZ6nDEZlRr=Gnt1a1}(0Jw?LELRoa0#(BSG zyd;<LscPW82?`x49qPh}==i`0aEeT2T16IxCs;W-F<y8&ooRfh<E$`^BG!@Cs_z-M zh|_)JM(Ut2{?Uo;#Zi1_#Br4VhpF4x>3?c4RmpLr<H2#H2K$o~jw%M(;b3%s8a|po z8s9s4urKGuM-PtG2d8?T-NSQ`4;~Mu$@FfLL&G$^`{Bn=507R~59p<B;c*P*X!FT| zii=_phGgL|+?k%4pc?!X8Wdd+#(f^x*5#XgzEL@3r&>93XcZpnDgHl0E8YQF@E35* zC0AWCsfPI%h@Nu+^E!KmhkXauA~O~zi9R%qgQa~ObqimsH;IrXO7b>1vlfO}MfMEC zU*SdJgD~FWE}w6$s8%nkLx#Lb4zk+y!02VTjGfzvSLnp|`of4L*Ve-dsf~A~D%Z4V z#A!4wVtE%!3VVEK-m9fACvTQayJ`gKm`naWNp<!RV+f7WB$q|sQDi}N2jn%fTg&Z3 zE$?GhCH~fR@t7acdFi3P_RI$uzz_V$RXfmwz2FOH!ME8Zs+2~;jA0E;$%B5I(#f?6 z;VcuvQ)E2jN7E_d$cSQ=8G-yz9lY)fYcIod<4Aqod9B%0BAi1c%!gRK^j*Mve14_= z)tXlfNba+)qjOk=_@3SWHD>b5eSSxBtcUn~y*5!f_oMdrY~cQWW&3Wuy`B0|yZco1 zio@NN?XR>i=U$RU>f9r%)E=foYj)0_JMb(b?KXQ3f4+d17vj?4jNXRG#<5uNx5&dZ z>s~TKoiY!+G6g9A6{VS4Bhm-yyJbfF0=yCV<V5|FrmiK3o5!cxx{KnSN=S>hLEC)Z zsm(-d>H|=S252L+;vUHS&gnY~jw-!L$M`3dgOZGtd=@-mRHZTIH2$hq+fh6CQvC*` zibN;ThM)dGKU5I)Hxgx`oIB9Z=RIddJ6eI%RPWPf8&nwcD2v0;w8Ai($XQB!I}D%A zqO_b*REvzepQN!`2dk(Cs-Muy0L6A1D}81&TfIvY)~;ky^=l%ebg4e2^@_sQv{d{Q z*=HNApjQD(p6dk7z-zm0H}C>MzgA#ZkrnHQOiPcwlT--)9ot6@kj_Og6tOFXbS-Lo z;63SE-Ur{1f#n<Eo3ds306dV~@=e*1UEp;~uFD?!HMt=-(YL=tI1W3ArduZXa)~r` zN{~hrtz@O*=O9#z7wp^tV51uS8<hwkEl9sh3*j~{#hwws;+GO107JcE29v6fF|w96 z0!3f_mL|(8q_$}44SIpgPZ*BUs3^j)G_5r#Ip`l~1u4TUyj8kh!5ifnJ=D{>&(I3m zx>TC(7-O-8Vp)NRs|Y+5-BD~&G))y}5fVB-culbq0KTtj+a;E?Yb`KQTa6ST%UK0( z#1Zu~Ojj84De*Vsmyd0M58q-%C31aLBw@$uu}Li}m9mA9LGmrC6u^W>R*DU9dz*NT z#0Fe7igO*Ui0suOmy@r^tWCX%Pqe+@jj3ii+lZ4=woOeyc9!I2fwIoO@yKcyyTmKP zH?D+VkIq-@TuP@iqoI;YUP-5Aur<lF(r-SwB8W&<1aH=Y>!^6;+_kOA!&S+v>M}2D z@Xbf0GLqGj_`F+7Dgns`7v?F3>NuiOf}F$ofD#C0x((1xppxj6mZiE{r4?a;ag%(c zR;m=`lW`9wdNKvKOsE#heXRt|-CXV;<BPK{Zbe8TLZ&Ay-*RymIclkQIr5IPuUYPV zbu%Og3kmPnkYI7_3KBf^9(K20GR?<l)A-LyP1Fx?LJepY;m)-)DXPXAt)NI?K#DGY zzH@~b^#KVn`dvl$EA@cLLn0OgJ|d11QvHF*ABpS|q39^<|L4S!Fw<F<s!^P#Rk<QJ zA;3PNMYeQN*(1AIwE|8UQ2l@dt}Tmu{dGdC{h6LApp~KkFl(bpn#LoIKZnbIECF50 z=+B?Mdm1;3^r5X@xZIr;7S+oCJh*%x<1Yxl1oZinr(<km;ifFYq~kT~nc$NWD?hcR SzK0cUr;TfX{Rvm}9{nGMUI6s~ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/bar.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/bar.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7b4e5a5056392208bece7d7ae674bcd7800da63a GIT binary patch literal 2741 zcmbVOTW=dh6yDjp*LLcp>77eZ396A=mzEYP0g4)l%L7rRRzj>m*2c58H(jsI>^c`~ zjgV473k3v7t$0hy1L6sZ7asW^^9WD*3w?p_>~0dLEfQs%IcLt9*_rRmocShKt5ruq zxqE8)qfg6<@)sGq#Xw^LHGTlW70yDX$6Us!t%j<ra*gYu*3(@bK8+ip(KB6>DeoxU z<kl^PTfXV*o4RYkWAhR`CEwcATpPB-%dpG74Z8%p!mF^WneD)y;)h@#%Ep&r*Z4H- zX}^r|71%TUFzmybUFGU^r9Qg@oJyU^+As=QeeO5IAn}D4#!EXa@3F6men<Fmj8T;j z1iHiM{a`(aTJ-5|QPEgHjbDZE6_;@Z!7^9ls;hI&HMs7Y+;A;!x;D4m61QE4m$-9F zam&06C>5z)^~BB`zL&~qdj3ohaeuwe8}ny+9`s0^OGj!t_mJW5^o<t5qhc3z5jtLh zNR(7rVW{e?vdPBOVktYWj8(L>R5_}QAy@R2%_?IZEhELqv4NJE^_rY*St*UNQ#~br zDK$IhHXB>1vgM@Kc6Ok^tS$*!zFwAE5GB%B3wY9%_Mq4?Y4xygUdNYuI|xJR_`N~0 z(ahRrJZ!gvb*ZoPgGf5do@fq)PoAt@^jd5AhSzPW$9~wBRr=WH&CriJSgMlGm|J2B zSfqxjq>=f>G&%Gzi2Pp^@eGWIy~aQUt6t(aRz1;Z_e1WBxY6r2TCWV6S4LM>&aYi; z^HF^H;;Oi?o{W0uQ94oMMq>~R&IVDOcwu<<(re4zo5SS}IkVba^&{RFm^{yw20)w} zY)ErB;8^T5mX2p26jo!7>ahGb!)!KkaO&ssVM|B?yV;Dqp5JUrr`hcF`7oq*rP=&s z=!JQYs9>Tj*epPCn9NxcH4=v)WVst4nOj2<_l0<l+!X$Vc$Q2P;sk1j&1U++pPKa_ zNOMZM1^QqP;;}SWk>(oG9JiMnNDot%7rUP51W^Y;j;ix#2EJ(dQBvpg^P+?)h8o15 zw|~s_z1vH5TRab!m?QB52|B|kg*XvQ7Fre%ZS;B6m?&yLAVK~o2SWSySRfj}>vH;S z<QlMF$JT=Y5JCa-L7{(IsvD2O-8+IO;(HORy^b2|5QI;V=YJzx3`8rOKz9Gv9NGOl zPmOFIINm&fj64UBX>csike4BL_srK;^euz4Z6;2F>&%GQ4k^G5FdNtoJ88+O_o9~Y zdpLP7#5PK8Er{ycL<ZcuyPE;^(xm&_!u?I5zb^Fd@UIH{%R=8N^zA)*q`N|ywn)H# zgUIQzAjXUmL4InYrz(6J=~O$e5IMpodd%#M9zlg5Pmtsa<LrczYWUJhb*|pj#WHzQ z{e%+XjT_sr%*5hqYG6Hk6ZE@DBwK<XeVE1J+7@UPHV8GfQ|c+FP6y;VE`w$(X?c%k z^`)J^Q3Tz-oN%jB1LsL|(Dh<J&IzGPy?BrdYM?}v8lH~)1`+#AT%#i}>lJa723b)) zjdb?ORT@!y2+B6HE@?(Np%TLiVhm}4TLcbNoFrFvNl#I0pJuWPN!0T$YD~iv@LmO+ zmvi70JIap3Q-g1G<Y0#E5#pnCAhmcS#tRdANxLt4(g7ihBwh=WuAsF1cdmO0y;o7= z?7_sErmCxgya$qekKt(lc9T4R$dSsLw66v0J|%J8&U0=1vqIl0^yh{CBG*6d>Yoey z_d@@%RM#J6k1T}!E!-!zOF;7>p;sYnCdhs|+}FDv-yqz^<OTaK2XpWHLjO=`F!6r} zcNt(lo&ZO7eTp8i_AnU=JYa%giwh)Z`vuXTw7PzX2O$>pUt{*xWIUZwq9FFkPA3ah m(3BIowYM?Sej|S*-=Y+ZiOnmjtyWk?n>kjqYX*MDYWhEWU`LSv literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/counter.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/counter.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9c7bb98f1f6b66c0c86f58830e5622e0cbc3694c GIT binary patch literal 1583 zcmbVM&1=*^6raf?+3a>(YpGg4kb3ZtLrt})2qMKE#Dj}aK?p)fcV>4}lk9dTY3s5c zbn6Ewh~URnkN!(@)KmWh@#K5ibX%pOIPl)f{AT98nfHD#Hzy}+1jg&rYY)C#gnYxv z-heq-22m0eC!EG4p+2RA8=S>P!hDvPzFEx8*h*~QrsNjk7Pof@w}ma((DW;SRJa3( z1BeNT14xzE0I8Ko6_5#D2c#~lL+01`<SKEeb|Eftsh-Z$sM+Nrh@(u%Fjl)17Yyy( zPFqn5pmy%cZd(eaV0-Pp1n5q*9i>h5us00&SO!sNKndbgPJDw?pK-%CIpgLI@hxsa zWLsBOx_Ju0G`ZKrU^vj4AS)nh7Sw=zA{iZ!bz?|BV_pcHr45&9YYVTSnaZTLqLhnm zxR<F!-1<V~Bpm&*;q_#+8D_%U45ioV##~6{B^|GMu@_wHUt3??T59pWy0Ww>FKuW2 zWD!O?_3nASsJ9TMDhuOy;qukB&cl4IjbI_crbu~Lg7Z;2yyoZ~7kZDho%c8dJcZZC zToBryDxY~_wA6r?J3)|!i3kE+3xcG}^BBMDL9mgBak)}SAk$%6=!s4QWohP8b)`H4 zE{n$<P*aFiKph8BHYkUh)HDk0@aoLLreCYW8C1sPCS=#r)#A#$yOsV=Wn>k+OXR$+ zN|A)Xp0w>!Sw|QPGg8I1@jd52_L4O{jyz76C8zPsQB*UikQRSV#4%Vs3!;!lkO)H} za(Ej4fuz=I7B(Nc)gN>|XW;1ThbN_dTH0Z0cS`%Lw9iZXqO>pfbBT_y^H)IB6;K)Q ze4P&IW11NQ%IO@*7$D|=&XOS=8jlU=0}J;IjFV*C2S!7pD_|6hMXK#yCsaadmPDy$ zQJQIIkE2CRTvpUTSJHALjSj1ai?>1=5n7{jv|le$Fs_IFdp(fse<{id*m54^AUhFj zf{X|D{xXQddjHB!U?tP+ZX{f5l+BN?O8c&~Z%g~Wv~L=&dFVy=30Qm;ES!gc9!AEN zb*RL7!=1qHY~@)lp*tlmNe2}YOJezSr6b}V{8J=mt7x}^Y!aVVI608saWw5*AGQ1q Tq_o1WsMBd$XEV-BWv2EMkWWYh literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/helpers.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/helpers.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..266d6a97bb6b59c0c61b67d443418c88bf407d07 GIT binary patch literal 3025 zcmai0TW{P%6rS;YFKN>@6rmJY3KR@#x1?%O5!V*lMu=2OdJ!&?<#@ciPQBiAW;RJz z+owb-50u}KKJu65l_&lJPn<LM?mCwSTRxr{&v?$|JKvdGb8~e9*B^`Pzy01I<ZtXu zE(;pp!y_07Mi|XVp9Yi?W&{Q^1M@Cn7PI#VvlDCA3~cB-%!R(I`wpz}GPmyrZr=+$ zSVvebtM%(aof4Q^XAPL!&~qECxkmiCe_$u#Q*~;Sr@0I}!#tMhARjr4Prh5ao|W%j zjMF9;s)?6a0+En_G6L$+z+|<Tq(hm>ti4(QiZW-91U7S-2XE&ku}I*;rgc?+%u|{C zlJ2DWot4<oe<Q?%w+#=tg@_&qNhBSUU1P)Okg@S6Is*EkIi~#L7+cnuY}lNk+;?6R z-E#Ro>B$;1aFm&^OiH8&ZL2z>SJYn<bP;G|t#AtaDdHQ-Ome2IPMRftL)l`unQ)Gp zDK8AuJe6UnoNzm3vZvgBB1F_pxP#xFR76rfSB+lEk}w`}G2qJ9epQWo%Rl}U-hQ~c zc7Ijboopz2zNsvcWF3xpP|nlsh<61<q85g676}oCf02KmwPF2MB$M`5#M_-g#u6^t z{a!o%Vl%usy18+6`&x&M#EolPd}&9H`d8uV=IsaV&2;l}nhP0a+2!kBuJ@h}*Sk2V zpKuF|9B}ygpv%FAb}z}mPH|=PIrl)Fci<6cK@fVDI@F?$F%R!~=#9?JVs~ZYk!c7K z8W_Uc@Q45eIGXTBDEBD@=n)2R!&o3Mj4|CevHhC9Fr_s%#^&3AbDUWQ&Bm|N8Pi?5 z3*({ww(nMg_Am7~?&upFH`QVAJ^kVcB3=Wb>}+EwB%i~!*^hRVnI$<t4PD>j^EgU{ zqU(yr{2cTOv4G?DHp28{Xo@BX0uHFtCS5=`%vao?r^SdMyzo8s!DrAxoA@P^+6UM& z_$3KeYj1$n2vQA1bLFT(cEuo6qp+m0cJKb<5>Y<Yb{tmU=>T3u?=q|rI%ny5IyzI) zyZG+Y72iX2=TScabl1bMKVZWQ+s!b1HjJ|33)j0NKKKO`?}1QrC0yeq%ffJ`0_cPQ z;^;`7Kj)z#aIr@%<5bi0^yu-#@)b-wKrD@uh=tWy9SFwN1mi(EH&s(xndK)^%pKU} zD8&G|T+rl#=(PAPl>0Vd7h4X$C0*(1xB;P@7`GaCVFUgl3hgvZ^y6a5Pr(P@EMll9 zoxy?9ff|$Ai};i4@CclPnTdG`A$_ZA>?|jb#p6e?66_$ng;L|OC4s!FnO9Qc$eLSx z^7BzVniU%`sosD-H_noXXZbfUrG(!+9W5NtwVX1g53B^!)VVQHb!n<9wDt`o00}jq znml@jHKm6COC$7xPNRYbjDiNNEX|V{f;DuNyNw)><v*Yq7y)Df51vD&l+%u9f#Xb( zn$H-01!WD?H~Eq@fDwvOUAD?NfPb;R91TR37%&h;e!dH><3pko_AY#$+R+43FA2TO zl`At&sPXslr!5p8pqQn<_TMEOLk{2<QB1jW0$hz*L_Z!AG-h??d!FSvIxC>qIwI}n zQKp==<-5x(51{;6$xbQ{u!0H8@e-ecsIr3Q1UMJ%d2ra!=c2&Y9N+*4II6Lhc9(Oh zDPVMCHR+~8LXB%htzy$wFUnb#@RsaFvK2$26s^Mg)*x>c3Qfa_O5lTKL!iAg;sCPH zXA>lJ2&BDhlw=OP>J%J+RiNO2Pq2lCsM8^+foHB#jgkPAh35eNW(If&i_3h1GPF=J za+dlNm*E?8>Nc*yctHLToj;I0yLg_$(~nV{exQo#X!<a3qKuBuun$KT4#i;><AT;d zhnc_PuZ!y9(b3`obq*Qm9s-nd!;lSPs2Z489RGF_l+cN*xEp2zLaAwS99sdthnm$H z${~lE#nE6*sT@;5IfM0$B$m3`6l6S$fhnE~j`r#wRm_``uJXPvis839^2pRp)1sC+ Ke*tdVH2(uCfLHAR literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/spinner.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/spinner.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..823ff18e35af6e56952a9fcf7e1f202dc501d32c GIT binary patch literal 1500 zcmbVMOK%e~5VrS~?ItayKzS6T9yk!8b_*4tN(e=8KuENz)JjMzq*WR_$(GG#YiHXM zl~a2}6^{eQQgY(Ng@?rRf9w%X{R=rUvvHvTF2$>v@n?I-pJ&FtIXLJLXphI1?(dj{ z{6MhZ0Fx4kY=dHi(U3H#M=4<%(?hMHdwSM4LZe}NCMCBCGnutTn8i)5ZyKHjBROWn zh|R4{-OB+UU=Cm>!#3bND*!HJcmVJq8v;C(VTT=AAjRQ5*q;<>I-Ep7rOCJ-1}!ei zq1>ar3Hwe|4I&tXMb13|o!MYLh${Hse$${+0+HjOIPoYWp2n!BGtD!Y?wQPB<`(fR zX2G7hG`A23QN%?`ibj`Cbm{#r-RM$xv4WdoLyrc?Ef9Gg)CO55EecxOq@&~!^j_+S zHt1=xi*Y01na&lB)C?lV*Hb;@QEJ8Yvg9%~*N}KoOAX1xYD$CGM2vvf?ur|WV71)h z?rK@M)n>@JkZz;yRxZW<OnYW|YHhm8+Vbl3s<^z~YB#2!)gpJ%je~e1h-9lAh7(t= zE!7_+OEnzK#9!qRYYK4QtO+iqD|-i?j31^}5;NFv3{QqfBy^azhg3u+dy{hzB-{6+ za)bMR>iB-6$&wKJ1>avu%AuOcHNbhf#>Ei$N%Qpp5?D!uYzlE4MzS*=P{(l00yPRE zZBRBf@YAx<zMLYp5-vLh>UU1DKABN7Ah#w&+)ADKfGhHe4oknk_@L~2W#1|L7P2Ew zz!HJmi<793_W^>K6Opkz1HEw&iIreef%w1p<!77CsGs0dMd+EbPn3Or7=oBTEX;j^ zi2Dd)oJ+XiET}&N2tm|p)~_Ju?*>tS6t_S2NNs;o_Or5I4nq>RzJMH56cP84#2P5! zf^krPk%Siq-<X;WL<b<-PFk1`)_K?$&d%2!vyRGp=Z(TUJ-hp@XJ0AXQ77sg>LllY z-$f*<PJ(!@n8&+OO<IY7yCHB&<WOPprnx!~W4O)&AKR?JvnmppDS?p?=;UA3m)h5R W7w*PUSRt`U3lu(m#2Gf=(|-a=6F|QJ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/progress/bar.py b/venv/lib/python3.7/site-packages/pip/_vendor/progress/bar.py new file mode 100644 index 0000000..025e61c --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/progress/bar.py @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +from __future__ import unicode_literals + +import sys + +from . import Progress +from .helpers import WritelnMixin + + +class Bar(WritelnMixin, Progress): + width = 32 + message = '' + suffix = '%(index)d/%(max)d' + bar_prefix = ' |' + bar_suffix = '| ' + empty_fill = ' ' + fill = '#' + hide_cursor = True + + def update(self): + filled_length = int(self.width * self.progress) + empty_length = self.width - filled_length + + message = self.message % self + bar = self.fill * filled_length + empty = self.empty_fill * empty_length + suffix = self.suffix % self + line = ''.join([message, self.bar_prefix, bar, empty, self.bar_suffix, + suffix]) + self.writeln(line) + + +class ChargingBar(Bar): + suffix = '%(percent)d%%' + bar_prefix = ' ' + bar_suffix = ' ' + empty_fill = '∙' + fill = '█' + + +class FillingSquaresBar(ChargingBar): + empty_fill = '▢' + fill = '▣' + + +class FillingCirclesBar(ChargingBar): + empty_fill = '◯' + fill = '◉' + + +class IncrementalBar(Bar): + if sys.platform.startswith('win'): + phases = (u' ', u'▌', u'█') + else: + phases = (' ', '▏', '▎', '▍', '▌', '▋', '▊', '▉', '█') + + def update(self): + nphases = len(self.phases) + filled_len = self.width * self.progress + nfull = int(filled_len) # Number of full chars + phase = int((filled_len - nfull) * nphases) # Phase of last char + nempty = self.width - nfull # Number of empty chars + + message = self.message % self + bar = self.phases[-1] * nfull + current = self.phases[phase] if phase > 0 else '' + empty = self.empty_fill * max(0, nempty - len(current)) + suffix = self.suffix % self + line = ''.join([message, self.bar_prefix, bar, current, empty, + self.bar_suffix, suffix]) + self.writeln(line) + + +class PixelBar(IncrementalBar): + phases = ('⡀', '⡄', '⡆', '⡇', '⣇', '⣧', '⣷', '⣿') + + +class ShadyBar(IncrementalBar): + phases = (' ', '░', '▒', '▓', '█') diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/progress/counter.py b/venv/lib/python3.7/site-packages/pip/_vendor/progress/counter.py new file mode 100644 index 0000000..6b45a1e --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/progress/counter.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +from __future__ import unicode_literals +from . import Infinite, Progress +from .helpers import WriteMixin + + +class Counter(WriteMixin, Infinite): + message = '' + hide_cursor = True + + def update(self): + self.write(str(self.index)) + + +class Countdown(WriteMixin, Progress): + hide_cursor = True + + def update(self): + self.write(str(self.remaining)) + + +class Stack(WriteMixin, Progress): + phases = (' ', '▁', '▂', '▃', '▄', '▅', '▆', '▇', '█') + hide_cursor = True + + def update(self): + nphases = len(self.phases) + i = min(nphases - 1, int(self.progress * nphases)) + self.write(self.phases[i]) + + +class Pie(Stack): + phases = ('○', '◔', '◑', '◕', '●') diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/progress/helpers.py b/venv/lib/python3.7/site-packages/pip/_vendor/progress/helpers.py new file mode 100644 index 0000000..0cde44e --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/progress/helpers.py @@ -0,0 +1,91 @@ +# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +from __future__ import print_function + + +HIDE_CURSOR = '\x1b[?25l' +SHOW_CURSOR = '\x1b[?25h' + + +class WriteMixin(object): + hide_cursor = False + + def __init__(self, message=None, **kwargs): + super(WriteMixin, self).__init__(**kwargs) + self._width = 0 + if message: + self.message = message + + if self.file and self.file.isatty(): + if self.hide_cursor: + print(HIDE_CURSOR, end='', file=self.file) + print(self.message, end='', file=self.file) + self.file.flush() + + def write(self, s): + if self.file and self.file.isatty(): + b = '\b' * self._width + c = s.ljust(self._width) + print(b + c, end='', file=self.file) + self._width = max(self._width, len(s)) + self.file.flush() + + def finish(self): + if self.file and self.file.isatty() and self.hide_cursor: + print(SHOW_CURSOR, end='', file=self.file) + + +class WritelnMixin(object): + hide_cursor = False + + def __init__(self, message=None, **kwargs): + super(WritelnMixin, self).__init__(**kwargs) + if message: + self.message = message + + if self.file and self.file.isatty() and self.hide_cursor: + print(HIDE_CURSOR, end='', file=self.file) + + def clearln(self): + if self.file and self.file.isatty(): + print('\r\x1b[K', end='', file=self.file) + + def writeln(self, line): + if self.file and self.file.isatty(): + self.clearln() + print(line, end='', file=self.file) + self.file.flush() + + def finish(self): + if self.file and self.file.isatty(): + print(file=self.file) + if self.hide_cursor: + print(SHOW_CURSOR, end='', file=self.file) + + +from signal import signal, SIGINT +from sys import exit + + +class SigIntMixin(object): + """Registers a signal handler that calls finish on SIGINT""" + + def __init__(self, *args, **kwargs): + super(SigIntMixin, self).__init__(*args, **kwargs) + signal(SIGINT, self._sigint_handler) + + def _sigint_handler(self, signum, frame): + self.finish() + exit(0) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/progress/spinner.py b/venv/lib/python3.7/site-packages/pip/_vendor/progress/spinner.py new file mode 100644 index 0000000..464c7b2 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/progress/spinner.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +from __future__ import unicode_literals +from . import Infinite +from .helpers import WriteMixin + + +class Spinner(WriteMixin, Infinite): + message = '' + phases = ('-', '\\', '|', '/') + hide_cursor = True + + def update(self): + i = self.index % len(self.phases) + self.write(self.phases[i]) + + +class PieSpinner(Spinner): + phases = ['◷', '◶', '◵', '◴'] + + +class MoonSpinner(Spinner): + phases = ['◑', '◒', '◐', '◓'] + + +class LineSpinner(Spinner): + phases = ['⎺', '⎻', '⎼', '⎽', '⎼', '⎻'] + +class PixelSpinner(Spinner): + phases = ['⣾','⣷', '⣯', '⣟', '⡿', '⢿', '⣻', '⣽'] diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/pyparsing.py b/venv/lib/python3.7/site-packages/pip/_vendor/pyparsing.py new file mode 100644 index 0000000..865152d --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/pyparsing.py @@ -0,0 +1,5742 @@ +# module pyparsing.py +# +# Copyright (c) 2003-2018 Paul T. McGuire +# +# 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. +# + +__doc__ = \ +""" +pyparsing module - Classes and methods to define and execute parsing grammars +============================================================================= + +The pyparsing module is an alternative approach to creating and executing simple grammars, +vs. the traditional lex/yacc approach, or the use of regular expressions. With pyparsing, you +don't need to learn a new syntax for defining grammars or matching expressions - the parsing module +provides a library of classes that you use to construct the grammar directly in Python. + +Here is a program to parse "Hello, World!" (or any greeting of the form +C{"<salutation>, <addressee>!"}), built up using L{Word}, L{Literal}, and L{And} elements +(L{'+'<ParserElement.__add__>} operator gives L{And} expressions, strings are auto-converted to +L{Literal} expressions):: + + from pip._vendor.pyparsing import Word, alphas + + # define grammar of a greeting + greet = Word(alphas) + "," + Word(alphas) + "!" + + hello = "Hello, World!" + print (hello, "->", greet.parseString(hello)) + +The program outputs the following:: + + Hello, World! -> ['Hello', ',', 'World', '!'] + +The Python representation of the grammar is quite readable, owing to the self-explanatory +class names, and the use of '+', '|' and '^' operators. + +The L{ParseResults} object returned from L{ParserElement.parseString<ParserElement.parseString>} can be accessed as a nested list, a dictionary, or an +object with named attributes. + +The pyparsing module handles some of the problems that are typically vexing when writing text parsers: + - extra or missing whitespace (the above program will also handle "Hello,World!", "Hello , World !", etc.) + - quoted strings + - embedded comments + + +Getting Started - +----------------- +Visit the classes L{ParserElement} and L{ParseResults} to see the base classes that most other pyparsing +classes inherit from. Use the docstrings for examples of how to: + - construct literal match expressions from L{Literal} and L{CaselessLiteral} classes + - construct character word-group expressions using the L{Word} class + - see how to create repetitive expressions using L{ZeroOrMore} and L{OneOrMore} classes + - use L{'+'<And>}, L{'|'<MatchFirst>}, L{'^'<Or>}, and L{'&'<Each>} operators to combine simple expressions into more complex ones + - associate names with your parsed results using L{ParserElement.setResultsName} + - find some helpful expression short-cuts like L{delimitedList} and L{oneOf} + - find more useful common expressions in the L{pyparsing_common} namespace class +""" + +__version__ = "2.2.1" +__versionTime__ = "18 Sep 2018 00:49 UTC" +__author__ = "Paul McGuire <ptmcg@users.sourceforge.net>" + +import string +from weakref import ref as wkref +import copy +import sys +import warnings +import re +import sre_constants +import collections +import pprint +import traceback +import types +from datetime import datetime + +try: + from _thread import RLock +except ImportError: + from threading import RLock + +try: + # Python 3 + from collections.abc import Iterable + from collections.abc import MutableMapping +except ImportError: + # Python 2.7 + from collections import Iterable + from collections import MutableMapping + +try: + from collections import OrderedDict as _OrderedDict +except ImportError: + try: + from ordereddict import OrderedDict as _OrderedDict + except ImportError: + _OrderedDict = None + +#~ sys.stderr.write( "testing pyparsing module, version %s, %s\n" % (__version__,__versionTime__ ) ) + +__all__ = [ +'And', 'CaselessKeyword', 'CaselessLiteral', 'CharsNotIn', 'Combine', 'Dict', 'Each', 'Empty', +'FollowedBy', 'Forward', 'GoToColumn', 'Group', 'Keyword', 'LineEnd', 'LineStart', 'Literal', +'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', +'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', +] + +system_version = tuple(sys.version_info)[:3] +PY_3 = system_version[0] == 3 +if PY_3: + _MAX_INT = sys.maxsize + basestring = str + unichr = chr + _ustr = str + + # build list of single arg builtins, that can be used as parse actions + singleArgBuiltins = [sum, len, sorted, reversed, list, tuple, set, any, all, min, max] + +else: + _MAX_INT = sys.maxint + range = xrange + + def _ustr(obj): + """Drop-in replacement for str(obj) that tries to be Unicode friendly. It first tries + str(obj). If that fails with a UnicodeEncodeError, then it tries unicode(obj). It + then < returns the unicode object | encodes it with the default encoding | ... >. + """ + if isinstance(obj,unicode): + return obj + + try: + # If this works, then _ustr(obj) has the same behaviour as str(obj), so + # it won't break any existing code. + return str(obj) + + except UnicodeEncodeError: + # Else encode it + ret = unicode(obj).encode(sys.getdefaultencoding(), 'xmlcharrefreplace') + xmlcharref = Regex(r'&#\d+;') + xmlcharref.setParseAction(lambda t: '\\u' + hex(int(t[0][2:-1]))[2:]) + return xmlcharref.transformString(ret) + + # 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)) + except AttributeError: + continue + +_generatorType = type((y for y in range(1))) + +def _xml_escape(data): + """Escape &, <, >, ", ', etc. in a string of 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): + data = data.replace(from_, to_) + return data + +class _Constants(object): + pass + +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) + +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 ): + self.loc = loc + if msg is None: + self.msg = pstr + self.pstr = "" + else: + self.msg = msg + self.pstr = pstr + self.parserElement = elem + self.args = (pstr, loc, msg) + + @classmethod + def _from_exception(cls, pe): + """ + internal factory method to simplify creating one type of ParseException + from another - avoids having __init__ signature conflicts among subclasses + """ + return cls(pe.pstr, pe.loc, pe.msg, pe.parserElement) + + 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 ) + 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 ): + return _ustr(self) + def markInputline( self, markerString = ">!<" ): + """Extracts the exception line from the input string, and marks + the location of the exception with a special symbol. + """ + line_str = self.line + line_column = self.column - 1 + if markerString: + line_str = "".join((line_str[:line_column], + markerString, line_str[line_column:])) + return line_str.strip() + def __dir__(self): + return "lineno col line".split() + dir(type(self)) + +class ParseException(ParseBaseException): + """ + Exception thrown when parse expressions don't match class; + 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 + + Example:: + try: + Word(nums).setName("integer").parseString("ABC") + except ParseException as pe: + print(pe) + print("column: {}".format(pe.col)) + + prints:: + Expected integer (at char 0), (line:1, col:1) + column: 1 + """ + pass + +class ParseFatalException(ParseBaseException): + """user-throwable exception thrown when inconsistent parse content + is found; stops all parsing immediately""" + pass + +class ParseSyntaxException(ParseFatalException): + """just like L{ParseFatalException}, but thrown internally when an + L{ErrorStop<And._ErrorStop>} ('-' operator) indicates that parsing is to stop + immediately because an unbacktrackable syntax error has been found""" + pass + +#~ class ReparseException(ParseBaseException): + #~ """Experimental class - parse actions can raise this exception to cause + #~ pyparsing to reparse the input string: + #~ - with a modified input string, and/or + #~ - with a modified start location + #~ Set the values of the ReparseException in the constructor, and raise the + #~ exception in a parse action to cause pyparsing to use the new string/location. + #~ Setting the values as None causes no change to be made. + #~ """ + #~ def __init_( self, newstring, restartLoc ): + #~ self.newParseText = newstring + #~ self.reparseLoc = restartLoc + +class RecursiveGrammarException(Exception): + """exception thrown by L{ParserElement.validate} if the grammar could be improperly recursive""" + def __init__( self, parseElementList ): + self.parseElementTrace = parseElementList + + def __str__( self ): + return "RecursiveGrammarException: %s" % self.parseElementTrace + +class _ParseResultsWithOffset(object): + 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) + +class ParseResults(object): + """ + Structured parse results, to provide multiple means of access to the parsed data: + - as a list (C{len(results)}) + - by list index (C{results[0], results[1]}, etc.) + - by attribute (C{results.<resultsName>} - see L{ParserElement.setResultsName}) + + Example:: + integer = Word(nums) + date_str = (integer.setResultsName("year") + '/' + + integer.setResultsName("month") + '/' + + integer.setResultsName("day")) + # equivalent form: + # date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + # parseString returns a ParseResults object + result = date_str.parseString("1999/12/31") + + def test(s, fn=repr): + print("%s -> %s" % (s, fn(eval(s)))) + test("list(result)") + test("result[0]") + test("result['month']") + test("result.day") + test("'month' in result") + test("'minutes' in result") + test("result.dump()", str) + prints:: + list(result) -> ['1999', '/', '12', '/', '31'] + result[0] -> '1999' + result['month'] -> '12' + result.day -> '31' + 'month' in result -> True + 'minutes' in result -> False + result.dump() -> ['1999', '/', '12', '/', '31'] + - day: 31 + - month: 12 + - year: 1999 + """ + def __new__(cls, toklist=None, name=None, asList=True, modal=True ): + if isinstance(toklist, cls): + return toklist + retobj = object.__new__(cls) + retobj.__doinit = True + return retobj + + # 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 ): + if self.__doinit: + self.__doinit = False + self.__name = None + self.__parent = None + self.__accumNames = {} + self.__asList = asList + self.__modal = modal + if toklist is None: + toklist = [] + if isinstance(toklist, list): + self.__toklist = toklist[:] + elif isinstance(toklist, _generatorType): + self.__toklist = list(toklist) + else: + self.__toklist = [toklist] + self.__tokdict = dict() + + 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 + self.__name = name + if not (isinstance(toklist, (type(None), basestring, list)) and toklist in (None,'',[])): + if isinstance(toklist,basestring): + toklist = [ toklist ] + if asList: + if isinstance(toklist,ParseResults): + self[name] = _ParseResultsWithOffset(toklist.copy(),0) + else: + self[name] = _ParseResultsWithOffset(ParseResults(toklist[0]),0) + self[name].__name = name + else: + try: + self[name] = toklist[0] + except (KeyError,TypeError,IndexError): + self[name] = toklist + + 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] ]) + + 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)): + self.__toklist[k] = v + sub = v + else: + self.__tokdict[k] = self.__tokdict.get(k,list()) + [_ParseResultsWithOffset(v,0)] + sub = v + if isinstance(sub,ParseResults): + sub.__parent = wkref(self) + + 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) + # get removed indices + removed = list(range(*i.indices(mylen))) + removed.reverse() + # fixup indices in token dictionary + 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 ): + return k in self.__tokdict + + 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 ): + if hasattr(self.__tokdict, "iterkeys"): + return self.__tokdict.iterkeys() + else: + return iter(self.__tokdict) + + def _itervalues( self ): + return (self[k] for k in self._iterkeys()) + + def _iteritems( self ): + return ((k, self[k]) for k in self._iterkeys()) + + if PY_3: + keys = _iterkeys + """Returns an iterator of all named result keys (Python 3.x only).""" + + values = _itervalues + """Returns an iterator of all named result values (Python 3.x only).""" + + items = _iteritems + """Returns an iterator of all named result key-value tuples (Python 3.x only).""" + + else: + iterkeys = _iterkeys + """Returns an iterator of all named result keys (Python 2.x only).""" + + itervalues = _itervalues + """Returns an iterator of all named result values (Python 2.x only).""" + + iteritems = _iteritems + """Returns an iterator of all named result key-value tuples (Python 2.x only).""" + + 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 ): + """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 ): + """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 ): + """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): + """ + Removes and returns item at specified index (default=C{last}). + Supports both C{list} and C{dict} semantics for C{pop()}. If passed no + argument or an integer argument, it will use C{list} semantics + and pop tokens from the list of parsed tokens. If passed a + non-integer argument (most likely a string), it will use C{dict} + semantics and pop the corresponding value from any defined + results names. A second default return value argument is + supported, just as in C{dict.pop()}. + + Example:: + def remove_first(tokens): + tokens.pop(0) + print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] + print(OneOrMore(Word(nums)).addParseAction(remove_first).parseString("0 123 321")) # -> ['123', '321'] + + label = Word(alphas) + patt = label("LABEL") + OneOrMore(Word(nums)) + print(patt.parseString("AAB 123 321").dump()) + + # Use pop() in a parse action to remove named result (note that corresponding value is not + # removed from list form of results) + def remove_LABEL(tokens): + tokens.pop("LABEL") + return tokens + patt.addParseAction(remove_LABEL) + print(patt.parseString("AAB 123 321").dump()) + prints:: + ['AAB', '123', '321'] + - LABEL: AAB + + ['AAB', '123', '321'] + """ + if not args: + args = [-1] + 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): + index = args[0] + ret = self[index] + del self[index] + return ret + else: + defaultvalue = args[1] + return defaultvalue + + def get(self, key, defaultValue=None): + """ + Returns named result matching the given key, or if there is no + such name, then returns the given C{defaultValue} or C{None} if no + C{defaultValue} is specified. + + Similar to C{dict.get()}. + + Example:: + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + result = date_str.parseString("1999/12/31") + print(result.get("year")) # -> '1999' + print(result.get("hour", "not specified")) # -> 'not specified' + print(result.get("hour")) # -> None + """ + if key in self: + return self[key] + else: + return defaultValue + + def insert( self, index, insStr ): + """ + Inserts new element at location index in the list of parsed tokens. + + Similar to C{list.insert()}. + + Example:: + print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] + + # use a parse action to insert the parse location in the front of the parsed results + def insert_locn(locn, tokens): + tokens.insert(0, locn) + print(OneOrMore(Word(nums)).addParseAction(insert_locn).parseString("0 123 321")) # -> [0, '0', '123', '321'] + """ + self.__toklist.insert(index, insStr) + # fixup indices in token dictionary + 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 ): + """ + Add single element to end of ParseResults list of elements. + + Example:: + print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] + + # use a parse action to compute the sum of the parsed integers, and add it to the end + def append_sum(tokens): + tokens.append(sum(map(int, tokens))) + print(OneOrMore(Word(nums)).addParseAction(append_sum).parseString("0 123 321")) # -> ['0', '123', '321', 444] + """ + self.__toklist.append(item) + + def extend( self, itemseq ): + """ + Add sequence of elements to end of ParseResults list of elements. + + Example:: + patt = OneOrMore(Word(alphas)) + + # use a parse action to append the reverse of the matched strings, to make a palindrome + def make_palindrome(tokens): + tokens.extend(reversed([t[::-1] for t in tokens])) + return ''.join(tokens) + print(patt.addParseAction(make_palindrome).parseString("lskdj sdlkjf lksd")) # -> 'lskdjsdlkjflksddsklfjkldsjdksl' + """ + if isinstance(itemseq, ParseResults): + self += itemseq + else: + self.__toklist.extend(itemseq) + + def clear( self ): + """ + Clear all elements and results names. + """ + del self.__toklist[:] + self.__tokdict.clear() + + 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 ): + ret = self.copy() + ret += other + return ret + + def __iadd__( self, other ): + if other.__tokdict: + offset = len(self.__toklist) + 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: + self[k] = v + if isinstance(v[0],ParseResults): + v[0].__parent = wkref(self) + + self.__toklist += other.__toklist + self.__accumNames.update( other.__accumNames ) + return self + + def __radd__(self, other): + 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 __str__( self ): + return '[' + ', '.join(_ustr(i) if isinstance(i, ParseResults) else repr(i) for i in self.__toklist) + ']' + + def _asStringList( self, sep='' ): + out = [] + for item in self.__toklist: + if out and sep: + out.append(sep) + if isinstance( item, ParseResults ): + out += item._asStringList() + else: + out.append( _ustr(item) ) + return out + + def asList( self ): + """ + Returns the parse results as a nested list of matching tokens, all converted to strings. + + Example:: + patt = OneOrMore(Word(alphas)) + result = patt.parseString("sldkj lsdkj sldkj") + # even though the result prints in string-like form, it is actually a pyparsing ParseResults + print(type(result), result) # -> <class 'pyparsing.ParseResults'> ['sldkj', 'lsdkj', 'sldkj'] + + # Use asList() to create an actual list + 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] + + def asDict( self ): + """ + Returns the named parse results as a nested dictionary. + + Example:: + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + result = date_str.parseString('12/31/1999') + print(type(result), repr(result)) # -> <class 'pyparsing.ParseResults'> (['12', '/', '31', '/', '1999'], {'day': [('1999', 4)], 'year': [('12', 0)], 'month': [('31', 2)]}) + + result_dict = result.asDict() + print(type(result_dict), repr(result_dict)) # -> <class 'dict'> {'day': '1999', 'year': '12', 'month': '31'} + + # even though a ParseResults supports dict-like access, sometime you just need to have a dict + import json + print(json.dumps(result)) # -> Exception: TypeError: ... is not JSON serializable + print(json.dumps(result.asDict())) # -> {"month": "31", "day": "1999", "year": "12"} + """ + if PY_3: + item_fn = self.items + else: + item_fn = self.iteritems + + def toItem(obj): + if isinstance(obj, ParseResults): + if obj.haskeys(): + return obj.asDict() + else: + return [toItem(v) for v in obj] + else: + return obj + + return dict((k,toItem(v)) for k,v in item_fn()) + + def copy( self ): + """ + Returns a new copy of a C{ParseResults} object. + """ + ret = ParseResults( self.__toklist ) + ret.__tokdict = self.__tokdict.copy() + ret.__parent = self.__parent + ret.__accumNames.update( self.__accumNames ) + ret.__name = self.__name + return ret + + 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) + nextLevelIndent = indent + " " + + # collapse out indents if formatting is not desired + if not formatted: + indent = "" + nextLevelIndent = "" + nl = "" + + selfTag = None + if doctag is not None: + selfTag = doctag + else: + if self.__name: + selfTag = self.__name + + if not selfTag: + if namedItemsOnly: + return "" + else: + selfTag = "ITEM" + + out += [ nl, indent, "<", selfTag, ">" ] + + 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)] + else: + out += [ res.asXML(None, + namedItemsOnly and doctag is None, + nextLevelIndent, + formatted)] + else: + # individual token, see if there is a name for it + resTag = None + if i in namedItems: + resTag = namedItems[i] + if not resTag: + if namedItemsOnly: + continue + else: + resTag = "ITEM" + xmlBodyText = _xml_escape(_ustr(res)) + out += [ nl, nextLevelIndent, "<", resTag, ">", + xmlBodyText, + "</", resTag, ">" ] + + out += [ nl, indent, "</", selfTag, ">" ] + return "".join(out) + + def __lookup(self,sub): + for k,vlist in self.__tokdict.items(): + for v,loc in vlist: + if sub is v: + return k + return None + + def getName(self): + r""" + Returns the results name for this token expression. Useful when several + different expressions might match at a particular location. + + Example:: + integer = Word(nums) + ssn_expr = Regex(r"\d\d\d-\d\d-\d\d\d\d") + house_number_expr = Suppress('#') + Word(nums, alphanums) + user_data = (Group(house_number_expr)("house_number") + | Group(ssn_expr)("ssn") + | Group(integer)("age")) + user_info = OneOrMore(user_data) + + result = user_info.parseString("22 111-22-3333 #221B") + for item in result: + print(item.getName(), ':', item[0]) + prints:: + age : 22 + ssn : 111-22-3333 + house_number : 221B + """ + if self.__name: + return self.__name + elif self.__parent: + par = self.__parent() + if par: + 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)): + return next(iter(self.__tokdict.keys())) + else: + return None + + def dump(self, indent='', depth=0, full=True): + """ + Diagnostic method for listing out the contents of a C{ParseResults}. + Accepts an optional C{indent} argument so that this string can be embedded + in a nested display of other data. + + Example:: + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + result = date_str.parseString('12/31/1999') + print(result.dump()) + prints:: + ['12', '/', '31', '/', '1999'] + - day: 1999 + - month: 31 + - year: 12 + """ + out = [] + NL = '\n' + out.append( indent+_ustr(self.asList()) ) + if full: + if self.haskeys(): + 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): + if v: + out.append( v.dump(indent,depth+1) ) + else: + out.append(_ustr(v)) + else: + out.append(repr(v)) + 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) )) + else: + out.append("\n%s%s[%d]:\n%s%s%s" % (indent,(' '*(depth)),i,indent,(' '*(depth+1)),_ustr(vv))) + + return "".join(out) + + def pprint(self, *args, **kwargs): + """ + Pretty-printer for parsed results as a list, using the C{pprint} module. + Accepts additional positional or keyword args as defined for the + C{pprint.pprint} method. (U{http://docs.python.org/3/library/pprint.html#pprint.pprint}) + + Example:: + ident = Word(alphas, alphanums) + num = Word(nums) + func = Forward() + term = ident | num | Group('(' + func + ')') + func <<= ident + Group(Optional(delimitedList(term))) + result = func.parseString("fna a,b,(fnb c,d,200),100") + result.pprint(width=40) + prints:: + ['fna', + ['a', + 'b', + ['(', 'fnb', ['c', 'd', '200'], ')'], + '100']] + """ + pprint.pprint(self.asList(), *args, **kwargs) + + # 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 ) ) + + def __setstate__(self,state): + self.__toklist = state[0] + (self.__tokdict, + par, + inAccumNames, + self.__name) = state[1] + self.__accumNames = {} + self.__accumNames.update(inAccumNames) + if par is not None: + self.__parent = wkref(par) + else: + self.__parent = None + + def __getnewargs__(self): + return self.__toklist, self.__name, self.__asList, self.__modal + + def __dir__(self): + return (dir(type(self)) + list(self.keys())) + +MutableMapping.register(ParseResults) + +def col (loc,strg): + """Returns current column within a string, counting newlines as line separators. + The first column is number 1. + + Note: the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See L{I{ParserElement.parseString}<ParserElement.parseString>} for more information + on parsing strings containing C{<TAB>}s, and suggested methods to maintain a + consistent view of the parsed string, the parse 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) + +def lineno(loc,strg): + """Returns current line number within a string, counting newlines as line separators. + The first line is number 1. + + Note: the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See L{I{ParserElement.parseString}<ParserElement.parseString>} for more information + on parsing strings containing C{<TAB>}s, and 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 + +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] + else: + 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 _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 nullDebugAction(*args): + """'Do-nothing' debug action, to suppress debugging output during parsing.""" + pass + +# Only works on Python 3.x - nonlocal is toxic to Python 2 installs +#~ 'decorator to trim function calls to match the arity of the target' +#~ def _trim_arity(func, maxargs=3): + #~ if func in singleArgBuiltins: + #~ return lambda s,l,t: func(t) + #~ limit = 0 + #~ foundArity = False + #~ def wrapper(*args): + #~ nonlocal limit,foundArity + #~ while 1: + #~ try: + #~ ret = func(*args[limit:]) + #~ foundArity = True + #~ return ret + #~ except TypeError: + #~ if limit == maxargs or foundArity: + #~ raise + #~ limit += 1 + #~ continue + #~ return wrapper + +# this version is Python 2.x-3.x cross-compatible +'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) + limit = [0] + foundArity = [False] + + # traceback return data structure changed in Py3.5 - normalize back to plain tuples + 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] + return [frame_summary[:2]] + def extract_tb(tb, limit=0): + frames = traceback.extract_tb(tb, limit=limit) + frame_summary = frames[-1] + return [frame_summary[:2]] + else: + extract_stack = traceback.extract_stack + extract_tb = traceback.extract_tb + + # synthesize what would be returned by traceback.extract_stack at the call to + # user's parse action 'func', so that we don't incur call penalty at parse time + + LINE_DIFF = 6 + # 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) + + def wrapper(*args): + while 1: + try: + ret = func(*args[limit[0]:]) + foundArity[0] = True + return ret + except TypeError: + # re-raise TypeErrors if they did not come from our arity testing + if foundArity[0]: + raise + else: + try: + tb = sys.exc_info()[-1] + if not extract_tb(tb, limit=2)[-1][:2] == pa_call_line_synth: + raise + finally: + del tb + + if limit[0] <= maxargs: + limit[0] += 1 + continue + raise + + # copy func name to wrapper for sensible debug output + func_name = "<parse action>" + try: + func_name = getattr(func, '__name__', + getattr(func, '__class__').__name__) + except Exception: + func_name = str(func) + wrapper.__name__ = func_name + + return wrapper + +class ParserElement(object): + """Abstract base level parser element class.""" + DEFAULT_WHITE_CHARS = " \n\t\r" + verbose_stacktrace = False + + @staticmethod + def setDefaultWhitespaceChars( chars ): + r""" + Overrides the default whitespace chars + + Example:: + # default whitespace chars are space, <TAB> and newline + OneOrMore(Word(alphas)).parseString("abc def\nghi jkl") # -> ['abc', 'def', 'ghi', 'jkl'] + + # change to just treat newline as significant + ParserElement.setDefaultWhitespaceChars(" \t") + OneOrMore(Word(alphas)).parseString("abc def\nghi jkl") # -> ['abc', 'def'] + """ + ParserElement.DEFAULT_WHITE_CHARS = chars + + @staticmethod + def inlineLiteralsUsing(cls): + """ + Set class to be used for inclusion of string literals into a parser. + + Example:: + # default literal class used is Literal + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + date_str.parseString("1999/12/31") # -> ['1999', '/', '12', '/', '31'] + + + # change to Suppress + ParserElement.inlineLiteralsUsing(Suppress) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + date_str.parseString("1999/12/31") # -> ['1999', '12', '31'] + """ + ParserElement._literalStringClass = cls + + 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.strRepr = None + self.resultsName = None + self.saveAsList = savelist + self.skipWhitespace = True + self.whiteChars = ParserElement.DEFAULT_WHITE_CHARS + self.copyDefaultWhiteChars = True + self.mayReturnEmpty = False # used when checking for left-recursion + self.keepTabs = False + self.ignoreExprs = list() + self.debug = False + self.streamlined = False + 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.re = None + self.callPreparse = True # used to avoid redundant calls to preParse + self.callDuringTry = False + + def copy( self ): + """ + Make a copy of this C{ParserElement}. Useful for defining different parse actions + for the same parsing pattern, using copies of the original parse element. + + 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") + + print(OneOrMore(integerK | integerM | integer).parseString("5K 100 640K 256M")) + prints:: + [5120, 100, 655360, 268435456] + Equivalent form of C{expr.copy()} is just C{expr()}:: + integerM = integer().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M") + """ + 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 ): + """ + Define name for this expression, makes debugging and exception messages clearer. + + Example:: + Word(nums).parseString("ABC") # -> Exception: Expected W:(0123...) (at char 0), (line:1, col:1) + Word(nums).setName("integer").parseString("ABC") # -> Exception: Expected integer (at char 0), (line:1, col:1) + """ + self.name = name + self.errmsg = "Expected " + self.name + if hasattr(self,"exception"): + self.exception.msg = self.errmsg + return self + + def setResultsName( self, name, listAllMatches=False ): + """ + Define name for referencing matching tokens as a nested attribute + of the returned parse results. + NOTE: this returns a *copy* of the original C{ParserElement} object; + this is so that the client can define a basic element, such as an + integer, and reference it in multiple places with different names. + + You can also set results names using the abbreviated syntax, + C{expr("name")} in place of C{expr.setResultsName("name")} - + see L{I{__call__}<__call__>}. + + Example:: + date_str = (integer.setResultsName("year") + '/' + + integer.setResultsName("month") + '/' + + integer.setResultsName("day")) + + # equivalent form: + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + """ + newself = self.copy() + if name.endswith("*"): + name = name[:-1] + listAllMatches=True + newself.resultsName = name + newself.modalResults = not listAllMatches + return newself + + def setBreak(self,breakFlag = True): + """Method to invoke the Python pdb debugger when this element is + about to be parsed. Set C{breakFlag} to True to enable, False to + disable. + """ + if breakFlag: + _parseMethod = self._parse + def breaker(instring, loc, doActions=True, callPreParse=True): + import pdb + pdb.set_trace() + return _parseMethod( instring, loc, doActions, callPreParse ) + breaker._originalParseMethod = _parseMethod + self._parse = breaker + else: + if hasattr(self._parse,"_originalParseMethod"): + self._parse = self._parse._originalParseMethod + return self + + 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 C{fn(s,loc,toks)}, + C{fn(loc,toks)}, C{fn(toks)}, or just C{fn()}, where: + - s = the original string being parsed (see note below) + - loc = the location of the matching substring + - toks = a list of the matched tokens, packaged as a C{L{ParseResults}} object + If the functions in fns modify the tokens, they can return them as the return + value from fn, and the modified list of tokens will replace the original. + Otherwise, fn does not need to return any value. + + Optional keyword arguments: + - callDuringTry = (default=C{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 L{I{parseString}<parseString>} for more information + on parsing strings containing C{<TAB>}s, and suggested methods to maintain a + consistent view of the parsed string, the parse location, and line and column + positions within the parsed string. + + Example:: + integer = Word(nums) + date_str = integer + '/' + integer + '/' + integer + + date_str.parseString("1999/12/31") # -> ['1999', '/', '12', '/', '31'] + + # use parse action to convert to ints at parse time + integer = Word(nums).setParseAction(lambda toks: int(toks[0])) + date_str = integer + '/' + integer + '/' + integer + + # 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) + return self + + def addParseAction( self, *fns, **kwargs ): + """ + Add one or more parse actions to expression's list of parse actions. See L{I{setParseAction}<setParseAction>}. + + See examples in L{I{copy}<copy>}. + """ + self.parseAction += list(map(_trim_arity, list(fns))) + self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False) + return self + + def addCondition(self, *fns, **kwargs): + """Add a boolean predicate function to expression's list of parse actions. See + L{I{setParseAction}<setParseAction>} for function call signatures. Unlike C{setParseAction}, + functions passed to C{addCondition} need to return boolean success/fail of the condition. + + Optional keyword arguments: + - message = define a custom message to be used in the raised exception + - fatal = if True, will raise ParseFatalException to stop parsing immediately; otherwise will raise ParseException + + Example:: + integer = Word(nums).setParseAction(lambda toks: int(toks[0])) + year_int = integer.copy() + year_int.addCondition(lambda toks: toks[0] >= 2000, message="Only support years 2000 and later") + date_str = year_int + '/' + integer + '/' + integer + + 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: + def pa(s,l,t): + if not bool(_trim_arity(fn)(s,l,t)): + raise exc_type(s,l,msg) + self.parseAction.append(pa) + self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False) + return self + + 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 + C{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 + - err = the exception thrown + The function returns no value. It may throw C{L{ParseFatalException}} + if it is desired to stop parsing immediately.""" + self.failAction = fn + return self + + 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 ) + exprsFound = True + except ParseException: + pass + return loc + + def preParse( self, instring, loc ): + if self.ignoreExprs: + loc = self._skipIgnorables( instring, loc ) + + if self.skipWhitespace: + wt = self.whiteChars + instrlen = len(instring) + while loc < instrlen and instring[loc] in wt: + loc += 1 + + return loc + + def parseImpl( self, instring, loc, doActions=True ): + return loc, [] + + def postParse( self, instring, loc, tokenlist ): + return tokenlist + + #~ @profile + def _parseNoCache( self, instring, loc, doActions=True, callPreParse=True ): + 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 + 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 self.failAction: + self.failAction( instring, tokensStart, self, err ) + raise + else: + 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 ) + + tokens = self.postParse( instring, loc, tokens ) + + 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: + tokens = fn( instring, tokensStart, retTokens ) + if tokens is not None: + 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 ) + raise + else: + for fn in self.parseAction: + tokens = fn( instring, tokensStart, retTokens ) + if tokens is not None: + retTokens = ParseResults( tokens, + self.resultsName, + 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 ) + + return loc, retTokens + + def tryParse( self, instring, loc ): + try: + return self._parse( instring, loc, doActions=False )[0] + except ParseFatalException: + raise ParseException( instring, loc, self.errmsg, self) + + def canParseNext(self, instring, loc): + try: + self.tryParse(instring, loc) + except (ParseException, IndexError): + return False + else: + return True + + class _UnboundedCache(object): + def __init__(self): + cache = {} + self.not_in_cache = not_in_cache = object() + + def get(self, key): + return cache.get(key, not_in_cache) + + def set(self, key, value): + cache[key] = value + + def clear(self): + cache.clear() + + def cache_len(self): + return len(cache) + + self.get = types.MethodType(get, self) + self.set = types.MethodType(set, self) + self.clear = types.MethodType(clear, self) + self.__len__ = types.MethodType(cache_len, self) + + if _OrderedDict is not None: + class _FifoCache(object): + def __init__(self, size): + self.not_in_cache = not_in_cache = object() + + cache = _OrderedDict() + + def get(self, key): + return cache.get(key, not_in_cache) + + def set(self, key, value): + cache[key] = value + while len(cache) > size: + try: + cache.popitem(False) + except KeyError: + pass + + def clear(self): + cache.clear() + + def cache_len(self): + return len(cache) + + self.get = types.MethodType(get, self) + self.set = types.MethodType(set, self) + self.clear = types.MethodType(clear, self) + self.__len__ = types.MethodType(cache_len, self) + + else: + class _FifoCache(object): + def __init__(self, size): + self.not_in_cache = not_in_cache = object() + + cache = {} + key_fifo = collections.deque([], size) + + def get(self, key): + return cache.get(key, not_in_cache) + + def set(self, key, value): + cache[key] = value + while len(key_fifo) > size: + cache.pop(key_fifo.popleft(), None) + key_fifo.append(key) + + def clear(self): + cache.clear() + key_fifo.clear() + + def cache_len(self): + return len(cache) + + self.get = types.MethodType(get, self) + self.set = types.MethodType(set, self) + self.clear = types.MethodType(clear, self) + self.__len__ = types.MethodType(cache_len, self) + + # argument cache for optimizing repeated calls when backtracking through recursive expressions + packrat_cache = {} # this is set later by enabledPackrat(); this is here so that resetCache() doesn't fail + packrat_cache_lock = RLock() + packrat_cache_stats = [0, 0] + + # 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 ): + HIT, MISS = 0, 1 + lookup = (self, instring, loc, callPreParse, doActions) + with ParserElement.packrat_cache_lock: + cache = ParserElement.packrat_cache + value = cache.get(lookup) + if value is cache.not_in_cache: + ParserElement.packrat_cache_stats[MISS] += 1 + try: + value = self._parseNoCache(instring, loc, doActions, callPreParse) + except ParseBaseException as pe: + # cache a copy of the exception, without the traceback + cache.set(lookup, pe.__class__(*pe.args)) + raise + else: + cache.set(lookup, (value[0], value[1].copy())) + return value + else: + ParserElement.packrat_cache_stats[HIT] += 1 + if isinstance(value, Exception): + raise value + return (value[0], value[1].copy()) + + _parse = _parseNoCache + + @staticmethod + def resetCache(): + ParserElement.packrat_cache.clear() + ParserElement.packrat_cache_stats[:] = [0] * len(ParserElement.packrat_cache_stats) + + _packratEnabled = False + @staticmethod + def enablePackrat(cache_size_limit=128): + """Enables "packrat" parsing, which adds memoizing to the parsing logic. + Repeated parse attempts at the same string location (which happens + often in many complex grammars) can immediately return a cached value, + instead of re-executing parsing/validating code. Memoizing is done of + both valid results and parsing exceptions. + + Parameters: + - cache_size_limit - (default=C{128}) - if an integer value is provided + will limit the size of the packrat cache; if None is passed, then + the cache size will be unbounded; if 0 is passed, the cache will + be effectively disabled. + + This speedup may break existing programs that use parse actions that + have side-effects. For this reason, packrat parsing is disabled when + you first import pyparsing. To activate the packrat feature, your + program must call the class method C{ParserElement.enablePackrat()}. If + your program uses C{psyco} to "compile as you go", you must call + C{enablePackrat} before calling C{psyco.full()}. If you do not do this, + Python will crash. For best results, call C{enablePackrat()} immediately + after importing pyparsing. + + Example:: + from pip._vendor import pyparsing + pyparsing.ParserElement.enablePackrat() + """ + if not ParserElement._packratEnabled: + ParserElement._packratEnabled = True + if cache_size_limit is None: + ParserElement.packrat_cache = ParserElement._UnboundedCache() + else: + ParserElement.packrat_cache = ParserElement._FifoCache(cache_size_limit) + ParserElement._parse = ParserElement._parseCache + + 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. + + If you want the grammar to require that the entire input string be + successfully parsed, then set C{parseAll} to True (equivalent to ending + the grammar with C{L{StringEnd()}}). + + Note: C{parseString} implicitly calls C{expandtabs()} on the input string, + in order to report proper column numbers in parse actions. + If the input string contains tabs and + the grammar uses parse actions that use the C{loc} argument to index into the + string being parsed, you can ensure you have a consistent view of the input + string by: + - calling C{parseWithTabs} on your grammar before calling C{parseString} + (see L{I{parseWithTabs}<parseWithTabs>}) + - define your parse action using the full C{(s,loc,toks)} signature, and + reference the input string using the parse action's C{s} argument + - explictly expand the tabs in your input string before calling + C{parseString} + + Example:: + Word('a').parseString('aaaaabaaa') # -> ['aaaaa'] + Word('a').parseString('aaaaabaaa', parseAll=True) # -> Exception: Expected end of text + """ + ParserElement.resetCache() + if not self.streamlined: + self.streamline() + #~ self.saveAsList = True + for e in self.ignoreExprs: + e.streamline() + if not self.keepTabs: + instring = instring.expandtabs() + try: + loc, tokens = self._parse( instring, 0 ) + if parseAll: + loc = self.preParse( instring, loc ) + se = Empty() + StringEnd() + 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 + raise exc + else: + return tokens + + 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 + C{maxMatches} argument, to clip scanning after 'n' matches are found. If + C{overlap} is specified, then overlapping matches will be reported. + + Note that the start and end locations are reported relative to the string + being parsed. See L{I{parseString}<parseString>} for more information on parsing + strings with embedded tabs. + + Example:: + source = "sldjf123lsdjjkf345sldkjf879lkjsfd987" + print(source) + for tokens,start,end in Word(alphas).scanString(source): + print(' '*start + '^'*(end-start)) + print(' '*start + tokens[0]) + + prints:: + + sldjf123lsdjjkf345sldkjf879lkjsfd987 + ^^^^^ + sldjf + ^^^^^^^ + lsdjjkf + ^^^^^^ + sldkjf + ^^^^^^ + lkjsfd + """ + if not self.streamlined: + self.streamline() + for e in self.ignoreExprs: + e.streamline() + + if not self.keepTabs: + instring = _ustr(instring).expandtabs() + instrlen = len(instring) + loc = 0 + preparseFn = self.preParse + parseFn = self._parse + ParserElement.resetCache() + matches = 0 + try: + while loc <= instrlen and matches < maxMatches: + try: + preloc = preparseFn( instring, loc ) + nextLoc,tokens = parseFn( instring, preloc, callPreParse=False ) + except ParseException: + loc = preloc+1 + else: + if nextLoc > loc: + matches += 1 + yield tokens, preloc, nextLoc + if overlap: + nextloc = preparseFn( instring, loc ) + if nextloc > loc: + loc = nextLoc + else: + loc += 1 + else: + loc = nextLoc + else: + 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 + raise exc + + def transformString( self, instring ): + """ + Extension to C{L{scanString}}, to modify matching text with modified tokens that may + be returned from a parse action. To use C{transformString}, define a grammar and + attach a parse action to it that modifies the returned token list. + Invoking C{transformString()} on a target string will then scan for matches, + and replace the matched text patterns according to the logic in the parse + action. C{transformString()} returns the resulting transformed string. + + Example:: + wd = Word(alphas) + wd.setParseAction(lambda toks: toks[0].title()) + + print(wd.transformString("now is the winter of our discontent made glorious summer by this sun of york.")) + Prints:: + Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York. + """ + out = [] + lastE = 0 + # force preservation of <TAB>s, to minimize unwanted transformation of string, and to + # 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] ) + if t: + if isinstance(t,ParseResults): + out += t.asList() + 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))) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def searchString( self, instring, maxMatches=_MAX_INT ): + """ + Another extension to C{L{scanString}}, simplifying the access to the tokens found + to match the given parse expression. May be called with optional + C{maxMatches} argument, to clip searching after 'n' matches are found. + + Example:: + # a capitalized word starts with an uppercase letter, followed by zero or more lowercase letters + cap_word = Word(alphas.upper(), alphas.lower()) + + print(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity")) + + # the sum() builtin can be used to merge results into a single ParseResults object + print(sum(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity"))) + prints:: + [['More'], ['Iron'], ['Lead'], ['Gold'], ['I'], ['Electricity']] + ['More', 'Iron', 'Lead', 'Gold', 'I', 'Electricity'] + """ + try: + 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 + raise exc + + def split(self, instring, maxsplit=_MAX_INT, includeSeparators=False): + """ + Generator method to split a string using the given expression as a separator. + May be called with optional C{maxsplit} argument, to limit the number of splits; + and the optional C{includeSeparators} argument (default=C{False}), if the separating + matching text should be included in the split results. + + Example:: + punc = oneOf(list(".,;:/-!?")) + print(list(punc.split("This, this?, this sentence, is badly punctuated!"))) + prints:: + ['This', ' this', '', ' this sentence', ' is badly punctuated', ''] + """ + splits = 0 + last = 0 + 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 ): + """ + Implementation of + operator - returns C{L{And}}. Adding strings to a ParserElement + converts them to L{Literal}s by default. + + Example:: + greet = Word(alphas) + "," + Word(alphas) + "!" + hello = "Hello, World!" + print (hello, "->", greet.parseString(hello)) + 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 ): + """ + Implementation of + operator when left operand is not a C{L{ParserElement}} + """ + 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 other + self + + def __sub__(self, other): + """ + Implementation of - operator, returns C{L{And}} with error stop + """ + 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 self + And._ErrorStop() + other + + def __rsub__(self, other ): + """ + Implementation of - operator when left operand is not a C{L{ParserElement}} + """ + 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 other - self + + def __mul__(self,other): + """ + Implementation of * operator, allows use of C{expr * 3} in place of + C{expr + expr + expr}. Expressions may also me multiplied by a 2-integer + tuple, similar to C{{min,max}} multipliers in regular expressions. Tuples + may also include C{None} as in: + - C{expr*(n,None)} or C{expr*(n,)} is equivalent + to C{expr*n + L{ZeroOrMore}(expr)} + (read as "at least n instances of C{expr}") + - C{expr*(None,n)} is equivalent to C{expr*(0,n)} + (read as "0 to n instances of C{expr}") + - C{expr*(None,None)} is equivalent to C{L{ZeroOrMore}(expr)} + - C{expr*(1,None)} is equivalent to C{L{OneOrMore}(expr)} + + Note that C{expr*(None,n)} does not raise an exception if + more than n exprs exist in the input stream; that is, + C{expr*(None,n)} does not enforce a maximum number of expr + occurrences. If this behavior is desired, then write + C{expr*(None,n) + ~expr} + """ + if isinstance(other,int): + minElements, optElements = other,0 + elif isinstance(other,tuple): + 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 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): + minElements, optElements = other + optElements -= minElements + else: + 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)) + + if minElements < 0: + raise ValueError("cannot multiply ParserElement by negative value") + 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)") + + if (optElements): + def makeOptionalList(n): + 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) + else: + ret = makeOptionalList(optElements) + else: + if minElements == 1: + ret = self + else: + ret = And([self]*minElements) + return ret + + def __rmul__(self, other): + return self.__mul__(other) + + def __or__(self, other ): + """ + Implementation of | operator - returns C{L{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 ] ) + + def __ror__(self, other ): + """ + Implementation of | operator when left operand is not a C{L{ParserElement}} + """ + 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 other | self + + def __xor__(self, other ): + """ + Implementation of ^ operator - returns C{L{Or}} + """ + 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 Or( [ self, other ] ) + + def __rxor__(self, other ): + """ + Implementation of ^ operator when left operand is not a C{L{ParserElement}} + """ + 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 other ^ self + + def __and__(self, other ): + """ + Implementation of & operator - returns C{L{Each}} + """ + 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 Each( [ self, other ] ) + + def __rand__(self, other ): + """ + Implementation of & operator when left operand is not a C{L{ParserElement}} + """ + 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 other & self + + def __invert__( self ): + """ + Implementation of ~ operator - returns C{L{NotAny}} + """ + return NotAny( self ) + + def __call__(self, name=None): + """ + Shortcut for C{L{setResultsName}}, with C{listAllMatches=False}. + + If C{name} is given with a trailing C{'*'} character, then C{listAllMatches} will be + passed as C{True}. + + If C{name} is omitted, same as calling C{L{copy}}. + + Example:: + # these are equivalent + 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) + else: + return self.copy() + + def suppress( self ): + """ + Suppresses the output of this C{ParserElement}; useful to keep punctuation from + cluttering up returned output. + """ + return Suppress( self ) + + def leaveWhitespace( self ): + """ + Disables the skipping of whitespace before matching the characters in the + C{ParserElement}'s defined pattern. This is normally only used internally by + the pyparsing module, but may be needed in some whitespace-sensitive grammars. + """ + self.skipWhitespace = False + return self + + def setWhitespaceChars( self, chars ): + """ + Overrides the default whitespace chars + """ + self.skipWhitespace = True + self.whiteChars = chars + self.copyDefaultWhiteChars = False + return self + + def parseWithTabs( self ): + """ + Overrides default behavior to expand C{<TAB>}s to spaces before parsing the input string. + Must be called before C{parseString} when the input grammar contains elements that + match C{<TAB>} characters. + """ + self.keepTabs = True + return self + + 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 + ignorable patterns. + + Example:: + patt = OneOrMore(Word(alphas)) + patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj'] + + patt.ignore(cStyleComment) + patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj', 'lskjd'] + """ + if isinstance(other, basestring): + other = Suppress(other) + + if isinstance( other, Suppress ): + if other not in self.ignoreExprs: + self.ignoreExprs.append(other) + else: + self.ignoreExprs.append( Suppress( other.copy() ) ) + return self + + def setDebugActions( self, startAction, successAction, exceptionAction ): + """ + Enable display of debugging messages while doing pattern matching. + """ + self.debugActions = (startAction or _defaultStartDebugAction, + successAction or _defaultSuccessDebugAction, + exceptionAction or _defaultExceptionDebugAction) + self.debug = True + return self + + def setDebug( self, flag=True ): + """ + Enable display of debugging messages while doing pattern matching. + Set C{flag} to True to enable, False to disable. + + Example:: + wd = Word(alphas).setName("alphaword") + integer = Word(nums).setName("numword") + term = wd | integer + + # turn on debugging for wd + wd.setDebug() + + OneOrMore(term).parseString("abc 123 xyz 890") + + prints:: + Match alphaword at loc 0(1,1) + Matched alphaword -> ['abc'] + Match alphaword at loc 3(1,4) + Exception raised:Expected alphaword (at char 4), (line:1, col:5) + Match alphaword at loc 7(1,8) + Matched alphaword -> ['xyz'] + Match alphaword at loc 11(1,12) + Exception raised:Expected alphaword (at char 12), (line:1, col:13) + Match alphaword at loc 15(1,16) + Exception raised:Expected alphaword (at char 15), (line:1, col:16) + + The output shown is that produced by the default debug actions - custom debug actions can be + specified using L{setDebugActions}. Prior to attempting + to match the C{wd} expression, the debugging message C{"Match <exprname> at loc <n>(<line>,<col>)"} + is shown. Then if the parse succeeds, a C{"Matched"} message is shown, or an C{"Exception raised"} + message is shown. Also note the use of L{setName} to assign a human-readable name to the expression, + which makes debugging and exception messages easier to understand - for instance, the default + name created for the C{Word} expression without calling C{setName} is C{"W:(ABCD...)"}. + """ + if flag: + self.setDebugActions( _defaultStartDebugAction, _defaultSuccessDebugAction, _defaultExceptionDebugAction ) + else: + self.debug = False + return self + + def __str__( self ): + return self.name + + def __repr__( self ): + return _ustr(self) + + def streamline( self ): + self.streamlined = True + self.strRepr = None + return self + + def checkRecursion( self, parseElementList ): + pass + + def validate( self, validateTrace=[] ): + """ + Check defined expressions for valid structure, check for infinite recursive definitions. + """ + self.checkRecursion( [] ) + + 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), + the entire file is opened, read, and closed before parsing. + """ + try: + file_contents = file_or_filename.read() + except AttributeError: + with open(file_or_filename, "r") as f: + file_contents = f.read() + try: + return self.parseString(file_contents, parseAll) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def __eq__(self,other): + if isinstance(other, ParserElement): + return self is other or vars(self) == vars(other) + elif isinstance(other, basestring): + return self.matches(other) + else: + return super(ParserElement,self)==other + + def __ne__(self,other): + return not (self == other) + + def __hash__(self): + return hash(id(self)) + + def __req__(self,other): + return self == other + + def __rne__(self,other): + return not (self == other) + + def matches(self, testString, parseAll=True): + """ + Method for quick testing of a parser against a test string. Good for simple + inline microtests of sub expressions while building up larger parser. + + Parameters: + - testString - to test against this expression for a match + - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests + + Example:: + expr = Word(nums) + assert expr.matches("100") + """ + try: + self.parseString(_ustr(testString), parseAll=parseAll) + return True + except ParseBaseException: + return False + + def runTests(self, tests, parseAll=True, comment='#', fullDump=True, printResults=True, failureTests=False): + """ + 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 + run a parse expression against a list of sample strings. + + Parameters: + - tests - a list of separate test strings, or a multiline string of test strings + - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests + - comment - (default=C{'#'}) - expression for indicating embedded comments in the test + string; pass None to disable comment filtering + - fullDump - (default=C{True}) - dump results as list followed by results names in nested outline; + if False, only dump nested list + - printResults - (default=C{True}) prints test output to stdout + - failureTests - (default=C{False}) indicates if these tests are expected to fail parsing + + Returns: a (success, results) tuple, where success indicates that all tests succeeded + (or failed if C{failureTests} is True), and the results contain a list of lines of each + test's output + + Example:: + number_expr = pyparsing_common.number.copy() + + result = number_expr.runTests(''' + # unsigned integer + 100 + # negative integer + -100 + # float with scientific notation + 6.02e23 + # integer with scientific notation + 1e-12 + ''') + print("Success" if result[0] else "Failed!") + + result = number_expr.runTests(''' + # stray character + 100Z + # missing leading digit before '.' + -.100 + # too many '.' + 3.14.159 + ''', failureTests=True) + print("Success" if result[0] else "Failed!") + prints:: + # unsigned integer + 100 + [100] + + # negative integer + -100 + [-100] + + # float with scientific notation + 6.02e23 + [6.02e+23] + + # integer with scientific notation + 1e-12 + [1e-12] + + Success + + # stray character + 100Z + ^ + FAIL: Expected end of text (at char 3), (line:1, col:4) + + # missing leading digit before '.' + -.100 + ^ + FAIL: Expected {real number with scientific notation | real number | signed integer} (at char 0), (line:1, col:1) + + # too many '.' + 3.14.159 + ^ + FAIL: Expected end of text (at char 4), (line:1, col:5) + + Success + + Each test string must be on a single line. If you want to test a string that spans multiple + lines, create a test like this:: + + expr.runTest(r"this is a test\\n of strings that spans \\n 3 lines") + + (Note that this is a raw string literal, you must include the leading 'r'.) + """ + if isinstance(tests, basestring): + tests = list(map(str.strip, tests.rstrip().splitlines())) + if isinstance(comment, basestring): + comment = Literal(comment) + allResults = [] + comments = [] + success = True + 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] + comments = [] + try: + t = t.replace(r'\n','\n') + result = self.parseString(t, parseAll=parseAll) + out.append(result.dump(full=fullDump)) + success = success and not failureTests + 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) + else: + out.append(' '*pe.loc + '^' + fatal) + out.append("FAIL: " + str(pe)) + success = success and failureTests + result = pe + except Exception as exc: + out.append("FAIL-EXCEPTION: " + str(exc)) + success = success and failureTests + result = exc + + if printResults: + if fullDump: + out.append('') + print('\n'.join(out)) + + allResults.append((t, result)) + + return success, allResults + + +class Token(ParserElement): + """ + Abstract C{ParserElement} subclass, for defining atomic matching patterns. + """ + 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__() + self.name = "Empty" + self.mayReturnEmpty = True + self.mayIndexError = False + + +class NoMatch(Token): + """ + A token that will never match. + """ + 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 ): + raise ParseException(instring, loc, self.errmsg, self) + + +class Literal(Token): + """ + Token to exactly match a specified string. + + Example:: + Literal('blah').parseString('blah') # -> ['blah'] + Literal('blah').parseString('blahfooblah') # -> ['blah'] + Literal('blah').parseString('bla') # -> Exception: Expected "blah" + + For case-insensitive matching, use L{CaselessLiteral}. + + For keyword matching (force word break before and after the matched string), + use L{Keyword} or L{CaselessKeyword}. + """ + def __init__( self, matchString ): + super(Literal,self).__init__() + self.match = matchString + self.matchLen = len(matchString) + try: + self.firstMatchChar = matchString[0] + except IndexError: + warnings.warn("null string passed to Literal; use Empty() instead", + SyntaxWarning, stacklevel=2) + self.__class__ = Empty + self.name = '"%s"' % _ustr(self.match) + self.errmsg = "Expected " + self.name + 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 + raise ParseException(instring, loc, self.errmsg, self) +_L = Literal +ParserElement._literalStringClass = Literal + +class Keyword(Token): + """ + Token to exactly match a specified string as a keyword, that is, it must be + immediately followed by a non-keyword character. Compare with C{L{Literal}}: + - C{Literal("if")} will match the leading C{'if'} in C{'ifAndOnlyIf'}. + - C{Keyword("if")} will not; it will only match the leading C{'if'} in C{'if x=1'}, or C{'if(y==2)'} + Accepts two optional constructor arguments in addition to the keyword string: + - C{identChars} is a string of characters that would be valid identifier characters, + defaulting to all alphanumerics + "_" and "$" + - C{caseless} allows case-insensitive matching, default is C{False}. + + Example:: + Keyword("start").parseString("start") # -> ['start'] + Keyword("start").parseString("starting") # -> Exception + + For case-insensitive matching, use L{CaselessKeyword}. + """ + DEFAULT_KEYWORD_CHARS = alphanums+"_$" + + def __init__( self, matchString, identChars=None, caseless=False ): + super(Keyword,self).__init__() + if identChars is None: + identChars = Keyword.DEFAULT_KEYWORD_CHARS + self.match = matchString + self.matchLen = len(matchString) + try: + self.firstMatchChar = matchString[0] + except IndexError: + warnings.warn("null string passed to Keyword; use Empty() instead", + SyntaxWarning, stacklevel=2) + self.name = '"%s"' % self.match + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = False + self.mayIndexError = False + self.caseless = caseless + if caseless: + self.caselessmatch = matchString.upper() + identChars = identChars.upper() + self.identChars = set(identChars) + + 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 + 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 + raise ParseException(instring, loc, self.errmsg, self) + + def copy(self): + c = super(Keyword,self).copy() + c.identChars = Keyword.DEFAULT_KEYWORD_CHARS + return c + + @staticmethod + def setDefaultKeywordChars( chars ): + """Overrides the default Keyword chars + """ + Keyword.DEFAULT_KEYWORD_CHARS = chars + +class CaselessLiteral(Literal): + """ + Token to match a specified string, ignoring case of letters. + Note: the matched results will always be in the case of the given + match string, NOT the case of the input text. + + Example:: + OneOrMore(CaselessLiteral("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD', 'CMD'] + + (Contrast with example for L{CaselessKeyword}.) + """ + 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 + raise ParseException(instring, loc, self.errmsg, self) + +class CaselessKeyword(Keyword): + """ + Caseless version of L{Keyword}. + + Example:: + OneOrMore(CaselessKeyword("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD'] + + (Contrast with example for L{CaselessLiteral}.) + """ + def __init__( self, matchString, identChars=None ): + super(CaselessKeyword,self).__init__( matchString, identChars, caseless=True ) + + def parseImpl( self, instring, loc, doActions=True ): + 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) ): + return loc+self.matchLen, self.match + raise ParseException(instring, loc, self.errmsg, self) + +class CloseMatch(Token): + """ + A variation on L{Literal} which matches "close" matches, that is, + strings with at most 'n' mismatching characters. C{CloseMatch} takes parameters: + - C{match_string} - string to be matched + - C{maxMismatches} - (C{default=1}) maximum number of mismatches allowed to count as a match + + The results from a successful parse will contain the matched text from the input string and the following named results: + - C{mismatches} - a list of the positions within the match_string where mismatches were found + - C{original} - the original match_string used to compare against the input string + + If C{mismatches} is an empty list, then the match was an exact match. + + Example:: + patt = CloseMatch("ATCATCGAATGGA") + patt.parseString("ATCATCGAAXGGA") # -> (['ATCATCGAAXGGA'], {'mismatches': [[9]], 'original': ['ATCATCGAATGGA']}) + patt.parseString("ATCAXCGAAXGGA") # -> Exception: Expected 'ATCATCGAATGGA' (with up to 1 mismatches) (at char 0), (line:1, col:1) + + # exact match + patt.parseString("ATCATCGAATGGA") # -> (['ATCATCGAATGGA'], {'mismatches': [[]], 'original': ['ATCATCGAATGGA']}) + + # close match allowing up to 2 mismatches + patt = CloseMatch("ATCATCGAATGGA", maxMismatches=2) + patt.parseString("ATCAXCGAAXGGA") # -> (['ATCAXCGAAXGGA'], {'mismatches': [[4, 9]], 'original': ['ATCATCGAATGGA']}) + """ + def __init__(self, match_string, maxMismatches=1): + super(CloseMatch,self).__init__() + self.name = match_string + self.match_string = match_string + self.maxMismatches = maxMismatches + self.errmsg = "Expected %r (with up to %d mismatches)" % (self.match_string, self.maxMismatches) + self.mayIndexError = False + self.mayReturnEmpty = False + + def parseImpl( self, instring, loc, doActions=True ): + start = loc + instrlen = len(instring) + maxloc = start + len(self.match_string) + + if maxloc <= instrlen: + match_string = self.match_string + match_stringloc = 0 + mismatches = [] + maxMismatches = self.maxMismatches + + for match_stringloc,s_m in enumerate(zip(instring[loc:maxloc], self.match_string)): + src,mat = s_m + if src != mat: + mismatches.append(match_stringloc) + if len(mismatches) > maxMismatches: + break + else: + loc = match_stringloc + 1 + results = ParseResults([instring[start:loc]]) + results['original'] = self.match_string + results['mismatches'] = mismatches + return loc, results + + raise ParseException(instring, loc, self.errmsg, self) + + +class Word(Token): + """ + Token for matching words composed of allowed character sets. + Defined with string containing all allowed initial characters, + an optional string containing allowed body characters (if omitted, + defaults to the initial character set), and an optional minimum, + maximum, and/or exact length. The default value for C{min} is 1 (a + minimum value < 1 is not valid); the default values for C{max} and C{exact} + are 0, meaning no maximum or exact length restriction. An optional + C{excludeChars} parameter can list characters that might be found in + the input C{bodyChars} string; useful to define a word of all printables + except for one or two characters, for instance. + + L{srange} is useful for defining custom character set strings for defining + C{Word} expressions, using range notation from regular expression character sets. + + A common mistake is to use C{Word} to match a specific literal string, as in + C{Word("Address")}. Remember that C{Word} uses the string argument to define + I{sets} of matchable characters. This expression would match "Add", "AAA", + "dAred", or any other word made up of the characters 'A', 'd', 'r', 'e', and 's'. + To match an exact literal string, use L{Literal} or L{Keyword}. + + pyparsing includes helper strings for building Words: + - L{alphas} + - L{nums} + - L{alphanums} + - L{hexnums} + - L{alphas8bit} (alphabetic characters in ASCII range 128-255 - accented, tilded, umlauted, etc.) + - L{punc8bit} (non-alphabetic characters in ASCII range 128-255 - currency, symbols, superscripts, diacriticals, etc.) + - L{printables} (any non-whitespace character) + + Example:: + # a word composed of digits + integer = Word(nums) # equivalent to Word("0123456789") or Word(srange("0-9")) + + # a word with a leading capital, and zero or more lowercase + capital_word = Word(alphas.upper(), alphas.lower()) + + # hostnames are alphanumeric, with leading alpha, and '-' + hostname = Word(alphas, alphanums+'-') + + # roman numeral (not a strict parser, accepts invalid mix of characters) + roman = Word("IVXLCDM") + + # 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__() + if excludeChars: + initChars = ''.join(c for c in initChars if c not in excludeChars) + if bodyChars: + bodyChars = ''.join(c for c in bodyChars if c not in excludeChars) + self.initCharsOrig = initChars + self.initChars = set(initChars) + if bodyChars : + self.bodyCharsOrig = bodyChars + self.bodyChars = set(bodyChars) + else: + self.bodyCharsOrig = initChars + self.bodyChars = set(initChars) + + self.maxSpecified = max > 0 + + if min < 1: + raise ValueError("cannot specify a minimum length < 1; use Optional(Word()) if zero-length word is permitted") + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayIndexError = False + self.asKeyword = asKeyword + + 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),) + else: + self.reString = "[%s][%s]*" % \ + (_escapeRegexRangeChars(self.initCharsOrig), + _escapeRegexRangeChars(self.bodyCharsOrig),) + if self.asKeyword: + self.reString = r"\b"+self.reString+r"\b" + try: + self.re = re.compile( self.reString ) + except Exception: + self.re = None + + 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() + + if not(instring[ loc ] in self.initChars): + raise ParseException(instring, loc, self.errmsg, self) + + start = loc + loc += 1 + instrlen = len(instring) + bodychars = self.bodyChars + maxloc = start + self.maxLen + maxloc = min( maxloc, instrlen ) + while loc < maxloc and instring[loc] in bodychars: + loc += 1 + + throwException = False + if loc - start < self.minLen: + throwException = True + if self.maxSpecified and loc < instrlen and instring[loc] in bodychars: + throwException = True + if self.asKeyword: + if (start>0 and instring[start-1] in bodychars) or (loc<instrlen and instring[loc] in bodychars): + throwException = True + + if throwException: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + def __str__( self ): + try: + return super(Word,self).__str__() + except Exception: + pass + + + if self.strRepr is None: + + def charsAsStr(s): + 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) ) + else: + self.strRepr = "W:(%s)" % charsAsStr(self.initCharsOrig) + + return self.strRepr + + +class Regex(Token): + r""" + Token for matching strings that match a given regular expression. + Defined with string specifying the regular expression in a form recognized by the inbuilt Python re module. + If the given regex contains named groups (defined using C{(?P<name>...)}), these will be preserved as + named parse results. + + Example:: + realnum = Regex(r"[+-]?\d+\.\d*") + date = Regex(r'(?P<year>\d{4})-(?P<month>\d\d?)-(?P<day>\d\d?)') + # ref: http://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?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})") + """ + compiledREtype = type(re.compile("[A-Z]")) + def __init__( self, pattern, flags=0): + """The parameters C{pattern} and C{flags} are passed to the C{re.compile()} function as-is. See the Python C{re} module for an explanation of the acceptable patterns and flags.""" + super(Regex,self).__init__() + + if isinstance(pattern, basestring): + if not pattern: + warnings.warn("null string passed to Regex; use Empty() instead", + SyntaxWarning, stacklevel=2) + + self.pattern = pattern + self.flags = flags + + try: + self.re = re.compile(self.pattern, self.flags) + self.reString = self.pattern + except sre_constants.error: + warnings.warn("invalid pattern (%s) passed to Regex" % pattern, + SyntaxWarning, stacklevel=2) + raise + + elif isinstance(pattern, Regex.compiledREtype): + self.re = pattern + self.pattern = \ + self.reString = str(pattern) + self.flags = flags + + else: + raise ValueError("Regex may only be constructed with a string or a compiled RE object") + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayIndexError = False + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + result = self.re.match(instring,loc) + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + d = result.groupdict() + ret = ParseResults(result.group()) + if d: + for k in d: + ret[k] = d[k] + return loc,ret + + def __str__( self ): + try: + return super(Regex,self).__str__() + except Exception: + pass + + if self.strRepr is None: + self.strRepr = "Re:(%s)" % repr(self.pattern) + + return self.strRepr + + +class QuotedString(Token): + r""" + Token for matching strings that are delimited by quoting characters. + + Defined with the following parameters: + - quoteChar - string of one or more characters defining the quote delimiting string + - escChar - character to escape quotes, typically backslash (default=C{None}) + - escQuote - special quote sequence to escape an embedded quote string (such as SQL's "" to escape an embedded ") (default=C{None}) + - multiline - boolean indicating whether quotes can span multiple lines (default=C{False}) + - unquoteResults - boolean indicating whether the matched text should be unquoted (default=C{True}) + - endQuoteChar - string of one or more characters defining the end of the quote delimited string (default=C{None} => same as quoteChar) + - convertWhitespaceEscapes - convert escaped whitespace (C{'\t'}, C{'\n'}, etc.) to actual whitespace (default=C{True}) + + Example:: + qs = QuotedString('"') + print(qs.searchString('lsjdf "This is the quote" sldjf')) + complex_qs = QuotedString('{{', endQuoteChar='}}') + print(complex_qs.searchString('lsjdf {{This is the "quote"}} sldjf')) + sql_qs = QuotedString('"', escQuote='""') + print(sql_qs.searchString('lsjdf "This is the quote with ""embedded"" quotes" sldjf')) + prints:: + [['This is the quote']] + [['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__() + + # 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) + raise SyntaxError() + + if endQuoteChar is None: + endQuoteChar = quoteChar + else: + endQuoteChar = endQuoteChar.strip() + if not endQuoteChar: + warnings.warn("endQuoteChar cannot be the empty string",SyntaxWarning,stacklevel=2) + raise SyntaxError() + + self.quoteChar = quoteChar + self.quoteCharLen = len(quoteChar) + self.firstQuoteChar = quoteChar[0] + self.endQuoteChar = endQuoteChar + self.endQuoteCharLen = len(endQuoteChar) + self.escChar = escChar + self.escQuote = escQuote + self.unquoteResults = unquoteResults + self.convertWhitespaceEscapes = convertWhitespaceEscapes + + 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 '') ) + 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 '') ) + 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)) + ')' + ) + 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.pattern += (r')*%s' % re.escape(self.endQuoteChar)) + + try: + self.re = re.compile(self.pattern, self.flags) + self.reString = self.pattern + except sre_constants.error: + warnings.warn("invalid pattern (%s) passed to Regex" % self.pattern, + SyntaxWarning, stacklevel=2) + raise + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + 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 + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + ret = result.group() + + if self.unquoteResults: + + # strip off quotes + ret = ret[self.quoteCharLen:-self.endQuoteCharLen] + + 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', + } + for wslit,wschar in ws_map.items(): + ret = ret.replace(wslit, wschar) + + # replace escaped characters + if self.escChar: + ret = re.sub(self.escCharReplacePattern, r"\g<1>", ret) + + # replace escaped quotes + if self.escQuote: + ret = ret.replace(self.escQuote, self.endQuoteChar) + + return loc, ret + + def __str__( self ): + try: + return super(QuotedString,self).__str__() + except Exception: + pass + + if self.strRepr is None: + self.strRepr = "quoted string, starting with %s ending with %s" % (self.quoteChar, self.endQuoteChar) + + return self.strRepr + + +class CharsNotIn(Token): + """ + Token for matching words composed of characters I{not} in a given set (will + include whitespace in matched characters if not listed in the provided exclusion set - see example). + Defined with string containing all disallowed characters, and an optional + minimum, maximum, and/or exact length. The default value for C{min} is 1 (a + minimum value < 1 is not valid); the default values for C{max} and C{exact} + are 0, meaning no maximum or exact length restriction. + + Example:: + # define a comma-separated-value as anything that is not a ',' + csv_value = CharsNotIn(',') + print(delimitedList(csv_value).parseString("dkls,lsdkjf,s12 34,@!#,213")) + prints:: + ['dkls', 'lsdkjf', 's12 34', '@!#', '213'] + """ + 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") + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = ( self.minLen == 0 ) + self.mayIndexError = False + + 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): + loc += 1 + + if loc - start < self.minLen: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + def __str__( self ): + try: + return super(CharsNotIn, self).__str__() + except Exception: + pass + + if self.strRepr is None: + if len(self.notChars) > 4: + self.strRepr = "!W:(%s...)" % self.notChars[:4] + else: + self.strRepr = "!W:(%s)" % self.notChars + + return self.strRepr + +class White(Token): + """ + Special matching class for matching whitespace. Normally, whitespace is ignored + by pyparsing grammars. This class is included when some whitespace structures + are significant. Define with a string containing the whitespace characters to be + matched; default is C{" \\t\\r\\n"}. Also takes optional C{min}, C{max}, and C{exact} arguments, + as defined for the C{L{Word}} class. + """ + whiteStrs = { + " " : "<SPC>", + "\t": "<TAB>", + "\n": "<LF>", + "\r": "<CR>", + "\f": "<FF>", + } + def __init__(self, ws=" \t\r\n", min=1, max=0, exact=0): + 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.name = ("".join(White.whiteStrs[c] for c in self.matchWhite)) + self.mayReturnEmpty = True + self.errmsg = "Expected " + self.name + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + def parseImpl( self, instring, loc, doActions=True ): + if not(instring[ loc ] in self.matchWhite): + raise ParseException(instring, loc, self.errmsg, self) + start = loc + loc += 1 + maxloc = start + self.maxLen + maxloc = min( maxloc, len(instring) ) + while loc < maxloc and instring[loc] in self.matchWhite: + loc += 1 + + if loc - start < self.minLen: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + +class _PositionToken(Token): + def __init__( self ): + super(_PositionToken,self).__init__() + self.name=self.__class__.__name__ + self.mayReturnEmpty = True + self.mayIndexError = False + +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__() + self.col = colno + + 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 += 1 + return loc + + 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 ) + newloc = loc + self.col - thiscol + ret = instring[ loc: newloc ] + return newloc, ret + + +class LineStart(_PositionToken): + """ + Matches if current position is at the beginning of a line within the parse string + + Example:: + + test = '''\ + AAA this line + AAA and this line + AAA but not this one + B AAA and definitely not this one + ''' + + for t in (LineStart() + 'AAA' + restOfLine).searchString(test): + print(t) + + Prints:: + ['AAA', ' this line'] + ['AAA', ' and this line'] + + """ + def __init__( self ): + super(LineStart,self).__init__() + self.errmsg = "Expected start of line" + + def parseImpl( self, instring, loc, doActions=True ): + if col(loc, instring) == 1: + return loc, [] + raise ParseException(instring, loc, self.errmsg, self) + +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","") ) + self.errmsg = "Expected end of line" + + def parseImpl( self, instring, loc, doActions=True ): + if loc<len(instring): + if instring[loc] == "\n": + return loc+1, "\n" + else: + raise ParseException(instring, loc, self.errmsg, self) + elif loc == len(instring): + return loc+1, [] + else: + raise ParseException(instring, loc, self.errmsg, self) + +class StringStart(_PositionToken): + """ + Matches if current position is at the beginning of the parse string + """ + def __init__( self ): + super(StringStart,self).__init__() + self.errmsg = "Expected start of text" + + 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 ): + 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__() + self.errmsg = "Expected end of text" + + 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, [] + elif loc > len(instring): + return loc, [] + else: + raise ParseException(instring, loc, self.errmsg, self) + +class WordStart(_PositionToken): + """ + Matches if the current position is at the beginning of a Word, and + is not preceded by any character in a given set of C{wordChars} + (default=C{printables}). To emulate the C{\b} behavior of regular expressions, + use C{WordStart(alphanums)}. C{WordStart} will also match at the beginning of + the string being parsed, or at the beginning of a line. + """ + 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 ): + if loc != 0: + if (instring[loc-1] in self.wordChars or + instring[loc] not in self.wordChars): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + +class WordEnd(_PositionToken): + """ + Matches if the current position is at the end of a Word, and + is not followed by any character in a given set of C{wordChars} + (default=C{printables}). To emulate the C{\b} behavior of regular expressions, + use C{WordEnd(alphanums)}. C{WordEnd} 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__() + self.wordChars = set(wordChars) + self.skipWhitespace = False + self.errmsg = "Not at the end of a word" + + def parseImpl(self, instring, loc, doActions=True ): + instrlen = len(instring) + if instrlen>0 and loc<instrlen: + if (instring[loc] in self.wordChars or + instring[loc-1] not in self.wordChars): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + + +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 ): + exprs = list(exprs) + + if isinstance( exprs, basestring ): + self.exprs = [ ParserElement._literalStringClass( 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) + self.exprs = list(exprs) + else: + try: + self.exprs = list( exprs ) + except TypeError: + self.exprs = [ exprs ] + self.callPreparse = False + + def __getitem__( self, i ): + return self.exprs[i] + + def append( self, other ): + self.exprs.append( other ) + self.strRepr = None + return self + + def leaveWhitespace( self ): + """Extends C{leaveWhitespace} defined in base class, and also invokes C{leaveWhitespace} on + all contained expressions.""" + self.skipWhitespace = False + 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 ): + if other not in self.ignoreExprs: + super( ParseExpression, self).ignore( other ) + for e in self.exprs: + e.ignore( self.ignoreExprs[-1] ) + else: + super( ParseExpression, self).ignore( other ) + for e in self.exprs: + e.ignore( self.ignoreExprs[-1] ) + return self + + def __str__( self ): + try: + return super(ParseExpression,self).__str__() + except Exception: + pass + + if self.strRepr is None: + self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.exprs) ) + return self.strRepr + + 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 ) + # 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 ): + 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] ] + 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 ): + self.exprs = self.exprs[:-1] + other.exprs[:] + self.strRepr = None + self.mayReturnEmpty |= other.mayReturnEmpty + self.mayIndexError |= other.mayIndexError + + self.errmsg = "Expected " + _ustr(self) + + return self + + def setResultsName( self, name, listAllMatches=False ): + ret = super(ParseExpression,self).setResultsName(name,listAllMatches) + return ret + + def validate( self, validateTrace=[] ): + tmp = validateTrace[:]+[self] + for e in self.exprs: + e.validate(tmp) + self.checkRecursion( [] ) + + def copy(self): + ret = super(ParseExpression,self).copy() + ret.exprs = [e.copy() for e in self.exprs] + return ret + +class And(ParseExpression): + """ + Requires all given C{ParseExpression}s to be found in the given order. + Expressions may be separated by whitespace. + May be constructed using the C{'+'} operator. + May also be constructed using the C{'-'} operator, which will suppress backtracking. + + Example:: + integer = Word(nums) + name_expr = OneOrMore(Word(alphas)) + + 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) + self.name = '-' + self.leaveWhitespace() + + def __init__( self, exprs, savelist = True ): + super(And,self).__init__(exprs, savelist) + self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) + self.setWhitespaceChars( self.exprs[0].whiteChars ) + self.skipWhitespace = self.exprs[0].skipWhitespace + self.callPreparse = 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 ) + errorStop = False + for e in self.exprs[1:]: + if isinstance(e, And._ErrorStop): + errorStop = True + continue + if errorStop: + try: + loc, exprtokens = e._parse( instring, loc, doActions ) + except ParseSyntaxException: + raise + except ParseBaseException as pe: + pe.__traceback__ = None + raise ParseSyntaxException._from_exception(pe) + except IndexError: + raise ParseSyntaxException(instring, len(instring), self.errmsg, self) + else: + 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 checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + if not e.mayReturnEmpty: + break + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + +class Or(ParseExpression): + """ + Requires that at least one C{ParseExpression} is found. + If two expressions match, the expression that matches the longest string will be used. + May be constructed using the C{'^'} operator. + + Example:: + # construct Or using '^' operator + + number = Word(nums) ^ Combine(Word(nums) + '.' + Word(nums)) + print(number.searchString("123 3.1416 789")) + prints:: + [['123'], ['3.1416'], ['789']] + """ + 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: + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + maxExcLoc = -1 + maxException = None + matches = [] + for e in self.exprs: + try: + loc2 = e.tryParse( instring, loc ) + except ParseException as err: + err.__traceback__ = None + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + except IndexError: + if len(instring) > maxExcLoc: + 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: + try: + return e._parse( instring, loc, doActions ) + except ParseException as err: + err.__traceback__ = None + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + + if maxException is not None: + maxException.msg = self.errmsg + raise maxException + else: + 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 __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " ^ ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class MatchFirst(ParseExpression): + """ + Requires that at least one C{ParseExpression} is found. + If two expressions match, the first one listed is the one that will match. + May be constructed using the C{'|'} operator. + + Example:: + # construct MatchFirst using '|' operator + + # watch the order of expressions to match + number = Word(nums) | Combine(Word(nums) + '.' + Word(nums)) + print(number.searchString("123 3.1416 789")) # Fail! -> [['123'], ['3'], ['1416'], ['789']] + + # put more selective expression first + 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) + if self.exprs: + self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs) + else: + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + maxExcLoc = -1 + maxException = None + for e in self.exprs: + try: + ret = e._parse( instring, loc, doActions ) + return ret + except ParseException as err: + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + except IndexError: + if len(instring) > maxExcLoc: + 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 + else: + if maxException is not None: + maxException.msg = self.errmsg + raise maxException + 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 __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " | ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class Each(ParseExpression): + """ + Requires all given C{ParseExpression}s to be found, but in any order. + Expressions may be separated by whitespace. + May be constructed using the C{'&'} operator. + + Example:: + color = oneOf("RED ORANGE YELLOW GREEN BLUE PURPLE BLACK WHITE BROWN") + shape_type = oneOf("SQUARE CIRCLE TRIANGLE STAR HEXAGON OCTAGON") + integer = Word(nums) + shape_attr = "shape:" + shape_type("shape") + posn_attr = "posn:" + Group(integer("x") + ',' + integer("y"))("posn") + color_attr = "color:" + color("color") + size_attr = "size:" + integer("size") + + # use Each (using operator '&') to accept attributes in any order + # (shape and posn are required, color and size are optional) + shape_spec = shape_attr & posn_attr & Optional(color_attr) & Optional(size_attr) + + shape_spec.runTests(''' + shape: SQUARE color: BLACK posn: 100, 120 + shape: CIRCLE size: 50 color: BLUE posn: 50,80 + color:GREEN size:20 shape:TRIANGLE posn:20,40 + ''' + ) + prints:: + shape: SQUARE color: BLACK posn: 100, 120 + ['shape:', 'SQUARE', 'color:', 'BLACK', 'posn:', ['100', ',', '120']] + - color: BLACK + - posn: ['100', ',', '120'] + - x: 100 + - y: 120 + - shape: SQUARE + + + shape: CIRCLE size: 50 color: BLUE posn: 50,80 + ['shape:', 'CIRCLE', 'size:', '50', 'color:', 'BLUE', 'posn:', ['50', ',', '80']] + - color: BLUE + - posn: ['50', ',', '80'] + - x: 50 + - y: 80 + - shape: CIRCLE + - size: 50 + + + color: GREEN size: 20 shape: TRIANGLE posn: 20,40 + ['color:', 'GREEN', 'size:', '20', 'shape:', 'TRIANGLE', 'posn:', ['20', ',', '40']] + - color: GREEN + - posn: ['20', ',', '40'] + - x: 20 + - y: 40 + - shape: TRIANGLE + - size: 20 + """ + 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 + + 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.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.required += self.multirequired + self.initExprGroups = False + tmpLoc = loc + tmpReqd = self.required[:] + tmpOpt = self.optionals[:] + matchOrder = [] + + keepMatching = True + while keepMatching: + tmpExprs = tmpReqd + tmpOpt + self.multioptionals + self.multirequired + failed = [] + for e in tmpExprs: + try: + tmpLoc = e.tryParse( instring, tmpLoc ) + except ParseException: + failed.append(e) + else: + matchOrder.append(self.opt1map.get(id(e),e)) + if e in tmpReqd: + tmpReqd.remove(e) + elif e in tmpOpt: + tmpOpt.remove(e) + if len(failed) == len(tmpExprs): + keepMatching = False + + if tmpReqd: + missing = ", ".join(_ustr(e) for e in tmpReqd) + 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] + + resultlist = [] + for e in matchOrder: + loc,results = e._parse(instring,loc,doActions) + resultlist.append(results) + + finalResults = sum(resultlist, ParseResults([])) + return loc, finalResults + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " & ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class ParseElementEnhance(ParserElement): + """ + Abstract subclass of C{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) + else: + expr = ParserElement._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.skipWhitespace = expr.skipWhitespace + self.saveAsList = expr.saveAsList + self.callPreparse = expr.callPreparse + self.ignoreExprs.extend(expr.ignoreExprs) + + def parseImpl( self, instring, loc, doActions=True ): + if self.expr is not None: + return self.expr._parse( instring, loc, doActions, callPreParse=False ) + else: + raise ParseException("",loc,self.errmsg,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 ): + if other not in self.ignoreExprs: + super( ParseElementEnhance, self).ignore( other ) + if self.expr is not None: + self.expr.ignore( self.ignoreExprs[-1] ) + else: + super( ParseElementEnhance, self).ignore( other ) + if self.expr is not None: + self.expr.ignore( self.ignoreExprs[-1] ) + return self + + def streamline( self ): + super(ParseElementEnhance,self).streamline() + if self.expr is not None: + self.expr.streamline() + return self + + def checkRecursion( self, parseElementList ): + if self in parseElementList: + raise RecursiveGrammarException( parseElementList+[self] ) + subRecCheckList = parseElementList[:] + [ self ] + if self.expr is not None: + self.expr.checkRecursion( subRecCheckList ) + + def validate( self, validateTrace=[] ): + tmp = validateTrace[:]+[self] + if self.expr is not None: + self.expr.validate(tmp) + self.checkRecursion( [] ) + + def __str__( self ): + try: + 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) ) + return self.strRepr + + +class FollowedBy(ParseElementEnhance): + """ + Lookahead matching of the given parse expression. C{FollowedBy} + does I{not} advance the parsing position within the input string, it only + verifies that the specified parse expression matches at the current + position. C{FollowedBy} always returns a null token list. + + Example:: + # use FollowedBy to match a label only if it is followed by a ':' + data_word = Word(alphas) + label = data_word + FollowedBy(':') + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + + OneOrMore(attr_expr).parseString("shape: SQUARE color: BLACK posn: upper left").pprint() + prints:: + [['shape', 'SQUARE'], ['color', 'BLACK'], ['posn', 'upper left']] + """ + def __init__( self, expr ): + super(FollowedBy,self).__init__(expr) + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + self.expr.tryParse( instring, loc ) + return loc, [] + + +class NotAny(ParseElementEnhance): + """ + Lookahead to disallow matching with the given parse expression. C{NotAny} + does I{not} advance the parsing position within the input string, it only + verifies that the specified parse expression does I{not} match at the current + position. Also, C{NotAny} does I{not} skip over leading whitespace. C{NotAny} + always returns a null token list. May be constructed using the '~' operator. + + Example:: + + """ + 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) + + 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"): + return self.name + + if self.strRepr is None: + self.strRepr = "~{" + _ustr(self.expr) + "}" + + return self.strRepr + +class _MultipleMatch(ParseElementEnhance): + 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 + + 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 + if check_ender: + try_not_ender = self.not_ender.tryParse + + # must be at least one (but first see if we are the stopOn sentinel; + # if so, fail) + if check_ender: + try_not_ender(instring, loc) + 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 ) + else: + preloc = loc + loc, tmptokens = self_expr_parse( instring, preloc, doActions ) + if tmptokens or tmptokens.haskeys(): + tokens += tmptokens + except (ParseException,IndexError): + pass + + return loc, tokens + +class OneOrMore(_MultipleMatch): + """ + Repetition of one or more of the given expression. + + Parameters: + - expr - expression that must match one or more times + - stopOn - (default=C{None}) - expression for a terminating sentinel + (only required if the sentinel would ordinarily match the repetition + expression) + + Example:: + data_word = Word(alphas) + label = data_word + FollowedBy(':') + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join)) + + text = "shape: SQUARE posn: upper left color: BLACK" + OneOrMore(attr_expr).parseString(text).pprint() # Fail! read 'color' as data instead of next label -> [['shape', 'SQUARE color']] + + # use stopOn attribute for OneOrMore to avoid reading label string as part of the data + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + OneOrMore(attr_expr).parseString(text).pprint() # Better -> [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'BLACK']] + + # could also be written as + (attr_expr * (1,)).parseString(text).pprint() + """ + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + _ustr(self.expr) + "}..." + + return self.strRepr + +class ZeroOrMore(_MultipleMatch): + """ + Optional repetition of zero or more of the given expression. + + Parameters: + - expr - expression that must match zero or more times + - stopOn - (default=C{None}) - expression for a terminating sentinel + (only required if the sentinel would ordinarily match the repetition + expression) + + Example: similar to L{OneOrMore} + """ + def __init__( self, expr, stopOn=None): + super(ZeroOrMore,self).__init__(expr, stopOn=stopOn) + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + try: + return super(ZeroOrMore, self).parseImpl(instring, loc, doActions) + except (ParseException,IndexError): + return loc, [] + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "[" + _ustr(self.expr) + "]..." + + return self.strRepr + +class _NullToken(object): + def __bool__(self): + return False + __nonzero__ = __bool__ + def __str__(self): + return "" + +_optionalNotMatched = _NullToken() +class Optional(ParseElementEnhance): + """ + Optional matching of the given expression. + + Parameters: + - expr - expression that must match zero or more times + - default (optional) - value to be returned if the optional expression is not found. + + Example:: + # US postal code can be a 5-digit zip, plus optional 4-digit qualifier + zip = Combine(Word(nums, exact=5) + Optional('-' + Word(nums, exact=4))) + zip.runTests(''' + # traditional ZIP code + 12345 + + # ZIP+4 form + 12101-0001 + + # invalid ZIP + 98765- + ''') + prints:: + # traditional ZIP code + 12345 + ['12345'] + + # ZIP+4 form + 12101-0001 + ['12101-0001'] + + # invalid ZIP + 98765- + ^ + 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 ) + self.saveAsList = self.expr.saveAsList + self.defaultValue = default + self.mayReturnEmpty = 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: + if self.expr.resultsName: + tokens = ParseResults([ self.defaultValue ]) + tokens[self.expr.resultsName] = self.defaultValue + else: + tokens = [ self.defaultValue ] + else: + tokens = [] + return loc, tokens + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "[" + _ustr(self.expr) + "]" + + return self.strRepr + +class SkipTo(ParseElementEnhance): + """ + Token for skipping over all undefined text until the matched expression is found. + + Parameters: + - expr - target expression marking the end of the data to be skipped + - include - (default=C{False}) if True, the target expression is also parsed + (the skipped text and target expression are returned as a 2-element list). + - ignore - (default=C{None}) used to define grammars (typically quoted strings and + comments) that might contain false matches to the target expression + - failOn - (default=C{None}) define expressions that are not allowed to be + included in the skipped test; if found before the target expression is found, + the SkipTo is not a match + + Example:: + report = ''' + Outstanding Issues Report - 1 Jan 2000 + + # | Severity | Description | Days Open + -----+----------+-------------------------------------------+----------- + 101 | Critical | Intermittent system crash | 6 + 94 | Cosmetic | Spelling error on Login ('log|n') | 14 + 79 | Minor | System slow when running too many reports | 47 + ''' + integer = Word(nums) + SEP = Suppress('|') + # use SkipTo to simply match everything up until the next SEP + # - ignore quoted strings, so that a '|' character inside a quoted string does not match + # - parse action will call token.strip() for each matched token, i.e., the description body + string_data = SkipTo(SEP, ignore=quotedString) + string_data.setParseAction(tokenMap(str.strip)) + ticket_expr = (integer("issue_num") + SEP + + string_data("sev") + SEP + + string_data("desc") + SEP + + integer("days_open")) + + for tkt in ticket_expr.searchString(report): + print tkt.dump() + prints:: + ['101', 'Critical', 'Intermittent system crash', '6'] + - days_open: 6 + - desc: Intermittent system crash + - issue_num: 101 + - sev: Critical + ['94', 'Cosmetic', "Spelling error on Login ('log|n')", '14'] + - days_open: 14 + - desc: Spelling error on Login ('log|n') + - issue_num: 94 + - sev: Cosmetic + ['79', 'Minor', 'System slow when running too many reports', '47'] + - days_open: 47 + - desc: System slow when running too many reports + - issue_num: 79 + - sev: Minor + """ + 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.asList = False + if isinstance(failOn, basestring): + self.failOn = ParserElement._literalStringClass(failOn) + else: + self.failOn = failOn + self.errmsg = "No match found for "+_ustr(self.expr) + + def parseImpl( self, instring, loc, doActions=True ): + startloc = loc + instrlen = len(instring) + expr = self.expr + expr_parse = self.expr._parse + self_failOn_canParseNext = self.failOn.canParseNext if self.failOn is not None else None + self_ignoreExpr_tryParse = self.ignoreExpr.tryParse if self.ignoreExpr is not None else None + + tmploc = loc + while tmploc <= instrlen: + if self_failOn_canParseNext is not None: + # break if failOn expression matches + if self_failOn_canParseNext(instring, tmploc): + break + + if self_ignoreExpr_tryParse is not None: + # advance past ignore expressions + while 1: + try: + tmploc = self_ignoreExpr_tryParse(instring, tmploc) + except ParseBaseException: + break + + try: + expr_parse(instring, tmploc, doActions=False, callPreParse=False) + except (ParseException, IndexError): + # no match, advance loc in string + tmploc += 1 + else: + # matched skipto expr, done + break + + else: + # ran off the end of the input string without matching skipto expr, fail + raise ParseException(instring, loc, self.errmsg, self) + + # build up return values + loc = tmploc + skiptext = instring[startloc:loc] + skipresult = ParseResults(skiptext) + + if self.includeMatch: + loc, mat = expr_parse(instring,loc,doActions,callPreParse=False) + skipresult += mat + + return loc, skipresult + +class Forward(ParseElementEnhance): + """ + Forward declaration of an expression to be defined later - + used for recursive grammars, such as algebraic infix notation. + When the expression is known, it is assigned to the C{Forward} variable using the '<<' operator. + + Note: take care when assigning to C{Forward} not to overlook precedence of operators. + Specifically, '|' has a lower precedence than '<<', so that:: + fwdExpr << a | b | c + will actually be evaluated as:: + (fwdExpr << a) | b | c + thereby leaving b and c out as parseable alternatives. It is recommended that you + explicitly group the values inserted into the C{Forward}:: + fwdExpr << (a | b | c) + Converting to use the '<<=' operator instead will avoid this problem. + + See L{ParseResults.pprint} for an example of a recursive parser created using + C{Forward}. + """ + def __init__( self, other=None ): + super(Forward,self).__init__( other, savelist=False ) + + def __lshift__( self, other ): + if isinstance( other, basestring ): + other = ParserElement._literalStringClass(other) + self.expr = other + self.strRepr = None + self.mayIndexError = self.expr.mayIndexError + self.mayReturnEmpty = self.expr.mayReturnEmpty + self.setWhitespaceChars( self.expr.whiteChars ) + self.skipWhitespace = self.expr.skipWhitespace + self.saveAsList = self.expr.saveAsList + self.ignoreExprs.extend(self.expr.ignoreExprs) + return self + + def __ilshift__(self, other): + return self << other + + def leaveWhitespace( self ): + self.skipWhitespace = False + return 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=[] ): + if self not in validateTrace: + tmp = validateTrace[:]+[self] + if self.expr is not None: + self.expr.validate(tmp) + self.checkRecursion([]) + + def __str__( self ): + if hasattr(self,"name"): + return self.name + return self.__class__.__name__ + ": ..." + + # stubbed out for now - creates awful memory and perf issues + self._revertClass = self.__class__ + self.__class__ = _ForwardNoRecurse + try: + if self.expr is not None: + retString = _ustr(self.expr) + else: + retString = "None" + finally: + self.__class__ = self._revertClass + return self.__class__.__name__ + ": " + retString + + def copy(self): + if self.expr is not None: + return super(Forward,self).copy() + else: + ret = Forward() + ret <<= self + return ret + +class _ForwardNoRecurse(Forward): + def __str__( self ): + return "..." + +class TokenConverter(ParseElementEnhance): + """ + Abstract subclass of C{ParseExpression}, for converting parsed results. + """ + def __init__( self, expr, savelist=False ): + super(TokenConverter,self).__init__( expr )#, savelist ) + self.saveAsList = False + +class Combine(TokenConverter): + """ + Converter to concatenate all matching tokens to a single string. + By default, the matching patterns must also be contiguous in the input string; + this can be disabled by specifying C{'adjacent=False'} in the constructor. + + Example:: + real = Word(nums) + '.' + Word(nums) + print(real.parseString('3.1416')) # -> ['3', '.', '1416'] + # will also erroneously match the following + print(real.parseString('3. 1416')) # -> ['3', '.', '1416'] + + real = Combine(Word(nums) + '.' + Word(nums)) + print(real.parseString('3.1416')) # -> ['3.1416'] + # 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 ) + # suppress whitespace-stripping in contained parse expressions, but re-enable it on the Combine itself + if adjacent: + self.leaveWhitespace() + self.adjacent = adjacent + self.skipWhitespace = True + self.joinString = joinString + self.callPreparse = True + + def ignore( self, other ): + if self.adjacent: + ParserElement.ignore(self, other) + else: + super( Combine, self).ignore( other ) + return self + + def postParse( self, instring, loc, tokenlist ): + retToks = tokenlist.copy() + del retToks[:] + retToks += ParseResults([ "".join(tokenlist._asStringList(self.joinString)) ], modal=self.modalResults) + + if self.resultsName and retToks.haskeys(): + return [ retToks ] + else: + return retToks + +class Group(TokenConverter): + """ + Converter to return the matched tokens as a list - useful for returning tokens of C{L{ZeroOrMore}} and C{L{OneOrMore}} expressions. + + Example:: + ident = Word(alphas) + num = Word(nums) + term = ident | num + func = ident + Optional(delimitedList(term)) + 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']] + """ + def __init__( self, expr ): + super(Group,self).__init__( expr ) + self.saveAsList = True + + def postParse( self, instring, loc, tokenlist ): + return [ tokenlist ] + +class Dict(TokenConverter): + """ + Converter to return a repetitive expression as a list, but also as a dictionary. + Each element can also be referenced using the first token in the expression as its key. + Useful for tabular report scraping when the first column can be used as a item key. + + Example:: + data_word = Word(alphas) + label = data_word + FollowedBy(':') + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join)) + + text = "shape: SQUARE posn: upper left color: light blue texture: burlap" + attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + + # print attributes as plain groups + print(OneOrMore(attr_expr).parseString(text).dump()) + + # instead of OneOrMore(expr), parse using Dict(OneOrMore(Group(expr))) - Dict will auto-assign names + result = Dict(OneOrMore(Group(attr_expr))).parseString(text) + print(result.dump()) + + # access named fields as dict entries, or output as dict + print(result['shape']) + print(result.asDict()) + prints:: + ['shape', 'SQUARE', 'posn', 'upper left', 'color', 'light blue', 'texture', 'burlap'] + + [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']] + - color: light blue + - posn: upper left + - shape: SQUARE + - texture: burlap + SQUARE + {'color': 'light blue', 'posn': 'upper left', 'texture': 'burlap', 'shape': 'SQUARE'} + See more examples at L{ParseResults} of accessing fields by results name. + """ + def __init__( self, expr ): + super(Dict,self).__init__( expr ) + self.saveAsList = True + + def postParse( self, instring, loc, tokenlist ): + for i,tok in enumerate(tokenlist): + if len(tok) == 0: + continue + ikey = tok[0] + 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) + else: + dictvalue = tok.copy() #ParseResults(i) + del dictvalue[0] + if len(dictvalue)!= 1 or (isinstance(dictvalue,ParseResults) and dictvalue.haskeys()): + tokenlist[ikey] = _ParseResultsWithOffset(dictvalue,i) + else: + tokenlist[ikey] = _ParseResultsWithOffset(dictvalue[0],i) + + if self.resultsName: + return [ tokenlist ] + else: + return tokenlist + + +class Suppress(TokenConverter): + """ + Converter for ignoring the results of a parsed expression. + + Example:: + source = "a, b, c,d" + wd = Word(alphas) + wd_list1 = wd + ZeroOrMore(',' + wd) + print(wd_list1.parseString(source)) + + # often, delimiters that are useful during parsing are just in the + # way afterward - use Suppress to keep them out of the parsed output + wd_list2 = wd + ZeroOrMore(Suppress(',') + wd) + print(wd_list2.parseString(source)) + prints:: + ['a', ',', 'b', ',', 'c', ',', 'd'] + ['a', 'b', 'c', 'd'] + (See also L{delimitedList}.) + """ + def postParse( self, instring, loc, tokenlist ): + return [] + + def suppress( self ): + return self + + +class OnlyOnce(object): + """ + Wrapper for parse actions, to ensure they are only called once. + """ + def __init__(self, methodCall): + self.callable = _trim_arity(methodCall) + self.called = False + def __call__(self,s,l,t): + if not self.called: + results = self.callable(s,l,t) + self.called = True + return results + raise ParseException(s,l,"") + def reset(self): + self.called = False + +def traceParseAction(f): + """ + Decorator for debugging parse actions. + + When the parse action is called, this decorator will print C{">> entering I{method-name}(line:I{current_source_line}, I{parse_location}, I{matched_tokens})".} + When the parse action completes, the decorator will print C{"<<"} followed by the returned value, or any exception that the parse action raised. + + Example:: + wd = Word(alphas) + + @traceParseAction + def remove_duplicate_chars(tokens): + return ''.join(sorted(set(''.join(tokens)))) + + wds = OneOrMore(wd).setParseAction(remove_duplicate_chars) + print(wds.parseString("slkdjs sld sldd sdlf sdljf")) + prints:: + >>entering remove_duplicate_chars(line: 'slkdjs sld sldd sdlf sdljf', 0, (['slkdjs', 'sld', 'sldd', 'sdlf', 'sdljf'], {})) + <<leaving remove_duplicate_chars (ret: 'dfjkls') + ['dfjkls'] + """ + f = _trim_arity(f) + def z(*paArgs): + thisFunc = f.__name__ + 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) ) + try: + ret = f(*paArgs) + except Exception as exc: + sys.stderr.write( "<<leaving %s (exception: %s)\n" % (thisFunc,exc) ) + raise + sys.stderr.write( "<<leaving %s (ret: %r)\n" % (thisFunc,ret) ) + return ret + try: + z.__name__ = f.__name__ + except AttributeError: + pass + return z + +# +# global helpers +# +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 overridden by passing C{combine=True} in the constructor. + If C{combine} is set to C{True}, the matching tokens are returned as a single token + string, with the delimiters included; otherwise, the matching tokens are returned + as a list of tokens, with the delimiters suppressed. + + Example:: + 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)+"]..." + if combine: + return Combine( expr + ZeroOrMore( delim + expr ) ).setName(dlName) + else: + return ( expr + ZeroOrMore( Suppress( delim ) + expr ) ).setName(dlName) + +def countedArray( expr, intExpr=None ): + """ + Helper to define a counted list of expressions. + This helper defines a pattern of the form:: + integer expr expr expr... + where the leading integer tells how many expr expressions follow. + The matched tokens returns the array of expr tokens as a list - the leading count token is suppressed. + + If C{intExpr} is specified, it should be a pyparsing expression that produces an integer value. + + Example:: + countedArray(Word(alphas)).parseString('2 ab cd ef') # -> ['ab', 'cd'] + + # in this parser, the leading integer value is given in binary, + # '10' indicating that 2 values are in the array + binaryConstant = Word('01').setParseAction(lambda t: int(t[0], 2)) + countedArray(Word(alphas), intExpr=binaryConstant).parseString('10 ab cd ef') # -> ['ab', 'cd'] + """ + arrayExpr = Forward() + def countFieldParseAction(s,l,t): + n = t[0] + arrayExpr << (n and Group(And([expr]*n)) or Group(empty)) + return [] + if intExpr is None: + 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) + '...') + +def _flatten(L): + ret = [] + for i in L: + if isinstance(i,list): + ret.extend(_flatten(i)) + else: + ret.append(i) + return ret + +def matchPreviousLiteral(expr): + """ + Helper to define an expression that is indirectly defined from + the tokens matched in a previous expression, that is, it looks + for a 'repeat' of a previous expression. For example:: + first = Word(nums) + second = matchPreviousLiteral(first) + matchExpr = first + ":" + second + will match C{"1:1"}, but not C{"1:2"}. Because this matches a + previous literal, will also match the leading C{"1:1"} in C{"1:10"}. + If this is not desired, use C{matchPreviousExpr}. + Do I{not} use with packrat parsing enabled. + """ + rep = Forward() + def copyTokenToRepeater(s,l,t): + if t: + if len(t) == 1: + rep << t[0] + else: + # flatten t tokens + tflat = _flatten(t.asList()) + rep << And(Literal(tt) for tt in tflat) + else: + rep << Empty() + expr.addParseAction(copyTokenToRepeater, callDuringTry=True) + rep.setName('(prev) ' + _ustr(expr)) + return rep + +def matchPreviousExpr(expr): + """ + Helper to define an expression that is indirectly defined from + the tokens matched in a previous expression, that is, it looks + for a 'repeat' of a previous expression. For example:: + first = Word(nums) + second = matchPreviousExpr(first) + matchExpr = first + ":" + second + will match C{"1:1"}, but not C{"1:2"}. Because this matches by + expressions, will I{not} match the leading C{"1:1"} in C{"1:10"}; + the expressions are evaluated first, and then compared, so + C{"1"} is compared with C{"10"}. + Do I{not} use with packrat parsing enabled. + """ + rep = Forward() + e2 = expr.copy() + rep <<= e2 + def copyTokenToRepeater(s,l,t): + matchTokens = _flatten(t.asList()) + def mustMatchTheseTokens(s,l,t): + theseTokens = _flatten(t.asList()) + 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") + return _ustr(s) + +def oneOf( strs, caseless=False, useRegex=True ): + """ + 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 a C{L{MatchFirst}} for best performance. + + Parameters: + - strs - a string of space-delimited literals, or a collection of string literals + - caseless - (default=C{False}) - treat all literals as caseless + - useRegex - (default=C{True}) - as an optimization, will generate a Regex + object; otherwise, will generate a C{MatchFirst} object (if C{caseless=True}, or + if creating a C{Regex} raises an exception) + + Example:: + comp_oper = oneOf("< = > <= >= !=") + var = Word(alphas) + number = Word(nums) + term = var | number + comparison_expr = term + comp_oper + term + print(comparison_expr.searchString("B = 12 AA=23 B<=AA AA>12")) + prints:: + [['B', '=', '12'], ['AA', '=', '23'], ['B', '<=', 'AA'], ['AA', '>', '12']] + """ + if caseless: + isequal = ( lambda a,b: a.upper() == b.upper() ) + masks = ( lambda a,b: b.upper().startswith(a.upper()) ) + parseElementClass = CaselessLiteral + else: + isequal = ( lambda a,b: a == b ) + masks = ( lambda a,b: b.startswith(a) ) + parseElementClass = Literal + + symbols = [] + 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) + 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)) + 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 ): + """ + Helper to easily and clearly define a dictionary by specifying the respective patterns + for the key and value. Takes care of defining the C{L{Dict}}, C{L{ZeroOrMore}}, and C{L{Group}} tokens + in the proper order. The key pattern can include delimiting markers or punctuation, + as long as they are suppressed, thereby leaving the significant key text. The value + pattern can include named results, so that the C{Dict} results can include named token + fields. + + Example:: + text = "shape: SQUARE posn: upper left color: light blue texture: burlap" + attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + print(OneOrMore(attr_expr).parseString(text).dump()) + + attr_label = label + attr_value = Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join) + + # similar to Dict, but simpler call format + result = dictOf(attr_label, attr_value).parseString(text) + print(result.dump()) + print(result['shape']) + print(result.shape) # object attribute access works too + print(result.asDict()) + prints:: + [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']] + - color: light blue + - posn: upper left + - shape: SQUARE + - texture: burlap + SQUARE + SQUARE + {'color': 'light blue', 'shape': 'SQUARE', 'posn': 'upper left', 'texture': 'burlap'} + """ + return Dict( ZeroOrMore( Group ( key + value ) ) ) + +def originalTextFor(expr, asString=True): + """ + Helper to return the original, untokenized text for a given expression. Useful to + restore the parsed fields of an HTML start tag into the raw tag text itself, or to + revert separate tokens with intervening whitespace back to the original matching + input text. By default, returns astring containing the original parsed text. + + If the optional C{asString} argument is passed as C{False}, then the return value is a + C{L{ParseResults}} containing any results names that were originally matched, and a + single token containing the original matched text from the input string. So if + the expression passed to C{L{originalTextFor}} contains expressions with defined + results names, you must set C{asString} to C{False} if you want to preserve those + results name values. + + Example:: + src = "this is test <b> bold <i>text</i> </b> normal text " + for tag in ("b","i"): + opener,closer = makeHTMLTags(tag) + patt = originalTextFor(opener + SkipTo(closer) + closer) + print(patt.searchString(src)[0]) + prints:: + ['<b> bold <i>text</i> </b>'] + ['<i>text</i>'] + """ + 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] + else: + def extractText(s,l,t): + t[:] = [s[t.pop('_original_start'):t.pop('_original_end')]] + matchExpr.setParseAction(extractText) + matchExpr.ignoreExprs = expr.ignoreExprs + return matchExpr + +def ungroup(expr): + """ + Helper to undo pyparsing's default grouping of And expressions, even + if all but one are non-empty. + """ + return TokenConverter(expr).setParseAction(lambda t:t[0]) + +def locatedExpr(expr): + """ + Helper to decorate a returned token with its starting and ending locations in the input string. + This helper adds the following results names: + - locn_start = location where matched expression begins + - locn_end = location where matched expression ends + - value = the actual parsed results + + Be careful if the input text contains C{<TAB>} characters, you may want to call + C{L{ParserElement.parseWithTabs}} + + Example:: + wd = Word(alphas) + for match in locatedExpr(wd).searchString("ljsdf123lksdjjf123lkkjj1222"): + print(match) + prints:: + [[0, 'ljsdf', 5]] + [[8, 'lksdjjf', 15]] + [[18, 'lkkjj', 23]] + """ + locator = Empty().setParseAction(lambda s,l,t: l) + return Group(locator("locn_start") + expr("value") + locator.copy().leaveWhitespace()("locn_end")) + + +# convenience constants for positional expressions +empty = Empty().setName("empty") +lineStart = LineStart().setName("lineStart") +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))) +_singleChar = _escapedPunc | _escapedHexChar | _escapedOctChar | CharsNotIn(r'\]', exact=1) +_charRange = Group(_singleChar + Suppress("-") + _singleChar) +_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 construction. Borrows + syntax from regexp '[]' string range definitions:: + srange("[0-9]") -> "0123456789" + srange("[a-z]") -> "abcdefghijklmnopqrstuvwxyz" + srange("[a-z$_]") -> "abcdefghijklmnopqrstuvwxyz$_" + The input string must be enclosed in []'s, and the returned string is the expanded + character set joined into a single string. + The values enclosed in the []'s may be: + - a single character + - an escaped character with a leading backslash (such as C{\-} or C{\]}) + - an escaped hex character with a leading C{'\x'} (C{\x21}, which is a C{'!'} character) + (C{\0x##} is also supported for backwards compatibility) + - an escaped octal character with a leading C{'\0'} (C{\041}, which is a C{'!'} character) + - a range of any of the above, separated by a dash (C{'a-z'}, etc.) + - any combination of the above (C{'aeiouy'}, C{'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)) + try: + return "".join(_expanded(part) for part in _reBracketExpr.parseString(s).body) + except Exception: + return "" + +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) + return verifyCol + +def replaceWith(replStr): + """ + Helper method for common parse actions that simply return a literal value. Especially + useful when used with C{L{transformString<ParserElement.transformString>}()}. + + Example:: + num = Word(nums).setParseAction(lambda toks: int(toks[0])) + na = oneOf("N/A NA").setParseAction(replaceWith(math.nan)) + term = na | num + + OneOrMore(term).parseString("324 234 N/A 234") # -> [324, 234, nan, 234] + """ + return lambda s,l,t: [replStr] + +def removeQuotes(s,l,t): + """ + Helper parse action for removing quotation marks from parsed quoted strings. + + Example:: + # by default, quotation marks are included in parsed results + quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["'Now is the Winter of our Discontent'"] + + # use removeQuotes to strip quotation marks from parsed results + quotedString.setParseAction(removeQuotes) + quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["Now is the Winter of our Discontent"] + """ + return t[0][1:-1] + +def tokenMap(func, *args): + """ + Helper to define a parse action by mapping a function to all elements of a ParseResults list.If any additional + args are passed, they are forwarded to the given function as additional arguments after + the token, as in C{hex_integer = Word(hexnums).setParseAction(tokenMap(int, 16))}, which will convert the + parsed data to an integer using base 16. + + Example (compare the last to example in L{ParserElement.transformString}:: + hex_ints = OneOrMore(Word(hexnums)).setParseAction(tokenMap(int, 16)) + hex_ints.runTests(''' + 00 11 22 aa FF 0a 0d 1a + ''') + + upperword = Word(alphas).setParseAction(tokenMap(str.upper)) + OneOrMore(upperword).runTests(''' + my kingdom for a horse + ''') + + wd = Word(alphas).setParseAction(tokenMap(str.title)) + OneOrMore(wd).setParseAction(' '.join).runTests(''' + now is the winter of our discontent made glorious summer by this sun of york + ''') + prints:: + 00 11 22 aa FF 0a 0d 1a + [0, 17, 34, 170, 255, 10, 13, 26] + + my kingdom for a horse + ['MY', 'KINGDOM', 'FOR', 'A', 'HORSE'] + + 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): + return [func(tokn, *args) for tokn in t] + + try: + func_name = getattr(func, '__name__', + getattr(func, '__class__').__name__) + except Exception: + func_name = str(func) + pa.__name__ = func_name + + return pa + +upcaseTokens = tokenMap(lambda t: _ustr(t).upper()) +"""(Deprecated) Helper parse action to convert tokens to upper case. Deprecated in favor of L{pyparsing_common.upcaseTokens}""" + +downcaseTokens = tokenMap(lambda t: _ustr(t).lower()) +"""(Deprecated) Helper parse action to convert tokens to lower case. Deprecated in favor of L{pyparsing_common.downcaseTokens}""" + +def _makeTags(tagStr, xml): + """Internal helper to construct opening and closing tag expressions, given a tag name""" + 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 ) + openTag = Suppress("<") + tagStr("tag") + \ + Dict(ZeroOrMore(Group( tagAttrName + Suppress("=") + tagAttrValue ))) + \ + Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") + else: + printablesLessRAbrack = "".join(c for c in printables if c not in ">") + tagAttrValue = quotedString.copy().setParseAction( removeQuotes ) | Word(printablesLessRAbrack) + openTag = Suppress("<") + tagStr("tag") + \ + Dict(ZeroOrMore(Group( tagAttrName.setParseAction(downcaseTokens) + \ + Optional( Suppress("=") + tagAttrValue ) ))) + \ + Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") + closeTag = Combine(_L("</") + tagStr + ">") + + openTag = openTag.setResultsName("start"+"".join(resname.replace(":"," ").title().split())).setName("<%s>" % resname) + closeTag = closeTag.setResultsName("end"+"".join(resname.replace(":"," ").title().split())).setName("</%s>" % resname) + openTag.tag = resname + closeTag.tag = resname + return openTag, closeTag + +def makeHTMLTags(tagStr): + """ + Helper to construct opening and closing tag expressions for HTML, given a tag name. Matches + tags in either upper or lower case, attributes with namespaces and with quoted or unquoted values. + + Example:: + text = '<td>More info at the <a href="http://pyparsing.wikispaces.com">pyparsing</a> wiki page</td>' + # makeHTMLTags returns pyparsing expressions for the opening and closing tags as a 2-tuple + a,a_end = makeHTMLTags("A") + link_expr = a + SkipTo(a_end)("link_text") + a_end + + for link in link_expr.searchString(text): + # attributes in the <A> tag (like "href" shown here) are also accessible as named results + print(link.link_text, '->', link.href) + prints:: + pyparsing -> http://pyparsing.wikispaces.com + """ + return _makeTags( tagStr, False ) + +def makeXMLTags(tagStr): + """ + Helper to construct opening and closing tag expressions for XML, given a tag name. Matches + tags only in the given upper/lower case. + + Example: similar to L{makeHTMLTags} + """ + return _makeTags( tagStr, True ) + +def withAttribute(*args,**attrDict): + """ + Helper to create a validating parse action to be used with start tags created + with C{L{makeXMLTags}} or C{L{makeHTMLTags}}. Use C{withAttribute} to qualify a starting tag + with a required attribute value, to avoid false matches on common tags such as + C{<TD>} or C{<DIV>}. + + Call C{withAttribute} with a series of attribute names and values. Specify the list + of filter attributes names and values as: + - keyword arguments, as in C{(align="right")}, or + - as an explicit dict with C{**} operator, when an attribute name is also a Python + reserved word, as in C{**{"class":"Customer", "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. + + If just testing for C{class} (with or without a namespace), use C{L{withClass}}. + + To verify that the attribute exists, but without specifying a value, pass + C{withAttribute.ANY_VALUE} as the value. + + Example:: + html = ''' + <div> + Some text + <div type="grid">1 4 0 1 0</div> + <div type="graph">1,3 2,3 1,1</div> + <div>this has no type</div> + </div> + + ''' + div,div_end = makeHTMLTags("div") + + # only match div tag having a type attribute with value "grid" + div_grid = div().setParseAction(withAttribute(type="grid")) + grid_expr = div_grid + SkipTo(div | div_end)("body") + for grid_header in grid_expr.searchString(html): + print(grid_header.body) + + # construct a match with any div tag having a type attribute, regardless of the value + div_any_type = div().setParseAction(withAttribute(type=withAttribute.ANY_VALUE)) + div_expr = div_any_type + SkipTo(div | div_end)("body") + for div_header in div_expr.searchString(html): + print(div_header.body) + prints:: + 1 4 0 1 0 + + 1 4 0 1 0 + 1,3 2,3 1,1 + """ + if args: + attrs = args[:] + else: + attrs = attrDict.items() + 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) + if attrValue != withAttribute.ANY_VALUE and tokens[attrName] != attrValue: + raise ParseException(s,l,"attribute '%s' has value '%s', must be '%s'" % + (attrName, tokens[attrName], attrValue)) + return pa +withAttribute.ANY_VALUE = object() + +def withClass(classname, namespace=''): + """ + Simplified version of C{L{withAttribute}} when matching on a div class - made + difficult because C{class} is a reserved word in Python. + + Example:: + html = ''' + <div> + Some text + <div class="grid">1 4 0 1 0</div> + <div class="graph">1,3 2,3 1,1</div> + <div>this <div> has no class</div> + </div> + + ''' + div,div_end = makeHTMLTags("div") + div_grid = div().setParseAction(withClass("grid")) + + grid_expr = div_grid + SkipTo(div | div_end)("body") + for grid_header in grid_expr.searchString(html): + print(grid_header.body) + + div_any_type = div().setParseAction(withClass(withAttribute.ANY_VALUE)) + div_expr = div_any_type + SkipTo(div | div_end)("body") + for div_header in div_expr.searchString(html): + print(div_header.body) + prints:: + 1 4 0 1 0 + + 1 4 0 1 0 + 1,3 2,3 1,1 + """ + classattr = "%s:class" % namespace if namespace else "class" + return withAttribute(**{classattr : classname}) + +opAssoc = _Constants() +opAssoc.LEFT = object() +opAssoc.RIGHT = object() + +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 attached + to operator expressions. The generated parser will also recognize the use + of parentheses to override operator precedences (see example below). + + Note: if you define a deep operator list, you may see performance issues + when using infixNotation. See L{ParserElement.enablePackrat} for a + mechanism to potentially improve your parser performance. + + Parameters: + - baseExpr - expression representing the most basic element for the nested + - opList - list of tuples, one for each operator precedence level in the + expression grammar; each tuple is of the form + (opExpr, numTerms, rightLeftAssoc, parseAction), where: + - opExpr is the pyparsing expression for the operator; + may also be a string, which will be converted to a Literal; + if numTerms is 3, opExpr is a tuple of two expressions, for the + two operators separating the 3 terms + - numTerms is the number of terms for this operator (must + be 1, 2, or 3) + - rightLeftAssoc is the indicator whether the operator is + right or left associative, using the pyparsing-defined + constants C{opAssoc.RIGHT} and C{opAssoc.LEFT}. + - parseAction is the parse action to be associated with + expressions matching this operator expression (the + parse action tuple member may be omitted); if the parse action + is passed a tuple or list of functions, this is equivalent to + calling C{setParseAction(*fn)} (L{ParserElement.setParseAction}) + - lpar - expression for matching left-parentheses (default=C{Suppress('(')}) + - rpar - expression for matching right-parentheses (default=C{Suppress(')')}) + + Example:: + # simple example of four-function arithmetic with ints and variable names + integer = pyparsing_common.signed_integer + varname = pyparsing_common.identifier + + arith_expr = infixNotation(integer | varname, + [ + ('-', 1, opAssoc.RIGHT), + (oneOf('* /'), 2, opAssoc.LEFT), + (oneOf('+ -'), 2, opAssoc.LEFT), + ]) + + arith_expr.runTests(''' + 5+3*6 + (5+3)*6 + -2--11 + ''', fullDump=False) + prints:: + 5+3*6 + [[5, '+', [3, '*', 6]]] + + (5+3)*6 + [[[5, '+', 3], '*', 6]] + + -2--11 + [[['-', 2], '-', ['-', 11]]] + """ + ret = Forward() + 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: + raise ValueError("if numterms=3, opExpr must be a tuple or list of two expressions") + opExpr1, opExpr2 = opExpr + thisExpr = Forward().setName(termName) + if rightLeftAssoc == opAssoc.LEFT: + if arity == 1: + matchExpr = FollowedBy(lastExpr + opExpr) + Group( lastExpr + OneOrMore( opExpr ) ) + elif arity == 2: + if opExpr is not None: + matchExpr = FollowedBy(lastExpr + opExpr + lastExpr) + Group( lastExpr + OneOrMore( opExpr + lastExpr ) ) + else: + matchExpr = FollowedBy(lastExpr+lastExpr) + Group( lastExpr + OneOrMore(lastExpr) ) + elif arity == 3: + matchExpr = FollowedBy(lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr) + \ + Group( lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr ) + else: + raise ValueError("operator must be unary (1), binary (2), or ternary (3)") + elif rightLeftAssoc == opAssoc.RIGHT: + if arity == 1: + # try to avoid LR with this extra test + if not isinstance(opExpr, Optional): + opExpr = Optional(opExpr) + matchExpr = FollowedBy(opExpr.expr + thisExpr) + Group( opExpr + thisExpr ) + elif arity == 2: + if opExpr is not None: + matchExpr = FollowedBy(lastExpr + opExpr + thisExpr) + Group( lastExpr + OneOrMore( opExpr + thisExpr ) ) + else: + matchExpr = FollowedBy(lastExpr + thisExpr) + Group( lastExpr + OneOrMore( thisExpr ) ) + elif arity == 3: + matchExpr = FollowedBy(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: + raise ValueError("operator must indicate right or left associativity") + if pa: + if isinstance(pa, (tuple, list)): + matchExpr.setParseAction(*pa) + else: + matchExpr.setParseAction(pa) + thisExpr <<= ( matchExpr.setName(termName) | lastExpr ) + lastExpr = thisExpr + ret <<= lastExpr + return ret + +operatorPrecedence = infixNotation +"""(Deprecated) Former name of C{L{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") +unicodeString = Combine(_L('u') + quotedString.copy()).setName("unicode string literal") + +def nestedExpr(opener="(", closer=")", content=None, ignoreExpr=quotedString.copy()): + """ + Helper method for defining nested lists enclosed in opening and closing + delimiters ("(" and ")" are the default). + + Parameters: + - opener - opening character for a nested list (default=C{"("}); can also be a pyparsing expression + - closer - closing character for a nested list (default=C{")"}); can also be a pyparsing expression + - content - expression for items within the nested lists (default=C{None}) + - ignoreExpr - expression for ignoring opening and closing delimiters (default=C{quotedString}) + + If an expression is not provided for the content argument, the nested + expression will capture all whitespace-delimited content between delimiters + as a list of separate values. + + Use the C{ignoreExpr} argument to define expressions that may contain + opening or closing characters that should not be treated as opening + or closing characters for nesting, such as quotedString or a comment + expression. Specify multiple expressions using an C{L{Or}} or C{L{MatchFirst}}. + The default is L{quotedString}, but if no expressions are to be ignored, + then pass C{None} for this argument. + + Example:: + data_type = oneOf("void int short long char float double") + decl_data_type = Combine(data_type + Optional(Word('*'))) + ident = Word(alphas+'_', alphanums+'_') + number = pyparsing_common.number + arg = Group(decl_data_type + ident) + LPAR,RPAR = map(Suppress, "()") + + code_body = nestedExpr('{', '}', ignoreExpr=(quotedString | cStyleComment)) + + c_function = (decl_data_type("type") + + ident("name") + + LPAR + Optional(delimitedList(arg), [])("args") + RPAR + + code_body("body")) + c_function.ignore(cStyleComment) + + source_code = ''' + int is_odd(int x) { + return (x%2); + } + + int dec_to_hex(char hchar) { + if (hchar >= '0' && hchar <= '9') { + return (ord(hchar)-ord('0')); + } else { + return (10+ord(hchar)-ord('A')); + } + } + ''' + for func in c_function.searchString(source_code): + print("%(name)s (%(type)s) args: %(args)s" % func) + + prints:: + is_odd (int) args: [['int', 'x']] + dec_to_hex (int) args: [['char', 'hchar']] + """ + 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 ignoreExpr is not None: + 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())) + 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())) + else: + 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) ) + else: + 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): + """ + Helper method for defining space-delimited indentation blocks, such as + those used to define block statements in Python source code. + + Parameters: + - blockStatementExpr - expression defining syntax of statement that + is repeated within the indented block + - indentStack - list created by caller to manage indentation stack + (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 statements + (default=C{True}) + + A valid block must contain at least one C{blockStatement}. + + Example:: + data = ''' + def A(z): + A1 + B = 100 + G = A2 + A2 + A3 + B + def BB(a,b,c): + BB1 + def BBA(): + bba1 + bba2 + bba3 + C + D + def spam(x,y): + def eggs(z): + pass + ''' + + + indentStack = [1] + stmt = Forward() + + identifier = Word(alphas, alphanums) + funcDecl = ("def" + identifier + Group( "(" + Optional( delimitedList(identifier) ) + ")" ) + ":") + func_body = indentedBlock(stmt, indentStack) + 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 ) + + module_body = OneOrMore(stmt) + + parseTree = module_body.parseString(data) + parseTree.pprint() + prints:: + [['def', + 'A', + ['(', 'z', ')'], + ':', + [['A1'], [['B', '=', '100']], [['G', '=', 'A2']], ['A2'], ['A3']]], + 'B', + ['def', + 'BB', + ['(', 'a', 'b', 'c', ')'], + ':', + [['BB1'], [['def', 'BBA', ['(', ')'], ':', [['bba1'], ['bba2'], ['bba3']]]]]], + 'C', + 'D', + ['def', + 'spam', + ['(', 'x', 'y', ')'], + ':', + [[['def', 'eggs', ['(', 'z', ')'], ':', [['pass']]]]]]] + """ + def checkPeerIndent(s,l,t): + if l >= len(s): return + curCol = col(l,s) + if curCol != indentStack[-1]: + if curCol > indentStack[-1]: + raise ParseFatalException(s,l,"illegal nesting") + raise ParseException(s,l,"not a peer entry") + + def checkSubIndent(s,l,t): + curCol = col(l,s) + if curCol > indentStack[-1]: + indentStack.append( curCol ) + else: + raise ParseException(s,l,"not a subentry") + + 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() + + NL = OneOrMore(LineEnd().setWhitespaceChars("\t ").suppress()) + 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) + else: + smExpr = Group( Optional(NL) + + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) ) + blockStatementExpr.ignore(_bslash + LineEnd()) + return smExpr.setName('indented block') + +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(),'><& "\'')) +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""" + return _htmlEntityMap.get(t.entity) + +# it's easy to get these comment structures wrong - they're very common, so may as well make them available +cStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/').setName("C style comment") +"Comment of the form C{/* ... */}" + +htmlComment = Regex(r"<!--[\s\S]*?-->").setName("HTML comment") +"Comment of the form C{<!-- ... -->}" + +restOfLine = Regex(r".*").leaveWhitespace().setName("rest of line") +dblSlashComment = Regex(r"//(?:\\\n|[^\n])*").setName("// comment") +"Comment of the form C{// ... (to end of line)}" + +cppStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/'| dblSlashComment).setName("C++ style comment") +"Comment of either form C{L{cStyleComment}} or C{L{dblSlashComment}}" + +javaStyleComment = cppStyleComment +"Same as C{L{cppStyleComment}}" + +pythonStyleComment = Regex(r"#.*").setName("Python style comment") +"Comment of the form C{# ... (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") +"""(Deprecated) Predefined expression of 1 or more printable words or quoted strings, separated by commas. + This expression is deprecated in favor of L{pyparsing_common.comma_separated_list}.""" + +# some other useful expressions - using lower-case class name since we are really using this as a namespace +class pyparsing_common: + """ + Here are some common low-level expressions that may be useful in jump-starting parser development: + - numeric forms (L{integers<integer>}, L{reals<real>}, L{scientific notation<sci_real>}) + - common L{programming identifiers<identifier>} + - network addresses (L{MAC<mac_address>}, L{IPv4<ipv4_address>}, L{IPv6<ipv6_address>}) + - ISO8601 L{dates<iso8601_date>} and L{datetime<iso8601_datetime>} + - L{UUID<uuid>} + - L{comma-separated list<comma_separated_list>} + Parse actions: + - C{L{convertToInteger}} + - C{L{convertToFloat}} + - C{L{convertToDate}} + - C{L{convertToDatetime}} + - C{L{stripHTMLTags}} + - C{L{upcaseTokens}} + - C{L{downcaseTokens}} + + Example:: + pyparsing_common.number.runTests(''' + # any int or real number, returned as the appropriate type + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + ''') + + pyparsing_common.fnumber.runTests(''' + # any int or real number, returned as float + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + ''') + + pyparsing_common.hex_integer.runTests(''' + # hex numbers + 100 + FF + ''') + + pyparsing_common.fraction.runTests(''' + # fractions + 1/2 + -3/4 + ''') + + pyparsing_common.mixed_integer.runTests(''' + # mixed fractions + 1 + 1/2 + -3/4 + 1-3/4 + ''') + + import uuid + pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID)) + pyparsing_common.uuid.runTests(''' + # uuid + 12345678-1234-5678-1234-567812345678 + ''') + prints:: + # any int or real number, returned as the appropriate type + 100 + [100] + + -100 + [-100] + + +100 + [100] + + 3.14159 + [3.14159] + + 6.02e23 + [6.02e+23] + + 1e-12 + [1e-12] + + # any int or real number, returned as float + 100 + [100.0] + + -100 + [-100.0] + + +100 + [100.0] + + 3.14159 + [3.14159] + + 6.02e23 + [6.02e+23] + + 1e-12 + [1e-12] + + # hex numbers + 100 + [256] + + FF + [255] + + # fractions + 1/2 + [0.5] + + -3/4 + [-0.75] + + # mixed fractions + 1 + [1] + + 1/2 + [0.5] + + -3/4 + [-0.75] + + 1-3/4 + [1.75] + + # uuid + 12345678-1234-5678-1234-567812345678 + [UUID('12345678-1234-5678-1234-567812345678')] + """ + + convertToInteger = tokenMap(int) + """ + Parse action for converting parsed integers to Python int + """ + + convertToFloat = tokenMap(float) + """ + Parse action for converting parsed numbers to Python float + """ + + 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)) + """expression that parses a hexadecimal integer, returns an int""" + + signed_integer = Regex(r'[+-]?\d+').setName("signed integer").setParseAction(convertToInteger) + """expression that parses an integer with optional leading sign, returns an int""" + + fraction = (signed_integer().setParseAction(convertToFloat) + '/' + signed_integer().setParseAction(convertToFloat)).setName("fraction") + """fractional expression of an integer divided by an integer, returns a float""" + fraction.addParseAction(lambda t: t[0]/t[-1]) + + mixed_integer = (fraction | signed_integer + Optional(Optional('-').suppress() + fraction)).setName("fraction or mixed integer-fraction") + """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) + """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) + """expression that parses a floating point number with optional scientific notation and returns a float""" + + # streamlining this expression makes the docs nicer-looking + number = (sci_real | real | signed_integer).streamline() + """any numeric expression, returns the corresponding Python type""" + + 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") + """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 (C{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") + _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") + "IPv6 address (long, short, or mixed form)" + + mac_address = Regex(r'[0-9a-fA-F]{2}([:.-])[0-9a-fA-F]{2}(?:\1[0-9a-fA-F]{2}){4}').setName("MAC address") + "MAC address xx:xx:xx:xx:xx (may also have '-' or '.' delimiters)" + + @staticmethod + def convertToDate(fmt="%Y-%m-%d"): + """ + Helper to create a parse action for converting parsed date string to Python datetime.date + + Params - + - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%d"}) + + Example:: + date_expr = pyparsing_common.iso8601_date.copy() + date_expr.setParseAction(pyparsing_common.convertToDate()) + print(date_expr.parseString("1999-12-31")) + prints:: + [datetime.date(1999, 12, 31)] + """ + def cvt_fn(s,l,t): + try: + return datetime.strptime(t[0], fmt).date() + except ValueError as ve: + raise ParseException(s, l, str(ve)) + return cvt_fn + + @staticmethod + def convertToDatetime(fmt="%Y-%m-%dT%H:%M:%S.%f"): + """ + Helper to create a parse action for converting parsed datetime string to Python datetime.datetime + + Params - + - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%dT%H:%M:%S.%f"}) + + Example:: + dt_expr = pyparsing_common.iso8601_datetime.copy() + dt_expr.setParseAction(pyparsing_common.convertToDatetime()) + print(dt_expr.parseString("1999-12-31T23:59:59.999")) + prints:: + [datetime.datetime(1999, 12, 31, 23, 59, 59, 999000)] + """ + def cvt_fn(s,l,t): + try: + return datetime.strptime(t[0], fmt) + except ValueError as ve: + raise ParseException(s, l, str(ve)) + return cvt_fn + + iso8601_date = Regex(r'(?P<year>\d{4})(?:-(?P<month>\d\d)(?:-(?P<day>\d\d))?)?').setName("ISO8601 date") + "ISO8601 date (C{yyyy-mm-dd})" + + iso8601_datetime = Regex(r'(?P<year>\d{4})-(?P<month>\d\d)-(?P<day>\d\d)[T ](?P<hour>\d\d):(?P<minute>\d\d)(:(?P<second>\d\d(\.\d*)?)?)?(?P<tz>Z|[+-]\d\d:?\d\d)?').setName("ISO8601 datetime") + "ISO8601 datetime (C{yyyy-mm-ddThh:mm:ss.s(Z|+-00:00)}) - trailing seconds, milliseconds, and timezone optional; accepts separating C{'T'} or C{' '}" + + uuid = Regex(r'[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}').setName("UUID") + "UUID (C{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx})" + + _html_stripper = anyOpenTag.suppress() | anyCloseTag.suppress() + @staticmethod + def stripHTMLTags(s, l, tokens): + """ + Parse action to remove HTML tags from web page HTML source + + Example:: + # strip HTML links from normal text + text = '<td>More info at the <a href="http://pyparsing.wikispaces.com">pyparsing</a> wiki page</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) # -> 'More info at the pyparsing wiki page' + """ + 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") + """Predefined expression of 1 or more printable words or quoted strings, separated by commas.""" + + upcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).upper())) + """Parse action to convert tokens to upper case.""" + + downcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).lower())) + """Parse action to convert tokens to lower case.""" + + +if __name__ == "__main__": + + selectToken = CaselessLiteral("select") + fromToken = CaselessLiteral("from") + + ident = Word(alphas, alphanums + "_$") + + columnName = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens) + columnNameList = Group(delimitedList(columnName)).setName("columns") + columnSpec = ('*' | columnNameList) + + tableName = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens) + tableNameList = Group(delimitedList(tableName)).setName("tables") + + simpleSQL = selectToken("command") + columnSpec("columns") + fromToken + tableNameList("tables") + + # demo runTests method, including embedded comments in test string + simpleSQL.runTests(""" + # '*' as column list and dotted table name + select * from SYS.XYZZY + + # caseless match on "SELECT", and casts back to "select" + SELECT * from XYZZY, ABC + + # list of column names, and mixed case SELECT keyword + Select AA,BB,CC from Sys.dual + + # multiple tables + Select A, B, C from Sys.dual, Table2 + + # invalid SELECT keyword - should fail + Xelect A, B, C from Sys.dual + + # incomplete command - should fail + Select + + # invalid column name - should fail + Select ^^^ frox Sys.dual + + """) + + pyparsing_common.number.runTests(""" + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + """) + + # any int or real number, returned as float + pyparsing_common.fnumber.runTests(""" + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + """) + + pyparsing_common.hex_integer.runTests(""" + 100 + FF + """) + + import uuid + pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID)) + pyparsing_common.uuid.runTests(""" + 12345678-1234-5678-1234-567812345678 + """) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/pytoml/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/pytoml/__init__.py new file mode 100644 index 0000000..8dc7315 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/pytoml/__init__.py @@ -0,0 +1,3 @@ +from .core import TomlError +from .parser import load, loads +from .writer import dump, dumps diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/pytoml/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/pytoml/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..74af274f4598b4323429c1a65f12543dd5a710d7 GIT binary patch literal 339 zcmXw!!Ait15QdvJ?XKd2cb}k#HPuCBK|}<vUffez2<;}j8%>%pX}fNp!58tBa`ogZ zcrq#Y!+e?lhaodhv)O6n^?6aR*Z%zu=3lXI9(~!ugGCI<NTCv;(8n@XNtq~I;?XBE zRau#-NjdQzzeaibgZx;I+{sES`3#^Tj~$k}VlEA|!Lm*nmj>FGeCqH<1BdXj%S;89 z10>!69+Lxz)+cF5GLNqa!uBJ64KX14s^z4wfNZs794t|Lvbi#JIV|6b!(z(@d%Ni2 z`lB6G;k9eXiWp($qOoly<^1NZ-oJPCE`(#zo;OSbF~`=QK`0fCXeqrkM>oA!nst&t MghOpu@eG}#Kk83e`v3p{ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/pytoml/__pycache__/core.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/pytoml/__pycache__/core.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..faa076a1060f1eb233f0f13ded2ac3f75c59db32 GIT binary patch literal 948 zcmbVKOK;Oa5Z?78aZ8Fs#Q}*6l{nNAjSCf^B7`as;+6yS6d|n~?<RFvKbUm_b(|AD z@*~<Kf5}(=1ric78#M|DE{rwbjQ277?Kk^!XJ?zCeZ4z+|C2NJoqn#(!{h|r+(vlA zB$NCCU9m6jkW1$s3*7`~*5+V#f^P03D28j;(2=<Ef(>2iN)Mwaec8e2%P#H@+O5+f z)2{&vNPOHyMzM?j3f=S(Dt5^m*6_w@+{U}|Ips_^_|JrkV@!CBhv-X&Mfo7?w7s{p zyh<}=OSgd#X`WU>wB1Y@6Hip@=`>fZn-sbY#;I0$oT<=nJ)`s(=;lB?phG}xzA@Os z@Iyx>r1Q8^(L9D|TxhAlMA=!CJS@d=eLOw<bTpQ=d2%#|N1v-YJ4Bo0(P>ns<w2U8 zD%Seo@zc@ShuLUCgVx1d<+6aNJg-oYC@Dbo%X4t?NRrjqF7aL7v0uHrmaTt%wFKK| zjUv&u`rW}q@=MmRDQY%F#ipp&)VuOfDQ8gMTrBq&%Ln%s%kUY2-*(0YWN~FLy`cd~ z5^@MISRqzGwA!u^rUD^IA46;zuWxM<w6p)mZ*N^^f3XKd^bZU}A8z20f9u&l_~L5- zRU+Zu2I1cnT}{(F!nO1=@a1d^kri^LDenpKaTe><jBOH7E!ZI-88(0<0_q95p~eI} e=mxGG8-xy!V)kcaldWOJ4W6$~ePOrbQuYhcSk9dQ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/pytoml/__pycache__/parser.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/pytoml/__pycache__/parser.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ecad4741bb3adc36fc71e512df698a0b6cd9b109 GIT binary patch literal 11151 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 Z4{w(bkAQ^{)QzIttII9rPNHV`{{i_8Ov3;G literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/pytoml/__pycache__/writer.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/pytoml/__pycache__/writer.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..93c6100b9b6a6893f7f4d24174a2d433173fce1a GIT binary patch literal 3850 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/pytoml/core.py b/venv/lib/python3.7/site-packages/pip/_vendor/pytoml/core.py new file mode 100644 index 0000000..c182734 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/pytoml/core.py @@ -0,0 +1,13 @@ +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.7/site-packages/pip/_vendor/pytoml/parser.py b/venv/lib/python3.7/site-packages/pip/_vendor/pytoml/parser.py new file mode 100644 index 0000000..9f94e92 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/pytoml/parser.py @@ -0,0 +1,374 @@ +import string, re, sys, datetime +from .core import TomlError + +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('[bnrt"\'\\\\/f]') +_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): + res.append(_chr(int(s.last().group(1), 16))) + 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)*))?') +_datetime_re = re.compile(r'(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(\.\d+)?(?:Z|([+-]\d{2}):(\d{2}))') + +_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(_datetime_re): + m = s.last() + s0 = m.group(0) + 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 + dt = datetime.datetime(y, m, d, H, M, S, int(micro * 1000000), tz) + return 'datetime', s0, dt, 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 + +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.7/site-packages/pip/_vendor/pytoml/writer.py b/venv/lib/python3.7/site-packages/pip/_vendor/pytoml/writer.py new file mode 100644 index 0000000..6eaf5d7 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/pytoml/writer.py @@ -0,0 +1,127 @@ +from __future__ import unicode_literals +import io, datetime, math, sys + +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) + '"' + + +def _escape_id(s): + if any(not c.isalnum() and c not in '-_' for c in s): + return _escape_string(s) + return s + + +def _format_list(v): + return '[{0}]'.format(', '.join(_format_value(obj) for obj in v)) + +# Formula from: +# https://docs.python.org/2/library/datetime.html#datetime.timedelta.total_seconds +# Once support for py26 is dropped, this can be replaced by td.total_seconds() +def _total_seconds(td): + return ((td.microseconds + + (td.seconds + td.days * 24 * 3600) * 10**6) / 10.0**6) + +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): + offs = v.utcoffset() + offs = _total_seconds(offs) // 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 + elif isinstance(v, list): + return _format_list(v) + 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.7/site-packages/pip/_vendor/requests/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/requests/__init__.py new file mode 100644 index 0000000..3f3f4f2 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/requests/__init__.py @@ -0,0 +1,138 @@ +# -*- coding: utf-8 -*- + +# __ +# /__) _ _ _ _ _/ _ +# / ( (- (/ (/ (- _) / _) +# / + +""" +Requests HTTP Library +~~~~~~~~~~~~~~~~~~~~~ + +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 + True + +... or POST: + + >>> payload = dict(key1='value1', key2='value2') + >>> r = requests.post('http://httpbin.org/post', data=payload) + >>> print(r.text) + { + ... + "form": { + "key2": "value2", + "key1": "value1" + }, + ... + } + +The other HTTP methods are supported - see `requests.api`. Full documentation +is at <http://python-requests.org>. + +:copyright: (c) 2017 by Kenneth Reitz. +:license: Apache 2.0, see LICENSE for more details. +""" + +from pip._vendor import urllib3 +from pip._vendor import chardet +import warnings +from .exceptions import RequestsDependencyWarning + + +def check_compatibility(urllib3_version, chardet_version): + urllib3_version = urllib3_version.split('.') + assert urllib3_version != ['dev'] # Verify urllib3 isn't installed from git. + + # Sometimes, urllib3 only reports its version as 16.1. + if len(urllib3_version) == 2: + urllib3_version.append('0') + + # Check urllib3 for compatibility. + major, minor, patch = urllib3_version # noqa: F811 + major, minor, patch = int(major), int(minor), int(patch) + # urllib3 >= 1.21.1, <= 1.23 + assert major == 1 + assert minor >= 21 + assert minor <= 23 + + # Check chardet for compatibility. + major, minor, patch = chardet_version.split('.')[:3] + major, minor, patch = int(major), int(minor), int(patch) + # chardet >= 3.0.2, < 3.1.0 + assert major == 3 + assert minor < 1 + assert patch >= 2 + + +def _check_cryptography(cryptography_version): + # cryptography < 1.3.4 + try: + cryptography_version = list(map(int, cryptography_version.split('.'))) + except ValueError: + return + + if cryptography_version < [1, 3, 4]: + warning = 'Old version of cryptography ({0}) may cause slowdown.'.format(cryptography_version) + warnings.warn(warning, RequestsDependencyWarning) + +# Check imported dependencies for compatibility. +try: + check_compatibility(urllib3.__version__, chardet.__version__) +except (AssertionError, ValueError): + warnings.warn("urllib3 ({0}) or chardet ({1}) doesn't match a supported " + "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: + try: + 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 + +# urllib3's DependencyWarnings should be silenced. +from pip._vendor.urllib3.exceptions import DependencyWarning +warnings.simplefilter('ignore', DependencyWarning) + +from .__version__ import __title__, __description__, __url__, __version__ +from .__version__ import __build__, __author__, __author_email__, __license__ +from .__version__ import __copyright__, __cake__ + +from . import utils +from . import packages +from .models import Request, Response, PreparedRequest +from .api import request, get, head, post, patch, put, delete, options +from .sessions import session, Session +from .status_codes import codes +from .exceptions import ( + RequestException, Timeout, URLRequired, + TooManyRedirects, HTTPError, ConnectionError, + FileModeWarning, ConnectTimeout, ReadTimeout +) + +# Set default logging handler to avoid "No handler found" warnings. +import logging +try: # Python 2.7+ + from logging import NullHandler +except ImportError: + class NullHandler(logging.Handler): + def emit(self, record): + pass + +logging.getLogger(__name__).addHandler(NullHandler()) + +# FileModeWarnings go off per the default. +warnings.simplefilter('default', FileModeWarning, append=True) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0153623cd7293a7a16c2657019d34d391a9f9248 GIT binary patch literal 3796 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4db1e83ed429c16a009b25b99da89c8c305b240e GIT binary patch literal 559 zcmZ8e%Z}496m>d%q!}s@ED(={w<FQG?TAMaLIZ3@LP8_x%0jZz*lkP`$M{jGzXARL zi7o6{@HJh+53pv%O@|`jTE05xTpjyf`|)6qAc%K2<}bfS2z_tJK7gYW*!C7Ajws?0 zjd+W;_yIlOZQAA?+TmT=<vrTtF^zej_IdIG9UX3CBVK!9oefvdHm;}@KAp|Z@S-;O z)K{6ZX}DfEr|%P@clF`kkk)1yx|4J~O~*32)<R+MR464}fu9TMLby_ilhwIm8ewNh z9_cJE1fHa$aPvv6H%2ZChbN=)J^YW|Uw~o0efWfbe0=`}19*0nZ2OEk=}N)a_9A0k z*xX3%WUWBxG3HGP;E=JkF!o#p$K1=3gPt&!c^J_EzVru+DwDrmrObu0&EW&a@_lbW zW1!gz3ZIc_+S;X`o@gW2nG<B48M3HL4!4r3Ao*CcX_&qmy*Xa+VDB8S&E%~M)d*s# z$c$*Ihf-OWmF4jE-FdO{^JOFMHZ-qzZOHze$zS87db5omR5kadc-U#a{4%6=^#A$= D>q@cr literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..977539a2abef0fd5f7432522d4e2b5cfad343552 GIT binary patch literal 1317 zcmZ8h&5j&35N>z({G`c_R#8qwLOwDQnOQa>D61$U2?25-ir7U$Bcx7GyJp+jZo5-< z&!k5K2gs3!fFl=9yajL2S5CYFC(7;_1S!cLySiLe{=U!i=;$a3$bP!D{Pv4D2>x`N zgGIFXgoc^XB!WdCm<UT&g^RF?7Eu*1Vit&NA{K);Y%vf+F?tg$hGKjkOq1<z3Bs!e zj5V`VDhsHxGHt9ZP4fN!EJ>cDUP}RnyU)_LeATGjO05jHMP_-1z;oI)6$pOFRknQD z@~`$al1(A=f(xiY39c1~*A}4yidw<O?R*2gfU*WO{C(3<cxEVXRcCgZ{Ke>!)2JIt zlh*BN_s+7BrIji*7Q4tzgUsYo<{`y7bLhD7n1)Bl2D`wrA45Fe1>c40T^l0b1wThS z_6wtZLhHC+??OU|ZU6XOu0ipPQ+BB?xn916+<w3jE;AG*7{m37+qMShvkej+8Lesr z1IlI&A&N*ina63LM=II^R}`>@L-IZis9XzID<hNy>^GYN5PTX1IhD<@o$-r8QaR&5 zH~iuG<EKw~qkL0Vmjp4Dz>PF8^9QGcE|EqmV>6WlI$+Qt)eU_~=!U);IE4E)yYZo! zF4B$tHNfi>|93mDQLZx!^L2*v6_p~o=2bDzKdjSx+j}ohHg{HHYwq4z<LPU=txm`; z)%;>!%lfu&pe%2H^zpK|YL=JI=|@UP3yt%GCg*Qya#pw9vDIl0nj@W1nmB4*SHU1* z!!Tyo!z4uK&7E4Dx!*AjuY$X@IH<r(Z1@9fCr$x^6hJS9SdRl6UnO|L=pcEb^Wd96 z#H5D7_V-VLG+IdoT&@UeN#y*?o>nAedIC118}8Z2iwv`z&X`%^IXJ7yQ8~hSv%kUF z+lj2^c>(#=jDOh}%a?En@EM$voHCTQ{CR5&($^_}K?z^<ET5s1(HUQAUHSt!petW| z_G~)9A+3=9LV|Ac&=^3c&L@Z(apasgzV2`I#3>N`hbimEhekd5{dDBQkM{ti^c?-W zdyl+57o!OaS;AsAVR(bQ&!)_`F&%ZIG!;5e({9*5YcIiGjIJ|Joj>!Ra*kj0HOKcW TEt(P@TywSDed6$DlpOy9%<g@a literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fcd09060c6a444332b35be807243275164d695bc GIT binary patch literal 16782 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/api.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/api.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b6bd6c64eff361e21d4757ac9c45363792cde5c2 GIT binary patch literal 6508 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0ce468557f0ae6cdfffc5a031f0cf1862465a3fd GIT binary patch literal 8353 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/certs.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/certs.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0e85405826b2609f195406ca7a637330c5ef6c76 GIT binary patch literal 642 zcmY*WO^eh(5bb1VbZA^J9=#ME#DUplbx~Om@dE@wJm{PjA#~D}q@AQYTiwa-%t3^` zdh}2DbG+uLC;x&cJDKdkf-brrU9aA&dUbfnnU8OG(@#GG#(ocv>j?ejg+KPbPm-N6 z8OX2->hLTK7#_%jO-T1}hT#>v3IZl)AK7x=zVS4i@VrIqY?L86%fI{=oUcn|p*FIu z5C~mM+JY+)8p0fjP=dr<w3UO`FJYiixypn?NLwu{j9^_NAt=j@uC`z_!mqF2M~dN| zlc~qYR0@sAHlo0Y^S3!{O$)+T??I&t_%Nwm0Y*i%g4_@Yc&BuG2~t@{Ds7!I8b-Vp z+H*;cx>ICyjoPh7(oAT`N}&rJn|ljNt9@M#7lYylOK@g#>^oR&1bJK4mQM=hV0bdg z|M;=9Wzf&Z+J2EFwNN@q-Y@6<%_NZ~OOpOhqnaq`P)kGOwEd`P*xc}6iyHl(c|%IO zAB+|rAJbnGd#v-l<4#bVn@S?txGv-DVUwKhPCp-CoaAz6pPY2`=+f=#V;_Z%*Rk(+ wq_lOSs*WB%P0LN276Uk*Nl1LX|9ISg)NK33v;DrG-}V~p4WDMgt#A?i1F##;ZvX%Q literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..609cf77fcf8c2042e8004acb5a272bc950e94470 GIT binary patch literal 1652 zcmZux-EP}96qYPomSx$_|6h~UU9+xU8#|5HZ3Tv5Sc?I>$U30CA_fThp=~ClsF1W< z=VDK=i@nBfcQNcK_5i%yRbHW2JCu|y-9mw%zH>+(eTO{MH=T}eLHqem{NtZZ%lgY0 z*UbU)HFWvAZCR;>tkh0x)MhnQvkiBsgB<Lf)lmaCQhV1*>*qD(R=fecS<Lc~hh6aw zxJz5iM?Pz#HVaU|I;g|CsLOh&$5zk^TScpE4XqW?n{=J6qjk1{HrOWGWLs#9ZKLgC z%%eMO7wuLm_Rt>0ZqYkzAMF=DpB}ISbWrd%{eay?cUd3x**$cx@CEckb|2lhEqsVR zg8l%1j1KWb^bim5C-~9CL5~fa)X-7(2X6jii{Ic29XkA<BBTDl8C|RF(veYlYj!<) z%$}gVLQRXF+)zILM|l9s3zhKgHvRPdEGp%P_yMQ~1g%E>BY1=MiH(j@=an^BxxDZN zzL;aF<S^kZkCgw@`_1=X&xq_Zp3W)m&!Q})SoR6axlsLb35f|MYS|}JLZp6-)f<en z{trtv<5~Zt4{Q9&7!Um`Q$Pb-H<MW;Qmnqes)6Iml+&Q48y9n~ux`$?lK90d%;{X} zpmLU0Yc43x5}so1PqE4ce@ie-GGrOX%RG`&@7%OPoGpmp8N-><TmP=P=^r$-2Z8fQ zNQet;o|U`_{EU;V7?wFCtc`*cPee3@bb7_KaHdoqQX&<&+*1xwC@}Ap5+s{`_j2H9 z?|DRN6jMm@G|F>u>+b1X8Bb-yg7!<;8iCUnBvAujbYXKu&%la-RRb*p4Fj$LxSp2q z46FeR8e-jWbA3hIKwzK)0MT0s=jQ~UMPl$&H^VUHNf_#OPV!;6z*)+LFlVA2xr7Z} zU?B<5LXu6muEPYOT_VGLc~ZT{x_%~krd`+%O5$5Z6>4u$b8BiQ11Nza+DVbfwPXmd z-RFgRv0*aWG*jCNrxYg&R7$aB+}j3r0MOt@R>Lync$i1Yc{Igx$jfaGQ`l#*YhpQ4 z3Eht8gesDS#%RP#1%(AANy=)ABMBGA9H@2(lv15?pp6OTk<y)P&afa!sFpdb>c9j% z#iBBUQUM4s_0_Gc>I&+*sUERsWCVu7l{Duhb&YV{yOHEDij!Y0@rB9Kz`J~u3$ln5 z9xWm<nsBH~AxCUBN}lB5v&&~^$8W}y^iqB{UWk*o>XIEpn`WceBiNoJl1T+cdGz%2 zcy>OIr^Z?Isv1Vu|A<j};fMKBdta8ngs;rW%5MScwV>uTT_<pYmgm;($IiYT*dFx2 Z-hi>XT|U0;*IfJ9HlyXUQH^;p`)^;<+g|_x literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8bfa3a3db44dcfd5d7c3d2fbb78a9f74d4d6e460 GIT binary patch literal 18761 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5f34d8ae036c6df3f4d5cd5eee881ba66d539c7c GIT binary patch literal 5514 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/help.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/help.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..411b0a8fd72710f4a58d4fd971cfd781e77ebca6 GIT binary patch literal 2706 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 O=$qxg>EH1k-~1nPVC}sC literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..861ac77e4ed7011f72e0c4e07b456842758f2cb8 GIT binary patch literal 1006 zcmY*YOK;RL5VrH!N5mrW5F9|r2M+9^Nui>sRaNom0jbhfYAcW`Q0k4HY}o83wY}T! zD$8YiMEnLga^&yi%D?CZ#_n!uCz`SIdHiMOv-7sq@(|d!N8L|<ErkB)m!-iwdJQh0 zKw#(yF`VEd%q(V~qa%ws%!ScrwFA_yPk(!YpNzOv((mPYUwU6}nCBh#Qb`6m8)cjn zA|I!WOQL$5M6{sYG)q+qK%5H$?k~uQAtQ1k6(9JX_hwAfjCO&;ENpt-@v-2t$cK_2 zA8&dD><~zo7)kh$3#vFHvB(F6k_EHxRgGm*1Pxx94YPOP@-74gO*88pDZGQ`c#fe} zyA$C>vQ|i^OYILJl<4#A87^^xV(SCK=)__Ow&2b$)V3<iU#(m|=0hd)P7^Njpb+U8 z3Jk_n1aY1*E@Uw11<~^&+?Z~BSv_5g*;KBtjm3*IH65&iCBxt_DAHmj9ZE&BY~|&v zZm&P;CK@yz!e>}6g5{wEMlQdYTr{_|Bxi-#)(uKsiG!wu@tBS>6<+3TWqCw1x$R#i zL;Vg*BUQQY_x5%V{&#RWbAhI6-5|NMq(@jZVIFCzwAH{J@Lh1Z523_GL!mj+(*3|C z`ib>Sbd*(MhUb=e29g4H_Oyg^`22Y0lul{IxU|3HnOnNd>Nka7x-;v<|A<OUpVD-F zCzS<NQ4ekvHMfQ6`qO+!#f0QT0Fx9{B1Ot0PV$&As;FNz!Vp@|!m!h}MIEZE?1ZbT z-lLK#CEB&h?(<3I8lkGD9zwmds`XE)NMz+`sPc@GX62ez3z-&`nUsfGh5HbY<zWvy y;5G1DxB-v22Y9FLRP``qc@&1C0f3RyEM22ESIY1=wl06O?H1%pqc*PDjoLrwVhY;; literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/models.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/models.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a6c77e8788ad4b2e396e684f6cdda82ce9806cbd GIT binary patch literal 23973 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/packages.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/packages.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..138a5e51ab80348da77ec4d0e3bdd624c96cde89 GIT binary patch literal 519 zcmYjM!EVz)5S_J?I2am*3sHr{J%@S=X+f2u3L%cD7mzAhAj`>4;%zqeW_O*YK5&V+ z@ey$33;374a^e>_F=-pbNb_d)X=dlWHwOnXP<(wl`S>#c__cfNqeIPWO8c2WfM5zz z*k}>Fg-=DwM2KtvX@DUHTZXMIAREKx9kvm!I$K6l=V^oy28+O6VDznvfoKijJ2NN5 zJ`mxS3HBv8gf!l5U~~w(D%uziU<|91OIY<T>F#?Nc7BrvxEO{$s*O@|GV(1c%G^iO zA~ynE^GHjbWNR!%WfISl=Gp&*!Bvgc*+l2lMLtKH3?KT?-dG>qGroVfiz3@IahA!Y zu8hkv-%-^xSJt<bw9ZG%O4JIi52^97b-8i&TDroA3QOOsOKor_H}n||`~dTq)ZfA% z!?ls?+#z4*hR-S`&{)1K`1HBX&YH8U<Ll8(H1_3aZC-3#vplAlm;3`KKS#2pTS^_B tzM2$^dNSXUw|VcJ?~U?*M)i&Fj_>rIGm>F@1l@Mbx~v!W*%Q`he*rq=n(qJr literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d9d404cc2a6a6ebdb2c9bb285a297c8ba8321a8d GIT binary patch literal 18578 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 Zfgz`k%T)|W_fMB6CVxh2;NsuO{|Bi$rK$h` literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/status_codes.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/status_codes.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9a983686712157091cec8807bd164c812ae3fa43 GIT binary patch literal 4175 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 K6w2Pn<o^JJm_K#^ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cb4a9aa4340ac1077b34f7b7de223d54afc22b9e GIT binary patch literal 4388 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 MEr4Tf+1LK`A6+Iac>n+a literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/utils.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/utils.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..34eaef4394e7988d7f18a57a2d04c574d1d1fb54 GIT binary patch literal 21958 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 R61a0)b{jGn6S!;J{|3wB3<CfF literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/__version__.py b/venv/lib/python3.7/site-packages/pip/_vendor/requests/__version__.py new file mode 100644 index 0000000..ef61ec0 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/requests/__version__.py @@ -0,0 +1,14 @@ +# .-. .-. .-. . . .-. .-. .-. .-. +# |( |- |.| | | |- `-. | `-. +# ' ' `-' `-`.`-' `-' `-' ' `-' + +__title__ = 'requests' +__description__ = 'Python HTTP for Humans.' +__url__ = 'http://python-requests.org' +__version__ = '2.19.1' +__build__ = 0x021901 +__author__ = 'Kenneth Reitz' +__author_email__ = 'me@kennethreitz.org' +__license__ = 'Apache 2.0' +__copyright__ = 'Copyright 2018 Kenneth Reitz' +__cake__ = u'\u2728 \U0001f370 \u2728' diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/_internal_utils.py b/venv/lib/python3.7/site-packages/pip/_vendor/requests/_internal_utils.py new file mode 100644 index 0000000..759d9a5 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/requests/_internal_utils.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- + +""" +requests._internal_utils +~~~~~~~~~~~~~~ + +Provides utility functions that are consumed internally by Requests +which depend on extremely few external helpers (such as compat) +""" + +from .compat import is_py2, builtin_str, str + + +def to_native_string(string, encoding='ascii'): + """Given a string object, regardless of type, returns a representation of + that string in the native string type, encoding and decoding where + necessary. This assumes ASCII unless told otherwise. + """ + if isinstance(string, builtin_str): + out = string + else: + if is_py2: + out = string.encode(encoding) + else: + out = string.decode(encoding) + + return out + + +def unicode_is_ascii(u_string): + """Determine if unicode string only contains ASCII characters. + + :param str u_string: unicode string to check. Must be unicode + and not Python 2 `str`. + :rtype: bool + """ + assert isinstance(u_string, str) + try: + u_string.encode('ascii') + return True + except UnicodeEncodeError: + return False diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/adapters.py b/venv/lib/python3.7/site-packages/pip/_vendor/requests/adapters.py new file mode 100644 index 0000000..f6f3f99 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/requests/adapters.py @@ -0,0 +1,530 @@ +# -*- coding: utf-8 -*- + +""" +requests.adapters +~~~~~~~~~~~~~~~~~ + +This module contains the transport adapters that Requests uses to define +and maintain connections. +""" + +import os.path +import socket + +from pip._vendor.urllib3.poolmanager import PoolManager, proxy_from_url +from pip._vendor.urllib3.response import HTTPResponse +from pip._vendor.urllib3.util import parse_url +from pip._vendor.urllib3.util import Timeout as TimeoutSauce +from pip._vendor.urllib3.util.retry import Retry +from pip._vendor.urllib3.exceptions import ClosedPoolError +from pip._vendor.urllib3.exceptions import ConnectTimeoutError +from pip._vendor.urllib3.exceptions import HTTPError as _HTTPError +from pip._vendor.urllib3.exceptions import MaxRetryError +from pip._vendor.urllib3.exceptions import NewConnectionError +from pip._vendor.urllib3.exceptions import ProxyError as _ProxyError +from pip._vendor.urllib3.exceptions import ProtocolError +from pip._vendor.urllib3.exceptions import ReadTimeoutError +from pip._vendor.urllib3.exceptions import SSLError as _SSLError +from pip._vendor.urllib3.exceptions import ResponseError + +from .models import Response +from .compat import urlparse, basestring +from .utils import (DEFAULT_CA_BUNDLE_PATH, extract_zipped_paths, + get_encoding_from_headers, prepend_scheme_if_needed, + get_auth_from_url, urldefragauth, select_proxy) +from .structures import CaseInsensitiveDict +from .cookies import extract_cookies_to_jar +from .exceptions import (ConnectionError, ConnectTimeout, ReadTimeout, SSLError, + ProxyError, RetryError, InvalidSchema, InvalidProxyURL) +from .auth import _basic_auth_str + +try: + from pip._vendor.urllib3.contrib.socks import SOCKSProxyManager +except ImportError: + def SOCKSProxyManager(*args, **kwargs): + raise InvalidSchema("Missing dependencies for SOCKS support.") + +DEFAULT_POOLBLOCK = False +DEFAULT_POOLSIZE = 10 +DEFAULT_RETRIES = 0 +DEFAULT_POOL_TIMEOUT = None + + +class BaseAdapter(object): + """The Base Transport Adapter""" + + def __init__(self): + super(BaseAdapter, self).__init__() + + def send(self, request, stream=False, timeout=None, verify=True, + cert=None, proxies=None): + """Sends PreparedRequest object. Returns Response object. + + :param request: The :class:`PreparedRequest <PreparedRequest>` being sent. + :param stream: (optional) Whether to stream the request content. + :param timeout: (optional) How long to wait for the server to send + data before giving up, as a float, or a :ref:`(connect timeout, + read timeout) <timeouts>` tuple. + :type timeout: float or tuple + :param verify: (optional) Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use + :param cert: (optional) Any user-provided SSL certificate to be trusted. + :param proxies: (optional) The proxies dictionary to apply to the request. + """ + raise NotImplementedError + + def close(self): + """Cleans up adapter specific items.""" + raise NotImplementedError + + +class HTTPAdapter(BaseAdapter): + """The built-in HTTP Adapter for urllib3. + + Provides a general-case interface for Requests sessions to contact HTTP and + HTTPS urls by implementing the Transport Adapter interface. This class will + usually be created by the :class:`Session <Session>` class under the + covers. + + :param pool_connections: The number of urllib3 connection pools to cache. + :param pool_maxsize: The maximum number of connections to save in the pool. + :param max_retries: The maximum number of retries each connection + should attempt. Note, this applies only to failed DNS lookups, socket + connections and connection timeouts, never to requests where data has + made it to the server. By default, Requests does not retry failed + connections. If you need granular control over the conditions under + which we retry a request, import urllib3's ``Retry`` class and pass + that instead. + :param pool_block: Whether the connection pool should block for connections. + + Usage:: + + >>> import requests + >>> s = requests.Session() + >>> a = requests.adapters.HTTPAdapter(max_retries=3) + >>> s.mount('http://', a) + """ + __attrs__ = ['max_retries', 'config', '_pool_connections', '_pool_maxsize', + '_pool_block'] + + def __init__(self, pool_connections=DEFAULT_POOLSIZE, + pool_maxsize=DEFAULT_POOLSIZE, max_retries=DEFAULT_RETRIES, + pool_block=DEFAULT_POOLBLOCK): + if max_retries == DEFAULT_RETRIES: + self.max_retries = Retry(0, read=False) + else: + self.max_retries = Retry.from_int(max_retries) + self.config = {} + self.proxy_manager = {} + + super(HTTPAdapter, self).__init__() + + self._pool_connections = pool_connections + self._pool_maxsize = pool_maxsize + self._pool_block = pool_block + + self.init_poolmanager(pool_connections, pool_maxsize, block=pool_block) + + def __getstate__(self): + return dict((attr, getattr(self, attr, None)) for attr in + self.__attrs__) + + def __setstate__(self, state): + # Can't handle by adding 'proxy_manager' to self.__attrs__ because + # self.poolmanager uses a lambda function, which isn't pickleable. + self.proxy_manager = {} + self.config = {} + + for attr, value in state.items(): + setattr(self, attr, value) + + self.init_poolmanager(self._pool_connections, self._pool_maxsize, + block=self._pool_block) + + def init_poolmanager(self, connections, maxsize, block=DEFAULT_POOLBLOCK, **pool_kwargs): + """Initializes a urllib3 PoolManager. + + This method should not be called from user code, and is only + exposed for use when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param connections: The number of urllib3 connection pools to cache. + :param maxsize: The maximum number of connections to save in the pool. + :param block: Block when no free connections are available. + :param pool_kwargs: Extra keyword arguments used to initialize the Pool Manager. + """ + # save these values for pickling + self._pool_connections = connections + self._pool_maxsize = maxsize + self._pool_block = block + + self.poolmanager = PoolManager(num_pools=connections, maxsize=maxsize, + block=block, strict=True, **pool_kwargs) + + def proxy_manager_for(self, proxy, **proxy_kwargs): + """Return urllib3 ProxyManager for the given proxy. + + This method should not be called from user code, and is only + exposed for use when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param proxy: The proxy to return a urllib3 ProxyManager for. + :param proxy_kwargs: Extra keyword arguments used to configure the Proxy Manager. + :returns: ProxyManager + :rtype: urllib3.ProxyManager + """ + if proxy in self.proxy_manager: + manager = self.proxy_manager[proxy] + elif proxy.lower().startswith('socks'): + username, password = get_auth_from_url(proxy) + manager = self.proxy_manager[proxy] = SOCKSProxyManager( + proxy, + username=username, + password=password, + num_pools=self._pool_connections, + maxsize=self._pool_maxsize, + block=self._pool_block, + **proxy_kwargs + ) + else: + proxy_headers = self.proxy_headers(proxy) + manager = self.proxy_manager[proxy] = proxy_from_url( + proxy, + proxy_headers=proxy_headers, + num_pools=self._pool_connections, + maxsize=self._pool_maxsize, + block=self._pool_block, + **proxy_kwargs) + + return manager + + def cert_verify(self, conn, url, verify, cert): + """Verify a SSL certificate. This method should not be called from user + code, and is only exposed for use when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param conn: The urllib3 connection object associated with the cert. + :param url: The requested URL. + :param verify: Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use + :param cert: The SSL certificate to verify. + """ + if url.lower().startswith('https') and verify: + + cert_loc = None + + # Allow self-specified cert location. + if verify is not True: + cert_loc = verify + + if not cert_loc: + cert_loc = extract_zipped_paths(DEFAULT_CA_BUNDLE_PATH) + + if not cert_loc or not os.path.exists(cert_loc): + raise IOError("Could not find a suitable TLS CA certificate bundle, " + "invalid path: {0}".format(cert_loc)) + + conn.cert_reqs = 'CERT_REQUIRED' + + if not os.path.isdir(cert_loc): + conn.ca_certs = cert_loc + else: + conn.ca_cert_dir = cert_loc + else: + conn.cert_reqs = 'CERT_NONE' + conn.ca_certs = None + conn.ca_cert_dir = None + + if cert: + if not isinstance(cert, basestring): + conn.cert_file = cert[0] + conn.key_file = cert[1] + else: + conn.cert_file = cert + conn.key_file = None + if conn.cert_file and not os.path.exists(conn.cert_file): + raise IOError("Could not find the TLS certificate file, " + "invalid path: {0}".format(conn.cert_file)) + if conn.key_file and not os.path.exists(conn.key_file): + raise IOError("Could not find the TLS key file, " + "invalid path: {0}".format(conn.key_file)) + + def build_response(self, req, resp): + """Builds a :class:`Response <requests.Response>` object from a urllib3 + response. This should not be called from user code, and is only exposed + for use when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>` + + :param req: The :class:`PreparedRequest <PreparedRequest>` used to generate the response. + :param resp: The urllib3 response object. + :rtype: requests.Response + """ + response = Response() + + # Fallback to None if there's no status_code, for whatever reason. + response.status_code = getattr(resp, 'status', None) + + # Make headers case-insensitive. + response.headers = CaseInsensitiveDict(getattr(resp, 'headers', {})) + + # Set encoding. + response.encoding = get_encoding_from_headers(response.headers) + response.raw = resp + response.reason = response.raw.reason + + if isinstance(req.url, bytes): + response.url = req.url.decode('utf-8') + else: + response.url = req.url + + # Add new cookies from the server. + extract_cookies_to_jar(response.cookies, req, resp) + + # Give the Response some context. + response.request = req + response.connection = self + + return response + + def get_connection(self, url, proxies=None): + """Returns a urllib3 connection for the given URL. This should not be + called from user code, and is only exposed for use when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param url: The URL to connect to. + :param proxies: (optional) A Requests-style dictionary of proxies used on this request. + :rtype: urllib3.ConnectionPool + """ + proxy = select_proxy(url, proxies) + + if proxy: + proxy = prepend_scheme_if_needed(proxy, 'http') + proxy_url = parse_url(proxy) + if not proxy_url.host: + raise InvalidProxyURL("Please check proxy URL. It is malformed" + " and could be missing the host.") + proxy_manager = self.proxy_manager_for(proxy) + conn = proxy_manager.connection_from_url(url) + else: + # Only scheme should be lower case + parsed = urlparse(url) + url = parsed.geturl() + conn = self.poolmanager.connection_from_url(url) + + return conn + + def close(self): + """Disposes of any internal state. + + Currently, this closes the PoolManager and any active ProxyManager, + which closes any pooled connections. + """ + self.poolmanager.clear() + for proxy in self.proxy_manager.values(): + proxy.clear() + + def request_url(self, request, proxies): + """Obtain the url to use when making the final request. + + If the message is being sent through a HTTP proxy, the full URL has to + be used. Otherwise, we should only use the path portion of the URL. + + This should not be called from user code, and is only exposed for use + when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param request: The :class:`PreparedRequest <PreparedRequest>` being sent. + :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs. + :rtype: str + """ + proxy = select_proxy(request.url, proxies) + scheme = urlparse(request.url).scheme + + is_proxied_http_request = (proxy and scheme != 'https') + using_socks_proxy = False + if proxy: + proxy_scheme = urlparse(proxy).scheme.lower() + using_socks_proxy = proxy_scheme.startswith('socks') + + url = request.path_url + if is_proxied_http_request and not using_socks_proxy: + url = urldefragauth(request.url) + + return url + + def add_headers(self, request, **kwargs): + """Add any headers needed by the connection. As of v2.0 this does + nothing by default, but is left for overriding by users that subclass + the :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + This should not be called from user code, and is only exposed for use + when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param request: The :class:`PreparedRequest <PreparedRequest>` to add headers to. + :param kwargs: The keyword arguments from the call to send(). + """ + pass + + def proxy_headers(self, proxy): + """Returns a dictionary of the headers to add to any request sent + through a proxy. This works with urllib3 magic to ensure that they are + correctly sent to the proxy, rather than in a tunnelled request if + CONNECT is being used. + + This should not be called from user code, and is only exposed for use + when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param proxies: The url of the proxy being used for this request. + :rtype: dict + """ + headers = {} + username, password = get_auth_from_url(proxy) + + if username: + headers['Proxy-Authorization'] = _basic_auth_str(username, + password) + + return headers + + def send(self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None): + """Sends PreparedRequest object. Returns Response object. + + :param request: The :class:`PreparedRequest <PreparedRequest>` being sent. + :param stream: (optional) Whether to stream the request content. + :param timeout: (optional) How long to wait for the server to send + data before giving up, as a float, or a :ref:`(connect timeout, + read timeout) <timeouts>` tuple. + :type timeout: float or tuple or urllib3 Timeout object + :param verify: (optional) Either a boolean, in which case it controls whether + we verify the server's TLS certificate, or a string, in which case it + must be a path to a CA bundle to use + :param cert: (optional) Any user-provided SSL certificate to be trusted. + :param proxies: (optional) The proxies dictionary to apply to the request. + :rtype: requests.Response + """ + + conn = self.get_connection(request.url, proxies) + + self.cert_verify(conn, request.url, verify, cert) + url = self.request_url(request, proxies) + self.add_headers(request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies) + + chunked = not (request.body is None or 'Content-Length' in request.headers) + + if isinstance(timeout, tuple): + try: + connect, read = timeout + timeout = TimeoutSauce(connect=connect, read=read) + except ValueError as e: + # this may raise a string formatting error. + err = ("Invalid timeout {0}. Pass a (connect, read) " + "timeout tuple, or a single float to set " + "both timeouts to the same value".format(timeout)) + raise ValueError(err) + elif isinstance(timeout, TimeoutSauce): + pass + else: + timeout = TimeoutSauce(connect=timeout, read=timeout) + + try: + if not chunked: + resp = conn.urlopen( + method=request.method, + url=url, + body=request.body, + headers=request.headers, + redirect=False, + assert_same_host=False, + preload_content=False, + decode_content=False, + retries=self.max_retries, + timeout=timeout + ) + + # Send the request. + else: + if hasattr(conn, 'proxy_pool'): + conn = conn.proxy_pool + + low_conn = conn._get_conn(timeout=DEFAULT_POOL_TIMEOUT) + + try: + low_conn.putrequest(request.method, + url, + skip_accept_encoding=True) + + for header, value in request.headers.items(): + low_conn.putheader(header, value) + + low_conn.endheaders() + + for i in request.body: + low_conn.send(hex(len(i))[2:].encode('utf-8')) + low_conn.send(b'\r\n') + low_conn.send(i) + low_conn.send(b'\r\n') + low_conn.send(b'0\r\n\r\n') + + # Receive the response from the server + try: + # For Python 2.7+ versions, use buffering of HTTP + # responses + r = low_conn.getresponse(buffering=True) + except TypeError: + # For compatibility with Python 2.6 versions and back + r = low_conn.getresponse() + + resp = HTTPResponse.from_httplib( + r, + pool=conn, + connection=low_conn, + preload_content=False, + decode_content=False + ) + except: + # If we hit any problems here, clean up the connection. + # Then, reraise so that we can handle the actual exception. + low_conn.close() + raise + + except (ProtocolError, socket.error) as err: + raise ConnectionError(err, request=request) + + except MaxRetryError as e: + if isinstance(e.reason, ConnectTimeoutError): + # TODO: Remove this in 3.0.0: see #2811 + if not isinstance(e.reason, NewConnectionError): + raise ConnectTimeout(e, request=request) + + if isinstance(e.reason, ResponseError): + raise RetryError(e, request=request) + + if isinstance(e.reason, _ProxyError): + raise ProxyError(e, request=request) + + if isinstance(e.reason, _SSLError): + # This branch is for urllib3 v1.22 and later. + raise SSLError(e, request=request) + + raise ConnectionError(e, request=request) + + except ClosedPoolError as e: + raise ConnectionError(e, request=request) + + except _ProxyError as e: + raise ProxyError(e) + + except (_SSLError, _HTTPError) as e: + if isinstance(e, _SSLError): + # This branch is for urllib3 versions earlier than v1.22 + raise SSLError(e, request=request) + elif isinstance(e, ReadTimeoutError): + raise ReadTimeout(e, request=request) + else: + raise + + return self.build_response(request, resp) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/api.py b/venv/lib/python3.7/site-packages/pip/_vendor/requests/api.py new file mode 100644 index 0000000..a2cc84d --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/requests/api.py @@ -0,0 +1,152 @@ +# -*- coding: utf-8 -*- + +""" +requests.api +~~~~~~~~~~~~ + +This module implements the Requests API. + +:copyright: (c) 2012 by Kenneth Reitz. +:license: Apache2, see LICENSE for more details. +""" + +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 url: URL for the new :class:`Request` object. + :param params: (optional) Dictionary or bytes to be sent in the query string for the :class:`Request`. + :param data: (optional) Dictionary or list of tuples ``[(key, value)]`` (will be form-encoded), bytes, or file-like object to send in the body of the :class:`Request`. + :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`. + :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`. + :param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`. + :param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload. + ``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')`` + or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content-type'`` is a string + defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers + to add for the file. + :param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth. + :param timeout: (optional) How many seconds to wait for the server to send data + before giving up, as a float, or a :ref:`(connect timeout, read + timeout) <timeouts>` tuple. + :type timeout: float or tuple + :param allow_redirects: (optional) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to ``True``. + :type allow_redirects: bool + :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy. + :param verify: (optional) Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use. Defaults to ``True``. + :param stream: (optional) if ``False``, the response content will be immediately downloaded. + :param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair. + :return: :class:`Response <Response>` object + :rtype: requests.Response + + Usage:: + + >>> import requests + >>> req = requests.request('GET', 'http://httpbin.org/get') + <Response [200]> + """ + + # By using the 'with' statement we are sure the session is closed, thus we + # avoid leaving sockets open which can trigger a ResourceWarning in some + # cases, and look like a memory leak in others. + with sessions.Session() as session: + return session.request(method=method, url=url, **kwargs) + + +def get(url, params=None, **kwargs): + r"""Sends a GET request. + + :param url: URL for the new :class:`Request` object. + :param params: (optional) Dictionary or bytes to be sent in the query string for the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', True) + return request('get', url, params=params, **kwargs) + + +def options(url, **kwargs): + r"""Sends an OPTIONS request. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', True) + return request('options', url, **kwargs) + + +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. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', False) + return request('head', url, **kwargs) + + +def post(url, data=None, json=None, **kwargs): + r"""Sends a POST request. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary (will be form-encoded), bytes, or file-like object to send in the body of the :class:`Request`. + :param json: (optional) json data to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + return request('post', url, data=data, json=json, **kwargs) + + +def put(url, data=None, **kwargs): + r"""Sends a PUT request. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary (will be form-encoded), bytes, or file-like object to send in the body of the :class:`Request`. + :param json: (optional) json data to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + return request('put', url, data=data, **kwargs) + + +def patch(url, data=None, **kwargs): + r"""Sends a PATCH request. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary (will be form-encoded), bytes, or file-like object to send in the body of the :class:`Request`. + :param json: (optional) json data to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + return request('patch', url, data=data, **kwargs) + + +def delete(url, **kwargs): + r"""Sends a DELETE request. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + return request('delete', url, **kwargs) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/auth.py b/venv/lib/python3.7/site-packages/pip/_vendor/requests/auth.py new file mode 100644 index 0000000..4ae4594 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/requests/auth.py @@ -0,0 +1,305 @@ +# -*- coding: utf-8 -*- + +""" +requests.auth +~~~~~~~~~~~~~ + +This module contains the authentication handlers for Requests. +""" + +import os +import re +import time +import hashlib +import threading +import warnings + +from base64 import b64encode + +from .compat import urlparse, str, basestring +from .cookies import extract_cookies_to_jar +from ._internal_utils import to_native_string +from .utils import parse_dict_header + +CONTENT_TYPE_FORM_URLENCODED = 'application/x-www-form-urlencoded' +CONTENT_TYPE_MULTI_PART = 'multipart/form-data' + + +def _basic_auth_str(username, password): + """Returns a Basic Auth string.""" + + # "I want us to put a big-ol' comment on top of it that + # says that this behaviour is dumb but we need to preserve + # it because people are relying on it." + # - Lukasa + # + # These are here solely to maintain backwards compatibility + # for things like ints. This will be removed in 3.0.0. + if not isinstance(username, basestring): + warnings.warn( + "Non-string usernames will no longer be supported in Requests " + "3.0.0. Please convert the object you've passed in ({0!r}) to " + "a string or bytes object in the near future to avoid " + "problems.".format(username), + category=DeprecationWarning, + ) + username = str(username) + + if not isinstance(password, basestring): + warnings.warn( + "Non-string passwords will no longer be supported in Requests " + "3.0.0. Please convert the object you've passed in ({0!r}) to " + "a string or bytes object in the near future to avoid " + "problems.".format(password), + category=DeprecationWarning, + ) + password = str(password) + # -- End Removal -- + + if isinstance(username, str): + username = username.encode('latin1') + + if isinstance(password, str): + password = password.encode('latin1') + + authstr = 'Basic ' + to_native_string( + b64encode(b':'.join((username, password))).strip() + ) + + return authstr + + +class AuthBase(object): + """Base class that all auth implementations derive from""" + + def __call__(self, r): + raise NotImplementedError('Auth hooks must be callable.') + + +class HTTPBasicAuth(AuthBase): + """Attaches HTTP Basic Authentication to the given Request object.""" + + def __init__(self, username, password): + self.username = username + self.password = password + + def __eq__(self, other): + return all([ + self.username == getattr(other, 'username', None), + self.password == getattr(other, 'password', None) + ]) + + def __ne__(self, other): + return not self == other + + def __call__(self, r): + r.headers['Authorization'] = _basic_auth_str(self.username, self.password) + return r + + +class HTTPProxyAuth(HTTPBasicAuth): + """Attaches HTTP Proxy Authentication to a given Request object.""" + + def __call__(self, r): + r.headers['Proxy-Authorization'] = _basic_auth_str(self.username, self.password) + return r + + +class HTTPDigestAuth(AuthBase): + """Attaches HTTP Digest Authentication to the given Request object.""" + + def __init__(self, username, password): + self.username = username + self.password = password + # Keep state in per-thread local storage + self._thread_local = threading.local() + + def init_per_thread_state(self): + # Ensure state is initialized just once per-thread + if not hasattr(self._thread_local, 'init'): + self._thread_local.init = True + self._thread_local.last_nonce = '' + self._thread_local.nonce_count = 0 + self._thread_local.chal = {} + self._thread_local.pos = None + self._thread_local.num_401_calls = None + + def build_digest_header(self, method, url): + """ + :rtype: str + """ + + realm = self._thread_local.chal['realm'] + nonce = self._thread_local.chal['nonce'] + qop = self._thread_local.chal.get('qop') + algorithm = self._thread_local.chal.get('algorithm') + opaque = self._thread_local.chal.get('opaque') + hash_utf8 = None + + if algorithm is None: + _algorithm = 'MD5' + else: + _algorithm = algorithm.upper() + # lambdas assume digest modules are imported at the top level + if _algorithm == 'MD5' or _algorithm == 'MD5-SESS': + def md5_utf8(x): + if isinstance(x, str): + x = x.encode('utf-8') + return hashlib.md5(x).hexdigest() + hash_utf8 = md5_utf8 + elif _algorithm == 'SHA': + def sha_utf8(x): + if isinstance(x, str): + x = x.encode('utf-8') + return hashlib.sha1(x).hexdigest() + hash_utf8 = sha_utf8 + elif _algorithm == 'SHA-256': + def sha256_utf8(x): + if isinstance(x, str): + x = x.encode('utf-8') + return hashlib.sha256(x).hexdigest() + hash_utf8 = sha256_utf8 + elif _algorithm == 'SHA-512': + def sha512_utf8(x): + if isinstance(x, str): + x = x.encode('utf-8') + return hashlib.sha512(x).hexdigest() + hash_utf8 = sha512_utf8 + + KD = lambda s, d: hash_utf8("%s:%s" % (s, d)) + + if hash_utf8 is None: + return None + + # XXX not implemented yet + entdig = None + p_parsed = urlparse(url) + #: path is request-uri defined in RFC 2616 which should not be empty + path = p_parsed.path or "/" + if p_parsed.query: + path += '?' + p_parsed.query + + A1 = '%s:%s:%s' % (self.username, realm, self.password) + A2 = '%s:%s' % (method, path) + + HA1 = hash_utf8(A1) + HA2 = hash_utf8(A2) + + if nonce == self._thread_local.last_nonce: + self._thread_local.nonce_count += 1 + else: + self._thread_local.nonce_count = 1 + ncvalue = '%08x' % self._thread_local.nonce_count + s = str(self._thread_local.nonce_count).encode('utf-8') + s += nonce.encode('utf-8') + s += time.ctime().encode('utf-8') + s += os.urandom(8) + + cnonce = (hashlib.sha1(s).hexdigest()[:16]) + if _algorithm == 'MD5-SESS': + HA1 = hash_utf8('%s:%s:%s' % (HA1, nonce, cnonce)) + + if not qop: + respdig = KD(HA1, "%s:%s" % (nonce, HA2)) + elif qop == 'auth' or 'auth' in qop.split(','): + noncebit = "%s:%s:%s:%s:%s" % ( + nonce, ncvalue, cnonce, 'auth', HA2 + ) + respdig = KD(HA1, noncebit) + else: + # XXX handle auth-int. + return None + + self._thread_local.last_nonce = nonce + + # XXX should the partial digests be encoded too? + base = 'username="%s", realm="%s", nonce="%s", uri="%s", ' \ + 'response="%s"' % (self.username, realm, nonce, path, respdig) + if opaque: + base += ', opaque="%s"' % opaque + if algorithm: + base += ', algorithm="%s"' % algorithm + if entdig: + base += ', digest="%s"' % entdig + if qop: + base += ', qop="auth", nc=%s, cnonce="%s"' % (ncvalue, cnonce) + + return 'Digest %s' % (base) + + def handle_redirect(self, r, **kwargs): + """Reset num_401_calls counter on redirects.""" + if r.is_redirect: + self._thread_local.num_401_calls = 1 + + def handle_401(self, r, **kwargs): + """ + Takes the given response and tries digest-auth, if needed. + + :rtype: requests.Response + """ + + # If response is not 4xx, do not auth + # See https://github.com/requests/requests/issues/3772 + if not 400 <= r.status_code < 500: + self._thread_local.num_401_calls = 1 + return r + + if self._thread_local.pos is not None: + # Rewind the file position indicator of the body to where + # it was to resend the request. + r.request.body.seek(self._thread_local.pos) + s_auth = r.headers.get('www-authenticate', '') + + if 'digest' in s_auth.lower() and self._thread_local.num_401_calls < 2: + + self._thread_local.num_401_calls += 1 + pat = re.compile(r'digest ', flags=re.IGNORECASE) + self._thread_local.chal = parse_dict_header(pat.sub('', s_auth, count=1)) + + # Consume content and release the original connection + # to allow our new request to reuse the same one. + r.content + r.close() + prep = r.request.copy() + extract_cookies_to_jar(prep._cookies, r.request, r.raw) + prep.prepare_cookies(prep._cookies) + + prep.headers['Authorization'] = self.build_digest_header( + prep.method, prep.url) + _r = r.connection.send(prep, **kwargs) + _r.history.append(r) + _r.request = prep + + return _r + + self._thread_local.num_401_calls = 1 + return r + + def __call__(self, r): + # Initialize per-thread state, if needed + self.init_per_thread_state() + # If we have a saved nonce, skip the 401 + if self._thread_local.last_nonce: + r.headers['Authorization'] = self.build_digest_header(r.method, r.url) + try: + self._thread_local.pos = r.body.tell() + except AttributeError: + # In the case of HTTPDigestAuth being reused and the body of + # the previous request was a file-like object, pos has the + # file position of the previous body. Ensure it's set to + # None. + self._thread_local.pos = None + r.register_hook('response', self.handle_401) + r.register_hook('response', self.handle_redirect) + self._thread_local.num_401_calls = 1 + + return r + + def __eq__(self, other): + return all([ + self.username == getattr(other, 'username', None), + self.password == getattr(other, 'password', None) + ]) + + def __ne__(self, other): + return not self == other diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/certs.py b/venv/lib/python3.7/site-packages/pip/_vendor/requests/certs.py new file mode 100644 index 0000000..06a594e --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/requests/certs.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +requests.certs +~~~~~~~~~~~~~~ + +This module returns the preferred default CA certificate bundle. There is +only one — the one from the certifi package. + +If you are packaging Requests, e.g., for a Linux distribution or a managed +environment, you can change the definition of where() to return a separately +packaged CA bundle. +""" +from pip._vendor.certifi import where + +if __name__ == '__main__': + print(where()) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/compat.py b/venv/lib/python3.7/site-packages/pip/_vendor/requests/compat.py new file mode 100644 index 0000000..ec5d305 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/requests/compat.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- + +""" +requests.compat +~~~~~~~~~~~~~~~ + +This module handles import compatibility issues between Python 2 and +Python 3. +""" + +from pip._vendor import chardet + +import sys + +# ------- +# Pythons +# ------- + +# Syntax sugar. +_ver = sys.version_info + +#: Python 2.x? +is_py2 = (_ver[0] == 2) + +#: Python 3.x? +is_py3 = (_ver[0] == 3) + +# Note: We've patched out simplejson support in pip because it prevents +# upgrading simplejson on Windows. +# try: +# import simplejson as json +# except (ImportError, SyntaxError): +# # simplejson does not support Python 3.2, it throws a SyntaxError +# # because of u'...' Unicode literals. +import json + +# --------- +# Specifics +# --------- + +if is_py2: + from urllib import ( + quote, unquote, quote_plus, unquote_plus, urlencode, getproxies, + proxy_bypass, proxy_bypass_environment, getproxies_environment) + from urlparse import urlparse, urlunparse, urljoin, urlsplit, urldefrag + from urllib2 import parse_http_list + import cookielib + from Cookie import Morsel + from StringIO import StringIO + from collections import Callable, Mapping, MutableMapping + + from pip._vendor.urllib3.packages.ordered_dict import OrderedDict + + builtin_str = str + bytes = str + str = unicode + basestring = basestring + numeric_types = (int, long, float) + integer_types = (int, long) + +elif is_py3: + from urllib.parse import urlparse, urlunparse, urljoin, urlsplit, urlencode, quote, unquote, quote_plus, unquote_plus, urldefrag + from urllib.request import parse_http_list, getproxies, proxy_bypass, proxy_bypass_environment, getproxies_environment + from http import cookiejar as cookielib + from http.cookies import Morsel + from io import StringIO + from collections import OrderedDict + from collections.abc import Callable, Mapping, MutableMapping + + builtin_str = str + str = str + bytes = bytes + basestring = (str, bytes) + numeric_types = (int, float) + integer_types = (int,) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/cookies.py b/venv/lib/python3.7/site-packages/pip/_vendor/requests/cookies.py new file mode 100644 index 0000000..50883a8 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/requests/cookies.py @@ -0,0 +1,546 @@ +# -*- coding: utf-8 -*- + +""" +requests.cookies +~~~~~~~~~~~~~~~~ + +Compatibility code to be able to use `cookielib.CookieJar` with requests. + +requests.utils imports from here, so be careful with imports. +""" + +import copy +import time +import calendar + +from ._internal_utils import to_native_string +from .compat import cookielib, urlparse, urlunparse, Morsel, MutableMapping + +try: + import threading +except ImportError: + import dummy_threading as threading + + +class MockRequest(object): + """Wraps a `requests.Request` to mimic a `urllib2.Request`. + + The code in `cookielib.CookieJar` expects this interface in order to correctly + manage cookie policies, i.e., determine whether a cookie can be set, given the + domains of the request and the cookie. + + The original request object is read-only. The client is responsible for collecting + the new headers via `get_new_headers()` and interpreting them appropriately. You + probably want `get_cookie_header`, defined below. + """ + + def __init__(self, request): + self._r = request + self._new_headers = {} + self.type = urlparse(self._r.url).scheme + + def get_type(self): + return self.type + + def get_host(self): + return urlparse(self._r.url).netloc + + def get_origin_req_host(self): + return self.get_host() + + def get_full_url(self): + # Only return the response's URL if the user hadn't set the Host + # header + if not self._r.headers.get('Host'): + return self._r.url + # If they did set it, retrieve it and reconstruct the expected domain + host = to_native_string(self._r.headers['Host'], encoding='utf-8') + parsed = urlparse(self._r.url) + # Reconstruct the URL as we expect it + return urlunparse([ + parsed.scheme, host, parsed.path, parsed.params, parsed.query, + parsed.fragment + ]) + + def is_unverifiable(self): + return True + + def has_header(self, name): + return name in self._r.headers or name in self._new_headers + + def get_header(self, name, default=None): + return self._r.headers.get(name, self._new_headers.get(name, default)) + + def add_header(self, key, val): + """cookielib has no legitimate use for this method; add it back if you find one.""" + raise NotImplementedError("Cookie headers should be added with add_unredirected_header()") + + def add_unredirected_header(self, name, value): + self._new_headers[name] = value + + def get_new_headers(self): + return self._new_headers + + @property + def unverifiable(self): + return self.is_unverifiable() + + @property + def origin_req_host(self): + return self.get_origin_req_host() + + @property + def host(self): + return self.get_host() + + +class MockResponse(object): + """Wraps a `httplib.HTTPMessage` to mimic a `urllib.addinfourl`. + + ...what? Basically, expose the parsed HTTP headers from the server response + the way `cookielib` expects to see them. + """ + + def __init__(self, headers): + """Make a MockResponse for `cookielib` to read. + + :param headers: a httplib.HTTPMessage or analogous carrying the headers + """ + self._headers = headers + + def info(self): + return self._headers + + def getheaders(self, name): + self._headers.getheaders(name) + + +def extract_cookies_to_jar(jar, request, response): + """Extract the cookies from the response into a CookieJar. + + :param jar: cookielib.CookieJar (not necessarily a RequestsCookieJar) + :param request: our own requests.Request object + :param response: urllib3.HTTPResponse object + """ + if not (hasattr(response, '_original_response') and + response._original_response): + return + # the _original_response field is the wrapped httplib.HTTPResponse object, + req = MockRequest(request) + # pull out the HTTPMessage with the headers and put it in the mock: + res = MockResponse(response._original_response.msg) + jar.extract_cookies(res, req) + + +def get_cookie_header(jar, request): + """ + Produce an appropriate Cookie header string to be sent with `request`, or None. + + :rtype: str + """ + r = MockRequest(request) + jar.add_cookie_header(r) + return r.get_new_headers().get('Cookie') + + +def remove_cookie_by_name(cookiejar, name, domain=None, path=None): + """Unsets a cookie by name, by default over all domains and paths. + + Wraps CookieJar.clear(), is O(n). + """ + clearables = [] + for cookie in cookiejar: + if cookie.name != name: + continue + if domain is not None and domain != cookie.domain: + continue + if path is not None and path != cookie.path: + continue + clearables.append((cookie.domain, cookie.path, cookie.name)) + + for domain, path, name in clearables: + cookiejar.clear(domain, path, name) + + +class CookieConflictError(RuntimeError): + """There are two cookies that meet the criteria specified in the cookie jar. + Use .get and .set and include domain and path args in order to be more specific. + """ + + +class RequestsCookieJar(cookielib.CookieJar, MutableMapping): + """Compatibility class; is a cookielib.CookieJar, but exposes a dict + interface. + + This is the CookieJar we create by default for requests and sessions that + don't specify one, since some clients may expect response.cookies and + session.cookies to support dict operations. + + Requests does not use the dict interface internally; it's just for + compatibility with external client code. All requests code should work + out of the box with externally provided instances of ``CookieJar``, e.g. + ``LWPCookieJar`` and ``FileCookieJar``. + + Unlike a regular CookieJar, this class is pickleable. + + .. warning:: dictionary operations that are normally O(1) may be O(n). + """ + + def get(self, name, default=None, domain=None, path=None): + """Dict-like get() that also supports optional domain and path args in + order to resolve naming collisions from using one cookie jar over + multiple domains. + + .. warning:: operation is O(n), not O(1). + """ + try: + return self._find_no_duplicates(name, domain, path) + except KeyError: + return default + + def set(self, name, value, **kwargs): + """Dict-like set() that also supports optional domain and path args in + order to resolve naming collisions from using one cookie jar over + multiple domains. + """ + # support client code that unsets cookies by assignment of a None value: + if value is None: + remove_cookie_by_name(self, name, domain=kwargs.get('domain'), path=kwargs.get('path')) + return + + if isinstance(value, Morsel): + c = morsel_to_cookie(value) + else: + c = create_cookie(name, value, **kwargs) + self.set_cookie(c) + return c + + def iterkeys(self): + """Dict-like iterkeys() that returns an iterator of names of cookies + from the jar. + + .. seealso:: itervalues() and iteritems(). + """ + for cookie in iter(self): + yield cookie.name + + def keys(self): + """Dict-like keys() that returns a list of names of cookies from the + jar. + + .. seealso:: values() and items(). + """ + return list(self.iterkeys()) + + def itervalues(self): + """Dict-like itervalues() that returns an iterator of values of cookies + from the jar. + + .. seealso:: iterkeys() and iteritems(). + """ + for cookie in iter(self): + yield cookie.value + + def values(self): + """Dict-like values() that returns a list of values of cookies from the + jar. + + .. seealso:: keys() and items(). + """ + return list(self.itervalues()) + + def iteritems(self): + """Dict-like iteritems() that returns an iterator of name-value tuples + from the jar. + + .. seealso:: iterkeys() and itervalues(). + """ + for cookie in iter(self): + yield cookie.name, cookie.value + + def items(self): + """Dict-like items() that returns a list of name-value tuples from the + jar. Allows client-code to call ``dict(RequestsCookieJar)`` and get a + vanilla python dict of key value pairs. + + .. seealso:: keys() and values(). + """ + return list(self.iteritems()) + + def list_domains(self): + """Utility method to list all the domains in the jar.""" + domains = [] + for cookie in iter(self): + if cookie.domain not in domains: + domains.append(cookie.domain) + return domains + + def list_paths(self): + """Utility method to list all the paths in the jar.""" + paths = [] + for cookie in iter(self): + if cookie.path not in paths: + paths.append(cookie.path) + return paths + + def multiple_domains(self): + """Returns True if there are multiple domains in the jar. + Returns False otherwise. + + :rtype: bool + """ + domains = [] + for cookie in iter(self): + if cookie.domain is not None and cookie.domain in domains: + return True + domains.append(cookie.domain) + return False # there is only one domain in jar + + def get_dict(self, domain=None, path=None): + """Takes as an argument an optional domain and path and returns a plain + old Python dict of name-value pairs of cookies that meet the + requirements. + + :rtype: dict + """ + dictionary = {} + for cookie in iter(self): + if ( + (domain is None or cookie.domain == domain) and + (path is None or cookie.path == path) + ): + dictionary[cookie.name] = cookie.value + return dictionary + + def __contains__(self, name): + try: + return super(RequestsCookieJar, self).__contains__(name) + except CookieConflictError: + return True + + def __getitem__(self, name): + """Dict-like __getitem__() for compatibility with client code. Throws + exception if there are more than one cookie with name. In that case, + use the more explicit get() method instead. + + .. warning:: operation is O(n), not O(1). + """ + return self._find_no_duplicates(name) + + def __setitem__(self, name, value): + """Dict-like __setitem__ for compatibility with client code. Throws + exception if there is already a cookie of that name in the jar. In that + case, use the more explicit set() method instead. + """ + self.set(name, value) + + def __delitem__(self, name): + """Deletes a cookie given a name. Wraps ``cookielib.CookieJar``'s + ``remove_cookie_by_name()``. + """ + remove_cookie_by_name(self, name) + + def set_cookie(self, cookie, *args, **kwargs): + if hasattr(cookie.value, 'startswith') and cookie.value.startswith('"') and cookie.value.endswith('"'): + cookie.value = cookie.value.replace('\\"', '') + return super(RequestsCookieJar, self).set_cookie(cookie, *args, **kwargs) + + def update(self, other): + """Updates this jar with cookies from another CookieJar or dict-like""" + if isinstance(other, cookielib.CookieJar): + for cookie in other: + self.set_cookie(copy.copy(cookie)) + else: + super(RequestsCookieJar, self).update(other) + + def _find(self, name, domain=None, path=None): + """Requests uses this method internally to get cookie values. + + If there are conflicting cookies, _find arbitrarily chooses one. + See _find_no_duplicates if you want an exception thrown if there are + conflicting cookies. + + :param name: a string containing name of cookie + :param domain: (optional) string containing domain of cookie + :param path: (optional) string containing path of cookie + :return: cookie.value + """ + for cookie in iter(self): + if cookie.name == name: + if domain is None or cookie.domain == domain: + if path is None or cookie.path == path: + return cookie.value + + raise KeyError('name=%r, domain=%r, path=%r' % (name, domain, path)) + + def _find_no_duplicates(self, name, domain=None, path=None): + """Both ``__get_item__`` and ``get`` call this function: it's never + used elsewhere in Requests. + + :param name: a string containing name of cookie + :param domain: (optional) string containing domain of cookie + :param path: (optional) string containing path of cookie + :raises KeyError: if cookie is not found + :raises CookieConflictError: if there are multiple cookies + that match name and optionally domain and path + :return: cookie.value + """ + toReturn = None + for cookie in iter(self): + if cookie.name == name: + if domain is None or cookie.domain == domain: + if path is None or cookie.path == path: + if toReturn is not None: # if there are multiple cookies that meet passed in criteria + raise CookieConflictError('There are multiple cookies with name, %r' % (name)) + toReturn = cookie.value # we will eventually return this as long as no cookie conflict + + if toReturn: + return toReturn + raise KeyError('name=%r, domain=%r, path=%r' % (name, domain, path)) + + def __getstate__(self): + """Unlike a normal CookieJar, this class is pickleable.""" + state = self.__dict__.copy() + # remove the unpickleable RLock object + state.pop('_cookies_lock') + return state + + def __setstate__(self, state): + """Unlike a normal CookieJar, this class is pickleable.""" + self.__dict__.update(state) + if '_cookies_lock' not in self.__dict__: + self._cookies_lock = threading.RLock() + + def copy(self): + """Return a copy of this RequestsCookieJar.""" + new_cj = RequestsCookieJar() + new_cj.set_policy(self.get_policy()) + new_cj.update(self) + return new_cj + + def get_policy(self): + """Return the CookiePolicy instance used.""" + return self._policy + + +def _copy_cookie_jar(jar): + if jar is None: + return None + + if hasattr(jar, 'copy'): + # We're dealing with an instance of RequestsCookieJar + return jar.copy() + # We're dealing with a generic CookieJar instance + new_jar = copy.copy(jar) + new_jar.clear() + for cookie in jar: + new_jar.set_cookie(copy.copy(cookie)) + return new_jar + + +def create_cookie(name, value, **kwargs): + """Make a cookie from underspecified parameters. + + By default, the pair of `name` and `value` will be set for the domain '' + and sent on every request (this is sometimes called a "supercookie"). + """ + result = dict( + version=0, + name=name, + value=value, + port=None, + domain='', + path='/', + secure=False, + expires=None, + discard=True, + comment=None, + comment_url=None, + rest={'HttpOnly': None}, + rfc2109=False,) + + badargs = set(kwargs) - set(result) + if badargs: + err = 'create_cookie() got unexpected keyword arguments: %s' + raise TypeError(err % list(badargs)) + + result.update(kwargs) + result['port_specified'] = bool(result['port']) + result['domain_specified'] = bool(result['domain']) + result['domain_initial_dot'] = result['domain'].startswith('.') + result['path_specified'] = bool(result['path']) + + return cookielib.Cookie(**result) + + +def morsel_to_cookie(morsel): + """Convert a Morsel object into a Cookie containing the one k/v pair.""" + + expires = None + if morsel['max-age']: + try: + expires = int(time.time() + int(morsel['max-age'])) + except ValueError: + raise TypeError('max-age: %s must be integer' % morsel['max-age']) + elif morsel['expires']: + time_template = '%a, %d-%b-%Y %H:%M:%S GMT' + expires = calendar.timegm( + time.strptime(morsel['expires'], time_template) + ) + return create_cookie( + comment=morsel['comment'], + comment_url=bool(morsel['comment']), + discard=False, + domain=morsel['domain'], + expires=expires, + name=morsel.key, + path=morsel['path'], + port=None, + rest={'HttpOnly': morsel['httponly']}, + rfc2109=False, + secure=bool(morsel['secure']), + value=morsel.value, + version=morsel['version'] or 0, + ) + + +def cookiejar_from_dict(cookie_dict, cookiejar=None, overwrite=True): + """Returns a CookieJar from a key/value dictionary. + + :param cookie_dict: Dict of key/values to insert into CookieJar. + :param cookiejar: (optional) A cookiejar to add the cookies to. + :param overwrite: (optional) If False, will not replace cookies + already in the jar with new ones. + """ + if cookiejar is None: + cookiejar = RequestsCookieJar() + + if cookie_dict is not None: + names_from_jar = [cookie.name for cookie in cookiejar] + for name in cookie_dict: + if overwrite or (name not in names_from_jar): + cookiejar.set_cookie(create_cookie(name, cookie_dict[name])) + + return cookiejar + + +def merge_cookies(cookiejar, cookies): + """Add cookies to cookiejar and returns a merged CookieJar. + + :param cookiejar: CookieJar object to add the cookies to. + :param cookies: Dictionary or CookieJar object to be added. + """ + if not isinstance(cookiejar, cookielib.CookieJar): + raise ValueError('You can only merge into CookieJar') + + if isinstance(cookies, dict): + cookiejar = cookiejar_from_dict( + cookies, cookiejar=cookiejar, overwrite=False) + elif isinstance(cookies, cookielib.CookieJar): + try: + cookiejar.update(cookies) + except AttributeError: + for cookie_in_jar in cookies: + cookiejar.set_cookie(cookie_in_jar) + + return cookiejar diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/exceptions.py b/venv/lib/python3.7/site-packages/pip/_vendor/requests/exceptions.py new file mode 100644 index 0000000..a91e1fd --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/requests/exceptions.py @@ -0,0 +1,126 @@ +# -*- coding: utf-8 -*- + +""" +requests.exceptions +~~~~~~~~~~~~~~~~~~~ + +This module contains the set of Requests' exceptions. +""" +from pip._vendor.urllib3.exceptions import HTTPError as BaseHTTPError + + +class RequestException(IOError): + """There was an ambiguous exception that occurred while handling your + request. + """ + + def __init__(self, *args, **kwargs): + """Initialize RequestException with `request` and `response` objects.""" + response = kwargs.pop('response', None) + self.response = response + self.request = kwargs.pop('request', None) + if (response is not None and not self.request and + hasattr(response, 'request')): + self.request = self.response.request + super(RequestException, self).__init__(*args, **kwargs) + + +class HTTPError(RequestException): + """An HTTP error occurred.""" + + +class ConnectionError(RequestException): + """A Connection error occurred.""" + + +class ProxyError(ConnectionError): + """A proxy error occurred.""" + + +class SSLError(ConnectionError): + """An SSL error occurred.""" + + +class Timeout(RequestException): + """The request timed out. + + Catching this error will catch both + :exc:`~requests.exceptions.ConnectTimeout` and + :exc:`~requests.exceptions.ReadTimeout` errors. + """ + + +class ConnectTimeout(ConnectionError, Timeout): + """The request timed out while trying to connect to the remote server. + + Requests that produced this error are safe to retry. + """ + + +class ReadTimeout(Timeout): + """The server did not send any data in the allotted amount of time.""" + + +class URLRequired(RequestException): + """A valid URL is required to make a request.""" + + +class TooManyRedirects(RequestException): + """Too many redirects.""" + + +class MissingSchema(RequestException, ValueError): + """The URL schema (e.g. http or https) is missing.""" + + +class InvalidSchema(RequestException, ValueError): + """See defaults.py for valid schemas.""" + + +class InvalidURL(RequestException, ValueError): + """The URL provided was somehow invalid.""" + + +class InvalidHeader(RequestException, ValueError): + """The header value provided was somehow invalid.""" + + +class InvalidProxyURL(InvalidURL): + """The proxy URL provided is invalid.""" + + +class ChunkedEncodingError(RequestException): + """The server declared chunked encoding but sent an invalid chunk.""" + + +class ContentDecodingError(RequestException, BaseHTTPError): + """Failed to decode response content""" + + +class StreamConsumedError(RequestException, TypeError): + """The content for this response was already consumed""" + + +class RetryError(RequestException): + """Custom retries logic failed""" + + +class UnrewindableBodyError(RequestException): + """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.7/site-packages/pip/_vendor/requests/help.py b/venv/lib/python3.7/site-packages/pip/_vendor/requests/help.py new file mode 100644 index 0000000..df1b4eb --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/requests/help.py @@ -0,0 +1,120 @@ +"""Module containing bug report helper(s).""" +from __future__ import print_function + +import json +import platform +import sys +import ssl + +from pip._vendor import idna +from pip._vendor import urllib3 +from pip._vendor import chardet + +from . import __version__ as requests_version + +try: + from pip._vendor.urllib3.contrib import pyopenssl +except ImportError: + pyopenssl = None + OpenSSL = None + cryptography = None +else: + import OpenSSL + import cryptography + + +def _implementation(): + """Return a dict with the Python implementation and version. + + Provide both the name and the version of the Python implementation + currently running. For example, on CPython 2.7.5 it will return + {'name': 'CPython', 'version': '2.7.5'}. + + This function works best on CPython and PyPy: in particular, it probably + doesn't work for Jython or IronPython. Future investigation should be done + to work out the correct shape of the code for those platforms. + """ + implementation = platform.python_implementation() + + if implementation == 'CPython': + implementation_version = platform.python_version() + elif implementation == 'PyPy': + implementation_version = '%s.%s.%s' % (sys.pypy_version_info.major, + sys.pypy_version_info.minor, + sys.pypy_version_info.micro) + if sys.pypy_version_info.releaselevel != 'final': + implementation_version = ''.join([ + implementation_version, sys.pypy_version_info.releaselevel + ]) + elif implementation == 'Jython': + implementation_version = platform.python_version() # Complete Guess + elif implementation == 'IronPython': + implementation_version = platform.python_version() # Complete Guess + else: + implementation_version = 'Unknown' + + return {'name': implementation, 'version': implementation_version} + + +def info(): + """Generate information for a bug report.""" + try: + platform_info = { + 'system': platform.system(), + 'release': platform.release(), + } + except IOError: + platform_info = { + 'system': 'Unknown', + 'release': 'Unknown', + } + + implementation_info = _implementation() + urllib3_info = {'version': urllib3.__version__} + chardet_info = {'version': chardet.__version__} + + pyopenssl_info = { + 'version': None, + 'openssl_version': '', + } + if OpenSSL: + pyopenssl_info = { + 'version': OpenSSL.__version__, + 'openssl_version': '%x' % OpenSSL.SSL.OPENSSL_VERSION_NUMBER, + } + cryptography_info = { + 'version': getattr(cryptography, '__version__', ''), + } + idna_info = { + 'version': getattr(idna, '__version__', ''), + } + + # OPENSSL_VERSION_NUMBER doesn't exist in the Python 2.6 ssl module. + system_ssl = getattr(ssl, 'OPENSSL_VERSION_NUMBER', None) + system_ssl_info = { + 'version': '%x' % system_ssl if system_ssl is not None else '' + } + + return { + 'platform': platform_info, + 'implementation': implementation_info, + 'system_ssl': system_ssl_info, + 'using_pyopenssl': pyopenssl is not None, + 'pyOpenSSL': pyopenssl_info, + 'urllib3': urllib3_info, + 'chardet': chardet_info, + 'cryptography': cryptography_info, + 'idna': idna_info, + 'requests': { + 'version': requests_version, + }, + } + + +def main(): + """Pretty-print the bug information as JSON.""" + print(json.dumps(info(), sort_keys=True, indent=2)) + + +if __name__ == '__main__': + main() diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/hooks.py b/venv/lib/python3.7/site-packages/pip/_vendor/requests/hooks.py new file mode 100644 index 0000000..32b32de --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/requests/hooks.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- + +""" +requests.hooks +~~~~~~~~~~~~~~ + +This module provides the capabilities for the Requests hooks system. + +Available hooks: + +``response``: + The response generated from a Request. +""" +HOOKS = ['response'] + + +def default_hooks(): + return dict((event, []) for event in HOOKS) + +# TODO: response is the only one + + +def dispatch_hook(key, hooks, hook_data, **kwargs): + """Dispatches a hook dictionary on a given piece of data.""" + hooks = hooks or dict() + hooks = hooks.get(key) + if hooks: + if hasattr(hooks, '__call__'): + hooks = [hooks] + for hook in hooks: + _hook_data = hook(hook_data, **kwargs) + if _hook_data is not None: + hook_data = _hook_data + return hook_data diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/models.py b/venv/lib/python3.7/site-packages/pip/_vendor/requests/models.py new file mode 100644 index 0000000..4230535 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/requests/models.py @@ -0,0 +1,952 @@ +# -*- coding: utf-8 -*- + +""" +requests.models +~~~~~~~~~~~~~~~ + +This module contains the primary objects that power Requests. +""" + +import datetime +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. +import encodings.idna + +from pip._vendor.urllib3.fields import RequestField +from pip._vendor.urllib3.filepost import encode_multipart_formdata +from pip._vendor.urllib3.util import parse_url +from pip._vendor.urllib3.exceptions import ( + DecodeError, ReadTimeoutError, ProtocolError, LocationParseError) + +from io import UnsupportedOperation +from .hooks import default_hooks +from .structures import CaseInsensitiveDict + +from .auth import HTTPBasicAuth +from .cookies import cookiejar_from_dict, get_cookie_header, _copy_cookie_jar +from .exceptions import ( + HTTPError, MissingSchema, InvalidURL, ChunkedEncodingError, + ContentDecodingError, ConnectionError, StreamConsumedError) +from ._internal_utils import to_native_string, unicode_is_ascii +from .utils import ( + guess_filename, get_auth_from_url, requote_uri, + stream_decode_response_unicode, to_key_val_list, parse_header_links, + iter_slices, guess_json_utf, super_len, check_header_validity) +from .compat import ( + Callable, Mapping, + cookielib, urlunparse, urlsplit, urlencode, str, bytes, + is_py2, chardet, builtin_str, basestring) +from .compat import json as complexjson +from .status_codes import codes + +#: The set of HTTP status codes that indicate an automatically +#: processable redirect. +REDIRECT_STATI = ( + codes.moved, # 301 + codes.found, # 302 + codes.other, # 303 + codes.temporary_redirect, # 307 + codes.permanent_redirect, # 308 +) + +DEFAULT_REDIRECT_LIMIT = 30 +CONTENT_CHUNK_SIZE = 10 * 1024 +ITER_CHUNK_SIZE = 512 + + +class RequestEncodingMixin(object): + @property + def path_url(self): + """Build the path URL to use.""" + + url = [] + + p = urlsplit(self.url) + + path = p.path + if not path: + path = '/' + + url.append(path) + + query = p.query + if query: + url.append('?') + url.append(query) + + return ''.join(url) + + @staticmethod + def _encode_params(data): + """Encode parameters in a piece of data. + + Will successfully encode parameters when passed as a dict or a list of + 2-tuples. Order is retained if data is a list of 2-tuples but arbitrary + if parameters are supplied as a dict. + """ + + if isinstance(data, (str, bytes)): + return data + elif hasattr(data, 'read'): + return data + elif hasattr(data, '__iter__'): + result = [] + for k, vs in to_key_val_list(data): + if isinstance(vs, basestring) or not hasattr(vs, '__iter__'): + vs = [vs] + for v in vs: + if v is not None: + result.append( + (k.encode('utf-8') if isinstance(k, str) else k, + v.encode('utf-8') if isinstance(v, str) else v)) + return urlencode(result, doseq=True) + else: + return data + + @staticmethod + def _encode_files(files, data): + """Build the body for a multipart/form-data request. + + Will successfully encode files when passed as a dict or a list of + tuples. Order is retained if data is a list of tuples but arbitrary + if parameters are supplied as a dict. + The tuples may be 2-tuples (filename, fileobj), 3-tuples (filename, fileobj, contentype) + or 4-tuples (filename, fileobj, contentype, custom_headers). + """ + if (not files): + raise ValueError("Files must be provided.") + elif isinstance(data, basestring): + raise ValueError("Data must not be a string.") + + new_fields = [] + fields = to_key_val_list(data or {}) + files = to_key_val_list(files or {}) + + for field, val in fields: + if isinstance(val, basestring) or not hasattr(val, '__iter__'): + val = [val] + for v in val: + if v is not None: + # Don't call str() on bytestrings: in Py3 it all goes wrong. + if not isinstance(v, bytes): + v = str(v) + + new_fields.append( + (field.decode('utf-8') if isinstance(field, bytes) else field, + v.encode('utf-8') if isinstance(v, str) else v)) + + for (k, v) in files: + # support for explicit filename + ft = None + fh = None + if isinstance(v, (tuple, list)): + if len(v) == 2: + fn, fp = v + elif len(v) == 3: + fn, fp, ft = v + else: + fn, fp, ft, fh = v + else: + fn = guess_filename(v) or k + fp = v + + if isinstance(fp, (str, bytes, bytearray)): + fdata = fp + elif hasattr(fp, 'read'): + fdata = fp.read() + elif fp is None: + continue + else: + fdata = fp + + rf = RequestField(name=k, data=fdata, filename=fn, headers=fh) + rf.make_multipart(content_type=ft) + new_fields.append(rf) + + body, content_type = encode_multipart_formdata(new_fields) + + return body, content_type + + +class RequestHooksMixin(object): + def register_hook(self, event, hook): + """Properly register a hook.""" + + if event not in self.hooks: + raise ValueError('Unsupported event specified, with event name "%s"' % (event)) + + if isinstance(hook, Callable): + self.hooks[event].append(hook) + elif hasattr(hook, '__iter__'): + self.hooks[event].extend(h for h in hook if isinstance(h, Callable)) + + def deregister_hook(self, event, hook): + """Deregister a previously registered hook. + Returns True if the hook existed, False if not. + """ + + try: + self.hooks[event].remove(hook) + return True + except ValueError: + return False + + +class Request(RequestHooksMixin): + """A user-created :class:`Request <Request>` object. + + Used to prepare a :class:`PreparedRequest <PreparedRequest>`, which is sent to the server. + + :param method: HTTP method to use. + :param url: URL to send. + :param headers: dictionary of headers to send. + :param files: dictionary of {filename: fileobject} files to multipart upload. + :param data: the body to attach to the request. If a dictionary is provided, form-encoding will take place. + :param json: json for the body to attach to the request (if files or data is not specified). + :param params: dictionary of URL parameters to append to the URL. + :param auth: Auth handler or (user, pass) tuple. + :param cookies: dictionary or CookieJar of cookies to attach to this request. + :param hooks: dictionary of callback hooks, for internal usage. + + Usage:: + + >>> import requests + >>> req = requests.Request('GET', 'http://httpbin.org/get') + >>> req.prepare() + <PreparedRequest [GET]> + """ + + def __init__(self, + method=None, url=None, headers=None, files=None, data=None, + params=None, auth=None, cookies=None, hooks=None, json=None): + + # Default empty dicts for dict params. + data = [] if data is None else data + files = [] if files is None else files + headers = {} if headers is None else headers + params = {} if params is None else params + hooks = {} if hooks is None else hooks + + self.hooks = default_hooks() + for (k, v) in list(hooks.items()): + self.register_hook(event=k, hook=v) + + self.method = method + self.url = url + self.headers = headers + self.files = files + self.data = data + self.json = json + self.params = params + self.auth = auth + self.cookies = cookies + + def __repr__(self): + return '<Request [%s]>' % (self.method) + + def prepare(self): + """Constructs a :class:`PreparedRequest <PreparedRequest>` for transmission and returns it.""" + p = PreparedRequest() + p.prepare( + method=self.method, + url=self.url, + headers=self.headers, + files=self.files, + data=self.data, + json=self.json, + params=self.params, + auth=self.auth, + cookies=self.cookies, + hooks=self.hooks, + ) + return p + + +class PreparedRequest(RequestEncodingMixin, RequestHooksMixin): + """The fully mutable :class:`PreparedRequest <PreparedRequest>` object, + containing the exact bytes that will be sent to the server. + + Generated from either a :class:`Request <Request>` object or manually. + + Usage:: + + >>> import requests + >>> req = requests.Request('GET', 'http://httpbin.org/get') + >>> r = req.prepare() + <PreparedRequest [GET]> + + >>> s = requests.Session() + >>> s.send(r) + <Response [200]> + """ + + def __init__(self): + #: HTTP verb to send to the server. + self.method = None + #: HTTP URL to send the request to. + self.url = None + #: dictionary of HTTP headers. + self.headers = None + # The `CookieJar` used to create the Cookie header will be stored here + # after prepare_cookies is called + self._cookies = None + #: request body to send to the server. + self.body = None + #: dictionary of callback hooks, for internal usage. + self.hooks = default_hooks() + #: integer denoting starting position of a readable file-like body. + self._body_position = None + + def prepare(self, + method=None, url=None, headers=None, files=None, data=None, + params=None, auth=None, cookies=None, hooks=None, json=None): + """Prepares the entire request with the given parameters.""" + + self.prepare_method(method) + self.prepare_url(url, params) + self.prepare_headers(headers) + self.prepare_cookies(cookies) + self.prepare_body(data, files, json) + self.prepare_auth(auth, url) + + # Note that prepare_auth must be last to enable authentication schemes + # such as OAuth to work on a fully prepared request. + + # This MUST go after prepare_auth. Authenticators could add a hook + self.prepare_hooks(hooks) + + def __repr__(self): + return '<PreparedRequest [%s]>' % (self.method) + + def copy(self): + p = PreparedRequest() + p.method = self.method + p.url = self.url + p.headers = self.headers.copy() if self.headers is not None else None + p._cookies = _copy_cookie_jar(self._cookies) + p.body = self.body + p.hooks = self.hooks + p._body_position = self._body_position + return p + + def prepare_method(self, method): + """Prepares the given HTTP method.""" + self.method = method + if self.method is not None: + self.method = to_native_string(self.method.upper()) + + @staticmethod + def _get_idna_encoded_host(host): + from pip._vendor import idna + + try: + host = idna.encode(host, uts46=True).decode('utf-8') + except idna.IDNAError: + raise UnicodeError + return host + + def prepare_url(self, url, params): + """Prepares the given HTTP URL.""" + #: Accept objects that have string representations. + #: 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 + if isinstance(url, bytes): + url = url.decode('utf8') + else: + url = unicode(url) if is_py2 else str(url) + + # Remove leading whitespaces from url + url = url.lstrip() + + # Don't do any URL preparation for non-HTTP schemes like `mailto`, + # `data` etc to work around exceptions from `url_parse`, which + # handles RFC 3986 only. + if ':' in url and not url.lower().startswith('http'): + self.url = url + return + + # Support for unicode domain names and paths. + try: + scheme, auth, host, port, path, query, fragment = parse_url(url) + except LocationParseError as e: + raise InvalidURL(*e.args) + + if not scheme: + error = ("Invalid URL {0!r}: No schema supplied. Perhaps you meant http://{0}?") + error = error.format(to_native_string(url, 'utf8')) + + raise MissingSchema(error) + + if not host: + raise InvalidURL("Invalid URL %r: No host supplied" % url) + + # In general, we want to try IDNA encoding the hostname if the string contains + # non-ASCII characters. This allows users to automatically get the correct IDNA + # behaviour. For strings containing only ASCII characters, we need to also verify + # it doesn't start with a wildcard (*), before allowing the unencoded hostname. + if not unicode_is_ascii(host): + try: + host = self._get_idna_encoded_host(host) + except UnicodeError: + raise InvalidURL('URL has an invalid label.') + elif host.startswith(u'*'): + raise InvalidURL('URL has an invalid label.') + + # Carefully reconstruct the network location + netloc = auth or '' + if netloc: + netloc += '@' + netloc += host + if port: + netloc += ':' + str(port) + + # Bare domains aren't valid URLs. + if not path: + path = '/' + + if is_py2: + if isinstance(scheme, str): + scheme = scheme.encode('utf-8') + if isinstance(netloc, str): + netloc = netloc.encode('utf-8') + if isinstance(path, str): + path = path.encode('utf-8') + if isinstance(query, str): + query = query.encode('utf-8') + if isinstance(fragment, str): + fragment = fragment.encode('utf-8') + + if isinstance(params, (str, bytes)): + params = to_native_string(params) + + enc_params = self._encode_params(params) + if enc_params: + if query: + query = '%s&%s' % (query, enc_params) + else: + query = enc_params + + url = requote_uri(urlunparse([scheme, netloc, path, None, query, fragment])) + self.url = url + + def prepare_headers(self, headers): + """Prepares the given HTTP headers.""" + + self.headers = CaseInsensitiveDict() + if headers: + for header in headers.items(): + # Raise exception on invalid header value. + check_header_validity(header) + name, value = header + self.headers[to_native_string(name)] = value + + def prepare_body(self, data, files, json=None): + """Prepares the given HTTP body data.""" + + # Check if file, fo, generator, iterator. + # If not, run through normal process. + + # Nottin' on you. + body = None + content_type = None + + if not data and json is not None: + # urllib3 requires a bytes-like body. Python 2's json.dumps + # provides this natively, but Python 3 gives a Unicode string. + content_type = 'application/json' + body = complexjson.dumps(json) + if not isinstance(body, bytes): + body = body.encode('utf-8') + + is_stream = all([ + hasattr(data, '__iter__'), + not isinstance(data, (basestring, list, tuple, Mapping)) + ]) + + try: + length = super_len(data) + except (TypeError, AttributeError, UnsupportedOperation): + length = None + + if is_stream: + body = data + + if getattr(body, 'tell', None) is not None: + # Record the current file position before reading. + # This will allow us to rewind a file in the event + # of a redirect. + try: + self._body_position = body.tell() + except (IOError, OSError): + # This differentiates from None, allowing us to catch + # a failed `tell()` later when trying to rewind the body + self._body_position = object() + + if files: + raise NotImplementedError('Streamed bodies and files are mutually exclusive.') + + if length: + self.headers['Content-Length'] = builtin_str(length) + else: + self.headers['Transfer-Encoding'] = 'chunked' + else: + # Multi-part file uploads. + if files: + (body, content_type) = self._encode_files(files, data) + else: + if data: + body = self._encode_params(data) + if isinstance(data, basestring) or hasattr(data, 'read'): + content_type = None + else: + content_type = 'application/x-www-form-urlencoded' + + self.prepare_content_length(body) + + # Add content-type if it wasn't explicitly provided. + if content_type and ('content-type' not in self.headers): + self.headers['Content-Type'] = content_type + + self.body = body + + def prepare_content_length(self, body): + """Prepare Content-Length header based on request method and body""" + if body is not None: + length = super_len(body) + if length: + # If length exists, set it. Otherwise, we fallback + # to Transfer-Encoding: chunked. + self.headers['Content-Length'] = builtin_str(length) + elif self.method not in ('GET', 'HEAD') and self.headers.get('Content-Length') is None: + # Set Content-Length to 0 for methods that can have a body + # but don't provide one. (i.e. not GET or HEAD) + self.headers['Content-Length'] = '0' + + def prepare_auth(self, auth, url=''): + """Prepares the given HTTP auth data.""" + + # If no Auth is explicitly provided, extract it from the URL first. + if auth is None: + url_auth = get_auth_from_url(self.url) + auth = url_auth if any(url_auth) else None + + if auth: + if isinstance(auth, tuple) and len(auth) == 2: + # special-case basic HTTP auth + auth = HTTPBasicAuth(*auth) + + # Allow auth to make its changes. + r = auth(self) + + # Update self to reflect the auth changes. + self.__dict__.update(r.__dict__) + + # Recompute Content-Length + self.prepare_content_length(self.body) + + def prepare_cookies(self, cookies): + """Prepares the given HTTP cookie data. + + This function eventually generates a ``Cookie`` header from the + given cookies using cookielib. Due to cookielib's design, the header + will not be regenerated if it already exists, meaning this function + can only be called once for the life of the + :class:`PreparedRequest <PreparedRequest>` object. Any subsequent calls + to ``prepare_cookies`` will have no actual effect, unless the "Cookie" + header is removed beforehand. + """ + if isinstance(cookies, cookielib.CookieJar): + self._cookies = cookies + else: + self._cookies = cookiejar_from_dict(cookies) + + cookie_header = get_cookie_header(self._cookies, self) + if cookie_header is not None: + self.headers['Cookie'] = cookie_header + + def prepare_hooks(self, hooks): + """Prepares the given hooks.""" + # hooks can be passed as None to the prepare method and to this + # method. To prevent iterating over None, simply use an empty list + # if hooks is False-y + hooks = hooks or [] + for event in hooks: + self.register_hook(event, hooks[event]) + + +class Response(object): + """The :class:`Response <Response>` object, which contains a + server's response to an HTTP request. + """ + + __attrs__ = [ + '_content', 'status_code', 'headers', 'url', 'history', + 'encoding', 'reason', 'cookies', 'elapsed', 'request' + ] + + def __init__(self): + self._content = False + self._content_consumed = False + self._next = None + + #: Integer Code of responded HTTP Status, e.g. 404 or 200. + self.status_code = None + + #: Case-insensitive Dictionary of Response Headers. + #: For example, ``headers['content-encoding']`` will return the + #: value of a ``'Content-Encoding'`` response header. + self.headers = CaseInsensitiveDict() + + #: 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. + self.raw = None + + #: Final URL location of Response. + self.url = None + + #: Encoding to decode with when accessing r.text. + self.encoding = None + + #: A list of :class:`Response <Response>` objects from + #: the history of the Request. Any redirect responses will end + #: up here. The list is sorted from the oldest to the most recent request. + self.history = [] + + #: Textual reason of responded HTTP Status, e.g. "Not Found" or "OK". + self.reason = None + + #: A CookieJar of Cookies the server sent back. + self.cookies = cookiejar_from_dict({}) + + #: The amount of time elapsed between sending the request + #: and the arrival of the response (as a timedelta). + #: This property specifically measures the time taken between sending + #: the first byte of the request and finishing parsing the headers. It + #: is therefore unaffected by consuming the response content or the + #: value of the ``stream`` keyword argument. + self.elapsed = datetime.timedelta(0) + + #: The :class:`PreparedRequest <PreparedRequest>` object to which this + #: is a response. + self.request = None + + def __enter__(self): + return self + + def __exit__(self, *args): + self.close() + + def __getstate__(self): + # Consume everything; accessing the content attribute makes + # sure the content has been fully read. + if not self._content_consumed: + self.content + + return dict( + (attr, getattr(self, attr, None)) + for attr in self.__attrs__ + ) + + def __setstate__(self, state): + for name, value in state.items(): + setattr(self, name, value) + + # pickled objects do not have .raw + setattr(self, '_content_consumed', True) + setattr(self, 'raw', None) + + def __repr__(self): + return '<Response [%s]>' % (self.status_code) + + def __bool__(self): + """Returns True if :attr:`status_code` is less than 400. + + This attribute checks if the status code of the response is between + 400 and 600 to see if there was a client error or a server error. If + the status code, is between 200 and 400, this will return True. This + is **not** a check to see if the response code is ``200 OK``. + """ + return self.ok + + def __nonzero__(self): + """Returns True if :attr:`status_code` is less than 400. + + This attribute checks if the status code of the response is between + 400 and 600 to see if there was a client error or a server error. If + the status code, is between 200 and 400, this will return True. This + is **not** a check to see if the response code is ``200 OK``. + """ + return self.ok + + def __iter__(self): + """Allows you to use a response as an iterator.""" + return self.iter_content(128) + + @property + def ok(self): + """Returns True if :attr:`status_code` is less than 400, False if not. + + This attribute checks if the status code of the response is between + 400 and 600 to see if there was a client error or a server error. If + the status code is between 200 and 400, this will return True. This + is **not** a check to see if the response code is ``200 OK``. + """ + try: + self.raise_for_status() + except HTTPError: + return False + return True + + @property + def is_redirect(self): + """True if this Response is a well-formed HTTP redirect that could have + been processed automatically (by :meth:`Session.resolve_redirects`). + """ + return ('location' in self.headers and self.status_code in REDIRECT_STATI) + + @property + def is_permanent_redirect(self): + """True if this Response one of the permanent versions of redirect.""" + return ('location' in self.headers and self.status_code in (codes.moved_permanently, codes.permanent_redirect)) + + @property + def next(self): + """Returns a PreparedRequest for the next request in a redirect chain, if there is one.""" + return self._next + + @property + def apparent_encoding(self): + """The apparent encoding, provided by the chardet library.""" + return chardet.detect(self.content)['encoding'] + + def iter_content(self, chunk_size=1, decode_unicode=False): + """Iterates over the response data. When stream=True is set on the + request, this avoids reading the content at once into memory for + large responses. The chunk size is the number of bytes it should + read into memory. This is not necessarily the length of each item + returned as decoding can take place. + + chunk_size must be of type int or None. A value of None will + function differently depending on the value of `stream`. + stream=True will read data as it arrives in whatever size the + chunks are received. If stream=False, data is returned as + a single chunk. + + If decode_unicode is True, content will be decoded using the best + available encoding based on the response. + """ + + def generate(): + # Special case for urllib3. + if hasattr(self.raw, 'stream'): + try: + for chunk in self.raw.stream(chunk_size, decode_content=True): + yield chunk + except ProtocolError as e: + raise ChunkedEncodingError(e) + except DecodeError as e: + raise ContentDecodingError(e) + except ReadTimeoutError as e: + raise ConnectionError(e) + else: + # Standard file-like object. + while True: + chunk = self.raw.read(chunk_size) + if not chunk: + break + yield chunk + + self._content_consumed = True + + if self._content_consumed and isinstance(self._content, bool): + raise StreamConsumedError() + elif chunk_size is not None and not isinstance(chunk_size, int): + raise TypeError("chunk_size must be an int, it is instead a %s." % type(chunk_size)) + # simulate reading small chunks of the content + reused_chunks = iter_slices(self._content, chunk_size) + + stream_chunks = generate() + + chunks = reused_chunks if self._content_consumed else stream_chunks + + if decode_unicode: + chunks = stream_decode_response_unicode(chunks, self) + + return chunks + + def iter_lines(self, chunk_size=ITER_CHUNK_SIZE, decode_unicode=None, delimiter=None): + """Iterates over the response data, one line at a time. When + stream=True is set on the request, this avoids reading the + content at once into memory for large responses. + + .. note:: This method is not reentrant safe. + """ + + pending = None + + for chunk in self.iter_content(chunk_size=chunk_size, decode_unicode=decode_unicode): + + if pending is not None: + chunk = pending + chunk + + if delimiter: + lines = chunk.split(delimiter) + else: + lines = chunk.splitlines() + + if lines and lines[-1] and chunk and lines[-1][-1] == chunk[-1]: + pending = lines.pop() + else: + pending = None + + for line in lines: + yield line + + if pending is not None: + yield pending + + @property + def content(self): + """Content of the response, in bytes.""" + + if self._content is False: + # Read the contents. + if self._content_consumed: + raise RuntimeError( + 'The content for this response was already consumed') + + if self.status_code == 0 or self.raw is None: + self._content = None + else: + self._content = b''.join(self.iter_content(CONTENT_CHUNK_SIZE)) or b'' + + self._content_consumed = True + # don't need to release the connection; that's been handled by urllib3 + # since we exhausted the data. + return self._content + + @property + def text(self): + """Content of the response, in unicode. + + If Response.encoding is None, encoding will be guessed using + ``chardet``. + + The encoding of the response content is determined based solely on HTTP + headers, following RFC 2616 to the letter. If you can take advantage of + non-HTTP knowledge to make a better guess at the encoding, you should + set ``r.encoding`` appropriately before accessing this property. + """ + + # Try charset from content-type + content = None + encoding = self.encoding + + if not self.content: + return str('') + + # Fallback to auto-detected encoding. + if self.encoding is None: + encoding = self.apparent_encoding + + # Decode unicode from given encoding. + try: + content = str(self.content, encoding, errors='replace') + except (LookupError, TypeError): + # A LookupError is raised if the encoding was not found which could + # indicate a misspelling or similar mistake. + # + # A TypeError can be raised if encoding is None + # + # So we try blindly encoding. + content = str(self.content, errors='replace') + + return content + + def json(self, **kwargs): + r"""Returns the json-encoded content of a response, if any. + + :param \*\*kwargs: Optional arguments that ``json.loads`` takes. + :raises ValueError: If the response body does not contain valid json. + """ + + if not self.encoding and self.content and len(self.content) > 3: + # No encoding set. JSON RFC 4627 section 3 states we should expect + # UTF-8, -16 or -32. Detect which one to use; If the detection or + # decoding fails, fall back to `self.text` (using chardet to make + # a best guess). + encoding = guess_json_utf(self.content) + if encoding is not None: + try: + return complexjson.loads( + self.content.decode(encoding), **kwargs + ) + except UnicodeDecodeError: + # Wrong UTF codec detected; usually because it's not UTF-8 + # but some other 8-bit codec. This is an RFC violation, + # and the server didn't bother to tell us what codec *was* + # used. + pass + return complexjson.loads(self.text, **kwargs) + + @property + def links(self): + """Returns the parsed header links of the response, if any.""" + + header = self.headers.get('link') + + # l = MultiDict() + l = {} + + if header: + links = parse_header_links(header) + + for link in links: + key = link.get('rel') or link.get('url') + l[key] = link + + return l + + def raise_for_status(self): + """Raises stored :class:`HTTPError`, if one occurred.""" + + http_error_msg = '' + if isinstance(self.reason, bytes): + # We attempt to decode utf-8 first because some servers + # choose to localize their reason strings. If the string + # isn't utf-8, we fall back to iso-8859-1 for all other + # encodings. (See PR #3538) + try: + reason = self.reason.decode('utf-8') + except UnicodeDecodeError: + reason = self.reason.decode('iso-8859-1') + else: + reason = self.reason + + if 400 <= self.status_code < 500: + http_error_msg = u'%s Client Error: %s for url: %s' % (self.status_code, reason, self.url) + + elif 500 <= self.status_code < 600: + http_error_msg = u'%s Server Error: %s for url: %s' % (self.status_code, reason, self.url) + + if http_error_msg: + raise HTTPError(http_error_msg, response=self) + + def close(self): + """Releases the connection back to the pool. Once this method has been + called the underlying ``raw`` object must not be accessed again. + + *Note: Should not normally need to be called explicitly.* + """ + if not self._content_consumed: + self.raw.close() + + release_conn = getattr(self.raw, 'release_conn', None) + if release_conn is not None: + release_conn() diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/packages.py b/venv/lib/python3.7/site-packages/pip/_vendor/requests/packages.py new file mode 100644 index 0000000..9582fa7 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/requests/packages.py @@ -0,0 +1,16 @@ +import sys + +# This code exists for backwards compatibility reasons. +# I don't like it either. Just look the other way. :) + +for package in ('urllib3', 'idna', 'chardet'): + vendored_package = "pip._vendor." + package + locals()[package] = __import__(vendored_package) + # This traversal is apparently necessary such that the identities are + # preserved (requests.packages.urllib3.* is urllib3.*) + for mod in list(sys.modules): + if mod == vendored_package or mod.startswith(vendored_package + '.'): + unprefixed_mod = mod[len("pip._vendor."):] + sys.modules['pip._vendor.requests.packages.' + unprefixed_mod] = sys.modules[mod] + +# Kinda cool, though, right? diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/sessions.py b/venv/lib/python3.7/site-packages/pip/_vendor/requests/sessions.py new file mode 100644 index 0000000..ba13526 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/requests/sessions.py @@ -0,0 +1,741 @@ +# -*- coding: utf-8 -*- + +""" +requests.session +~~~~~~~~~~~~~~~~ + +This module provides a Session object to manage and persist settings across +requests (cookies, auth, proxies). +""" +import os +import sys +import time +from datetime import timedelta + +from .auth import _basic_auth_str +from .compat import cookielib, is_py3, OrderedDict, urljoin, urlparse, Mapping +from .cookies import ( + cookiejar_from_dict, extract_cookies_to_jar, RequestsCookieJar, merge_cookies) +from .models import Request, PreparedRequest, DEFAULT_REDIRECT_LIMIT +from .hooks import default_hooks, dispatch_hook +from ._internal_utils import to_native_string +from .utils import to_key_val_list, default_headers +from .exceptions import ( + TooManyRedirects, InvalidSchema, ChunkedEncodingError, ContentDecodingError) + +from .structures import CaseInsensitiveDict +from .adapters import HTTPAdapter + +from .utils import ( + requote_uri, get_environ_proxies, get_netrc_auth, should_bypass_proxies, + get_auth_from_url, rewind_body +) + +from .status_codes import codes + +# formerly defined here, reexposed here for backward compatibility +from .models import REDIRECT_STATI + +# Preferred clock, based on which one is more accurate on a given system. +if sys.platform == 'win32': + try: # Python 3.4+ + preferred_clock = time.perf_counter + except AttributeError: # Earlier than Python 3. + preferred_clock = time.clock +else: + preferred_clock = time.time + + +def merge_setting(request_setting, session_setting, dict_class=OrderedDict): + """Determines appropriate setting for a given request, taking into account + the explicit setting on that request, and the setting in the session. If a + setting is a dictionary, they will be merged together using `dict_class` + """ + + if session_setting is None: + return request_setting + + if request_setting is None: + return session_setting + + # Bypass if not a dictionary (e.g. verify) + if not ( + isinstance(session_setting, Mapping) and + isinstance(request_setting, Mapping) + ): + return request_setting + + merged_setting = dict_class(to_key_val_list(session_setting)) + merged_setting.update(to_key_val_list(request_setting)) + + # Remove keys that are set to None. Extract keys first to avoid altering + # the dictionary during iteration. + none_keys = [k for (k, v) in merged_setting.items() if v is None] + for key in none_keys: + del merged_setting[key] + + return merged_setting + + +def merge_hooks(request_hooks, session_hooks, dict_class=OrderedDict): + """Properly merges both requests and session hooks. + + This is necessary because when request_hooks == {'response': []}, the + merge breaks Session hooks entirely. + """ + if session_hooks is None or session_hooks.get('response') == []: + return request_hooks + + if request_hooks is None or request_hooks.get('response') == []: + return session_hooks + + return merge_setting(request_hooks, session_hooks, dict_class) + + +class SessionRedirectMixin(object): + + def get_redirect_target(self, resp): + """Receives a Response. Returns a redirect URI or ``None``""" + # Due to the nature of how requests processes redirects this method will + # be called at least once upon the original response and at least twice + # on each subsequent redirect response (if any). + # If a custom mixin is used to handle this logic, it may be advantageous + # to cache the redirect location onto the response object as a private + # attribute. + if resp.is_redirect: + location = resp.headers['location'] + # Currently the underlying http module on py3 decode headers + # in latin1, but empirical evidence suggests that latin1 is very + # rarely used with non-ASCII characters in HTTP headers. + # It is more likely to get UTF8 header rather than latin1. + # This causes incorrect handling of UTF8 encoded location headers. + # To solve this, we re-encode the location in latin1. + if is_py3: + location = location.encode('latin1') + return to_native_string(location, 'utf8') + return None + + def resolve_redirects(self, resp, req, stream=False, timeout=None, + verify=True, cert=None, proxies=None, yield_requests=False, **adapter_kwargs): + """Receives a Response. Returns a generator of Responses or Requests.""" + + hist = [] # keep track of history + + url = self.get_redirect_target(resp) + previous_fragment = urlparse(req.url).fragment + while url: + prepared_request = req.copy() + + # Update history and keep track of redirects. + # resp.history must ignore the original request in this loop + hist.append(resp) + resp.history = hist[1:] + + try: + resp.content # Consume socket so it can be released + except (ChunkedEncodingError, ContentDecodingError, RuntimeError): + resp.raw.read(decode_content=False) + + if len(resp.history) >= self.max_redirects: + raise TooManyRedirects('Exceeded %s redirects.' % self.max_redirects, response=resp) + + # Release the connection back into the pool. + resp.close() + + # 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) + + # Normalize url case and attach previous fragment if needed (RFC 7231 7.1.2) + parsed = urlparse(url) + if parsed.fragment == '' and previous_fragment: + parsed = parsed._replace(fragment=previous_fragment) + elif parsed.fragment: + previous_fragment = parsed.fragment + url = parsed.geturl() + + # Facilitate relative 'location' headers, as allowed by RFC 7231. + # (e.g. '/path/to/resource' instead of 'http://domain.tld/path/to/resource') + # Compliant with RFC3986, we percent encode the url. + if not parsed.netloc: + url = urljoin(resp.url, requote_uri(url)) + else: + url = requote_uri(url) + + prepared_request.url = to_native_string(url) + + self.rebuild_method(prepared_request, resp) + + # https://github.com/requests/requests/issues/1084 + if resp.status_code not in (codes.temporary_redirect, codes.permanent_redirect): + # https://github.com/requests/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 + + # Extract any cookies sent on the response to the cookiejar + # in the new request. Because we've mutated our copied prepared + # request, use the old one that we haven't yet touched. + extract_cookies_to_jar(prepared_request._cookies, req, resp.raw) + merge_cookies(prepared_request._cookies, self.cookies) + prepared_request.prepare_cookies(prepared_request._cookies) + + # Rebuild auth and proxy information. + proxies = self.rebuild_proxies(prepared_request, proxies) + self.rebuild_auth(prepared_request, resp) + + # A failed tell() sets `_body_position` to `object()`. This non-None + # value ensures `rewindable` will be True, allowing us to raise an + # UnrewindableBodyError, instead of hanging the connection. + rewindable = ( + prepared_request._body_position is not None and + ('Content-Length' in headers or 'Transfer-Encoding' in headers) + ) + + # Attempt to rewind consumed file-like object. + if rewindable: + rewind_body(prepared_request) + + # Override the original request. + req = prepared_request + + if yield_requests: + yield req + else: + + resp = self.send( + req, + stream=stream, + timeout=timeout, + verify=verify, + cert=cert, + proxies=proxies, + allow_redirects=False, + **adapter_kwargs + ) + + extract_cookies_to_jar(self.cookies, prepared_request, resp.raw) + + # extract redirect url, if any, for the next loop + url = self.get_redirect_target(resp) + yield resp + + def rebuild_auth(self, prepared_request, response): + """When being redirected we may want to strip authentication from the + request to avoid leaking credentials. This method intelligently removes + and reapplies authentication where possible to avoid credential loss. + """ + headers = prepared_request.headers + url = prepared_request.url + + if 'Authorization' in headers: + # If we get redirected to a new host, we should strip out any + # authentication headers. + original_parsed = urlparse(response.request.url) + redirect_parsed = urlparse(url) + + if (original_parsed.hostname != redirect_parsed.hostname): + del headers['Authorization'] + + # .netrc might have more auth for us on our new host. + new_auth = get_netrc_auth(url) if self.trust_env else None + 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 + environment variables. If we are redirected to a URL covered by + NO_PROXY, we strip the proxy configuration. Otherwise, we set missing + proxy keys for this URL (in case they were stripped by a previous + redirect). + + This method also replaces the Proxy-Authorization header where + necessary. + + :rtype: dict + """ + proxies = proxies if proxies is not None else {} + headers = prepared_request.headers + url = prepared_request.url + scheme = urlparse(url).scheme + new_proxies = proxies.copy() + no_proxy = proxies.get('no_proxy') + + bypass_proxy = should_bypass_proxies(url, no_proxy=no_proxy) + if self.trust_env and not bypass_proxy: + environ_proxies = get_environ_proxies(url, no_proxy=no_proxy) + + proxy = environ_proxies.get(scheme, environ_proxies.get('all')) + + if proxy: + new_proxies.setdefault(scheme, proxy) + + if 'Proxy-Authorization' in headers: + del headers['Proxy-Authorization'] + + try: + username, password = get_auth_from_url(new_proxies[scheme]) + except KeyError: + username, password = None, None + + if username and password: + headers['Proxy-Authorization'] = _basic_auth_str(username, password) + + return new_proxies + + def rebuild_method(self, prepared_request, response): + """When being redirected we may want to change the method of the request + based on certain specs or browser behavior. + """ + method = prepared_request.method + + # http://tools.ietf.org/html/rfc7231#section-6.4.4 + if response.status_code == codes.see_other and method != 'HEAD': + method = 'GET' + + # Do what the browsers do, despite standards... + # First, turn 302s into GETs. + if response.status_code == codes.found and method != 'HEAD': + method = 'GET' + + # Second, if a POST is responded to with a 301, turn it into a GET. + # This bizarre behaviour is explained in Issue 1704. + if response.status_code == codes.moved and method == 'POST': + method = 'GET' + + prepared_request.method = method + + +class Session(SessionRedirectMixin): + """A Requests session. + + Provides cookie persistence, connection-pooling, and configuration. + + Basic Usage:: + + >>> import requests + >>> s = requests.Session() + >>> s.get('http://httpbin.org/get') + <Response [200]> + + Or as a context manager:: + + >>> with requests.Session() as s: + >>> s.get('http://httpbin.org/get') + <Response [200]> + """ + + __attrs__ = [ + 'headers', 'cookies', 'auth', 'proxies', 'hooks', 'params', 'verify', + 'cert', 'prefetch', 'adapters', 'stream', 'trust_env', + 'max_redirects', + ] + + def __init__(self): + + #: A case-insensitive dictionary of headers to be sent on each + #: :class:`Request <Request>` sent from this + #: :class:`Session <Session>`. + self.headers = default_headers() + + #: Default Authentication tuple or object to attach to + #: :class:`Request <Request>`. + self.auth = None + + #: Dictionary mapping protocol or protocol and host to the URL of the proxy + #: (e.g. {'http': 'foo.bar:3128', 'http://host.name': 'foo.bar:4012'}) to + #: be used on each :class:`Request <Request>`. + self.proxies = {} + + #: Event-handling hooks. + self.hooks = default_hooks() + + #: Dictionary of querystring data to attach to each + #: :class:`Request <Request>`. The dictionary values may be lists for + #: representing multivalued query parameters. + self.params = {} + + #: Stream response content default. + self.stream = False + + #: SSL Verification default. + self.verify = True + + #: SSL client certificate default, if String, path to ssl client + #: cert file (.pem). If Tuple, ('cert', 'key') pair. + self.cert = None + + #: Maximum number of redirects allowed. If the request exceeds this + #: limit, a :class:`TooManyRedirects` exception is raised. + #: This defaults to requests.models.DEFAULT_REDIRECT_LIMIT, which is + #: 30. + self.max_redirects = DEFAULT_REDIRECT_LIMIT + + #: Trust environment settings for proxy configuration, default + #: authentication and similar. + self.trust_env = True + + #: A CookieJar containing all currently outstanding cookies set on this + #: session. By default it is a + #: :class:`RequestsCookieJar <requests.cookies.RequestsCookieJar>`, but + #: may be any other ``cookielib.CookieJar`` compatible object. + self.cookies = cookiejar_from_dict({}) + + # Default connection adapters. + self.adapters = OrderedDict() + self.mount('https://', HTTPAdapter()) + self.mount('http://', HTTPAdapter()) + + def __enter__(self): + return self + + def __exit__(self, *args): + self.close() + + def prepare_request(self, request): + """Constructs a :class:`PreparedRequest <PreparedRequest>` for + transmission and returns it. The :class:`PreparedRequest` has settings + merged from the :class:`Request <Request>` instance and those of the + :class:`Session`. + + :param request: :class:`Request` instance to prepare with this + session's settings. + :rtype: requests.PreparedRequest + """ + cookies = request.cookies or {} + + # Bootstrap CookieJar. + if not isinstance(cookies, cookielib.CookieJar): + cookies = cookiejar_from_dict(cookies) + + # Merge with session cookies + merged_cookies = merge_cookies( + merge_cookies(RequestsCookieJar(), self.cookies), cookies) + + # Set environment's basic authentication if not explicitly set. + auth = request.auth + if self.trust_env and not auth and not self.auth: + auth = get_netrc_auth(request.url) + + p = PreparedRequest() + p.prepare( + method=request.method.upper(), + url=request.url, + files=request.files, + data=request.data, + json=request.json, + headers=merge_setting(request.headers, self.headers, dict_class=CaseInsensitiveDict), + params=merge_setting(request.params, self.params), + auth=merge_setting(auth, self.auth), + cookies=merged_cookies, + hooks=merge_hooks(request.hooks, self.hooks), + ) + return p + + def request(self, method, url, + params=None, data=None, headers=None, cookies=None, files=None, + auth=None, timeout=None, allow_redirects=True, proxies=None, + hooks=None, stream=None, verify=None, cert=None, json=None): + """Constructs a :class:`Request <Request>`, prepares it and sends it. + Returns :class:`Response <Response>` object. + + :param method: method for the new :class:`Request` object. + :param url: URL for the new :class:`Request` object. + :param params: (optional) Dictionary or bytes to be sent in the query + string for the :class:`Request`. + :param data: (optional) Dictionary, bytes, or file-like object to send + in the body of the :class:`Request`. + :param json: (optional) json to send in the body of the + :class:`Request`. + :param headers: (optional) Dictionary of HTTP Headers to send with the + :class:`Request`. + :param cookies: (optional) Dict or CookieJar object to send with the + :class:`Request`. + :param files: (optional) Dictionary of ``'filename': file-like-objects`` + for multipart encoding upload. + :param auth: (optional) Auth tuple or callable to enable + Basic/Digest/Custom HTTP Auth. + :param timeout: (optional) How long to wait for the server to send + data before giving up, as a float, or a :ref:`(connect timeout, + read timeout) <timeouts>` tuple. + :type timeout: float or tuple + :param allow_redirects: (optional) Set to True by default. + :type allow_redirects: bool + :param proxies: (optional) Dictionary mapping protocol or protocol and + hostname to the URL of the proxy. + :param stream: (optional) whether to immediately download the response + content. Defaults to ``False``. + :param verify: (optional) Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use. Defaults to ``True``. + :param cert: (optional) if String, path to ssl client cert file (.pem). + If Tuple, ('cert', 'key') pair. + :rtype: requests.Response + """ + # Create the Request. + req = Request( + method=method.upper(), + url=url, + headers=headers, + files=files, + data=data or {}, + json=json, + params=params or {}, + auth=auth, + cookies=cookies, + hooks=hooks, + ) + prep = self.prepare_request(req) + + proxies = proxies or {} + + settings = self.merge_environment_settings( + prep.url, proxies, stream, verify, cert + ) + + # Send the request. + send_kwargs = { + 'timeout': timeout, + 'allow_redirects': allow_redirects, + } + send_kwargs.update(settings) + resp = self.send(prep, **send_kwargs) + + return resp + + def get(self, url, **kwargs): + r"""Sends a GET request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', True) + return self.request('GET', url, **kwargs) + + def options(self, url, **kwargs): + r"""Sends a OPTIONS request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', True) + return self.request('OPTIONS', url, **kwargs) + + def head(self, url, **kwargs): + r"""Sends a HEAD request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', False) + return self.request('HEAD', url, **kwargs) + + def post(self, url, data=None, json=None, **kwargs): + r"""Sends a POST request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`. + :param json: (optional) json to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request('POST', url, data=data, json=json, **kwargs) + + def put(self, url, data=None, **kwargs): + r"""Sends a PUT request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request('PUT', url, data=data, **kwargs) + + def patch(self, url, data=None, **kwargs): + r"""Sends a PATCH request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request('PATCH', url, data=data, **kwargs) + + def delete(self, url, **kwargs): + r"""Sends a DELETE request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request('DELETE', url, **kwargs) + + def send(self, request, **kwargs): + """Send a given PreparedRequest. + + :rtype: requests.Response + """ + # Set defaults that the hooks can utilize to ensure they always have + # the correct parameters to reproduce the previous request. + kwargs.setdefault('stream', self.stream) + kwargs.setdefault('verify', self.verify) + kwargs.setdefault('cert', self.cert) + kwargs.setdefault('proxies', self.proxies) + + # It's possible that users might accidentally send a Request object. + # Guard against that specific failure case. + if isinstance(request, Request): + raise ValueError('You can only send PreparedRequests.') + + # Set up variables needed for resolve_redirects and dispatching of hooks + allow_redirects = kwargs.pop('allow_redirects', True) + stream = kwargs.get('stream') + hooks = request.hooks + + # Get the appropriate adapter to use + adapter = self.get_adapter(url=request.url) + + # Start time (approximately) of the request + start = preferred_clock() + + # Send the request + r = adapter.send(request, **kwargs) + + # Total elapsed time of the request (approximately) + elapsed = preferred_clock() - start + r.elapsed = timedelta(seconds=elapsed) + + # Response manipulation hooks + r = dispatch_hook('response', hooks, r, **kwargs) + + # Persist cookies + if r.history: + + # If the hooks create history then we want those cookies too + for resp in r.history: + extract_cookies_to_jar(self.cookies, resp.request, resp.raw) + + 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 [] + + # Shuffle things around if there's history. + if history: + # Insert the first (original) request at the start + history.insert(0, r) + # Get the last request made + r = history.pop() + r.history = history + + # If redirects aren't being followed, store the response on the Request for Response.next(). + if not allow_redirects: + try: + r._next = next(self.resolve_redirects(r, request, yield_requests=True, **kwargs)) + except StopIteration: + pass + + if not stream: + r.content + + return r + + def merge_environment_settings(self, url, proxies, stream, verify, cert): + """ + Check the environment and merge it with some settings. + + :rtype: dict + """ + # Gather clues from the surrounding environment. + if self.trust_env: + # Set environment's proxies. + no_proxy = proxies.get('no_proxy') if proxies is not None else None + env_proxies = get_environ_proxies(url, no_proxy=no_proxy) + for (k, v) in env_proxies.items(): + proxies.setdefault(k, v) + + # Look for requests environment configuration and be compatible + # with cURL. + if verify is True or verify is None: + verify = (os.environ.get('REQUESTS_CA_BUNDLE') or + os.environ.get('CURL_CA_BUNDLE')) + + # Merge all the kwargs. + proxies = merge_setting(proxies, self.proxies) + stream = merge_setting(stream, self.stream) + verify = merge_setting(verify, self.verify) + cert = merge_setting(cert, self.cert) + + return {'verify': verify, 'proxies': proxies, 'stream': stream, + 'cert': cert} + + def get_adapter(self, url): + """ + Returns the appropriate connection adapter for the given URL. + + :rtype: requests.adapters.BaseAdapter + """ + for (prefix, adapter) in self.adapters.items(): + + if url.lower().startswith(prefix.lower()): + return adapter + + # Nothing matches :-/ + raise InvalidSchema("No connection adapters were found for '%s'" % url) + + def close(self): + """Closes all adapters and as such the session""" + for v in self.adapters.values(): + v.close() + + def mount(self, prefix, adapter): + """Registers a connection adapter to a prefix. + + Adapters are sorted in descending order by prefix length. + """ + self.adapters[prefix] = adapter + keys_to_move = [k for k in self.adapters if len(k) < len(prefix)] + + for key in keys_to_move: + self.adapters[key] = self.adapters.pop(key) + + def __getstate__(self): + state = dict((attr, getattr(self, attr, None)) for attr in self.__attrs__) + return state + + def __setstate__(self, state): + for attr, value in state.items(): + setattr(self, attr, value) + + +def session(): + """ + Returns a :class:`Session` for context-management. + + :rtype: Session + """ + + return Session() diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/status_codes.py b/venv/lib/python3.7/site-packages/pip/_vendor/requests/status_codes.py new file mode 100644 index 0000000..ff462c6 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/requests/status_codes.py @@ -0,0 +1,120 @@ +# -*- coding: utf-8 -*- + +""" +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 + +Some codes have multiple names, and both upper- and lower-case versions of +the names are allowed. For example, ``codes.ok``, ``codes.OK``, and +``codes.okay`` all correspond to the HTTP status code 200. +""" + +from .structures import LookupDict + +_codes = { + + # Informational. + 100: ('continue',), + 101: ('switching_protocols',), + 102: ('processing',), + 103: ('checkpoint',), + 122: ('uri_too_long', 'request_uri_too_long'), + 200: ('ok', 'okay', 'all_ok', 'all_okay', 'all_good', '\\o/', '✓'), + 201: ('created',), + 202: ('accepted',), + 203: ('non_authoritative_info', 'non_authoritative_information'), + 204: ('no_content',), + 205: ('reset_content', 'reset'), + 206: ('partial_content', 'partial'), + 207: ('multi_status', 'multiple_status', 'multi_stati', 'multiple_stati'), + 208: ('already_reported',), + 226: ('im_used',), + + # Redirection. + 300: ('multiple_choices',), + 301: ('moved_permanently', 'moved', '\\o-'), + 302: ('found',), + 303: ('see_other', 'other'), + 304: ('not_modified',), + 305: ('use_proxy',), + 306: ('switch_proxy',), + 307: ('temporary_redirect', 'temporary_moved', 'temporary'), + 308: ('permanent_redirect', + 'resume_incomplete', 'resume',), # These 2 to be removed in 3.0 + + # Client Error. + 400: ('bad_request', 'bad'), + 401: ('unauthorized',), + 402: ('payment_required', 'payment'), + 403: ('forbidden',), + 404: ('not_found', '-o-'), + 405: ('method_not_allowed', 'not_allowed'), + 406: ('not_acceptable',), + 407: ('proxy_authentication_required', 'proxy_auth', 'proxy_authentication'), + 408: ('request_timeout', 'timeout'), + 409: ('conflict',), + 410: ('gone',), + 411: ('length_required',), + 412: ('precondition_failed', 'precondition'), + 413: ('request_entity_too_large',), + 414: ('request_uri_too_large',), + 415: ('unsupported_media_type', 'unsupported_media', 'media_type'), + 416: ('requested_range_not_satisfiable', 'requested_range', 'range_not_satisfiable'), + 417: ('expectation_failed',), + 418: ('im_a_teapot', 'teapot', 'i_am_a_teapot'), + 421: ('misdirected_request',), + 422: ('unprocessable_entity', 'unprocessable'), + 423: ('locked',), + 424: ('failed_dependency', 'dependency'), + 425: ('unordered_collection', 'unordered'), + 426: ('upgrade_required', 'upgrade'), + 428: ('precondition_required', 'precondition'), + 429: ('too_many_requests', 'too_many'), + 431: ('header_fields_too_large', 'fields_too_large'), + 444: ('no_response', 'none'), + 449: ('retry_with', 'retry'), + 450: ('blocked_by_windows_parental_controls', 'parental_controls'), + 451: ('unavailable_for_legal_reasons', 'legal_reasons'), + 499: ('client_closed_request',), + + # Server Error. + 500: ('internal_server_error', 'server_error', '/o\\', '✗'), + 501: ('not_implemented',), + 502: ('bad_gateway',), + 503: ('service_unavailable', 'unavailable'), + 504: ('gateway_timeout',), + 505: ('http_version_not_supported', 'http_version'), + 506: ('variant_also_negotiates',), + 507: ('insufficient_storage',), + 509: ('bandwidth_limit_exceeded', 'bandwidth'), + 510: ('not_extended',), + 511: ('network_authentication_required', 'network_auth', 'network_authentication'), +} + +codes = LookupDict(name='status_codes') + +def _init(): + for code, titles in _codes.items(): + for title in titles: + setattr(codes, title, code) + if not title.startswith(('\\', '/')): + setattr(codes, title.upper(), code) + + def doc(code): + names = ', '.join('``%s``' % n for n in _codes[code]) + return '* %d: %s' % (code, names) + + global __doc__ + __doc__ = (__doc__ + '\n' + + '\n'.join(doc(code) for code in sorted(_codes)) + if __doc__ is not None else None) + +_init() diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/structures.py b/venv/lib/python3.7/site-packages/pip/_vendor/requests/structures.py new file mode 100644 index 0000000..da930e2 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/requests/structures.py @@ -0,0 +1,103 @@ +# -*- coding: utf-8 -*- + +""" +requests.structures +~~~~~~~~~~~~~~~~~~~ + +Data structures that power Requests. +""" + +from .compat import OrderedDict, Mapping, MutableMapping + + +class CaseInsensitiveDict(MutableMapping): + """A case-insensitive ``dict``-like object. + + Implements all methods and operations of + ``MutableMapping`` as well as dict's ``copy``. Also + provides ``lower_items``. + + All keys are expected to be strings. The structure remembers the + case of the last key to be set, and ``iter(instance)``, + ``keys()``, ``items()``, ``iterkeys()``, and ``iteritems()`` + will contain case-sensitive keys. However, querying and contains + testing is case insensitive:: + + cid = CaseInsensitiveDict() + cid['Accept'] = 'application/json' + cid['aCCEPT'] == 'application/json' # True + list(cid) == ['Accept'] # True + + For example, ``headers['content-encoding']`` will return the + value of a ``'Content-Encoding'`` response header, regardless + of how the header name was originally stored. + + If the constructor, ``.update``, or equality comparison + operations are given keys that have equal ``.lower()``s, the + behavior is undefined. + """ + + def __init__(self, data=None, **kwargs): + self._store = OrderedDict() + if data is None: + data = {} + self.update(data, **kwargs) + + def __setitem__(self, key, value): + # Use the lowercased key for lookups, but store the actual + # key alongside the value. + self._store[key.lower()] = (key, value) + + def __getitem__(self, key): + return self._store[key.lower()][1] + + def __delitem__(self, key): + del self._store[key.lower()] + + def __iter__(self): + return (casedkey for casedkey, mappedvalue in self._store.values()) + + def __len__(self): + return len(self._store) + + def lower_items(self): + """Like iteritems(), but with all lowercase keys.""" + return ( + (lowerkey, keyval[1]) + for (lowerkey, keyval) + in self._store.items() + ) + + def __eq__(self, other): + if isinstance(other, Mapping): + other = CaseInsensitiveDict(other) + else: + return NotImplemented + # Compare insensitively + return dict(self.lower_items()) == dict(other.lower_items()) + + # Copy is required + def copy(self): + return CaseInsensitiveDict(self._store.values()) + + def __repr__(self): + return str(dict(self.items())) + + +class LookupDict(dict): + """Dictionary lookup object.""" + + def __init__(self, name=None): + self.name = name + super(LookupDict, self).__init__() + + def __repr__(self): + return '<lookup \'%s\'>' % (self.name) + + def __getitem__(self, key): + # We allow fall-through here, so values default to None + + return self.__dict__.get(key, None) + + def get(self, key, default=None): + return self.__dict__.get(key, default) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/requests/utils.py b/venv/lib/python3.7/site-packages/pip/_vendor/requests/utils.py new file mode 100644 index 0000000..431f6be --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/requests/utils.py @@ -0,0 +1,976 @@ +# -*- coding: utf-8 -*- + +""" +requests.utils +~~~~~~~~~~~~~~ + +This module provides utility functions that are used within Requests +that are also useful for external consumption. +""" + +import codecs +import contextlib +import io +import os +import re +import socket +import struct +import sys +import tempfile +import warnings +import zipfile + +from .__version__ import __version__ +from . import certs +# to_native_string is unused here, but imported here for backwards compatibility +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, + proxy_bypass, urlunparse, basestring, integer_types, is_py3, + proxy_bypass_environment, getproxies_environment, Mapping) +from .cookies import cookiejar_from_dict +from .structures import CaseInsensitiveDict +from .exceptions import ( + InvalidURL, InvalidHeader, FileModeWarning, UnrewindableBodyError) + +NETRC_FILES = ('.netrc', '_netrc') + +DEFAULT_CA_BUNDLE_PATH = certs.where() + + +if sys.platform == 'win32': + # provide a proxy_bypass version on Windows without DNS lookups + + def proxy_bypass_registry(host): + try: + if is_py3: + import winreg + else: + import _winreg as winreg + except ImportError: + return False + + try: + internetSettings = winreg.OpenKey(winreg.HKEY_CURRENT_USER, + r'Software\Microsoft\Windows\CurrentVersion\Internet Settings') + # ProxyEnable could be REG_SZ or REG_DWORD, normalizing it + proxyEnable = int(winreg.QueryValueEx(internetSettings, + 'ProxyEnable')[0]) + # ProxyOverride is almost always a string + proxyOverride = winreg.QueryValueEx(internetSettings, + 'ProxyOverride')[0] + except OSError: + return False + if not proxyEnable or not proxyOverride: + return False + + # make a check value list from the registry entry: replace the + # '<local>' string by the localhost entry and the corresponding + # canonical entry. + proxyOverride = proxyOverride.split(';') + # now check if we match one of the registry values. + for test in proxyOverride: + if test == '<local>': + if '.' not in host: + return True + test = test.replace(".", r"\.") # mask dots + test = test.replace("*", r".*") # change glob sequence + test = test.replace("?", r".") # change glob char + if re.match(test, host, re.I): + return True + return False + + def proxy_bypass(host): # noqa + """Return True, if the host should be bypassed. + + Checks proxy settings gathered from the environment, if specified, + or the registry. + """ + if getproxies_environment(): + return proxy_bypass_environment(host) + else: + return proxy_bypass_registry(host) + + +def dict_to_sequence(d): + """Returns an internal sequence dictionary update.""" + + if hasattr(d, 'items'): + d = d.items() + + return d + + +def super_len(o): + total_length = None + current_position = 0 + + if hasattr(o, '__len__'): + total_length = len(o) + + elif hasattr(o, 'len'): + total_length = o.len + + elif hasattr(o, 'fileno'): + try: + fileno = o.fileno() + except io.UnsupportedOperation: + pass + else: + total_length = os.fstat(fileno).st_size + + # Having used fstat to determine the file length, we need to + # confirm that this file was opened up in binary mode. + if 'b' not in o.mode: + warnings.warn(( + "Requests has determined the content-length for this " + "request using the binary size of the file: however, the " + "file has been opened in text mode (i.e. without the 'b' " + "flag in the mode). This may lead to an incorrect " + "content-length. In Requests 3.0, support will be removed " + "for files in text mode."), + FileModeWarning + ) + + if hasattr(o, 'tell'): + try: + current_position = o.tell() + except (OSError, IOError): + # This can happen in some weird situations, such as when the file + # is actually a special file descriptor like stdin. In this + # instance, we don't know what the length is, so set it to zero and + # let requests chunk it instead. + if total_length is not None: + current_position = total_length + else: + if hasattr(o, 'seek') and total_length is None: + # StringIO and BytesIO have seek but no useable fileno + try: + # seek to end of file + o.seek(0, 2) + total_length = o.tell() + + # seek back to current position to support + # partially read file-like objects + o.seek(current_position or 0) + except (OSError, IOError): + total_length = 0 + + if total_length is None: + total_length = 0 + + return max(0, total_length - current_position) + + +def get_netrc_auth(url, raise_errors=False): + """Returns the Requests tuple auth for a given url from netrc.""" + + try: + from netrc import netrc, NetrcParseError + + netrc_path = None + + for f in NETRC_FILES: + try: + loc = os.path.expanduser('~/{0}'.format(f)) + except KeyError: + # os.path.expanduser can fail when $HOME is undefined and + # getpwuid fails. See http://bugs.python.org/issue20164 & + # https://github.com/requests/requests/issues/1846 + return + + if os.path.exists(loc): + netrc_path = loc + break + + # Abort early if there isn't one. + if netrc_path is None: + return + + ri = urlparse(url) + + # Strip port numbers from netloc. This weird `if...encode`` dance is + # used for Python 3.2, which doesn't support unicode literals. + splitstr = b':' + if isinstance(url, str): + splitstr = splitstr.decode('ascii') + host = ri.netloc.split(splitstr)[0] + + try: + _netrc = netrc(netrc_path).authenticators(host) + if _netrc: + # Return with login / password + login_i = (0 if _netrc[0] else 1) + return (_netrc[login_i], _netrc[2]) + except (NetrcParseError, IOError): + # If there was a parsing error or a permissions issue reading the file, + # we'll just skip netrc auth unless explicitly asked to raise errors. + if raise_errors: + raise + + # AppEngine hackiness. + except (ImportError, AttributeError): + pass + + +def guess_filename(obj): + """Tries to guess the filename of the given object.""" + name = getattr(obj, 'name', None) + if (name and isinstance(name, basestring) and name[0] != '<' and + name[-1] != '>'): + return os.path.basename(name) + + +def extract_zipped_paths(path): + """Replace nonexistent paths that look like they refer to a member of a zip + archive with the location of an extracted copy of the target, or else + just return the provided path unchanged. + """ + if os.path.exists(path): + # this is already a valid path, no need to do anything further + return path + + # find the first valid part of the provided path and treat that as a zip archive + # assume the rest of the path is the name of a member in the archive + archive, member = os.path.split(path) + while archive and not os.path.exists(archive): + archive, prefix = os.path.split(archive) + member = '/'.join([prefix, member]) + + if not zipfile.is_zipfile(archive): + return path + + zip_file = zipfile.ZipFile(archive) + if member not in zip_file.namelist(): + return path + + # we have a valid zip archive and a valid member of that archive + tmp = tempfile.gettempdir() + extracted_path = os.path.join(tmp, *member.split('/')) + if not os.path.exists(extracted_path): + extracted_path = zip_file.extract(member, path=tmp) + + return extracted_path + + +def from_key_val_list(value): + """Take an object and test to see if it can be represented as a + dictionary. Unless it can not be represented as such, return an + OrderedDict, e.g., + + :: + + >>> from_key_val_list([('key', 'val')]) + OrderedDict([('key', 'val')]) + >>> from_key_val_list('string') + ValueError: need more than 1 value to unpack + >>> from_key_val_list({'key': 'val'}) + OrderedDict([('key', 'val')]) + + :rtype: OrderedDict + """ + if value is None: + return None + + if isinstance(value, (str, bytes, bool, int)): + raise ValueError('cannot encode objects that are not 2-tuples') + + return OrderedDict(value) + + +def to_key_val_list(value): + """Take an object and test to see if it can be represented as a + dictionary. If it can be, return a list of tuples, e.g., + + :: + + >>> to_key_val_list([('key', 'val')]) + [('key', 'val')] + >>> to_key_val_list({'key': 'val'}) + [('key', 'val')] + >>> to_key_val_list('string') + ValueError: cannot encode objects that are not 2-tuples. + + :rtype: list + """ + if value is None: + return None + + if isinstance(value, (str, bytes, bool, int)): + raise ValueError('cannot encode objects that are not 2-tuples') + + if isinstance(value, Mapping): + value = value.items() + + return list(value) + + +# From mitsuhiko/werkzeug (used with permission). +def parse_list_header(value): + """Parse lists as described by RFC 2068 Section 2. + + In particular, parse comma-separated lists where the elements of + the list may include quoted-strings. A quoted-string could + contain a comma. A non-quoted string could have quotes in the + middle. Quotes are removed automatically after parsing. + + It basically works like :func:`parse_set_header` just that items + may appear multiple times and case sensitivity is preserved. + + The return value is a standard :class:`list`: + + >>> parse_list_header('token, "quoted value"') + ['token', 'quoted value'] + + To create a header from the :class:`list` again, use the + :func:`dump_header` function. + + :param value: a string with a list header. + :return: :class:`list` + :rtype: list + """ + result = [] + for item in _parse_list_header(value): + if item[:1] == item[-1:] == '"': + item = unquote_header_value(item[1:-1]) + result.append(item) + return result + + +# From mitsuhiko/werkzeug (used with permission). +def parse_dict_header(value): + """Parse lists of key, value pairs as described by RFC 2068 Section 2 and + convert them into a python dict: + + >>> d = parse_dict_header('foo="is a fish", bar="as well"') + >>> type(d) is dict + True + >>> sorted(d.items()) + [('bar', 'as well'), ('foo', 'is a fish')] + + If there is no value for a key it will be `None`: + + >>> parse_dict_header('key_without_value') + {'key_without_value': None} + + To create a header from the :class:`dict` again, use the + :func:`dump_header` function. + + :param value: a string with a dict header. + :return: :class:`dict` + :rtype: dict + """ + result = {} + for item in _parse_list_header(value): + if '=' not in item: + result[item] = None + continue + name, value = item.split('=', 1) + if value[:1] == value[-1:] == '"': + value = unquote_header_value(value[1:-1]) + result[name] = value + return result + + +# From mitsuhiko/werkzeug (used with permission). +def unquote_header_value(value, is_filename=False): + r"""Unquotes a header value. (Reversal of :func:`quote_header_value`). + This does not use the real unquoting but what browsers are actually + using for quoting. + + :param value: the header value to unquote. + :rtype: str + """ + if value and value[0] == value[-1] == '"': + # this is not the real unquoting, but fixing this so that the + # RFC is met will result in bugs with internet explorer and + # probably some other browsers as well. IE for example is + # uploading files with "C:\foo\bar.txt" as filename + value = value[1:-1] + + # if this is a filename and the starting characters look like + # a UNC path, then just return the value without quotes. Using the + # replace sequence below on a UNC path has the effect of turning + # the leading double slash into a single slash and then + # _fix_ie_filename() doesn't work correctly. See #458. + if not is_filename or value[:2] != '\\\\': + return value.replace('\\\\', '\\').replace('\\"', '"') + return value + + +def dict_from_cookiejar(cj): + """Returns a key/value dictionary from a CookieJar. + + :param cj: CookieJar object to extract cookies from. + :rtype: dict + """ + + cookie_dict = {} + + for cookie in cj: + cookie_dict[cookie.name] = cookie.value + + return cookie_dict + + +def add_dict_to_cookiejar(cj, cookie_dict): + """Returns a CookieJar from a key/value dictionary. + + :param cj: CookieJar to insert cookies into. + :param cookie_dict: Dict of key/values to insert into CookieJar. + :rtype: CookieJar + """ + + return cookiejar_from_dict(cookie_dict, cj) + + +def get_encodings_from_content(content): + """Returns encodings from given content string. + + :param content: bytestring to extract encodings from. + """ + warnings.warn(( + 'In requests 3.0, get_encodings_from_content will be removed. For ' + 'more information, please see the discussion on issue #2266. (This' + ' warning should only appear once.)'), + DeprecationWarning) + + charset_re = re.compile(r'<meta.*?charset=["\']*(.+?)["\'>]', flags=re.I) + pragma_re = re.compile(r'<meta.*?content=["\']*;?charset=(.+?)["\'>]', flags=re.I) + xml_re = re.compile(r'^<\?xml.*?encoding=["\']*(.+?)["\'>]') + + return (charset_re.findall(content) + + pragma_re.findall(content) + + xml_re.findall(content)) + + +def _parse_content_type_header(header): + """Returns content type and parameters from given header + + :param header: string + :return: tuple containing content type and dictionary of + parameters + """ + + tokens = header.split(';') + content_type, params = tokens[0].strip(), tokens[1:] + params_dict = {} + items_to_strip = "\"' " + + for param in params: + param = param.strip() + if param: + key, value = param, True + index_of_equals = param.find("=") + if index_of_equals != -1: + key = param[:index_of_equals].strip(items_to_strip) + value = param[index_of_equals + 1:].strip(items_to_strip) + params_dict[key] = value + return content_type, params_dict + + +def get_encoding_from_headers(headers): + """Returns encodings from given HTTP Header Dict. + + :param headers: dictionary to extract encoding from. + :rtype: str + """ + + content_type = headers.get('content-type') + + if not content_type: + return None + + content_type, params = _parse_content_type_header(content_type) + + if 'charset' in params: + return params['charset'].strip("'\"") + + if 'text' in content_type: + return 'ISO-8859-1' + + +def stream_decode_response_unicode(iterator, r): + """Stream decodes a iterator.""" + + if r.encoding is None: + for item in iterator: + yield item + return + + decoder = codecs.getincrementaldecoder(r.encoding)(errors='replace') + for chunk in iterator: + rv = decoder.decode(chunk) + if rv: + yield rv + rv = decoder.decode(b'', final=True) + if rv: + yield rv + + +def iter_slices(string, slice_length): + """Iterate over slices of a string.""" + pos = 0 + if slice_length is None or slice_length <= 0: + slice_length = len(string) + while pos < len(string): + yield string[pos:pos + slice_length] + pos += slice_length + + +def get_unicode_from_response(r): + """Returns the requested content back in unicode. + + :param r: Response object to get unicode content from. + + Tried: + + 1. charset from content-type + 2. fall back and replace all unicode characters + + :rtype: str + """ + warnings.warn(( + 'In requests 3.0, get_unicode_from_response will be removed. For ' + 'more information, please see the discussion on issue #2266. (This' + ' warning should only appear once.)'), + DeprecationWarning) + + tried_encodings = [] + + # Try charset from content-type + encoding = get_encoding_from_headers(r.headers) + + if encoding: + try: + return str(r.content, encoding) + except UnicodeError: + tried_encodings.append(encoding) + + # Fall back: + try: + return str(r.content, encoding, errors='replace') + except TypeError: + return r.content + + +# The unreserved URI characters (RFC 3986) +UNRESERVED_SET = frozenset( + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789-._~") + + +def unquote_unreserved(uri): + """Un-escape any percent-escape sequences in a URI that are unreserved + characters. This leaves all reserved, illegal and non-ASCII bytes encoded. + + :rtype: str + """ + parts = uri.split('%') + for i in range(1, len(parts)): + h = parts[i][0:2] + if len(h) == 2 and h.isalnum(): + try: + c = chr(int(h, 16)) + except ValueError: + raise InvalidURL("Invalid percent-escape sequence: '%s'" % h) + + if c in UNRESERVED_SET: + parts[i] = c + parts[i][2:] + else: + parts[i] = '%' + parts[i] + else: + parts[i] = '%' + parts[i] + return ''.join(parts) + + +def requote_uri(uri): + """Re-quote the given URI. + + This function passes the given URI through an unquote/quote cycle to + ensure that it is fully and consistently quoted. + + :rtype: str + """ + safe_with_percent = "!#$%&'()*+,/:;=?@[]~" + safe_without_percent = "!#$&'()*+,/:;=?@[]~" + try: + # Unquote only the unreserved characters + # Then quote only illegal characters (do not quote reserved, + # unreserved, or '%') + return quote(unquote_unreserved(uri), safe=safe_with_percent) + except InvalidURL: + # We couldn't unquote the given URI, so let's try quoting it, but + # there may be unquoted '%'s in the URI. We need to make sure they're + # properly quoted so they do not cause issues elsewhere. + return quote(uri, safe=safe_without_percent) + + +def address_in_network(ip, net): + """This function allows you to check if an IP belongs to a network subnet + + Example: returns True if ip = 192.168.1.1 and net = 192.168.1.0/24 + returns False if ip = 192.168.1.1 and net = 192.168.100.0/24 + + :rtype: bool + """ + ipaddr = struct.unpack('=L', socket.inet_aton(ip))[0] + netaddr, bits = net.split('/') + netmask = struct.unpack('=L', socket.inet_aton(dotted_netmask(int(bits))))[0] + network = struct.unpack('=L', socket.inet_aton(netaddr))[0] & netmask + return (ipaddr & netmask) == (network & netmask) + + +def dotted_netmask(mask): + """Converts mask from /xx format to xxx.xxx.xxx.xxx + + Example: if mask is 24 function returns 255.255.255.0 + + :rtype: str + """ + bits = 0xffffffff ^ (1 << 32 - mask) - 1 + return socket.inet_ntoa(struct.pack('>I', bits)) + + +def is_ipv4_address(string_ip): + """ + :rtype: bool + """ + try: + socket.inet_aton(string_ip) + except socket.error: + return False + return True + + +def is_valid_cidr(string_network): + """ + Very simple check of the cidr format in no_proxy variable. + + :rtype: bool + """ + if string_network.count('/') == 1: + try: + mask = int(string_network.split('/')[1]) + except ValueError: + return False + + if mask < 1 or mask > 32: + return False + + try: + socket.inet_aton(string_network.split('/')[0]) + except socket.error: + return False + else: + return False + return True + + +@contextlib.contextmanager +def set_environ(env_name, value): + """Set the environment variable 'env_name' to 'value' + + Save previous value, yield, and then restore the previous value stored in + the environment variable 'env_name'. + + If 'value' is None, do nothing""" + value_changed = value is not None + if value_changed: + old_value = os.environ.get(env_name) + os.environ[env_name] = value + try: + yield + finally: + if value_changed: + if old_value is None: + del os.environ[env_name] + else: + os.environ[env_name] = old_value + + +def should_bypass_proxies(url, no_proxy): + """ + Returns whether we should bypass proxies or not. + + :rtype: bool + """ + # Prioritize lowercase environment variables over uppercase + # to keep a consistent behaviour with other http projects (curl, wget). + get_proxy = lambda k: os.environ.get(k) or os.environ.get(k.upper()) + + # First check whether no_proxy is defined. If it is, check that the URL + # we're getting isn't in the no_proxy list. + no_proxy_arg = no_proxy + if no_proxy is None: + no_proxy = get_proxy('no_proxy') + parsed = urlparse(url) + + if no_proxy: + # We need to check whether we match here. We need to see if we match + # the end of the hostname, both with and without the port. + no_proxy = ( + host for host in no_proxy.replace(' ', '').split(',') if host + ) + + if is_ipv4_address(parsed.hostname): + for proxy_ip in no_proxy: + if is_valid_cidr(proxy_ip): + if address_in_network(parsed.hostname, proxy_ip): + return True + elif parsed.hostname == proxy_ip: + # If no_proxy ip was defined in plain IP notation instead of cidr notation & + # matches the IP of the index + return True + else: + host_with_port = parsed.hostname + if parsed.port: + host_with_port += ':{0}'.format(parsed.port) + + for host in no_proxy: + if parsed.hostname.endswith(host) or host_with_port.endswith(host): + # The URL does match something in no_proxy, so we don't want + # to apply the proxies on this URL. + return True + + # If the system proxy settings indicate that this URL should be bypassed, + # don't proxy. + # The proxy_bypass function is incredibly buggy on OS X in early versions + # of Python 2.6, so allow this call to fail. Only catch the specific + # exceptions we've seen, though: this call failing in other ways can reveal + # legitimate problems. + with set_environ('no_proxy', no_proxy_arg): + try: + bypass = proxy_bypass(parsed.hostname) + except (TypeError, socket.gaierror): + bypass = False + + if bypass: + return True + + return False + + +def get_environ_proxies(url, no_proxy=None): + """ + Return a dict of environment proxies. + + :rtype: dict + """ + if should_bypass_proxies(url, no_proxy=no_proxy): + return {} + else: + return getproxies() + + +def select_proxy(url, proxies): + """Select a proxy for the url, if applicable. + + :param url: The url being for the request + :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs + """ + proxies = proxies or {} + urlparts = urlparse(url) + if urlparts.hostname is None: + return proxies.get(urlparts.scheme, proxies.get('all')) + + proxy_keys = [ + urlparts.scheme + '://' + urlparts.hostname, + urlparts.scheme, + 'all://' + urlparts.hostname, + 'all', + ] + proxy = None + for proxy_key in proxy_keys: + if proxy_key in proxies: + proxy = proxies[proxy_key] + break + + return proxy + + +def default_user_agent(name="python-requests"): + """ + Return a string representing the default user agent. + + :rtype: str + """ + return '%s/%s' % (name, __version__) + + +def default_headers(): + """ + :rtype: requests.structures.CaseInsensitiveDict + """ + return CaseInsensitiveDict({ + 'User-Agent': default_user_agent(), + 'Accept-Encoding': ', '.join(('gzip', 'deflate')), + 'Accept': '*/*', + 'Connection': 'keep-alive', + }) + + +def parse_header_links(value): + """Return a list of parsed link headers proxies. + + i.e. Link: <http:/.../front.jpeg>; rel=front; type="image/jpeg",<http://.../back.jpeg>; rel=back;type="image/jpeg" + + :rtype: list + """ + + links = [] + + replace_chars = ' \'"' + + value = value.strip(replace_chars) + if not value: + return links + + for val in re.split(', *<', value): + try: + url, params = val.split(';', 1) + except ValueError: + url, params = val, '' + + link = {'url': url.strip('<> \'"')} + + for param in params.split(';'): + try: + key, value = param.split('=') + except ValueError: + break + + link[key.strip(replace_chars)] = value.strip(replace_chars) + + links.append(link) + + return links + + +# Null bytes; no need to recreate these on each call to guess_json_utf +_null = '\x00'.encode('ascii') # encoding to ASCII for Python 3 +_null2 = _null * 2 +_null3 = _null * 3 + + +def guess_json_utf(data): + """ + :rtype: str + """ + # JSON always starts with two ASCII characters, so detection is as + # easy as counting the nulls and from their location and count + # determine the encoding. Also detect a BOM, if present. + sample = data[:4] + if sample in (codecs.BOM_UTF32_LE, codecs.BOM_UTF32_BE): + return 'utf-32' # BOM included + if sample[:3] == codecs.BOM_UTF8: + return 'utf-8-sig' # BOM included, MS style (discouraged) + if sample[:2] in (codecs.BOM_UTF16_LE, codecs.BOM_UTF16_BE): + return 'utf-16' # BOM included + nullcount = sample.count(_null) + if nullcount == 0: + return 'utf-8' + if nullcount == 2: + if sample[::2] == _null2: # 1st and 3rd are null + return 'utf-16-be' + if sample[1::2] == _null2: # 2nd and 4th are null + return 'utf-16-le' + # Did not detect 2 valid UTF-16 ascii-range characters + if nullcount == 3: + if sample[:3] == _null3: + return 'utf-32-be' + if sample[1:] == _null3: + return 'utf-32-le' + # Did not detect a valid UTF-32 ascii-range character + return None + + +def prepend_scheme_if_needed(url, new_scheme): + """Given a URL that may or may not have a scheme, prepend the given scheme. + Does not replace a present scheme with the one provided as an argument. + + :rtype: str + """ + scheme, netloc, path, params, query, fragment = urlparse(url, new_scheme) + + # urlparse is a finicky beast, and sometimes decides that there isn't a + # netloc present. Assume that it's being over-cautious, and switch netloc + # and path if urlparse decided there was no netloc. + if not netloc: + netloc, path = path, netloc + + return urlunparse((scheme, netloc, path, params, query, fragment)) + + +def get_auth_from_url(url): + """Given a url with authentication components, extract them into a tuple of + username,password. + + :rtype: (str,str) + """ + parsed = urlparse(url) + + try: + auth = (unquote(parsed.username), unquote(parsed.password)) + except (AttributeError, TypeError): + auth = ('', '') + + return auth + + +# Moved outside of function to avoid recompile every call +_CLEAN_HEADER_REGEX_BYTE = re.compile(b'^\\S[^\\r\\n]*$|^$') +_CLEAN_HEADER_REGEX_STR = re.compile(r'^\S[^\r\n]*$|^$') + + +def check_header_validity(header): + """Verifies that header value is a string which doesn't contain + leading whitespace or return characters. This prevents unintended + header injection. + + :param header: tuple, in the format (name, value). + """ + name, value = header + + if isinstance(value, bytes): + pat = _CLEAN_HEADER_REGEX_BYTE + else: + pat = _CLEAN_HEADER_REGEX_STR + try: + if not pat.match(value): + raise InvalidHeader("Invalid return character or leading space in header: %s" % name) + except TypeError: + raise InvalidHeader("Value for header {%s: %s} must be of type str or " + "bytes, not %s" % (name, value, type(value))) + + +def urldefragauth(url): + """ + Given a url remove the fragment and the authentication part. + + :rtype: str + """ + scheme, netloc, path, params, query, fragment = urlparse(url) + + # see func:`prepend_scheme_if_needed` + if not netloc: + netloc, path = path, netloc + + netloc = netloc.rsplit('@', 1)[-1] + + return urlunparse((scheme, netloc, path, params, query, '')) + + +def rewind_body(prepared_request): + """Move file pointer back to its recorded starting position + so it can be read again on redirect. + """ + body_seek = getattr(prepared_request.body, 'seek', None) + if body_seek is not None and isinstance(prepared_request._body_position, integer_types): + try: + body_seek(prepared_request._body_position) + except (IOError, OSError): + raise UnrewindableBodyError("An error occurred when rewinding request " + "body for redirect.") + else: + raise UnrewindableBodyError("Unable to rewind request body for redirect.") diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/retrying.py b/venv/lib/python3.7/site-packages/pip/_vendor/retrying.py new file mode 100644 index 0000000..6d1e627 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/retrying.py @@ -0,0 +1,267 @@ +## Copyright 2013-2014 Ray Holder +## +## 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. + +import random +from pip._vendor import six +import sys +import time +import traceback + + +# sys.maxint / 2, since Python 3.2 doesn't have a sys.maxint... +MAX_WAIT = 1073741823 + + +def retry(*dargs, **dkw): + """ + Decorator function that instantiates the Retrying object + @param *dargs: positional arguments passed to Retrying object + @param **dkw: keyword arguments passed to the Retrying object + """ + # support both @retry and @retry() as valid syntax + if len(dargs) == 1 and callable(dargs[0]): + def wrap_simple(f): + + @six.wraps(f) + def wrapped_f(*args, **kw): + return Retrying().call(f, *args, **kw) + + return wrapped_f + + return wrap_simple(dargs[0]) + + else: + def wrap(f): + + @six.wraps(f) + def wrapped_f(*args, **kw): + return Retrying(*dargs, **dkw).call(f, *args, **kw) + + return wrapped_f + + return wrap + + +class Retrying(object): + + def __init__(self, + stop=None, wait=None, + stop_max_attempt_number=None, + stop_max_delay=None, + wait_fixed=None, + wait_random_min=None, wait_random_max=None, + wait_incrementing_start=None, wait_incrementing_increment=None, + wait_exponential_multiplier=None, wait_exponential_max=None, + retry_on_exception=None, + retry_on_result=None, + wrap_exception=False, + stop_func=None, + wait_func=None, + wait_jitter_max=None): + + self._stop_max_attempt_number = 5 if stop_max_attempt_number is None else stop_max_attempt_number + self._stop_max_delay = 100 if stop_max_delay is None else stop_max_delay + self._wait_fixed = 1000 if wait_fixed is None else wait_fixed + self._wait_random_min = 0 if wait_random_min is None else wait_random_min + self._wait_random_max = 1000 if wait_random_max is None else wait_random_max + self._wait_incrementing_start = 0 if wait_incrementing_start is None else wait_incrementing_start + self._wait_incrementing_increment = 100 if wait_incrementing_increment is None else wait_incrementing_increment + self._wait_exponential_multiplier = 1 if wait_exponential_multiplier is None else wait_exponential_multiplier + self._wait_exponential_max = MAX_WAIT if wait_exponential_max is None else wait_exponential_max + self._wait_jitter_max = 0 if wait_jitter_max is None else wait_jitter_max + + # TODO add chaining of stop behaviors + # stop behavior + stop_funcs = [] + if stop_max_attempt_number is not None: + stop_funcs.append(self.stop_after_attempt) + + if stop_max_delay is not None: + stop_funcs.append(self.stop_after_delay) + + if stop_func is not None: + self.stop = stop_func + + elif stop is None: + self.stop = lambda attempts, delay: any(f(attempts, delay) for f in stop_funcs) + + else: + self.stop = getattr(self, stop) + + # TODO add chaining of wait behaviors + # wait behavior + wait_funcs = [lambda *args, **kwargs: 0] + if wait_fixed is not None: + wait_funcs.append(self.fixed_sleep) + + if wait_random_min is not None or wait_random_max is not None: + wait_funcs.append(self.random_sleep) + + if wait_incrementing_start is not None or wait_incrementing_increment is not None: + wait_funcs.append(self.incrementing_sleep) + + if wait_exponential_multiplier is not None or wait_exponential_max is not None: + wait_funcs.append(self.exponential_sleep) + + if wait_func is not None: + self.wait = wait_func + + elif wait is None: + self.wait = lambda attempts, delay: max(f(attempts, delay) for f in wait_funcs) + + else: + self.wait = getattr(self, wait) + + # retry on exception filter + if retry_on_exception is None: + self._retry_on_exception = self.always_reject + else: + self._retry_on_exception = retry_on_exception + + # TODO simplify retrying by Exception types + # retry on result filter + if retry_on_result is None: + self._retry_on_result = self.never_reject + else: + self._retry_on_result = retry_on_result + + self._wrap_exception = wrap_exception + + def stop_after_attempt(self, previous_attempt_number, delay_since_first_attempt_ms): + """Stop after the previous attempt >= stop_max_attempt_number.""" + return previous_attempt_number >= self._stop_max_attempt_number + + def stop_after_delay(self, previous_attempt_number, delay_since_first_attempt_ms): + """Stop after the time from the first attempt >= stop_max_delay.""" + return delay_since_first_attempt_ms >= self._stop_max_delay + + def no_sleep(self, previous_attempt_number, delay_since_first_attempt_ms): + """Don't sleep at all before retrying.""" + return 0 + + def fixed_sleep(self, previous_attempt_number, delay_since_first_attempt_ms): + """Sleep a fixed amount of time between each retry.""" + return self._wait_fixed + + def random_sleep(self, previous_attempt_number, delay_since_first_attempt_ms): + """Sleep a random amount of time between wait_random_min and wait_random_max""" + return random.randint(self._wait_random_min, self._wait_random_max) + + def incrementing_sleep(self, previous_attempt_number, delay_since_first_attempt_ms): + """ + Sleep an incremental amount of time after each attempt, starting at + wait_incrementing_start and incrementing by wait_incrementing_increment + """ + result = self._wait_incrementing_start + (self._wait_incrementing_increment * (previous_attempt_number - 1)) + if result < 0: + result = 0 + return result + + def exponential_sleep(self, previous_attempt_number, delay_since_first_attempt_ms): + exp = 2 ** previous_attempt_number + result = self._wait_exponential_multiplier * exp + if result > self._wait_exponential_max: + result = self._wait_exponential_max + if result < 0: + result = 0 + return result + + def never_reject(self, result): + return False + + def always_reject(self, result): + return True + + def should_reject(self, attempt): + reject = False + if attempt.has_exception: + reject |= self._retry_on_exception(attempt.value[1]) + else: + reject |= self._retry_on_result(attempt.value) + + return reject + + def call(self, fn, *args, **kwargs): + start_time = int(round(time.time() * 1000)) + attempt_number = 1 + while True: + try: + attempt = Attempt(fn(*args, **kwargs), attempt_number, False) + except: + tb = sys.exc_info() + attempt = Attempt(tb, attempt_number, True) + + if not self.should_reject(attempt): + return attempt.get(self._wrap_exception) + + delay_since_first_attempt_ms = int(round(time.time() * 1000)) - start_time + if self.stop(attempt_number, delay_since_first_attempt_ms): + if not self._wrap_exception and attempt.has_exception: + # get() on an attempt with an exception should cause it to be raised, but raise just in case + raise attempt.get() + else: + raise RetryError(attempt) + else: + sleep = self.wait(attempt_number, delay_since_first_attempt_ms) + if self._wait_jitter_max: + jitter = random.random() * self._wait_jitter_max + sleep = sleep + max(0, jitter) + time.sleep(sleep / 1000.0) + + attempt_number += 1 + + +class Attempt(object): + """ + An Attempt encapsulates a call to a target function that may end as a + normal return value from the function or an Exception depending on what + occurred during the execution. + """ + + def __init__(self, value, attempt_number, has_exception): + self.value = value + self.attempt_number = attempt_number + self.has_exception = has_exception + + def get(self, wrap_exception=False): + """ + Return the return value of this Attempt instance or raise an Exception. + If wrap_exception is true, this Attempt is wrapped inside of a + RetryError before being raised. + """ + if self.has_exception: + if wrap_exception: + raise RetryError(self) + else: + six.reraise(self.value[0], self.value[1], self.value[2]) + else: + return self.value + + def __repr__(self): + if self.has_exception: + return "Attempts: {0}, Error:\n{1}".format(self.attempt_number, "".join(traceback.format_tb(self.value[2]))) + else: + return "Attempts: {0}, Value: {1}".format(self.attempt_number, self.value) + + +class RetryError(Exception): + """ + A RetryError encapsulates the last Attempt instance right before giving up. + """ + + def __init__(self, last_attempt): + self.last_attempt = last_attempt + + def __str__(self): + return "RetryError[{0}]".format(self.last_attempt) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/six.py b/venv/lib/python3.7/site-packages/pip/_vendor/six.py new file mode 100644 index 0000000..6bf4fd3 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/six.py @@ -0,0 +1,891 @@ +# Copyright (c) 2010-2017 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 +# 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. + +"""Utilities for writing code that runs on Python 2 and 3""" + +from __future__ import absolute_import + +import functools +import itertools +import operator +import sys +import types + +__author__ = "Benjamin Peterson <benjamin@python.org>" +__version__ = "1.11.0" + + +# Useful for very coarse version differentiation. +PY2 = sys.version_info[0] == 2 +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, + text_type = str + binary_type = bytes + + MAXSIZE = sys.maxsize +else: + string_types = basestring, + integer_types = (int, long) + class_types = (type, types.ClassType) + text_type = unicode + binary_type = str + + if sys.platform.startswith("java"): + # Jython always uses 32 bits. + MAXSIZE = int((1 << 31) - 1) + 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: + # 32-bit + MAXSIZE = int((1 << 31) - 1) + else: + # 64-bit + MAXSIZE = int((1 << 63) - 1) + del X + + +def _add_doc(func, doc): + """Add documentation to a function.""" + func.__doc__ = doc + + +def _import_module(name): + """Import module, returning the module after the last dot.""" + __import__(name) + return sys.modules[name] + + +class _LazyDescr(object): + + def __init__(self, name): + self.name = name + + def __get__(self, obj, tp): + result = self._resolve() + setattr(obj, self.name, result) # Invokes __set__. + try: + # This is a bit ugly, but it avoids running this again by + # removing this descriptor. + delattr(obj.__class__, self.name) + except AttributeError: + pass + return result + + +class MovedModule(_LazyDescr): + + def __init__(self, name, old, new=None): + super(MovedModule, self).__init__(name) + if PY3: + if new is None: + new = name + self.mod = new + else: + self.mod = old + + def _resolve(self): + return _import_module(self.mod) + + def __getattr__(self, attr): + _module = self._resolve() + value = getattr(_module, attr) + setattr(self, attr, value) + return value + + +class _LazyModule(types.ModuleType): + + def __init__(self, name): + super(_LazyModule, self).__init__(name) + self.__doc__ = self.__class__.__doc__ + + def __dir__(self): + attrs = ["__doc__", "__name__"] + attrs += [attr.name for attr in self._moved_attributes] + return attrs + + # Subclasses should override this + _moved_attributes = [] + + +class MovedAttribute(_LazyDescr): + + def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): + super(MovedAttribute, self).__init__(name) + if PY3: + if new_mod is None: + new_mod = name + self.mod = new_mod + if new_attr is None: + if old_attr is None: + new_attr = name + else: + new_attr = old_attr + self.attr = new_attr + else: + self.mod = old_mod + if old_attr is None: + old_attr = name + self.attr = old_attr + + def _resolve(self): + module = _import_module(self.mod) + return getattr(module, self.attr) + + +class _SixMetaPathImporter(object): + + """ + A meta path importer to import six.moves and its submodules. + + This class implements a PEP302 finder and loader. It should be compatible + with Python 2.5 and all existing versions of Python3 + """ + + def __init__(self, six_module_name): + self.name = six_module_name + self.known_modules = {} + + def _add_module(self, mod, *fullnames): + for fullname in fullnames: + self.known_modules[self.name + "." + fullname] = mod + + def _get_module(self, fullname): + return self.known_modules[self.name + "." + fullname] + + def find_module(self, fullname, path=None): + if fullname in self.known_modules: + return self + return None + + def __get_module(self, fullname): + try: + return self.known_modules[fullname] + except KeyError: + raise ImportError("This loader does not know module " + fullname) + + def load_module(self, fullname): + try: + # in case of a reload + return sys.modules[fullname] + except KeyError: + pass + mod = self.__get_module(fullname) + if isinstance(mod, MovedModule): + mod = mod._resolve() + else: + mod.__loader__ = self + sys.modules[fullname] = mod + return mod + + def is_package(self, fullname): + """ + Return true, if the named module is a package. + + We need this method to get correct spec objects with + Python 3.4 (see PEP451) + """ + return hasattr(self.__get_module(fullname), "__path__") + + def get_code(self, fullname): + """Return None + + 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("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("reduce", "__builtin__", "functools"), + MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), + MovedAttribute("StringIO", "StringIO", "io"), + MovedAttribute("UserDict", "UserDict", "collections"), + MovedAttribute("UserList", "UserList", "collections"), + 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"), + MovedModule("builtins", "__builtin__"), + MovedModule("configparser", "ConfigParser"), + MovedModule("copyreg", "copy_reg"), + MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), + MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"), + MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), + MovedModule("http_cookies", "Cookie", "http.cookies"), + MovedModule("html_entities", "htmlentitydefs", "html.entities"), + MovedModule("html_parser", "HTMLParser", "html.parser"), + MovedModule("http_client", "httplib", "http.client"), + 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"), + MovedModule("cPickle", "cPickle", "pickle"), + MovedModule("queue", "Queue"), + MovedModule("reprlib", "repr"), + MovedModule("socketserver", "SocketServer"), + MovedModule("_thread", "thread", "_thread"), + MovedModule("tkinter", "Tkinter"), + MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), + MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), + MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), + MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), + MovedModule("tkinter_tix", "Tix", "tkinter.tix"), + 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_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), + MovedModule("tkinter_font", "tkFont", "tkinter.font"), + MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), + 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"), + MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), + MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), + MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"), +] +# Add windows specific modules. +if sys.platform == "win32": + _moved_attributes += [ + MovedModule("winreg", "_winreg"), + ] + +for attr in _moved_attributes: + setattr(_MovedItems, attr.name, attr) + if isinstance(attr, MovedModule): + _importer._add_module(attr, "moves." + attr.name) +del attr + +_MovedItems._moved_attributes = _moved_attributes + +moves = _MovedItems(__name__ + ".moves") +_importer._add_module(moves, "moves") + + +class Module_six_moves_urllib_parse(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_parse""" + + +_urllib_parse_moved_attributes = [ + MovedAttribute("ParseResult", "urlparse", "urllib.parse"), + MovedAttribute("SplitResult", "urlparse", "urllib.parse"), + MovedAttribute("parse_qs", "urlparse", "urllib.parse"), + MovedAttribute("parse_qsl", "urlparse", "urllib.parse"), + MovedAttribute("urldefrag", "urlparse", "urllib.parse"), + MovedAttribute("urljoin", "urlparse", "urllib.parse"), + MovedAttribute("urlparse", "urlparse", "urllib.parse"), + MovedAttribute("urlsplit", "urlparse", "urllib.parse"), + MovedAttribute("urlunparse", "urlparse", "urllib.parse"), + MovedAttribute("urlunsplit", "urlparse", "urllib.parse"), + MovedAttribute("quote", "urllib", "urllib.parse"), + 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"), + MovedAttribute("uses_query", "urlparse", "urllib.parse"), + MovedAttribute("uses_relative", "urlparse", "urllib.parse"), +] +for attr in _urllib_parse_moved_attributes: + setattr(Module_six_moves_urllib_parse, attr.name, attr) +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") + + +class Module_six_moves_urllib_error(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_error""" + + +_urllib_error_moved_attributes = [ + MovedAttribute("URLError", "urllib2", "urllib.error"), + MovedAttribute("HTTPError", "urllib2", "urllib.error"), + MovedAttribute("ContentTooShortError", "urllib", "urllib.error"), +] +for attr in _urllib_error_moved_attributes: + setattr(Module_six_moves_urllib_error, attr.name, attr) +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") + + +class Module_six_moves_urllib_request(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_request""" + + +_urllib_request_moved_attributes = [ + MovedAttribute("urlopen", "urllib2", "urllib.request"), + MovedAttribute("install_opener", "urllib2", "urllib.request"), + MovedAttribute("build_opener", "urllib2", "urllib.request"), + MovedAttribute("pathname2url", "urllib", "urllib.request"), + MovedAttribute("url2pathname", "urllib", "urllib.request"), + MovedAttribute("getproxies", "urllib", "urllib.request"), + MovedAttribute("Request", "urllib2", "urllib.request"), + MovedAttribute("OpenerDirector", "urllib2", "urllib.request"), + MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"), + MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), + MovedAttribute("BaseHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), + MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"), + MovedAttribute("FileHandler", "urllib2", "urllib.request"), + MovedAttribute("FTPHandler", "urllib2", "urllib.request"), + MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"), + MovedAttribute("UnknownHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"), + MovedAttribute("urlretrieve", "urllib", "urllib.request"), + MovedAttribute("urlcleanup", "urllib", "urllib.request"), + 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) +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") + + +class Module_six_moves_urllib_response(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_response""" + + +_urllib_response_moved_attributes = [ + MovedAttribute("addbase", "urllib", "urllib.response"), + MovedAttribute("addclosehook", "urllib", "urllib.response"), + MovedAttribute("addinfo", "urllib", "urllib.response"), + MovedAttribute("addinfourl", "urllib", "urllib.response"), +] +for attr in _urllib_response_moved_attributes: + setattr(Module_six_moves_urllib_response, attr.name, attr) +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") + + +class Module_six_moves_urllib_robotparser(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_robotparser""" + + +_urllib_robotparser_moved_attributes = [ + 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 + +_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") + request = _importer._get_module("moves.urllib_request") + response = _importer._get_module("moves.urllib_response") + robotparser = _importer._get_module("moves.urllib_robotparser") + + def __dir__(self): + return ['parse', 'error', 'request', 'response', 'robotparser'] + +_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"), + "moves.urllib") + + +def add_move(move): + """Add an item to six.moves.""" + setattr(_MovedItems, move.name, move) + + +def remove_move(name): + """Remove item from six.moves.""" + try: + delattr(_MovedItems, name) + except AttributeError: + try: + del moves.__dict__[name] + except KeyError: + raise AttributeError("no such move, %r" % (name,)) + + +if PY3: + _meth_func = "__func__" + _meth_self = "__self__" + + _func_closure = "__closure__" + _func_code = "__code__" + _func_defaults = "__defaults__" + _func_globals = "__globals__" +else: + _meth_func = "im_func" + _meth_self = "im_self" + + _func_closure = "func_closure" + _func_code = "func_code" + _func_defaults = "func_defaults" + _func_globals = "func_globals" + + +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 + + create_bound_method = types.MethodType + + def create_unbound_method(func, cls): + return func + + Iterator = object +else: + def get_unbound_function(unbound): + return unbound.im_func + + def create_bound_method(func, obj): + return types.MethodType(func, obj, obj.__class__) + + def create_unbound_method(func, cls): + 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""") + + +get_method_function = operator.attrgetter(_meth_func) +get_method_self = operator.attrgetter(_meth_self) +get_function_closure = operator.attrgetter(_func_closure) +get_function_code = operator.attrgetter(_func_code) +get_function_defaults = operator.attrgetter(_func_defaults) +get_function_globals = operator.attrgetter(_func_globals) + + +if PY3: + def iterkeys(d, **kw): + return iter(d.keys(**kw)) + + def itervalues(d, **kw): + return iter(d.values(**kw)) + + def iteritems(d, **kw): + return iter(d.items(**kw)) + + def iterlists(d, **kw): + return iter(d.lists(**kw)) + + viewkeys = operator.methodcaller("keys") + + viewvalues = operator.methodcaller("values") + + viewitems = operator.methodcaller("items") +else: + def iterkeys(d, **kw): + return d.iterkeys(**kw) + + def itervalues(d, **kw): + return d.itervalues(**kw) + + def iteritems(d, **kw): + return d.iteritems(**kw) + + def iterlists(d, **kw): + return d.iterlists(**kw) + + viewkeys = operator.methodcaller("viewkeys") + + viewvalues = operator.methodcaller("viewvalues") + + viewitems = operator.methodcaller("viewitems") + +_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.") + + +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 + _assertCountEqual = "assertCountEqual" + if sys.version_info[1] <= 1: + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" + else: + _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") + unichr = unichr + int2byte = chr + + def byte2int(bs): + return ord(bs[0]) + + def indexbytes(buf, i): + return ord(buf[i]) + iterbytes = functools.partial(itertools.imap, ord) + import StringIO + StringIO = BytesIO = StringIO.StringIO + _assertCountEqual = "assertItemsEqual" + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" +_add_doc(b, """Byte literal""") +_add_doc(u, """Text literal""") + + +def assertCountEqual(self, *args, **kwargs): + return getattr(self, _assertCountEqual)(*args, **kwargs) + + +def assertRaisesRegex(self, *args, **kwargs): + return getattr(self, _assertRaisesRegex)(*args, **kwargs) + + +def assertRegex(self, *args, **kwargs): + return getattr(self, _assertRegex)(*args, **kwargs) + + +if PY3: + exec_ = getattr(moves.builtins, "exec") + + def reraise(tp, value, tb=None): + 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: + frame = sys._getframe(1) + _globs_ = frame.f_globals + if _locs_ is None: + _locs_ = frame.f_locals + del frame + elif _locs_ is None: + _locs_ = _globs_ + exec("""exec _code_ in _globs_, _locs_""") + + 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): + 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): + 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) + if fp is None: + return + + def write(data): + 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): + 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: + if isinstance(sep, unicode): + want_unicode = True + elif not isinstance(sep, str): + raise TypeError("sep must be None or a string") + end = kwargs.pop("end", None) + if end is not None: + if isinstance(end, unicode): + want_unicode = True + elif not isinstance(end, str): + raise TypeError("end must be None or a string") + if kwargs: + raise TypeError("invalid keyword arguments to print()") + if not want_unicode: + for arg in args: + if isinstance(arg, unicode): + want_unicode = True + break + if want_unicode: + newline = unicode("\n") + space = unicode(" ") + else: + newline = "\n" + space = " " + if sep is None: + sep = space + if end is None: + end = newline + for i, arg in enumerate(args): + if i: + write(sep) + write(arg) + write(end) +if sys.version_info[:2] < (3, 3): + _print = print_ + + def print_(*args, **kwargs): + fp = kwargs.get("file", sys.stdout) + flush = kwargs.pop("flush", False) + _print(*args, **kwargs) + 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 wrapper(f): + f = functools.wraps(wrapped, assigned, updated)(f) + f.__wrapped__ = wrapped + return f + return wrapper +else: + wraps = functools.wraps + + +def with_metaclass(meta, *bases): + """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(type): + + def __new__(cls, name, this_bases, d): + return meta(name, bases, d) + + @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__') + 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) + return metaclass(cls.__name__, cls.__bases__, orig_vars) + return wrapper + + +def python_2_unicode_compatible(klass): + """ + A 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 + 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__) + klass.__unicode__ = klass.__str__ + klass.__str__ = lambda self: self.__unicode__().encode('utf-8') + return klass + + +# Complete the moves implementation. +# This code is at the end of this module to speed up module loading. +# Turn this module into a package. +__path__ = [] # required for PEP 302 and PEP 451 +__package__ = __name__ # see PEP 366 @ReservedAssignment +if globals().get("__spec__") is not None: + __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable +# Remove other six meta path importers, since they cause problems. This can +# happen if six is removed from sys.modules and then reloaded. (Setuptools does +# this for some reason.) +if sys.meta_path: + for i, importer in enumerate(sys.meta_path): + # Here's some real nastiness: Another "instance" of the six module might + # 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__): + del sys.meta_path[i] + break + del i, importer +# Finally, add the importer to the meta path import hook. +sys.meta_path.append(_importer) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__init__.py new file mode 100644 index 0000000..4bd533b --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__init__.py @@ -0,0 +1,97 @@ +""" +urllib3 - Thread-safe connection pooling and re-using. +""" + +from __future__ import absolute_import +import warnings + +from .connectionpool import ( + HTTPConnectionPool, + HTTPSConnectionPool, + connection_from_url +) + +from . import exceptions +from .filepost import encode_multipart_formdata +from .poolmanager import PoolManager, ProxyManager, proxy_from_url +from .response import HTTPResponse +from .util.request import make_headers +from .util.url import get_host +from .util.timeout import Timeout +from .util.retry import Retry + + +# Set default logging handler to avoid "No handler found" warnings. +import logging +try: # Python 2.7+ + from logging import NullHandler +except ImportError: + class NullHandler(logging.Handler): + def emit(self, record): + pass + +__author__ = 'Andrey Petrov (andrey.petrov@shazow.net)' +__license__ = 'MIT' +__version__ = '1.23' + +__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', +) + +logging.getLogger(__name__).addHandler(NullHandler()) + + +def add_stderr_logger(level=logging.DEBUG): + """ + Helper for quickly adding a StreamHandler to the logger. Useful for + debugging. + + Returns the handler after adding it. + """ + # This method needs to be in this __init__.py to get the __name__ correct + # 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')) + logger.addHandler(handler) + logger.setLevel(level) + logger.debug('Added a stderr logging handler to logger: %s', __name__) + return handler + + +# ... Clean up. +del NullHandler + + +# All warning filters *must* be appended unless you're really certain that they +# 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) +# SubjectAltNameWarning's should go off once per host +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) +# SNIMissingWarnings should go off only once. +warnings.simplefilter('default', exceptions.SNIMissingWarning, append=True) + + +def disable_warnings(category=exceptions.HTTPWarning): + """ + Helper for quickly disabling all urllib3 warnings. + """ + warnings.simplefilter('ignore', category) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f719c06b6a55159bd1608c440c72bf190ef20396 GIT binary patch literal 2431 zcmZ`)OLN;c5GE)}q8^rI*^Xl?Y1y<+tu~gDc=|{t)5)WG%_JUA>`Yp=9hMRxi8lB! zNZOIcIVICm`ycFM|4xs%_LRTSQ+Girc9SVM0CyK4u-N_f<K3B=vIgz<X7}gSil+UI z%Cwmv+=d?iN;HjXwnhonIq`K{Cn)E5&dyPT=DFeL?Yv*G3x3fq!kj@1-1JL!Ny$ZC z_A7Qp$tJJ*Gxm&MvupmWJ*#XbUiathIVG2Q!=Jb3m0aNq{-V98<SIYsFWE~<p5f>H zWqTQ9^kKzb8P!3m@fE*mH;MK_3oaWPyRcUle-RCzhZ>!w^*0)=vz6V8uXA?uM=j8Q z(CD1~5pCEX(|OyX3-%{$<@gf&^n@IL#+t9S6GAjtzuG5sk)C@)?8`qjS#I}py2MJm zYxF!_{v!t~(6R!S)(4g^KCpcG&QjXF0{b@U1=x3;=C-xg#qqc0RB-NfH>`DQXDFCU z*JHQOtX>!dte1FUU`1iby<lLu0ks5MPh(Kp<+qrz7Ll`VHx7B4Fvs(wP$ZjgA#qwO zCmWA;cDC-l+hz-Pk@INVe&2X{meUuZ?|?_JahbjBu?RhgL0e`)FQm-zQ=WK{D-x$4 z3ZJ@(3rAIO^QUg$4w#VDEfKyPO|@Et+Sz@p=)*G>N3b!2ovXgP$DASDoC!S19I(V0 zhH(ONamVvnn4*|}#u70Cp|Y8B{s@A>ndo5<rcDRoHuQJ_2Bz5r;Hx8i-)I0?47VZX zV5)};vEdtobq{)Mz(6%vL^l7_TDml1#{04$ST7V*G+<T@|Lk`n;T^aM>m0bE(+@ei z-SLN=-nGcNF}|^T^>Cw4$MM%22jcq6Wb9vsHV8U9oyd#Uy&z6p&ey;CraRnAy8|?; z?i{dyhN3e;L&tHvz)Kvb9gU>Hd@uP3om8Haas5mP+Bmt{GNkD^f$KBJk!8p6Lz;4w ztB$jux;&c^=cd;<y^vT$8^-10^aPVAeY|!jpn{F8Er@)0V68#SL2XA$y&VtTad_Ac zSkjWYr;m5W#<lkKjaE%yBt;&F5)Q~UqKZQuhglfpoJ*+_ClET}@NfXI5e2l@sTaFl zaQx5}0l+*K$VZ}v!we2US6UBqhAjsj&r$h%079Z2lSDruuLwxF6YZ6Lq#qj~=P5aX zhiFISxNrn3lvF%Y^$s?Z>hK*f+>s6l$c=w1ThJac9x-77(5?N{>+SK81%9hiw6+td zReu6QD+#S+$gJ!tZR>f=`YFc`)jpJU)4@Pht<nL>sR&~A$uI-5<@OUeYO=kTwAI4# z>gt*s0}J@96<e!ooE<QgN~QTMj-ldO@%YLeN*T3WD+{Ue1Kpf%4(?^H-LzKYR!J67 zg9Wk#we}>7{}RMc&iv<EvKq7G0hGC$fOE2RDwe^~$=#(1i=LokGOsQQe2`a;%0hOi zEKdA*A9PJP@&@!6^Q)E0#3Xf6hNnsd&dGwy58Y9`165yeqX;TQ7Afnyz(MaofM7tx zDG(sS5CoJ!YVn7arSsPRr89$@$|&d7l!>R{%aR}q-XI7C+XPZDr&ACbpj*!R9*59? ze`XITVGxSZ`<J``F8u;Mt6f8&-fGLD<Iu2|6>C2QJV3DuEN^iI23b4hWTgKyHKpoA z6GdEQ!tpEus#IknE4b9pX!uO+Va-TWOc+;{qFqfBkGBQePZ@lTrDdDS1Tj$MHd%qt z1O8Q2YnLY<0S{-jjEteELRKEDpU-_ELLrM&XaEtpX)+82+_U01-0Lym{7g9j+Jt`# zC=d#uM7TauoIo6kOEAd%_xJBUf2fck*3mG#&3dWulF^Hd9pvJ6+TDe}<Q<-D0`*PJ zOON3cSjo1yn?Moz(}}t5&Bsr@7=NHsQw9G<6Gi3bO#T$<BRxv<Rz|4bA?3t3VKDS6 pG4+K)6~MXxeexJ4(E-FYa^5fqJUOG@$kpccVnc7}0C2sL`xpMrn7aS~ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/_collections.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/_collections.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2e3b61132b1f6bb073f8d0aec6f445a6a5c4e3e6 GIT binary patch literal 10755 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/connection.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/connection.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..06e0e25b758cadff04015db2b51b56475efd1ade GIT binary patch literal 10276 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 Z;};86eLlDN`^uI1m*)LqHLsEK|37I~wz&WR literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..74579855a52f438f45673f2f14db2b21224ea8e5 GIT binary patch literal 23810 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/exceptions.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/exceptions.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2d545439053897647a623be12dc033fcd60c2cb0 GIT binary patch literal 10409 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 Ac>n+a literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/fields.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/fields.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..13539943dcdc7ab44fd2dad57316c86aeef8f564 GIT binary patch literal 5877 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 C9YH7n literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/filepost.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/filepost.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d634b1d5b4d3a9e5ac567f3f7493168ac664928e GIT binary patch literal 2769 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1bff42d8c9b80ac69b82018293a1d14cdb89a08b GIT binary patch literal 12708 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/request.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/request.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4e125aba2c53dc526ad3697ff6648dc9dd4a4362 GIT binary patch literal 5600 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 IR%(@h0uOF(v;Y7A literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/response.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/response.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6c33b4c19bba6a3e477cb4f48bc798bf1f39fb98 GIT binary patch literal 17426 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 Yggxy6jD^EG4Ula5rRm)Ci}~FD2JEdl3;+NC literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/_collections.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/_collections.py new file mode 100644 index 0000000..6e36b84 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/_collections.py @@ -0,0 +1,332 @@ +from __future__ import absolute_import +try: + from collections.abc import Mapping, MutableMapping +except ImportError: + from collections import Mapping, MutableMapping +try: + from threading import RLock +except ImportError: # Platform-specific: No threads available + class RLock: + def __enter__(self): + pass + + def __exit__(self, exc_type, exc_value, traceback): + pass + + +try: # Python 2.7+ + from collections import OrderedDict +except ImportError: + from .packages.ordered_dict import OrderedDict +from .exceptions import InvalidHeader +from .packages.six import iterkeys, itervalues, PY3 + + +__all__ = ['RecentlyUsedContainer', 'HTTPHeaderDict'] + + +_Null = object() + + +class RecentlyUsedContainer(MutableMapping): + """ + Provides a thread-safe dict-like container which maintains up to + ``maxsize`` keys while throwing away the least-recently-used keys beyond + ``maxsize``. + + :param maxsize: + Maximum number of recent elements to retain. + + :param dispose_func: + Every time an item is evicted from the container, + ``dispose_func(value)`` is called. Callback which will get called + """ + + ContainerCls = OrderedDict + + def __init__(self, maxsize=10, dispose_func=None): + self._maxsize = maxsize + self.dispose_func = dispose_func + + self._container = self.ContainerCls() + self.lock = RLock() + + def __getitem__(self, key): + # Re-insert the item, moving it to the end of the eviction line. + with self.lock: + item = self._container.pop(key) + self._container[key] = item + return item + + def __setitem__(self, key, value): + evicted_value = _Null + with self.lock: + # Possibly evict the existing value of 'key' + evicted_value = self._container.get(key, _Null) + self._container[key] = value + + # If we didn't evict an existing value, we might have to evict the + # least recently used item from the beginning of the container. + if len(self._container) > self._maxsize: + _key, evicted_value = self._container.popitem(last=False) + + if self.dispose_func and evicted_value is not _Null: + self.dispose_func(evicted_value) + + def __delitem__(self, key): + with self.lock: + value = self._container.pop(key) + + if self.dispose_func: + self.dispose_func(value) + + def __len__(self): + with self.lock: + return len(self._container) + + def __iter__(self): + raise NotImplementedError('Iteration over this class is unlikely to be threadsafe.') + + def clear(self): + with self.lock: + # Copy pointers to all values, then wipe the mapping + values = list(itervalues(self._container)) + self._container.clear() + + if self.dispose_func: + for value in values: + self.dispose_func(value) + + def keys(self): + with self.lock: + return list(iterkeys(self._container)) + + +class HTTPHeaderDict(MutableMapping): + """ + :param headers: + An iterable of field-value pairs. Must not contain multiple field names + when compared case-insensitively. + + :param kwargs: + Additional field-value pairs to pass in to ``dict.update``. + + A ``dict`` like container for storing HTTP Headers. + + Field names are stored and compared case-insensitively in compliance with + RFC 7230. Iteration provides the first case-sensitive key seen for each + case-insensitive pair. + + Using ``__setitem__`` syntax overwrites fields that compare equal + case-insensitively in order to maintain ``dict``'s api. For fields that + compare equal, instead create a new ``HTTPHeaderDict`` and use ``.add`` + in a loop. + + If multiple fields that are equal case-insensitively are passed to the + constructor or ``.update``, the behavior is undefined and some will be + lost. + + >>> headers = HTTPHeaderDict() + >>> headers.add('Set-Cookie', 'foo=bar') + >>> headers.add('set-cookie', 'baz=quxx') + >>> headers['content-length'] = '7' + >>> headers['SET-cookie'] + 'foo=bar, baz=quxx' + >>> headers['Content-Length'] + '7' + """ + + def __init__(self, headers=None, **kwargs): + super(HTTPHeaderDict, self).__init__() + self._container = OrderedDict() + if headers is not None: + if isinstance(headers, HTTPHeaderDict): + self._copy_from(headers) + else: + self.extend(headers) + if kwargs: + self.extend(kwargs) + + def __setitem__(self, key, val): + self._container[key.lower()] = [key, val] + return self._container[key.lower()] + + def __getitem__(self, key): + val = self._container[key.lower()] + return ', '.join(val[1:]) + + def __delitem__(self, key): + del self._container[key.lower()] + + def __contains__(self, key): + return key.lower() in self._container + + def __eq__(self, other): + 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())) + + def __ne__(self, other): + return not self.__eq__(other) + + if not PY3: # Python 2 + iterkeys = MutableMapping.iterkeys + itervalues = MutableMapping.itervalues + + __marker = object() + + def __len__(self): + return len(self._container) + + def __iter__(self): + # Only provide the originally cased names + for vals in self._container.values(): + yield vals[0] + + def pop(self, key, default=__marker): + '''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. + try: + value = self[key] + except KeyError: + if default is self.__marker: + raise + return default + else: + del self[key] + return value + + def discard(self, key): + try: + del self[key] + except KeyError: + pass + + def add(self, key, val): + """Adds a (name, value) pair, doesn't overwrite the value if it already + exists. + + >>> headers = HTTPHeaderDict(foo='bar') + >>> headers.add('Foo', 'baz') + >>> headers['foo'] + 'bar, baz' + """ + key_lower = key.lower() + new_vals = [key, val] + # Keep the common case aka no item present as fast as possible + vals = self._container.setdefault(key_lower, new_vals) + if new_vals is not vals: + vals.append(val) + + def extend(self, *args, **kwargs): + """Generic import function for any type of header-like object. + Adapted version of MutableMapping.update in order to insert items + 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))) + other = args[0] if len(args) >= 1 else () + + if isinstance(other, HTTPHeaderDict): + for key, val in other.iteritems(): + self.add(key, val) + elif isinstance(other, Mapping): + for key in other: + self.add(key, other[key]) + elif hasattr(other, "keys"): + for key in other.keys(): + self.add(key, other[key]) + else: + for key, value in other: + self.add(key, value) + + for key, value in kwargs.items(): + self.add(key, value) + + def getlist(self, key, default=__marker): + """Returns a list of all the values for the named field. Returns an + empty list if the key doesn't exist.""" + try: + vals = self._container[key.lower()] + except KeyError: + if default is self.__marker: + return [] + return default + else: + return vals[1:] + + # Backwards compatibility for httplib + getheaders = getlist + getallmatchingheaders = getlist + iget = getlist + + # Backwards compatibility for http.cookiejar + get_all = getlist + + def __repr__(self): + return "%s(%s)" % (type(self).__name__, dict(self.itermerged())) + + def _copy_from(self, other): + for key in other: + val = other.getlist(key) + if isinstance(val, list): + # Don't need to convert tuples + val = list(val) + self._container[key.lower()] = [key] + val + + def copy(self): + clone = type(self)() + clone._copy_from(self) + return clone + + def iteritems(self): + """Iterate over all header lines, including duplicate ones.""" + for key in self: + vals = self._container[key.lower()] + for val in vals[1:]: + yield vals[0], val + + def itermerged(self): + """Iterate over all headers, merging duplicate ones together.""" + for key in self: + val = self._container[key.lower()] + yield val[0], ', '.join(val[1:]) + + def items(self): + return list(self.iteritems()) + + @classmethod + def from_httplib(cls, message): # Python 2 + """Read headers from a Python 2 httplib message object.""" + # 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') + headers = [] + + for line in message.headers: + if line.startswith(obs_fold_continued_leaders): + if not headers: + # We received a header line that starts with OWS as described + # 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 + ) + else: + key, value = headers[-1] + headers[-1] = (key, value + ' ' + line.strip()) + continue + + key, value = line.split(':', 1) + headers.append((key, value.strip())) + + return cls(headers) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/connection.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/connection.py new file mode 100644 index 0000000..a03b573 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/connection.py @@ -0,0 +1,403 @@ +from __future__ import absolute_import +import datetime +import logging +import os +import sys +import socket +from socket import error as SocketError, timeout as SocketTimeout +import warnings +from .packages import six +from .packages.six.moves.http_client import HTTPConnection as _HTTPConnection +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 + + class BaseSSLError(BaseException): + pass + + +try: # Python 3: + # Not a no-op, we're adding this to the namespace so it can be imported. + ConnectionError = ConnectionError +except NameError: # Python 2: + class ConnectionError(Exception): + pass + + +from .exceptions import ( + NewConnectionError, + ConnectTimeoutError, + SubjectAltNameWarning, + SystemTimeWarning, +) +from .packages.ssl_match_hostname import match_hostname, CertificateError + +from .util.ssl_ import ( + resolve_cert_reqs, + resolve_ssl_version, + assert_fingerprint, + create_urllib3_context, + ssl_wrap_socket +) + + +from .util import connection + +from ._collections import HTTPHeaderDict + +log = logging.getLogger(__name__) + +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) + + +class DummyConnection(object): + """Used to detect a failed ConnectionCls import.""" + pass + + +class HTTPConnection(_HTTPConnection, object): + """ + Based on httplib.HTTPConnection but provides an extra constructor + backwards-compatibility layer between older and newer Pythons. + + Additional keyword parameters are used to configure attributes of the connection. + Accepted parameters include: + + - ``strict``: See the documentation on :class:`urllib3.connectionpool.HTTPConnectionPool` + - ``source_address``: Set the source address for the current connection. + + .. note:: This is ignored for Python 2.6. It is only applied for 2.7 and 3.x + + - ``socket_options``: Set specific options on the underlying socket. If not specified, then + defaults are loaded from ``HTTPConnection.default_socket_options`` which includes disabling + Nagle's algorithm (sets TCP_NODELAY to 1) unless the connection is behind a proxy. + + For example, if you wish to enable TCP Keep Alive in addition to the defaults, + you might pass:: + + HTTPConnection.default_socket_options + [ + (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1), + ] + + Or you may want to disable the defaults by passing an empty list (e.g., ``[]``). + """ + + default_port = port_by_scheme['http'] + + #: Disable Nagle's algorithm by default. + #: ``[(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)]`` + default_socket_options = [(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)] + + #: Whether this connection verifies the host's certificate. + is_verified = False + + def __init__(self, *args, **kw): + if six.PY3: # Python 3 + kw.pop('strict', None) + + # Pre-set source_address in case we have an older Python like 2.6. + self.source_address = kw.get('source_address') + + if sys.version_info < (2, 7): # Python 2.6 + # _HTTPConnection on Python 2.6 will balk at this keyword arg, but + # not newer versions. We can still use it when creating a + # connection though, so we pop it *after* we have saved it as + # self.source_address. + kw.pop('source_address', None) + + #: 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) + + # Superclass also sets self.source_address in Python 2.7+. + _HTTPConnection.__init__(self, *args, **kw) + + @property + def host(self): + """ + Getter method to remove any trailing dots that indicate the hostname is an FQDN. + + In general, SSL certificates don't include the trailing dot indicating a + fully-qualified domain name, and thus, they don't validate properly when + checked against a domain name that includes the dot. In addition, some + servers may not expect to receive the trailing dot when provided. + + However, the hostname with trailing dot is critical to DNS resolution; doing a + lookup with the trailing dot will properly only resolve the appropriate FQDN, + whereas a lookup without a trailing dot will search the system's search domain + list. Thus, it's important to keep the original host around for use only in + 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('.') + + @host.setter + def host(self, value): + """ + Setter for the `host` property. + + We assume that only urllib3 uses the _dns_host attribute; httplib itself + only uses `host`, and it seems reasonable that other libraries follow suit. + """ + self._dns_host = value + + def _new_conn(self): + """ Establish a socket connection and set nodelay settings on it. + + :return: New socket connection. + """ + extra_kw = {} + if self.source_address: + extra_kw['source_address'] = self.source_address + + if self.socket_options: + extra_kw['socket_options'] = self.socket_options + + try: + conn = connection.create_connection( + (self._dns_host, self.port), self.timeout, **extra_kw) + + except SocketTimeout as e: + raise ConnectTimeoutError( + 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) + + return conn + + def _prepare_conn(self, conn): + self.sock = conn + # the _tunnel_host attribute was added in python 2.6.3 (via + # http://hg.python.org/cpython/rev/0f57b30a152f) so pythons 2.6(0-2) do + # not have them. + 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 + self.auto_open = 0 + + def connect(self): + conn = self._new_conn() + self._prepare_conn(conn) + + 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 + self.putrequest( + 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') + self.endheaders() + + if body is not None: + stringish_types = six.string_types + (six.binary_type,) + if isinstance(body, stringish_types): + body = (body,) + for chunk in body: + if not chunk: + continue + if not isinstance(chunk, six.binary_type): + chunk = chunk.encode('utf8') + len_str = hex(len(chunk))[2:] + self.send(len_str.encode('utf-8')) + self.send(b'\r\n') + self.send(chunk) + self.send(b'\r\n') + + # After the if clause, to always have a closed body + self.send(b'0\r\n\r\n') + + +class HTTPSConnection(HTTPConnection): + default_port = port_by_scheme['https'] + + ssl_version = None + + def __init__(self, host, port=None, key_file=None, cert_file=None, + strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, + ssl_context=None, **kw): + + HTTPConnection.__init__(self, host, port, strict=strict, + timeout=timeout, **kw) + + self.key_file = key_file + self.cert_file = cert_file + self.ssl_context = ssl_context + + # Required property for Google AppEngine 1.9.0 which otherwise causes + # HTTPS requests to go out as HTTP. (See Issue #356) + self._protocol = 'https' + + def connect(self): + conn = self._new_conn() + self._prepare_conn(conn) + + if self.ssl_context is None: + self.ssl_context = create_urllib3_context( + ssl_version=resolve_ssl_version(None), + cert_reqs=resolve_cert_reqs(None), + ) + + self.sock = ssl_wrap_socket( + sock=conn, + keyfile=self.key_file, + certfile=self.cert_file, + ssl_context=self.ssl_context, + ) + + +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, ca_certs=None, + assert_hostname=None, assert_fingerprint=None, + ca_cert_dir=None): + """ + This method should only be called once, before the connection is used. + """ + # If cert_reqs is not provided, we can try to guess. If the user gave + # us a cert database, we assume they want to use it: otherwise, if + # they gave us an SSL Context object we should use whatever is set for + # it. + if cert_reqs is None: + if ca_certs or ca_cert_dir: + cert_reqs = 'CERT_REQUIRED' + elif self.ssl_context is not None: + cert_reqs = self.ssl_context.verify_mode + + self.key_file = key_file + self.cert_file = cert_file + self.cert_reqs = cert_reqs + self.assert_hostname = assert_hostname + 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) + + def connect(self): + # Add certificate verification + conn = self._new_conn() + + hostname = self.host + if getattr(self, '_tunnel_host', None): + # _tunnel_host was added in Python 2.6.3 + # (See: http://hg.python.org/cpython/rev/0f57b30a152f) + + self.sock = conn + # Calls self._set_hostport(), so self.host is + # self._tunnel_host below. + self._tunnel() + # Mark this connection as not reusable + self.auto_open = 0 + + # Override the host with the one we're requesting data from. + hostname = self._tunnel_host + + 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 + ) + + # Wrap socket using verification with the root certs in + # trusted_root_certs + if self.ssl_context is None: + self.ssl_context = create_urllib3_context( + ssl_version=resolve_ssl_version(self.ssl_version), + cert_reqs=resolve_cert_reqs(self.cert_reqs), + ) + + context = self.ssl_context + context.verify_mode = resolve_cert_reqs(self.cert_reqs) + self.sock = ssl_wrap_socket( + sock=conn, + keyfile=self.key_file, + certfile=self.cert_file, + ca_certs=self.ca_certs, + ca_cert_dir=self.ca_cert_dir, + server_hostname=hostname, + 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: + # 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 + ) + _match_hostname(cert, self.assert_hostname or hostname) + + self.is_verified = ( + context.verify_mode == ssl.CERT_REQUIRED or + self.assert_fingerprint is not None + ) + + +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 + ) + # Add cert to exception and reraise so client code can inspect + # the cert when catching the exception, if they want to + e._peer_cert = cert + raise + + +if ssl: + # Make a copy for testing. + UnverifiedHTTPSConnection = HTTPSConnection + HTTPSConnection = VerifiedHTTPSConnection +else: + HTTPSConnection = DummyConnection diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/connectionpool.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/connectionpool.py new file mode 100644 index 0000000..8fcb0bc --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/connectionpool.py @@ -0,0 +1,906 @@ +from __future__ import absolute_import +import errno +import logging +import sys +import warnings + +from socket import error as SocketError, timeout as SocketTimeout +import socket + + +from .exceptions import ( + ClosedPoolError, + ProtocolError, + EmptyPoolError, + HeaderParsingError, + HostChangedError, + LocationValueError, + MaxRetryError, + ProxyError, + ReadTimeoutError, + SSLError, + TimeoutError, + InsecureRequestWarning, + NewConnectionError, +) +from .packages.ssl_match_hostname import CertificateError +from .packages import six +from .packages.six.moves import queue +from .connection import ( + port_by_scheme, + DummyConnection, + HTTPConnection, HTTPSConnection, VerifiedHTTPSConnection, + HTTPException, BaseSSLError, +) +from .request import RequestMethods +from .response import HTTPResponse + +from .util.connection import is_connection_dropped +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.queue import LifoQueue + + +xrange = six.moves.xrange + +log = logging.getLogger(__name__) + +_Default = object() + + +# Pool objects +class ConnectionPool(object): + """ + Base class for all connection pools, such as + :class:`.HTTPConnectionPool` and :class:`.HTTPSConnectionPool`. + """ + + scheme = None + QueueCls = LifoQueue + + def __init__(self, host, port=None): + if not host: + raise LocationValueError("No host specified.") + + self.host = _ipv6_host(host, self.scheme) + self._proxy_host = host.lower() + self.port = port + + def __str__(self): + return '%s(host=%r, port=%r)' % (type(self).__name__, + self.host, self.port) + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.close() + # Return False to re-raise any potential exceptions + return False + + def close(self): + """ + Close all pooled connections and disable the pool. + """ + pass + + +# This is taken from http://hg.python.org/cpython/file/7aaba721ebc0/Lib/socket.py#l252 +_blocking_errnos = set([errno.EAGAIN, errno.EWOULDBLOCK]) + + +class HTTPConnectionPool(ConnectionPool, RequestMethods): + """ + Thread-safe connection pool for one host. + + :param host: + Host used for this HTTP Connection (e.g. "localhost"), passed into + :class:`httplib.HTTPConnection`. + + :param port: + Port used for this HTTP Connection (None is equivalent to 80), passed + into :class:`httplib.HTTPConnection`. + + :param strict: + Causes BadStatusLine to be raised if the status line can't be parsed + as a valid HTTP/1.0 or 1.1 status line, passed into + :class:`httplib.HTTPConnection`. + + .. note:: + Only works in Python 2. This parameter is ignored in Python 3. + + :param timeout: + Socket timeout in seconds for each individual connection. This can + be a float or integer, which sets the timeout for the HTTP request, + or an instance of :class:`urllib3.util.Timeout` which gives you more + fine-grained control over request timeouts. After the constructor has + been parsed, this is always a `urllib3.util.Timeout` object. + + :param maxsize: + Number of connections to save that can be reused. More than 1 is useful + in multithreaded situations. If ``block`` is set to False, more + connections will be created but they will not be saved once they've + been used. + + :param block: + If set to True, no more than ``maxsize`` connections will be used at + a time. When no free connections are available, the call will block + until a connection has been released. This is a useful side effect for + particular multithreaded situations where one does not want to use more + than maxsize connections per host to prevent flooding. + + :param headers: + Headers to include with all requests, unless other headers are given + explicitly. + + :param retries: + Retry configuration to use by default with requests in this pool. + + :param _proxy: + Parsed proxy URL, should not be used directly, instead, see + :class:`urllib3.connectionpool.ProxyManager`" + + :param _proxy_headers: + A dictionary with proxy headers, should not be used directly, + instead, see :class:`urllib3.connectionpool.ProxyManager`" + + :param \\**conn_kw: + Additional parameters are used to create fresh :class:`urllib3.connection.HTTPConnection`, + :class:`urllib3.connection.HTTPSConnection` instances. + """ + + 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): + ConnectionPool.__init__(self, host, port) + RequestMethods.__init__(self, headers) + + self.strict = strict + + if not isinstance(timeout, Timeout): + timeout = Timeout.from_float(timeout) + + if retries is None: + retries = Retry.DEFAULT + + self.timeout = timeout + self.retries = retries + + self.pool = self.QueueCls(maxsize) + self.block = block + + self.proxy = _proxy + self.proxy_headers = _proxy_headers or {} + + # Fill the queue up so that doing get() on it will block properly + for _ in xrange(maxsize): + self.pool.put(None) + + # These are mostly for testing and debugging purposes. + self.num_connections = 0 + self.num_requests = 0 + self.conn_kw = conn_kw + + if self.proxy: + # 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', []) + + 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") + + 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): + """ + Get a connection. Will return a pooled connection if one is available. + + If no connections are available and :prop:`.block` is ``False``, then a + fresh connection is returned. + + :param timeout: + Seconds to wait before giving up and raising + :class:`urllib3.exceptions.EmptyPoolError` if the pool is empty and + :prop:`.block` is ``True``. + """ + conn = None + try: + conn = self.pool.get(block=self.block, timeout=timeout) + + except AttributeError: # self.pool is None + raise ClosedPoolError(self, "Pool is closed.") + + except queue.Empty: + if self.block: + 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: + # This is a proxied connection that has been mutated by + # httplib._tunnel() and cannot be reused (since it would + # attempt to bypass the proxy) + conn = None + + return conn or self._new_conn() + + def _put_conn(self, conn): + """ + Put a connection back into the pool. + + :param conn: + Connection object for the current host and port as returned by + :meth:`._new_conn` or :meth:`._get_conn`. + + If the pool is already full, the connection is closed and discarded + because we exceeded maxsize. If connections are discarded frequently, + then maxsize should be increased. + + If the pool is closed, then the connection will be closed and discarded. + """ + try: + self.pool.put(conn, block=False) + return # Everything is dandy, done. + except AttributeError: + # self.pool is None. + pass + except queue.Full: + # This should never happen if self.block == True + log.warning( + "Connection pool is full, discarding connection: %s", + self.host) + + # Connection never got put back into the pool, close it. + if conn: + conn.close() + + def _validate_conn(self, conn): + """ + Called right before a request is made, after the socket is created. + """ + pass + + def _prepare_proxy(self, conn): + # Nothing to do for HTTP connections. + pass + + def _get_timeout(self, timeout): + """ Helper that always returns a :class:`urllib3.util.Timeout` """ + if timeout is _Default: + return self.timeout.clone() + + if isinstance(timeout, Timeout): + return timeout.clone() + else: + # User passed us an int/float. This is for backwards compatibility, + # can be removed later + return Timeout.from_float(timeout) + + def _raise_timeout(self, err, url, timeout_value): + """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) + + # 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) + + # 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.6 + 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): + """ + Perform a request on a given urllib connection object taken from our + pool. + + :param conn: + a connection from one of our connection pools + + :param timeout: + Socket timeout in seconds for the request. This can be a + float or integer, which will set the same timeout value for + the socket connect and the socket read, or an instance of + :class:`urllib3.util.Timeout`, which gives you more fine-grained + control over your timeouts. + """ + self.num_requests += 1 + + timeout_obj = self._get_timeout(timeout) + timeout_obj.start_connect() + conn.timeout = timeout_obj.connect_timeout + + # Trigger any extra validation we need to do. + try: + self._validate_conn(conn) + except (SocketTimeout, BaseSSLError) as e: + # Py2 raises this as a BaseSSLError, Py3 raises it as socket timeout. + self._raise_timeout(err=e, url=url, timeout_value=conn.timeout) + raise + + # conn.request() calls httplib.*.request, not the method in + # urllib3.request. It also calls makefile (recv) on the socket. + if chunked: + conn.request_chunked(method, url, **httplib_request_kw) + else: + conn.request(method, url, **httplib_request_kw) + + # Reset the timeout for the recv() on the socket + read_timeout = timeout_obj.read_timeout + + # App Engine doesn't have a sock attr + 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 + # the exception and assuming all BadStatusLine exceptions are read + # 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) + if read_timeout is Timeout.DEFAULT_TIMEOUT: + conn.sock.settimeout(socket.getdefaulttimeout()) + else: # None or a value + conn.sock.settimeout(read_timeout) + + # Receive the response from the server + try: + try: # Python 2.7, use buffering of HTTP responses + httplib_response = conn.getresponse(buffering=True) + except TypeError: # Python 2.6 and older, 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. + 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) + + 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) + + return httplib_response + + def _absolute_url(self, path): + return Url(scheme=self.scheme, host=self.host, port=self.port, path=path).url + + def close(self): + """ + Close all pooled connections and disable the pool. + """ + if self.pool is None: + return + # Disable access to the pool + old_pool, self.pool = self.pool, None + + try: + while True: + conn = old_pool.get(block=False) + if conn: + conn.close() + + except queue.Empty: + pass # Done. + + def is_same_host(self, url): + """ + Check if the given ``url`` is a member of the same host as this + connection pool. + """ + if url.startswith('/'): + return True + + # TODO: Add optional support for socket.gethostbyname checking. + scheme, host, port = get_host(url) + + host = _ipv6_host(host, self.scheme) + + # Use explicit default port for comparison when none is given + if self.port and not port: + port = port_by_scheme.get(scheme) + elif not self.port and port == port_by_scheme.get(scheme): + port = None + + 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): + """ + 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 + the raw details. + + .. note:: + + More commonly, it's appropriate to use a convenience method provided + by :class:`.RequestMethods`, such as :meth:`request`. + + .. note:: + + `release_conn` will only behave as expected if + `preload_content=False` because we want to make + `preload_content=False` the default behaviour someday soon without + breaking backwards compatibility. + + :param method: + HTTP request method (such as GET, POST, PUT, etc.) + + :param body: + Data to send in the request body (useful for creating + POST requests, see HTTPConnectionPool.post_url for + more convenience). + + :param headers: + Dictionary of custom headers to send, such as User-Agent, + If-None-Match, etc. If None, pool headers are used. If provided, + these headers completely replace any pool-specific headers. + + :param retries: + Configure the number of retries to allow before raising a + :class:`~urllib3.exceptions.MaxRetryError` exception. + + Pass ``None`` to retry until you receive a response. Pass a + :class:`~urllib3.util.retry.Retry` object for fine-grained control + over different types of retries. + Pass an integer number to retry connection errors that many times, + but no other types of errors. Pass zero to never retry. + + If ``False``, then retries are disabled and any exception is raised + immediately. Also, instead of raising a MaxRetryError on redirects, + the redirect response will be returned. + + :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. + + :param redirect: + If True, automatically handle redirects (status codes 301, 302, + 303, 307, 308). Each redirect counts as a retry. Disabling retries + will disable redirect, too. + + :param assert_same_host: + If ``True``, will make sure that the host of the pool requests is + consistent else will raise HostChangedError. When False, you can + use the pool on an HTTP proxy and request foreign hosts. + + :param timeout: + If specified, overrides the default timeout for this one + request. It may be a float (in seconds) or an instance of + :class:`urllib3.util.Timeout`. + + :param pool_timeout: + If set and the pool is set to block=True, then this method will + block for ``pool_timeout`` seconds and raise EmptyPoolError if no + connection is available within the time period. + + :param release_conn: + If False, then the urlopen call will not release the connection + back into the pool once a response is received (but will release if + you read the entire contents of the response such as when + `preload_content=True`). This is useful if you're not preloading + the response's content immediately. You will need to call + ``r.release_conn()`` on the response ``r`` to return the connection + back into the pool. If None, it takes the value of + ``response_kw.get('preload_content', True)``. + + :param chunked: + If True, urllib3 will send the body using chunked transfer + encoding. Otherwise, urllib3 will send the body using the standard + content-length form. Defaults to False. + + :param int body_pos: + Position to seek to in file-like body in the event of a retry or + redirect. Typically this won't need to be set because urllib3 will + auto-populate the value when needed. + + :param \\**response_kw: + Additional parameters are passed to + :meth:`urllib3.response.HTTPResponse.from_httplib` + """ + if headers is None: + headers = self.headers + + if not isinstance(retries, Retry): + retries = Retry.from_int(retries, redirect=redirect, default=self.retries) + + if release_conn is None: + 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) + + conn = None + + # Track whether `conn` needs to be released before + # returning/raising/recursing. Update this variable if necessary, and + # leave `release_conn` constant throughout the function. That way, if + # the function recurses, the original value of `release_conn` will be + # passed down into the recursive call, and its value will be respected. + # + # See issue #651 [1] for details. + # + # [1] <https://github.com/shazow/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': + headers = headers.copy() + headers.update(self.proxy_headers) + + # Must keep the exception bound to a separate variable or else Python 3 + # complains about UnboundLocalError. + err = None + + # Keep track of whether we cleanly exited the except block. This + # ensures we do proper cleanup in finally. + clean_exit = False + + # Rewind body position, if needed. Record current position + # for future rewinds in the event of a redirect/retry. + body_pos = set_file_position(body, body_pos) + + try: + # Request a connection from the queue. + timeout_obj = self._get_timeout(timeout) + conn = self._get_conn(timeout=pool_timeout) + + conn.timeout = timeout_obj.connect_timeout + + 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) + + # If we're going to release the connection in ``finally:``, then + # the response doesn't need to know about the connection. Otherwise + # it will also try to release it and we'll have a double-release + # mess. + response_conn = conn if not release_conn else None + + # Pass method to Response for length checking + 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) + + # Everything went great! + clean_exit = True + + except queue.Empty: + # Timed out by queue. + raise EmptyPoolError(self, "No pool connections are available.") + + 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) + elif isinstance(e, (SocketError, HTTPException)): + e = ProtocolError('Connection aborted.', e) + + 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. + err = e + + finally: + if not clean_exit: + # We hit some kind of exception, handled or otherwise. We need + # to throw the connection away unless explicitly told not to. + # Close the connection, set the variable to None, and make sure + # we put the None back in the pool to avoid leaking it. + conn = conn and conn.close() + release_this_conn = True + + if release_this_conn: + # Put the connection back to be reused. If the connection is + # expired then it will be None, which will get replaced with a + # fresh connection during _get_conn. + self._put_conn(conn) + + 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) as e: + pass + + # Handle redirect? + redirect_location = redirect and response.get_redirect_location() + if redirect_location: + if response.status == 303: + 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) + raise + return response + + # drain and return the connection to the pool before recursing + drain_and_release_conn(response) + + 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, + assert_same_host=assert_same_host, + timeout=timeout, pool_timeout=pool_timeout, + release_conn=release_conn, body_pos=body_pos, + **response_kw) + + # Check if we should retry the HTTP response. + 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) + raise + return response + + # drain and return the connection to the pool before recursing + drain_and_release_conn(response) + + retries.sleep(response) + log.debug("Retry: %s", url) + return self.urlopen( + method, url, 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) + + return response + + +class HTTPSConnectionPool(HTTPConnectionPool): + """ + Same as :class:`.HTTPConnectionPool`, but HTTPS. + + When Python is compiled with the :mod:`ssl` module, then + :class:`.VerifiedHTTPSConnection` is used, which *can* verify certificates, + instead of :class:`.HTTPSConnection`. + + :class:`.VerifiedHTTPSConnection` uses one of ``assert_fingerprint``, + ``assert_hostname`` and ``host`` in this order to verify connections. + If ``assert_hostname`` is False, no verification is done. + + The ``key_file``, ``cert_file``, ``cert_reqs``, ``ca_certs``, + ``ca_cert_dir``, and ``ssl_version`` are only used if :mod:`ssl` is + available and are fed into :meth:`urllib3.util.ssl_wrap_socket` to upgrade + the connection socket into an SSL socket. + """ + + 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, + 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) + + if ca_certs and cert_reqs is None: + cert_reqs = 'CERT_REQUIRED' + + self.key_file = key_file + self.cert_file = cert_file + self.cert_reqs = cert_reqs + self.ca_certs = ca_certs + self.ca_cert_dir = ca_cert_dir + self.ssl_version = ssl_version + self.assert_hostname = assert_hostname + self.assert_fingerprint = assert_fingerprint + + def _prepare_conn(self, conn): + """ + Prepare the ``connection`` for :meth:`urllib3.util.ssl_wrap_socket` + and establish the tunnel if proxy is used. + """ + + if isinstance(conn, VerifiedHTTPSConnection): + conn.set_cert(key_file=self.key_file, + 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 + + def _prepare_proxy(self, conn): + """ + Establish tunnel connection early, because otherwise httplib + would improperly set Host: header to proxy's IP:port. + """ + # Python 2.7+ + try: + set_tunnel = conn.set_tunnel + except AttributeError: # Platform-specific: Python 2.6 + set_tunnel = conn._set_tunnel + + if sys.version_info <= (2, 6, 4) and not self.proxy_headers: # Python 2.6.4 and older + set_tunnel(self._proxy_host, self.port) + else: + set_tunnel(self._proxy_host, self.port, self.proxy_headers) + + conn.connect() + + def _new_conn(self): + """ + 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") + + if not self.ConnectionCls or self.ConnectionCls is DummyConnection: + raise SSLError("Can't connect to HTTPS URL because the SSL " + "module is not available.") + + actual_host = self.host + actual_port = self.port + if self.proxy is not None: + 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, **self.conn_kw) + + return self._prepare_conn(conn) + + def _validate_conn(self, conn): + """ + Called right before a request is made, after the socket is created. + """ + 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` + 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) + + +def connection_from_url(url, **kw): + """ + Given a url, return an :class:`.ConnectionPool` instance of its host. + + This is a shortcut for not having to parse out the scheme, host, and port + of the url before creating an :class:`.ConnectionPool` instance. + + :param url: + Absolute URL string that must include the scheme. Port is optional. + + :param \\**kw: + Passes additional parameters to the constructor of the appropriate + :class:`.ConnectionPool`. Useful for specifying things like + timeout, maxsize, headers, etc. + + Example:: + + >>> conn = connection_from_url('http://google.com/') + >>> r = conn.request('GET', '/') + """ + scheme, host, port = get_host(url) + port = port or port_by_scheme.get(scheme, 80) + if scheme == 'https': + return HTTPSConnectionPool(host, port=port, **kw) + else: + return HTTPConnectionPool(host, port=port, **kw) + + +def _ipv6_host(host, scheme): + """ + Process IPv6 address literals + """ + + # 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 + # + # Also if an IPv6 address literal has a zone identifier, the + # percent sign might be URIencoded, convert it back into ASCII + if host.startswith('[') and host.endswith(']'): + host = host.replace('%25', '%').strip('[]') + if scheme in NORMALIZABLE_SCHEMES: + host = host.lower() + return host diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..64c3de904c2aa900a1d09f48fb4bdceb749f86af GIT binary patch literal 208 zcmZ?b<>g`kf*$Fl7!ds!M8E(ekl_Ht#VkM~g&~+hlhJP_LlH<ALHw%JFDS|^ODsv% zFH0=aPs`6qNi8bY&&|+JHY|v@tg_59C^t?^sVX)zE-NysD5=Ud0D|;9{Sf_v%mUra zyyB9?oE%+K^Q4UI(xh~dAQ;D&rRJsN7wMN4<>X{08S5wK=am#?Ch5n=XXa&=#K-Fu VRNmsS$<0qG%}KQbIjI<k82~90I6?pb literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d35363022b688d6a2c20c43e4c7d8748efb2e6d8 GIT binary patch literal 8956 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 HLb>=qx8%BC literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..63859c90219486bf46f0690e289e175bdbc70a06 GIT binary patch literal 3256 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 Im5NpQFVPl&RR910 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7f09c0e62d4ff61e4173398cb53ae41d71b51234 GIT binary patch literal 14283 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0c88cf5493c886bda7e08e04d9b41017e22c8d39 GIT binary patch literal 17905 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 GP5mE_W?rWN literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..105d2767c0ef965abc1f8b7f3c3660c4f253f5dd GIT binary patch literal 4914 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 AX#fBK literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9a21190f83ee46200491ec73795491b3d4db5f01 GIT binary patch literal 225 zcmYL@K@I^i6oxCY5Q!5wfdvl}L?R*%V8c?<Os7TZw9RX0Fh>v<aV1-~u+mDzpM2l{ z@~_^q)oPNEdz)=zzoLGrg<}zL^&n2xq*Gfx2*&xZ_YEw{GW7z=6k%r+7w8~AKsK;+ zT1}7rbF$-=8z&_WFTTqAA$tuQu+ny=c0N_AJDRY=sbKp!exaq%+#nRFlw=8HMthVD is1sR%!egqPHRyp-simj1XRpu3EH}JRVjh2V0rCNG5kFM` literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e8b6eb50e6c66c2b307408bca6f1cc06976d4c06 GIT binary patch literal 10320 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 bgR-p`Z?eZ>%$)4E$Fpc4G8!K48IAo9sL3W9 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..51e163f4937268a014650d2e8d16edb62f7e0b9a GIT binary patch literal 7501 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 NSKKw1emC5Y{}1Wg^+f;x literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py new file mode 100644 index 0000000..bcf41c0 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py @@ -0,0 +1,593 @@ +""" +This module uses ctypes to bind a whole bunch of functions and constants from +SecureTransport. The goal here is to provide the low-level API to +SecureTransport. These are essentially the C-level functions and constants, and +they're pretty gross to work with. + +This code is a bastardised version of the code found in Will Bond's oscrypto +library. An enormous debt is owed to him for blazing this trail for us. For +that reason, this code should be considered to be covered both by urllib3's +license and by oscrypto's: + + Copyright (c) 2015-2016 Will Bond <will@wbond.net> + + 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. +""" +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 +) +from ctypes import CDLL, POINTER, CFUNCTYPE + + +security_path = find_library('Security') +if not security_path: + raise ImportError('The library Security could not be found') + + +core_foundation_path = find_library('CoreFoundation') +if not core_foundation_path: + raise ImportError('The library CoreFoundation could not be found') + + +version = platform.mac_ver()[0] +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] + ) + ) + +Security = CDLL(security_path, use_errno=True) +CoreFoundation = CDLL(core_foundation_path, use_errno=True) + +Boolean = c_bool +CFIndex = c_long +CFStringEncoding = c_uint32 +CFData = c_void_p +CFString = c_void_p +CFArray = c_void_p +CFMutableArray = c_void_p +CFDictionary = c_void_p +CFError = c_void_p +CFType = c_void_p +CFTypeID = c_ulong + +CFTypeRef = POINTER(CFType) +CFAllocatorRef = c_void_p + +OSStatus = c_int32 + +CFDataRef = POINTER(CFData) +CFStringRef = POINTER(CFString) +CFArrayRef = POINTER(CFArray) +CFMutableArrayRef = POINTER(CFMutableArray) +CFDictionaryRef = POINTER(CFDictionary) +CFArrayCallBacks = c_void_p +CFDictionaryKeyCallBacks = c_void_p +CFDictionaryValueCallBacks = c_void_p + +SecCertificateRef = POINTER(c_void_p) +SecExternalFormat = c_uint32 +SecExternalItemType = c_uint32 +SecIdentityRef = POINTER(c_void_p) +SecItemImportExportFlags = c_uint32 +SecItemImportExportKeyParameters = c_void_p +SecKeychainRef = POINTER(c_void_p) +SSLProtocol = c_uint32 +SSLCipherSuite = c_uint32 +SSLContextRef = POINTER(c_void_p) +SecTrustRef = POINTER(c_void_p) +SSLConnectionRef = c_uint32 +SecTrustResultType = c_uint32 +SecTrustOptionFlags = c_uint32 +SSLProtocolSide = c_uint32 +SSLConnectionType = c_uint32 +SSLSessionOption = c_uint32 + + +try: + Security.SecItemImport.argtypes = [ + CFDataRef, + CFStringRef, + POINTER(SecExternalFormat), + POINTER(SecExternalItemType), + SecItemImportExportFlags, + POINTER(SecItemImportExportKeyParameters), + SecKeychainRef, + POINTER(CFArrayRef), + ] + Security.SecItemImport.restype = OSStatus + + Security.SecCertificateGetTypeID.argtypes = [] + Security.SecCertificateGetTypeID.restype = CFTypeID + + Security.SecIdentityGetTypeID.argtypes = [] + Security.SecIdentityGetTypeID.restype = CFTypeID + + Security.SecKeyGetTypeID.argtypes = [] + Security.SecKeyGetTypeID.restype = CFTypeID + + Security.SecCertificateCreateWithData.argtypes = [ + CFAllocatorRef, + CFDataRef + ] + Security.SecCertificateCreateWithData.restype = SecCertificateRef + + Security.SecCertificateCopyData.argtypes = [ + SecCertificateRef + ] + Security.SecCertificateCopyData.restype = CFDataRef + + Security.SecCopyErrorMessageString.argtypes = [ + OSStatus, + c_void_p + ] + Security.SecCopyErrorMessageString.restype = CFStringRef + + Security.SecIdentityCreateWithCertificate.argtypes = [ + CFTypeRef, + SecCertificateRef, + POINTER(SecIdentityRef) + ] + Security.SecIdentityCreateWithCertificate.restype = OSStatus + + Security.SecKeychainCreate.argtypes = [ + c_char_p, + c_uint32, + c_void_p, + Boolean, + c_void_p, + POINTER(SecKeychainRef) + ] + Security.SecKeychainCreate.restype = OSStatus + + Security.SecKeychainDelete.argtypes = [ + SecKeychainRef + ] + Security.SecKeychainDelete.restype = OSStatus + + Security.SecPKCS12Import.argtypes = [ + CFDataRef, + CFDictionaryRef, + 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)) + + Security.SSLSetIOFuncs.argtypes = [ + SSLContextRef, + SSLReadFunc, + SSLWriteFunc + ] + Security.SSLSetIOFuncs.restype = OSStatus + + Security.SSLSetPeerID.argtypes = [ + SSLContextRef, + c_char_p, + c_size_t + ] + Security.SSLSetPeerID.restype = OSStatus + + Security.SSLSetCertificate.argtypes = [ + SSLContextRef, + CFArrayRef + ] + Security.SSLSetCertificate.restype = OSStatus + + Security.SSLSetCertificateAuthorities.argtypes = [ + SSLContextRef, + CFTypeRef, + Boolean + ] + Security.SSLSetCertificateAuthorities.restype = OSStatus + + Security.SSLSetConnection.argtypes = [ + SSLContextRef, + SSLConnectionRef + ] + Security.SSLSetConnection.restype = OSStatus + + Security.SSLSetPeerDomainName.argtypes = [ + SSLContextRef, + c_char_p, + c_size_t + ] + Security.SSLSetPeerDomainName.restype = OSStatus + + Security.SSLHandshake.argtypes = [ + SSLContextRef + ] + Security.SSLHandshake.restype = OSStatus + + 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.restype = OSStatus + + Security.SSLClose.argtypes = [ + SSLContextRef + ] + Security.SSLClose.restype = OSStatus + + Security.SSLGetNumberSupportedCiphers.argtypes = [ + SSLContextRef, + POINTER(c_size_t) + ] + Security.SSLGetNumberSupportedCiphers.restype = OSStatus + + Security.SSLGetSupportedCiphers.argtypes = [ + SSLContextRef, + POINTER(SSLCipherSuite), + POINTER(c_size_t) + ] + Security.SSLGetSupportedCiphers.restype = OSStatus + + Security.SSLSetEnabledCiphers.argtypes = [ + SSLContextRef, + POINTER(SSLCipherSuite), + c_size_t + ] + Security.SSLSetEnabledCiphers.restype = OSStatus + + Security.SSLGetNumberEnabledCiphers.argtype = [ + SSLContextRef, + POINTER(c_size_t) + ] + Security.SSLGetNumberEnabledCiphers.restype = OSStatus + + Security.SSLGetEnabledCiphers.argtypes = [ + SSLContextRef, + POINTER(SSLCipherSuite), + POINTER(c_size_t) + ] + Security.SSLGetEnabledCiphers.restype = OSStatus + + Security.SSLGetNegotiatedCipher.argtypes = [ + SSLContextRef, + POINTER(SSLCipherSuite) + ] + Security.SSLGetNegotiatedCipher.restype = OSStatus + + Security.SSLGetNegotiatedProtocolVersion.argtypes = [ + SSLContextRef, + POINTER(SSLProtocol) + ] + Security.SSLGetNegotiatedProtocolVersion.restype = OSStatus + + Security.SSLCopyPeerTrust.argtypes = [ + SSLContextRef, + POINTER(SecTrustRef) + ] + Security.SSLCopyPeerTrust.restype = OSStatus + + Security.SecTrustSetAnchorCertificates.argtypes = [ + SecTrustRef, + CFArrayRef + ] + Security.SecTrustSetAnchorCertificates.restype = OSStatus + + Security.SecTrustSetAnchorCertificatesOnly.argstypes = [ + SecTrustRef, + Boolean + ] + Security.SecTrustSetAnchorCertificatesOnly.restype = OSStatus + + Security.SecTrustEvaluate.argtypes = [ + SecTrustRef, + POINTER(SecTrustResultType) + ] + Security.SecTrustEvaluate.restype = OSStatus + + Security.SecTrustGetCertificateCount.argtypes = [ + SecTrustRef + ] + Security.SecTrustGetCertificateCount.restype = CFIndex + + Security.SecTrustGetCertificateAtIndex.argtypes = [ + SecTrustRef, + CFIndex + ] + Security.SecTrustGetCertificateAtIndex.restype = SecCertificateRef + + Security.SSLCreateContext.argtypes = [ + CFAllocatorRef, + SSLProtocolSide, + SSLConnectionType + ] + Security.SSLCreateContext.restype = SSLContextRef + + Security.SSLSetSessionOption.argtypes = [ + SSLContextRef, + SSLSessionOption, + Boolean + ] + Security.SSLSetSessionOption.restype = OSStatus + + Security.SSLSetProtocolVersionMin.argtypes = [ + SSLContextRef, + SSLProtocol + ] + Security.SSLSetProtocolVersionMin.restype = OSStatus + + Security.SSLSetProtocolVersionMax.argtypes = [ + SSLContextRef, + SSLProtocol + ] + Security.SSLSetProtocolVersionMax.restype = OSStatus + + Security.SecCopyErrorMessageString.argtypes = [ + OSStatus, + c_void_p + ] + Security.SecCopyErrorMessageString.restype = CFStringRef + + Security.SSLReadFunc = SSLReadFunc + Security.SSLWriteFunc = SSLWriteFunc + Security.SSLContextRef = SSLContextRef + Security.SSLProtocol = SSLProtocol + Security.SSLCipherSuite = SSLCipherSuite + Security.SecIdentityRef = SecIdentityRef + Security.SecKeychainRef = SecKeychainRef + Security.SecTrustRef = SecTrustRef + Security.SecTrustResultType = SecTrustResultType + Security.SecExternalFormat = SecExternalFormat + Security.OSStatus = OSStatus + + Security.kSecImportExportPassphrase = CFStringRef.in_dll( + Security, 'kSecImportExportPassphrase' + ) + Security.kSecImportItemIdentity = CFStringRef.in_dll( + Security, 'kSecImportItemIdentity' + ) + + # CoreFoundation time! + CoreFoundation.CFRetain.argtypes = [ + CFTypeRef + ] + CoreFoundation.CFRetain.restype = CFTypeRef + + CoreFoundation.CFRelease.argtypes = [ + CFTypeRef + ] + CoreFoundation.CFRelease.restype = None + + CoreFoundation.CFGetTypeID.argtypes = [ + CFTypeRef + ] + CoreFoundation.CFGetTypeID.restype = CFTypeID + + CoreFoundation.CFStringCreateWithCString.argtypes = [ + CFAllocatorRef, + c_char_p, + CFStringEncoding + ] + CoreFoundation.CFStringCreateWithCString.restype = CFStringRef + + CoreFoundation.CFStringGetCStringPtr.argtypes = [ + CFStringRef, + CFStringEncoding + ] + CoreFoundation.CFStringGetCStringPtr.restype = c_char_p + + CoreFoundation.CFStringGetCString.argtypes = [ + CFStringRef, + c_char_p, + CFIndex, + CFStringEncoding + ] + CoreFoundation.CFStringGetCString.restype = c_bool + + CoreFoundation.CFDataCreate.argtypes = [ + CFAllocatorRef, + c_char_p, + CFIndex + ] + CoreFoundation.CFDataCreate.restype = CFDataRef + + CoreFoundation.CFDataGetLength.argtypes = [ + CFDataRef + ] + CoreFoundation.CFDataGetLength.restype = CFIndex + + CoreFoundation.CFDataGetBytePtr.argtypes = [ + CFDataRef + ] + CoreFoundation.CFDataGetBytePtr.restype = c_void_p + + CoreFoundation.CFDictionaryCreate.argtypes = [ + CFAllocatorRef, + POINTER(CFTypeRef), + POINTER(CFTypeRef), + CFIndex, + CFDictionaryKeyCallBacks, + CFDictionaryValueCallBacks + ] + CoreFoundation.CFDictionaryCreate.restype = CFDictionaryRef + + CoreFoundation.CFDictionaryGetValue.argtypes = [ + CFDictionaryRef, + CFTypeRef + ] + CoreFoundation.CFDictionaryGetValue.restype = CFTypeRef + + CoreFoundation.CFArrayCreate.argtypes = [ + CFAllocatorRef, + POINTER(CFTypeRef), + CFIndex, + CFArrayCallBacks, + ] + CoreFoundation.CFArrayCreate.restype = CFArrayRef + + CoreFoundation.CFArrayCreateMutable.argtypes = [ + CFAllocatorRef, + CFIndex, + CFArrayCallBacks + ] + CoreFoundation.CFArrayCreateMutable.restype = CFMutableArrayRef + + CoreFoundation.CFArrayAppendValue.argtypes = [ + CFMutableArrayRef, + c_void_p + ] + CoreFoundation.CFArrayAppendValue.restype = None + + CoreFoundation.CFArrayGetCount.argtypes = [ + CFArrayRef + ] + CoreFoundation.CFArrayGetCount.restype = CFIndex + + CoreFoundation.CFArrayGetValueAtIndex.argtypes = [ + CFArrayRef, + CFIndex + ] + CoreFoundation.CFArrayGetValueAtIndex.restype = c_void_p + + CoreFoundation.kCFAllocatorDefault = CFAllocatorRef.in_dll( + CoreFoundation, 'kCFAllocatorDefault' + ) + CoreFoundation.kCFTypeArrayCallBacks = c_void_p.in_dll(CoreFoundation, 'kCFTypeArrayCallBacks') + CoreFoundation.kCFTypeDictionaryKeyCallBacks = c_void_p.in_dll( + CoreFoundation, 'kCFTypeDictionaryKeyCallBacks' + ) + CoreFoundation.kCFTypeDictionaryValueCallBacks = c_void_p.in_dll( + CoreFoundation, 'kCFTypeDictionaryValueCallBacks' + ) + + CoreFoundation.CFTypeRef = CFTypeRef + CoreFoundation.CFArrayRef = CFArrayRef + CoreFoundation.CFStringRef = CFStringRef + CoreFoundation.CFDictionaryRef = CFDictionaryRef + +except (AttributeError): + raise ImportError('Error initializing ctypes') + + +class CFConst(object): + """ + A class object that acts as essentially a namespace for CoreFoundation + constants. + """ + kCFStringEncodingUTF8 = CFStringEncoding(0x08000100) + + +class SecurityConst(object): + """ + A class object that acts as essentially a namespace for Security constants. + """ + kSSLSessionOptionBreakOnServerAuth = 0 + + kSSLProtocol2 = 1 + kSSLProtocol3 = 2 + kTLSProtocol1 = 4 + kTLSProtocol11 = 7 + kTLSProtocol12 = 8 + + kSSLClientSide = 1 + kSSLStreamType = 0 + + kSecFormatPEMSequence = 10 + + kSecTrustResultInvalid = 0 + kSecTrustResultProceed = 1 + # This gap is present on purpose: this was kSecTrustResultConfirm, which + # is deprecated. + kSecTrustResultDeny = 3 + kSecTrustResultUnspecified = 4 + kSecTrustResultRecoverableTrustFailure = 5 + kSecTrustResultFatalTrustFailure = 6 + kSecTrustResultOtherError = 7 + + errSSLProtocol = -9800 + errSSLWouldBlock = -9803 + errSSLClosedGraceful = -9805 + errSSLClosedNoNotify = -9816 + errSSLClosedAbort = -9806 + + errSSLXCertChainInvalid = -9807 + errSSLCrypto = -9809 + errSSLInternal = -9810 + errSSLCertExpired = -9814 + errSSLCertNotYetValid = -9815 + errSSLUnknownRootCert = -9812 + errSSLNoRootCert = -9813 + errSSLHostNameMismatch = -9843 + errSSLPeerHandshakeFail = -9824 + errSSLPeerUserCancelled = -9839 + errSSLWeakPeerEphemeralDHKey = -9850 + errSSLServerAuthCompleted = -9841 + errSSLRecordOverflow = -9847 + + errSecVerifyFailed = -67808 + errSecNoTrustSettings = -25263 + errSecItemNotFound = -25300 + errSecInvalidTrustSettings = -25262 + + # Cipher suites. We only pick the ones our default cipher string allows. + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030 + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F + TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 = 0x00A3 + TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F + TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 = 0x00A2 + TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC024 + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xC028 + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014 + TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B + TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 = 0x006A + TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039 + TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0x0038 + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023 + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027 + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009 + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013 + TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067 + TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 = 0x0040 + TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033 + TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0x0032 + TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D + TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C + TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D + TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C + TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035 + TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F + TLS_AES_128_GCM_SHA256 = 0x1301 + TLS_AES_256_GCM_SHA384 = 0x1302 + TLS_CHACHA20_POLY1305_SHA256 = 0x1303 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py new file mode 100644 index 0000000..b13cd9e --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py @@ -0,0 +1,346 @@ +""" +Low-level helpers for the SecureTransport bindings. + +These are Python functions that are not directly related to the high-level APIs +but are necessary to get them to work. They include a whole bunch of low-level +CoreFoundation messing about and memory management. The concerns in this module +are almost entirely about trying to avoid memory leaks and providing +appropriate and useful assistance to the higher-level code. +""" +import base64 +import ctypes +import itertools +import re +import os +import ssl +import tempfile + +from .bindings import Security, CoreFoundation, CFConst + + +# This regular expression is used to grab PEM data out of a PEM bundle. +_PEM_CERTS_RE = re.compile( + b"-----BEGIN CERTIFICATE-----\n(.*?)\n-----END CERTIFICATE-----", re.DOTALL +) + + +def _cf_data_from_bytes(bytestring): + """ + Given a bytestring, create a CFData object from it. This CFData object must + be CFReleased by the caller. + """ + return CoreFoundation.CFDataCreate( + CoreFoundation.kCFAllocatorDefault, bytestring, len(bytestring) + ) + + +def _cf_dictionary_from_tuples(tuples): + """ + Given a list of Python tuples, create an associated CFDictionary. + """ + dictionary_size = len(tuples) + + # We need to get the dictionary keys and values out in the same order. + keys = (t[0] for t in tuples) + values = (t[1] for t in tuples) + cf_keys = (CoreFoundation.CFTypeRef * dictionary_size)(*keys) + cf_values = (CoreFoundation.CFTypeRef * dictionary_size)(*values) + + return CoreFoundation.CFDictionaryCreate( + CoreFoundation.kCFAllocatorDefault, + cf_keys, + cf_values, + dictionary_size, + CoreFoundation.kCFTypeDictionaryKeyCallBacks, + CoreFoundation.kCFTypeDictionaryValueCallBacks, + ) + + +def _cf_string_to_unicode(value): + """ + Creates a Unicode string from a CFString object. Used entirely for error + reporting. + + Yes, it annoys me quite a lot that this function is this complex. + """ + value_as_void_p = ctypes.cast(value, ctypes.POINTER(ctypes.c_void_p)) + + string = CoreFoundation.CFStringGetCStringPtr( + 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 + ) + if not result: + raise OSError('Error copying C string from CFStringRef') + string = buffer.value + if string is not None: + string = string.decode('utf-8') + return string + + +def _assert_no_error(error, exception_class=None): + """ + Checks the return code and throws an exception if there is an error to + report + """ + if error == 0: + return + + cf_error_string = Security.SecCopyErrorMessageString(error, 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 exception_class is None: + exception_class = ssl.SSLError + + raise exception_class(output) + + +def _cert_array_from_pem(pem_bundle): + """ + Given a bundle of certs in PEM format, turns them into a CFArray of certs + that can be used to validate a cert chain. + """ + # Normalize the PEM bundle's line endings. + 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) + ] + if not der_certs: + raise ssl.SSLError("No root certificates specified") + + cert_array = CoreFoundation.CFArrayCreateMutable( + CoreFoundation.kCFAllocatorDefault, + 0, + ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks) + ) + if not cert_array: + raise ssl.SSLError("Unable to allocate memory!") + + try: + for der_bytes in der_certs: + certdata = _cf_data_from_bytes(der_bytes) + if not certdata: + raise ssl.SSLError("Unable to allocate memory!") + cert = Security.SecCertificateCreateWithData( + CoreFoundation.kCFAllocatorDefault, certdata + ) + CoreFoundation.CFRelease(certdata) + if not cert: + raise ssl.SSLError("Unable to build cert object!") + + CoreFoundation.CFArrayAppendValue(cert_array, cert) + CoreFoundation.CFRelease(cert) + except Exception: + # We need to free the array before the exception bubbles further. + # We only want to do that if an error occurs: otherwise, the caller + # should free. + CoreFoundation.CFRelease(cert_array) + + return cert_array + + +def _is_cert(item): + """ + Returns True if a given CFTypeRef is a certificate. + """ + expected = Security.SecCertificateGetTypeID() + return CoreFoundation.CFGetTypeID(item) == expected + + +def _is_identity(item): + """ + Returns True if a given CFTypeRef is an identity. + """ + expected = Security.SecIdentityGetTypeID() + return CoreFoundation.CFGetTypeID(item) == expected + + +def _temporary_keychain(): + """ + This function creates a temporary Mac keychain that we can use to work with + credentials. This keychain uses a one-time password and a temporary file to + store the data. We expect to have one keychain per socket. The returned + SecKeychainRef must be freed by the caller, including calling + SecKeychainDelete. + + Returns a tuple of the SecKeychainRef and the path to the temporary + directory that contains it. + """ + # Unfortunately, SecKeychainCreate requires a path to a keychain. This + # means we cannot use mkstemp to use a generic temporary file. Instead, + # we're going to create a temporary directory and a filename to use there. + # This filename will be 8 random bytes expanded into base64. We also need + # 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') + password = base64.b16encode(random_bytes[8:]) # Must be valid UTF-8 + tempdirectory = tempfile.mkdtemp() + + 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) + ) + _assert_no_error(status) + + # Having created the keychain, we want to pass it off to the caller. + return keychain, tempdirectory + + +def _load_items_from_file(keychain, path): + """ + Given a single file, loads all the trust objects from it into arrays and + the keychain. + Returns a tuple of lists: the first list is a list of identities, the + second a list of certs. + """ + certificates = [] + identities = [] + result_array = None + + with open(path, 'rb') as f: + raw_filedata = f.read() + + try: + filedata = CoreFoundation.CFDataCreate( + CoreFoundation.kCFAllocatorDefault, + raw_filedata, + len(raw_filedata) + ) + result_array = CoreFoundation.CFArrayRef() + result = Security.SecItemImport( + filedata, # cert data + None, # Filename, leaving it out for now + None, # What the type of the file is, we don't care + None, # what's in the file, we don't care + 0, # import flags + None, # key params, can include passphrase in the future + keychain, # The keychain to insert into + ctypes.byref(result_array) # Results + ) + _assert_no_error(result) + + # A CFArray is not very useful to us as an intermediary + # representation, so we are going to extract the objects we want + # and then free the array. We don't need to keep hold of keys: the + # keychain already has them! + result_count = CoreFoundation.CFArrayGetCount(result_array) + for index in range(result_count): + item = CoreFoundation.CFArrayGetValueAtIndex( + result_array, index + ) + item = ctypes.cast(item, CoreFoundation.CFTypeRef) + + if _is_cert(item): + CoreFoundation.CFRetain(item) + certificates.append(item) + elif _is_identity(item): + CoreFoundation.CFRetain(item) + identities.append(item) + finally: + if result_array: + CoreFoundation.CFRelease(result_array) + + CoreFoundation.CFRelease(filedata) + + return (identities, certificates) + + +def _load_client_cert_chain(keychain, *paths): + """ + Load certificates and maybe keys from a number of files. Has the end goal + of returning a CFArray containing one SecIdentityRef, and then zero or more + SecCertificateRef objects, suitable for use as a client certificate trust + chain. + """ + # Ok, the strategy. + # + # This relies on knowing that macOS will not give you a SecIdentityRef + # unless you have imported a key into a keychain. This is a somewhat + # artificial limitation of macOS (for example, it doesn't necessarily + # affect iOS), but there is nothing inside Security.framework that lets you + # get a SecIdentityRef without having a key in a keychain. + # + # So the policy here is we take all the files and iterate them in order. + # Each one will use SecItemImport to have one or more objects loaded from + # it. We will also point at a keychain that macOS can use to work with the + # private key. + # + # Once we have all the objects, we'll check what we actually have. If we + # already have a SecIdentityRef in hand, fab: we'll use that. Otherwise, + # we'll take the first certificate (which we assume to be our leaf) and + # ask the keychain to give us a SecIdentityRef with that cert's associated + # key. + # + # We'll then return a CFArray containing the trust chain: one + # SecIdentityRef and then zero-or-more SecCertificateRef objects. The + # responsibility for freeing this CFArray will be with the caller. This + # CFArray must remain alive for the entire connection, so in practice it + # will be stored with a single SSLSocket, along with the reference to the + # keychain. + certificates = [] + identities = [] + + # Filter out bad paths. + paths = (path for path in paths if path) + + try: + for file_path in paths: + new_identities, new_certs = _load_items_from_file( + keychain, file_path + ) + identities.extend(new_identities) + certificates.extend(new_certs) + + # Ok, we have everything. The question is: do we have an identity? If + # not, we want to grab one from the first cert we have. + if not identities: + new_identity = Security.SecIdentityRef() + status = Security.SecIdentityCreateWithCertificate( + keychain, + certificates[0], + ctypes.byref(new_identity) + ) + _assert_no_error(status) + identities.append(new_identity) + + # We now want to release the original certificate, as we no longer + # need it. + CoreFoundation.CFRelease(certificates.pop(0)) + + # We now need to build a new CFArray that holds the trust chain. + trust_chain = CoreFoundation.CFArrayCreateMutable( + CoreFoundation.kCFAllocatorDefault, + 0, + ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks), + ) + for item in itertools.chain(identities, certificates): + # ArrayAppendValue does a CFRetain on the item. That's fine, + # because the finally block will release our other refs to them. + CoreFoundation.CFArrayAppendValue(trust_chain, item) + + return trust_chain + finally: + for obj in itertools.chain(identities, certificates): + CoreFoundation.CFRelease(obj) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/appengine.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/appengine.py new file mode 100644 index 0000000..59f2a61 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/appengine.py @@ -0,0 +1,305 @@ +""" +This module provides a pool manager that uses Google App Engine's +`URLFetch Service <https://cloud.google.com/appengine/docs/python/urlfetch>`_. + +Example usage:: + + from pip._vendor.urllib3 import PoolManager + from pip._vendor.urllib3.contrib.appengine import AppEngineManager, is_appengine_sandbox + + if is_appengine_sandbox(): + # AppEngineManager uses AppEngine's URLFetch API behind the scenes + http = AppEngineManager() + else: + # PoolManager uses a socket-level API behind the scenes + http = PoolManager() + + r = http.request('GET', 'https://google.com/') + +There are `limitations <https://cloud.google.com/appengine/docs/python/\ +urlfetch/#Python_Quotas_and_limits>`_ to the URLFetch service and it may not be +the best choice for your application. There are three options for using +urllib3 on Google App Engine: + +1. You can use :class:`AppEngineManager` with URLFetch. URLFetch is + cost-effective in many circumstances as long as your usage is within the + limitations. +2. You can use a normal :class:`~urllib3.PoolManager` by enabling sockets. + Sockets also have `limitations and restrictions + <https://cloud.google.com/appengine/docs/python/sockets/\ + #limitations-and-restrictions>`_ and have a lower free quota than URLFetch. + To use sockets, be sure to specify the following in your ``app.yaml``:: + + env_variables: + GAE_USE_SOCKETS_HTTPLIB : 'true' + +3. If you are using `App Engine Flexible +<https://cloud.google.com/appengine/docs/flexible/>`_, you can use the standard +:class:`PoolManager` without any configuration or special environment variables. +""" + +from __future__ import absolute_import +import logging +import os +import warnings +from ..packages.six.moves.urllib.parse import urljoin + +from ..exceptions import ( + HTTPError, + HTTPWarning, + MaxRetryError, + ProtocolError, + TimeoutError, + SSLError +) + +from ..packages.six import BytesIO +from ..request import RequestMethods +from ..response import HTTPResponse +from ..util.timeout import Timeout +from ..util.retry import Retry + +try: + from google.appengine.api import urlfetch +except ImportError: + urlfetch = None + + +log = logging.getLogger(__name__) + + +class AppEnginePlatformWarning(HTTPWarning): + pass + + +class AppEnginePlatformError(HTTPError): + pass + + +class AppEngineManager(RequestMethods): + """ + Connection manager for Google App Engine sandbox applications. + + This manager uses the URLFetch service directly instead of using the + emulated httplib, and is subject to URLFetch limitations as described in + the App Engine documentation `here + <https://cloud.google.com/appengine/docs/python/urlfetch>`_. + + Notably it will raise an :class:`AppEnginePlatformError` if: + * URLFetch is not available. + * If you attempt to use this on App Engine Flexible, as full socket + support is available. + * If a request size is more than 10 megabytes. + * If a response size is more than 32 megabtyes. + * If you use an unsupported request method such as OPTIONS. + + Beyond those cases, it will raise normal urllib3 errors. + """ + + 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.") + + 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) + + RequestMethods.__init__(self, headers) + self.validate_certificate = validate_certificate + self.urlfetch_retries = urlfetch_retries + + self.retries = retries or Retry.DEFAULT + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + # 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): + + retries = self._get_retries(retries, redirect) + + try: + follow_redirects = ( + redirect and + retries.redirect != 0 and + retries.total) + response = urlfetch.fetch( + url, + payload=body, + method=method, + headers=headers or {}, + allow_truncated=False, + follow_redirects=self.urlfetch_retries and follow_redirects, + deadline=self._get_absolute_timeout(timeout), + validate_certificate=self.validate_certificate, + ) + except urlfetch.DeadlineExceededError as e: + raise TimeoutError(self, e) + + except urlfetch.InvalidURLError as e: + if 'too large' in str(e): + raise AppEnginePlatformError( + "URLFetch request too large, URLFetch only " + "supports requests up to 10mb in size.", e) + raise ProtocolError(e) + + except urlfetch.DownloadError as 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) + + except urlfetch.SSLCertificateError as e: + raise SSLError(e) + + except urlfetch.InvalidMethodError as e: + raise AppEnginePlatformError( + "URLFetch does not support method: %s" % method, e) + + http_response = self._urlfetch_response_to_http_response( + 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): + raise MaxRetryError(self, url, "too many redirects") + else: + if http_response.status == 303: + method = 'GET' + + try: + retries = retries.increment(method, url, response=http_response, _pool=self) + except MaxRetryError: + if retries.raise_on_redirect: + raise MaxRetryError(self, url, "too many redirects") + return http_response + + retries.sleep_for_retry(http_response) + 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) + + # Check if we should retry the HTTP response. + 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) + 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) + + return http_response + + def _urlfetch_response_to_http_response(self, urlfetch_resp, **response_kw): + + 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') + + if content_encoding == 'deflate': + del urlfetch_resp.headers['content-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': + encodings = transfer_encoding.split(",") + 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 + # a file-like object. + body=BytesIO(urlfetch_resp.content), + msg=urlfetch_resp.header_msg, + headers=urlfetch_resp.headers, + status=urlfetch_resp.status_code, + **response_kw + ) + + return HTTPResponse( + body=BytesIO(urlfetch_resp.content), + headers=urlfetch_resp.headers, + status=urlfetch_resp.status_code, + original_response=original_response, + **response_kw + ) + + def _get_absolute_timeout(self, timeout): + if timeout is Timeout.DEFAULT_TIMEOUT: + return None # Defer to URLFetch's default. + if isinstance(timeout, Timeout): + if timeout._read is not None or timeout._connect is not None: + warnings.warn( + "URLFetch does not support granular timeout settings, " + "reverting to total or default URLFetch timeout.", + 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) + + 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) + + return retries + + +def is_appengine(): + return (is_local_appengine() or + is_prod_appengine() or + is_prod_appengine_mvms()) + + +def is_appengine_sandbox(): + return is_appengine() and not is_prod_appengine_mvms() + + +def is_local_appengine(): + return ('APPENGINE_RUNTIME' in os.environ and + 'Development/' in os.environ['SERVER_SOFTWARE']) + + +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()) + + +def is_prod_appengine_mvms(): + return os.environ.get('GAE_VM', False) == 'true' diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py new file mode 100644 index 0000000..642e99e --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py @@ -0,0 +1,112 @@ +""" +NTLM authenticating pool, contributed by erikcederstran + +Issue #10, see: http://code.google.com/p/urllib3/issues/detail?id=10 +""" +from __future__ import absolute_import + +from logging import getLogger +from ntlm import ntlm + +from .. import HTTPSConnectionPool +from ..packages.six.moves.http_client import HTTPSConnection + + +log = getLogger(__name__) + + +class NTLMConnectionPool(HTTPSConnectionPool): + """ + Implements an NTLM authentication version of an urllib3 connection pool + """ + + scheme = 'https' + + def __init__(self, user, pw, authurl, *args, **kwargs): + """ + authurl is a random URL on the server that is protected by NTLM. + user is the Windows user, probably in the DOMAIN\\username format. + pw is the password for the user. + """ + super(NTLMConnectionPool, self).__init__(*args, **kwargs) + self.authurl = authurl + self.rawuser = user + user_parts = user.split('\\', 1) + self.domain = user_parts[0].upper() + self.user = user_parts[1] + self.pw = pw + + def _new_conn(self): + # 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) + + headers = {} + 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) + 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)) + + # 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_value = None + for s in auth_header_values: + 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])) + + # 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) + 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]) + 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)) + + res.fp = None + log.debug('Connection established') + return conn + + 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) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py new file mode 100644 index 0000000..6dd3a01 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py @@ -0,0 +1,457 @@ +""" +SSL with SNI_-support for Python 2. Follow these instructions if you would +like to verify SSL certificates in Python 2. Note, the default libraries do +*not* do certificate checking; you need to do additional work to validate +certificates yourself. + +This needs the following packages installed: + +* pyOpenSSL (tested with 16.0.0) +* cryptography (minimum 1.3.4, from pyopenssl) +* idna (minimum 2.0, from cryptography) + +However, pyopenssl depends on cryptography, which depends on idna, so while we +use all three directly here we end up having relatively few packages required. + +You can install them with the following command: + + pip install pyopenssl cryptography idna + +To activate certificate checking, call +:func:`~urllib3.contrib.pyopenssl.inject_into_urllib3` from your Python code +before you begin making HTTP requests. This can be done in a ``sitecustomize`` +module, or at any other time before your application begins using ``urllib3``, +like this:: + + try: + import urllib3.contrib.pyopenssl + urllib3.contrib.pyopenssl.inject_into_urllib3() + except ImportError: + pass + +Now you can use :mod:`urllib3` as you normally would, and it will support SNI +when the required modules are installed. + +Activating this module also has the positive side effect of disabling SSL/TLS +compression in Python 2 (see `CRIME attack`_). + +If you want to configure the default list of supported cipher suites, you can +set the ``urllib3.contrib.pyopenssl.DEFAULT_SSL_CIPHER_LIST`` variable. + +.. _sni: https://en.wikipedia.org/wiki/Server_Name_Indication +.. _crime attack: https://en.wikipedia.org/wiki/CRIME_(security_exploit) +""" +from __future__ import absolute_import + +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: + # UnsupportedExtension is gone in cryptography >= 2.1.0 + class UnsupportedExtension(Exception): + pass + +from socket import timeout, error as SocketError +from io import BytesIO + +try: # Platform-specific: Python 2 + from socket import _fileobject +except ImportError: # Platform-specific: Python 3 + _fileobject = None + from ..packages.backports.makefile import backport_makefile + +import logging +import ssl +from ..packages import six +import sys + +from .. import util + +__all__ = ['inject_into_urllib3', 'extract_from_urllib3'] + +# SNI always works. +HAS_SNI = True + +# Map from urllib3 to PyOpenSSL compatible parameter-values. +_openssl_versions = { + ssl.PROTOCOL_SSLv23: OpenSSL.SSL.SSLv23_METHOD, + ssl.PROTOCOL_TLSv1: OpenSSL.SSL.TLSv1_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'): + _openssl_versions[ssl.PROTOCOL_TLSv1_2] = OpenSSL.SSL.TLSv1_2_METHOD + +try: + _openssl_versions.update({ssl.PROTOCOL_SSLv3: OpenSSL.SSL.SSLv3_METHOD}) +except AttributeError: + pass + +_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, +} +_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 + +orig_util_HAS_SNI = util.HAS_SNI +orig_util_SSLContext = util.ssl_.SSLContext + + +log = logging.getLogger(__name__) + + +def inject_into_urllib3(): + 'Monkey-patch urllib3 with PyOpenSSL-backed SSL-support.' + + _validate_dependencies_met() + + util.ssl_.SSLContext = PyOpenSSLContext + util.HAS_SNI = HAS_SNI + util.ssl_.HAS_SNI = HAS_SNI + util.IS_PYOPENSSL = True + util.ssl_.IS_PYOPENSSL = True + + +def extract_from_urllib3(): + 'Undo monkey-patching by :func:`inject_into_urllib3`.' + + util.ssl_.SSLContext = orig_util_SSLContext + util.HAS_SNI = orig_util_HAS_SNI + util.ssl_.HAS_SNI = orig_util_HAS_SNI + util.IS_PYOPENSSL = False + util.ssl_.IS_PYOPENSSL = False + + +def _validate_dependencies_met(): + """ + Verifies that PyOpenSSL's package-level dependencies have been met. + Throws `ImportError` if they are not 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.") + + # 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.") + + +def _dnsname_to_stdlib(name): + """ + Converts a dNSName SubjectAlternativeName field to the form used by the + standard library on the given Python version. + + Cryptography produces a dNSName as a unicode string that was idna-decoded + from ASCII bytes. We need to idna-encode that string to get it back, and + then on Python 3 we also need to convert to unicode via UTF-8 (the stdlib + uses PyUnicode_FromStringAndSize on it, which decodes via UTF-8). + """ + def idna_encode(name): + """ + Borrowed wholesale from the Python Cryptography Project. It turns out + that we can't just safely call `idna.encode`: it can explode for + wildcard names. This avoids that problem. + """ + from pip._vendor import idna + + for prefix in [u'*.', u'.']: + if name.startswith(prefix): + name = name[len(prefix):] + return prefix.encode('ascii') + idna.encode(name) + return idna.encode(name) + + name = idna_encode(name) + if sys.version_info >= (3, 0): + name = name.decode('utf-8') + return name + + +def get_subj_alt_name(peer_cert): + """ + Given an PyOpenSSL certificate, provides all the subject alternative names. + """ + # Pass the cert to cryptography, which has much better APIs for this. + if hasattr(peer_cert, "to_cryptography"): + cert = peer_cert.to_cryptography() + else: + # This is technically using private APIs, but should work across all + # relevant versions before PyOpenSSL got a proper API for this. + cert = _Certificate(openssl_backend, peer_cert._x509) + + # 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 + except x509.ExtensionNotFound: + # No such extension, return the empty list. + return [] + 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( + "A problem was encountered with the certificate that prevented " + "urllib3 from finding the SubjectAlternativeName field. This can " + "affect certificate validation. The error was %s", + e, + ) + return [] + + # We want to return dNSName and iPAddress fields. We need to cast the IPs + # back to strings because the match_hostname function wants them as + # strings. + # Sadly the DNS names need to be idna encoded and then, on Python 3, UTF-8 + # decoded. This is pretty frustrating, but that's what the standard library + # does with certificates, and so we need to attempt to do the same. + names = [ + ('DNS', _dnsname_to_stdlib(name)) + for name in ext.get_values_for_type(x509.DNSName) + ] + names.extend( + ('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. + + 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 + self.socket = socket + self.suppress_ragged_eofs = suppress_ragged_eofs + self._makefile_refs = 0 + self._closed = False + + def fileno(self): + return self.socket.fileno() + + # Copy-pasted from Python 3.5 source code + def _decref_socketios(self): + if self._makefile_refs > 0: + self._makefile_refs -= 1 + if self._closed: + self.close() + + def recv(self, *args, **kwargs): + 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'' + else: + raise SocketError(str(e)) + except OpenSSL.SSL.ZeroReturnError as e: + if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN: + 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') + else: + return self.recv(*args, **kwargs) + else: + return data + + def recv_into(self, *args, **kwargs): + 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'): + return 0 + else: + raise SocketError(str(e)) + except OpenSSL.SSL.ZeroReturnError as e: + if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN: + return 0 + else: + raise + except OpenSSL.SSL.WantReadError: + if not util.wait_for_read(self.socket, self.socket.gettimeout()): + raise timeout('The read operation timed out') + else: + return self.recv_into(*args, **kwargs) + + def settimeout(self, timeout): + return self.socket.settimeout(timeout) + + def _send_until_done(self, data): + while True: + try: + return self.connection.send(data) + except OpenSSL.SSL.WantWriteError: + if not util.wait_for_write(self.socket, self.socket.gettimeout()): + raise timeout() + continue + except OpenSSL.SSL.SysCallError as e: + raise SocketError(str(e)) + + 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]) + total_sent += sent + + def shutdown(self): + # FIXME rethrow compatible exceptions should we ever use this + self.connection.shutdown() + + def close(self): + if self._makefile_refs < 1: + try: + self._closed = True + return self.connection.close() + except OpenSSL.SSL.Error: + return + else: + self._makefile_refs -= 1 + + def getpeercert(self, binary_form=False): + x509 = self.connection.get_peer_certificate() + + if not x509: + return x509 + + if binary_form: + return OpenSSL.crypto.dump_certificate( + OpenSSL.crypto.FILETYPE_ASN1, + x509) + + return { + 'subject': ( + (('commonName', x509.get_subject().CN),), + ), + 'subjectAltName': get_subj_alt_name(x509) + } + + def _reuse(self): + self._makefile_refs += 1 + + def _drop(self): + if self._makefile_refs < 1: + self.close() + else: + self._makefile_refs -= 1 + + +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 + +WrappedSocket.makefile = makefile + + +class PyOpenSSLContext(object): + """ + I am a wrapper class for the PyOpenSSL ``Context`` object. I am responsible + 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) + self._options = 0 + self.check_hostname = False + + @property + def options(self): + return self._options + + @options.setter + def options(self, value): + self._options = value + self._ctx.set_options(value) + + @property + def verify_mode(self): + return _openssl_to_stdlib_verify[self._ctx.get_verify_mode()] + + @verify_mode.setter + def verify_mode(self, value): + 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') + 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') + 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)) + + def load_cert_chain(self, certfile, keyfile=None, password=None): + self._ctx.use_certificate_chain_file(certfile) + if password is not None: + self._ctx.set_passwd_cb(lambda max_length, prompt_twice, userdata: 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): + 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') + + if server_hostname is not None: + cnx.set_tlsext_host_name(server_hostname) + + cnx.set_connect_state() + + while True: + try: + cnx.do_handshake() + except OpenSSL.SSL.WantReadError: + if not util.wait_for_read(sock, sock.gettimeout()): + raise timeout('select timed out') + continue + except OpenSSL.SSL.Error as e: + raise ssl.SSLError('bad handshake: %r' % e) + break + + return WrappedSocket(cnx, sock) + + +def _verify_callback(cnx, x509, err_no, err_depth, return_code): + return err_no == 0 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/securetransport.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/securetransport.py new file mode 100644 index 0000000..77cb59e --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/securetransport.py @@ -0,0 +1,804 @@ +""" +SecureTranport support for urllib3 via ctypes. + +This makes platform-native TLS available to urllib3 users on macOS without the +use of a compiler. This is an important feature because the Python Package +Index is moving to become a TLSv1.2-or-higher server, and the default OpenSSL +that ships with macOS is not capable of doing TLSv1.2. The only way to resolve +this is to give macOS users an alternative solution to the problem, and that +solution is to use SecureTransport. + +We use ctypes here because this solution must not require a compiler. That's +because pip is not allowed to require a compiler either. + +This is not intended to be a seriously long-term solution to this problem. +The hope is that PEP 543 will eventually solve this issue for us, at which +point we can retire this contrib module. But in the short term, we need to +solve the impending tire fire that is Python on Mac without this kind of +contrib module. So...here we are. + +To use this module, simply import and inject it:: + + import urllib3.contrib.securetransport + urllib3.contrib.securetransport.inject_into_urllib3() + +Happy TLSing! +""" +from __future__ import absolute_import + +import contextlib +import ctypes +import errno +import os.path +import shutil +import socket +import ssl +import threading +import weakref + +from .. import util +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 +) + +try: # Platform-specific: Python 2 + from socket import _fileobject +except ImportError: # Platform-specific: Python 3 + _fileobject = None + from ..packages.backports.makefile import backport_makefile + +__all__ = ['inject_into_urllib3', 'extract_from_urllib3'] + +# SNI always works +HAS_SNI = True + +orig_util_HAS_SNI = util.HAS_SNI +orig_util_SSLContext = util.ssl_.SSLContext + +# This dictionary is used by the read callback to obtain a handle to the +# calling wrapped socket. This is a pretty silly approach, but for now it'll +# do. I feel like I should be able to smuggle a handle to the wrapped socket +# directly in the SSLConnectionRef, but for now this approach will work I +# guess. +# +# We need to lock around this structure for inserts, but we don't do it for +# reads/writes in the callbacks. The reasoning here goes as follows: +# +# 1. It is not possible to call into the callbacks before the dictionary is +# populated, so once in the callback the id must be in the dictionary. +# 2. The callbacks don't mutate the dictionary, they only read from it, and +# so cannot conflict with any of the insertions. +# +# This is good: if we had to lock in the callbacks we'd drastically slow down +# the performance of this code. +_connection_refs = weakref.WeakValueDictionary() +_connection_ref_lock = threading.Lock() + +# Limit writes to 16kB. This is OpenSSL's limit, but we'll cargo-cult it over +# for no better reason than we need *a* limit, and this one is right there. +SSL_WRITE_BLOCKSIZE = 16384 + +# This is our equivalent of util.ssl_.DEFAULT_CIPHERS, but expanded out to +# individual cipher suites. We need to do this because this is how +# SecureTransport wants them. +CIPHER_SUITES = [ + SecurityConst.TLS_AES_256_GCM_SHA384, + SecurityConst.TLS_CHACHA20_POLY1305_SHA256, + SecurityConst.TLS_AES_128_GCM_SHA256, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + SecurityConst.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, + SecurityConst.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + SecurityConst.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, + SecurityConst.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + SecurityConst.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, + SecurityConst.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, + SecurityConst.TLS_DHE_RSA_WITH_AES_256_CBC_SHA, + SecurityConst.TLS_DHE_DSS_WITH_AES_256_CBC_SHA, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + SecurityConst.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, + SecurityConst.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, + SecurityConst.TLS_DHE_RSA_WITH_AES_128_CBC_SHA, + SecurityConst.TLS_DHE_DSS_WITH_AES_128_CBC_SHA, + SecurityConst.TLS_RSA_WITH_AES_256_GCM_SHA384, + SecurityConst.TLS_RSA_WITH_AES_128_GCM_SHA256, + SecurityConst.TLS_RSA_WITH_AES_256_CBC_SHA256, + SecurityConst.TLS_RSA_WITH_AES_128_CBC_SHA256, + SecurityConst.TLS_RSA_WITH_AES_256_CBC_SHA, + SecurityConst.TLS_RSA_WITH_AES_128_CBC_SHA, +] + +# Basically this is simple: for PROTOCOL_SSLv23 we turn it into a low of +# TLSv1 and a high of TLSv1.2. For everything else, we pin to that version. +_protocol_to_min_max = { + ssl.PROTOCOL_SSLv23: (SecurityConst.kTLSProtocol1, SecurityConst.kTLSProtocol12), +} + +if hasattr(ssl, "PROTOCOL_SSLv2"): + _protocol_to_min_max[ssl.PROTOCOL_SSLv2] = ( + SecurityConst.kSSLProtocol2, SecurityConst.kSSLProtocol2 + ) +if hasattr(ssl, "PROTOCOL_SSLv3"): + _protocol_to_min_max[ssl.PROTOCOL_SSLv3] = ( + SecurityConst.kSSLProtocol3, SecurityConst.kSSLProtocol3 + ) +if hasattr(ssl, "PROTOCOL_TLSv1"): + _protocol_to_min_max[ssl.PROTOCOL_TLSv1] = ( + SecurityConst.kTLSProtocol1, SecurityConst.kTLSProtocol1 + ) +if hasattr(ssl, "PROTOCOL_TLSv1_1"): + _protocol_to_min_max[ssl.PROTOCOL_TLSv1_1] = ( + SecurityConst.kTLSProtocol11, SecurityConst.kTLSProtocol11 + ) +if hasattr(ssl, "PROTOCOL_TLSv1_2"): + _protocol_to_min_max[ssl.PROTOCOL_TLSv1_2] = ( + SecurityConst.kTLSProtocol12, SecurityConst.kTLSProtocol12 + ) +if hasattr(ssl, "PROTOCOL_TLS"): + _protocol_to_min_max[ssl.PROTOCOL_TLS] = _protocol_to_min_max[ssl.PROTOCOL_SSLv23] + + +def inject_into_urllib3(): + """ + Monkey-patch urllib3 with SecureTransport-backed SSL-support. + """ + util.ssl_.SSLContext = SecureTransportContext + util.HAS_SNI = HAS_SNI + util.ssl_.HAS_SNI = HAS_SNI + util.IS_SECURETRANSPORT = True + util.ssl_.IS_SECURETRANSPORT = True + + +def extract_from_urllib3(): + """ + Undo monkey-patching by :func:`inject_into_urllib3`. + """ + util.ssl_.SSLContext = orig_util_SSLContext + util.HAS_SNI = orig_util_HAS_SNI + util.ssl_.HAS_SNI = orig_util_HAS_SNI + util.IS_SECURETRANSPORT = False + util.ssl_.IS_SECURETRANSPORT = False + + +def _read_callback(connection_id, data_buffer, data_length_pointer): + """ + SecureTransport read callback. This is called by ST to request that data + be returned from the socket. + """ + wrapped_socket = None + try: + wrapped_socket = _connection_refs.get(connection_id) + if wrapped_socket is None: + return SecurityConst.errSSLInternal + base_socket = wrapped_socket.socket + + requested_length = data_length_pointer[0] + + timeout = wrapped_socket.gettimeout() + error = None + read_count = 0 + + try: + 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') + + remaining = requested_length - read_count + buffer = (ctypes.c_char * remaining).from_address( + data_buffer + read_count + ) + chunk_size = base_socket.recv_into(buffer, remaining) + read_count += chunk_size + if not chunk_size: + if not read_count: + return SecurityConst.errSSLClosedGraceful + break + except (socket.error) as e: + error = e.errno + + if error is not None and error != errno.EAGAIN: + data_length_pointer[0] = read_count + if error == errno.ECONNRESET or error == errno.EPIPE: + return SecurityConst.errSSLClosedAbort + raise + + data_length_pointer[0] = read_count + + if read_count != requested_length: + return SecurityConst.errSSLWouldBlock + + return 0 + except Exception as e: + if wrapped_socket is not None: + wrapped_socket._exception = e + return SecurityConst.errSSLInternal + + +def _write_callback(connection_id, data_buffer, data_length_pointer): + """ + SecureTransport write callback. This is called by ST to request that data + actually be sent on the network. + """ + wrapped_socket = None + try: + wrapped_socket = _connection_refs.get(connection_id) + if wrapped_socket is None: + return SecurityConst.errSSLInternal + base_socket = wrapped_socket.socket + + bytes_to_write = data_length_pointer[0] + data = ctypes.string_at(data_buffer, bytes_to_write) + + timeout = wrapped_socket.gettimeout() + error = None + sent = 0 + + try: + 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') + chunk_sent = base_socket.send(data) + sent += chunk_sent + + # This has some needless copying here, but I'm not sure there's + # much value in optimising this data path. + data = data[chunk_sent:] + except (socket.error) as e: + error = e.errno + + if error is not None and error != errno.EAGAIN: + data_length_pointer[0] = sent + if error == errno.ECONNRESET or error == errno.EPIPE: + return SecurityConst.errSSLClosedAbort + raise + + data_length_pointer[0] = sent + + if sent != bytes_to_write: + return SecurityConst.errSSLWouldBlock + + return 0 + except Exception as e: + if wrapped_socket is not None: + wrapped_socket._exception = e + return SecurityConst.errSSLInternal + + +# We need to keep these two objects references alive: if they get GC'd while +# in use then SecureTransport could attempt to call a function that is in freed +# memory. That would be...uh...bad. Yeah, that's the word. Bad. +_read_callback_pointer = Security.SSLReadFunc(_read_callback) +_write_callback_pointer = Security.SSLWriteFunc(_write_callback) + + +class WrappedSocket(object): + """ + API-compatibility wrapper for Python's OpenSSL wrapped socket 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 + self._makefile_refs = 0 + self._closed = False + self._exception = None + self._keychain = None + self._keychain_dir = None + self._client_cert_chain = None + + # We save off the previously-configured timeout and then set it to + # zero. This is done because we use select and friends to handle the + # timeouts, but if we leave the timeout set on the lower socket then + # Python will "kindly" call select on that socket again for us. Avoid + # that by forcing the timeout to zero. + self._timeout = self.socket.gettimeout() + self.socket.settimeout(0) + + @contextlib.contextmanager + def _raise_on_error(self): + """ + A context manager that can be used to wrap calls that do I/O from + SecureTransport. If any of the I/O callbacks hit an exception, this + context manager will correctly propagate the exception after the fact. + This avoids silently swallowing those exceptions. + + It also correctly forces the socket closed. + """ + self._exception = None + + # We explicitly don't catch around this yield because in the unlikely + # event that an exception was hit in the block we don't want to swallow + # it. + yield + if self._exception is not None: + exception, self._exception = self._exception, None + self.close() + raise exception + + def _set_ciphers(self): + """ + Sets up the allowed ciphers. By default this matches the set in + util.ssl_.DEFAULT_CIPHERS, at least as supported by macOS. This is done + custom and doesn't allow changing at this time, mostly because parsing + OpenSSL cipher strings is going to be a freaking nightmare. + """ + ciphers = (Security.SSLCipherSuite * len(CIPHER_SUITES))(*CIPHER_SUITES) + result = Security.SSLSetEnabledCiphers( + self.context, ciphers, len(CIPHER_SUITES) + ) + _assert_no_error(result) + + def _custom_validate(self, verify, trust_bundle): + """ + Called when we have set custom validation. We do this in two cases: + first, when cert validation is entirely disabled; and second, when + using a custom trust DB. + """ + # If we disabled cert validation, just say: cool. + if not verify: + return + + # We want data in memory, so load it up. + if os.path.isfile(trust_bundle): + with open(trust_bundle, 'rb') as f: + trust_bundle = f.read() + + cert_array = None + trust = Security.SecTrustRef() + + try: + # Get a CFArray that contains the certs we want. + cert_array = _cert_array_from_pem(trust_bundle) + + # Ok, now the hard part. We want to get the SecTrustRef that ST has + # 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) + ) + _assert_no_error(result) + if not trust: + raise ssl.SSLError("Failed to copy trust reference") + + result = Security.SecTrustSetAnchorCertificates(trust, cert_array) + _assert_no_error(result) + + result = Security.SecTrustSetAnchorCertificatesOnly(trust, True) + _assert_no_error(result) + + trust_result = Security.SecTrustResultType() + result = Security.SecTrustEvaluate( + trust, ctypes.byref(trust_result) + ) + _assert_no_error(result) + finally: + if trust: + CoreFoundation.CFRelease(trust) + + if cert_array is not None: + CoreFoundation.CFRelease(cert_array) + + # Ok, now we can look at what the result was. + successes = ( + SecurityConst.kSecTrustResultUnspecified, + SecurityConst.kSecTrustResultProceed + ) + if trust_result.value not in successes: + raise ssl.SSLError( + "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): + """ + Actually performs the TLS handshake. This is run automatically by + wrapped socket, and shouldn't be needed in user code. + """ + # First, we do the initial bits of connection setup. We need to create + # a context, set its I/O funcs, and set the connection reference. + self.context = Security.SSLCreateContext( + None, SecurityConst.kSSLClientSide, SecurityConst.kSSLStreamType + ) + result = Security.SSLSetIOFuncs( + self.context, _read_callback_pointer, _write_callback_pointer + ) + _assert_no_error(result) + + # Here we need to compute the handle to use. We do this by taking the + # id of self modulo 2**31 - 1. If this is already in the dictionary, we + # just keep incrementing by one until we find a free space. + with _connection_ref_lock: + handle = id(self) % 2147483647 + while handle in _connection_refs: + handle = (handle + 1) % 2147483647 + _connection_refs[handle] = self + + result = Security.SSLSetConnection(self.context, handle) + _assert_no_error(result) + + # 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') + + result = Security.SSLSetPeerDomainName( + self.context, server_hostname, len(server_hostname) + ) + _assert_no_error(result) + + # Setup the ciphers. + self._set_ciphers() + + # Set the minimum and maximum TLS versions. + result = Security.SSLSetProtocolVersionMin(self.context, min_version) + _assert_no_error(result) + result = Security.SSLSetProtocolVersionMax(self.context, max_version) + _assert_no_error(result) + + # If there's a trust DB, we need to use it. We do that by telling + # SecureTransport to break on server auth. We also do that if we don't + # want to validate the certs at all: we just won't actually do any + # authing in that case. + if not verify or trust_bundle is not None: + result = Security.SSLSetSessionOption( + self.context, + SecurityConst.kSSLSessionOptionBreakOnServerAuth, + True + ) + _assert_no_error(result) + + # If there's a client cert, we need to use it. + if client_cert: + self._keychain, self._keychain_dir = _temporary_keychain() + self._client_cert_chain = _load_client_cert_chain( + self._keychain, client_cert, client_key + ) + result = Security.SSLSetCertificate( + self.context, self._client_cert_chain + ) + _assert_no_error(result) + + while True: + with self._raise_on_error(): + result = Security.SSLHandshake(self.context) + + if result == SecurityConst.errSSLWouldBlock: + raise socket.timeout("handshake timed out") + elif result == SecurityConst.errSSLServerAuthCompleted: + self._custom_validate(verify, trust_bundle) + continue + else: + _assert_no_error(result) + break + + def fileno(self): + return self.socket.fileno() + + # Copy-pasted from Python 3.5 source code + def _decref_socketios(self): + if self._makefile_refs > 0: + self._makefile_refs -= 1 + if self._closed: + self.close() + + def recv(self, bufsiz): + buffer = ctypes.create_string_buffer(bufsiz) + bytes_read = self.recv_into(buffer, bufsiz) + data = buffer[:bytes_read] + return data + + def recv_into(self, buffer, nbytes=None): + # Read short on EOF. + if self._closed: + return 0 + + if nbytes is None: + nbytes = len(buffer) + + buffer = (ctypes.c_char * nbytes).from_buffer(buffer) + processed_bytes = ctypes.c_size_t(0) + + with self._raise_on_error(): + result = Security.SSLRead( + self.context, buffer, nbytes, ctypes.byref(processed_bytes) + ) + + # 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 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" + # and return. + if processed_bytes.value == 0: + # Timed out, no data read. + raise socket.timeout("recv timed out") + 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. + # It's unlikely though. + self.close() + else: + _assert_no_error(result) + + # Ok, we read and probably succeeded. We should return whatever data + # was actually read. + return processed_bytes.value + + def settimeout(self, timeout): + self._timeout = timeout + + def gettimeout(self): + return self._timeout + + def send(self, data): + processed_bytes = ctypes.c_size_t(0) + + with self._raise_on_error(): + result = Security.SSLWrite( + self.context, data, len(data), ctypes.byref(processed_bytes) + ) + + if result == SecurityConst.errSSLWouldBlock and processed_bytes.value == 0: + # Timed out + raise socket.timeout("send timed out") + else: + _assert_no_error(result) + + # We sent, and probably succeeded. Tell them how much we sent. + return processed_bytes.value + + def sendall(self, data): + total_sent = 0 + while total_sent < len(data): + sent = self.send(data[total_sent:total_sent + SSL_WRITE_BLOCKSIZE]) + total_sent += sent + + def shutdown(self): + with self._raise_on_error(): + Security.SSLClose(self.context) + + def close(self): + # TODO: should I do clean shutdown here? Do I have to? + if self._makefile_refs < 1: + self._closed = True + if self.context: + CoreFoundation.CFRelease(self.context) + self.context = None + if self._client_cert_chain: + CoreFoundation.CFRelease(self._client_cert_chain) + self._client_cert_chain = None + if self._keychain: + Security.SecKeychainDelete(self._keychain) + CoreFoundation.CFRelease(self._keychain) + shutil.rmtree(self._keychain_dir) + self._keychain = self._keychain_dir = None + return self.socket.close() + else: + self._makefile_refs -= 1 + + def getpeercert(self, binary_form=False): + # Urgh, annoying. + # + # Here's how we do this: + # + # 1. Call SSLCopyPeerTrust to get hold of the trust object for this + # connection. + # 2. Call SecTrustGetCertificateAtIndex for index 0 to get the leaf. + # 3. To get the CN, call SecCertificateCopyCommonName and process that + # string so that it's of the appropriate type. + # 4. To get the SAN, we need to do something a bit more complex: + # a. Call SecCertificateCopyValues to get the data, requesting + # kSecOIDSubjectAltName. + # b. Mess about with this dictionary to try to get the SANs out. + # + # This is gross. Really gross. It's going to be a few hundred LoC extra + # just to repeat something that SecureTransport can *already do*. So my + # operating assumption at this time is that what we want to do is + # 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" + ) + trust = Security.SecTrustRef() + certdata = None + der_bytes = None + + try: + # Grab the trust store. + 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. + return None + + cert_count = Security.SecTrustGetCertificateCount(trust) + if not cert_count: + # Also a case that might happen if we haven't handshaked. + # Handshook? Handshaken? + return None + + leaf = Security.SecTrustGetCertificateAtIndex(trust, 0) + assert leaf + + # Ok, now we want the DER bytes. + certdata = Security.SecCertificateCopyData(leaf) + assert certdata + + data_length = CoreFoundation.CFDataGetLength(certdata) + data_buffer = CoreFoundation.CFDataGetBytePtr(certdata) + der_bytes = ctypes.string_at(data_buffer, data_length) + finally: + if certdata: + CoreFoundation.CFRelease(certdata) + if trust: + CoreFoundation.CFRelease(trust) + + return der_bytes + + def _reuse(self): + self._makefile_refs += 1 + + def _drop(self): + if self._makefile_refs < 1: + self.close() + else: + self._makefile_refs -= 1 + + +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 + + +class SecureTransportContext(object): + """ + I am a wrapper class for the SecureTransport library, to translate the + 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 + self._verify = False + self._trust_bundle = None + self._client_cert = None + self._client_key = None + self._client_key_passphrase = None + + @property + def check_hostname(self): + """ + SecureTransport cannot have its hostname checking disabled. For more, + see the comment on getpeercert() in this file. + """ + return True + + @check_hostname.setter + def check_hostname(self, value): + """ + SecureTransport cannot have its hostname checking disabled. For more, + see the comment on getpeercert() in this file. + """ + pass + + @property + def options(self): + # TODO: Well, crap. + # + # So this is the bit of the code that is the most likely to cause us + # trouble. Essentially we need to enumerate all of the SSL options that + # users might want to use and try to see if we can sensibly translate + # them, or whether we should just ignore them. + return self._options + + @options.setter + def options(self, value): + # TODO: Update in line with above. + self._options = value + + @property + def verify_mode(self): + return ssl.CERT_REQUIRED if self._verify else ssl.CERT_NONE + + @verify_mode.setter + def verify_mode(self, value): + self._verify = True if value == ssl.CERT_REQUIRED else False + + def set_default_verify_paths(self): + # So, this has to do something a bit weird. Specifically, what it does + # is nothing. + # + # This means that, if we had previously had load_verify_locations + # called, this does not undo that. We need to do that because it turns + # out that the rest of the urllib3 code will attempt to load the + # default verify paths if it hasn't been told about any paths, even if + # the context itself was sometime earlier. We resolve that by just + # ignoring it. + pass + + def load_default_certs(self): + return self.set_default_verify_paths() + + 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" + ) + + 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" + ) + + self._trust_bundle = cafile or cadata + + def load_cert_chain(self, certfile, keyfile=None, password=None): + self._client_cert = certfile + 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): + # 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. + assert not server_side + assert do_handshake_on_connect + assert suppress_ragged_eofs + + # Ok, we're good to go. Now we want to create the wrapped socket object + # and store it in the appropriate place. + wrapped_socket = WrappedSocket(sock) + + # 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 + ) + return wrapped_socket diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/socks.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/socks.py new file mode 100644 index 0000000..811e312 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/socks.py @@ -0,0 +1,192 @@ +# -*- coding: utf-8 -*- +""" +This module contains provisional support for SOCKS proxies from within +urllib3. This module supports SOCKS4 (specifically the SOCKS4A variant) and +SOCKS5. To enable its functionality, either install PySocks or install this +module with the ``socks`` extra. + +The SOCKS implementation supports the full range of urllib3 features. It also +supports the following SOCKS features: + +- SOCKS4 +- SOCKS4a +- SOCKS5 +- Usernames and passwords for the SOCKS proxy + +Known Limitations: + +- Currently PySocks does not support contacting remote websites via literal + IPv6 addresses. Any such connection attempt will fail. You must use a domain + name. +- Currently PySocks does not support IPv6 connections to the SOCKS proxy. Any + such connection attempt will fail. +""" +from __future__ import absolute_import + +try: + import socks +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' + ), + DependencyWarning + ) + raise + +from socket import error as SocketError, timeout as SocketTimeout + +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 + +try: + import ssl +except ImportError: + ssl = None + + +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') + super(SOCKSConnection, self).__init__(*args, **kwargs) + + def _new_conn(self): + """ + Establish a new connection via the SOCKS proxy. + """ + extra_kw = {} + if self.source_address: + extra_kw['source_address'] = self.source_address + + if 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'], + timeout=self.timeout, + **extra_kw + ) + + except SocketTimeout as e: + raise ConnectTimeoutError( + 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 + # useful errors here. + if e.socket_err: + error = e.socket_err + if isinstance(error, SocketTimeout): + raise ConnectTimeoutError( + self, + "Connection to %s timed out. (connect timeout=%s)" % + (self.host, self.timeout) + ) + else: + raise NewConnectionError( + self, + "Failed to establish a new connection: %s" % error + ) + else: + raise NewConnectionError( + 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) + + return conn + + +# We don't need to duplicate the Verified/Unverified distinction from +# urllib3/connection.py here because the HTTPSConnection will already have been +# correctly set to either the Verified or Unverified form by that module. This +# means the SOCKSHTTPSConnection will automatically be the correct type. +class SOCKSHTTPSConnection(SOCKSConnection, HTTPSConnection): + pass + + +class SOCKSHTTPConnectionPool(HTTPConnectionPool): + ConnectionCls = SOCKSConnection + + +class SOCKSHTTPSConnectionPool(HTTPSConnectionPool): + ConnectionCls = SOCKSHTTPSConnection + + +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, + } + + 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(':') + if len(split) == 2: + username, password = split + if parsed.scheme == 'socks5': + socks_version = socks.PROXY_TYPE_SOCKS5 + rdns = False + elif parsed.scheme == 'socks5h': + socks_version = socks.PROXY_TYPE_SOCKS5 + rdns = True + elif parsed.scheme == 'socks4': + socks_version = socks.PROXY_TYPE_SOCKS4 + rdns = False + elif parsed.scheme == 'socks4a': + socks_version = socks.PROXY_TYPE_SOCKS4 + rdns = True + else: + 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 + } + connection_pool_kw['_socks_options'] = socks_options + + super(SOCKSProxyManager, self).__init__( + num_pools, headers, **connection_pool_kw + ) + + self.pool_classes_by_scheme = SOCKSProxyManager.pool_classes_by_scheme diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/exceptions.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/exceptions.py new file mode 100644 index 0000000..7bbaa98 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/exceptions.py @@ -0,0 +1,246 @@ +from __future__ import absolute_import +from .packages.six.moves.http_client import ( + IncompleteRead as httplib_IncompleteRead +) +# Base Exceptions + + +class HTTPError(Exception): + "Base exception used by this module." + pass + + +class HTTPWarning(Warning): + "Base warning used by this module." + pass + + +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)) + + def __reduce__(self): + # For pickling purposes. + return self.__class__, (None, None) + + +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) + + def __reduce__(self): + # For pickling purposes. + return self.__class__, (None, self.url, None) + + +class SSLError(HTTPError): + "Raised when SSL certificate fails in an HTTPS connection." + pass + + +class ProxyError(HTTPError): + "Raised when the connection to a proxy fails." + pass + + +class DecodeError(HTTPError): + "Raised when automatic decoding based on Content-Type fails." + pass + + +class ProtocolError(HTTPError): + "Raised when something unexpected happens mid-request/response." + pass + + +#: Renamed to ProtocolError but aliased for backwards compatibility. +ConnectionError = ProtocolError + + +# Leaf Exceptions + +class MaxRetryError(RequestError): + """Raised when the maximum number of retries is exceeded. + + :param pool: The connection pool + :type pool: :class:`~urllib3.connectionpool.HTTPConnectionPool` + :param string url: The requested Url + :param exceptions.Exception reason: The underlying error + + """ + + def __init__(self, pool, url, reason=None): + self.reason = reason + + message = "Max retries exceeded with url: %s (Caused by %r)" % ( + url, reason) + + RequestError.__init__(self, pool, url, message) + + +class HostChangedError(RequestError): + "Raised when an existing pool gets a request for a foreign host." + + def __init__(self, pool, url, retries=3): + message = "Tried to open a foreign host with url: %s" % url + RequestError.__init__(self, pool, url, message) + self.retries = retries + + +class TimeoutStateError(HTTPError): + """ Raised when passing an invalid state to a timeout """ + pass + + +class TimeoutError(HTTPError): + """ Raised when a socket timeout error occurs. + + Catching this error will catch both :exc:`ReadTimeoutErrors + <ReadTimeoutError>` and :exc:`ConnectTimeoutErrors <ConnectTimeoutError>`. + """ + pass + + +class ReadTimeoutError(TimeoutError, RequestError): + "Raised when a socket timeout occurs while receiving data from a server" + pass + + +# This timeout error does not have a URL attached and needs to inherit from the +# base HTTPError +class ConnectTimeoutError(TimeoutError): + "Raised when a socket timeout occurs while connecting to a server" + pass + + +class NewConnectionError(ConnectTimeoutError, PoolError): + "Raised when we fail to establish a new connection. Usually ECONNREFUSED." + pass + + +class EmptyPoolError(PoolError): + "Raised when a pool runs out of connections and no more are allowed." + pass + + +class ClosedPoolError(PoolError): + "Raised when a request enters a pool after the pool has been closed." + pass + + +class LocationValueError(ValueError, HTTPError): + "Raised when there is something wrong with a given URL input." + pass + + +class LocationParseError(LocationValueError): + "Raised when get_host or similar fails to parse the URL input." + + def __init__(self, location): + message = "Failed to parse: %s" % location + HTTPError.__init__(self, message) + + self.location = location + + +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' + + +class SecurityWarning(HTTPWarning): + "Warned when performing security reducing actions" + pass + + +class SubjectAltNameWarning(SecurityWarning): + "Warned when connecting to a host with a certificate missing a SAN." + pass + + +class InsecureRequestWarning(SecurityWarning): + "Warned when making an unverified HTTPS request." + pass + + +class SystemTimeWarning(SecurityWarning): + "Warned when system time is suspected to be wrong" + pass + + +class InsecurePlatformWarning(SecurityWarning): + "Warned when certain SSL configuration is not available on a platform." + pass + + +class SNIMissingWarning(HTTPWarning): + "Warned when making a HTTPS request without SNI available." + pass + + +class DependencyWarning(HTTPWarning): + """ + Warned when an attempt is made to import a module with missing optional + dependencies. + """ + pass + + +class ResponseNotChunked(ProtocolError, ValueError): + "Response needs to be chunked in order to read it as chunks." + pass + + +class BodyNotHttplibCompatible(HTTPError): + """ + Body should be httplib.HTTPResponse like (have an fp attribute which + returns raw chunks) for read_chunked(). + """ + pass + + +class IncompleteRead(HTTPError, httplib_IncompleteRead): + """ + Response length doesn't match expected Content-Length + + Subclass of http_client.IncompleteRead to allow int value + 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)) + + +class InvalidHeader(HTTPError): + "The header provided was somehow invalid." + pass + + +class ProxySchemeUnknown(AssertionError, ValueError): + "ProxyManager does not support the supplied scheme" + # TODO(t-8ch): Stop inheriting from AssertionError in v2.0. + + def __init__(self, scheme): + message = "Not supported proxy scheme %s" % scheme + super(ProxySchemeUnknown, self).__init__(message) + + +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) + super(HeaderParsingError, self).__init__(message) + + +class UnrewindableBodyError(HTTPError): + "urllib3 encountered an error when trying to rewind a body" + pass diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/fields.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/fields.py new file mode 100644 index 0000000..37fe64a --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/fields.py @@ -0,0 +1,178 @@ +from __future__ import absolute_import +import email.utils +import mimetypes + +from .packages import six + + +def guess_content_type(filename, default='application/octet-stream'): + """ + Guess the "Content-Type" of a file. + + :param filename: + The filename to guess the "Content-Type" of using :mod:`mimetypes`. + :param default: + If no "Content-Type" can be guessed, default to `default`. + """ + if filename: + return mimetypes.guess_type(filename)[0] or default + return default + + +def format_header_param(name, value): + """ + Helper function to format and quote a single header parameter. + + Particularly useful for header parameters which might contain + non-ASCII values, like file names. This follows RFC 2231, as + suggested by RFC 2388 Section 4.4. + + :param name: + The name of the parameter, a string expected to be ASCII only. + :param value: + The value of the parameter, provided as a unicode string. + """ + if not any(ch in value for ch in '"\\\r\n'): + result = '%s="%s"' % (name, value) + try: + result.encode('ascii') + except (UnicodeEncodeError, UnicodeDecodeError): + pass + else: + return result + if not six.PY3 and isinstance(value, six.text_type): # Python 2: + value = value.encode('utf-8') + value = email.utils.encode_rfc2231(value, 'utf-8') + value = '%s*=%s' % (name, value) + return value + + +class RequestField(object): + """ + A data container for request body parameters. + + :param name: + The name of this request field. + :param data: + The data/value body. + :param filename: + An optional filename of the request field. + :param headers: + An optional dict-like object of headers to initially use for the field. + """ + def __init__(self, name, data, filename=None, headers=None): + self._name = name + self._filename = filename + self.data = data + self.headers = {} + if headers: + self.headers = dict(headers) + + @classmethod + def from_tuples(cls, fieldname, value): + """ + A :class:`~urllib3.fields.RequestField` factory from old-style tuple parameters. + + Supports constructing :class:`~urllib3.fields.RequestField` from + parameter of key/value strings AND key/filetuple. A filetuple is a + (filename, data, MIME type) tuple where the MIME type is optional. + For example:: + + 'foo': 'bar', + 'fakefile': ('foofile.txt', 'contents of foofile'), + 'realfile': ('barfile.txt', open('realfile').read()), + 'typedfile': ('bazfile.bin', open('bazfile').read(), 'image/jpeg'), + 'nonamefile': 'contents of nonamefile field', + + Field names and filenames must be unicode. + """ + if isinstance(value, tuple): + if len(value) == 3: + filename, data, content_type = value + else: + filename, data = value + content_type = guess_content_type(filename) + else: + filename = None + content_type = None + data = value + + request_param = cls(fieldname, data, filename=filename) + request_param.make_multipart(content_type=content_type) + + return request_param + + def _render_part(self, name, value): + """ + Overridable helper function to format a single header parameter. + + :param name: + The name of the parameter, a string expected to be ASCII only. + :param value: + The value of the parameter, provided as a unicode string. + """ + return format_header_param(name, value) + + def _render_parts(self, header_parts): + """ + Helper function to format and quote a single header. + + Useful for single headers that are composed of multiple items. E.g., + 'Content-Disposition' fields. + + :param header_parts: + A sequence of (k, v) tuples or a :class:`dict` of (k, v) to format + as `k1="v1"; k2="v2"; ...`. + """ + parts = [] + iterable = header_parts + if isinstance(header_parts, dict): + iterable = header_parts.items() + + for name, value in iterable: + if value is not None: + parts.append(self._render_part(name, value)) + + return '; '.join(parts) + + def render_headers(self): + """ + Renders the headers for this request field. + """ + lines = [] + + sort_keys = ['Content-Disposition', 'Content-Type', 'Content-Location'] + for sort_key in sort_keys: + if self.headers.get(sort_key, False): + lines.append('%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('%s: %s' % (header_name, header_value)) + + lines.append('\r\n') + return '\r\n'.join(lines) + + def make_multipart(self, content_disposition=None, content_type=None, + content_location=None): + """ + Makes this request field into a multipart request field. + + This method overrides "Content-Disposition", "Content-Type" and + "Content-Location" headers to the request parameter. + + :param content_type: + The 'Content-Type' of the request body. + :param content_location: + The 'Content-Location' of the request body. + + """ + self.headers['Content-Disposition'] = content_disposition or 'form-data' + self.headers['Content-Disposition'] += '; '.join([ + '', self._render_parts( + (('name', self._name), ('filename', self._filename)) + ) + ]) + self.headers['Content-Type'] = content_type + self.headers['Content-Location'] = content_location diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/filepost.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/filepost.py new file mode 100644 index 0000000..78f1e19 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/filepost.py @@ -0,0 +1,98 @@ +from __future__ import absolute_import +import binascii +import codecs +import os + +from io import BytesIO + +from .packages import six +from .packages.six import b +from .fields import RequestField + +writer = codecs.lookup('utf-8')[3] + + +def choose_boundary(): + """ + Our embarrassingly-simple replacement for mimetools.choose_boundary. + """ + boundary = binascii.hexlify(os.urandom(16)) + if six.PY3: + boundary = boundary.decode('ascii') + return boundary + + +def iter_field_objects(fields): + """ + Iterate over fields. + + Supports list of (k, v) tuples and dicts, and lists of + :class:`~urllib3.fields.RequestField`. + + """ + if isinstance(fields, dict): + i = six.iteritems(fields) + else: + i = iter(fields) + + for field in i: + if isinstance(field, RequestField): + yield field + else: + yield RequestField.from_tuples(*field) + + +def iter_fields(fields): + """ + .. deprecated:: 1.6 + + Iterate over fields. + + The addition of :class:`~urllib3.fields.RequestField` makes this function + obsolete. Instead, use :func:`iter_field_objects`, which returns + :class:`~urllib3.fields.RequestField` objects. + + Supports list of (k, v) tuples and dicts. + """ + if isinstance(fields, dict): + return ((k, v) for k, v in six.iteritems(fields)) + + return ((k, v) for k, v in fields) + + +def encode_multipart_formdata(fields, boundary=None): + """ + Encode a dictionary of ``fields`` using the multipart/form-data MIME format. + + :param fields: + Dictionary of fields or list of (key, :class:`~urllib3.fields.RequestField`). + + :param boundary: + If not specified, then a random boundary will be generated using + :func:`urllib3.filepost.choose_boundary`. + """ + body = BytesIO() + if boundary is None: + boundary = choose_boundary() + + for field in iter_field_objects(fields): + body.write(b('--%s\r\n' % (boundary))) + + writer(body).write(field.render_headers()) + data = field.data + + if isinstance(data, int): + data = str(data) # Backwards compatibility + + if isinstance(data, six.text_type): + writer(body).write(data) + else: + body.write(data) + + body.write(b'\r\n') + + body.write(b('--%s--\r\n' % (boundary))) + + content_type = str('multipart/form-data; boundary=%s' % boundary) + + return body.getvalue(), content_type diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__init__.py new file mode 100644 index 0000000..170e974 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__init__.py @@ -0,0 +1,5 @@ +from __future__ import absolute_import + +from . import ssl_match_hostname + +__all__ = ('ssl_match_hostname', ) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f0d6bf5b78639c09a5294aed76d7815a0a8e50f7 GIT binary patch literal 322 zcmXv}%SyyB6iwO=4#NzBTQ_dI7&BT_21LXUaHFdtT+$|O<0Ng!qiVmwAMuyEbv3`> z%5=m7=iYNJm-~2FtrjTY^R#$TA%9QiA5jqZf%Yr}h8UJe;T&VcA{NU?#d#cboF^=K zLg{QDx=@P8V_MiwddER1-5IyXfAte<B`E632Aa;gmMZ?3&c+2m<()Siz)TxQWRfWz z0Z=IczL1#*e+WMV(MI&tane&ms!lR)EKv<9FEnh2?d#?(tJq+#v))|3yFqON>Xtkc zE%aKn)`gkttDB<P`J$eR2SU$V)*0fBl%mLprsa;-+!6rM3I}kmKgRj3>X?`OZu-Yg JH!h=P^a}zOS^oe4 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__pycache__/ordered_dict.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__pycache__/ordered_dict.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ade18babcd3ca76c7602a0051f0573fc95fe6997 GIT binary patch literal 8416 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d8ccfd67568ac10b1d06f3be067be38ae56e01a2 GIT binary patch literal 24410 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b350186730b76907231fb356a7b8c551fd63d1f2 GIT binary patch literal 219 zcmZ?b<>g`kf*$Fl7!ds!M8E(ekl_Ht#VkM~g&~+hlhJP_LlH<ALHugbFDS|^ODsv% zFH0=aPs`6qNi8bY&&|+JHY|v@tg_59C^t?^sVX)zE-NysD5=Ud0D|;9{Sf_v%mUra zyyB9?oE%+K^Q4UI(xh~dAQ;D&rRJsN7wMN4<>X{08S57$CTAz6rxxoc0T~7PMJ2`h f@$s2?nI-Y@dIgoYIBatBQ%ZAE?Le+824V&P)jK?s literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..428499445b5717cdbf655f97f5327346d7633989 GIT binary patch literal 1317 zcmZuxPmkL~6rZsj+j0J=l&TjFOe<Issf|llWhp|41~$@4Xj?T~R*Dc_J2Ot4ICeBM zNxIR51KT6w6M#gI+&I9u=qH#17bK+p3cbLyvxzFfvu5VK-@JK$XWVHtJOuQ^JJC0P zR1o^B5Viy|`W%MXgNdR(qL>;f?qgWZ)R>xm6C>)-3bkM0zD125YPqYQy(k<^W;vIl zJq;%;PEzK5_aE}S&Q^`c5hG8|<tWd{J~=xR`C!82?(o?enKIa<B+faR3r3cS9FZ`C z6G=9N)1ma1VI~EUIT>&kN=8C*I|k>s$;KGTqcI!Ews#4spyL+SZm;xm^jKp)unQEZ z0i)o*fFW*Rgd|e<0?RUUY7Wf{Ji+2UiK(S<jBla~{5{k};fcMrDK6I8$I7mwwWA!- zRkr9#12oK1!=;sVRXO}yRi*d<0dMm$@J7K)Qz2EoFxH+z78+aBK0pQvEM-t<;_@G< zyEcHYP7wb|R>t;~WbogWD}IBBydoCm^$>V?1(sjQ$}f)c;4@yD>sq!4_@98eC1L<_ z1LFI;h!4=}7F8~Pt!h04n5SyWRF<l|wAOWnRXwPwI`p`<`otqZ+Xj+6{@<>}JfH6R z+J4Y34{;M}tMO9fXtkGQi!e<nndX#{_c{3>&(d?k?~vsk5|J=X^ChD#jV_@T==ky< zAYQPmTk|ZM$1&rK5+R}GQ$eP4AxXqYlw=`4Z`HLanAG0aVLE4roabCO9|^&@O!BOh zxdEp7&0u>=1I}WhjU?A^e|gw_^z5sXp!2NTJ$xGUj{1kX*}3xg^z=!XfVG{>LdxEd zPkACiZk({^^62p?4`(wFts==*LtBESF~43^p}NTdF0po5Hppqg*{q0FXeVRKG|8BD zmSC^gaUjo)$|gks!ewDqo4{y$V@+EU{QipgyWryW3xCFw1-uA<5pqAyQ;1af(~&>; za27mVJsjU#?#FZ`KH6XK`_JWSdJkxr`6vD?ncYn?A)yO*9~?xZ$vhesU^#*X%V^I1 zIZx9h+V^Mhmct<v{_gGj+p4x_=lZQJysLE+f)gE>P~|2zaNTfm6W6heE%=Jr#U3CV z&c0d;^cw6nLAzdRUc)x#x4=rPQeLcMpjJgYK|u3C5b!!|X?ybzDBE2sm!)}QB88Uw UDU@=avd>(QL@|Loqi!PnFE3_+4FCWD literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py new file mode 100644 index 0000000..75b80dc --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +""" +backports.makefile +~~~~~~~~~~~~~~~~~~ + +Backports the Python 3 ``socket.makefile`` method for use with anything that +wants to create a "fake" socket object. +""" +import io + +from socket import SocketIO + + +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) <= set(["r", "w", "b"]): + 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 + binary = "b" in mode + rawmode = "" + if reading: + rawmode += "r" + if writing: + rawmode += "w" + raw = SocketIO(self, rawmode) + self._makefile_refs += 1 + if buffering is None: + buffering = -1 + if buffering < 0: + buffering = io.DEFAULT_BUFFER_SIZE + if buffering == 0: + if not binary: + raise ValueError("unbuffered streams must be binary") + return raw + if reading and writing: + buffer = io.BufferedRWPair(raw, raw, buffering) + elif reading: + buffer = io.BufferedReader(raw, buffering) + else: + assert writing + buffer = io.BufferedWriter(raw, buffering) + if binary: + return buffer + text = io.TextIOWrapper(buffer, encoding, errors, newline) + text.mode = mode + return text diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ordered_dict.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ordered_dict.py new file mode 100644 index 0000000..4479363 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ordered_dict.py @@ -0,0 +1,259 @@ +# Backport of OrderedDict() class that runs on Python 2.4, 2.5, 2.6, 2.7 and pypy. +# Passes Python2.7's test suite and incorporates all the latest updates. +# Copyright 2009 Raymond Hettinger, released under the MIT License. +# http://code.activestate.com/recipes/576693/ +try: + from thread import get_ident as _get_ident +except ImportError: + from dummy_thread import get_ident as _get_ident + +try: + from _abcoll import KeysView, ValuesView, ItemsView +except ImportError: + pass + + +class OrderedDict(dict): + 'Dictionary that remembers insertion order' + # An inherited dict maps keys to values. + # The inherited dict provides __getitem__, __len__, __contains__, and get. + # The remaining methods are order-aware. + # Big-O running times for all methods are the same as for regular dictionaries. + + # The internal self.__map dictionary maps keys to links in a doubly linked list. + # The circular doubly linked list starts and ends with a sentinel element. + # The sentinel element never gets deleted (this simplifies the algorithm). + # Each link is stored as a list of length three: [PREV, NEXT, KEY]. + + def __init__(self, *args, **kwds): + '''Initialize an ordered dictionary. Signature is the same as for + regular dictionaries, but keyword arguments are not recommended + because their insertion order is arbitrary. + + ''' + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + try: + self.__root + except AttributeError: + self.__root = root = [] # sentinel node + root[:] = [root, root, None] + self.__map = {} + self.__update(*args, **kwds) + + def __setitem__(self, key, value, dict_setitem=dict.__setitem__): + 'od.__setitem__(i, y) <==> od[i]=y' + # Setting a new item creates a new link which goes at the end of the linked + # list, and the inherited dictionary is updated with the new key/value pair. + if key not in self: + root = self.__root + last = root[0] + last[1] = root[0] = self.__map[key] = [last, root, key] + dict_setitem(self, key, value) + + def __delitem__(self, key, dict_delitem=dict.__delitem__): + 'od.__delitem__(y) <==> del od[y]' + # Deleting an existing item uses self.__map to find the link which is + # then removed by updating the links in the predecessor and successor nodes. + dict_delitem(self, key) + link_prev, link_next, key = self.__map.pop(key) + link_prev[1] = link_next + link_next[0] = link_prev + + def __iter__(self): + 'od.__iter__() <==> iter(od)' + root = self.__root + curr = root[1] + while curr is not root: + yield curr[2] + curr = curr[1] + + def __reversed__(self): + 'od.__reversed__() <==> reversed(od)' + root = self.__root + curr = root[0] + while curr is not root: + yield curr[2] + curr = curr[0] + + def clear(self): + 'od.clear() -> None. Remove all items from od.' + try: + for node in self.__map.itervalues(): + del node[:] + root = self.__root + root[:] = [root, root, None] + self.__map.clear() + except AttributeError: + pass + dict.clear(self) + + def popitem(self, last=True): + '''od.popitem() -> (k, v), return and remove a (key, value) pair. + Pairs are returned in LIFO order if last is true or FIFO order if false. + + ''' + if not self: + raise KeyError('dictionary is empty') + root = self.__root + if last: + link = root[0] + link_prev = link[0] + link_prev[1] = root + root[0] = link_prev + else: + link = root[1] + link_next = link[1] + root[1] = link_next + link_next[0] = root + key = link[2] + del self.__map[key] + value = dict.pop(self, key) + return key, value + + # -- the following methods do not depend on the internal structure -- + + def keys(self): + 'od.keys() -> list of keys in od' + return list(self) + + def values(self): + 'od.values() -> list of values in od' + return [self[key] for key in self] + + def items(self): + 'od.items() -> list of (key, value) pairs in od' + return [(key, self[key]) for key in self] + + def iterkeys(self): + 'od.iterkeys() -> an iterator over the keys in od' + return iter(self) + + def itervalues(self): + 'od.itervalues -> an iterator over the values in od' + for k in self: + yield self[k] + + def iteritems(self): + 'od.iteritems -> an iterator over the (key, value) items in od' + for k in self: + yield (k, self[k]) + + def update(*args, **kwds): + '''od.update(E, **F) -> None. Update od from dict/iterable E and F. + + If E is a dict instance, does: for k in E: od[k] = E[k] + If E has a .keys() method, does: for k in E.keys(): od[k] = E[k] + Or if E is an iterable of items, does: for k, v in E: od[k] = v + In either case, this is followed by: for k, v in F.items(): od[k] = v + + ''' + if len(args) > 2: + raise TypeError('update() takes at most 2 positional ' + 'arguments (%d given)' % (len(args),)) + elif not args: + raise TypeError('update() takes at least 1 argument (0 given)') + self = args[0] + # Make progressively weaker assumptions about "other" + other = () + if len(args) == 2: + other = args[1] + if isinstance(other, dict): + for key in other: + self[key] = other[key] + elif hasattr(other, 'keys'): + for key in other.keys(): + self[key] = other[key] + else: + for key, value in other: + self[key] = value + for key, value in kwds.items(): + self[key] = value + + __update = update # let subclasses override update without breaking __init__ + + __marker = object() + + def pop(self, key, default=__marker): + '''od.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. + + ''' + if key in self: + result = self[key] + del self[key] + return result + if default is self.__marker: + raise KeyError(key) + return default + + def setdefault(self, key, default=None): + 'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od' + if key in self: + return self[key] + self[key] = default + return default + + def __repr__(self, _repr_running={}): + 'od.__repr__() <==> repr(od)' + call_key = id(self), _get_ident() + if call_key in _repr_running: + return '...' + _repr_running[call_key] = 1 + try: + if not self: + return '%s()' % (self.__class__.__name__,) + return '%s(%r)' % (self.__class__.__name__, self.items()) + finally: + del _repr_running[call_key] + + def __reduce__(self): + 'Return state information for pickling' + items = [[k, self[k]] for k in self] + inst_dict = vars(self).copy() + for k in vars(OrderedDict()): + inst_dict.pop(k, None) + if inst_dict: + return (self.__class__, (items,), inst_dict) + return self.__class__, (items,) + + def copy(self): + 'od.copy() -> a shallow copy of od' + return self.__class__(self) + + @classmethod + def fromkeys(cls, iterable, value=None): + '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S + and values equal to v (which defaults to None). + + ''' + d = cls() + for key in iterable: + d[key] = value + return d + + def __eq__(self, other): + '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive + while comparison to a regular mapping is order-insensitive. + + ''' + if isinstance(other, OrderedDict): + return len(self)==len(other) and self.items() == other.items() + return dict.__eq__(self, other) + + def __ne__(self, other): + return not self == other + + # -- the following methods are only used in Python 2.7 -- + + def viewkeys(self): + "od.viewkeys() -> a set-like object providing a view on od's keys" + return KeysView(self) + + def viewvalues(self): + "od.viewvalues() -> an object providing a view on od's values" + return ValuesView(self) + + def viewitems(self): + "od.viewitems() -> a set-like object providing a view on od's items" + return ItemsView(self) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/six.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/six.py new file mode 100644 index 0000000..190c023 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/six.py @@ -0,0 +1,868 @@ +"""Utilities for writing code that runs on Python 2 and 3""" + +# Copyright (c) 2010-2015 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 +# 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. + +from __future__ import absolute_import + +import functools +import itertools +import operator +import sys +import types + +__author__ = "Benjamin Peterson <benjamin@python.org>" +__version__ = "1.10.0" + + +# Useful for very coarse version differentiation. +PY2 = sys.version_info[0] == 2 +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, + text_type = str + binary_type = bytes + + MAXSIZE = sys.maxsize +else: + string_types = basestring, + integer_types = (int, long) + class_types = (type, types.ClassType) + text_type = unicode + binary_type = str + + if sys.platform.startswith("java"): + # Jython always uses 32 bits. + MAXSIZE = int((1 << 31) - 1) + 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: + # 32-bit + MAXSIZE = int((1 << 31) - 1) + else: + # 64-bit + MAXSIZE = int((1 << 63) - 1) + del X + + +def _add_doc(func, doc): + """Add documentation to a function.""" + func.__doc__ = doc + + +def _import_module(name): + """Import module, returning the module after the last dot.""" + __import__(name) + return sys.modules[name] + + +class _LazyDescr(object): + + def __init__(self, name): + self.name = name + + def __get__(self, obj, tp): + result = self._resolve() + setattr(obj, self.name, result) # Invokes __set__. + try: + # This is a bit ugly, but it avoids running this again by + # removing this descriptor. + delattr(obj.__class__, self.name) + except AttributeError: + pass + return result + + +class MovedModule(_LazyDescr): + + def __init__(self, name, old, new=None): + super(MovedModule, self).__init__(name) + if PY3: + if new is None: + new = name + self.mod = new + else: + self.mod = old + + def _resolve(self): + return _import_module(self.mod) + + def __getattr__(self, attr): + _module = self._resolve() + value = getattr(_module, attr) + setattr(self, attr, value) + return value + + +class _LazyModule(types.ModuleType): + + def __init__(self, name): + super(_LazyModule, self).__init__(name) + self.__doc__ = self.__class__.__doc__ + + def __dir__(self): + attrs = ["__doc__", "__name__"] + attrs += [attr.name for attr in self._moved_attributes] + return attrs + + # Subclasses should override this + _moved_attributes = [] + + +class MovedAttribute(_LazyDescr): + + def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): + super(MovedAttribute, self).__init__(name) + if PY3: + if new_mod is None: + new_mod = name + self.mod = new_mod + if new_attr is None: + if old_attr is None: + new_attr = name + else: + new_attr = old_attr + self.attr = new_attr + else: + self.mod = old_mod + if old_attr is None: + old_attr = name + self.attr = old_attr + + def _resolve(self): + module = _import_module(self.mod) + return getattr(module, self.attr) + + +class _SixMetaPathImporter(object): + + """ + A meta path importer to import six.moves and its submodules. + + This class implements a PEP302 finder and loader. It should be compatible + with Python 2.5 and all existing versions of Python3 + """ + + def __init__(self, six_module_name): + self.name = six_module_name + self.known_modules = {} + + def _add_module(self, mod, *fullnames): + for fullname in fullnames: + self.known_modules[self.name + "." + fullname] = mod + + def _get_module(self, fullname): + return self.known_modules[self.name + "." + fullname] + + def find_module(self, fullname, path=None): + if fullname in self.known_modules: + return self + return None + + def __get_module(self, fullname): + try: + return self.known_modules[fullname] + except KeyError: + raise ImportError("This loader does not know module " + fullname) + + def load_module(self, fullname): + try: + # in case of a reload + return sys.modules[fullname] + except KeyError: + pass + mod = self.__get_module(fullname) + if isinstance(mod, MovedModule): + mod = mod._resolve() + else: + mod.__loader__ = self + sys.modules[fullname] = mod + return mod + + def is_package(self, fullname): + """ + Return true, if the named module is a package. + + We need this method to get correct spec objects with + Python 3.4 (see PEP451) + """ + return hasattr(self.__get_module(fullname), "__path__") + + def get_code(self, fullname): + """Return None + + 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("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("range", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"), + MovedAttribute("reduce", "__builtin__", "functools"), + MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), + MovedAttribute("StringIO", "StringIO", "io"), + MovedAttribute("UserDict", "UserDict", "collections"), + MovedAttribute("UserList", "UserList", "collections"), + 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"), + MovedModule("builtins", "__builtin__"), + MovedModule("configparser", "ConfigParser"), + MovedModule("copyreg", "copy_reg"), + MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), + MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"), + MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), + MovedModule("http_cookies", "Cookie", "http.cookies"), + 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("BaseHTTPServer", "BaseHTTPServer", "http.server"), + MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), + MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), + MovedModule("cPickle", "cPickle", "pickle"), + MovedModule("queue", "Queue"), + MovedModule("reprlib", "repr"), + MovedModule("socketserver", "SocketServer"), + MovedModule("_thread", "thread", "_thread"), + MovedModule("tkinter", "Tkinter"), + MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), + MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), + MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), + MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), + MovedModule("tkinter_tix", "Tix", "tkinter.tix"), + 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_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), + MovedModule("tkinter_font", "tkFont", "tkinter.font"), + MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), + 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"), + MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), + MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), + MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"), +] +# Add windows specific modules. +if sys.platform == "win32": + _moved_attributes += [ + MovedModule("winreg", "_winreg"), + ] + +for attr in _moved_attributes: + setattr(_MovedItems, attr.name, attr) + if isinstance(attr, MovedModule): + _importer._add_module(attr, "moves." + attr.name) +del attr + +_MovedItems._moved_attributes = _moved_attributes + +moves = _MovedItems(__name__ + ".moves") +_importer._add_module(moves, "moves") + + +class Module_six_moves_urllib_parse(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_parse""" + + +_urllib_parse_moved_attributes = [ + MovedAttribute("ParseResult", "urlparse", "urllib.parse"), + MovedAttribute("SplitResult", "urlparse", "urllib.parse"), + MovedAttribute("parse_qs", "urlparse", "urllib.parse"), + MovedAttribute("parse_qsl", "urlparse", "urllib.parse"), + MovedAttribute("urldefrag", "urlparse", "urllib.parse"), + MovedAttribute("urljoin", "urlparse", "urllib.parse"), + MovedAttribute("urlparse", "urlparse", "urllib.parse"), + MovedAttribute("urlsplit", "urlparse", "urllib.parse"), + MovedAttribute("urlunparse", "urlparse", "urllib.parse"), + MovedAttribute("urlunsplit", "urlparse", "urllib.parse"), + MovedAttribute("quote", "urllib", "urllib.parse"), + MovedAttribute("quote_plus", "urllib", "urllib.parse"), + MovedAttribute("unquote", "urllib", "urllib.parse"), + MovedAttribute("unquote_plus", "urllib", "urllib.parse"), + MovedAttribute("urlencode", "urllib", "urllib.parse"), + MovedAttribute("splitquery", "urllib", "urllib.parse"), + MovedAttribute("splittag", "urllib", "urllib.parse"), + MovedAttribute("splituser", "urllib", "urllib.parse"), + MovedAttribute("uses_fragment", "urlparse", "urllib.parse"), + MovedAttribute("uses_netloc", "urlparse", "urllib.parse"), + MovedAttribute("uses_params", "urlparse", "urllib.parse"), + MovedAttribute("uses_query", "urlparse", "urllib.parse"), + MovedAttribute("uses_relative", "urlparse", "urllib.parse"), +] +for attr in _urllib_parse_moved_attributes: + setattr(Module_six_moves_urllib_parse, attr.name, attr) +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") + + +class Module_six_moves_urllib_error(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_error""" + + +_urllib_error_moved_attributes = [ + MovedAttribute("URLError", "urllib2", "urllib.error"), + MovedAttribute("HTTPError", "urllib2", "urllib.error"), + MovedAttribute("ContentTooShortError", "urllib", "urllib.error"), +] +for attr in _urllib_error_moved_attributes: + setattr(Module_six_moves_urllib_error, attr.name, attr) +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") + + +class Module_six_moves_urllib_request(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_request""" + + +_urllib_request_moved_attributes = [ + MovedAttribute("urlopen", "urllib2", "urllib.request"), + MovedAttribute("install_opener", "urllib2", "urllib.request"), + MovedAttribute("build_opener", "urllib2", "urllib.request"), + MovedAttribute("pathname2url", "urllib", "urllib.request"), + MovedAttribute("url2pathname", "urllib", "urllib.request"), + MovedAttribute("getproxies", "urllib", "urllib.request"), + MovedAttribute("Request", "urllib2", "urllib.request"), + MovedAttribute("OpenerDirector", "urllib2", "urllib.request"), + MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"), + MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), + MovedAttribute("BaseHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), + MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"), + MovedAttribute("FileHandler", "urllib2", "urllib.request"), + MovedAttribute("FTPHandler", "urllib2", "urllib.request"), + MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"), + MovedAttribute("UnknownHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"), + MovedAttribute("urlretrieve", "urllib", "urllib.request"), + MovedAttribute("urlcleanup", "urllib", "urllib.request"), + MovedAttribute("URLopener", "urllib", "urllib.request"), + MovedAttribute("FancyURLopener", "urllib", "urllib.request"), + MovedAttribute("proxy_bypass", "urllib", "urllib.request"), +] +for attr in _urllib_request_moved_attributes: + setattr(Module_six_moves_urllib_request, attr.name, attr) +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") + + +class Module_six_moves_urllib_response(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_response""" + + +_urllib_response_moved_attributes = [ + MovedAttribute("addbase", "urllib", "urllib.response"), + MovedAttribute("addclosehook", "urllib", "urllib.response"), + MovedAttribute("addinfo", "urllib", "urllib.response"), + MovedAttribute("addinfourl", "urllib", "urllib.response"), +] +for attr in _urllib_response_moved_attributes: + setattr(Module_six_moves_urllib_response, attr.name, attr) +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") + + +class Module_six_moves_urllib_robotparser(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_robotparser""" + + +_urllib_robotparser_moved_attributes = [ + 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 + +_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") + request = _importer._get_module("moves.urllib_request") + response = _importer._get_module("moves.urllib_response") + robotparser = _importer._get_module("moves.urllib_robotparser") + + def __dir__(self): + return ['parse', 'error', 'request', 'response', 'robotparser'] + +_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"), + "moves.urllib") + + +def add_move(move): + """Add an item to six.moves.""" + setattr(_MovedItems, move.name, move) + + +def remove_move(name): + """Remove item from six.moves.""" + try: + delattr(_MovedItems, name) + except AttributeError: + try: + del moves.__dict__[name] + except KeyError: + raise AttributeError("no such move, %r" % (name,)) + + +if PY3: + _meth_func = "__func__" + _meth_self = "__self__" + + _func_closure = "__closure__" + _func_code = "__code__" + _func_defaults = "__defaults__" + _func_globals = "__globals__" +else: + _meth_func = "im_func" + _meth_self = "im_self" + + _func_closure = "func_closure" + _func_code = "func_code" + _func_defaults = "func_defaults" + _func_globals = "func_globals" + + +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 + + create_bound_method = types.MethodType + + def create_unbound_method(func, cls): + return func + + Iterator = object +else: + def get_unbound_function(unbound): + return unbound.im_func + + def create_bound_method(func, obj): + return types.MethodType(func, obj, obj.__class__) + + def create_unbound_method(func, cls): + 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""") + + +get_method_function = operator.attrgetter(_meth_func) +get_method_self = operator.attrgetter(_meth_self) +get_function_closure = operator.attrgetter(_func_closure) +get_function_code = operator.attrgetter(_func_code) +get_function_defaults = operator.attrgetter(_func_defaults) +get_function_globals = operator.attrgetter(_func_globals) + + +if PY3: + def iterkeys(d, **kw): + return iter(d.keys(**kw)) + + def itervalues(d, **kw): + return iter(d.values(**kw)) + + def iteritems(d, **kw): + return iter(d.items(**kw)) + + def iterlists(d, **kw): + return iter(d.lists(**kw)) + + viewkeys = operator.methodcaller("keys") + + viewvalues = operator.methodcaller("values") + + viewitems = operator.methodcaller("items") +else: + def iterkeys(d, **kw): + return d.iterkeys(**kw) + + def itervalues(d, **kw): + return d.itervalues(**kw) + + def iteritems(d, **kw): + return d.iteritems(**kw) + + def iterlists(d, **kw): + return d.iterlists(**kw) + + viewkeys = operator.methodcaller("viewkeys") + + viewvalues = operator.methodcaller("viewvalues") + + viewitems = operator.methodcaller("viewitems") + +_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.") + + +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 + _assertCountEqual = "assertCountEqual" + if sys.version_info[1] <= 1: + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" + else: + _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") + unichr = unichr + int2byte = chr + + def byte2int(bs): + return ord(bs[0]) + + def indexbytes(buf, i): + return ord(buf[i]) + iterbytes = functools.partial(itertools.imap, ord) + import StringIO + StringIO = BytesIO = StringIO.StringIO + _assertCountEqual = "assertItemsEqual" + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" +_add_doc(b, """Byte literal""") +_add_doc(u, """Text literal""") + + +def assertCountEqual(self, *args, **kwargs): + return getattr(self, _assertCountEqual)(*args, **kwargs) + + +def assertRaisesRegex(self, *args, **kwargs): + return getattr(self, _assertRaisesRegex)(*args, **kwargs) + + +def assertRegex(self, *args, **kwargs): + return getattr(self, _assertRegex)(*args, **kwargs) + + +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 + +else: + def exec_(_code_, _globs_=None, _locs_=None): + """Execute code in a namespace.""" + if _globs_ is None: + frame = sys._getframe(1) + _globs_ = frame.f_globals + if _locs_ is None: + _locs_ = frame.f_locals + del frame + elif _locs_ is None: + _locs_ = _globs_ + exec("""exec _code_ in _globs_, _locs_""") + + exec_("""def reraise(tp, value, tb=None): + raise tp, value, tb +""") + + +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 +""") +elif sys.version_info[:2] > (3, 2): + exec_("""def raise_from(value, from_value): + raise value from from_value +""") +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) + if fp is None: + return + + def write(data): + 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): + 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: + if isinstance(sep, unicode): + want_unicode = True + elif not isinstance(sep, str): + raise TypeError("sep must be None or a string") + end = kwargs.pop("end", None) + if end is not None: + if isinstance(end, unicode): + want_unicode = True + elif not isinstance(end, str): + raise TypeError("end must be None or a string") + if kwargs: + raise TypeError("invalid keyword arguments to print()") + if not want_unicode: + for arg in args: + if isinstance(arg, unicode): + want_unicode = True + break + if want_unicode: + newline = unicode("\n") + space = unicode(" ") + else: + newline = "\n" + space = " " + if sep is None: + sep = space + if end is None: + end = newline + for i, arg in enumerate(args): + if i: + write(sep) + write(arg) + write(end) +if sys.version_info[:2] < (3, 3): + _print = print_ + + def print_(*args, **kwargs): + fp = kwargs.get("file", sys.stdout) + flush = kwargs.pop("flush", False) + _print(*args, **kwargs) + 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 wrapper(f): + f = functools.wraps(wrapped, assigned, updated)(f) + f.__wrapped__ = wrapped + return f + return wrapper +else: + wraps = functools.wraps + + +def with_metaclass(meta, *bases): + """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): + + def __new__(cls, name, this_bases, d): + return meta(name, bases, d) + 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__') + 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) + return metaclass(cls.__name__, cls.__bases__, orig_vars) + return wrapper + + +def python_2_unicode_compatible(klass): + """ + A 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 + 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__) + klass.__unicode__ = klass.__str__ + klass.__str__ = lambda self: self.__unicode__().encode('utf-8') + return klass + + +# Complete the moves implementation. +# This code is at the end of this module to speed up module loading. +# Turn this module into a package. +__path__ = [] # required for PEP 302 and PEP 451 +__package__ = __name__ # see PEP 366 @ReservedAssignment +if globals().get("__spec__") is not None: + __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable +# Remove other six meta path importers, since they cause problems. This can +# happen if six is removed from sys.modules and then reloaded. (Setuptools does +# this for some reason.) +if sys.meta_path: + for i, importer in enumerate(sys.meta_path): + # Here's some real nastiness: Another "instance" of the six module might + # 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__): + del sys.meta_path[i] + break + del i, importer +# Finally, add the importer to the meta path import hook. +sys.meta_path.append(_importer) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py new file mode 100644 index 0000000..d6594eb --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py @@ -0,0 +1,19 @@ +import sys + +try: + # Our match_hostname function is the same as 3.5's, so we only want to + # import the match_hostname function if it's at least that good. + if sys.version_info < (3, 5): + raise ImportError("Fallback to vendored code") + + from ssl import CertificateError, match_hostname +except ImportError: + try: + # Backport of the function from a pypi module + from backports.ssl_match_hostname import CertificateError, match_hostname + except ImportError: + # Our vendored copy + from ._implementation import CertificateError, match_hostname + +# Not needed, but documenting what we provide. +__all__ = ('CertificateError', 'match_hostname') diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3117ca1e829e29d6d00a8ce7f4d39da536207912 GIT binary patch literal 563 zcmZWl%We}f6tz8*Hlz=_$Oe%`78Oz!tqW19Dxs<>0*OsGAORyJYi8^uZu}V8&d@|% zQK_r)A?)~`*|N$nu;RKYLKWBY@#7w!dwkEfwmJyn_G$6uCqd{}Jp7Ff*qp-jHvk-Q ztWbvL&jh-_oJ^7H3Br?W{0&1cRf$fsRJXDgMjw$mPmv(gj=RDrj(PWvv-W_qd(Wv? z9Nq$z^?!`d$dFHHg*?sL9KT0{wIz5#=L51#U|qHV7Ej*hN)>rI?FZYhh2ho--Y+c| z1Jdlg7B0w<Eb}1VIA>k6t@BV$*u?r^axIn^GzO2F#Ls=RSqtZ-HB6e3Z8qNN%DS+6 zmUypR3S1Y9X1!Q2X8k@S*h9_iF_XGdLJJe}0D8?jV_=f8AINP+jR?QL)5^&jjL|xG zbYvBW>Qql?`MhGsi{p!fufq{v_?N@ly|@eueE=~w^aHJAwI_`apt*N=R7|F`VjM5; zCR_D@&YV)R7}5%y=40XM|3)c;pUS}4el>5}ue9YeB~D^Td>5ciNYcS=(#6}DL?pfB E4^Zu#+5i9m literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/_implementation.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/_implementation.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3a1148ab3df9275026dbc95adafea4d46bbfe55e GIT binary patch literal 3322 zcmZ`*&u<&Y72eq&<dULjRWK4K^<m(~si{h&ZPh<wxIt7~2^_eRYdLYtI^C>xhT=-g z-Sx~+mWb6Qb^{+;z=xcAl8yoL2jnlwVXi&-A1I2R`pvGW*aEu5ydBQGnR)Z}d*6G% zpPg-5c>ey&%_ooFv8;cYKhwuY=Myx!2f?hq#R#(#(kJEH?%Vrw=sAfqa{Df^9$V=- z*W%tzQ`{z&`7yii{@F_HKUvJ}*FLkD$7(MuR^#>OPTyy9%x8@kq~BmoHuJ*jH(86# z;yuIK><r#5W^Y)XUrauKG~{#?s%RJtGpW*W#4mN|V4OxO&QdxM*@!;aS3~rdyZ9|q zE+tP@947SHkf(Gk<8+H|Y~1g@#!alX4$+M`4;d3soYa@Q*SeRxS0XbveF!?Apve{l zw{T~xZ!-dWY&~~}3l$IIC{%n^h)k??9PI~zF)RplGYCc*8z-jU3WBHOFsWv~w?rMg zmEynO^>PvKVu#*tD0+h|VO+@GXxNLc<iSUikG3yATOP29yuQ3EuI{PH=rW$IwD+i& z$N5s6N);x_(zP3#!=3TwmKiKtu**}HiQZTwNxZq-%fo0V+~Tq)WfHvY!(I@N@`R7z zsn9sGo9_z;_5lW#v>|*_{(o(J5t$kD7`W8X?x4wkLu^?GP60m|=M>f<KKc<ka0{0? z?^y>P-Y)b0W}{y#yhFljn5`G}!rpPkePy${!s_SbU9@jVQI}t15BJC_h><%0KmpL~ z*g_S~p~w6qLag*->{MfoBO+fyuk49`nt4?}^b7BZlv?NB962mOb_CmqwRgU#-L<|t zd*GjFU|%!y^vA~*_9%gPI8!)Bu#2_d#n^W1$UbNkjl<ajnt;KX$?y*bk_K5}6lH>$ zp33OMPw&v{SFT=Lq>@(vz25z8ce&Z5c!o;lw|YI5Wr^&@Tn)OJ*y;_{DCvnoWS0Hv zc-2z1$}IX+lddoyK{O!NG+CG|Vh4mox=)|Q35!C(B#l!V{R~WccWr|j+})xR?=OGt ze)XG)yO%C4P3$KN)xZL}D`;J`ey6QHnJ2N*UX+bfRepKx3Z4t?CD}7BbS=ztfJ-+4 zJ)z{YSPiu;xUO*-g*n%CC?{crPLz%EIN{pe&f-)z?|rtm{&4lq%EqepN(gqE+GeTt zr_tP>9ff<r$xZrh9xAE5+#J*Q6FyKQ#Jz3^J__R$fub8H%Gw=>a7#N_@^f?vLtVNZ zuvC_zSDyMl#^eHo<+%huw@G}`vLQX2v>lhsdA`#kXT5pnoYN#{?ej!XXh+8N<}q&% zt%UxE=qLbQk>|F!pzLjjksS*?w?GImhq?c74loa>cp#kDCVsRR$|#O?O)3#b3RL3r zG|CKe;6=kEvg7Gy47!4kQ@GNBCd9tftzGZ~qBMxpL8j~DG{!;>CUdgQ?bA1(2~-vw ztE}T-X(HAlXGxogMf4&Q-sUk@xoG8;jDwVQNR(|N^3XZ55UX}!7sSM2hfH3s?uC)6 zsMw%A8_;_X=rNCS*{v`>4FJmb0H`Qd$v$Nnm+7w+Wqc5)oQ5e4ldVhuLL)lJ1XaUW zmH~2U8Z=kBH@a8p61}iKR_36MD9ibUPPf$RxWe23uF8Ys<I8*LnlP@-!N;{YH=kbD z4akBx*LIwrcGDcjkC#{6_z0Uy;}6T9C*msJC!R8hGOhH~cYuQ7JcX2Kcx!)NkwY6y zhJVIqNQDnv_!6n``ZN_D*hq!9FzRCT{#&CTVAQ0|v>H`Nvpc>RGW)<z?Qg6qg;qQZ zwga@lMeg2a;ey5bPwWHFa4Yk`l0O!9x%LNDFKV#H7C)FI3ZC-|FfSPH+haccw$yBh zpHu^yHZ*@at@#-1UJ-e7?>;!W#_Hx=oOt`7zIVN-qt`t-+uyNY5n)eHMgN1hcY8&i z!Yfbz1Ac85&U3;VJ1(@Cnqkd?u$jY_npJJgfT0KWJ7qRV7f*D}?k}O+DoEk5+4rmy z9Ur4@^9{;k;Y`@Ur}>hLc(4ypg^Dg1PF$duz>bWYkYNUJAOsppD!3Yp6hoW)C9Y5+ zY-G_6SKTeHa?XWWe5uo^AkQVX<aA+5TMJ!Uvi;SYS8f8*?1cKuy#y)%NkhSLUSb%O zEz(V3`OSzar_&6!L=n$bW!swvR1tN$-k>o|4`T^^Q~!i<G8Vi`*HbFT*htF7($Hyz zRGCv=RZ^U0a#j^b6U9fl+NX%XG<!39ES{>jXv#TKOlXQIDoYocMdn|WrHbz<BqBAW z9D)maXZ7KuVEw_Pd+Tc}_l;sX@No5yU)+1RdUs8?<#=-&*>NRNYY5UZF13S<HEF^< zD^+2p>&IHUiG(uB(o)r=z{!WxPe3n<6K*L<erf?2<D#6{i*$1S|La~9Wm=v54wpxA z6B$Y}RAji)^f+Vt+qTj{%oDf*8PR;%amqSpbo0wF8CSJnNlao1R#uGE`l4d$vQX6R z6$O3*3@T;q0B2>A5p!mRVI1uwJT23&FqN2gMqw`6=yiPU8axWa)8ew3^N$mpM2-kk z?d<S<?d=*{FfiUc&3En6MJGk{*VsaS4q^E&@g3WqCvDp&Z5Ivi8k$R5$QeGFFMHLy zO==D_ks@0dH95t#-!J97Eet(&NLi?KW_3LXSQZ6=n8&cV1fge8sdkU6)QZGs?v3(H zsLDYz0p_Yi7l<2Xm16`o!ep+}Mdc}PT&}FD%arfmu1fEZO|F*bAY9KUe%&T>u&`;n M&Yau4=6inYe~EO4IsgCw literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py new file mode 100644 index 0000000..92c9bc7 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py @@ -0,0 +1,157 @@ +"""The match_hostname() function from Python 3.3.3, essential when using SSL.""" + +# Note: This file is under the PSF license as the code comes from the python +# stdlib. http://docs.python.org/3/license.html + +import re +import sys + +# ipaddress has been backported to 2.6+ in pypi. If it is installed on the +# system, use it to handle IPAddress ServerAltnames (this was added in +# python-3.5) otherwise only do DNS matching. This allows +# backports.ssl_match_hostname to continue to be used all the way back to +# python-2.4. +try: + from pip._vendor import ipaddress +except ImportError: + ipaddress = None + +__version__ = '3.5.0.1' + + +class CertificateError(ValueError): + pass + + +def _dnsname_match(dn, hostname, max_wildcards=1): + """Matching according to RFC 6125, section 6.4.3 + + http://tools.ietf.org/html/rfc6125#section-6.4.3 + """ + pats = [] + if not dn: + return False + + # Ported from python3-syntax: + # leftmost, *remainder = dn.split(r'.') + parts = dn.split(r'.') + leftmost = parts[0] + remainder = parts[1:] + + 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)) + + # speed up common case w/o wildcards + if not wildcards: + 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. + 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--'): + # 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 + # U-label of an internationalized domain name. + pats.append(re.escape(leftmost)) + else: + # Otherwise, '*' matches any dotless string, e.g. www* + 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) + return pat.match(hostname) + + +def _to_unicode(obj): + if isinstance(obj, str) and sys.version_info < (3,): + obj = unicode(obj, encoding='ascii', errors='strict') + return obj + +def _ipaddress_match(ipname, host_ip): + """Exact matching of IP addresses. + + RFC 6125 explicitly doesn't define an algorithm for this + (section 1.7.2 - "Out of Scope"). + """ + # OpenSSL may add a trailing newline to a subjectAltName's IP address + # Divergence from upstream: ipaddress can't handle byte str + ip = ipaddress.ip_address(_to_unicode(ipname).rstrip()) + return ip == host_ip + + +def match_hostname(cert, hostname): + """Verify that *cert* (in decoded format as returned by + SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125 + rules are followed, but IP addresses are not accepted for *hostname*. + + CertificateError is raised on failure. On success, the function + 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") + try: + # Divergence from upstream: ipaddress can't handle byte str + host_ip = ipaddress.ip_address(_to_unicode(hostname)) + except ValueError: + # Not an IP address (common case) + host_ip = None + except UnicodeError: + # Divergence from upstream: Have to deal with ipaddress not taking + # byte strings. addresses should be all ascii, so we consider it not + # an ipaddress in this case + host_ip = None + except AttributeError: + # Divergence from upstream: Make ipaddress library optional + if ipaddress is None: + host_ip = None + else: + raise + dnsnames = [] + san = cert.get('subjectAltName', ()) + for key, value in san: + if key == 'DNS': + if host_ip is None and _dnsname_match(value, hostname): + return + dnsnames.append(value) + 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 key, value in sub: + # XXX according to RFC 2818, the most specific Common Name + # must be used. + 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)))) + elif len(dnsnames) == 1: + raise CertificateError("hostname %r " + "doesn't match %r" + % (hostname, dnsnames[0])) + else: + raise CertificateError("no appropriate commonName or " + "subjectAltName fields were found") diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/poolmanager.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/poolmanager.py new file mode 100644 index 0000000..506a3c9 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/poolmanager.py @@ -0,0 +1,449 @@ +from __future__ import absolute_import +import collections +import functools +import logging + +from ._collections import RecentlyUsedContainer +from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool +from .connectionpool import port_by_scheme +from .exceptions import LocationValueError, MaxRetryError, ProxySchemeUnknown +from .packages.six.moves.urllib.parse import urljoin +from .request import RequestMethods +from .util.url import parse_url +from .util.retry import Retry + + +__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') + +# 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_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 +) + +#: 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) + + +def _default_key_normalizer(key_class, request_context): + """ + Create a pool key out of a request context dictionary. + + According to RFC 3986, both the scheme and host are case-insensitive. + Therefore, this function normalizes both before constructing the pool + key for an HTTPS request. If you wish to change this behaviour, provide + alternate callables to ``key_fn_by_scheme``. + + :param key_class: + The class to use when constructing the key. This should be a namedtuple + with the ``scheme`` and ``host`` keys at a minimum. + :type key_class: namedtuple + :param request_context: + A dictionary-like object that contain the context for a request. + :type request_context: dict + + :return: A namedtuple that can be used as a connection pool key. + :rtype: PoolKey + """ + # Since we mutate the dictionary, make a copy first + context = request_context.copy() + 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'): + 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') + if socket_opts is not None: + 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) + + # Default to ``None`` for keys missing from the context + for field in key_class._fields: + if field not in context: + context[field] = None + + return key_class(**context) + + +#: A dictionary that maps a scheme to a callable that creates a pool key. +#: This can be used to alter the way pool keys are constructed, if desired. +#: 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), +} + +pool_classes_by_scheme = { + 'http': HTTPConnectionPool, + 'https': HTTPSConnectionPool, +} + + +class PoolManager(RequestMethods): + """ + Allows for arbitrary requests while transparently keeping track of + necessary connection pools for you. + + :param num_pools: + Number of connection pools to cache before discarding the least + recently used pool. + + :param headers: + Headers to include with all requests, unless other headers are given + explicitly. + + :param \\**connection_pool_kw: + Additional parameters are used to create fresh + :class:`urllib3.connectionpool.ConnectionPool` instances. + + Example:: + + >>> manager = PoolManager(num_pools=2) + >>> r = manager.request('GET', 'http://google.com/') + >>> r = manager.request('GET', 'http://google.com/mail') + >>> r = manager.request('GET', 'http://yahoo.com/') + >>> len(manager.pools) + 2 + + """ + + proxy = None + + 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()) + + # Locally set the pool classes and keys so other PoolManagers can + # override them. + self.pool_classes_by_scheme = pool_classes_by_scheme + self.key_fn_by_scheme = key_fn_by_scheme.copy() + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.clear() + # Return False to re-raise any potential exceptions + return False + + def _new_pool(self, scheme, host, port, request_context=None): + """ + Create a new :class:`ConnectionPool` based on host, port, scheme, and + any additional pool keyword arguments. + + If ``request_context`` is provided, it is provided as keyword arguments + to the pool class used. This method is used to actually create the + connection pools handed out by :meth:`connection_from_url` and + companion methods. It is intended to be overridden for customization. + """ + pool_cls = self.pool_classes_by_scheme[scheme] + if request_context is None: + request_context = self.connection_pool_kw.copy() + + # Although the context has everything necessary to create the pool, + # 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'): + request_context.pop(key, None) + + if scheme == 'http': + for kw in SSL_KEYWORDS: + request_context.pop(kw, None) + + return pool_cls(host, port, **request_context) + + def clear(self): + """ + Empty our store of pools and direct them all to close. + + This will not affect in-flight connections, but they will not be + re-used after completion. + """ + self.pools.clear() + + def connection_from_host(self, host, port=None, scheme='http', pool_kwargs=None): + """ + Get a :class:`ConnectionPool` based on the host, port, and scheme. + + If ``port`` isn't given, it will be derived from the ``scheme`` using + ``urllib3.connectionpool.port_by_scheme``. If ``pool_kwargs`` is + provided, it is merged with the instance's ``connection_pool_kw`` + variable and used to create the new connection pool, if one is + needed. + """ + + if not host: + raise LocationValueError("No host specified.") + + request_context = self._merge_pool_kwargs(pool_kwargs) + 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 + + return self.connection_from_context(request_context) + + def connection_from_context(self, request_context): + """ + Get a :class:`ConnectionPool` based on the request context. + + ``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() + pool_key_constructor = self.key_fn_by_scheme[scheme] + pool_key = pool_key_constructor(request_context) + + return self.connection_from_pool_key(pool_key, request_context=request_context) + + def connection_from_pool_key(self, pool_key, request_context=None): + """ + Get a :class:`ConnectionPool` based on the provided pool key. + + ``pool_key`` should be a namedtuple that only contains immutable + objects. At a minimum it must have the ``scheme``, ``host``, and + ``port`` fields. + """ + with self.pools.lock: + # If the scheme, host, or port doesn't match existing open + # connections, open a new ConnectionPool. + pool = self.pools.get(pool_key) + if pool: + return pool + + # Make a fresh ConnectionPool of the desired type + 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 + + return pool + + def connection_from_url(self, url, pool_kwargs=None): + """ + Similar to :func:`urllib3.connectionpool.connection_from_url`. + + If ``pool_kwargs`` is not provided and a new pool needs to be + constructed, ``self.connection_pool_kw`` is used to initialize + the :class:`urllib3.connectionpool.ConnectionPool`. If ``pool_kwargs`` + is provided, it is used instead. Note that if a new pool does not + need to be created for the request, the provided ``pool_kwargs`` are + not used. + """ + u = parse_url(url) + return self.connection_from_host(u.host, port=u.port, scheme=u.scheme, + pool_kwargs=pool_kwargs) + + def _merge_pool_kwargs(self, override): + """ + Merge a dictionary of override values for self.connection_pool_kw. + + This does not modify self.connection_pool_kw and returns a new dict. + Any keys in the override dictionary with a value of ``None`` are + removed from the merged dictionary. + """ + base_pool_kwargs = self.connection_pool_kw.copy() + if override: + for key, value in override.items(): + if value is None: + try: + del base_pool_kwargs[key] + except KeyError: + pass + else: + base_pool_kwargs[key] = value + return base_pool_kwargs + + def urlopen(self, method, url, redirect=True, **kw): + """ + Same as :meth:`urllib3.connectionpool.HTTPConnectionPool.urlopen` + with custom cross-host redirect logic and only sends the request-uri + portion of the ``url``. + + The given ``url`` parameter must be absolute, such that an appropriate + :class:`urllib3.connectionpool.ConnectionPool` can be chosen for it. + """ + 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 + + 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) + else: + response = conn.urlopen(method, u.request_uri, **kw) + + redirect_location = redirect and response.get_redirect_location() + if not redirect_location: + return response + + # Support relative URLs for redirecting. + redirect_location = urljoin(url, redirect_location) + + # RFC 7231, Section 6.4.4 + if response.status == 303: + method = 'GET' + + 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)): + for header in retries.remove_headers_on_redirect: + kw['headers'].pop(header, None) + + try: + retries = retries.increment(method, url, response=response, _pool=conn) + except MaxRetryError: + if retries.raise_on_redirect: + raise + return response + + kw['retries'] = retries + kw['redirect'] = redirect + + log.info("Redirecting %s -> %s", url, redirect_location) + return self.urlopen(method, redirect_location, **kw) + + +class ProxyManager(PoolManager): + """ + Behaves just like :class:`PoolManager`, but sends all requests through + the defined proxy, using the CONNECT method for HTTPS URLs. + + :param proxy_url: + The URL of the proxy to be used. + + :param proxy_headers: + A dictionary containing headers that will be sent to the proxy. In case + of HTTP they are being sent with each request, while in the + HTTPS/CONNECT case they are sent only once. Could be used for proxy + authentication. + + Example: + >>> proxy = urllib3.ProxyManager('http://localhost:3128/') + >>> r1 = proxy.request('GET', 'http://google.com/') + >>> r2 = proxy.request('GET', 'http://httpbin.org/') + >>> len(proxy.pools) + 1 + >>> r3 = proxy.request('GET', 'https://httpbin.org/') + >>> r4 = proxy.request('GET', 'https://twitter.com/') + >>> len(proxy.pools) + 3 + + """ + + 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 = parse_url(proxy_url) + if not proxy.port: + port = port_by_scheme.get(proxy.scheme, 80) + proxy = proxy._replace(port=port) + + if proxy.scheme not in ("http", "https"): + raise ProxySchemeUnknown(proxy.scheme) + + self.proxy = proxy + self.proxy_headers = proxy_headers or {} + + connection_pool_kw['_proxy'] = self.proxy + connection_pool_kw['_proxy_headers'] = self.proxy_headers + + super(ProxyManager, self).__init__( + num_pools, headers, **connection_pool_kw) + + 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) + + return super(ProxyManager, self).connection_from_host( + 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': '*/*'} + + netloc = parse_url(url).netloc + if netloc: + headers_['Host'] = netloc + + if headers: + headers_.update(headers) + return headers_ + + def urlopen(self, method, url, redirect=True, **kw): + "Same as HTTP(S)ConnectionPool.urlopen, ``url`` must be absolute." + u = parse_url(url) + + 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) + + return super(ProxyManager, self).urlopen(method, url, redirect=redirect, **kw) + + +def proxy_from_url(url, **kw): + return ProxyManager(proxy_url=url, **kw) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/request.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/request.py new file mode 100644 index 0000000..1be3334 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/request.py @@ -0,0 +1,150 @@ +from __future__ import absolute_import + +from .filepost import encode_multipart_formdata +from .packages.six.moves.urllib.parse import urlencode + + +__all__ = ['RequestMethods'] + + +class RequestMethods(object): + """ + Convenience mixin for classes who implement a :meth:`urlopen` method, such + as :class:`~urllib3.connectionpool.HTTPConnectionPool` and + :class:`~urllib3.poolmanager.PoolManager`. + + Provides behavior for making common types of HTTP request methods and + decides which type of request field encoding to use. + + Specifically, + + :meth:`.request_encode_url` is for sending requests whose fields are + encoded in the URL (such as GET, HEAD, DELETE). + + :meth:`.request_encode_body` is for sending requests whose fields are + encoded in the *body* of the request using multipart or www-form-urlencoded + (such as for POST, PUT, PATCH). + + :meth:`.request` is for making any kind of request, it will look up the + appropriate encoding format and use one of the above two methods to make + the request. + + Initializer parameters: + + :param headers: + Headers to include with all requests, unless other headers are given + explicitly. + """ + + _encode_url_methods = set(['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 request(self, method, url, fields=None, headers=None, **urlopen_kw): + """ + Make a request using :meth:`urlopen` with the appropriate encoding of + ``fields`` based on the ``method`` used. + + This is a convenience method that requires the least amount of manual + effort. It can be used in most situations, while still having the + option to drop down to more specific methods when necessary, such as + :meth:`request_encode_url`, :meth:`request_encode_body`, + or even the lowest level :meth:`urlopen`. + """ + method = method.upper() + + 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) + else: + 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): + """ + Make a request using :meth:`urlopen` with the ``fields`` encoded in + the url. This is useful for request methods like GET, HEAD, DELETE, etc. + """ + if headers is None: + headers = self.headers + + extra_kw = {'headers': headers} + extra_kw.update(urlopen_kw) + + if 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): + """ + Make a request using :meth:`urlopen` with the ``fields`` encoded in + the body. This is useful for request methods like POST, PUT, PATCH, etc. + + When ``encode_multipart=True`` (default), then + :meth:`urllib3.filepost.encode_multipart_formdata` is used to encode + the payload with the appropriate content type. Otherwise + :meth:`urllib.urlencode` is used with the + 'application/x-www-form-urlencoded' content type. + + Multipart encoding must be used when posting files, and it's reasonably + safe to use it in other times too. However, it may break request + signing, such as with OAuth. + + Supports an optional ``fields`` parameter of key/value strings AND + key/filetuple. A filetuple is a (filename, data, MIME type) tuple where + the MIME type is optional. For example:: + + fields = { + 'foo': 'bar', + 'fakefile': ('foofile.txt', 'contents of foofile'), + 'realfile': ('barfile.txt', open('realfile').read()), + 'typedfile': ('bazfile.bin', open('bazfile').read(), + 'image/jpeg'), + 'nonamefile': 'contents of nonamefile field', + } + + When uploading a file, providing a filename (the first parameter of the + tuple) is optional but recommended to best mimic behavior of browsers. + + Note that if ``headers`` are supplied, the 'Content-Type' header will + be overwritten because it depends on the dynamic random boundary string + which is used to compose the body of the request. The random boundary + string can be explicitly set with the ``multipart_boundary`` parameter. + """ + if headers is None: + headers = self.headers + + extra_kw = {'headers': {}} + + if fields: + if 'body' in urlopen_kw: + raise TypeError( + "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) + else: + body, content_type = urlencode(fields), 'application/x-www-form-urlencoded' + + extra_kw['body'] = body + extra_kw['headers'] = {'Content-Type': content_type} + + extra_kw['headers'].update(headers) + extra_kw.update(urlopen_kw) + + return self.urlopen(method, url, **extra_kw) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/response.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/response.py new file mode 100644 index 0000000..9873cb9 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/response.py @@ -0,0 +1,676 @@ +from __future__ import absolute_import +from contextlib import contextmanager +import zlib +import io +import logging +from socket import timeout as SocketTimeout +from socket import error as SocketError + +from ._collections import HTTPHeaderDict +from .exceptions import ( + BodyNotHttplibCompatible, ProtocolError, DecodeError, ReadTimeoutError, + ResponseNotChunked, IncompleteRead, InvalidHeader +) +from .packages.six import string_types as basestring, binary_type, PY3 +from .packages.six.moves import http_client as httplib +from .connection import HTTPException, BaseSSLError +from .util.response import is_fp_closed, is_response_to_head + +log = logging.getLogger(__name__) + + +class DeflateDecoder(object): + + def __init__(self): + self._first_try = True + self._data = binary_type() + self._obj = zlib.decompressobj() + + def __getattr__(self, name): + return getattr(self._obj, name) + + def decompress(self, data): + if not data: + return data + + if not self._first_try: + return self._obj.decompress(data) + + self._data += data + try: + decompressed = self._obj.decompress(data) + if decompressed: + self._first_try = False + self._data = None + return decompressed + except zlib.error: + self._first_try = False + self._obj = zlib.decompressobj(-zlib.MAX_WBITS) + try: + return self.decompress(self._data) + finally: + self._data = None + + +class GzipDecoderState(object): + + FIRST_MEMBER = 0 + OTHER_MEMBERS = 1 + SWALLOW_DATA = 2 + + +class GzipDecoder(object): + + def __init__(self): + self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) + self._state = GzipDecoderState.FIRST_MEMBER + + def __getattr__(self, name): + return getattr(self._obj, name) + + def decompress(self, data): + ret = binary_type() + if self._state == GzipDecoderState.SWALLOW_DATA or not data: + return ret + while True: + try: + ret += self._obj.decompress(data) + except zlib.error: + previous_state = self._state + # Ignore data after the first error + self._state = GzipDecoderState.SWALLOW_DATA + if previous_state == GzipDecoderState.OTHER_MEMBERS: + # Allow trailing garbage acceptable in other gzip clients + return ret + raise + data = self._obj.unused_data + if not data: + return ret + self._state = GzipDecoderState.OTHER_MEMBERS + self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) + + +def _get_decoder(mode): + if mode == 'gzip': + return GzipDecoder() + + return DeflateDecoder() + + +class HTTPResponse(io.IOBase): + """ + HTTP Response container. + + Backwards-compatible to httplib's HTTPResponse but the response ``body`` is + loaded and decoded on-demand when the ``data`` property is accessed. This + class is also compatible with the Python standard library's :mod:`io` + module, and can hence be treated as a readable object in the context of that + framework. + + Extra parameters for behaviour not present in httplib.HTTPResponse: + + :param preload_content: + If True, the response's body will be preloaded during construction. + + :param decode_content: + If True, will attempt to decode the body based on the + 'content-encoding' header. + + :param original_response: + When this HTTPResponse wrapper is generated from an httplib.HTTPResponse + object, it's convenient to include the original for debug purposes. It's + otherwise unused. + + :param retries: + The retries contains the last :class:`~urllib3.util.retry.Retry` that + was used during the request. + + :param enforce_content_length: + Enforce content length checking. Body returned by server must match + value of Content-Length header, if present. Otherwise, raise error. + """ + + CONTENT_DECODERS = ['gzip', 'deflate'] + 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): + + if isinstance(headers, HTTPHeaderDict): + self.headers = headers + else: + self.headers = HTTPHeaderDict(headers) + self.status = status + self.version = version + self.reason = reason + self.strict = strict + self.decode_content = decode_content + self.retries = retries + self.enforce_content_length = enforce_content_length + + self._decoder = None + self._body = None + self._fp = None + self._original_response = original_response + self._fp_bytes_read = 0 + self.msg = msg + self._request_url = request_url + + if body and isinstance(body, (basestring, binary_type)): + self._body = body + + self._pool = pool + self._connection = connection + + 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() + # 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: + self.chunked = True + + # Determine length of response + self.length_remaining = self._init_length(request_method) + + # If requested, preload the body. + if preload_content and not self._body: + self._body = self.read(decode_content=decode_content) + + def get_redirect_location(self): + """ + Should we redirect and where to? + + :returns: Truthy redirect location string if we got a redirect status + code and valid location. ``None`` if redirect status and no + location. ``False`` if not a redirect status code. + """ + if self.status in self.REDIRECT_STATUSES: + return self.headers.get('location') + + return False + + def release_conn(self): + if not self._pool or not self._connection: + return + + self._pool._put_conn(self._connection) + self._connection = None + + @property + def data(self): + # For backwords-compat with earlier urllib3 0.4 and earlier. + if self._body: + return self._body + + if self._fp: + return self.read(cache_content=True) + + @property + def connection(self): + return self._connection + + def isclosed(self): + return is_fp_closed(self._fp) + + def tell(self): + """ + Obtain the number of bytes pulled over the wire so far. May differ from + the amount of content returned by :meth:``HTTPResponse.read`` if bytes + are encoded on the wire (e.g, compressed). + """ + return self._fp_bytes_read + + def _init_length(self, request_method): + """ + Set initial length value for Response content if available. + """ + 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.") + return None + + try: + # RFC 7230 section 3.3.2 specifies multiple content lengths can + # be sent in a single Content-Length header + # (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(',')]) + if len(lengths) > 1: + raise InvalidHeader("Content-Length contained multiple " + "unmatching values (%s)" % length) + length = lengths.pop() + except ValueError: + length = None + else: + if length < 0: + length = None + + # Convert status to int for comparison + # In some cases, httplib returns a status of "_UNKNOWN" + try: + status = int(self.status) + except ValueError: + status = 0 + + # Check for responses that shouldn't include a body + if status in (204, 304) or 100 <= status < 200 or request_method == 'HEAD': + length = 0 + + return length + + def _init_decoder(self): + """ + Set-up the _decoder attribute if necessary. + """ + # Note: content-encoding value should be case-insensitive, per RFC 7230 + # Section 3.2 + content_encoding = self.headers.get('content-encoding', '').lower() + if self._decoder is None and content_encoding in self.CONTENT_DECODERS: + self._decoder = _get_decoder(content_encoding) + + def _decode(self, data, decode_content, flush_decoder): + """ + Decode the data passed in and potentially flush the decoder. + """ + try: + if decode_content and self._decoder: + data = self._decoder.decompress(data) + except (IOError, zlib.error) as e: + content_encoding = self.headers.get('content-encoding', '').lower() + raise DecodeError( + "Received response with content-encoding: %s, but " + "failed to decode it." % content_encoding, e) + + if flush_decoder and decode_content: + data += self._flush_decoder() + + return data + + def _flush_decoder(self): + """ + Flushes the decoder. Should only be called if the decoder is actually + being used. + """ + if self._decoder: + buf = self._decoder.decompress(b'') + return buf + self._decoder.flush() + + return b'' + + @contextmanager + def _error_catcher(self): + """ + Catch low-level python exceptions, instead re-raising urllib3 + variants, so that low-level exceptions are not leaked in the + high-level api. + + On exit, release the connection back to the pool. + """ + clean_exit = False + + try: + try: + yield + + 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.') + + except BaseSSLError as e: + # FIXME: Is there a better way to differentiate between SSLErrors? + 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.') + + except (HTTPException, SocketError) as e: + # This includes IncompleteRead. + raise ProtocolError('Connection broken: %r' % e, e) + + # If no exception is thrown, we should avoid cleaning up + # unnecessarily. + clean_exit = True + finally: + # If we didn't terminate cleanly, we need to throw away our + # connection. + if not clean_exit: + # The response may not be closed but we're not going to use it + # anymore so close it now to ensure that the connection is + # released back to the pool. + if self._original_response: + self._original_response.close() + + # Closing the response may not actually be sufficient to close + # everything, so if we have a hold of the connection close that + # too. + if self._connection: + self._connection.close() + + # If we hold the original response but it's closed now, we should + # return the connection back to the pool. + if self._original_response and self._original_response.isclosed(): + self.release_conn() + + def read(self, amt=None, decode_content=None, cache_content=False): + """ + Similar to :meth:`httplib.HTTPResponse.read`, but with two additional + parameters: ``decode_content`` and ``cache_content``. + + :param amt: + How much of the content to read. If specified, caching is skipped + because it doesn't make sense to cache partial content as the full + response. + + :param decode_content: + If True, will attempt to decode the body based on the + 'content-encoding' header. + + :param cache_content: + If True, will save the returned data such that the same result is + returned despite of the state of the underlying file object. This + is useful if you want the ``.data`` property to continue working + after having ``.read()`` the file object. (Overridden if ``amt`` is + set.) + """ + self._init_decoder() + if decode_content is None: + decode_content = self.decode_content + + if self._fp is None: + return + + flush_decoder = False + data = None + + with self._error_catcher(): + if amt is None: + # cStringIO doesn't like amt=None + data = self._fp.read() + flush_decoder = True + else: + cache_content = False + data = self._fp.read(amt) + 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_ + # already do. However, versions of python released before + # December 15, 2012 (http://bugs.python.org/issue16298) do + # not properly close the connection in all cases. There is + # 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): + # 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 + # raised during streaming, so all calls with incorrect + # Content-Length are caught. + raise IncompleteRead(self._fp_bytes_read, self.length_remaining) + + if data: + self._fp_bytes_read += len(data) + if self.length_remaining is not None: + self.length_remaining -= len(data) + + data = self._decode(data, decode_content, flush_decoder) + + if cache_content: + self._body = data + + return data + + 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 + connection is closed. + + :param amt: + How much of the content to read. The generator will return up to + much data per iteration, but may return less. This is particularly + likely when using compressed data. However, the empty string will + never be returned. + + :param decode_content: + If True, will attempt to decode the body based on the + 'content-encoding' header. + """ + if self.chunked and self.supports_chunked_reads(): + for line in self.read_chunked(amt, decode_content=decode_content): + yield line + else: + while not is_fp_closed(self._fp): + data = self.read(amt=amt, decode_content=decode_content) + + if data: + yield data + + @classmethod + def from_httplib(ResponseCls, r, **response_kw): + """ + Given an :class:`httplib.HTTPResponse` instance ``r``, return a + corresponding :class:`urllib3.response.HTTPResponse` object. + + Remaining parameters are passed to the HTTPResponse constructor, along + with ``original_response=r``. + """ + headers = r.msg + + if not isinstance(headers, HTTPHeaderDict): + if PY3: # Python 3 + headers = HTTPHeaderDict(headers.items()) + else: # Python 2 + 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) + return resp + + # Backwards-compatibility methods for httplib.HTTPResponse + def getheaders(self): + return self.headers + + def getheader(self, name, default=None): + return self.headers.get(name, default) + + # Backwards compatibility for http.cookiejar + def info(self): + return self.headers + + # Overrides from io.IOBase + def close(self): + if not self.closed: + self._fp.close() + + if self._connection: + self._connection.close() + + @property + def closed(self): + if self._fp is None: + return True + elif hasattr(self._fp, 'isclosed'): + return self._fp.isclosed() + elif hasattr(self._fp, 'closed'): + return self._fp.closed + else: + return True + + def fileno(self): + if self._fp is None: + raise IOError("HTTPResponse has no file to get a fileno from") + 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") + + def flush(self): + if self._fp is not None and hasattr(self._fp, 'flush'): + return self._fp.flush() + + def readable(self): + # This method is required for `io` module compatibility. + return True + + def readinto(self, b): + # This method is required for `io` module compatibility. + temp = self.read(len(b)) + if len(temp) == 0: + return 0 + else: + b[:len(temp)] = temp + return len(temp) + + def supports_chunked_reads(self): + """ + Checks if the underlying file-like object looks like a + httplib.HTTPResponse object. We do this by testing for the fp + attribute. If it is present we assume it returns raw chunks as + processed by read_chunked(). + """ + return hasattr(self._fp, 'fp') + + def _update_chunk_length(self): + # First, we'll figure out length of a chunk and then + # we'll try to read it from socket. + if self.chunk_left is not None: + return + line = self._fp.fp.readline() + line = line.split(b';', 1)[0] + try: + self.chunk_left = int(line, 16) + except ValueError: + # Invalid chunked protocol response, abort. + self.close() + raise httplib.IncompleteRead(line) + + def _handle_chunk(self, amt): + returned_chunk = None + if amt is None: + chunk = self._fp._safe_read(self.chunk_left) + returned_chunk = chunk + self._fp._safe_read(2) # Toss the CRLF at the end of the chunk. + self.chunk_left = None + elif amt < self.chunk_left: + value = self._fp._safe_read(amt) + self.chunk_left = self.chunk_left - amt + returned_chunk = value + elif amt == self.chunk_left: + value = self._fp._safe_read(amt) + self._fp._safe_read(2) # Toss the CRLF at the end of the chunk. + self.chunk_left = None + returned_chunk = value + else: # amt > self.chunk_left + returned_chunk = self._fp._safe_read(self.chunk_left) + self._fp._safe_read(2) # Toss the CRLF at the end of the chunk. + self.chunk_left = None + return returned_chunk + + def read_chunked(self, amt=None, decode_content=None): + """ + Similar to :meth:`HTTPResponse.read`, but with an additional + parameter: ``decode_content``. + + :param amt: + How much of the content to read. If specified, caching is skipped + because it doesn't make sense to cache partial content as the full + response. + + :param decode_content: + If True, will attempt to decode the body based on the + 'content-encoding' header. + """ + self._init_decoder() + # FIXME: Rewrite this method and make it a class with a better structured logic. + if not self.chunked: + raise ResponseNotChunked( + "Response is not chunked. " + "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.") + + with self._error_catcher(): + # Don't bother reading the body of a HEAD request. + if self._original_response and is_response_to_head(self._original_response): + self._original_response.close() + return + + # If a response is already read and closed + # then return immediately. + if self._fp.fp is None: + return + + while True: + self._update_chunk_length() + if self.chunk_left == 0: + break + chunk = self._handle_chunk(amt) + decoded = self._decode(chunk, decode_content=decode_content, + flush_decoder=False) + if decoded: + yield decoded + + if decode_content: + # On CPython and PyPy, we should never need to flush the + # decoder. However, on Jython we *might* need to, so + # lets defensively do it anyway. + decoded = self._flush_decoder() + if decoded: # Platform-specific: Jython. + yield decoded + + # Chunk content ends with \r\n: discard it. + while True: + line = self._fp.fp.readline() + if not line: + # Some sites may not end with '\r\n'. + break + if line == b'\r\n': + break + + # We read everything; close the "file". + if self._original_response: + self._original_response.close() + + def geturl(self): + """ + Returns the URL that was the source of this response. + If the request that generated this response redirected, this method + will return the final redirect location. + """ + if self.retries is not None and len(self.retries.history): + return self.retries.history[-1].redirect_location + else: + return self._request_url diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__init__.py new file mode 100644 index 0000000..2f2770b --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__init__.py @@ -0,0 +1,54 @@ +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 +from .response import is_fp_closed +from .ssl_ import ( + SSLContext, + HAS_SNI, + IS_PYOPENSSL, + IS_SECURETRANSPORT, + assert_fingerprint, + resolve_cert_reqs, + resolve_ssl_version, + ssl_wrap_socket, +) +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 +) + +__all__ = ( + 'HAS_SNI', + 'IS_PYOPENSSL', + 'IS_SECURETRANSPORT', + 'SSLContext', + '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.7/site-packages/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..575747ecb991a2061670dcd21550e0d48538044b GIT binary patch literal 1000 zcmZ9KTW`}a6vxwR+BCham)!>vPxN7AFaer`5M!FeB-Bl9dB8%l(#CDW>?GJuyX`aZ zF?iuC`IV=A1)ex3(-^{0emdtkvH$-2ysy_C3&!`I$(L@?vVLK5Kk^W~gIE0k1Xhsa zmdKG@&I<BDf#*em6tcL;i=sqISzO{}VG}!x%e*40q$(WZh#IL0m$;%%>Y_m!qDh*f zMOxW+HeVBM(iR=k$?^*CiXQ1@ah0!&4YDCN$)?yMTVk7RXLX0~h+VQP_Q)ROHS#EM zM^?Xn3reki&NTgrig~IT4Mh@5eVe<h_d-RdaTKws4&#UhGENc}zz?qQFBx4hKVVW} z4j;}EI_0r~`HFEyqmL(Xq}i1=_J`vU9SzQmdp4pMpU*E&2QX{ekd01HJ`GRD!{fo| z;(RzZZC@!SHJydgoXJFnkv40Rfwm>1Q=F0Pn=+mIl2V*5K>>&}O-xqOPpFEgmrVEb z#+{~8vPe@M3TEsvFithdEe)BL*ZrcY%$cT(SZPyDe5n{sB{wyd@DN2vs24s-4olTn zK9*t$3jDw{{-!G#YS!<{3OFXK2<#APBi0ZtL=RCzG!f7`mMkOMhz_EJa1nJx7tuhh zBQ^ko{$t}%I!kpb8Kn{%&NvVElPzm(uqb6pXA7DNSe3*PxQg4EBARq3?mxkqxQFd= zXJeyp;MkpLJcubtbS^uYDS%o393WGS2Q@`>=RvozDfKz0^rt1Cz<h?^OAqdM>1*aK zed*0&j;-X0g*Sbk(4(89uLrBcS#YCX9WLdID}5slV9X<L>?L8cA4W>Un)@$bPZpQy zWRAt`g?@;FSbCt1hm%7u)gkvN4I{Wd`YgFNl{X>|QqJCDk1O=w&AT~#o;t0Po7*h6 G%6|YU>JHoh literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/connection.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/connection.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..17cdf9327763b41615a6be0b7e4b63daded654e1 GIT binary patch literal 3077 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 ako{iWS?4P%TUoZ<n~vF7b6vOYUjH9pgHI>` literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/queue.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/queue.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..307a6063077dbd233c432f4b27328492d3da98e7 GIT binary patch literal 1049 zcmZuwO>fjN5VhkZo3>jh&>O!Xhi*zMK$Q@x0Er8#KyV>Kva+#vo2~OvJ6XzVZ|#vE z(H{9rzH;i3D<@{W-D(SrG~>xk;y3Tvd9}H@PQboD9)9^n3HgZ+OY<Q)1UGLW2qLH= zDG{Dvik4pLQOteCN<Z}}k=`WG1NT;#_TCZ^i131lQ2LYboTZVVA4%N1hMmaKwFfb# zmYL!Vmf*CLoy@VdGzQ5bxY>muNlFDtJwb(cK~g6D5fx1M7c>nPFli`yB7$B|tO3lr zU3*uI>JM&P#6rUr{WZ9`2cadG^oq<0_XL5D=uyn<MqVo=^R}ofV*?>!GL16Cp7o7X zBTM-YqEWKnCTVmr&03jEGo6fTC8Rb<d7R`=8h$W4nCyPtABmZHwm;Q-XYH)q1shk% zr=%&GouV>rrqs^U=fmTZZaBuGb3T=osCCk5rHbKx(zS(3oIr!-n+<qT73~I6aJ=a3 z{w>pi>*fFDixbc3oJ`0$o&#{DH@tKNEz6Xw9IZt_02}gCQ_LhvwFKK*0dvheXn1H& z-7QEE>ypmt6@`0pqp#;MZJ0F;kc_<rwqLZe{2ScoP1inHfxfo_4Xqq5t2110kJZt1 zz*l!6SyMMa8M*$8G?wi)G?pY+k)U-HM>gWT%1X((UFW>4MW-<DbAH-oYSGbs+<OxP zDyDIE{RjgNwGvQU9YDak!HFUou|A8KtHx_Ogqn?-EI-M{(rA=5eYkuaz&|r6>nSww wVp{h8^PUadRZq8hS9L~;<%q88c3r`D<G2HkUM#4*L=6qrBig5ZFZ3ez2f*{>KmY&$ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f19bccf89c5f79cf5cbb4026e21db228dc01e7a5 GIT binary patch literal 3230 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aa4d6108785724fb4ac6a3bd1e00fbce1890705c GIT binary patch literal 1911 zcmZXVTW=#Z6oBoSNiv<L-K7f>0>oM?1d2qHLd9hxgebd}iUg%%3o6x0Q)lc+rtw_X z_M}ZoUnr08AKFLW_&xK=Q~v@_9D9<syKBkz8Q+e5&UemyyRs4>D1W{?c>d86LjRhN zMR7p*2C6a*LktU);zNuPbC@ff)IId9?1@I&JZys8V9h_!VT-kx553QpSOEPJTYiQ* z?Q1v%b#Qf$4pc5m&BG)ua;dM49vEL9X<dYoNO-2<b8UxH#^oNBD#?c1Qsy$k<_IXJ z_n|(4s$yuS{tR8BEA$L`NaJxJ-@~v7qhC?x9H41)hK`+^xi4Ru3t-M=c<kTIAKabS z9&;}6@0ekDgL|d}0_DkwM`J}!MqH1$B$N!33C~EJ2)-_oF(>)pm`9o<ibNt;oOJ`c zuU}9}Q#0GQ-{!3S5r2K7&Pil+bnUX;v(C>M9SBZfoN>)%nq>S&eO%m8)M-?HqH3+x z>Xz0r8Gx;={i^1C+=+`S_=SqH9tUf?aHqeKY=bTToAe5qOsM9)36;G#7vKifOGmxv zlOlY4_V{??WHV-G>hsNs{Pa|xr5jL&S#Q5rB*l7?DNTh~|LlvwXj~44X3*9UOvG~8 zE2R+0V6#{1MD!$AMV=|%Ev8jFQDJNdFcxbW*S-S{@*UU5tGMYnPP6Xa!1i(#W^b7A z;G+T6GVvS)jb^~Yv2)?5_ceI<($kF@y1-Z1_)`NDhT{wOyp}yH!^pWibL7*RbAdp@ z>id~14|HpWXD(~}<p2pTkkF)i0HO8HmQq~mJ2VJEMwVSgMs&i-fCC$<j3Ta7TnaHI zfPsa=_<#FUOB%s`o<(_?fpa+{+~BTAEc28AVg$@o3Qh9ZZiRSQXqbcbV+N<5<PxCF zGqN|;Bj`3?rfz<xKB)ss8JH$qCh@eUtgoj9U!2<~M<yJ>QQe*W{k<RH>U7AD7AH!Y zD6Yudm0f-s@j@ry$nNV=dyD#ax7VLPkV=3bUJU_aY;pF8pB4}}V1b49x#o|_FxTX_ zjq`5RVmyX5YPVV*avc_QDssv?j=Tp>uU5*ewr<F%rX9Zu638EbWESzNH9xglzVoPR zX&)Xw50E&QDb<x{Y*Dq~d<qdH4Oblxw%2a8n&f>Lly8{EL`~hSfK<IjEfHb88ZKxv z*oQEs-h>9-Z{sFzJ8h^Q_5f@jOGEk%$|fPYP%X+IfB-290j79{HQ+4Yo<TYqLqeP3 zOZN&eHZmlqf2<K-NlrCBFG{W~Kh&^fLk{3nHJg;|Y;QeXm)x$ZU9m$mCcwpJ`-?KM zWW{8wD7Ld9B%cKcbwZ2sEUVpILu9{6KN4Vx{!1YJG*^CPuX=4>S$RggF>jbcKFyh2 zGox;j>8eo{1(zMC@)x(Rn)5}k82texkHwl$=hpb!aE>zn3AEJ20R}Ta0(rL+R6!WV zr7k58LussixK_|;41}w$N>00JKH*B5j3OUEQw6txTNZ5Qu|BgW-T}bg%2MEemFBDz U{A=^GQsysf9Nu>QhyKI=0sNm4$^ZZW literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/retry.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/retry.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ad046a98cabf5f477da43440095e65d400c1e4b3 GIT binary patch literal 12663 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 PAyv=|=Ja1`^k@7Jx5W*b literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0e98679b3699bf3b9c82948de3b97aabc137a4d8 GIT binary patch literal 10001 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 N&3_835r6rm{{~s#zH$Hn literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..55409419f9f9ef562fde4c16d6a577ed77ff60f6 GIT binary patch literal 8779 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/url.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/url.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ff0cada0424f0ac81c0333d646789a0c441a666d GIT binary patch literal 5189 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/wait.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/wait.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a39b8fabd0efb6ac1b828f319c686ee43728d4c6 GIT binary patch literal 3162 zcmc&$&u<&Y6`q;>!6i*ew5`apow$ntP0Jt_oj7%CAPw9GR$w5Y3QL7u!svF%SxPG| zcj?)oBnr#6hy<hs+Mt)-t=<ackLh`@z106gPyODkM7Kf@MJ`?G&2P@k``-87o1ZQ% zH5k4>-0r`4@fKr$r_ROaq45Zk{|$v?k|(T3wMh6_^aQWQte$1&?4CVqp=Bk`*zLKT zJ!7eFv#2&|s2$Ge53@FA9h&_GOT}|09qG#2uGRBCXVR0-DMq6DiPdXF_Wl)FA35q& zHsqC4)@!DoY*sCKOD@ZmQ{G#Ww`EISMQd4Jlh?6oMXt)XP`Bioym89HtMYBRE?um+ zCf|`aWeu(Cl5ey2o!8Kcb=$nGO+uyPFhR3E&eBY0X*@v3*6}zhZ+5e1;cN#*tT!{Y zoef5jeymic%B4e$1;b1QDhg$}yyzaPSVsfe|Kj6lJc8s+6cOuj$$G-vLnsGB-L_SF zL6C;yC<w|%5R5Z9O{m=rf|t`Usb>Dl)D^5Y#XnVNqT+*4N1cOEb%t3YBb9f?d!50D zli=a;!~J`Q_lNR0e{lameRQOc$M^8<rk$P6B%a)j(_Dv1a`y*6?C*`H{aqR~5*$RS z%v5Kpk|gfm?@V=^bV#+0$;{k!iS!UCJl+<sEi_(}3IiIVk7|<7AUTn!U<E%R%z4+` zye&#GOv@VKn@#l_l@y^<E(1=jW<iz)ajI3DwlRBibrtQ!IW{`PUUSYjXcRzoR9EY$ z`G})FKi7<V>U|CFp76Oy8=9YB?gpESBQ^6b*4a!8ZSC7b0nYw~v$@6D@uR}pcO<{b zw7Xv$S!(}FmVUnww8J`^b8{9`zm=TY)d?e^{v<JX_~03F9{c>-dJe|FeDEAXW5B}d zDk4Q`#p$r^mCi89LahkRvbMEd5zNh_BpT?_i45QDQ0?ZXlV&~V@ssY()3&Wv@DtUd z-+2-=OyV>ud2|U>gWO##%HKu7c#C_&;|<Xef(x|QM2p*^!98yCCS-F!=+Z|BlX(rw z5{-iAtwQ82=nAWT$#>b@hByUR?-lkdUa&LHSs~QNg>%s}xLSo>IE8a!&s}X7Zeg8> z7uLKs_vUr&6t&5(3J+2@OcCAVkH*tn`}rgq#KV~%YCnlW3}k8KXG5Pn?#DZ78hzj! zZ!_(-TQ;9gQ{vS*fZ=2UHY=i!LVRNehtlq6S<-Hlb`EbYZR5R;*`@;0RfD|<Gwz|O z4aB9ZXx$8h=k<}PF9BVyRW=J2!GO+)^yfG{UqiuwF`-O<4HCBnYpC}yv%uU%hwvvh z<iA958FMM-Ht>G8ur=QoTd)A|zGr$C^)!EFpRwPw-?3K?*lnL7T7SicTw2mT_2!Ot zbq%(F1q|BGw?f<ScR(bjk7~N_bx3{-MFF0}8(XOPLpG<oVC;<Ifau2mz*>s2lPsaY z%QXs*IziUouP`;ipeD0`hKIB*;Zosu{9Uv56382$B-tQL@=rI;f7SNXZT!TTzI1=K z^~D!Yx@C>(t)K6x?_sL+RJ0rC8Xoozt)vLkcGVqfe}@X63gce(ILt@ted<#XZgUfw zs+hI<->%ccs!KLE7Ki<tR?|@(%nu;uBZ`u2K}?po@GlcB;174w%&)k0H+nfm;7_7d z`{6+tCt*K{a2;~fwoo@vmG0<}qQzx)uBKB!d<nLcj-<00S0AEW+=*;jhkORfe}rPT zrr9fg25T0mB_~fuo?ovbr-_>z=eb^NGvs$`yNY&p740^65U`9N8tj*UqP2?qQ(d{M zTE!6;urBgk1@N_CFFc5X!%U6hbk|Tq(XEIi%ti>~%lsO5g}RUaLIG0Bf*4TAa+;km z)zmx`>8iH0jSwc(+uA|j)@~@Ypk(lMMN)IqcFk;Qj8(2&Lawasg?R`iDy7JY4T9%Z zQ1@uyKQ&PwW9&DO>guk`UBm%b*xbx4vKw7}5qFo-(d1E-Z^R#gYTG*g%72Eeocnly zm~aSOe4Y9I=nW|lE&b5njgiv*Dh_Qle0)zMJymJ$Qvmhjp|AI%^Lanc&1OWY4}9#r z34dCwInUUBbTo-oB&*GKpsjHg@)DSj6vU8mAsV_20D1A(kcx8lx73)z_5V|2pEUa) zHLhXppWkTQwl+8M;G=?@|5de)*|I*IrUQ-Cl)p(>rIpWeMaiIg8(euZo@DC$0a^<J zJmK(2tUo>)L=zonsR;sQ^8iml^zeWJJ1C}^1Y<~S2wHKPETzaCif;ICb~2PT@z?vL qdWn8Yu^=acBY2q<CXlw^bE09jZs8$ed$$_b8>^n}EqN=A+P?t2t<IhR literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/connection.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/connection.py new file mode 100644 index 0000000..5cf488f --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/connection.py @@ -0,0 +1,126 @@ +from __future__ import absolute_import +import socket +from .wait import NoWayToWaitForSocketError, wait_for_read + + +def is_connection_dropped(conn): # Platform-specific + """ + Returns True if the connection is dropped and should be closed. + + :param conn: + :class:`httplib.HTTPConnection` object. + + 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) + if sock is False: # Platform-specific: AppEngine + return False + if sock is None: # Connection already closed (such as by httplib). + return True + try: + # Returns True if readable, which here means it's been dropped + return wait_for_read(sock, timeout=0.0) + except NoWayToWaitForSocketError: # Platform-specific: AppEngine + return False + + +# This function is copied from socket.py in the Python 2.7 standard +# 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): + """Connect to *address* and return the socket object. + + Convenience function. Connect to *address* (a 2-tuple ``(host, + port)``) and return the socket object. Passing the optional + *timeout* parameter will set the timeout on the socket instance + before attempting to connect. If no *timeout* is supplied, the + global default timeout setting returned by :func:`getdefaulttimeout` + is used. If *source_address* is set it must be a tuple of (host, port) + for the socket to bind as a source address before making the connection. + An host of '' or port 0 tells the OS to use the default. + """ + + host, port = address + if host.startswith('['): + host = host.strip('[]') + err = None + + # Using the value from allowed_gai_family() in the context of getaddrinfo lets + # us select whether to work with IPv4 DNS records, IPv6 records, or both. + # The original create_connection function always returns all records. + family = allowed_gai_family() + + for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): + af, socktype, proto, canonname, sa = res + sock = None + try: + sock = socket.socket(af, socktype, proto) + + # If provided, set socket level options before connecting. + _set_socket_options(sock, socket_options) + + if timeout is not socket._GLOBAL_DEFAULT_TIMEOUT: + sock.settimeout(timeout) + if source_address: + sock.bind(source_address) + sock.connect(sa) + return sock + + except socket.error as e: + err = e + if sock is not None: + sock.close() + sock = None + + if err is not None: + raise err + + raise socket.error("getaddrinfo returns an empty list") + + +def _set_socket_options(sock, options): + if options is None: + return + + for opt in options: + sock.setsockopt(*opt) + + +def allowed_gai_family(): + """This function is designed to work in the context of + getaddrinfo, where family=socket.AF_UNSPEC is the default and + will perform a DNS search for both IPv6 and IPv4 records.""" + + family = socket.AF_INET + if HAS_IPV6: + family = socket.AF_UNSPEC + return family + + +def _has_ipv6(host): + """ Returns True if the system can bind an IPv6 address. """ + sock = None + has_ipv6 = False + + if socket.has_ipv6: + # 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://bugs.python.org/issue658327 + try: + sock = socket.socket(socket.AF_INET6) + sock.bind((host, 0)) + has_ipv6 = True + except Exception: + pass + + if sock: + sock.close() + return has_ipv6 + + +HAS_IPV6 = _has_ipv6('::1') diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/queue.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/queue.py new file mode 100644 index 0000000..d3d379a --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/queue.py @@ -0,0 +1,21 @@ +import collections +from ..packages import six +from ..packages.six.moves import queue + +if six.PY2: + # Queue is imported for side effects on MS Windows. See issue #229. + import Queue as _unused_module_Queue # noqa: F401 + + +class LifoQueue(queue.Queue): + def _init(self, _): + self.queue = collections.deque() + + def _qsize(self, len=len): + return len(self.queue) + + def _put(self, item): + self.queue.append(item) + + def _get(self): + return self.queue.pop() diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/request.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/request.py new file mode 100644 index 0000000..3ddfcd5 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/request.py @@ -0,0 +1,118 @@ +from __future__ import absolute_import +from base64 import b64encode + +from ..packages.six import b, integer_types +from ..exceptions import UnrewindableBodyError + +ACCEPT_ENCODING = 'gzip,deflate' +_FAILEDTELL = object() + + +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. + + :param keep_alive: + If ``True``, adds 'connection: keep-alive' header. + + :param accept_encoding: + Can be a boolean, list, or string. + ``True`` translates to 'gzip,deflate'. + List will get joined by comma. + String will be used as provided. + + :param user_agent: + String representing the user-agent you want, such as + "python-urllib3/0.6" + + :param basic_auth: + Colon-separated username:password string for 'authorization: basic ...' + auth header. + + :param proxy_basic_auth: + Colon-separated username:password string for 'proxy-authorization: basic ...' + auth header. + + :param disable_cache: + If ``True``, adds 'cache-control: no-cache' header. + + Example:: + + >>> make_headers(keep_alive=True, user_agent="Batman/1.0") + {'connection': 'keep-alive', 'user-agent': 'Batman/1.0'} + >>> make_headers(accept_encoding=True) + {'accept-encoding': 'gzip,deflate'} + """ + headers = {} + if accept_encoding: + if isinstance(accept_encoding, str): + pass + elif isinstance(accept_encoding, list): + accept_encoding = ','.join(accept_encoding) + else: + accept_encoding = ACCEPT_ENCODING + headers['accept-encoding'] = accept_encoding + + if user_agent: + headers['user-agent'] = user_agent + + if keep_alive: + headers['connection'] = 'keep-alive' + + if basic_auth: + 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') + + if disable_cache: + headers['cache-control'] = 'no-cache' + + return headers + + +def set_file_position(body, pos): + """ + If a position is provided, move file to that point. + Otherwise, we'll attempt to record a position for future use. + """ + if pos is not None: + rewind_body(body, pos) + elif getattr(body, 'tell', None) is not None: + try: + pos = body.tell() + except (IOError, OSError): + # This differentiates from None, allowing us to catch + # a failed `tell()` later when trying to rewind the body. + pos = _FAILEDTELL + + return pos + + +def rewind_body(body, body_pos): + """ + Attempt to rewind body to a certain position. + Primarily used for request redirects and retries. + + :param body: + File-like object that supports seek. + + :param int pos: + Position to seek to in file. + """ + 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.") + elif body_pos is _FAILEDTELL: + 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)) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/response.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/response.py new file mode 100644 index 0000000..67cf730 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/response.py @@ -0,0 +1,81 @@ +from __future__ import absolute_import +from ..packages.six.moves import http_client as httplib + +from ..exceptions import HeaderParsingError + + +def is_fp_closed(obj): + """ + Checks whether a given file-like object is closed. + + :param obj: + The file-like object to check. + """ + + try: + # Check `isclosed()` first, in case Python3 doesn't set `closed`. + # GH Issue #928 + return obj.isclosed() + except AttributeError: + pass + + try: + # Check via the official file-like-object way. + return obj.closed + except AttributeError: + pass + + try: + # Check if the object is a container for another file-like object that + # gets released on exhaustion (e.g. HTTPResponse). + return obj.fp is None + except AttributeError: + pass + + raise ValueError("Unable to determine whether fp is closed.") + + +def assert_header_parsing(headers): + """ + Asserts whether all headers have been successfully parsed. + Extracts encountered errors from the result of parsing headers. + + Only works on Python 3. + + :param headers: Headers to verify. + :type headers: `httplib.HTTPMessage`. + + :raises urllib3.exceptions.HeaderParsingError: + If parsing errors are found. + """ + + # 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))) + + defects = getattr(headers, 'defects', None) + get_payload = getattr(headers, 'get_payload', None) + + unparsed_data = None + if get_payload: # Platform-specific: Python 3. + unparsed_data = get_payload() + + if defects or unparsed_data: + raise HeaderParsingError(defects=defects, unparsed_data=unparsed_data) + + +def is_response_to_head(response): + """ + Checks whether the request of a response has been a HEAD-request. + Handles the quirks of AppEngine. + + :param conn: + :type conn: :class:`httplib.HTTPResponse` + """ + # FIXME: Can we do this somehow without accessing private httplib _method? + method = response._method + if isinstance(method, int): # Platform-specific: Appengine + return method == 3 + return method.upper() == 'HEAD' diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/retry.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/retry.py new file mode 100644 index 0000000..7ad3dc6 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/retry.py @@ -0,0 +1,411 @@ +from __future__ import absolute_import +import time +import logging +from collections import namedtuple +from itertools import takewhile +import email +import re + +from ..exceptions import ( + ConnectTimeoutError, + MaxRetryError, + ProtocolError, + ReadTimeoutError, + ResponseError, + InvalidHeader, +) +from ..packages import six + + +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"]) + + +class Retry(object): + """ Retry configuration. + + Each retry attempt will create a new Retry object with updated values, so + they can be safely reused. + + Retries can be defined as a default for a pool:: + + retries = Retry(connect=5, read=2, redirect=5) + http = PoolManager(retries=retries) + response = http.request('GET', 'http://example.com/') + + Or per-request (which overrides the default for the pool):: + + response = http.request('GET', 'http://example.com/', retries=Retry(10)) + + Retries can be disabled by passing ``False``:: + + response = http.request('GET', 'http://example.com/', retries=False) + + Errors will be wrapped in :class:`~urllib3.exceptions.MaxRetryError` unless + retries are disabled, in which case the causing exception will be raised. + + :param int total: + Total number of retries to allow. Takes precedence over other counts. + + Set to ``None`` to remove this constraint and fall back on other + counts. It's a good idea to set this to some sensibly-high value to + account for unexpected edge cases and avoid infinite retry loops. + + Set to ``0`` to fail on the first retry. + + Set to ``False`` to disable and imply ``raise_on_redirect=False``. + + :param int connect: + How many connection-related errors to retry on. + + These are errors raised before the request is sent to the remote server, + which we assume has not triggered the server to process the request. + + Set to ``0`` to fail on the first retry of this type. + + :param int read: + How many times to retry on read errors. + + These errors are raised after the request was sent to the server, so the + request may have side-effects. + + Set to ``0`` to fail on the first retry of this type. + + :param int redirect: + How many redirects to perform. Limit this to avoid infinite redirect + loops. + + A redirect is a HTTP response with a status code 301, 302, 303, 307 or + 308. + + Set to ``0`` to fail on the first retry of this type. + + Set to ``False`` to disable and imply ``raise_on_redirect=False``. + + :param int status: + How many times to retry on bad status codes. + + These are retries made on responses, where status code matches + ``status_forcelist``. + + Set to ``0`` to fail on the first retry of this type. + + :param iterable method_whitelist: + Set of uppercased HTTP method verbs that we should retry on. + + By default, we only retry on methods which are considered to be + idempotent (multiple requests with the same parameters end with the + same state). See :attr:`Retry.DEFAULT_METHOD_WHITELIST`. + + Set to a ``False`` value to retry on any verb. + + :param iterable status_forcelist: + A set of integer HTTP status codes that we should force a retry on. + A retry is initiated if the request method is in ``method_whitelist`` + and the response status code is in ``status_forcelist``. + + By default, this is disabled with ``None``. + + :param float backoff_factor: + A backoff factor to apply between attempts after the second try + (most errors are resolved immediately by a second try without a + delay). urllib3 will sleep for:: + + {backoff factor} * (2 ^ ({number of total retries} - 1)) + + seconds. If the backoff_factor is 0.1, then :func:`.sleep` will sleep + for [0.0s, 0.2s, 0.4s, ...] between retries. It will never be longer + than :attr:`Retry.BACKOFF_MAX`. + + By default, backoff is disabled (set to 0). + + :param bool raise_on_redirect: Whether, if the number of redirects is + exhausted, to raise a MaxRetryError, or to return a response with a + response code in the 3xx range. + + :param bool raise_on_status: Similar meaning to ``raise_on_redirect``: + whether we should raise an exception, or return a response, + if status falls in ``status_forcelist`` range and retries have + been exhausted. + + :param tuple history: The history of the request encountered during + each call to :meth:`~Retry.increment`. The list is in the order + the requests occurred. Each list item is of class :class:`RequestHistory`. + + :param bool respect_retry_after_header: + Whether to respect Retry-After header on status codes defined as + :attr:`Retry.RETRY_AFTER_STATUS_CODES` or not. + + :param iterable remove_headers_on_redirect: + Sequence of headers to remove from the request when a response + indicating a redirect is returned before firing off the redirected + request. + """ + + DEFAULT_METHOD_WHITELIST = frozenset([ + 'HEAD', 'GET', 'PUT', 'DELETE', 'OPTIONS', 'TRACE']) + + RETRY_AFTER_STATUS_CODES = frozenset([413, 429, 503]) + + 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): + + self.total = total + self.connect = connect + self.read = read + self.status = status + + if redirect is False or total is False: + redirect = 0 + raise_on_redirect = False + + self.redirect = redirect + self.status_forcelist = status_forcelist or set() + self.method_whitelist = method_whitelist + self.backoff_factor = backoff_factor + self.raise_on_redirect = raise_on_redirect + 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 = 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, + 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 + ) + params.update(kw) + return type(self)(**params) + + @classmethod + def from_int(cls, retries, redirect=True, default=None): + """ Backwards-compatibility for the old retries format.""" + if retries is None: + retries = default if default is not None else cls.DEFAULT + + if isinstance(retries, Retry): + return retries + + redirect = bool(redirect) and None + new_retries = cls(retries, redirect=redirect) + log.debug("Converted retries value: %r -> %r", retries, new_retries) + return new_retries + + def get_backoff_time(self): + """ Formula for computing the current backoff + + :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)))) + if consecutive_errors_len <= 1: + return 0 + + backoff_value = self.backoff_factor * (2 ** (consecutive_errors_len - 1)) + return min(self.BACKOFF_MAX, backoff_value) + + def parse_retry_after(self, retry_after): + # Whitespace: https://tools.ietf.org/html/rfc7230#section-3.2.4 + if re.match(r"^\s*[0-9]+\s*$", retry_after): + seconds = int(retry_after) + else: + retry_date_tuple = email.utils.parsedate(retry_after) + if retry_date_tuple is None: + raise InvalidHeader("Invalid Retry-After header: %s" % retry_after) + retry_date = time.mktime(retry_date_tuple) + seconds = retry_date - time.time() + + if seconds < 0: + seconds = 0 + + return seconds + + def get_retry_after(self, response): + """ Get the value of Retry-After in seconds. """ + + retry_after = response.getheader("Retry-After") + + if retry_after is None: + return None + + return self.parse_retry_after(retry_after) + + def sleep_for_retry(self, response=None): + retry_after = self.get_retry_after(response) + if retry_after: + time.sleep(retry_after) + return True + + return False + + def _sleep_backoff(self): + backoff = self.get_backoff_time() + if backoff <= 0: + return + time.sleep(backoff) + + def sleep(self, response=None): + """ Sleep between retry attempts. + + This method will respect a server's ``Retry-After`` response header + and sleep the duration of the time requested. If that is not present, it + will use an exponential backoff. By default, the backoff factor is 0 and + this method will return immediately. + """ + + if response: + slept = self.sleep_for_retry(response) + if slept: + return + + self._sleep_backoff() + + def _is_connection_error(self, err): + """ Errors when we're fairly sure that the server did not receive the + request, so it should be safe to retry. + """ + return isinstance(err, ConnectTimeoutError) + + def _is_read_error(self, err): + """ Errors that occur after the request has been started, so we should + assume that the server began processing it. + """ + return isinstance(err, (ReadTimeoutError, ProtocolError)) + + def _is_method_retryable(self, method): + """ Checks if a given HTTP method should be retried upon, depending if + it is included on the method whitelist. + """ + if self.method_whitelist and method.upper() not in self.method_whitelist: + return False + + return True + + def is_retry(self, method, status_code, has_retry_after=False): + """ Is this method/status code retryable? (Based on whitelists and control + variables such as the number of total retries to allow, whether to + respect the Retry-After header, whether this header is present, and + whether the returned status code is on the list of status codes to + be retried upon on the presence of the aforementioned header) + """ + if not self._is_method_retryable(method): + return False + + 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)) + + def is_exhausted(self): + """ Are we out of retries? """ + retry_counts = (self.total, self.connect, self.read, self.redirect, self.status) + retry_counts = list(filter(None, retry_counts)) + if not retry_counts: + return False + + return min(retry_counts) < 0 + + 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 + return a response. + :type response: :class:`~urllib3.response.HTTPResponse` + :param Exception error: An error encountered during the request, or + None if the response was received successfully. + + :return: A new ``Retry`` object. + """ + if self.total is False and error: + # Disabled, indicate to re-raise the error. + raise six.reraise(type(error), error, _stacktrace) + + total = self.total + if total is not None: + total -= 1 + + connect = self.connect + read = self.read + redirect = self.redirect + status_count = self.status + cause = 'unknown' + status = None + redirect_location = None + + if error and self._is_connection_error(error): + # Connect retry? + if connect is False: + raise six.reraise(type(error), error, _stacktrace) + elif connect is not None: + connect -= 1 + + elif error and self._is_read_error(error): + # Read retry? + if read is False or not self._is_method_retryable(method): + raise six.reraise(type(error), error, _stacktrace) + elif read is not None: + read -= 1 + + elif response and response.get_redirect_location(): + # Redirect retry? + if redirect is not None: + redirect -= 1 + cause = 'too many redirects' + redirect_location = response.get_redirect_location() + status = response.status + + else: + # Incrementing because of a server error like a 500 in + # status_forcelist and a the given method is in the whitelist + cause = ResponseError.GENERIC_ERROR + if response and response.status: + if status_count is not None: + status_count -= 1 + cause = ResponseError.SPECIFIC_ERROR.format( + status_code=response.status) + status = response.status + + 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) + + if new_retry.is_exhausted(): + raise MaxRetryError(_pool, url, error or ResponseError(cause)) + + log.debug("Incremented Retry for (url='%s'): %r", url, new_retry) + + 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) + + +# For backwards compatibility (equivalent to pre-v1.9): +Retry.DEFAULT = Retry(3) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/ssl_.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/ssl_.py new file mode 100644 index 0000000..3254280 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/ssl_.py @@ -0,0 +1,396 @@ +from __future__ import absolute_import +import errno +import warnings +import hmac +import socket + +from binascii import hexlify, unhexlify +from hashlib import md5, sha1, sha256 + +from ..exceptions import SSLError, InsecurePlatformWarning, SNIMissingWarning +from ..packages import six + + +SSLContext = None +HAS_SNI = False +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, +} + + +def _const_compare_digest_backport(a, b): + """ + Compare two digests of equal length in constant time. + + The digests must be of type str/bytes. + Returns True if the digests match, and False otherwise. + """ + result = abs(len(a) - len(b)) + for l, r in zip(bytearray(a), bytearray(b)): + result |= l ^ r + return result == 0 + + +_const_compare_digest = getattr(hmac, 'compare_digest', + _const_compare_digest_backport) + + +try: # Test for SSL features + import ssl + from ssl import wrap_socket, CERT_NONE, PROTOCOL_SSLv23 + from ssl import HAS_SNI # Has SNI? +except ImportError: + pass + + +try: + from ssl import OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_COMPRESSION +except ImportError: + OP_NO_SSLv2, OP_NO_SSLv3 = 0x1000000, 0x2000000 + OP_NO_COMPRESSION = 0x20000 + + +# Python 2.7 and earlier didn't have inet_pton on non-Linux +# so we fallback on inet_aton in those cases. This means that +# we can only detect IPv4 addresses in this case. +if hasattr(socket, 'inet_pton'): + inet_pton = socket.inet_pton +else: + # Maybe we can use ipaddress if the user has urllib3[secure]? + try: + from pip._vendor import ipaddress + + def inet_pton(_, host): + if isinstance(host, six.binary_type): + host = host.decode('ascii') + return ipaddress.ip_address(host) + + except ImportError: # Platform-specific: Non-Linux + def inet_pton(_, host): + return socket.inet_aton(host) + + +# A secure default. +# Sources for more information on TLS ciphers: +# +# - https://wiki.mozilla.org/Security/Server_Side_TLS +# - https://www.ssllabs.com/projects/best-practices/index.html +# - https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/ +# +# The general intent is: +# - Prefer TLS 1.3 cipher suites +# - prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE), +# - prefer ECDHE over DHE for better performance, +# - prefer any AES-GCM and ChaCha20 over any AES-CBC for better performance and +# security, +# - prefer AES-GCM over ChaCha20 because hardware-accelerated AES is common, +# - disable NULL authentication, MD5 MACs and DSS for security reasons. +DEFAULT_CIPHERS = ':'.join([ + 'TLS13-AES-256-GCM-SHA384', + 'TLS13-CHACHA20-POLY1305-SHA256', + 'TLS13-AES-128-GCM-SHA256', + 'ECDH+AESGCM', + 'ECDH+CHACHA20', + 'DH+AESGCM', + 'DH+CHACHA20', + 'ECDH+AES256', + 'DH+AES256', + 'ECDH+AES128', + 'DH+AES', + 'RSA+AESGCM', + 'RSA+AES', + '!aNULL', + '!eNULL', + '!MD5', +]) + +try: + from ssl import SSLContext # Modern SSL? +except ImportError: + import sys + + class SSLContext(object): # Platform-specific: Python 2 & 3.1 + supports_set_ciphers = ((2, 7) <= sys.version_info < (3,) or + (3, 2) <= sys.version_info) + + def __init__(self, protocol_version): + self.protocol = protocol_version + # Use default values from a real SSLContext + self.check_hostname = False + self.verify_mode = ssl.CERT_NONE + self.ca_certs = None + self.options = 0 + self.certfile = None + self.keyfile = None + self.ciphers = None + + def load_cert_chain(self, certfile, keyfile): + self.certfile = certfile + self.keyfile = keyfile + + def load_verify_locations(self, cafile=None, capath=None): + self.ca_certs = cafile + + if capath is not None: + raise SSLError("CA directories not supported in older Pythons") + + def set_ciphers(self, cipher_suite): + if not self.supports_set_ciphers: + raise TypeError( + 'Your version of Python does not support setting ' + 'a custom cipher suite. Please upgrade to Python ' + '2.7, 3.2, or later if you need this functionality.' + ) + 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 + ) + 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, + } + if self.supports_set_ciphers: # Platform-specific: Python 2.7+ + return wrap_socket(socket, ciphers=self.ciphers, **kwargs) + else: # Platform-specific: Python 2.6 + return wrap_socket(socket, **kwargs) + + +def assert_fingerprint(cert, fingerprint): + """ + Checks if given fingerprint matches the supplied certificate. + + :param cert: + Certificate as bytes object. + :param fingerprint: + Fingerprint as string of hexdigits, can be interspersed by colons. + """ + + 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)) + + # We need encode() here for py32; works on py2 and p33. + fingerprint_bytes = unhexlify(fingerprint.encode()) + + 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))) + + +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`. + 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`. + If it's neither `None` nor a string we assume it is already the numeric + constant which can directly be passed to wrap_socket. + """ + if candidate is None: + return CERT_NONE + + if isinstance(candidate, str): + res = getattr(ssl, candidate, None) + if res is None: + res = getattr(ssl, 'CERT_' + candidate) + return res + + return candidate + + +def resolve_ssl_version(candidate): + """ + like resolve_cert_reqs + """ + if candidate is None: + return PROTOCOL_SSLv23 + + if isinstance(candidate, str): + res = getattr(ssl, candidate, None) + if res is None: + res = getattr(ssl, 'PROTOCOL_' + candidate) + return res + + return candidate + + +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 + ``ssl.create_default_context`` does on Python 3.4+. It: + + - Disables SSLv2, SSLv3, and compression + - Sets a restricted set of server ciphers + + If you wish to enable SSLv3, you can do:: + + from pip._vendor.urllib3.util import ssl_ + context = ssl_.create_urllib3_context() + context.options &= ~ssl_.OP_NO_SSLv3 + + You can do the same to enable compression (substituting ``COMPRESSION`` + for ``SSLv3`` in the last line above). + + :param ssl_version: + The desired protocol version to use. This will default to + PROTOCOL_SSLv23 which will negotiate the highest protocol that both + the server and your installation of OpenSSL support. + :param cert_reqs: + Whether to require the certificate verification. This defaults to + ``ssl.CERT_REQUIRED``. + :param options: + Specific OpenSSL options. These default to ``ssl.OP_NO_SSLv2``, + ``ssl.OP_NO_SSLv3``, ``ssl.OP_NO_COMPRESSION``. + :param ciphers: + Which cipher suites to allow the server to select. + :returns: + Constructed SSLContext object with specified options + :rtype: SSLContext + """ + context = SSLContext(ssl_version or ssl.PROTOCOL_SSLv23) + + # Setting the default here, as we may have no ssl module on import + cert_reqs = ssl.CERT_REQUIRED if cert_reqs is None else cert_reqs + + if options is None: + options = 0 + # SSLv2 is easily broken and is considered harmful and dangerous + options |= OP_NO_SSLv2 + # SSLv3 has several problems and is now dangerous + options |= OP_NO_SSLv3 + # Disable compression to prevent CRIME attacks for OpenSSL 1.0+ + # (issue #309) + options |= OP_NO_COMPRESSION + + context.options |= options + + if getattr(context, 'supports_set_ciphers', True): # Platform-specific: Python 2.6 + context.set_ciphers(ciphers or DEFAULT_CIPHERS) + + context.verify_mode = cert_reqs + 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): + """ + 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`. + + :param server_hostname: + When SNI is supported, the expected hostname of the certificate + :param ssl_context: + A pre-made :class:`SSLContext` object. If none is provided, one will + be created using :func:`create_urllib3_context`. + :param ciphers: + A string of ciphers we wish the client to support. This is not + supported on Python 2.6 as the ssl module does not support it. + :param ca_cert_dir: + A directory containing CA certificates in multiple separate files, as + supported by OpenSSL's -CApath flag or the capath argument 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) + + if ca_certs or ca_cert_dir: + try: + context.load_verify_locations(ca_certs, ca_cert_dir) + except IOError as e: # Platform-specific: Python 2.6, 2.7, 3.2 + raise SSLError(e) + # Py33 raises FileNotFoundError which subclasses OSError + # These are not equivalent unless we check the errno attribute + except OSError as e: # Platform-specific: Python 3.3 and beyond + if e.errno == errno.ENOENT: + raise SSLError(e) + raise + elif getattr(context, 'load_default_certs', None) is not None: + # try to load OS default certs; works well on Windows (require Python3.4+) + context.load_default_certs() + + if certfile: + context.load_cert_chain(certfile, keyfile) + + # If we detect server_hostname is an IP address then the SNI + # 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 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 + ) + + return context.wrap_socket(sock) + + +def is_ipaddress(hostname): + """Detects whether the hostname given is an IP address. + + :param str hostname: Hostname to examine. + :return: True if the hostname is an IP address, False otherwise. + """ + if six.PY3 and isinstance(hostname, six.binary_type): + # IDN A-label bytes are ASCII compatible. + hostname = hostname.decode('ascii') + + families = [socket.AF_INET] + if hasattr(socket, 'AF_INET6'): + families.append(socket.AF_INET6) + + for af in families: + try: + inet_pton(af, hostname) + except (socket.error, ValueError, OSError): + pass + else: + return True + return False diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/timeout.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/timeout.py new file mode 100644 index 0000000..cec817e --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/timeout.py @@ -0,0 +1,242 @@ +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 +import time + +from ..exceptions import TimeoutStateError + +# A sentinel value to indicate that no timeout was specified by the user in +# urllib3 +_Default = object() + + +# Use time.monotonic if available. +current_time = getattr(time, "monotonic", time.time) + + +class Timeout(object): + """ Timeout configuration. + + Timeouts can be defined as a default for a pool:: + + timeout = Timeout(connect=2.0, read=7.0) + http = PoolManager(timeout=timeout) + response = http.request('GET', 'http://example.com/') + + Or per-request (which overrides the default for the pool):: + + response = http.request('GET', 'http://example.com/', timeout=Timeout(10)) + + Timeouts can be disabled by setting all the parameters to ``None``:: + + no_timeout = Timeout(connect=None, read=None) + response = http.request('GET', 'http://example.com/, timeout=no_timeout) + + + :param total: + This combines the connect and read timeouts into one; the read timeout + will be set to the time leftover from the connect attempt. In the + event that both a connect timeout and a total are specified, or a read + timeout and a total are specified, the shorter timeout will be applied. + + Defaults to None. + + :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 + <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 + <http://hg.python.org/cpython/file/603b4d593758/Lib/socket.py#l535>`_. + None will set an infinite timeout. + + :type read: integer, float, or None + + .. note:: + + Many factors can affect the total amount of time for urllib3 to return + an HTTP response. + + For example, Python's DNS resolver does not obey the timeout specified + on the socket. Other factors that can affect total request time include + high CPU load, high swap, the program running at a low priority level, + or other behaviors. + + In addition, the read and total timeouts only measure the time between + read operations on the socket connecting the client and the server, + not the total amount of time for the request to return a complete + response. For most requests, the timeout is raised because the server + has not sent the first byte in the specified time. This is not always + the case; if a server streams one byte every fifteen seconds, a timeout + of 20 seconds will not trigger, even though the request will take + several minutes to complete. + + If your goal is to cut off any request after a set amount of wall clock + time, consider having a second "watcher" thread to cut off a slow + request. + """ + + #: A sentinel object representing the default timeout value + 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._start_connect = None + + def __str__(self): + return '%s(connect=%r, read=%r, total=%r)' % ( + type(self).__name__, self._connect, self._read, self.total) + + @classmethod + def _validate_timeout(cls, value, name): + """ Check that a timeout attribute is valid. + + :param value: The timeout value to validate + :param name: The name of the timeout attribute to validate. This is + used to specify in error messages. + :return: The validated and casted version of the given value. + :raises ValueError: If it is a numeric value less than or equal to + zero, or the type is not an integer, float, or None. + """ + if value is _Default: + return cls.DEFAULT_TIMEOUT + + if value is None or value is cls.DEFAULT_TIMEOUT: + return value + + if isinstance(value, bool): + 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)) + + 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)) + except TypeError: # Python 3 + raise ValueError("Timeout value %s was %s, but it must be an " + "int, float or None." % (name, value)) + + return value + + @classmethod + def from_float(cls, timeout): + """ Create a new Timeout from a legacy timeout value. + + The timeout value used by httplib.py sets the same timeout on the + connect(), and recv() socket requests. This creates a :class:`Timeout` + object that sets the individual timeouts to the ``timeout`` value + passed to this function. + + :param timeout: The legacy timeout value. + :type timeout: integer, float, sentinel default object, or None + :return: Timeout object + :rtype: :class:`Timeout` + """ + return Timeout(read=timeout, connect=timeout) + + def clone(self): + """ Create a copy of the timeout object + + Timeout properties are stored per-pool but each request needs a fresh + Timeout object to ensure each one has its own start/stop configured. + + :return: a copy of the timeout object + :rtype: :class:`Timeout` + """ + # 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) + + def start_connect(self): + """ Start the timeout clock, used during a connect() attempt + + :raises urllib3.exceptions.TimeoutStateError: if you attempt + to start a timer that has been started already. + """ + if self._start_connect is not None: + raise TimeoutStateError("Timeout timer has already been started.") + self._start_connect = current_time() + return self._start_connect + + def get_connect_duration(self): + """ Gets the time elapsed since the call to :meth:`start_connect`. + + :return: Elapsed time. + :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.") + return current_time() - self._start_connect + + @property + def connect_timeout(self): + """ Get the value to use when setting a connection timeout. + + This will be a positive float or integer, the value None + (never timeout), or the default system timeout. + + :return: Connect timeout. + :rtype: int, float, :attr:`Timeout.DEFAULT_TIMEOUT` or None + """ + if self.total is None: + return self._connect + + if self._connect is None or self._connect is self.DEFAULT_TIMEOUT: + return self.total + + return min(self._connect, self.total) + + @property + def read_timeout(self): + """ Get the value for the read timeout. + + This assumes some time has elapsed in the connection timeout and + computes the read timeout appropriately. + + If self.total is set, the read timeout is dependent on the amount of + time taken by the connect timeout. If the connection time has not been + established, a :exc:`~urllib3.exceptions.TimeoutStateError` will be + raised. + + :return: Value to use for the read timeout. + :rtype: int, float, :attr:`Timeout.DEFAULT_TIMEOUT` or None + :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): + # 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)) + elif self.total is not None and self.total is not self.DEFAULT_TIMEOUT: + return max(0, self.total - self.get_connect_duration()) + else: + return self._read diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/url.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/url.py new file mode 100644 index 0000000..6b6f996 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/url.py @@ -0,0 +1,230 @@ +from __future__ import absolute_import +from collections import namedtuple + +from ..exceptions import LocationParseError + + +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) + + +class Url(namedtuple('Url', url_attrs)): + """ + Datastructure 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 + if scheme: + scheme = scheme.lower() + if host and scheme in NORMALIZABLE_SCHEMES: + host = host.lower() + return super(Url, cls).__new__(cls, scheme, auth, host, port, path, + query, fragment) + + @property + def hostname(self): + """For backwards-compatibility with urlparse. We're nice like that.""" + return self.host + + @property + def request_uri(self): + """Absolute path including the query string.""" + uri = self.path or '/' + + if self.query is not None: + uri += '?' + self.query + + return uri + + @property + def netloc(self): + """Network location including host and port""" + if self.port: + return '%s:%d' % (self.host, self.port) + return self.host + + @property + def url(self): + """ + Convert self into a url + + This function should more or less round-trip with :func:`.parse_url`. The + returned url may not be exactly the same as the url inputted to + :func:`.parse_url`, but it should be equivalent by the RFC (e.g., urls + with a blank port will have : removed). + + Example: :: + + >>> U = parse_url('http://google.com/mail/') + >>> U.url + 'http://google.com/mail/' + >>> Url('http', 'username:password', 'host.com', 80, + ... '/path', 'query', 'fragment').url + 'http://username:password@host.com:80/path?query#fragment' + """ + scheme, auth, host, port, path, query, fragment = self + url = '' + + # We use "is not None" we want things to happen with empty strings (or 0 port) + if scheme is not None: + url += scheme + '://' + if auth is not None: + url += auth + '@' + if host is not None: + url += host + if port is not None: + url += ':' + str(port) + if path is not None: + url += path + if query is not None: + url += '?' + query + if fragment is not None: + url += '#' + fragment + + return url + + def __str__(self): + return self.url + + +def split_first(s, delims): + """ + Given a string and an iterable of delimiters, split on the first found + delimiter. Return two split parts and the matched delimiter. + + If not found, then the first part is the full input string. + + Example:: + + >>> split_first('foo/bar?baz', '?/=') + ('foo', 'bar?baz', '/') + >>> split_first('foo/bar?baz', '123') + ('foo/bar?baz', '', None) + + Scales linearly with number of delims. Not ideal for large number of delims. + """ + min_idx = None + min_delim = None + for d in delims: + idx = s.find(d) + if idx < 0: + continue + + if min_idx is None or idx < min_idx: + min_idx = idx + min_delim = d + + if min_idx is None or min_idx < 0: + return s, '', None + + return s[:min_idx], s[min_idx + 1:], min_delim + + +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. + + Partly backwards-compatible with :mod:`urlparse`. + + Example:: + + >>> parse_url('http://google.com/mail/') + Url(scheme='http', host='google.com', port=None, path='/mail/', ...) + >>> parse_url('google.com:80') + Url(scheme=None, host='google.com', port=80, path=None, ...) + >>> parse_url('/foo?bar') + Url(scheme=None, host=None, port=None, path='/foo', query='bar', ...) + """ + + # While this code has overlap with stdlib's urlparse, it is much + # simplified for our needs and less annoying. + # Additionally, this implementations does silly things to be optimal + # on CPython. + + if not url: + # Empty + return Url() + + scheme = None + auth = None + host = None + port = None + path = None + fragment = None + query = None + + # Scheme + if '://' in url: + scheme, url = url.split('://', 1) + + # Find the earliest Authority Terminator + # (http://tools.ietf.org/html/rfc3986#section-3.2) + url, path_, delim = split_first(url, ['/', '?', '#']) + + if delim: + # Reassemble the path + path = delim + path_ + + # Auth + if '@' in url: + # Last '@' denotes end of auth part + auth, url = url.rsplit('@', 1) + + # IPv6 + if url and url[0] == '[': + host, url = url.split(']', 1) + host += ']' + + # Port + if ':' in url: + _host, port = url.split(':', 1) + + if not host: + host = _host + + if port: + # If given, ports must be integers. No whitespace, no plus or + # minus prefixes, no non-integer digits such as ^2 (superscript). + if not port.isdigit(): + raise LocationParseError(url) + try: + port = int(port) + except ValueError: + raise LocationParseError(url) + else: + # Blank ports are cool, too. (rfc3986#section-3.2.3) + port = None + + elif not host and url: + host = url + + if not path: + return Url(scheme, auth, host, port, path, query, fragment) + + # Fragment + if '#' in path: + path, fragment = path.split('#', 1) + + # Query + if '?' in path: + path, query = path.split('?', 1) + + return Url(scheme, auth, host, port, path, query, fragment) + + +def get_host(url): + """ + Deprecated. Use :func:`parse_url` instead. + """ + p = parse_url(url) + return p.scheme or 'http', p.hostname, p.port diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/wait.py b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/wait.py new file mode 100644 index 0000000..fa686ef --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/wait.py @@ -0,0 +1,153 @@ +import errno +from functools import partial +import select +import sys +try: + from time import monotonic +except ImportError: + from time import time as monotonic + +__all__ = ["NoWayToWaitForSocketError", "wait_for_read", "wait_for_write"] + + +class NoWayToWaitForSocketError(Exception): + pass + + +# How should we wait on sockets? +# +# There are two types of APIs you can use for waiting on sockets: the fancy +# modern stateful APIs like epoll/kqueue, and the older stateless APIs like +# select/poll. The stateful APIs are more efficient when you have a lots of +# sockets to keep track of, because you can set them up once and then use them +# lots of times. But we only ever want to wait on a single socket at a time +# and don't want to keep track of state, so the stateless APIs are actually +# more efficient. So we want to use select() or poll(). +# +# Now, how do we choose between select() and poll()? On traditional Unixes, +# select() has a strange calling convention that makes it slow, or fail +# altogether, for high-numbered file descriptors. The point of poll() is to fix +# that, so on Unixes, we prefer poll(). +# +# On Windows, there is no poll() (or at least Python doesn't provide a wrapper +# for it), but that's OK, because on Windows, select() doesn't have this +# strange calling convention; plain select() works fine. +# +# So: on Windows we use select(), and everywhere else we use poll(). We also +# fall back to select() in case poll() is somehow broken or missing. + +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): + if timeout is not None and timeout <= 0: + return fn(timeout) + + if timeout is None: + deadline = float("inf") + else: + deadline = monotonic() + timeout + + while True: + try: + return fn(timeout) + # OSError for 3 <= pyver < 3.5, select.error for pyver <= 2.7 + except (OSError, select.error) as e: + # 'e.args[0]' incantation works for both OSError and select.error + if e.args[0] != errno.EINTR: + raise + else: + timeout = deadline - monotonic() + if timeout < 0: + timeout = 0 + if timeout == float("inf"): + timeout = None + continue + + +def select_wait_for_socket(sock, read=False, write=False, timeout=None): + if not read and not write: + raise RuntimeError("must specify at least one of read=True, write=True") + rcheck = [] + wcheck = [] + if read: + rcheck.append(sock) + if write: + wcheck.append(sock) + # When doing a non-blocking connect, most systems signal success by + # marking the socket writable. Windows, though, signals success by marked + # it as "exceptional". We paper over the difference by checking the write + # sockets for both conditions. (The stdlib selectors module does the same + # thing.) + fn = partial(select.select, rcheck, wcheck, wcheck) + rready, wready, xready = _retry_on_intr(fn, timeout) + return bool(rready or wready or xready) + + +def poll_wait_for_socket(sock, read=False, write=False, timeout=None): + if not read and not write: + raise RuntimeError("must specify at least one of read=True, write=True") + mask = 0 + if read: + mask |= select.POLLIN + if write: + mask |= select.POLLOUT + poll_obj = select.poll() + poll_obj.register(sock, mask) + + # For some reason, poll() takes timeout in milliseconds + def do_poll(t): + if t is not None: + t *= 1000 + return poll_obj.poll(t) + + return bool(_retry_on_intr(do_poll, timeout)) + + +def null_wait_for_socket(*args, **kwargs): + raise NoWayToWaitForSocketError("no select-equivalent available") + + +def _have_working_poll(): + # Apparently some systems have a select.poll that fails as soon as you try + # to use it, either due to strange configuration or broken monkeypatching + # from libraries like eventlet/greenlet. + try: + poll_obj = select.poll() + poll_obj.poll(0) + except (AttributeError, OSError): + return False + else: + return True + + +def wait_for_socket(*args, **kwargs): + # We delay choosing which implementation to use until the first time we're + # called. We could do it at import time, but then we might make the wrong + # decision if someone goes wild with monkeypatching select.poll after + # we're imported. + global wait_for_socket + if _have_working_poll(): + wait_for_socket = poll_wait_for_socket + elif hasattr(select, "select"): + wait_for_socket = select_wait_for_socket + else: # Platform-specific: Appengine. + wait_for_socket = null_wait_for_socket + return wait_for_socket(*args, **kwargs) + + +def wait_for_read(sock, timeout=None): + """ Waits for reading to be available on a given socket. + Returns True if the socket is readable, or False if the timeout expired. + """ + return wait_for_socket(sock, read=True, timeout=timeout) + + +def wait_for_write(sock, timeout=None): + """ Waits for writing to be available on a given socket. + Returns True if the socket is readable, or False if the timeout expired. + """ + return wait_for_socket(sock, write=True, timeout=timeout) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/webencodings/__init__.py b/venv/lib/python3.7/site-packages/pip/_vendor/webencodings/__init__.py new file mode 100644 index 0000000..d21d697 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/webencodings/__init__.py @@ -0,0 +1,342 @@ +# coding: utf-8 +""" + + webencodings + ~~~~~~~~~~~~ + + This is a Python implementation of the `WHATWG Encoding standard + <http://encoding.spec.whatwg.org/>`. See README for details. + + :copyright: Copyright 2012 by Simon Sapin + :license: BSD, see LICENSE for details. + +""" + +from __future__ import unicode_literals + +import codecs + +from .labels import LABELS + + +VERSION = '0.5.1' + + +# Some names in Encoding are not valid Python aliases. Remap these. +PYTHON_NAMES = { + 'iso-8859-8-i': 'iso-8859-8', + 'x-mac-cyrillic': 'mac-cyrillic', + 'macintosh': 'mac-roman', + 'windows-874': 'cp874'} + +CACHE = {} + + +def ascii_lower(string): + r"""Transform (only) ASCII letters to lower case: A-Z is mapped to a-z. + + :param string: An Unicode string. + :returns: A new Unicode string. + + This is used for `ASCII case-insensitive + <http://encoding.spec.whatwg.org/#ascii-case-insensitive>`_ + matching of encoding labels. + The same matching is also used, among other things, + for `CSS keywords <http://dev.w3.org/csswg/css-values/#keywords>`_. + + This is different from the :meth:`~py:str.lower` method of Unicode strings + which also affect non-ASCII characters, + sometimes mapping them into the ASCII range: + + >>> keyword = u'Bac\N{KELVIN SIGN}ground' + >>> assert keyword.lower() == u'background' + >>> assert ascii_lower(keyword) != keyword.lower() + >>> assert ascii_lower(keyword) == u'bac\N{KELVIN SIGN}ground' + + """ + # This turns out to be faster than unicode.translate() + return string.encode('utf8').lower().decode('utf8') + + +def lookup(label): + """ + Look for an encoding by its label. + This is the spec’s `get an encoding + <http://encoding.spec.whatwg.org/#concept-encoding-get>`_ algorithm. + Supported labels are listed there. + + :param label: A string. + :returns: + An :class:`Encoding` object, or :obj:`None` for an unknown label. + + """ + # Only strip ASCII whitespace: U+0009, U+000A, U+000C, U+000D, and U+0020. + label = ascii_lower(label.strip('\t\n\f\r ')) + name = LABELS.get(label) + if name is None: + return None + encoding = CACHE.get(name) + if encoding is None: + if name == 'x-user-defined': + from .x_user_defined import codec_info + else: + python_name = PYTHON_NAMES.get(name, name) + # Any python_name value that gets to here should be valid. + codec_info = codecs.lookup(python_name) + encoding = Encoding(name, codec_info) + CACHE[name] = encoding + return encoding + + +def _get_encoding(encoding_or_label): + """ + Accept either an encoding object or label. + + :param encoding: An :class:`Encoding` object or a label string. + :returns: An :class:`Encoding` object. + :raises: :exc:`~exceptions.LookupError` for an unknown label. + + """ + if hasattr(encoding_or_label, 'codec_info'): + return encoding_or_label + + encoding = lookup(encoding_or_label) + if encoding is None: + raise LookupError('Unknown encoding label: %r' % encoding_or_label) + return encoding + + +class Encoding(object): + """Reresents a character encoding such as UTF-8, + that can be used for decoding or encoding. + + .. attribute:: name + + Canonical name of the encoding + + .. attribute:: codec_info + + The actual implementation of the encoding, + a stdlib :class:`~codecs.CodecInfo` object. + See :func:`codecs.register`. + + """ + def __init__(self, name, codec_info): + self.name = name + self.codec_info = codec_info + + def __repr__(self): + return '<Encoding %s>' % self.name + + +#: The UTF-8 encoding. Should be used for new content and formats. +UTF8 = lookup('utf-8') + +_UTF16LE = lookup('utf-16le') +_UTF16BE = lookup('utf-16be') + + +def decode(input, fallback_encoding, errors='replace'): + """ + Decode a single string. + + :param input: A byte string + :param fallback_encoding: + An :class:`Encoding` object or a label string. + The encoding to use if :obj:`input` does note have a BOM. + :param errors: Type of error handling. See :func:`codecs.register`. + :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. + :return: + A ``(output, encoding)`` tuple of an Unicode string + and an :obj:`Encoding`. + + """ + # Fail early if `encoding` is an invalid label. + fallback_encoding = _get_encoding(fallback_encoding) + bom_encoding, input = _detect_bom(input) + encoding = bom_encoding or fallback_encoding + return encoding.codec_info.decode(input, errors)[0], encoding + + +def _detect_bom(input): + """Return (bom_encoding, input), with any BOM removed from the input.""" + if input.startswith(b'\xFF\xFE'): + return _UTF16LE, input[2:] + if input.startswith(b'\xFE\xFF'): + return _UTF16BE, input[2:] + if input.startswith(b'\xEF\xBB\xBF'): + return UTF8, input[3:] + return None, input + + +def encode(input, encoding=UTF8, errors='strict'): + """ + Encode a single string. + + :param input: An Unicode string. + :param encoding: An :class:`Encoding` object or a label string. + :param errors: Type of error handling. See :func:`codecs.register`. + :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. + :return: A byte string. + + """ + return _get_encoding(encoding).codec_info.encode(input, errors)[0] + + +def iter_decode(input, fallback_encoding, errors='replace'): + """ + "Pull"-based decoder. + + :param input: + An iterable of byte strings. + + The input is first consumed just enough to determine the encoding + based on the precense of a BOM, + then consumed on demand when the return value is. + :param fallback_encoding: + An :class:`Encoding` object or a label string. + The encoding to use if :obj:`input` does note have a BOM. + :param errors: Type of error handling. See :func:`codecs.register`. + :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. + :returns: + An ``(output, encoding)`` tuple. + :obj:`output` is an iterable of Unicode strings, + :obj:`encoding` is the :obj:`Encoding` that is being used. + + """ + + decoder = IncrementalDecoder(fallback_encoding, errors) + generator = _iter_decode_generator(input, decoder) + encoding = next(generator) + return generator, encoding + + +def _iter_decode_generator(input, decoder): + """Return a generator that first yields the :obj:`Encoding`, + then yields output chukns as Unicode strings. + + """ + decode = decoder.decode + input = iter(input) + for chunck in input: + output = decode(chunck) + if output: + assert decoder.encoding is not None + yield decoder.encoding + yield output + break + else: + # Input exhausted without determining the encoding + output = decode(b'', final=True) + assert decoder.encoding is not None + yield decoder.encoding + if output: + yield output + return + + for chunck in input: + output = decode(chunck) + if output: + yield output + output = decode(b'', final=True) + if output: + yield output + + +def iter_encode(input, encoding=UTF8, errors='strict'): + """ + “Pull”-based encoder. + + :param input: An iterable of Unicode strings. + :param encoding: An :class:`Encoding` object or a label string. + :param errors: Type of error handling. See :func:`codecs.register`. + :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. + :returns: An iterable of byte strings. + + """ + # Fail early if `encoding` is an invalid label. + encode = IncrementalEncoder(encoding, errors).encode + return _iter_encode_generator(input, encode) + + +def _iter_encode_generator(input, encode): + for chunck in input: + output = encode(chunck) + if output: + yield output + output = encode('', final=True) + if output: + yield output + + +class IncrementalDecoder(object): + """ + “Push”-based decoder. + + :param fallback_encoding: + An :class:`Encoding` object or a label string. + The encoding to use if :obj:`input` does note have a BOM. + :param errors: Type of error handling. See :func:`codecs.register`. + :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. + + """ + def __init__(self, fallback_encoding, errors='replace'): + # Fail early if `encoding` is an invalid label. + self._fallback_encoding = _get_encoding(fallback_encoding) + self._errors = errors + self._buffer = b'' + self._decoder = None + #: The actual :class:`Encoding` that is being used, + #: or :obj:`None` if that is not determined yet. + #: (Ie. if there is not enough input yet to determine + #: if there is a BOM.) + self.encoding = None # Not known yet. + + def decode(self, input, final=False): + """Decode one chunk of the input. + + :param input: A byte string. + :param final: + Indicate that no more input is available. + Must be :obj:`True` if this is the last call. + :returns: An Unicode string. + + """ + decoder = self._decoder + if decoder is not None: + return decoder(input, final) + + input = self._buffer + input + encoding, input = _detect_bom(input) + if encoding is None: + if len(input) < 3 and not final: # Not enough data yet. + self._buffer = input + return '' + else: # No BOM + encoding = self._fallback_encoding + decoder = encoding.codec_info.incrementaldecoder(self._errors).decode + self._decoder = decoder + self.encoding = encoding + return decoder(input, final) + + +class IncrementalEncoder(object): + """ + “Push”-based encoder. + + :param encoding: An :class:`Encoding` object or a label string. + :param errors: Type of error handling. See :func:`codecs.register`. + :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. + + .. method:: encode(input, final=False) + + :param input: An Unicode string. + :param final: + Indicate that no more input is available. + Must be :obj:`True` if this is the last call. + :returns: A byte string. + + """ + def __init__(self, encoding=UTF8, errors='strict'): + encoding = _get_encoding(encoding) + self.encode = encoding.codec_info.incrementalencoder(errors).encode diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..da464d04088b4a032f05615a8fbf3364fc5bc344 GIT binary patch literal 9684 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 a?zKF9Udj~a^Ha04g*WnIb}nC-yY|2OuP%uI literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/labels.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/labels.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a3b77a0f1ef7ad230cc1ba80d8262ac8bf9a5a3b GIT binary patch literal 4098 zcmeHKOK;>v5T3kdCX?4bcrOcvg@wR6<Hy)zM+m_#dq7(D5>6{5%XW8WI^(fNZcmc+ zfnUH+;13{i=D-hGq`vYmI8oj0vD*m|XC(Y7aaDJ9SGnue^LTG>(1GWtd(jVfA9Ol@ za%T1X0mN7EM}J@IbWrC-2dxRLBZ&=k6`SZPw$N2{Q5!vUGy3SCv5o!-1H`e@!Y<<2 z6WB)$4$!R{x6z#ncTt1a5Xb8RZ=ip}n~3AB8}K&bct_wK;&@l!KDv+IyN36XhCZnA zA>w!d_^5@C(RDmT578&+Q@|nm?B`c6*3joCox?}vZ-apb&jpTf8fS>46MB?{5l*NW z|MB`G7kn2kwABhtF3^fhE2fy_S{lyrk(4`*v&GAtOs2)L_GCqBmSI|2^in$^^DNa) z!Uai%y5oezIHmYldwlZEBaLFLJ^S{_)8{8owbLxu5H3QJP}sWMS{A3e$GRk%d#+m! z2+efQb9~)WXj`F23hgMgx^}FLd*yDur>B#0r{+vUWo(rhsf?pCZrPn>#MATYy=2?- zFeYh{(P_DJK~j`mP~97k%H0)XT8`1;%ob<0IJ?EQcX3*CZi^eYIIrBl)WI%22A?J1 z47M?eW~?`fOwX{5axg9RNu*o0X|c_SOq{Zdm$81fke_N9mIVykrc-iS1ZRZG`B|>a z1JmcuGu;TUs04GxONw(H;Zu@gboi>gy-W#&B-TxUaQDjVo4|Q&102t`;st;8V=5yd zhl12$JHXN`2@8^{@lequ*G<DLw?RaP4C_~<6bPz7I)KrNJ~n-C%+?c&b>*(A3N_3s zTBz_F6?Uyc3dn8kvQc4k6&|RtD;2h?LXF;v<|-f*>#rEqDx`o^F;Y~FRw_o7iV?fh z98~S{{)$qvp~@Jpb2MsnI<-zIAay#5PDkqOhItr~xa@~?p6O%5t3HmOw2M`Suv?8y zt5rCjhw!!PDL@#5dt}bLI&N`9TF$Mt#*MWQCY7IM(o1Vy#adVT`Jl02l4Cq8`;`G6 z>*FLV0^jo3mY8B)@$!_js;Y?4?l#)TwRR~WwT~6;W2t?YF4F)n1G&EpWqwW`R*z<i zqa0tbu6!%%+l31^M`3%7G4LVPQAo?BF`i<KS2^yS&}En?9`cBC)=(K)FUck(u4P1i zxN7Z#y1`w=55$q*E)vW%*eZB|Tu<C8DqCx1x=4Auk-t)P`TkO7)X0p~1oBmbWU$Hw zPP0H3Y<U!>0~WOwxvUpcUc+;?0WY@6=~Y!{qPho7bqBZA^_^`1nXf}(DtBag&9ix! zmOYfolCSg@Q=FAF&1_6F%U(gK?pn}$R{a5*1?$F(Yi+_P`<J>Lujbp0!>s4caz9Kd z2`=rUk#71f1a(MbLaJq!sII23o}(#SuIVcgCv6t~HI#y6)-fgps)JQx%#;DYp1`gm zY{0Z7)rAeMzGT%VLje|_*6w$9JrC7W%(tAc_WR0kQOT5q@M~kGfHc-ujP<#(K1796 z8QX5FquPX(SK9MVJrC=JiS0)0*7J}DV!qv)$MyWUnukPRg#yHYSI=K-;^l#iy5%en zNlL;LB6$i;mSWyFCy{99vgSFSWIY24o1B2=A8?6sP!YOk<QqJgdG>OzgYK<MxEIXw zO+Kt#67nrEz;6orbVg%Z_Tp6MEPMkM7YK;eOF42krf`{9%+Tq)I13jcH?Y26fS9~# zRKduv8dt9!gP4ko2i!YYe@=s0n4XbRUPg2n%)4L>+oV7?S!A1MW%p9&gFL}O$t-7k zkm)pbT*KsjzrMr_R%LAD^MubaB=P=?264beA%j4+&HJoZZN&OO2)RbL5Btda&Ohho zTT)lvmu|i-JwIG$y&ynY90aWU?CZx*pPl^D$z%9l@$au<xX8(QSm5D#m=9001mT<x z=hI<qE&{*w&x{NE6qVGq&vWatDCY(|lXUp~a6uM2Nof%#iSCS}>1-KI_@MX;&M{nE o^P&3lVJLqM94%h5{ulEMEff6Z4j4jzg{#?ScYW=D{5MYEZvp{oD*ylh literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/mklabels.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/mklabels.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..efdfa761ae116ead98b3bdfa21219e2e94e87c4d GIT binary patch literal 1920 zcmcIl&2HO95Z+x<6wM^A;if^{_^?T8paK%fvD*|eT%$?sLjc!@Drj9J0YPb35@U*_ zch`Ta)I)8cEznEfKtA?0`WSodsjuKuXUNELP@}glv9tfP-^_eFe0JkTK%o3~r}b*C zLdah@m=qs6UqRI!5Q6LwK?O_b4n3ZMo|CY?v*S?m9Z9)Mq`MoaRZ8$HRx9P|_atT8 zM7W}IN_ITqi7K>J=?j0Csg|6QRWWr!Pbi#XO;QU6e+B`EawuCeZD%4*ySm=rO`?`e zbg}Z|Ri!-ijqJ)aQjw9|^yK?GN)5c9iTy;@%l#|uEI(Fpw`W%P^GTO4Ek0V}tz+Jd z`&r7HQ68to#VbkNmZ_F2{8@AT0oPLU%@@x%wwfEflPNBwiQ+_q>c7EXWUEGPbzdb} z4t7wSfr70A^*L016T}d{F*zf<OwSnl6CDz80^O=HTS>A*sqFMqt)((?mToAODNyQZ zqrfYF5aoe_^MgjN;sY?baS*9SCrgA>y3y}7+K=+^$>7PG#lz)}80g2#2Wsia4El>u zx@qHOBaickajH#}Bo9CTqSf2oZ*_69sNsQ3MWz~;<ItGIp`IVx>rnwLEMTH3+66)A z3{^;+3zN}Y1d46RB-*7TV3Kf7i6LWZ*pQsiv2#You5i!j8C{3*h?$D02=9~(8IDir zuVhHa-p`~%MHS}#a{dgM1M^kkV^2(t{UK;TCT&F@g1hhCyLSbl{+mwafv=;SPbkRW zvd3gdtXT0h>i^FqDuCbT+uPfGJ>zL+xD>Iu8{FqFd$H!7IFTIMXy0W0$i!`k;xPyM zOQgR*{$7e!5Ntkuwz1jdU-BP<i_l=eFjh?r%_fL0u<`Z!hz_YBb7Y;oemr7BCTP+B zbmSOf=+MDnjG16()Ie~AGl$_T#vS&%yEnf#v*$tpTst*!pSE7<Kuh<ni@vKl)>SfB z1y^7dIi151R$sJ!8!YH%>e%`d1@Ia$0ThfcMHS$l2dhb}O*`x7YY))|<eA49y-o-7 z6Iaw%lMI}r*Pt`mY%7s&$MJ<DkedZRQOU<3zzwsn*a%q&>^h;}!pq%b;_c(4)=6Yq zbJPd0Rn4Nfjsma0gl=jTF&yP;Z3z}M1L2avohyJ%_PqxPEnLQf4?qB*Pf9=n015gF zJRJmfo7{vLbevn{EksPB&R`l-=z?BZ&>$ZK=afS_QXhe$f1$=S)sK!su;?9jbqltB zhL;zpsih-JYE#yIqq7uKQzW#)C5&PutS2PoYH1zNWIcIgAbD6X$|3g&IF!ZUE$cuw zw3R$kMl1a56xRW)+t^2Itv~V29E>zNmdtw0WAn}|b!kw1YN6N}hW#i`!*EdV8I!Lx z8WXD2buQcW!(L<#yY)<UFBWti!Pf#?4MUN&!%*EpO&*|1;#O(RwHN(7Q>I9@cDh`t zE4jBXfuQ(QE^bE>has2)x!7Eae8GXznAP%Mvvv*66~?&CrwkJ0G@W()ihtLq{{YTH B^U44K literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/tests.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/tests.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fbdb86181121d42c813b02b3ccc6cfc6c70021aa GIT binary patch literal 5061 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-37.pyc b/venv/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eb190db60a3defd1640f869ac3804fa764d94c22 GIT binary patch literal 2673 zcmbtWS$7mg6z-nxSu+ztL<QVh#U)BIEGiNaBLNhbs06ohX(!W_q+?IdSltsKqNqV| zVR6O%UgCm)`@ZXs@c7cNKKXRteezZhlLW+b<WO_!cGXwa_f~&*saaDf<TP%(&l<Y_ z_YO__Q%zbe%Y#1d!66ooR?-~ZNqBlSQA+4)Y<Nb=xIuGFC%Hp&lEN4>CykQHNXkhw zl4c~yNRp9^lVv2!NQ#jZBRQvykv3s6mYy_AX~yzSfw4l2Wf;rwTGnY7=A<^3i)EWg zij>HRv@>T<x|DZ1N(EsYXcvVky)?%$2DPra6My7#7Prk}NcfeS<N6~(&lbB82x&WF z*!6`IuRs3Zt*PL8-*T&UPgI2;mP5DZTeV>;92M4<Zl$dIs4}Z%rKkB?Z>3h>D&3LM zu-EEu4XtHMmM*h~wpxR3l@$$^>#iT4qStdP!Vg5RwPtYbVk;2Bx@ANEx`DxU)^JT) zjtI-H7qIHT*a=#f9(6Q)m%mEbo*N2T_JV<mT4^<d2YuWFi-piiIy)}mq@9Fg?9fXF zJ3_fjFPTn?$;w8_e%4iqQb8!)N?1{^tEQew?)}_@b{3&_K;NcsON5Cj#j-xoWke}; zj!F=<S4PXSTCUqM6C!GFF=B`1Ay4p5GZ5Zzlyv=iBaBi)%9;!gYqE_M|GlkPm+p8u z6vgqfEDqN^N64U99W7Rt*6o!OE60{>UOwzh1XnE|m&>+<6V)Z$M*QNYV%@EGyM7Rs zJ+J%96+@#BH-<(O7<YSI_)bk0XNN)Y*f8j+Z{@?N7!hZx?@X}J^oe{-Nl$a(q!^Kk zvKcy<99A8*$4?H!79BFf+oVb_sj@Gop(*m}{Z#Y4g*-m)NX><TE?t_u*m@+RjBWen zs<7=SXWP}9)9}<dZ`+SF%3gCt7L+AU@!94S|5DkM%HOAR50v6eB4@-%g(uTZZRz74 zoWWu`vXax0WpY@gqRtI|MK)8$TNhI+*Pocfd93DWRB2<0(3mnDeSyYG5(84_wJtNJ zQ>J*_<SDICV}`vb$=O`?j^i)>((`z0i@XK@KGIR=GL!4s%v@!mQ;E}*h?$D1nGrEb z>cr=Aj}>Qhsph9h(b_mfPL(2+piPSA@MtzgQaSZ_f>abN;(j86jvlCII@C@;(0@je zii`_eikToaKZYRX*FLpD@i`qsx^jAy9}J}^SMQdpu5o!e-YqlEm<d~zwwEe>Ds|bQ znxCw}jiSsI=YJZU&juFHGN|Sg?Z;jSUFpbFNjH;nQKvhT70tRLkHMO3%P7xfm^t9i zM{3PB$BZ;I^^JPMFq5ftCYx)^7ux4^%<VjF-sxwYIe)>zv(7%}-1DsSFSu~gMHgRk zY1d_!FYfLs@};x<iYu>LarMgHYgS#m`ntaB*YvMlxBiA3H{5jdEw>KbcKaP02RGe$ z*WLHrTe|Q52OhK^Di2loS{oU4#~${oey#q948q3v<}F(%9^LlX<J$?IAb67CDS}CY z9RyDk>?GJl@C?DT1kVvXPq3R{55Zo7eFQHMyh!j8!OH}%5WGsTpWrou*9qPrc$45Q zg0~6YApim-I6yE(@Gil71n(1kKyZ-YLxMvDhY5}ld_?du!6yWt5`0GRIl&hMUlM#p z@HN3V1m6;TNANwt4+K9F{6z3G!7l{A68uK^1mTl}PZ3TM?jU@ca3|p|!e<DdC47$X zdBWX<dkFUu?jwAG@I}Ix2wx_Ah459v{e-U(zE1cC;hThS5x!0M4j~XC;Q_)a!gmSZ zBYdCm1HyxZ9}*rSJWP0m@FT*H2|pqHl<+gc&k4UE{F3l1!mkOxA^eu`JHqb?e<1vk z@F&8b34bB{mGHN&jwo&0POZ``^}~&@A-U8`6&lTIX{eDZOmXtX2_aRGM%nmQ+u-xR zis`E$%Bc&gV!H}er6Ve|uJWOV>p4<Y+*#FQI`N{+s^&GbS|xIDF$*)1Ph^sv+0JBV Ya-KOaW$Fn%#lJ-S%Vf>%+IB7Z51jiC^Z)<= literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/webencodings/labels.py b/venv/lib/python3.7/site-packages/pip/_vendor/webencodings/labels.py new file mode 100644 index 0000000..29cbf91 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/webencodings/labels.py @@ -0,0 +1,231 @@ +""" + + webencodings.labels + ~~~~~~~~~~~~~~~~~~~ + + Map encoding labels to their name. + + :copyright: Copyright 2012 by Simon Sapin + :license: BSD, see LICENSE for details. + +""" + +# XXX Do not edit! +# This file is automatically generated by mklabels.py + +LABELS = { + 'unicode-1-1-utf-8': 'utf-8', + 'utf-8': 'utf-8', + 'utf8': 'utf-8', + '866': 'ibm866', + 'cp866': 'ibm866', + 'csibm866': 'ibm866', + 'ibm866': 'ibm866', + 'csisolatin2': 'iso-8859-2', + 'iso-8859-2': 'iso-8859-2', + 'iso-ir-101': 'iso-8859-2', + 'iso8859-2': 'iso-8859-2', + 'iso88592': 'iso-8859-2', + 'iso_8859-2': 'iso-8859-2', + 'iso_8859-2:1987': 'iso-8859-2', + 'l2': 'iso-8859-2', + 'latin2': 'iso-8859-2', + 'csisolatin3': 'iso-8859-3', + 'iso-8859-3': 'iso-8859-3', + 'iso-ir-109': 'iso-8859-3', + 'iso8859-3': 'iso-8859-3', + 'iso88593': 'iso-8859-3', + 'iso_8859-3': 'iso-8859-3', + 'iso_8859-3:1988': 'iso-8859-3', + 'l3': 'iso-8859-3', + 'latin3': 'iso-8859-3', + 'csisolatin4': 'iso-8859-4', + 'iso-8859-4': 'iso-8859-4', + 'iso-ir-110': 'iso-8859-4', + 'iso8859-4': 'iso-8859-4', + 'iso88594': 'iso-8859-4', + 'iso_8859-4': 'iso-8859-4', + 'iso_8859-4:1988': 'iso-8859-4', + 'l4': 'iso-8859-4', + 'latin4': 'iso-8859-4', + 'csisolatincyrillic': 'iso-8859-5', + 'cyrillic': 'iso-8859-5', + 'iso-8859-5': 'iso-8859-5', + 'iso-ir-144': 'iso-8859-5', + 'iso8859-5': 'iso-8859-5', + 'iso88595': 'iso-8859-5', + 'iso_8859-5': 'iso-8859-5', + 'iso_8859-5:1988': 'iso-8859-5', + 'arabic': 'iso-8859-6', + 'asmo-708': 'iso-8859-6', + 'csiso88596e': 'iso-8859-6', + 'csiso88596i': 'iso-8859-6', + 'csisolatinarabic': 'iso-8859-6', + 'ecma-114': 'iso-8859-6', + 'iso-8859-6': 'iso-8859-6', + 'iso-8859-6-e': 'iso-8859-6', + 'iso-8859-6-i': 'iso-8859-6', + 'iso-ir-127': 'iso-8859-6', + 'iso8859-6': 'iso-8859-6', + 'iso88596': 'iso-8859-6', + 'iso_8859-6': 'iso-8859-6', + 'iso_8859-6:1987': 'iso-8859-6', + 'csisolatingreek': 'iso-8859-7', + 'ecma-118': 'iso-8859-7', + 'elot_928': 'iso-8859-7', + 'greek': 'iso-8859-7', + 'greek8': 'iso-8859-7', + 'iso-8859-7': 'iso-8859-7', + 'iso-ir-126': 'iso-8859-7', + 'iso8859-7': 'iso-8859-7', + 'iso88597': 'iso-8859-7', + 'iso_8859-7': 'iso-8859-7', + 'iso_8859-7:1987': 'iso-8859-7', + 'sun_eu_greek': 'iso-8859-7', + 'csiso88598e': 'iso-8859-8', + 'csisolatinhebrew': 'iso-8859-8', + 'hebrew': 'iso-8859-8', + 'iso-8859-8': 'iso-8859-8', + 'iso-8859-8-e': 'iso-8859-8', + 'iso-ir-138': 'iso-8859-8', + 'iso8859-8': 'iso-8859-8', + 'iso88598': 'iso-8859-8', + 'iso_8859-8': 'iso-8859-8', + 'iso_8859-8:1988': 'iso-8859-8', + 'visual': 'iso-8859-8', + 'csiso88598i': 'iso-8859-8-i', + 'iso-8859-8-i': 'iso-8859-8-i', + 'logical': 'iso-8859-8-i', + 'csisolatin6': 'iso-8859-10', + 'iso-8859-10': 'iso-8859-10', + 'iso-ir-157': 'iso-8859-10', + 'iso8859-10': 'iso-8859-10', + 'iso885910': 'iso-8859-10', + 'l6': 'iso-8859-10', + 'latin6': 'iso-8859-10', + 'iso-8859-13': 'iso-8859-13', + 'iso8859-13': 'iso-8859-13', + 'iso885913': 'iso-8859-13', + 'iso-8859-14': 'iso-8859-14', + 'iso8859-14': 'iso-8859-14', + 'iso885914': 'iso-8859-14', + 'csisolatin9': 'iso-8859-15', + 'iso-8859-15': 'iso-8859-15', + 'iso8859-15': 'iso-8859-15', + 'iso885915': 'iso-8859-15', + 'iso_8859-15': 'iso-8859-15', + 'l9': 'iso-8859-15', + 'iso-8859-16': 'iso-8859-16', + 'cskoi8r': 'koi8-r', + 'koi': 'koi8-r', + 'koi8': 'koi8-r', + 'koi8-r': 'koi8-r', + 'koi8_r': 'koi8-r', + 'koi8-u': 'koi8-u', + 'csmacintosh': 'macintosh', + 'mac': 'macintosh', + 'macintosh': 'macintosh', + 'x-mac-roman': 'macintosh', + 'dos-874': 'windows-874', + 'iso-8859-11': 'windows-874', + 'iso8859-11': 'windows-874', + 'iso885911': 'windows-874', + 'tis-620': 'windows-874', + 'windows-874': 'windows-874', + 'cp1250': 'windows-1250', + 'windows-1250': 'windows-1250', + 'x-cp1250': 'windows-1250', + 'cp1251': 'windows-1251', + 'windows-1251': 'windows-1251', + 'x-cp1251': 'windows-1251', + 'ansi_x3.4-1968': 'windows-1252', + 'ascii': 'windows-1252', + 'cp1252': 'windows-1252', + 'cp819': 'windows-1252', + 'csisolatin1': 'windows-1252', + 'ibm819': 'windows-1252', + 'iso-8859-1': 'windows-1252', + 'iso-ir-100': 'windows-1252', + 'iso8859-1': 'windows-1252', + 'iso88591': 'windows-1252', + 'iso_8859-1': 'windows-1252', + 'iso_8859-1:1987': 'windows-1252', + 'l1': 'windows-1252', + 'latin1': 'windows-1252', + 'us-ascii': 'windows-1252', + 'windows-1252': 'windows-1252', + 'x-cp1252': 'windows-1252', + 'cp1253': 'windows-1253', + 'windows-1253': 'windows-1253', + 'x-cp1253': 'windows-1253', + 'cp1254': 'windows-1254', + 'csisolatin5': 'windows-1254', + 'iso-8859-9': 'windows-1254', + 'iso-ir-148': 'windows-1254', + 'iso8859-9': 'windows-1254', + 'iso88599': 'windows-1254', + 'iso_8859-9': 'windows-1254', + 'iso_8859-9:1989': 'windows-1254', + 'l5': 'windows-1254', + 'latin5': 'windows-1254', + 'windows-1254': 'windows-1254', + 'x-cp1254': 'windows-1254', + 'cp1255': 'windows-1255', + 'windows-1255': 'windows-1255', + 'x-cp1255': 'windows-1255', + 'cp1256': 'windows-1256', + 'windows-1256': 'windows-1256', + 'x-cp1256': 'windows-1256', + 'cp1257': 'windows-1257', + 'windows-1257': 'windows-1257', + 'x-cp1257': 'windows-1257', + 'cp1258': 'windows-1258', + 'windows-1258': 'windows-1258', + 'x-cp1258': 'windows-1258', + 'x-mac-cyrillic': 'x-mac-cyrillic', + 'x-mac-ukrainian': 'x-mac-cyrillic', + 'chinese': 'gbk', + 'csgb2312': 'gbk', + 'csiso58gb231280': 'gbk', + 'gb2312': 'gbk', + 'gb_2312': 'gbk', + 'gb_2312-80': 'gbk', + 'gbk': 'gbk', + 'iso-ir-58': 'gbk', + 'x-gbk': 'gbk', + 'gb18030': 'gb18030', + 'hz-gb-2312': 'hz-gb-2312', + 'big5': 'big5', + 'big5-hkscs': 'big5', + 'cn-big5': 'big5', + 'csbig5': 'big5', + 'x-x-big5': 'big5', + 'cseucpkdfmtjapanese': 'euc-jp', + 'euc-jp': 'euc-jp', + 'x-euc-jp': 'euc-jp', + 'csiso2022jp': 'iso-2022-jp', + 'iso-2022-jp': 'iso-2022-jp', + 'csshiftjis': 'shift_jis', + 'ms_kanji': 'shift_jis', + 'shift-jis': 'shift_jis', + 'shift_jis': 'shift_jis', + 'sjis': 'shift_jis', + 'windows-31j': 'shift_jis', + 'x-sjis': 'shift_jis', + 'cseuckr': 'euc-kr', + 'csksc56011987': 'euc-kr', + 'euc-kr': 'euc-kr', + 'iso-ir-149': 'euc-kr', + 'korean': 'euc-kr', + 'ks_c_5601-1987': 'euc-kr', + 'ks_c_5601-1989': 'euc-kr', + 'ksc5601': 'euc-kr', + 'ksc_5601': 'euc-kr', + 'windows-949': 'euc-kr', + 'csiso2022kr': 'iso-2022-kr', + 'iso-2022-kr': 'iso-2022-kr', + 'utf-16be': 'utf-16be', + 'utf-16': 'utf-16le', + 'utf-16le': 'utf-16le', + 'x-user-defined': 'x-user-defined', +} diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/webencodings/mklabels.py b/venv/lib/python3.7/site-packages/pip/_vendor/webencodings/mklabels.py new file mode 100644 index 0000000..295dc92 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/webencodings/mklabels.py @@ -0,0 +1,59 @@ +""" + + webencodings.mklabels + ~~~~~~~~~~~~~~~~~~~~~ + + Regenarate the webencodings.labels module. + + :copyright: Copyright 2012 by Simon Sapin + :license: BSD, see LICENSE for details. + +""" + +import json +try: + from urllib import urlopen +except ImportError: + from urllib.request import urlopen + + +def assert_lower(string): + assert string == string.lower() + return string + + +def generate(url): + parts = ['''\ +""" + + webencodings.labels + ~~~~~~~~~~~~~~~~~~~ + + Map encoding labels to their name. + + :copyright: Copyright 2012 by Simon Sapin + :license: BSD, see LICENSE for details. + +""" + +# XXX Do not edit! +# This file is automatically generated by mklabels.py + +LABELS = { +'''] + labels = [ + (repr(assert_lower(label)).lstrip('u'), + repr(encoding['name']).lstrip('u')) + for category in json.loads(urlopen(url).read().decode('ascii')) + for encoding in category['encodings'] + for label in encoding['labels']] + max_len = max(len(label) for label, name in labels) + parts.extend( + ' %s:%s %s,\n' % (label, ' ' * (max_len - len(label)), name) + for label, name in labels) + parts.append('}') + return ''.join(parts) + + +if __name__ == '__main__': + print(generate('http://encoding.spec.whatwg.org/encodings.json')) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/webencodings/tests.py b/venv/lib/python3.7/site-packages/pip/_vendor/webencodings/tests.py new file mode 100644 index 0000000..e12c10d --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/webencodings/tests.py @@ -0,0 +1,153 @@ +# coding: utf-8 +""" + + webencodings.tests + ~~~~~~~~~~~~~~~~~~ + + A basic test suite for Encoding. + + :copyright: Copyright 2012 by Simon Sapin + :license: BSD, see LICENSE for details. + +""" + +from __future__ import unicode_literals + +from . import (lookup, LABELS, decode, encode, iter_decode, iter_encode, + IncrementalDecoder, IncrementalEncoder, UTF8) + + +def assert_raises(exception, function, *args, **kwargs): + try: + function(*args, **kwargs) + except exception: + return + else: # pragma: no cover + raise AssertionError('Did not raise %s.' % exception) + + +def test_labels(): + assert lookup('utf-8').name == 'utf-8' + assert lookup('Utf-8').name == 'utf-8' + assert lookup('UTF-8').name == 'utf-8' + assert lookup('utf8').name == 'utf-8' + assert lookup('utf8').name == 'utf-8' + assert lookup('utf8 ').name == 'utf-8' + assert lookup(' \r\nutf8\t').name == 'utf-8' + assert lookup('u8') is None # Python label. + assert lookup('utf-8 ') is None # Non-ASCII white space. + + assert lookup('US-ASCII').name == 'windows-1252' + assert lookup('iso-8859-1').name == 'windows-1252' + assert lookup('latin1').name == 'windows-1252' + assert lookup('LATIN1').name == 'windows-1252' + assert lookup('latin-1') is None + assert lookup('LATİN1') is None # ASCII-only case insensitivity. + + +def test_all_labels(): + for label in LABELS: + assert decode(b'', label) == ('', lookup(label)) + assert encode('', label) == b'' + for repeat in [0, 1, 12]: + output, _ = iter_decode([b''] * repeat, label) + assert list(output) == [] + assert list(iter_encode([''] * repeat, label)) == [] + decoder = IncrementalDecoder(label) + assert decoder.decode(b'') == '' + assert decoder.decode(b'', final=True) == '' + encoder = IncrementalEncoder(label) + assert encoder.encode('') == b'' + assert encoder.encode('', final=True) == b'' + # All encoding names are valid labels too: + for name in set(LABELS.values()): + assert lookup(name).name == name + + +def test_invalid_label(): + assert_raises(LookupError, decode, b'\xEF\xBB\xBF\xc3\xa9', 'invalid') + assert_raises(LookupError, encode, 'é', 'invalid') + assert_raises(LookupError, iter_decode, [], 'invalid') + assert_raises(LookupError, iter_encode, [], 'invalid') + assert_raises(LookupError, IncrementalDecoder, 'invalid') + assert_raises(LookupError, IncrementalEncoder, 'invalid') + + +def test_decode(): + assert decode(b'\x80', 'latin1') == ('€', lookup('latin1')) + assert decode(b'\x80', lookup('latin1')) == ('€', lookup('latin1')) + assert decode(b'\xc3\xa9', 'utf8') == ('é', lookup('utf8')) + assert decode(b'\xc3\xa9', UTF8) == ('é', lookup('utf8')) + assert decode(b'\xc3\xa9', 'ascii') == ('é', lookup('ascii')) + assert decode(b'\xEF\xBB\xBF\xc3\xa9', 'ascii') == ('é', lookup('utf8')) # UTF-8 with BOM + + assert decode(b'\xFE\xFF\x00\xe9', 'ascii') == ('é', lookup('utf-16be')) # UTF-16-BE with BOM + assert decode(b'\xFF\xFE\xe9\x00', 'ascii') == ('é', lookup('utf-16le')) # UTF-16-LE with BOM + assert decode(b'\xFE\xFF\xe9\x00', 'ascii') == ('\ue900', lookup('utf-16be')) + assert decode(b'\xFF\xFE\x00\xe9', 'ascii') == ('\ue900', lookup('utf-16le')) + + assert decode(b'\x00\xe9', 'UTF-16BE') == ('é', lookup('utf-16be')) + assert decode(b'\xe9\x00', 'UTF-16LE') == ('é', lookup('utf-16le')) + assert decode(b'\xe9\x00', 'UTF-16') == ('é', lookup('utf-16le')) + + assert decode(b'\xe9\x00', 'UTF-16BE') == ('\ue900', lookup('utf-16be')) + assert decode(b'\x00\xe9', 'UTF-16LE') == ('\ue900', lookup('utf-16le')) + assert decode(b'\x00\xe9', 'UTF-16') == ('\ue900', lookup('utf-16le')) + + +def test_encode(): + assert encode('é', 'latin1') == b'\xe9' + assert encode('é', 'utf8') == b'\xc3\xa9' + assert encode('é', 'utf8') == b'\xc3\xa9' + assert encode('é', 'utf-16') == b'\xe9\x00' + assert encode('é', 'utf-16le') == b'\xe9\x00' + assert encode('é', 'utf-16be') == b'\x00\xe9' + + +def test_iter_decode(): + def iter_decode_to_string(input, fallback_encoding): + output, _encoding = iter_decode(input, fallback_encoding) + return ''.join(output) + assert iter_decode_to_string([], 'latin1') == '' + assert iter_decode_to_string([b''], 'latin1') == '' + assert iter_decode_to_string([b'\xe9'], 'latin1') == 'é' + assert iter_decode_to_string([b'hello'], 'latin1') == 'hello' + assert iter_decode_to_string([b'he', b'llo'], 'latin1') == 'hello' + assert iter_decode_to_string([b'hell', b'o'], 'latin1') == 'hello' + assert iter_decode_to_string([b'\xc3\xa9'], 'latin1') == 'é' + assert iter_decode_to_string([b'\xEF\xBB\xBF\xc3\xa9'], 'latin1') == 'é' + assert iter_decode_to_string([ + b'\xEF\xBB\xBF', b'\xc3', b'\xa9'], 'latin1') == 'é' + assert iter_decode_to_string([ + b'\xEF\xBB\xBF', b'a', b'\xc3'], 'latin1') == 'a\uFFFD' + assert iter_decode_to_string([ + b'', b'\xEF', b'', b'', b'\xBB\xBF\xc3', b'\xa9'], 'latin1') == 'é' + assert iter_decode_to_string([b'\xEF\xBB\xBF'], 'latin1') == '' + assert iter_decode_to_string([b'\xEF\xBB'], 'latin1') == 'ï»' + assert iter_decode_to_string([b'\xFE\xFF\x00\xe9'], 'latin1') == 'é' + assert iter_decode_to_string([b'\xFF\xFE\xe9\x00'], 'latin1') == 'é' + assert iter_decode_to_string([ + b'', b'\xFF', b'', b'', b'\xFE\xe9', b'\x00'], 'latin1') == 'é' + assert iter_decode_to_string([ + b'', b'h\xe9', b'llo'], 'x-user-defined') == 'h\uF7E9llo' + + +def test_iter_encode(): + assert b''.join(iter_encode([], 'latin1')) == b'' + assert b''.join(iter_encode([''], 'latin1')) == b'' + assert b''.join(iter_encode(['é'], 'latin1')) == b'\xe9' + assert b''.join(iter_encode(['', 'é', '', ''], 'latin1')) == b'\xe9' + assert b''.join(iter_encode(['', 'é', '', ''], 'utf-16')) == b'\xe9\x00' + assert b''.join(iter_encode(['', 'é', '', ''], 'utf-16le')) == b'\xe9\x00' + assert b''.join(iter_encode(['', 'é', '', ''], 'utf-16be')) == b'\x00\xe9' + assert b''.join(iter_encode([ + '', 'h\uF7E9', '', 'llo'], 'x-user-defined')) == b'h\xe9llo' + + +def test_x_user_defined(): + encoded = b'2,\x0c\x0b\x1aO\xd9#\xcb\x0f\xc9\xbbt\xcf\xa8\xca' + decoded = '2,\x0c\x0b\x1aO\uf7d9#\uf7cb\x0f\uf7c9\uf7bbt\uf7cf\uf7a8\uf7ca' + encoded = b'aa' + decoded = 'aa' + assert decode(encoded, 'x-user-defined') == (decoded, lookup('x-user-defined')) + assert encode(decoded, 'x-user-defined') == encoded diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/webencodings/x_user_defined.py b/venv/lib/python3.7/site-packages/pip/_vendor/webencodings/x_user_defined.py new file mode 100644 index 0000000..d16e326 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/webencodings/x_user_defined.py @@ -0,0 +1,325 @@ +# coding: utf-8 +""" + + webencodings.x_user_defined + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + An implementation of the x-user-defined encoding. + + :copyright: Copyright 2012 by Simon Sapin + :license: BSD, see LICENSE for details. + +""" + +from __future__ import unicode_literals + +import codecs + + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self, input, errors='strict'): + return codecs.charmap_encode(input, errors, encoding_table) + + def decode(self, input, errors='strict'): + return codecs.charmap_decode(input, errors, decoding_table) + + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input, self.errors, encoding_table)[0] + + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input, self.errors, decoding_table)[0] + + +class StreamWriter(Codec, codecs.StreamWriter): + pass + + +class StreamReader(Codec, codecs.StreamReader): + pass + + +### encodings module API + +codec_info = codecs.CodecInfo( + name='x-user-defined', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, +) + + +### Decoding Table + +# Python 3: +# for c in range(256): print(' %r' % chr(c if c < 128 else c + 0xF700)) +decoding_table = ( + '\x00' + '\x01' + '\x02' + '\x03' + '\x04' + '\x05' + '\x06' + '\x07' + '\x08' + '\t' + '\n' + '\x0b' + '\x0c' + '\r' + '\x0e' + '\x0f' + '\x10' + '\x11' + '\x12' + '\x13' + '\x14' + '\x15' + '\x16' + '\x17' + '\x18' + '\x19' + '\x1a' + '\x1b' + '\x1c' + '\x1d' + '\x1e' + '\x1f' + ' ' + '!' + '"' + '#' + '$' + '%' + '&' + "'" + '(' + ')' + '*' + '+' + ',' + '-' + '.' + '/' + '0' + '1' + '2' + '3' + '4' + '5' + '6' + '7' + '8' + '9' + ':' + ';' + '<' + '=' + '>' + '?' + '@' + 'A' + 'B' + 'C' + 'D' + 'E' + 'F' + 'G' + 'H' + 'I' + 'J' + 'K' + 'L' + 'M' + 'N' + 'O' + 'P' + 'Q' + 'R' + 'S' + 'T' + 'U' + 'V' + 'W' + 'X' + 'Y' + 'Z' + '[' + '\\' + ']' + '^' + '_' + '`' + 'a' + 'b' + 'c' + 'd' + 'e' + 'f' + 'g' + 'h' + 'i' + 'j' + 'k' + 'l' + 'm' + 'n' + 'o' + 'p' + 'q' + 'r' + 's' + 't' + 'u' + 'v' + 'w' + 'x' + 'y' + 'z' + '{' + '|' + '}' + '~' + '\x7f' + '\uf780' + '\uf781' + '\uf782' + '\uf783' + '\uf784' + '\uf785' + '\uf786' + '\uf787' + '\uf788' + '\uf789' + '\uf78a' + '\uf78b' + '\uf78c' + '\uf78d' + '\uf78e' + '\uf78f' + '\uf790' + '\uf791' + '\uf792' + '\uf793' + '\uf794' + '\uf795' + '\uf796' + '\uf797' + '\uf798' + '\uf799' + '\uf79a' + '\uf79b' + '\uf79c' + '\uf79d' + '\uf79e' + '\uf79f' + '\uf7a0' + '\uf7a1' + '\uf7a2' + '\uf7a3' + '\uf7a4' + '\uf7a5' + '\uf7a6' + '\uf7a7' + '\uf7a8' + '\uf7a9' + '\uf7aa' + '\uf7ab' + '\uf7ac' + '\uf7ad' + '\uf7ae' + '\uf7af' + '\uf7b0' + '\uf7b1' + '\uf7b2' + '\uf7b3' + '\uf7b4' + '\uf7b5' + '\uf7b6' + '\uf7b7' + '\uf7b8' + '\uf7b9' + '\uf7ba' + '\uf7bb' + '\uf7bc' + '\uf7bd' + '\uf7be' + '\uf7bf' + '\uf7c0' + '\uf7c1' + '\uf7c2' + '\uf7c3' + '\uf7c4' + '\uf7c5' + '\uf7c6' + '\uf7c7' + '\uf7c8' + '\uf7c9' + '\uf7ca' + '\uf7cb' + '\uf7cc' + '\uf7cd' + '\uf7ce' + '\uf7cf' + '\uf7d0' + '\uf7d1' + '\uf7d2' + '\uf7d3' + '\uf7d4' + '\uf7d5' + '\uf7d6' + '\uf7d7' + '\uf7d8' + '\uf7d9' + '\uf7da' + '\uf7db' + '\uf7dc' + '\uf7dd' + '\uf7de' + '\uf7df' + '\uf7e0' + '\uf7e1' + '\uf7e2' + '\uf7e3' + '\uf7e4' + '\uf7e5' + '\uf7e6' + '\uf7e7' + '\uf7e8' + '\uf7e9' + '\uf7ea' + '\uf7eb' + '\uf7ec' + '\uf7ed' + '\uf7ee' + '\uf7ef' + '\uf7f0' + '\uf7f1' + '\uf7f2' + '\uf7f3' + '\uf7f4' + '\uf7f5' + '\uf7f6' + '\uf7f7' + '\uf7f8' + '\uf7f9' + '\uf7fa' + '\uf7fb' + '\uf7fc' + '\uf7fd' + '\uf7fe' + '\uf7ff' +) + +### Encoding table +encoding_table = codecs.charmap_build(decoding_table) diff --git a/venv/lib/python3.7/site-packages/pkg_resources/__init__.py b/venv/lib/python3.7/site-packages/pkg_resources/__init__.py new file mode 100644 index 0000000..6ca68da --- /dev/null +++ b/venv/lib/python3.7/site-packages/pkg_resources/__init__.py @@ -0,0 +1,3171 @@ +# coding: utf-8 +""" +Package resource API +-------------------- + +A resource is a logical file contained within a package, or a logical +subdirectory thereof. The package resource API expects resource names +to have their path parts separated with ``/``, *not* whatever the local +path separator is. Do not use os.path operations to manipulate resource +names being passed into the API. + +The package resource API is designed to work with normal filesystem packages, +.egg files, and unpacked .egg files. It can also work in a limited way with +.zip files and with custom PEP 302 loaders that support the ``get_data()`` +method. +""" + +from __future__ import absolute_import + +import sys +import os +import io +import time +import re +import types +import zipfile +import zipimport +import warnings +import stat +import functools +import pkgutil +import operator +import platform +import collections +import plistlib +import email.parser +import errno +import tempfile +import textwrap +import itertools +import inspect +from pkgutil import get_importer + +try: + import _imp +except ImportError: + # Python 3.2 compatibility + import imp as _imp + +try: + FileExistsError +except NameError: + FileExistsError = OSError + +from pkg_resources.extern import six +from pkg_resources.extern.six.moves import urllib, map, filter + +# capture these to bypass sandboxing +from os import utime +try: + from os import mkdir, rename, unlink + WRITE_SUPPORT = True +except ImportError: + # no write support, probably under GAE + WRITE_SUPPORT = False + +from os import open as os_open +from os.path import isdir, split + +try: + import importlib.machinery as importlib_machinery + # access attribute to force import under delayed import mechanisms. + importlib_machinery.__name__ +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') +__import__('pkg_resources.extern.packaging.specifiers') +__import__('pkg_resources.extern.packaging.requirements') +__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 six.PY2: + # Those builtin exceptions are only defined in Python 3 + PermissionError = None + NotADirectoryError = None + +# declare some globals that will be defined later to +# satisfy the linters. +require = None +working_set = None +add_activation_listener = None +resources_stream = None +cleanup_resources = None +resource_dir = None +resource_stream = None +set_extraction_path = None +resource_isdir = None +resource_string = None +iter_entry_points = None +resource_listdir = None +resource_filename = None +resource_exists = None +_distribution_finders = None +_namespace_handlers = None +_namespace_packages = None + + +class PEP440Warning(RuntimeWarning): + """ + Used when there is an issue with a version or specifier not complying with + PEP 440. + """ + + +def parse_version(v): + try: + return packaging.version.Version(v) + except packaging.version.InvalidVersion: + return packaging.version.LegacyVersion(v) + + +_state_vars = {} + + +def _declare_state(vartype, **kw): + globals().update(kw) + _state_vars.update(dict.fromkeys(kw, vartype)) + + +def __getstate__(): + state = {} + g = globals() + for k, v in _state_vars.items(): + state[k] = g['_sget_' + v](g[k]) + return state + + +def __setstate__(state): + g = globals() + for k, v in state.items(): + g['_sset_' + _state_vars[k]](k, g[k], v) + return state + + +def _sget_dict(val): + return val.copy() + + +def _sset_dict(key, ob, state): + ob.clear() + ob.update(state) + + +def _sget_object(val): + return val.__getstate__() + + +def _sset_object(key, ob, state): + ob.__setstate__(state) + + +_sget_none = _sset_none = lambda *args: None + + +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 + 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 + current version of the OS. + + If this condition occurs for any other platform with a version in its + platform strings, this function should be extended accordingly. + """ + plat = get_build_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)) + except ValueError: + # not Mac OS X + pass + return plat + + +__all__ = [ + # Basic resource access and distribution/entry point discovery + 'require', 'run_script', 'get_provider', 'get_distribution', + 'load_entry_point', 'get_entry_map', 'get_entry_info', + 'iter_entry_points', + 'resource_string', 'resource_stream', 'resource_filename', + 'resource_listdir', 'resource_exists', 'resource_isdir', + + # Environmental control + 'declare_namespace', 'working_set', 'add_activation_listener', + 'find_distributions', 'set_extraction_path', 'cleanup_resources', + 'get_default_cache', + + # Primary implementation classes + 'Environment', 'WorkingSet', 'ResourceManager', + 'Distribution', 'Requirement', 'EntryPoint', + + # Exceptions + 'ResolutionError', 'VersionConflict', 'DistributionNotFound', + 'UnknownExtra', 'ExtractionError', + + # Warnings + 'PEP440Warning', + + # Parsing functions and string utilities + 'parse_requirements', 'parse_version', 'safe_name', 'safe_version', + 'get_platform', 'compatible_platforms', 'yield_lines', 'split_sections', + 'safe_extra', 'to_filename', 'invalid_marker', 'evaluate_marker', + + # filesystem utilities + 'ensure_directory', 'normalize_path', + + # Distribution "precedence" constants + 'EGG_DIST', 'BINARY_DIST', 'SOURCE_DIST', 'CHECKOUT_DIST', 'DEVELOP_DIST', + + # "Provider" interfaces, implementations, and registration/lookup APIs + 'IMetadataProvider', 'IResourceProvider', 'FileMetadata', + 'PathMetadata', 'EggMetadata', 'EmptyProvider', 'empty_provider', + 'NullProvider', 'EggProvider', 'DefaultProvider', 'ZipProvider', + 'register_finder', 'register_namespace_handler', 'register_loader_type', + 'fixup_namespace_packages', 'get_importer', + + # Warnings + 'PkgResourcesDeprecationWarning', + + # Deprecated/backward compatibility only + 'run_main', 'AvailableDistributions', +] + + +class ResolutionError(Exception): + """Abstract base for dependency resolution errors""" + + def __repr__(self): + return self.__class__.__name__ + repr(self.args) + + +class VersionConflict(ResolutionError): + """ + An already-installed version conflicts with the requested version. + + Should be initialized with the installed Distribution and the requested + Requirement. + """ + + _template = "{self.dist} is installed but {self.req} is required" + + @property + def dist(self): + return self.args[0] + + @property + def req(self): + return self.args[1] + + def report(self): + return self._template.format(**locals()) + + def with_context(self, required_by): + """ + If required_by is non-empty, return a version of self that is a + ContextualVersionConflict. + """ + if not required_by: + return self + args = self.args + (required_by,) + return ContextualVersionConflict(*args) + + +class ContextualVersionConflict(VersionConflict): + """ + A VersionConflict that accepts a third parameter, the set of the + requirements that required the installed Distribution. + """ + + _template = VersionConflict._template + ' by {self.required_by}' + + @property + def required_by(self): + return self.args[2] + + +class DistributionNotFound(ResolutionError): + """A requested distribution was not found""" + + _template = ("The '{self.req}' distribution was not found " + "and is required by {self.requirers_str}") + + @property + def req(self): + return self.args[0] + + @property + def requirers(self): + return self.args[1] + + @property + def requirers_str(self): + if not self.requirers: + return 'the application' + return ', '.join(self.requirers) + + def report(self): + return self._template.format(**locals()) + + def __str__(self): + return self.report() + + +class UnknownExtra(ResolutionError): + """Distribution doesn't have an "extra feature" of the given name""" + + +_provider_factories = {} + +PY_MAJOR = sys.version[:3] +EGG_DIST = 3 +BINARY_DIST = 2 +SOURCE_DIST = 1 +CHECKOUT_DIST = 0 +DEVELOP_DIST = -1 + + +def register_loader_type(loader_type, provider_factory): + """Register `provider_factory` to make providers for `loader_type` + + `loader_type` is the type or class of a PEP 302 ``module.__loader__``, + and `provider_factory` is a function that, passed a *module* object, + returns an ``IResourceProvider`` for that module. + """ + _provider_factories[loader_type] = provider_factory + + +def get_provider(moduleOrReq): + """Return an IResourceProvider for the named module or requirement""" + if isinstance(moduleOrReq, Requirement): + return working_set.find(moduleOrReq) or require(str(moduleOrReq))[0] + try: + module = sys.modules[moduleOrReq] + except KeyError: + __import__(moduleOrReq) + module = sys.modules[moduleOrReq] + loader = getattr(module, '__loader__', None) + return _find_adapter(_provider_factories, loader)(module) + + +def _macosx_vers(_cache=[]): + if not _cache: + version = platform.mac_ver()[0] + # fallback for MacPorts + if version == '': + plist = '/System/Library/CoreServices/SystemVersion.plist' + if os.path.exists(plist): + if hasattr(plistlib, 'readPlist'): + plist_content = plistlib.readPlist(plist) + if 'ProductVersion' in plist_content: + version = plist_content['ProductVersion'] + + _cache.append(version.split('.')) + return _cache[0] + + +def _macosx_arch(machine): + return {'PowerPC': 'ppc', 'Power_Macintosh': 'ppc'}.get(machine, machine) + + +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. + """ + from sysconfig import get_platform + + plat = get_platform() + if sys.platform == "darwin" and not plat.startswith('macosx-'): + try: + version = _macosx_vers() + machine = os.uname()[4].replace(" ", "_") + return "macosx-%d.%d-%s" % ( + int(version[0]), int(version[1]), + _macosx_arch(machine), + ) + except ValueError: + # if someone is running a non-Mac darwin system, this will fall + # through to the default implementation + pass + return plat + + +macosVersionString = re.compile(r"macosx-(\d+)\.(\d+)-(.*)") +darwinVersionString = re.compile(r"darwin-(\d+)\.(\d+)\.(\d+)-(.*)") +# XXX backward compat +get_platform = get_build_platform + + +def compatible_platforms(provided, required): + """Can code for the `provided` platform run on the `required` platform? + + Returns true if either platform is ``None``, or the platforms are equal. + + XXX Needs compatibility checks for Linux and other unixy OSes. + """ + if provided is None or required is None or provided == required: + # easy case + return True + + # Mac OS X special cases + reqMac = macosVersionString.match(required) + if reqMac: + provMac = macosVersionString.match(provided) + + # is this a Mac package? + 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. + provDarwin = darwinVersionString.match(provided) + if provDarwin: + dversion = int(provDarwin.group(1)) + macosversion = "%s.%s" % (reqMac.group(1), reqMac.group(2)) + if dversion == 7 and macosversion >= "10.3" or \ + dversion == 8 and macosversion >= "10.4": + return True + # egg isn't macosx or legacy darwin + return False + + # are they the same major version and machine type? + if provMac.group(1) != reqMac.group(1) or \ + provMac.group(3) != reqMac.group(3): + return False + + # is the required OS major update >= the provided one? + if int(provMac.group(2)) > int(reqMac.group(2)): + return False + + return True + + # XXX Linux and other platforms' special cases should go here + return False + + +def run_script(dist_spec, script_name): + """Locate distribution `dist_spec` and run its `script_name` script""" + ns = sys._getframe(1).f_globals + name = ns['__name__'] + ns.clear() + ns['__name__'] = name + require(dist_spec)[0].run_script(script_name, ns) + + +# backward compatibility +run_main = run_script + + +def get_distribution(dist): + """Return a current distribution object for a Requirement or string""" + if isinstance(dist, six.string_types): + dist = Requirement.parse(dist) + if isinstance(dist, Requirement): + dist = get_provider(dist) + if not isinstance(dist, Distribution): + raise TypeError("Expected string, Requirement, or Distribution", dist) + return dist + + +def load_entry_point(dist, group, name): + """Return `name` entry point of `group` for `dist` or raise ImportError""" + return get_distribution(dist).load_entry_point(group, name) + + +def get_entry_map(dist, group=None): + """Return the entry point map for `group`, or the full entry map""" + return get_distribution(dist).get_entry_map(group) + + +def get_entry_info(dist, group, name): + """Return the EntryPoint object for `group`+`name`, or ``None``""" + return get_distribution(dist).get_entry_info(group, name) + + +class IMetadataProvider: + def has_metadata(name): + """Does the package's distribution contain the named metadata?""" + + def get_metadata(name): + """The named metadata resource as a string""" + + def get_metadata_lines(name): + """Yield named metadata resource as list of non-blank non-comment lines + + Leading and trailing whitespace is stripped from each line, and lines + with ``#`` as the first non-blank character are omitted.""" + + def metadata_isdir(name): + """Is the named metadata a directory? (like ``os.path.isdir()``)""" + + def metadata_listdir(name): + """List of metadata names in the directory (like ``os.listdir()``)""" + + def run_script(script_name, namespace): + """Execute the named script in the supplied namespace dictionary""" + + +class IResourceProvider(IMetadataProvider): + """An object that provides access to package resources""" + + def get_resource_filename(manager, resource_name): + """Return a true filesystem path for `resource_name` + + `manager` must be an ``IResourceManager``""" + + def get_resource_stream(manager, resource_name): + """Return a readable file-like object for `resource_name` + + `manager` must be an ``IResourceManager``""" + + def get_resource_string(manager, resource_name): + """Return a string containing the contents of `resource_name` + + `manager` must be an ``IResourceManager``""" + + def has_resource(resource_name): + """Does the package contain the named resource?""" + + def resource_isdir(resource_name): + """Is the named resource a directory? (like ``os.path.isdir()``)""" + + def resource_listdir(resource_name): + """List of resource names in the directory (like ``os.listdir()``)""" + + +class WorkingSet: + """A collection of active distributions on sys.path (or a similar list)""" + + def __init__(self, entries=None): + """Create working set from list of path entries (default=sys.path)""" + self.entries = [] + self.entry_keys = {} + self.by_key = {} + self.callbacks = [] + + if entries is None: + entries = sys.path + + for entry in entries: + self.add_entry(entry) + + @classmethod + def _build_master(cls): + """ + Prepare the master working set. + """ + ws = cls() + try: + from __main__ import __requires__ + except ImportError: + # The main program does not list any requirements + return ws + + # ensure the requirements are met + try: + ws.require(__requires__) + except VersionConflict: + return cls._build_from_requirements(__requires__) + + return ws + + @classmethod + def _build_from_requirements(cls, req_spec): + """ + Build a working set from a requirement spec. Rewrites sys.path. + """ + # try it without defaults already on sys.path + # by starting with an empty path + ws = cls([]) + reqs = parse_requirements(req_spec) + dists = ws.resolve(reqs, Environment()) + for dist in dists: + ws.add(dist) + + # add any missing entries from sys.path + for entry in sys.path: + if entry not in ws.entries: + ws.add_entry(entry) + + # then copy back to sys.path + sys.path[:] = ws.entries + return ws + + def add_entry(self, entry): + """Add a path item to ``.entries``, finding any distributions on it + + ``find_distributions(entry, True)`` is used to find distributions + corresponding to the path entry, and they are added. `entry` is + always appended to ``.entries``, even if it is already present. + (This is because ``sys.path`` can contain the same value more than + once, and the ``.entries`` of the ``sys.path`` WorkingSet should always + equal ``sys.path``.) + """ + self.entry_keys.setdefault(entry, []) + self.entries.append(entry) + for dist in find_distributions(entry, True): + self.add(dist, entry, False) + + def __contains__(self, dist): + """True if `dist` is the active distribution for its project""" + return self.by_key.get(dist.key) == dist + + def find(self, req): + """Find a distribution matching requirement `req` + + If there is an active distribution for the requested project, this + returns it as long as it meets the version requirement specified by + `req`. But, if there is an active distribution for the project and it + does *not* meet the `req` requirement, ``VersionConflict`` is raised. + If there is no active distribution for the requested project, ``None`` + is returned. + """ + dist = self.by_key.get(req.key) + if dist is not None and dist not in req: + # XXX add more info + raise VersionConflict(dist, req) + return dist + + def iter_entry_points(self, group, name=None): + """Yield entry point objects from `group` matching `name` + + If `name` is None, yields all entry points in `group` from all + distributions in the working set, otherwise only ones matching + both `group` and `name` are yielded (in distribution order). + """ + return ( + entry + for dist in self + for entry in dist.get_entry_map(group).values() + if name is None or name == entry.name + ) + + def run_script(self, requires, script_name): + """Locate distribution for `requires` and run `script_name` script""" + ns = sys._getframe(1).f_globals + name = ns['__name__'] + ns.clear() + ns['__name__'] = name + self.require(requires)[0].run_script(script_name, ns) + + def __iter__(self): + """Yield distributions for non-duplicate projects in the working set + + The yield order is the order in which the items' path entries were + added to the working set. + """ + seen = {} + for item in self.entries: + if item not in self.entry_keys: + # workaround a cache issue + continue + + for key in self.entry_keys[item]: + if key not in seen: + seen[key] = 1 + yield self.by_key[key] + + def add(self, dist, entry=None, insert=True, replace=False): + """Add `dist` to working set, associated with `entry` + + If `entry` is unspecified, it defaults to the ``.location`` of `dist`. + On exit from this routine, `entry` is added to the end of the working + set's ``.entries`` (if it wasn't already present). + + `dist` is only added to the working set if it's for a project that + doesn't already have a distribution in the set, unless `replace=True`. + If it's added, any callbacks registered with the ``subscribe()`` method + will be called. + """ + if insert: + dist.insert_on(self.entries, entry, replace=replace) + + if entry is None: + entry = dist.location + keys = self.entry_keys.setdefault(entry, []) + keys2 = self.entry_keys.setdefault(dist.location, []) + if not replace and dist.key in self.by_key: + # ignore hidden distros + return + + self.by_key[dist.key] = dist + if dist.key not in keys: + keys.append(dist.key) + if dist.key not in keys2: + keys2.append(dist.key) + self._added_new(dist) + + def resolve(self, requirements, env=None, installer=None, + replace_conflicting=False, extras=None): + """List all distributions needed to (recursively) meet `requirements` + + `requirements` must be a sequence of ``Requirement`` objects. `env`, + if supplied, should be an ``Environment`` instance. If + not supplied, it defaults to all distributions available within any + entry or distribution in the working set. `installer`, if supplied, + will be invoked with each requirement that cannot be met by an + already-installed distribution; it should return a ``Distribution`` or + ``None``. + + Unless `replace_conflicting=True`, raises a VersionConflict exception + if + any requirements are found on the path that have the correct name but + the wrong version. Otherwise, if an `installer` is supplied it will be + invoked to obtain the correct version of the requirement and activate + it. + + `extras` is a list of the extras to be used with these requirements. + This is important because extra requirements may look like `my_req; + extra = "my_extra"`, which would otherwise be interpreted as a purely + optional requirement. Instead, we want to be able to assert that these + requirements are truly required. + """ + + # set up the stack + requirements = list(requirements)[::-1] + # set of processed requirements + processed = {} + # key -> dist + best = {} + to_activate = [] + + req_extras = _ReqExtras() + + # Mapping of requirement to set of distributions that required it; + # useful for reporting info about conflicts. + required_by = collections.defaultdict(set) + + while requirements: + # process dependencies breadth-first + req = requirements.pop(0) + if req in processed: + # Ignore cyclic or redundant dependencies + continue + + if not req_extras.markers_pass(req, extras): + continue + + dist = best.get(req.key) + if dist is None: + # Find the best distribution and add it to the map + dist = self.by_key.get(req.key) + if dist is None or (dist not in req and replace_conflicting): + ws = self + if env is None: + if dist is None: + env = Environment(self.entries) + else: + # Use an empty environment and workingset to avoid + # any further conflicts with the conflicting + # distribution + env = Environment([]) + ws = WorkingSet([]) + dist = best[req.key] = env.best_match( + req, ws, installer, + replace_conflicting=replace_conflicting + ) + if dist is None: + requirers = required_by.get(req, None) + raise DistributionNotFound(req, requirers) + to_activate.append(dist) + if dist not in req: + # Oops, the "best" so far conflicts with a dependency + dependent_req = required_by[req] + raise VersionConflict(dist, req).with_context(dependent_req) + + # push the new requirements onto the stack + new_requirements = dist.requires(req.extras)[::-1] + requirements.extend(new_requirements) + + # Register the new requirements needed by req + for new_requirement in new_requirements: + required_by[new_requirement].add(req.project_name) + req_extras[new_requirement] = req.extras + + processed[req] = True + + # return list of distros to activate + return to_activate + + def find_plugins( + self, plugin_env, full_env=None, installer=None, fallback=True): + """Find all activatable distributions in `plugin_env` + + Example usage:: + + distributions, errors = working_set.find_plugins( + Environment(plugin_dirlist) + ) + # add plugins+libs to sys.path + map(working_set.add, distributions) + # display errors + print('Could not load', errors) + + The `plugin_env` should be an ``Environment`` instance that contains + only distributions that are in the project's "plugin directory" or + directories. The `full_env`, if supplied, should be an ``Environment`` + contains all currently-available distributions. If `full_env` is not + supplied, one is created automatically from the ``WorkingSet`` this + method is called on, which will typically mean that every directory on + ``sys.path`` will be scanned for distributions. + + `installer` is a standard installer callback as used by the + ``resolve()`` method. The `fallback` flag indicates whether we should + attempt to resolve older versions of a plugin if the newest version + cannot be resolved. + + This method returns a 2-tuple: (`distributions`, `error_info`), where + `distributions` is a list of the distributions found in `plugin_env` + that were loadable, along with any other distributions that are needed + to resolve their dependencies. `error_info` is a dictionary mapping + unloadable plugin distributions to an exception instance describing the + error that occurred. Usually this will be a ``DistributionNotFound`` or + ``VersionConflict`` instance. + """ + + plugin_projects = list(plugin_env) + # scan project names in alphabetic order + plugin_projects.sort() + + error_info = {} + distributions = {} + + if full_env is None: + env = Environment(self.entries) + env += plugin_env + else: + env = full_env + plugin_env + + shadow_set = self.__class__([]) + # put all our entries in shadow_set + list(map(shadow_set.add, self)) + + for project_name in plugin_projects: + + for dist in plugin_env[project_name]: + + req = [dist.as_requirement()] + + try: + resolvees = shadow_set.resolve(req, env, installer) + + except ResolutionError as v: + # save error info + error_info[dist] = v + if fallback: + # try the next older version of project + continue + else: + # give up on this project, keep going + break + + else: + list(map(shadow_set.add, resolvees)) + distributions.update(dict.fromkeys(resolvees)) + + # success, no need to try any more versions of this project + break + + distributions = list(distributions) + distributions.sort() + + return distributions, error_info + + def require(self, *requirements): + """Ensure that distributions matching `requirements` are activated + + `requirements` must be a string or a (possibly-nested) sequence + thereof, specifying the distributions and versions required. The + return value is a sequence of the distributions that needed to be + activated to fulfill the requirements; all relevant distributions are + included, even if they were already activated in this working set. + """ + needed = self.resolve(parse_requirements(requirements)) + + for dist in needed: + self.add(dist) + + return needed + + def subscribe(self, callback, existing=True): + """Invoke `callback` for all distributions + + If `existing=True` (default), + call on all existing ones, as well. + """ + if callback in self.callbacks: + return + self.callbacks.append(callback) + if not existing: + return + for dist in self: + callback(dist) + + def _added_new(self, dist): + for callback in self.callbacks: + callback(dist) + + def __getstate__(self): + return ( + self.entries[:], self.entry_keys.copy(), self.by_key.copy(), + self.callbacks[:] + ) + + def __setstate__(self, e_k_b_c): + entries, keys, by_key, callbacks = e_k_b_c + self.entries = entries[:] + self.entry_keys = keys.copy() + self.by_key = by_key.copy() + self.callbacks = callbacks[:] + + +class _ReqExtras(dict): + """ + Map each requirement to the extras that demanded it. + """ + + def markers_pass(self, req, extras=None): + """ + Evaluate markers for req against each extra that + demanded it. + + Return False if the req has a marker and fails + evaluation. Otherwise, return True. + """ + extra_evals = ( + req.marker.evaluate({'extra': extra}) + for extra in self.get(req, ()) + (extras or (None,)) + ) + return not req.marker or any(extra_evals) + + +class Environment: + """Searchable snapshot of distributions on a search path""" + + def __init__( + self, search_path=None, platform=get_supported_platform(), + python=PY_MAJOR): + """Snapshot distributions available on a search path + + Any distributions found on `search_path` are added to the environment. + `search_path` should be a sequence of ``sys.path`` items. If not + supplied, ``sys.path`` is used. + + `platform` is an optional string specifying the name of the platform + that platform-specific distributions must be compatible with. If + unspecified, it defaults to the current platform. `python` is an + optional string naming the desired version of Python (e.g. ``'3.6'``); + it defaults to the current version. + + You may explicitly set `platform` (and/or `python`) to ``None`` if you + wish to map *all* distributions, not just those compatible with the + running platform or Python version. + """ + self._distmap = {} + self.platform = platform + self.python = python + self.scan(search_path) + + def can_add(self, dist): + """Is distribution `dist` acceptable for this environment? + + The distribution must match the platform and python version + requirements specified when this environment was created, or False + is returned. + """ + py_compat = ( + self.python is None + or dist.py_version is None + or dist.py_version == self.python + ) + return py_compat and compatible_platforms(dist.platform, self.platform) + + def remove(self, dist): + """Remove `dist` from the environment""" + self._distmap[dist.key].remove(dist) + + def scan(self, search_path=None): + """Scan `search_path` for distributions usable in this environment + + Any distributions found are added to the environment. + `search_path` should be a sequence of ``sys.path`` items. If not + supplied, ``sys.path`` is used. Only distributions conforming to + the platform/python version defined at initialization are added. + """ + if search_path is None: + search_path = sys.path + + for item in search_path: + for dist in find_distributions(item): + self.add(dist) + + def __getitem__(self, project_name): + """Return a newest-to-oldest list of distributions for `project_name` + + Uses case-insensitive `project_name` comparison, assuming all the + project's distributions use their project's name converted to all + lowercase as their key. + + """ + distribution_key = project_name.lower() + return self._distmap.get(distribution_key, []) + + def add(self, dist): + """Add `dist` if we ``can_add()`` it and it has not already been added + """ + if self.can_add(dist) and dist.has_version(): + dists = self._distmap.setdefault(dist.key, []) + if dist not in dists: + dists.append(dist) + dists.sort(key=operator.attrgetter('hashcmp'), reverse=True) + + def best_match( + self, req, working_set, installer=None, replace_conflicting=False): + """Find distribution best matching `req` and usable on `working_set` + + This calls the ``find(req)`` method of the `working_set` to see if a + suitable distribution is already active. (This may raise + ``VersionConflict`` if an unsuitable version of the project is already + active in the specified `working_set`.) If a suitable distribution + isn't active, this method returns the newest distribution in the + environment that meets the ``Requirement`` in `req`. If no suitable + distribution is found, and `installer` is supplied, then the result of + calling the environment's ``obtain(req, installer)`` method will be + returned. + """ + try: + dist = working_set.find(req) + except VersionConflict: + if not replace_conflicting: + raise + dist = None + if dist is not None: + return dist + for dist in self[req.key]: + if dist in req: + return dist + # try to download/install + return self.obtain(req, installer) + + def obtain(self, requirement, installer=None): + """Obtain a distribution matching `requirement` (e.g. via download) + + Obtain a distro that matches requirement (e.g. via download). In the + base ``Environment`` class, this routine just returns + ``installer(requirement)``, unless `installer` is None, in which case + None is returned instead. This method is a hook that allows subclasses + to attempt other ways of obtaining a distribution before falling back + to the `installer` argument.""" + if installer is not None: + return installer(requirement) + + def __iter__(self): + """Yield the unique project names of the available distributions""" + for key in self._distmap.keys(): + if self[key]: + yield key + + def __iadd__(self, other): + """In-place addition of a distribution or environment""" + if isinstance(other, Distribution): + self.add(other) + elif isinstance(other, Environment): + for project in other: + for dist in other[project]: + self.add(dist) + else: + raise TypeError("Can't add %r to environment" % (other,)) + return self + + def __add__(self, other): + """Add an environment or distribution to an environment""" + new = self.__class__([], platform=None, python=None) + for env in self, other: + new += env + return new + + +# XXX backward compatibility +AvailableDistributions = Environment + + +class ExtractionError(RuntimeError): + """An error occurred extracting a resource + + The following attributes are available from instances of this exception: + + manager + The resource manager that raised this exception + + cache_path + The base directory for resource extraction + + original_error + The exception instance that caused extraction to fail + """ + + +class ResourceManager: + """Manage resource extraction and packages""" + extraction_path = None + + def __init__(self): + self.cached_files = {} + + def resource_exists(self, package_or_requirement, resource_name): + """Does the named resource exist?""" + return get_provider(package_or_requirement).has_resource(resource_name) + + def resource_isdir(self, package_or_requirement, resource_name): + """Is the named resource an existing directory?""" + return get_provider(package_or_requirement).resource_isdir( + resource_name + ) + + def resource_filename(self, package_or_requirement, resource_name): + """Return a true filesystem path for specified resource""" + return get_provider(package_or_requirement).get_resource_filename( + self, resource_name + ) + + def resource_stream(self, package_or_requirement, resource_name): + """Return a readable file-like object for specified resource""" + return get_provider(package_or_requirement).get_resource_stream( + self, resource_name + ) + + def resource_string(self, package_or_requirement, resource_name): + """Return specified resource as a string""" + return get_provider(package_or_requirement).get_resource_string( + self, resource_name + ) + + def resource_listdir(self, package_or_requirement, resource_name): + """List the contents of the named resource directory""" + return get_provider(package_or_requirement).resource_listdir( + resource_name + ) + + def extraction_error(self): + """Give an error message for problems extracting file(s)""" + + old_exc = sys.exc_info()[1] + cache_path = self.extraction_path or get_default_cache() + + tmpl = textwrap.dedent(""" + Can't extract file(s) to egg cache + + The following error occurred while trying to extract file(s) + to the Python egg cache: + + {old_exc} + + The Python egg cache directory is currently set to: + + {cache_path} + + Perhaps your account does not have write access to this directory? + You can change the cache directory by setting the PYTHON_EGG_CACHE + environment variable to point to an accessible directory. + """).lstrip() + err = ExtractionError(tmpl.format(**locals())) + err.manager = self + err.cache_path = cache_path + err.original_error = old_exc + raise err + + def get_cache_path(self, archive_name, names=()): + """Return absolute location in cache for `archive_name` and `names` + + The parent directory of the resulting path will be created if it does + not already exist. `archive_name` should be the base filename of the + enclosing egg (which may not be the name of the enclosing zipfile!), + including its ".egg" extension. `names`, if provided, should be a + sequence of path name parts "under" the egg's extraction location. + + This method should only be called by resource providers that need to + obtain an extraction location, and only for names they intend to + extract, as it tracks the generated names for possible cleanup later. + """ + extract_path = self.extraction_path or get_default_cache() + target_path = os.path.join(extract_path, archive_name + '-tmp', *names) + try: + _bypass_ensure_directory(target_path) + except Exception: + self.extraction_error() + + self._warn_unsafe_extraction_path(extract_path) + + self.cached_files[target_path] = 1 + return target_path + + @staticmethod + def _warn_unsafe_extraction_path(path): + """ + If the default extraction path is overridden and set to an insecure + location, such as /tmp, it opens up an opportunity for an attacker to + replace an extracted file with an unauthorized payload. Warn the user + if a known insecure location is used. + + See Distribute #375 for more details. + """ + if os.name == 'nt' and not path.startswith(os.environ['windir']): + # On Windows, permissions are generally restrictive by default + # and temp directories are not writable by other users, so + # bypass the warning. + return + 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 " + "location (set with .set_extraction_path or the " + "PYTHON_EGG_CACHE environment variable)." % path + ) + warnings.warn(msg, UserWarning) + + def postprocess(self, tempname, filename): + """Perform any platform-specific postprocessing of `tempname` + + This is where Mac header rewrites should be done; other platforms don't + have anything special they should do. + + Resource providers should call this method ONLY after successfully + extracting a compressed resource. They must NOT call it on resources + that are already in the filesystem. + + `tempname` is the current (temporary) name of the file, and `filename` + is the name it will be renamed to by the caller after this routine + returns. + """ + + if os.name == 'posix': + # Make the resource executable + mode = ((os.stat(tempname).st_mode) | 0o555) & 0o7777 + os.chmod(tempname, mode) + + def set_extraction_path(self, path): + """Set the base path where resources will be extracted to, if needed. + + If you do not call this routine before any extractions take place, the + path defaults to the return value of ``get_default_cache()``. (Which + is based on the ``PYTHON_EGG_CACHE`` environment variable, with various + platform-specific fallbacks. See that routine's documentation for more + details.) + + Resources are extracted to subdirectories of this path based upon + information given by the ``IResourceProvider``. You may set this to a + temporary directory, but then you must call ``cleanup_resources()`` to + delete the extracted files when done. There is no guarantee that + ``cleanup_resources()`` will be able to remove all extracted files. + + (Note: you may not change the extraction path for a given resource + manager once resources have been extracted, unless you first call + ``cleanup_resources()``.) + """ + if self.cached_files: + raise ValueError( + "Can't change extraction path, files already extracted" + ) + + self.extraction_path = path + + def cleanup_resources(self, force=False): + """ + Delete all extracted resource files and directories, returning a list + of the file and directory names that could not be successfully removed. + This function does not have any concurrency protection, so it should + generally only be called when the extraction path is a temporary + directory exclusive to a single process. This method is not + automatically called; you must call it explicitly or register it as an + ``atexit`` function if you wish to ensure cleanup of a temporary + directory used for extractions. + """ + # XXX + + +def get_default_cache(): + """ + Return the ``PYTHON_EGG_CACHE`` environment variable + or a platform-relevant user cache dir for an app + named "Python-Eggs". + """ + return ( + os.environ.get('PYTHON_EGG_CACHE') + or appdirs.user_cache_dir(appname='Python-Eggs') + ) + + +def safe_name(name): + """Convert an arbitrary string to a standard distribution name + + Any runs of non-alphanumeric/. characters are replaced with a single '-'. + """ + return re.sub('[^A-Za-z0-9.]+', '-', name) + + +def safe_version(version): + """ + Convert an arbitrary string to a standard version string + """ + try: + # normalize the version + return str(packaging.version.Version(version)) + except packaging.version.InvalidVersion: + version = version.replace(' ', '.') + return re.sub('[^A-Za-z0-9.]+', '-', version) + + +def safe_extra(extra): + """Convert an arbitrary string to a standard 'extra' name + + Any runs of non-alphanumeric characters are replaced with a single '_', + and the result is always lowercased. + """ + return re.sub('[^A-Za-z0-9.-]+', '_', extra).lower() + + +def to_filename(name): + """Convert a project or version name to its filename-escaped form + + Any '-' characters are currently replaced with '_'. + """ + return name.replace('-', '_') + + +def invalid_marker(text): + """ + Validate text as a PEP 508 environment marker; return an exception + if invalid or False otherwise. + """ + try: + evaluate_marker(text) + except SyntaxError as e: + e.filename = None + e.lineno = None + return e + return False + + +def evaluate_marker(text, extra=None): + """ + Evaluate a PEP 508 environment marker. + Return a boolean indicating the marker result in this environment. + Raise SyntaxError if marker is invalid. + + This implementation uses the 'pyparsing' module. + """ + try: + marker = packaging.markers.Marker(text) + return marker.evaluate() + except packaging.markers.InvalidMarker as e: + raise SyntaxError(e) + + +class NullProvider: + """Try to implement resources and metadata for arbitrary PEP 302 loaders""" + + egg_name = None + egg_info = None + loader = None + + def __init__(self, module): + self.loader = getattr(module, '__loader__', None) + self.module_path = os.path.dirname(getattr(module, '__file__', '')) + + def get_resource_filename(self, manager, resource_name): + return self._fn(self.module_path, resource_name) + + def get_resource_stream(self, manager, resource_name): + return io.BytesIO(self.get_resource_string(manager, resource_name)) + + def get_resource_string(self, manager, resource_name): + return self._get(self._fn(self.module_path, resource_name)) + + def has_resource(self, resource_name): + return self._has(self._fn(self.module_path, resource_name)) + + def has_metadata(self, name): + return self.egg_info and self._has(self._fn(self.egg_info, name)) + + 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 + + def get_metadata_lines(self, name): + return yield_lines(self.get_metadata(name)) + + def resource_isdir(self, resource_name): + return self._isdir(self._fn(self.module_path, resource_name)) + + def metadata_isdir(self, name): + return self.egg_info and self._isdir(self._fn(self.egg_info, name)) + + def resource_listdir(self, resource_name): + return self._listdir(self._fn(self.module_path, resource_name)) + + def metadata_listdir(self, name): + if self.egg_info: + return self._listdir(self._fn(self.egg_info, name)) + return [] + + def run_script(self, script_name, namespace): + script = 'scripts/' + script_name + if not self.has_metadata(script): + raise ResolutionError( + "Script {script!r} not found in metadata at {self.egg_info!r}" + .format(**locals()), + ) + script_text = self.get_metadata(script).replace('\r\n', '\n') + script_text = script_text.replace('\r', '\n') + script_filename = self._fn(self.egg_info, script) + namespace['__file__'] = script_filename + if os.path.exists(script_filename): + source = open(script_filename).read() + code = compile(source, script_filename, 'exec') + exec(code, namespace, namespace) + else: + from linecache import cache + cache[script_filename] = ( + len(script_text), 0, script_text.split('\n'), script_filename + ) + script_code = compile(script_text, script_filename, 'exec') + exec(script_code, namespace, namespace) + + def _has(self, path): + raise NotImplementedError( + "Can't perform this operation for unregistered loader type" + ) + + def _isdir(self, path): + raise NotImplementedError( + "Can't perform this operation for unregistered loader type" + ) + + def _listdir(self, path): + raise NotImplementedError( + "Can't perform this operation for unregistered loader type" + ) + + def _fn(self, base, resource_name): + if resource_name: + return os.path.join(base, *resource_name.split('/')) + return base + + def _get(self, path): + if hasattr(self.loader, 'get_data'): + return self.loader.get_data(path) + raise NotImplementedError( + "Can't perform this operation for loaders without 'get_data()'" + ) + + +register_loader_type(object, NullProvider) + + +class EggProvider(NullProvider): + """Provider based on a virtual filesystem""" + + def __init__(self, module): + NullProvider.__init__(self, module) + 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) + + +class DefaultProvider(EggProvider): + """Provides access to package resources in the filesystem""" + + def _has(self, path): + return os.path.exists(path) + + def _isdir(self, path): + return os.path.isdir(path) + + def _listdir(self, path): + return os.listdir(path) + + def get_resource_stream(self, manager, resource_name): + return open(self._fn(self.module_path, resource_name), 'rb') + + def _get(self, path): + with open(path, 'rb') as stream: + return stream.read() + + @classmethod + def _register(cls): + loader_names = 'SourceFileLoader', 'SourcelessFileLoader', + for name in loader_names: + loader_cls = getattr(importlib_machinery, name, type(None)) + register_loader_type(loader_cls, cls) + + +DefaultProvider._register() + + +class EmptyProvider(NullProvider): + """Provider that returns nothing for all requests""" + + module_path = None + + _isdir = _has = lambda self, path: False + + def _get(self, path): + return '' + + def _listdir(self, path): + return [] + + def __init__(self): + pass + + +empty_provider = EmptyProvider() + + +class ZipManifests(dict): + """ + zip manifest builder + """ + + @classmethod + def build(cls, path): + """ + Build a dictionary similar to the zipimport directory + caches, except instead of tuples, store ZipInfo objects. + + Use a platform-specific path separator (os.sep) for the path keys + for compatibility with pypy on Windows. + """ + with zipfile.ZipFile(path) as zfile: + items = ( + ( + name.replace('/', os.sep), + zfile.getinfo(name), + ) + for name in zfile.namelist() + ) + return dict(items) + + load = build + + +class MemoizedZipManifests(ZipManifests): + """ + Memoized zipfile manifests. + """ + manifest_mod = collections.namedtuple('manifest_mod', 'manifest mtime') + + def load(self, path): + """ + Load a manifest at path or return a suitable manifest already loaded. + """ + path = os.path.normpath(path) + mtime = os.stat(path).st_mtime + + if path not in self or self[path].mtime != mtime: + manifest = self.build(path) + self[path] = self.manifest_mod(manifest, mtime) + + return self[path].manifest + + +class ZipProvider(EggProvider): + """Resource support for zips and eggs""" + + eagers = None + _zip_manifests = MemoizedZipManifests() + + def __init__(self, module): + EggProvider.__init__(self, module) + self.zip_pre = self.loader.archive + os.sep + + def _zipinfo_name(self, fspath): + # Convert a virtual filename (full path to file) into a zipfile subpath + # usable with the zipimport directory cache for our target archive + fspath = fspath.rstrip(os.sep) + if fspath == self.loader.archive: + return '' + if fspath.startswith(self.zip_pre): + return fspath[len(self.zip_pre):] + raise AssertionError( + "%s is not a subpath of %s" % (fspath, self.zip_pre) + ) + + def _parts(self, zip_path): + # Convert a zipfile subpath into an egg-relative path part list. + # pseudo-fs path + fspath = self.zip_pre + zip_path + if fspath.startswith(self.egg_root + os.sep): + return fspath[len(self.egg_root) + 1:].split(os.sep) + raise AssertionError( + "%s is not a subpath of %s" % (fspath, self.egg_root) + ) + + @property + def zipinfo(self): + return self._zip_manifests.load(self.loader.archive) + + def get_resource_filename(self, manager, resource_name): + if not self.egg_name: + raise NotImplementedError( + "resource_filename() only supported for .egg, not .zip" + ) + # no need to lock for extraction, since we use temp names + zip_path = self._resource_to_zip(resource_name) + eagers = self._get_eager_resources() + if '/'.join(self._parts(zip_path)) in eagers: + for name in eagers: + self._extract_resource(manager, self._eager_to_zip(name)) + return self._extract_resource(manager, zip_path) + + @staticmethod + def _get_date_and_size(zip_stat): + size = zip_stat.file_size + # ymdhms+wday, yday, dst + date_time = zip_stat.date_time + (0, 0, -1) + # 1980 offset already done + timestamp = time.mktime(date_time) + return timestamp, size + + def _extract_resource(self, manager, zip_path): + + if zip_path in self._index(): + for name in self._index()[zip_path]: + last = self._extract_resource( + manager, os.path.join(zip_path, name) + ) + # return the extracted directory name + return os.path.dirname(last) + + timestamp, size = self._get_date_and_size(self.zipinfo[zip_path]) + + if not WRITE_SUPPORT: + raise IOError('"os.rename" and "os.unlink" are not supported ' + 'on this platform') + try: + + real_path = manager.get_cache_path( + self.egg_name, self._parts(zip_path) + ) + + if self._is_current(real_path, zip_path): + return real_path + + outf, tmpnam = _mkstemp( + ".$extract", + dir=os.path.dirname(real_path), + ) + os.write(outf, self.loader.get_data(zip_path)) + os.close(outf) + utime(tmpnam, (timestamp, timestamp)) + manager.postprocess(tmpnam, real_path) + + try: + rename(tmpnam, real_path) + + except os.error: + if os.path.isfile(real_path): + if self._is_current(real_path, zip_path): + # the file became current since it was checked above, + # so proceed. + return real_path + # Windows, del old file and retry + elif os.name == 'nt': + unlink(real_path) + rename(tmpnam, real_path) + return real_path + raise + + except os.error: + # report a user-friendly error + manager.extraction_error() + + return real_path + + def _is_current(self, file_path, zip_path): + """ + Return True if the file_path is current for this zip_path + """ + timestamp, size = self._get_date_and_size(self.zipinfo[zip_path]) + if not os.path.isfile(file_path): + return False + stat = os.stat(file_path) + if stat.st_size != size or stat.st_mtime != timestamp: + return False + # check that the contents match + zip_contents = self.loader.get_data(zip_path) + with open(file_path, 'rb') as f: + file_contents = f.read() + return zip_contents == file_contents + + def _get_eager_resources(self): + if self.eagers is None: + eagers = [] + for name in ('native_libs.txt', 'eager_resources.txt'): + if self.has_metadata(name): + eagers.extend(self.get_metadata_lines(name)) + self.eagers = eagers + return self.eagers + + def _index(self): + try: + return self._dirindex + except AttributeError: + ind = {} + for path in self.zipinfo: + parts = path.split(os.sep) + while parts: + parent = os.sep.join(parts[:-1]) + if parent in ind: + ind[parent].append(parts[-1]) + break + else: + ind[parent] = [parts.pop()] + self._dirindex = ind + return ind + + def _has(self, fspath): + zip_path = self._zipinfo_name(fspath) + return zip_path in self.zipinfo or zip_path in self._index() + + def _isdir(self, fspath): + return self._zipinfo_name(fspath) in self._index() + + def _listdir(self, fspath): + return list(self._index().get(self._zipinfo_name(fspath), ())) + + def _eager_to_zip(self, resource_name): + return self._zipinfo_name(self._fn(self.egg_root, resource_name)) + + def _resource_to_zip(self, resource_name): + return self._zipinfo_name(self._fn(self.module_path, resource_name)) + + +register_loader_type(zipimport.zipimporter, ZipProvider) + + +class FileMetadata(EmptyProvider): + """Metadata handler for standalone PKG-INFO files + + Usage:: + + metadata = FileMetadata("/path/to/PKG-INFO") + + This provider rejects all data and metadata requests except for PKG-INFO, + which is treated as existing, and will be the contents of the file at + the provided location. + """ + + def __init__(self, path): + self.path = path + + def has_metadata(self, name): + return name == 'PKG-INFO' and os.path.isfile(self.path) + + def get_metadata(self, name): + if name != 'PKG-INFO': + raise KeyError("No metadata except PKG-INFO is available") + + with io.open(self.path, encoding='utf-8', errors="replace") as f: + metadata = f.read() + self._warn_on_replacement(metadata) + return metadata + + def _warn_on_replacement(self, metadata): + # Python 2.7 compat for: replacement_char = '�' + replacement_char = b'\xef\xbf\xbd'.decode('utf-8') + if replacement_char in metadata: + tmpl = "{self.path} could not be properly decoded in UTF-8" + msg = tmpl.format(**locals()) + warnings.warn(msg) + + def get_metadata_lines(self, name): + return yield_lines(self.get_metadata(name)) + + +class PathMetadata(DefaultProvider): + """Metadata provider for egg directories + + Usage:: + + # Development eggs: + + egg_info = "/path/to/PackageName.egg-info" + base_dir = os.path.dirname(egg_info) + metadata = PathMetadata(base_dir, egg_info) + dist_name = os.path.splitext(os.path.basename(egg_info))[0] + dist = Distribution(basedir, project_name=dist_name, metadata=metadata) + + # Unpacked egg directories: + + egg_path = "/path/to/PackageName-ver-pyver-etc.egg" + metadata = PathMetadata(egg_path, os.path.join(egg_path,'EGG-INFO')) + dist = Distribution.from_filename(egg_path, metadata=metadata) + """ + + def __init__(self, path, egg_info): + self.module_path = path + self.egg_info = egg_info + + +class EggMetadata(ZipProvider): + """Metadata provider for .egg files""" + + def __init__(self, importer): + """Create a metadata provider from a zipimporter""" + + self.zip_pre = importer.archive + os.sep + self.loader = importer + if importer.prefix: + self.module_path = os.path.join(importer.archive, importer.prefix) + else: + self.module_path = importer.archive + self._setup_prefix() + + +_declare_state('dict', _distribution_finders={}) + + +def register_finder(importer_type, distribution_finder): + """Register `distribution_finder` to find distributions in sys.path items + + `importer_type` is the type or class of a PEP 302 "Importer" (sys.path item + handler), and `distribution_finder` is a callable that, passed a path + item and the importer instance, yields ``Distribution`` instances found on + that path item. See ``pkg_resources.find_on_path`` for an example.""" + _distribution_finders[importer_type] = distribution_finder + + +def find_distributions(path_item, only=False): + """Yield distributions accessible via `path_item`""" + importer = get_importer(path_item) + finder = _find_adapter(_distribution_finders, importer) + return finder(importer, path_item, only) + + +def find_eggs_in_zip(importer, path_item, only=False): + """ + Find eggs in zip files; possibly multiple nested eggs. + """ + if importer.archive.endswith('.whl'): + # wheels are not supported with this finder + # they don't have PKG-INFO metadata, and won't ever contain eggs + return + metadata = EggMetadata(importer) + if metadata.has_metadata('PKG-INFO'): + yield Distribution.from_filename(path_item, metadata=metadata) + if only: + # don't yield nested distros + return + for subitem in metadata.resource_listdir('/'): + if _is_egg_path(subitem): + subpath = os.path.join(path_item, subitem) + dists = find_eggs_in_zip(zipimport.zipimporter(subpath), subpath) + for dist in dists: + yield dist + elif subitem.lower().endswith('.dist-info'): + subpath = os.path.join(path_item, subitem) + submeta = EggMetadata(zipimport.zipimporter(subpath)) + submeta.egg_info = subpath + yield Distribution.from_location(path_item, subitem, submeta) + + +register_finder(zipimport.zipimporter, find_eggs_in_zip) + + +def find_nothing(importer, path_item, only=False): + return () + + +register_finder(object, find_nothing) + + +def _by_version_descending(names): + """ + Given a list of filenames, return them in descending order + by version number. + + >>> names = 'bar', 'foo', 'Python-2.7.10.egg', 'Python-2.7.2.egg' + >>> _by_version_descending(names) + ['Python-2.7.10.egg', 'Python-2.7.2.egg', 'foo', 'bar'] + >>> names = 'Setuptools-1.2.3b1.egg', 'Setuptools-1.2.3.egg' + >>> _by_version_descending(names) + ['Setuptools-1.2.3.egg', 'Setuptools-1.2.3b1.egg'] + >>> names = 'Setuptools-1.2.3b1.egg', 'Setuptools-1.2.3.post1.egg' + >>> _by_version_descending(names) + ['Setuptools-1.2.3.post1.egg', 'Setuptools-1.2.3b1.egg'] + """ + def _by_version(name): + """ + Parse each component of the filename + """ + name, ext = os.path.splitext(name) + parts = itertools.chain(name.split('-'), [ext]) + return [packaging.version.parse(part) for part in parts] + + return sorted(names, key=_by_version, reverse=True) + + +def find_on_path(importer, path_item, only=False): + """Yield distributions accessible on a sys.path directory""" + path_item = _normalize_cached(path_item) + + if _is_unpacked_egg(path_item): + yield Distribution.from_filename( + path_item, metadata=PathMetadata( + path_item, os.path.join(path_item, 'EGG-INFO') + ) + ) + return + + entries = safe_listdir(path_item) + + # for performance, before sorting by version, + # screen entries for only those that will yield + # distributions + filtered = ( + entry + for entry in entries + if dist_factory(path_item, entry, only) + ) + + # scan for .egg and .egg-info in directory + path_item_entries = _by_version_descending(filtered) + for entry in path_item_entries: + fullpath = os.path.join(path_item, entry) + factory = dist_factory(path_item, entry, only) + for dist in factory(fullpath): + yield dist + + +def dist_factory(path_item, entry, only): + """ + Return a dist_factory for a path_item and entry + """ + lower = entry.lower() + is_meta = any(map(lower.endswith, ('.egg-info', '.dist-info'))) + return ( + distributions_from_metadata + if is_meta else + find_distributions + if not only and _is_egg_path(entry) else + resolve_egg_link + if not only and lower.endswith('.egg-link') else + NoDists() + ) + + +class NoDists: + """ + >>> bool(NoDists()) + False + + >>> list(NoDists()('anything')) + [] + """ + def __bool__(self): + return False + if six.PY2: + __nonzero__ = __bool__ + + def __call__(self, fullpath): + return iter(()) + + +def safe_listdir(path): + """ + Attempt to list contents of path, but suppress some exceptions. + """ + try: + return os.listdir(path) + except (PermissionError, NotADirectoryError): + pass + except OSError as e: + # Ignore the directory if does not exist, not a directory or + # permission denied + ignorable = ( + e.errno in (errno.ENOTDIR, errno.EACCES, errno.ENOENT) + # Python 2 on Windows needs to be handled this way :( + or getattr(e, "winerror", None) == 267 + ) + if not ignorable: + raise + return () + + +def distributions_from_metadata(path): + root = os.path.dirname(path) + if os.path.isdir(path): + if len(os.listdir(path)) == 0: + # empty metadata dir; skip + return + metadata = PathMetadata(root, path) + else: + metadata = FileMetadata(path) + entry = os.path.basename(path) + yield Distribution.from_location( + root, entry, metadata, precedence=DEVELOP_DIST, + ) + + +def non_empty_lines(path): + """ + Yield non-empty lines from file at path + """ + with open(path) as f: + for line in f: + line = line.strip() + if line: + yield line + + +def resolve_egg_link(path): + """ + Given a path to an .egg-link, resolve distributions + present in the referenced path. + """ + referenced_paths = non_empty_lines(path) + resolved_paths = ( + os.path.join(os.path.dirname(path), ref) + for ref in referenced_paths + ) + dist_groups = map(find_distributions, resolved_paths) + return next(dist_groups, ()) + + +register_finder(pkgutil.ImpImporter, find_on_path) + +if hasattr(importlib_machinery, 'FileFinder'): + register_finder(importlib_machinery.FileFinder, find_on_path) + +_declare_state('dict', _namespace_handlers={}) +_declare_state('dict', _namespace_packages={}) + + +def register_namespace_handler(importer_type, namespace_handler): + """Register `namespace_handler` to declare namespace packages + + `importer_type` is the type or class of a PEP 302 "Importer" (sys.path item + handler), and `namespace_handler` is a callable like this:: + + def namespace_handler(importer, path_entry, moduleName, module): + # return a path_entry to use for child packages + + Namespace handlers are only called if the importer object has already + agreed that it can handle the relevant path item, and they should only + return a subpath if the module __path__ does not already contain an + equivalent subpath. For an example namespace handler, see + ``pkg_resources.file_ns_handler``. + """ + _namespace_handlers[importer_type] = namespace_handler + + +def _handle_ns(packageName, path_item): + """Ensure that named package includes a subpath of path_item (if needed)""" + + importer = get_importer(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) + + if loader is None: + return None + module = sys.modules.get(packageName) + if module is None: + module = sys.modules[packageName] = types.ModuleType(packageName) + module.__path__ = [] + _set_parent_ns(packageName) + elif not hasattr(module, '__path__'): + raise TypeError("Not a package:", packageName) + handler = _find_adapter(_namespace_handlers, importer) + subpath = handler(importer, path_item, packageName, module) + if subpath is not None: + path = module.__path__ + path.append(subpath) + loader.load_module(packageName) + _rebuild_mod_path(path, packageName, module) + return subpath + + +def _rebuild_mod_path(orig_path, package_name, module): + """ + Rebuild module.__path__ ensuring that all entries are ordered + corresponding to their sys.path order + """ + sys_path = [_normalize_cached(p) for p in sys.path] + + def safe_sys_path_index(entry): + """ + Workaround for #520 and #513. + """ + try: + return sys_path.index(entry) + except ValueError: + return float('inf') + + def position_in_sys_path(path): + """ + Return the ordinal of the path based on its position in sys.path + """ + path_parts = path.split(os.sep) + module_parts = package_name.count('.') + 1 + parts = path_parts[:-module_parts] + return safe_sys_path_index(_normalize_cached(os.sep.join(parts))) + + new_path = sorted(orig_path, key=position_in_sys_path) + new_path = [_normalize_cached(p) for p in new_path] + + if isinstance(module.__path__, list): + module.__path__[:] = new_path + else: + module.__path__ = new_path + + +def declare_namespace(packageName): + """Declare that package 'packageName' is a namespace package""" + + _imp.acquire_lock() + try: + if packageName in _namespace_packages: + return + + path = sys.path + parent, _, _ = packageName.rpartition('.') + + if parent: + declare_namespace(parent) + if parent not in _namespace_packages: + __import__(parent) + try: + path = sys.modules[parent].__path__ + except AttributeError: + raise TypeError("Not a package:", parent) + + # Track what packages are namespaces, so when new path items are added, + # they can be updated + _namespace_packages.setdefault(parent or None, []).append(packageName) + _namespace_packages.setdefault(packageName, []) + + for path_item in path: + # Ensure all the parent's path items are reflected in the child, + # if they apply + _handle_ns(packageName, path_item) + + finally: + _imp.release_lock() + + +def fixup_namespace_packages(path_item, parent=None): + """Ensure that previously-declared namespace packages include path_item""" + _imp.acquire_lock() + try: + for package in _namespace_packages.get(parent, ()): + subpath = _handle_ns(package, path_item) + if subpath: + fixup_namespace_packages(subpath, package) + finally: + _imp.release_lock() + + +def file_ns_handler(importer, path_item, packageName, module): + """Compute an ns-package subpath for a filesystem or zipfile importer""" + + subpath = os.path.join(path_item, packageName.split('.')[-1]) + normalized = _normalize_cached(subpath) + for item in module.__path__: + if _normalize_cached(item) == normalized: + break + else: + # Only return the path if it's not already there + return subpath + + +register_namespace_handler(pkgutil.ImpImporter, file_ns_handler) +register_namespace_handler(zipimport.zipimporter, file_ns_handler) + +if hasattr(importlib_machinery, 'FileFinder'): + register_namespace_handler(importlib_machinery.FileFinder, file_ns_handler) + + +def null_ns_handler(importer, path_item, packageName, module): + return None + + +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)))) + + +def _cygwin_patch(filename): # pragma: nocover + """ + Contrary to POSIX 2008, on Cygwin, getcwd (3) contains + symlink components. Using + os.path.abspath() works around this limitation. A fix in os.getcwd() + would probably better, in Cygwin even more so, except + that this seems to be by design... + """ + return os.path.abspath(filename) if sys.platform == 'cygwin' else filename + + +def _normalize_cached(filename, _cache={}): + try: + return _cache[filename] + except KeyError: + _cache[filename] = result = normalize_path(filename) + return result + + +def _is_egg_path(path): + """ + Determine if given path appears to be an egg. + """ + return path.lower().endswith('.egg') + + +def _is_unpacked_egg(path): + """ + Determine if given path appears to be an unpacked egg. + """ + return ( + _is_egg_path(path) and + os.path.isfile(os.path.join(path, 'EGG-INFO', 'PKG-INFO')) + ) + + +def _set_parent_ns(packageName): + parts = packageName.split('.') + name = parts.pop() + if parts: + parent = '.'.join(parts) + setattr(sys.modules[parent], name, sys.modules[packageName]) + + +def yield_lines(strs): + """Yield non-empty/non-comment lines of a string or sequence""" + if isinstance(strs, six.string_types): + for s in strs.splitlines(): + s = s.strip() + # skip blank lines/comments + if s and not s.startswith('#'): + yield s + else: + for ss in strs: + for s in yield_lines(ss): + yield s + + +MODULE = re.compile(r"\w+(\.\w+)*$").match +EGG_NAME = re.compile( + r""" + (?P<name>[^-]+) ( + -(?P<ver>[^-]+) ( + -py(?P<pyver>[^-]+) ( + -(?P<plat>.+) + )? + )? + )? + """, + re.VERBOSE | re.IGNORECASE, +).match + + +class EntryPoint: + """Object representing an advertised importable object""" + + def __init__(self, name, module_name, attrs=(), extras=(), dist=None): + if not MODULE(module_name): + raise ValueError("Invalid module name", module_name) + self.name = name + self.module_name = module_name + self.attrs = tuple(attrs) + self.extras = tuple(extras) + self.dist = dist + + def __str__(self): + s = "%s = %s" % (self.name, self.module_name) + if self.attrs: + s += ':' + '.'.join(self.attrs) + if self.extras: + s += ' [%s]' % ','.join(self.extras) + return s + + def __repr__(self): + return "EntryPoint.parse(%r)" % str(self) + + def load(self, require=True, *args, **kwargs): + """ + Require packages for this EntryPoint, then resolve it. + """ + if not require or args or kwargs: + warnings.warn( + "Parameters to load are deprecated. Call .resolve and " + ".require separately.", + PkgResourcesDeprecationWarning, + stacklevel=2, + ) + if require: + self.require(*args, **kwargs) + return self.resolve() + + def resolve(self): + """ + Resolve the entry point from its module and attrs. + """ + module = __import__(self.module_name, fromlist=['__name__'], level=0) + try: + return functools.reduce(getattr, self.attrs, module) + except AttributeError as exc: + raise ImportError(str(exc)) + + def require(self, env=None, installer=None): + if self.extras and not self.dist: + raise UnknownExtra("Can't require() without a distribution", self) + + # Get the requirements for this entry point with all its extras and + # then resolve them. We have to pass `extras` along when resolving so + # that the working set knows what extras we want. Otherwise, for + # dist-info distributions, the working set will assume that the + # requirements for that extra are purely optional and skip over them. + reqs = self.dist.requires(self.extras) + items = working_set.resolve(reqs, env, installer, extras=self.extras) + list(map(working_set.add, items)) + + pattern = re.compile( + r'\s*' + r'(?P<name>.+?)\s*' + r'=\s*' + r'(?P<module>[\w.]+)\s*' + r'(:\s*(?P<attr>[\w.]+))?\s*' + r'(?P<extras>\[.*\])?\s*$' + ) + + @classmethod + def parse(cls, src, dist=None): + """Parse a single entry point from string `src` + + Entry point syntax follows the form:: + + name = some.module:some.attr [extra1, extra2] + + The entry name and module name are required, but the ``:attrs`` and + ``[extras]`` parts are optional + """ + m = cls.pattern.match(src) + if not m: + msg = "EntryPoint must be in 'name=module:attrs [extras]' format" + raise ValueError(msg, src) + res = m.groupdict() + extras = cls._parse_extras(res['extras']) + attrs = res['attr'].split('.') if res['attr'] else () + return cls(res['name'], res['module'], attrs, extras, dist) + + @classmethod + def _parse_extras(cls, extras_spec): + if not extras_spec: + return () + req = Requirement.parse('x' + extras_spec) + if req.specs: + raise ValueError() + return req.extras + + @classmethod + def parse_group(cls, group, lines, dist=None): + """Parse an entry point group""" + if not MODULE(group): + raise ValueError("Invalid group name", group) + this = {} + for line in yield_lines(lines): + ep = cls.parse(line, dist) + if ep.name in this: + raise ValueError("Duplicate entry point", group, ep.name) + this[ep.name] = ep + return this + + @classmethod + def parse_map(cls, data, dist=None): + """Parse a map of entry point groups""" + if isinstance(data, dict): + data = data.items() + else: + data = split_sections(data) + maps = {} + for group, lines in data: + if group is None: + if not lines: + continue + raise ValueError("Entry points must be listed in groups") + group = group.strip() + if group in maps: + raise ValueError("Duplicate group name", group) + maps[group] = cls.parse_group(group, lines, dist) + 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 + the value of the Version field, if present, or None otherwise. + """ + def is_version_line(line): + return line.lower().startswith('version:') + version_lines = filter(is_version_line, lines) + line = next(iter(version_lines), '') + _, _, value = line.partition(':') + return safe_version(value.strip()) or None + + +class Distribution: + """Wrap an actual or potential sys.path entry w/metadata""" + PKG_INFO = 'PKG-INFO' + + def __init__( + self, location=None, metadata=None, project_name=None, + version=None, py_version=PY_MAJOR, platform=None, + precedence=EGG_DIST): + self.project_name = safe_name(project_name or 'Unknown') + if version is not None: + self._version = safe_version(version) + self.py_version = py_version + self.platform = platform + self.location = location + self.precedence = precedence + self._provider = metadata or empty_provider + + @classmethod + def from_location(cls, location, basename, metadata=None, **kw): + project_name, version, py_version, platform = [None] * 4 + basename, ext = os.path.splitext(basename) + if ext.lower() in _distributionImpl: + cls = _distributionImpl[ext.lower()] + + match = EGG_NAME(basename) + if match: + project_name, version, py_version, platform = match.group( + 'name', 'ver', 'pyver', 'plat' + ) + return cls( + location, metadata, project_name=project_name, version=version, + py_version=py_version, platform=platform, **kw + )._reload_version() + + def _reload_version(self): + return self + + @property + def hashcmp(self): + return ( + self.parsed_version, + self.precedence, + self.key, + _remove_md5_fragment(self.location), + self.py_version or '', + self.platform or '', + ) + + def __hash__(self): + return hash(self.hashcmp) + + def __lt__(self, other): + return self.hashcmp < other.hashcmp + + def __le__(self, other): + return self.hashcmp <= other.hashcmp + + def __gt__(self, other): + return self.hashcmp > other.hashcmp + + def __ge__(self, other): + return self.hashcmp >= other.hashcmp + + def __eq__(self, other): + if not isinstance(other, self.__class__): + # It's not a Distribution, so they are not equal + return False + return self.hashcmp == other.hashcmp + + def __ne__(self, other): + return not self == other + + # These properties have to be lazy so that we don't have to load any + # metadata until/unless it's actually needed. (i.e., some distributions + # may not know their name or version without loading PKG-INFO) + + @property + def key(self): + try: + return self._key + except AttributeError: + self._key = key = self.project_name.lower() + return key + + @property + def parsed_version(self): + if not hasattr(self, "_parsed_version"): + self._parsed_version = parse_version(self.version) + + return self._parsed_version + + def _warn_legacy_version(self): + LV = packaging.version.LegacyVersion + is_legacy = isinstance(self._parsed_version, LV) + if not is_legacy: + return + + # While an empty version is technically a legacy version and + # is not a valid PEP 440 version, it's also unlikely to + # actually come from someone and instead it is more likely that + # it comes from setuptools attempting to parse a filename and + # including it in the list. So for that we'll gate this warning + # on if the version is anything at all or not. + if not self.version: + return + + tmpl = textwrap.dedent(""" + '{project_name} ({version})' is being parsed as a legacy, + non PEP 440, + version. You may find odd behavior and sort order. + In particular it will be sorted as less than 0.0. It + is recommended to migrate to PEP 440 compatible + versions. + """).strip().replace('\n', ' ') + + warnings.warn(tmpl.format(**vars(self)), PEP440Warning) + + @property + def version(self): + try: + return self._version + except AttributeError: + version = _version_from_file(self._get_metadata(self.PKG_INFO)) + if version is None: + tmpl = "Missing 'Version:' header and/or %s file" + raise ValueError(tmpl % self.PKG_INFO, self) + return version + + @property + def _dep_map(self): + """ + A map of extra to its list of (direct) requirements + for this distribution, including the null extra. + """ + try: + return self.__dep_map + except AttributeError: + self.__dep_map = self._filter_extras(self._build_dep_map()) + return self.__dep_map + + @staticmethod + def _filter_extras(dm): + """ + Given a mapping of extras to dependencies, strip off + environment markers and filter out any dependencies + not matching the markers. + """ + for extra in list(filter(None, dm)): + new_extra = extra + reqs = dm.pop(extra) + new_extra, _, marker = extra.partition(':') + fails_marker = marker and ( + invalid_marker(marker) + or not evaluate_marker(marker) + ) + if fails_marker: + reqs = [] + new_extra = safe_extra(new_extra) or None + + dm.setdefault(new_extra, []).extend(reqs) + return dm + + def _build_dep_map(self): + dm = {} + for name in 'requires.txt', 'depends.txt': + for extra, reqs in split_sections(self._get_metadata(name)): + dm.setdefault(extra, []).extend(parse_requirements(reqs)) + return dm + + def requires(self, extras=()): + """List of Requirements needed for this distro if `extras` are used""" + dm = self._dep_map + deps = [] + deps.extend(dm.get(None, ())) + for ext in extras: + try: + deps.extend(dm[safe_extra(ext)]) + except KeyError: + raise UnknownExtra( + "%s has no such extra feature %r" % (self, ext) + ) + return deps + + def _get_metadata(self, name): + if self.has_metadata(name): + for line in self.get_metadata_lines(name): + yield line + + def activate(self, path=None, replace=False): + """Ensure distribution is importable on `path` (default=sys.path)""" + if path is None: + path = sys.path + self.insert_on(path, replace=replace) + if path is sys.path: + fixup_namespace_packages(self.location) + for pkg in self._get_metadata('namespace_packages.txt'): + if pkg in sys.modules: + declare_namespace(pkg) + + def egg_name(self): + """Return what this distribution's standard .egg filename should be""" + filename = "%s-%s-py%s" % ( + to_filename(self.project_name), to_filename(self.version), + self.py_version or PY_MAJOR + ) + + if self.platform: + filename += '-' + self.platform + return filename + + def __repr__(self): + if self.location: + return "%s (%s)" % (self, self.location) + else: + return str(self) + + def __str__(self): + try: + version = getattr(self, 'version', None) + except ValueError: + version = None + version = version or "[unknown version]" + return "%s %s" % (self.project_name, version) + + def __getattr__(self, attr): + """Delegate all unrecognized public attributes to .metadata provider""" + if attr.startswith('_'): + raise AttributeError(attr) + return getattr(self._provider, attr) + + def __dir__(self): + return list( + set(super(Distribution, self).__dir__()) + | set( + attr for attr in self._provider.__dir__() + if not attr.startswith('_') + ) + ) + + if not hasattr(object, '__dir__'): + # python 2.7 not supported + del __dir__ + + @classmethod + def from_filename(cls, filename, metadata=None, **kw): + return cls.from_location( + _normalize_cached(filename), os.path.basename(filename), metadata, + **kw + ) + + def as_requirement(self): + """Return a ``Requirement`` that matches this distribution exactly""" + if isinstance(self.parsed_version, packaging.version.Version): + spec = "%s==%s" % (self.project_name, self.parsed_version) + else: + spec = "%s===%s" % (self.project_name, self.parsed_version) + + return Requirement.parse(spec) + + def load_entry_point(self, group, name): + """Return the `name` entry point of `group` or raise ImportError""" + ep = self.get_entry_info(group, name) + if ep is None: + raise ImportError("Entry point %r not found" % ((group, name),)) + return ep.load() + + def get_entry_map(self, group=None): + """Return the entry point map for `group`, or the full entry map""" + try: + ep_map = self._ep_map + except AttributeError: + ep_map = self._ep_map = EntryPoint.parse_map( + self._get_metadata('entry_points.txt'), self + ) + if group is not None: + return ep_map.get(group, {}) + return ep_map + + def get_entry_info(self, group, name): + """Return the EntryPoint object for `group`+`name`, or ``None``""" + return self.get_entry_map(group).get(name) + + def insert_on(self, path, loc=None, replace=False): + """Ensure self.location is on path + + If replace=False (default): + - If location is already in path anywhere, do nothing. + - Else: + - If it's an egg and its parent directory is on path, + insert just ahead of the parent. + - Else: add to the end of path. + If replace=True: + - If location is already on path anywhere (not eggs) + or higher priority than its parent (eggs) + do nothing. + - Else: + - If it's an egg and its parent directory is on path, + insert just ahead of the parent, + removing any lower-priority entries. + - Else: add it to the front of path. + """ + + loc = loc or self.location + if not loc: + return + + nloc = _normalize_cached(loc) + bdir = os.path.dirname(nloc) + npath = [(p and _normalize_cached(p) or p) for p in path] + + for p, item in enumerate(npath): + if item == nloc: + if replace: + break + else: + # don't modify path (even removing duplicates) if + # found and not replace + return + elif item == bdir and self.precedence == EGG_DIST: + # if it's an .egg, give it precedence over its directory + # UNLESS it's already been added to sys.path and replace=False + if (not replace) and nloc in npath[p:]: + return + if path is sys.path: + self.check_version_conflict() + path.insert(p, loc) + npath.insert(p, nloc) + break + else: + if path is sys.path: + self.check_version_conflict() + if replace: + path.insert(0, loc) + else: + path.append(loc) + return + + # p is the spot where we found or inserted loc; now remove duplicates + while True: + try: + np = npath.index(nloc, p + 1) + except ValueError: + break + else: + del npath[np], path[np] + # ha! + p = np + + return + + def check_version_conflict(self): + if self.key == 'setuptools': + # ignore the inevitable setuptools self-conflicts :( + return + + nsp = dict.fromkeys(self._get_metadata('namespace_packages.txt')) + loc = normalize_path(self.location) + for modname in self._get_metadata('top_level.txt'): + if (modname not in sys.modules or modname in nsp + or modname in _namespace_packages): + continue + if modname in ('pkg_resources', 'setuptools', 'site'): + continue + fn = getattr(sys.modules[modname], '__file__', None) + if fn and (normalize_path(fn).startswith(loc) or + fn.startswith(self.location)): + continue + issue_warning( + "Module %s was already imported from %s, but %s is being added" + " to sys.path" % (modname, fn, self.location), + ) + + def has_version(self): + try: + self.version + except ValueError: + issue_warning("Unbuilt egg for " + repr(self)) + return False + return True + + def clone(self, **kw): + """Copy this distribution, substituting in any changed keyword args""" + names = 'project_name version py_version platform location precedence' + for attr in names.split(): + kw.setdefault(attr, getattr(self, attr, None)) + kw.setdefault('metadata', self._provider) + return self.__class__(**kw) + + @property + def extras(self): + return [dep for dep in self._dep_map if dep] + + +class EggInfoDistribution(Distribution): + def _reload_version(self): + """ + Packages installed by distutils (e.g. numpy or scipy), + which uses an old safe_version, and so + their version numbers can get mangled when + converted to filenames (e.g., 1.11.0.dev0+2329eae to + 1.11.0.dev0_2329eae). These distributions will not be + parsed properly + downstream by Distribution and safe_version, so + take an extra step and try to get the version number from + the metadata file itself instead of the filename. + """ + md_version = _version_from_file(self._get_metadata(self.PKG_INFO)) + if md_version: + self._version = md_version + return self + + +class DistInfoDistribution(Distribution): + """ + Wrap an actual or potential sys.path entry + w/metadata, .dist-info style. + """ + PKG_INFO = 'METADATA' + EQEQ = re.compile(r"([\(,])\s*(\d.*?)\s*([,\)])") + + @property + def _parsed_pkg_info(self): + """Parse and cache metadata""" + try: + return self._pkg_info + except AttributeError: + metadata = self.get_metadata(self.PKG_INFO) + self._pkg_info = email.parser.Parser().parsestr(metadata) + return self._pkg_info + + @property + def _dep_map(self): + try: + return self.__dep_map + except AttributeError: + self.__dep_map = self._compute_dependencies() + return self.__dep_map + + def _compute_dependencies(self): + """Recompute this distribution's dependencies.""" + dm = self.__dep_map = {None: []} + + reqs = [] + # Including any condition expressions + for req in self._parsed_pkg_info.get_all('Requires-Dist') or []: + reqs.extend(parse_requirements(req)) + + def reqs_for_extra(extra): + for req in reqs: + if not req.marker or req.marker.evaluate({'extra': extra}): + yield req + + common = frozenset(reqs_for_extra(None)) + dm[None].extend(common) + + for extra in self._parsed_pkg_info.get_all('Provides-Extra') or []: + s_extra = safe_extra(extra.strip()) + dm[s_extra] = list(frozenset(reqs_for_extra(extra)) - common) + + return dm + + +_distributionImpl = { + '.egg': Distribution, + '.egg-info': EggInfoDistribution, + '.dist-info': DistInfoDistribution, +} + + +def issue_warning(*args, **kw): + level = 1 + g = globals() + try: + # find the first stack frame that is *not* code in + # the pkg_resources module, to use for the warning + while sys._getframe(level).f_globals is g: + level += 1 + except ValueError: + pass + 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` + + `strs` must be a string, or a (possibly-nested) iterable thereof. + """ + # create a steppable iterator, so we can handle \-continuations + lines = iter(yield_lines(strs)) + + for line in lines: + # Drop comments -- a hash without a space may be in a URL. + if ' #' in line: + line = line[:line.find(' #')] + # If there is a line continuation, drop it, and append the next line. + if line.endswith('\\'): + line = line[:-2].strip() + try: + line += next(lines) + except StopIteration: + return + yield Requirement(line) + + +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)) + self.unsafe_name = self.name + project_name = safe_name(self.name) + self.project_name, self.key = project_name, project_name.lower() + self.specs = [ + (spec.operator, spec.version) for spec in self.specifier] + self.extras = tuple(map(safe_extra, self.extras)) + self.hashCmp = ( + self.key, + self.specifier, + frozenset(self.extras), + str(self.marker) if self.marker else None, + ) + self.__hash = hash(self.hashCmp) + + def __eq__(self, other): + return ( + isinstance(other, Requirement) and + self.hashCmp == other.hashCmp + ) + + def __ne__(self, other): + return not self == other + + def __contains__(self, item): + if isinstance(item, Distribution): + if item.key != self.key: + return False + + item = item.version + + # Allow prereleases always in order to match the previous behavior of + # this method. In the future this should be smarter and follow PEP 440 + # more accurately. + return self.specifier.contains(item, prereleases=True) + + def __hash__(self): + return self.__hash + + def __repr__(self): + return "Requirement.parse(%r)" % str(self) + + @staticmethod + def parse(s): + req, = parse_requirements(s) + return req + + +def _always_object(classes): + """ + Ensure object appears in the mro even + for old-style classes. + """ + if object not in classes: + return classes + (object,) + return classes + + +def _find_adapter(registry, ob): + """Return an adapter factory for `ob` from `registry`""" + types = _always_object(inspect.getmro(getattr(ob, '__class__', type(ob)))) + for t in types: + if t in registry: + return registry[t] + + +def ensure_directory(path): + """Ensure that the parent directory of `path` exists""" + dirname = os.path.dirname(path) + py31compat.makedirs(dirname, exist_ok=True) + + +def _bypass_ensure_directory(path): + """Sandbox-bypassing version of ensure_directory()""" + if not WRITE_SUPPORT: + raise IOError('"os.mkdir" not supported on this platform.') + dirname, filename = split(path) + if dirname and filename and not isdir(dirname): + _bypass_ensure_directory(dirname) + try: + mkdir(dirname, 0o755) + except FileExistsError: + pass + + +def split_sections(s): + """Split a string or iterable thereof into (section, content) pairs + + Each ``section`` is a stripped version of the section header ("[section]") + and each ``content`` is a list of stripped lines excluding blank lines and + comment-only lines. If there are any such lines before the first section + header, they're returned in a first ``section`` of ``None``. + """ + section = None + content = [] + for line in yield_lines(s): + if line.startswith("["): + if line.endswith("]"): + if section or content: + yield section, content + section = line[1:-1].strip() + content = [] + else: + raise ValueError("Invalid section heading", line) + else: + content.append(line) + + # wrap up last segment + yield section, content + + +def _mkstemp(*args, **kw): + old_open = os.open + try: + # temporarily bypass sandboxing + os.open = os_open + return tempfile.mkstemp(*args, **kw) + finally: + # and then put it back + os.open = old_open + + +# Silence the PEP440Warning by default, so that end users don't get hit by it +# randomly just because they use pkg_resources. We want to append the rule +# because we want earlier uses of filterwarnings to take precedence over this +# one. +warnings.filterwarnings("ignore", category=PEP440Warning, append=True) + + +# from jaraco.functools 1.3 +def _call_aside(f, *args, **kwargs): + f(*args, **kwargs) + return f + + +@_call_aside +def _initialize(g=globals()): + "Set up global resource manager (deliberately not state-saved)" + manager = ResourceManager() + g['_manager'] = manager + g.update( + (name, getattr(manager, name)) + for name in dir(manager) + if not name.startswith('_') + ) + + +@_call_aside +def _initialize_master_working_set(): + """ + Prepare the master working set and make the ``require()`` + API available. + + This function has explicit effects on the global state + of pkg_resources. It is intended to be invoked once at + the initialization of this module. + + Invocation by other packages is unsupported and done + at their own risk. + """ + working_set = WorkingSet._build_master() + _declare_state('object', working_set=working_set) + + require = working_set.require + iter_entry_points = working_set.iter_entry_points + add_activation_listener = working_set.subscribe + run_script = working_set.run_script + # backward compatibility + run_main = run_script + # Activate all distributions already on sys.path with replace=False and + # ensure that all distributions added to the working set in the future + # (e.g. by calling ``require()``) will get activated as well, + # with higher priority (replace=True). + tuple( + dist.activate(replace=False) + for dist in working_set + ) + add_activation_listener( + lambda dist: dist.activate(replace=True), + existing=False, + ) + working_set.entries = [] + # match order + list(map(working_set.add_entry, sys.path)) + globals().update(locals()) + +class PkgResourcesDeprecationWarning(Warning): + """ + Base class for warning about deprecations in ``pkg_resources`` + + This class is not derived from ``DeprecationWarning``, and as such is + visible by default. + """ diff --git a/venv/lib/python3.7/site-packages/pkg_resources/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pkg_resources/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7f5a94cb55e7a39653b3fe8719020ec0310f4ef8 GIT binary patch literal 96877 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ⅅ@ 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�R+d{i+rZ+{gDK1P>iZbnOeV8tLA45 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 X_V+z%_veeN7_Zemj2=&Qc5VOPAo)5m literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pkg_resources/__pycache__/py31compat.cpython-37.pyc b/venv/lib/python3.7/site-packages/pkg_resources/__pycache__/py31compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..980a20b6be6c2893ffc7a01ec9e537c3505a7e52 GIT binary patch literal 646 zcmYk3%We}f6o!xONivC&&=m`Kf?2ea3l~+Y5GqPlBvg=6K|4YUN$ez(nT$urlaNG# z1!BoVz>-(;mQ`MX6~{qE9Lv9beEt0UywRuu#kYr}_a_|SmrL$KQ0F;S^MOQyWGO^{ zTNbfH&Lb|l6scHvk;gz*Wl5I5vZ$oIc{zV2D~iu69tcR7zLb6fna6=a<SQTFs#4}D zm{+5!WPJ!~d%6X#_KY-OR+xBwF(#x#I1~r^f~vVB*)$9I&UWyFF?a{rBM%Cm)bO0a zC(dAdf5))3<8x7nxt9p+e4$l@OtYW)4ctOTDuJ$LS3${gZLGf-CQ8O=Y~^*ohp5q( z6k?`rx!1dS*}o2i_3~jcv%Xr#rWokN3bh{p1gsO#?;^}GUJVNsu7(&+bSf2^a4`$V z?R;>$J)O5cb|-Rco^)5(Sr^+yi(;CE*I^##$8lzgVVWL4ema^Z%h5D6s#xZQ)~N~e zWI8})^b*I4vQ4)=)(avz$v3t>xWgWF+rD$>@SlvcCOe{nO&SaM-Wj;}TwmZlYVgR3 zvo~NDK@Hs$R!GSBjfu)?T`0`ZZ95!c#hcrXt*_`!vCal@Hqo}3DJ9K604%x1&Wrz~ c;g0mr7FsS-_00XPaYR0&!t0_|FS7^y56Bvs+5i9m literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pkg_resources/_vendor/__init__.py b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6950eb5fb9135e7aebf422491cee08e59d7ede73 GIT binary patch literal 209 zcmYL@K?=e!5JgjPAwo~!30%~v7L|gCcmOxL6hdp#Ha2ZSCau~tcoDDU)?2tTU5F3< zo8hni&i6;e@ffG4{=R$t@Z7U?!GRMa2Qu;YPh$G|uTKZsh&Hht+QdMnB;y95D&RcR zH16U{c#SgF;WBE?{ARl<bmTQ0K?@y-8f_wFuvn!<*`zrjw~e++Nd#Ty)NoXdIdcTs b@|r0Fl!{tdN~ik%8m=qF8p${PCUhZRk-0g8 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/appdirs.cpython-37.pyc b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/appdirs.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9c0a891508a37853cb4481e73b63bfc3c19022bf GIT binary patch literal 20697 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/pyparsing.cpython-37.pyc b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/pyparsing.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cadd1e0d4e71b38400fa524ccc7482562f531832 GIT binary patch literal 203052 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/six.cpython-37.pyc b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/six.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5703f04a7364c682892755d53baab41e5f3a43e1 GIT binary patch literal 24410 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 E0%B<X6951J literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pkg_resources/_vendor/appdirs.py b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/appdirs.py new file mode 100644 index 0000000..ae67001 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/appdirs.py @@ -0,0 +1,608 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2005-2010 ActiveState Software Inc. +# Copyright (c) 2013 Eddy Petrișor + +"""Utilities for determining application-specific dirs. + +See <http://github.com/ActiveState/appdirs> for details and usage. +""" +# Dev Notes: +# - MSDN on where to store app data files: +# http://support.microsoft.com/default.aspx?scid=kb;en-us;310294#XSLTH3194121123120121120120 +# - 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__)) + + +import sys +import os + +PY3 = sys.version_info[0] == 3 + +if PY3: + unicode = str + +if sys.platform.startswith('java'): + import platform + os_name = platform.java_ver()[3][0] + if os_name.startswith('Windows'): # "Windows XP", "Windows 7", etc. + system = 'win32' + elif os_name.startswith('Mac'): # "Mac OS X", etc. + system = 'darwin' + else: # "Linux", "SunOS", "FreeBSD", etc. + # Setting this to "linux2" is not ideal, but only Windows or Mac + # are actually checked for and the rest of the module expects + # *sys.platform* style strings. + system = 'linux2' +else: + system = sys.platform + + + +def user_data_dir(appname=None, appauthor=None, version=None, roaming=False): + 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. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "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: + Mac OS X: ~/Library/Application Support/<AppName> + 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> + Win 7 (not roaming): C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName> + Win 7 (roaming): C:\Users\<username>\AppData\Roaming\<AppAuthor>\<AppName> + + For Unix, we follow the XDG spec and support $XDG_DATA_HOME. + That means, by default "~/.local/share/<AppName>". + """ + if system == "win32": + if appauthor is None: + appauthor = appname + const = roaming and "CSIDL_APPDATA" or "CSIDL_LOCAL_APPDATA" + path = os.path.normpath(_get_win_folder(const)) + if appname: + if appauthor is not False: + path = os.path.join(path, appauthor, appname) + else: + path = os.path.join(path, appname) + elif system == 'darwin': + path = os.path.expanduser('~/Library/Application Support/') + if appname: + path = os.path.join(path, appname) + else: + path = os.getenv('XDG_DATA_HOME', os.path.expanduser("~/.local/share")) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +def site_data_dir(appname=None, appauthor=None, version=None, multipath=False): + r"""Return full path to the user-shared data dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "multipath" is an optional parameter only applicable to *nix + which indicates that the entire list of data dirs should be + returned. By default, the first item from XDG_DATA_DIRS is + returned, or '/usr/local/share/<AppName>', + if XDG_DATA_DIRS is not set + + Typical site data directories are: + Mac OS X: /Library/Application Support/<AppName> + Unix: /usr/local/share/<AppName> or /usr/share/<AppName> + Win XP: C:\Documents and Settings\All Users\Application Data\<AppAuthor>\<AppName> + Vista: (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.) + Win 7: C:\ProgramData\<AppAuthor>\<AppName> # Hidden, but writeable on Win 7. + + For Unix, this is using the $XDG_DATA_DIRS[0] default. + + WARNING: Do not use this on Windows. See the Vista-Fail note above for why. + """ + if system == "win32": + if appauthor is None: + appauthor = appname + path = os.path.normpath(_get_win_folder("CSIDL_COMMON_APPDATA")) + if appname: + if appauthor is not False: + path = os.path.join(path, appauthor, appname) + else: + path = os.path.join(path, appname) + elif system == 'darwin': + path = os.path.expanduser('/Library/Application Support') + if appname: + path = os.path.join(path, appname) + else: + # XDG default for $XDG_DATA_DIRS + # only first, if multipath is False + path = os.getenv('XDG_DATA_DIRS', + os.pathsep.join(['/usr/local/share', '/usr/share'])) + pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)] + if appname: + if version: + appname = os.path.join(appname, version) + pathlist = [os.sep.join([x, appname]) for x in pathlist] + + if multipath: + path = os.pathsep.join(pathlist) + else: + path = pathlist[0] + return path + + if appname and version: + path = os.path.join(path, version) + return path + + +def user_config_dir(appname=None, appauthor=None, version=None, roaming=False): + r"""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. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "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 config directories are: + Mac OS X: same as user_data_dir + Unix: ~/.config/<AppName> # or in $XDG_CONFIG_HOME, if defined + 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 system in ["win32", "darwin"]: + path = user_data_dir(appname, appauthor, None, roaming) + else: + path = os.getenv('XDG_CONFIG_HOME', os.path.expanduser("~/.config")) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +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. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "multipath" is an optional parameter only applicable to *nix + which indicates that the entire list of config dirs should be + returned. By default, the first item from XDG_CONFIG_DIRS is + returned, or '/etc/xdg/<AppName>', if XDG_CONFIG_DIRS is not set + + Typical site config directories are: + Mac OS X: same as site_data_dir + Unix: /etc/xdg/<AppName> or $XDG_CONFIG_DIRS[i]/<AppName> for each value in + $XDG_CONFIG_DIRS + Win *: same as site_data_dir + Vista: (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.) + + For Unix, this is using the $XDG_CONFIG_DIRS[0] default, if multipath=False + + WARNING: Do not use this on Windows. See the Vista-Fail note above for why. + """ + if system in ["win32", "darwin"]: + path = site_data_dir(appname, appauthor) + if appname and version: + path = os.path.join(path, version) + else: + # XDG default for $XDG_CONFIG_DIRS + # 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)] + if appname: + if version: + appname = os.path.join(appname, version) + pathlist = [os.sep.join([x, appname]) for x in pathlist] + + if multipath: + path = os.pathsep.join(pathlist) + else: + path = pathlist[0] + return path + + +def user_cache_dir(appname=None, appauthor=None, version=None, opinion=True): + r"""Return full path to the user-specific cache dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "opinion" (boolean) can be False to disable the appending of + "Cache" to the base app data dir for Windows. See + discussion below. + + Typical user cache directories are: + Mac OS X: ~/Library/Caches/<AppName> + Unix: ~/.cache/<AppName> (XDG default) + Win XP: C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>\Cache + Vista: C:\Users\<username>\AppData\Local\<AppAuthor>\<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` above). 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. + This can be disabled with the `opinion=False` option. + """ + if system == "win32": + if appauthor is None: + appauthor = appname + path = os.path.normpath(_get_win_folder("CSIDL_LOCAL_APPDATA")) + if appname: + if appauthor is not False: + path = os.path.join(path, appauthor, appname) + else: + path = os.path.join(path, appname) + if opinion: + path = os.path.join(path, "Cache") + elif system == 'darwin': + path = os.path.expanduser('~/Library/Caches') + if appname: + path = os.path.join(path, appname) + else: + path = os.getenv('XDG_CACHE_HOME', os.path.expanduser('~/.cache')) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +def user_state_dir(appname=None, appauthor=None, version=None, roaming=False): + r"""Return full path to the user-specific state dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "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 state directories are: + Mac OS X: same as user_data_dir + Unix: ~/.local/state/<AppName> # or in $XDG_STATE_HOME, if defined + Win *: same as user_data_dir + + For Unix, we follow this Debian proposal <https://wiki.debian.org/XDGBaseDirectorySpecification#state> + to extend the XDG spec and support $XDG_STATE_HOME. + + That means, by default "~/.local/state/<AppName>". + """ + if system in ["win32", "darwin"]: + path = user_data_dir(appname, appauthor, None, roaming) + else: + path = os.getenv('XDG_STATE_HOME', os.path.expanduser("~/.local/state")) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +def user_log_dir(appname=None, appauthor=None, version=None, opinion=True): + r"""Return full path to the user-specific log dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "opinion" (boolean) can be False to disable the appending of + "Logs" to the base app data dir for Windows, and "log" to the + base cache dir for Unix. See discussion below. + + Typical user log directories are: + Mac OS X: ~/Library/Logs/<AppName> + Unix: ~/.cache/<AppName>/log # or under $XDG_CACHE_HOME if defined + Win XP: C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>\Logs + Vista: C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName>\Logs + + On Windows the only suggestion in the MSDN docs is that local settings + go in the `CSIDL_LOCAL_APPDATA` directory. (Note: I'm interested in + examples of what some windows apps use for a logs dir.) + + OPINION: This function appends "Logs" to the `CSIDL_LOCAL_APPDATA` + value for Windows and appends "log" to the user cache dir for Unix. + This can be disabled with the `opinion=False` option. + """ + if system == "darwin": + path = os.path.join( + os.path.expanduser('~/Library/Logs'), + appname) + elif system == "win32": + path = user_data_dir(appname, appauthor, version) + version = False + if opinion: + path = os.path.join(path, "Logs") + else: + path = user_cache_dir(appname, appauthor, version) + version = False + if opinion: + path = os.path.join(path, "log") + if appname and version: + path = os.path.join(path, version) + return path + + +class AppDirs(object): + """Convenience wrapper for getting application dirs.""" + def __init__(self, appname=None, appauthor=None, version=None, + roaming=False, multipath=False): + self.appname = appname + self.appauthor = appauthor + self.version = version + self.roaming = roaming + self.multipath = multipath + + @property + def user_data_dir(self): + return user_data_dir(self.appname, self.appauthor, + version=self.version, roaming=self.roaming) + + @property + def site_data_dir(self): + return site_data_dir(self.appname, self.appauthor, + version=self.version, multipath=self.multipath) + + @property + def user_config_dir(self): + return user_config_dir(self.appname, self.appauthor, + version=self.version, roaming=self.roaming) + + @property + def site_config_dir(self): + return site_config_dir(self.appname, self.appauthor, + version=self.version, multipath=self.multipath) + + @property + def user_cache_dir(self): + return user_cache_dir(self.appname, self.appauthor, + version=self.version) + + @property + def user_state_dir(self): + return user_state_dir(self.appname, self.appauthor, + version=self.version) + + @property + def user_log_dir(self): + return user_log_dir(self.appname, self.appauthor, + version=self.version) + + +#---- internal support stuff + +def _get_win_folder_from_registry(csidl_name): + """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. + """ + if PY3: + import winreg as _winreg + else: + 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" + ) + dir, type = _winreg.QueryValueEx(key, shell_folder_name) + return dir + + +def _get_win_folder_with_pywin32(csidl_name): + from win32com.shell import shellcon, shell + dir = shell.SHGetFolderPath(0, getattr(shellcon, csidl_name), 0, 0) + # Try to make this a unicode path because SHGetFolderPath does + # not return unicode strings when there is unicode data in the + # path. + try: + dir = unicode(dir) + + # 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 dir: + if ord(c) > 255: + has_high_char = True + break + if has_high_char: + try: + import win32api + dir = win32api.GetShortPathName(dir) + except ImportError: + pass + except UnicodeError: + pass + return dir + + +def _get_win_folder_with_ctypes(csidl_name): + import ctypes + + 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 + +def _get_win_folder_with_jna(csidl_name): + import array + from com.sun import jna + from com.sun.jna.platform import win32 + + buf_size = win32.WinDef.MAX_PATH * 2 + buf = array.zeros('c', buf_size) + shell = win32.Shell32.INSTANCE + shell.SHGetFolderPath(None, getattr(win32.ShlObj, csidl_name), None, win32.ShlObj.SHGFP_TYPE_CURRENT, buf) + dir = jna.Native.toString(buf.tostring()).rstrip("\0") + + # 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 dir: + if ord(c) > 255: + has_high_char = True + break + if has_high_char: + buf = array.zeros('c', buf_size) + kernel = win32.Kernel32.INSTANCE + if kernel.GetShortPathName(dir, buf, buf_size): + dir = jna.Native.toString(buf.tostring()).rstrip("\0") + + return dir + +if system == "win32": + try: + import win32com.shell + _get_win_folder = _get_win_folder_with_pywin32 + except ImportError: + try: + from ctypes import windll + _get_win_folder = _get_win_folder_with_ctypes + except ImportError: + try: + import com.sun.jna + _get_win_folder = _get_win_folder_with_jna + except ImportError: + _get_win_folder = _get_win_folder_from_registry + + +#---- self test code + +if __name__ == "__main__": + appname = "MyApp" + appauthor = "MyCompany" + + props = ("user_data_dir", + "user_config_dir", + "user_cache_dir", + "user_state_dir", + "user_log_dir", + "site_data_dir", + "site_config_dir") + + print("-- app dirs %s --" % __version__) + + print("-- app dirs (with optional 'version')") + dirs = AppDirs(appname, appauthor, version="1.0") + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) + + print("\n-- app dirs (without optional 'version')") + dirs = AppDirs(appname, appauthor) + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) + + print("\n-- app dirs (without optional 'appauthor')") + dirs = AppDirs(appname) + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) + + print("\n-- app dirs (with disabled 'appauthor')") + dirs = AppDirs(appname, appauthor=False) + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) diff --git a/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__about__.py b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__about__.py new file mode 100644 index 0000000..95d330e --- /dev/null +++ b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__about__.py @@ -0,0 +1,21 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +__all__ = [ + "__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" + +__author__ = "Donald Stufft and individual contributors" +__email__ = "donald@stufft.io" + +__license__ = "BSD or Apache License, Version 2.0" +__copyright__ = "Copyright 2014-2016 %s" % __author__ diff --git a/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__init__.py b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__init__.py new file mode 100644 index 0000000..5ee6220 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__init__.py @@ -0,0 +1,14 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +from .__about__ import ( + __author__, __copyright__, __email__, __license__, __summary__, __title__, + __uri__, __version__ +) + +__all__ = [ + "__title__", "__summary__", "__uri__", "__version__", "__author__", + "__email__", "__license__", "__copyright__", +] diff --git a/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8a69c055db48afc1661ef11e2b6431bf941651fe GIT binary patch literal 745 zcmYL{OK;RL5P*}-w)^U~1*%@Sm`WU0qU+rj3PlK&wnv026>*4=tR&+kZj;#ZV_|dW z#vkF|aNa8?{sJe)T~!^+pJuG_cpg3<kB0%u&!_3v-<=@%<BfaiqjHAZTp=KUunOuh z4(m?bsiQaw1L!~mUD$w4=s_O_ML+JsFy4Ssya`)z55{pHw&MZp#6#GPNAQRb_Jeo} z9$yEOCx0<&Fo{+>Nor)}EN7xtQrlG@#6lP$o7J|`qOmM@O=i74V9W|zamH37#*C}$ zL@&|kG3K;bpDwuechML!mN;8VjXK`sbt0;@PbD(m7$0WLSSHm{i=wpNO(ofFQi!H# z4=$wU#92`ZE4U%K)Z}W3;Tp1b;--C8TC2=kN(*62mrgTTQ?*nHeF)Q?pG@DhlS|no z6_9J|^4yZ70U{b-Cb*;`nQW{Usk2g>b{Fnk&&-|cRLJ(={Q8pM>mM*`$;roc@-N7j zb*1EJI&1eY?yDe2v-!(I#0hzBK265H4Y{*UW4Rhf9O%fSi|~C*D(s2g@JE{-Jr6&5 zJ@D|qLytVR5WfPw>vfNRKPXOTkyuU_iKe-%0P~@BNwc|Pr|s#@?Avh;tvNYf=%eqp zt!F4jLqAg`)S+mM#kUV%y-v$pmlo7;>y(wUGF06bOmich&bXm$!5fhJp{EqHPNl<n fP1SPMe^*Oz6@Tw5GJA-<Xc!KoZiuUc%QO5Bi5}sQ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..482abd3423d90953fcd8371f29a2b614a82b3888 GIT binary patch literal 583 zcmYjN%Z}7A5X@sH&&eVrZu|gqSiG<Tv=Uk&K7b2*vXELy?8%skW6O`g%$XxUvcHro zr~L&^w08ueC6`=QcXhcwHcb^_{e0eiiIXV$70BNz@bUqVy+dFTi^oXDG?ocXWJ=RG zVhKyfm0Z)c%xETan#+O~vZSS~XeDb}%MION--@kS#&TA$l2xo83fi#E=V;qJpmMZL zmnUs!)#x1uA+<7YDVUgr6>3^8v=Nhoou7J#{2>k##Zm#Z-tCnESQ>y{>7x<D-XSdk zxNOCU*BW3HJ)bN;6YHgH&GFpigd4+q4&aSAH_Y6GtpKLRJtl->HUXLdS%46WDFfsP zpSBml%g#G*P|RS6kx2ur5Q3MsQyy)dhr`H!3Xl4aoBk~ccG?lm-$&+Y=nnAv2f-NT z)^ReohV0bH&?u36(!bJhbGrF@_3e7cPWJ8fY+iqNCwYZ6OyrJep)bW`9co^_dDra^ zz8i?;&TFUCXo)@yV7OJ@^xP7d`NWhVy6q3`Af|x;h)JOTm-@IA@1<gX<hS8(Hl*<^ Id68A|AM!PzX#fBK literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/_compat.cpython-37.pyc b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/_compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dafddb23367be675f425ba9ce2e0f972d5d46728 GIT binary patch literal 1035 zcmah{y>1gh5Z<4&eKC$x5JiGem<Gv3e2@rGq$omwL>D1}kT^wJop0C9#rMbVo`bDW zB~nuG5K!_;+fwBfsF*n?CWwNOW^QKo_M4e+_T}non}B@X93CEWLVjX!BMh7upymS@ zNhD24MnjshkYzmN6mu-~LQi?e4N2}1$tNsqE+Y@3mTKwO${*2iC2y)Weq}>8&q;Vk zvUjB4x&my{=WZ<;nj)>N5=mAT+B#n*)5Ii2?z*K;aw|qv9$SbHuCTEy=$6D3Z-Zda z1Z{zuM_}HN3vxk6Oj60teaSBA8UMm8`9@Ef<kCyXcMr-p=0Up$@=B}7s$SF^Mn?7G zG%}`llGr22WXeW$Vo?7X1Nc&~EQ+}gMv;(860+NcLoPX#@#YT^P5i;yON%&4&HiAS zioF_&5d5Ov1vMQom-Ligl2d+$Q1svj;5i<r#(8;^Dc80~i4oYiaa8u1Yb<;Zp*1q{ z>ns2Yr!ZkKjdU<7QmM2FvZEk=Qi|RA?(yT3ospcIXFF59{n^g5#~|Z8cpsEWxs~L` zMrpeB^!e~;QVqv}QMM{=QKTj)Cu5<NDJmT+6NstGWub#IiYL)H$;W|+i>!?7pq#mu z5V<-L;sMTuD<pK@|1T|r>stpfv=2T^EQD(dkrlE^(eDWHsfyCYiCzQTdgwmWNS<E3 zN$4(kZe>aMCWLh#KGn#zTeAwEUZiKDUidYP^X#ltHE^FV;A&vJ^KYfPNcZot*0EB( z-qr@!8xZw7IKrs1m4*>CvZ3)YY5dD^Gc&F;g&o0j7fC)U9Dn<98_f<JTJ1VufL?)} l8P~2CUT13bx~p5J?#bU<Ft(2+45rqZ&%3nidDLf3{u@EG3OE1& literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-37.pyc b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1090f8b11554baeb8c1a5c84f0bd6850c8ea2294 GIT binary patch literal 2887 zcmcIm&5qkP5GEyCmc8CxZ?b8U1})H2AfOwi3DPD=5o~|Zq8DGfC!+u%i?pp>SyD*K zNsQbapgrV8`bxU?)K}=KGxRF87gFW^ga$d3hU7OhocZLh_xF1Q+S@zhpMGf*@*6&s ztp$@)=;~V-IN>xVb2_4PYh=yskxj|>gj?KxL%1zkD|^%y?G+id;cbhz;ceTzb%X<N z9q#-{yw2}%67lTfFc_;e&b46CJWHi6TpleV6{SgWkjW^~Y?3FThUXA>l+A+4DRgxP zgCHZy$;jfATW`q7<~DDE1Z?hrZ1WCxK{~w4dmuY}kM}{ke4ihH?D9iC0NLY5{2ItT zejO}4F5DlINt8tTRY(B@8%pfoKvx(PPGO}rln^lTEAeR2QX-y62OiDv$Im`Eu?V#A z7lHIAY0QOG{(R<#pJnXH^2z!A7Y`?VsXl+WkPlw!<@`RhY2u&xS(KebiPAwFpFH|v zJiExpQ(p<4XF5$|<!2XDCWT6K84BgIg-CcR{VWJCf@zdYeWtX`L!HB#d)cePWw1Jv zjCIj=3?HG(qte5BrFP3z8x|Q?`!LZ&)7NB0SLiYwdREbz1!`8b@K}$^4y^ghap}S% zg5ny+@PI1NwKg>7z!H>I@%_#m>{$k+Xs3E6<W($(u~;*9xPf%I;U4P#8IIhCqpDB@ zW7q0XK(~c*C4{dbgy(c+l_BgwrsEwap(whrH4c<w?9$OX1H^O2Zqyinx@rRsV2389 z0ey05f*hciM=&&?Cg9qw8dTJ6p;leu+2$qI`8I`Xx>JLKy8j6U?ESb71${yLv7y}Z zMPJ5^7K5Rf20B`ZGRbOcpu<=qri^_8N0lWoDEC0!8RgLHW3eQ`9MFp%WAl{fG0yvp zJ<o%9t&v!~5{pUVbxKTjiMc4R<8X`vW`?|p!#fsQ&#)p5QDLPj+~r!Xz5O%#5LE9P zmgFh)_eiwz1314v<d+<~?4FcSTPIQ_<(LS0Xs_WEy1ae$n*I&dN&Ga*Js7Gl*<8t| z4X8VEU1OP;tM@m+ZdSOs6WujKVS+tqg2I9^(T0U6|DN-9A{>*{j~amA57(JedfWiL z6X9)rwW<iu6ztOmsGV4^8479PSrgQ5)MrSdrVx;LzS@AfRgs$|<4OFS$lEx4h{Jy- zH{_AK(Cf$z^+T_N{5r|;pAr1)!Gx8Vu@e8!6;3)n7oj#T8eXbm(Zc<5&Ckzpk3wQS Kwg(?M(EkKIG6($t literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/markers.cpython-37.pyc b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/markers.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4ade0111209d430be61d74aaa8f6bee24fad91c8 GIT binary patch literal 8895 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 a$xo6Ygkg;Tc{6(;ZDa?sN3z-M#Qy<&D%$)2 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-37.pyc b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..059c52be6ffb1e42d10317db2b07da5cb1431bdd GIT binary patch literal 3900 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eb57004b8c358fcac8edabf2a3a29d1d23e880d6 GIT binary patch literal 19813 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/utils.cpython-37.pyc b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/utils.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..efb6fb2d0101c53448da0721a07f19a6a33942aa GIT binary patch literal 514 zcmY*Wy>1jS5VpO0m(xM`QRsMr6S_Dg0u(7ii1cZo+JG$Y+P5+1Klx{qtZ0xZd5F6r zMPA7*6|aygb|fVDr1?B!&*+;Of85=jgN$D<+b=f|fZrwfiz+)GviZYI3@|8xf(=xt zL8@vhSniOlo0`{~39GiSnX;Nqeu8F)p-*5j{gdm!qDoI`>y3<o6QQheA<dW=gcnAq zC)Noa$SUeC<oIlyo-fJ%*H>L`<^kobvz=!1&oTwDfed~JTeLx2kY&)>9b9IWJ<?Ha zwCJc5BPWjc{3=yGwrL{GC3g#$YE2ct1+L6|_XB6`fd-BT>hQ`)#+}FN0(Y-1IUbL{ z9b6u**y!IL4eszNjOrkx*Z4EG!Y+mOfl9f2^RB&E$F|3whiHQ_(qp^sv%ELab=+ez zaLtUvmUe5}3*F-wg!KFNIz9id<I>#YGA7CdkSqRTmgXd{Cq%~yaplF8e{p3e2|1p2 kI-{(R+)c}Msd*UhA9_?$XD7<ADEa$R=u7SkG^^&-J(7Ei3jhEB literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/version.cpython-37.pyc b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/version.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8f21d9bea3ece11a04c8d4b37734c9394ba4514f GIT binary patch literal 10580 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/_compat.py b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/_compat.py new file mode 100644 index 0000000..210bb80 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/_compat.py @@ -0,0 +1,30 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import sys + + +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 + +# flake8: noqa + +if PY3: + string_types = str, +else: + string_types = basestring, + + +def with_metaclass(meta, *bases): + """ + 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): + def __new__(cls, name, this_bases, d): + return meta(name, bases, d) + return type.__new__(metaclass, 'temporary_class', (), {}) diff --git a/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/_structures.py b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/_structures.py new file mode 100644 index 0000000..ccc2786 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/_structures.py @@ -0,0 +1,68 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + + +class Infinity(object): + + def __repr__(self): + return "Infinity" + + def __hash__(self): + return hash(repr(self)) + + def __lt__(self, other): + return False + + def __le__(self, other): + return False + + def __eq__(self, other): + return isinstance(other, self.__class__) + + def __ne__(self, other): + return not isinstance(other, self.__class__) + + def __gt__(self, other): + return True + + def __ge__(self, other): + return True + + def __neg__(self): + return NegativeInfinity + +Infinity = Infinity() + + +class NegativeInfinity(object): + + def __repr__(self): + return "-Infinity" + + def __hash__(self): + return hash(repr(self)) + + def __lt__(self, other): + return True + + def __le__(self, other): + return True + + def __eq__(self, other): + return isinstance(other, self.__class__) + + def __ne__(self, other): + return not isinstance(other, self.__class__) + + def __gt__(self, other): + return False + + def __ge__(self, other): + return False + + def __neg__(self): + return Infinity + +NegativeInfinity = NegativeInfinity() diff --git a/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/markers.py b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/markers.py new file mode 100644 index 0000000..892e578 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/markers.py @@ -0,0 +1,301 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import operator +import os +import platform +import sys + +from pkg_resources.extern.pyparsing import ParseException, ParseResults, stringStart, stringEnd +from pkg_resources.extern.pyparsing import ZeroOrMore, Group, Forward, QuotedString +from pkg_resources.extern.pyparsing import Literal as L # noqa + +from ._compat import string_types +from .specifiers import Specifier, InvalidSpecifier + + +__all__ = [ + "InvalidMarker", "UndefinedComparison", "UndefinedEnvironmentName", + "Marker", "default_environment", +] + + +class InvalidMarker(ValueError): + """ + An invalid marker was found, users should refer to PEP 508. + """ + + +class UndefinedComparison(ValueError): + """ + An invalid operation was attempted on a value that doesn't support it. + """ + + +class UndefinedEnvironmentName(ValueError): + """ + A name was attempted to be used that does not exist inside of the + environment. + """ + + +class Node(object): + + def __init__(self, value): + self.value = value + + def __str__(self): + return str(self.value) + + def __repr__(self): + return "<{0}({1!r})>".format(self.__class__.__name__, str(self)) + + def serialize(self): + raise NotImplementedError + + +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") +) +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' +} +VARIABLE.setParseAction(lambda s, l, t: Variable(ALIASES.get(t[0], t[0]))) + +VERSION_CMP = ( + L("===") | + L("==") | + L(">=") | + L("<=") | + L("!=") | + L("~=") | + L(">") | + L("<") +) + +MARKER_OP = VERSION_CMP | L("not in") | L("in") +MARKER_OP.setParseAction(lambda s, l, t: Op(t[0])) + +MARKER_VALUE = QuotedString("'") | QuotedString('"') +MARKER_VALUE.setParseAction(lambda s, l, t: Value(t[0])) + +BOOLOP = L("and") | L("or") + +MARKER_VAR = VARIABLE | MARKER_VALUE + +MARKER_ITEM = Group(MARKER_VAR + MARKER_OP + MARKER_VAR) +MARKER_ITEM.setParseAction(lambda s, l, t: tuple(t[0])) + +LPAREN = L("(").suppress() +RPAREN = L(")").suppress() + +MARKER_EXPR = Forward() +MARKER_ATOM = MARKER_ITEM | Group(LPAREN + MARKER_EXPR + RPAREN) +MARKER_EXPR << MARKER_ATOM + ZeroOrMore(BOOLOP + MARKER_EXPR) + +MARKER = stringStart + MARKER_EXPR + stringEnd + + +def _coerce_parse_result(results): + if isinstance(results, ParseResults): + return [_coerce_parse_result(i) for i in results] + else: + return results + + +def _format_marker(marker, first=True): + assert isinstance(marker, (list, tuple, string_types)) + + # Sometimes we have a structure like [[...]] which is a single item list + # 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))): + return _format_marker(marker[0]) + + if isinstance(marker, list): + inner = (_format_marker(m, first=False) for m in marker) + if first: + return " ".join(inner) + else: + return "(" + " ".join(inner) + ")" + elif isinstance(marker, tuple): + return " ".join([m.serialize() for m in marker]) + else: + return marker + + +_operators = { + "in": lambda lhs, rhs: lhs in rhs, + "not in": lambda lhs, rhs: lhs not in rhs, + "<": operator.lt, + "<=": operator.le, + "==": operator.eq, + "!=": operator.ne, + ">=": operator.ge, + ">": operator.gt, +} + + +def _eval_op(lhs, op, rhs): + try: + spec = Specifier("".join([op.serialize(), rhs])) + except InvalidSpecifier: + pass + else: + return spec.contains(lhs) + + oper = _operators.get(op.serialize()) + if oper is None: + raise UndefinedComparison( + "Undefined {0!r} on {1!r} and {2!r}.".format(op, lhs, rhs) + ) + + return oper(lhs, rhs) + + +_undefined = object() + + +def _get_env(environment, name): + value = environment.get(name, _undefined) + + if value is _undefined: + raise UndefinedEnvironmentName( + "{0!r} does not exist in evaluation environment.".format(name) + ) + + return value + + +def _evaluate_markers(markers, environment): + groups = [[]] + + for marker in markers: + assert isinstance(marker, (list, tuple, string_types)) + + if isinstance(marker, list): + groups[-1].append(_evaluate_markers(marker, environment)) + elif isinstance(marker, tuple): + lhs, op, rhs = marker + + if isinstance(lhs, Variable): + lhs_value = _get_env(environment, lhs.value) + rhs_value = rhs.value + else: + lhs_value = lhs.value + rhs_value = _get_env(environment, rhs.value) + + groups[-1].append(_eval_op(lhs_value, op, rhs_value)) + else: + assert marker in ["and", "or"] + if marker == "or": + groups.append([]) + + return any(all(item) for item in groups) + + +def format_full_version(info): + version = '{0.major}.{0.minor}.{0.micro}'.format(info) + kind = info.releaselevel + if kind != 'final': + version += kind[0] + str(info.serial) + return version + + +def default_environment(): + if hasattr(sys, 'implementation'): + iver = format_full_version(sys.implementation.version) + implementation_name = sys.implementation.name + else: + iver = '0' + implementation_name = '' + + return { + "implementation_name": implementation_name, + "implementation_version": iver, + "os_name": os.name, + "platform_machine": platform.machine(), + "platform_release": platform.release(), + "platform_system": platform.system(), + "platform_version": platform.version(), + "python_full_version": platform.python_version(), + "platform_python_implementation": platform.python_implementation(), + "python_version": platform.python_version()[:3], + "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]) + raise InvalidMarker(err_str) + + def __str__(self): + return _format_marker(self._markers) + + def __repr__(self): + return "<Marker({0!r})>".format(str(self)) + + def evaluate(self, environment=None): + """Evaluate a marker. + + Return the boolean from evaluating the given marker against the + environment. environment is an optional argument to override all or + part of the determined environment. + + The environment is determined from the current Python process. + """ + current_environment = default_environment() + if environment is not None: + current_environment.update(environment) + + return _evaluate_markers(self._markers, current_environment) diff --git a/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/requirements.py b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/requirements.py new file mode 100644 index 0000000..0c8c4a3 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/requirements.py @@ -0,0 +1,127 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import string +import re + +from pkg_resources.extern.pyparsing import stringStart, stringEnd, originalTextFor, ParseException +from pkg_resources.extern.pyparsing import ZeroOrMore, Word, Optional, Regex, Combine +from pkg_resources.extern.pyparsing import Literal as L # noqa +from pkg_resources.extern.six.moves.urllib import parse as urlparse + +from .markers import MARKER_EXPR, Marker +from .specifiers import LegacySpecifier, Specifier, SpecifierSet + + +class InvalidRequirement(ValueError): + """ + An invalid requirement was found, users should refer to PEP 508. + """ + + +ALPHANUM = Word(string.ascii_letters + string.digits) + +LBRACKET = L("[").suppress() +RBRACKET = L("]").suppress() +LPAREN = L("(").suppress() +RPAREN = L(")").suppress() +COMMA = L(",").suppress() +SEMICOLON = L(";").suppress() +AT = L("@").suppress() + +PUNCTUATION = Word("-_.") +IDENTIFIER_END = ALPHANUM | (ZeroOrMore(PUNCTUATION) + ALPHANUM) +IDENTIFIER = Combine(ALPHANUM + ZeroOrMore(IDENTIFIER_END)) + +NAME = IDENTIFIER("name") +EXTRA = IDENTIFIER + +URI = Regex(r'[^ ]+')("url") +URL = (AT + URI) + +EXTRAS_LIST = EXTRA + ZeroOrMore(COMMA + EXTRA) +EXTRAS = (LBRACKET + Optional(EXTRAS_LIST) + RBRACKET)("extras") + +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_SPEC = Optional(((LPAREN + VERSION_MANY + RPAREN) | VERSION_MANY)) +_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]) +) +MARKER_SEPERATOR = SEMICOLON +MARKER = MARKER_SEPERATOR + 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) + +REQUIREMENT = stringStart + NAMED_REQUIREMENT + stringEnd + + +class Requirement(object): + """Parse a requirement. + + Parse a given requirement string into its parts, such as name, specifier, + URL, and extras. Raises InvalidRequirement on a badly-formed requirement + string. + """ + + # TODO: Can we test whether something is contained within a requirement? + # If so how do we do that? Do we need to test against the _name_ of + # the thing as well as the version? What about the markers? + # TODO: Can we normalize the name and extra name? + + def __init__(self, requirement_string): + try: + 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])) + + 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") + self.url = req.url + else: + self.url = None + self.extras = set(req.extras.asList() if req.extras else []) + self.specifier = SpecifierSet(req.specifier) + self.marker = req.marker if req.marker else None + + def __str__(self): + parts = [self.name] + + if self.extras: + parts.append("[{0}]".format(",".join(sorted(self.extras)))) + + if self.specifier: + parts.append(str(self.specifier)) + + if self.url: + parts.append("@ {0}".format(self.url)) + + if self.marker: + parts.append("; {0}".format(self.marker)) + + return "".join(parts) + + def __repr__(self): + return "<Requirement({0!r})>".format(str(self)) diff --git a/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/specifiers.py b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/specifiers.py new file mode 100644 index 0000000..7f5a76c --- /dev/null +++ b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/specifiers.py @@ -0,0 +1,774 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import abc +import functools +import itertools +import re + +from ._compat import string_types, with_metaclass +from .version import Version, LegacyVersion, parse + + +class InvalidSpecifier(ValueError): + """ + An invalid specifier was found, users should refer to PEP 440. + """ + + +class BaseSpecifier(with_metaclass(abc.ABCMeta, object)): + + @abc.abstractmethod + def __str__(self): + """ + Returns the str representation of this Specifier like object. This + should be representative of the Specifier itself. + """ + + @abc.abstractmethod + def __hash__(self): + """ + Returns a hash value for this Specifier like object. + """ + + @abc.abstractmethod + def __eq__(self, other): + """ + Returns a boolean representing whether or not the two Specifier like + objects are equal. + """ + + @abc.abstractmethod + def __ne__(self, other): + """ + Returns a boolean representing whether or not the two Specifier like + objects are not equal. + """ + + @abc.abstractproperty + def prereleases(self): + """ + Returns whether or not pre-releases as a whole are allowed by this + specifier. + """ + + @prereleases.setter + def prereleases(self, value): + """ + Sets whether or not pre-releases as a whole are allowed by this + specifier. + """ + + @abc.abstractmethod + def contains(self, item, prereleases=None): + """ + Determines if the given item is contained within this specifier. + """ + + @abc.abstractmethod + def filter(self, iterable, prereleases=None): + """ + Takes an iterable of items and filters them so that only items which + are contained within this specifier are allowed in it. + """ + + +class _IndividualSpecifier(BaseSpecifier): + + _operators = {} + + def __init__(self, spec="", prereleases=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(), + ) + + # Store whether or not this Specifier should accept prereleases + self._prereleases = prereleases + + def __repr__(self): + pre = ( + ", prereleases={0!r}".format(self.prereleases) + if self._prereleases is not None + else "" + ) + + return "<{0}({1!r}{2})>".format( + self.__class__.__name__, + str(self), + pre, + ) + + def __str__(self): + return "{0}{1}".format(*self._spec) + + def __hash__(self): + return hash(self._spec) + + def __eq__(self, other): + if isinstance(other, string_types): + try: + other = self.__class__(other) + except InvalidSpecifier: + return NotImplemented + elif not isinstance(other, self.__class__): + return NotImplemented + + return self._spec == other._spec + + def __ne__(self, other): + if isinstance(other, string_types): + try: + other = self.__class__(other) + except InvalidSpecifier: + return NotImplemented + elif not isinstance(other, self.__class__): + return NotImplemented + + return self._spec != other._spec + + def _get_operator(self, op): + return getattr(self, "_compare_{0}".format(self._operators[op])) + + def _coerce_version(self, version): + if not isinstance(version, (LegacyVersion, Version)): + version = parse(version) + return version + + @property + def operator(self): + return self._spec[0] + + @property + def version(self): + return self._spec[1] + + @property + def prereleases(self): + return self._prereleases + + @prereleases.setter + def prereleases(self, value): + self._prereleases = value + + def __contains__(self, item): + return self.contains(item) + + def contains(self, item, prereleases=None): + # 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) + + # 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: + 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) + + def filter(self, iterable, prereleases=None): + yielded = False + found_prereleases = [] + + kw = {"prereleases": prereleases if prereleases is not None else True} + + # Attempt to iterate over all the values in the iterable and if any of + # them match, yield them. + for version in iterable: + parsed_version = self._coerce_version(version) + + if self.contains(parsed_version, **kw): + # 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)): + found_prereleases.append(version) + # Either this is not a prerelease, or we should have been + # accepting prereleases from the begining. + else: + yielded = True + yield version + + # Now that we've iterated over everything, determine if we've yielded + # any values, and if we have not and we have any prereleases stored up + # then we will go ahead and yield the prereleases. + if not yielded and found_prereleases: + for version in found_prereleases: + yield version + + +class LegacySpecifier(_IndividualSpecifier): + + _regex_str = ( + r""" + (?P<operator>(==|!=|<=|>=|<|>)) + \s* + (?P<version> + [^,;\s)]* # Since this is a "legacy" specifier, and the version + # string can be just about anything, we match everything + # except for whitespace, a semi-colon for marker support, + # a closing paren since versions can be enclosed in + # them, and a comma since it's a version separator. + ) + """ + ) + + _regex = re.compile( + r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) + + _operators = { + "==": "equal", + "!=": "not_equal", + "<=": "less_than_equal", + ">=": "greater_than_equal", + "<": "less_than", + ">": "greater_than", + } + + def _coerce_version(self, version): + if not isinstance(version, LegacyVersion): + version = LegacyVersion(str(version)) + return version + + def _compare_equal(self, prospective, spec): + return prospective == self._coerce_version(spec) + + def _compare_not_equal(self, prospective, spec): + return prospective != self._coerce_version(spec) + + def _compare_less_than_equal(self, prospective, spec): + return prospective <= self._coerce_version(spec) + + def _compare_greater_than_equal(self, prospective, spec): + return prospective >= self._coerce_version(spec) + + def _compare_less_than(self, prospective, spec): + return prospective < self._coerce_version(spec) + + def _compare_greater_than(self, prospective, spec): + return prospective > self._coerce_version(spec) + + +def _require_version_compare(fn): + @functools.wraps(fn) + def wrapped(self, prospective, spec): + if not isinstance(prospective, Version): + return False + return fn(self, prospective, spec) + return wrapped + + +class Specifier(_IndividualSpecifier): + + _regex_str = ( + r""" + (?P<operator>(~=|==|!=|<=|>=|<|>|===)) + (?P<version> + (?: + # The identity operators allow for an escape hatch that will + # do an exact string match of the version you wish to install. + # This will not be parsed by PEP 440 and we cannot determine + # any semantic meaning from it. This operator is discouraged + # but included entirely as an escape hatch. + (?<====) # Only match for the identity operator + \s* + [^\s]* # We just match everything, except for whitespace + # since we are only testing for strict identity. + ) + | + (?: + # The (non)equality operators allow for wild card and local + # versions to be specified so we have to define these two + # operators separately to enable that. + (?<===|!=) # Only match for equals and not equals + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)* # release + (?: # pre release + [-_\.]? + (a|b|c|rc|alpha|beta|pre|preview) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + + # You cannot use a wild card and a dev or local version + # together so group them with a | and make them optional. + (?: + (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + (?:\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*)? # local + | + \.\* # Wild card syntax of .* + )? + ) + | + (?: + # The compatible operator requires at least two digits in the + # release segment. + (?<=~=) # Only match for the compatible operator + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)+ # release (We have a + instead of a *) + (?: # pre release + [-_\.]? + (a|b|c|rc|alpha|beta|pre|preview) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + ) + | + (?: + # All other operators only allow a sub set of what the + # (non)equality operators do. Specifically they do not allow + # local versions to be specified nor do they allow the prefix + # matching wild cards. + (?<!==|!=|~=) # We have special cases for these + # operators so we want to make sure they + # don't match here. + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)* # release + (?: # pre release + [-_\.]? + (a|b|c|rc|alpha|beta|pre|preview) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + ) + ) + """ + ) + + _regex = re.compile( + r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) + + _operators = { + "~=": "compatible", + "==": "equal", + "!=": "not_equal", + "<=": "less_than_equal", + ">=": "greater_than_equal", + "<": "less_than", + ">": "greater_than", + "===": "arbitrary", + } + + @_require_version_compare + def _compare_compatible(self, prospective, spec): + # 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 + # implementing it ourselves. The only thing we need to do is construct + # the other specifiers. + + # We want everything but the last item in the version, but we want to + # ignore post and dev releases and we want to treat the pre-release as + # it's own separate segment. + prefix = ".".join( + list( + itertools.takewhile( + lambda x: (not x.startswith("post") and not + x.startswith("dev")), + _version_split(spec), + ) + )[:-1] + ) + + # Add the prefix notation to the end of our string + prefix += ".*" + + return (self._get_operator(">=")(prospective, spec) and + self._get_operator("==")(prospective, prefix)) + + @_require_version_compare + def _compare_equal(self, prospective, spec): + # 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 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)) + + # 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)] + + # Pad out our two sides with zeros so that they both equal the same + # length. + spec, prospective = _pad_version(spec, prospective) + else: + # Convert our spec string into a Version + spec = 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: + prospective = Version(prospective.public) + + return prospective == spec + + @_require_version_compare + def _compare_not_equal(self, prospective, spec): + return not self._compare_equal(prospective, spec) + + @_require_version_compare + def _compare_less_than_equal(self, prospective, spec): + return prospective <= Version(spec) + + @_require_version_compare + def _compare_greater_than_equal(self, prospective, spec): + return prospective >= Version(spec) + + @_require_version_compare + def _compare_less_than(self, prospective, spec): + # Convert our spec to a Version instance, since we'll want to work with + # it as a version. + spec = Version(spec) + + # 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 + # instead of doing extra unneeded work. + if not prospective < spec: + return False + + # This special case is here so that, unless the specifier itself + # includes is a pre-release version, that we do not accept pre-release + # versions for the version mentioned in the specifier (e.g. <3.1 should + # not match 3.1.dev0, but should match 3.0.dev0). + if not spec.is_prerelease and prospective.is_prerelease: + if Version(prospective.base_version) == Version(spec.base_version): + return False + + # If we've gotten to here, it means that prospective version is both + # less than the spec version *and* it's not a pre-release of the same + # version in the spec. + return True + + @_require_version_compare + def _compare_greater_than(self, prospective, spec): + # Convert our spec to a Version instance, since we'll want to work with + # it as a version. + spec = Version(spec) + + # 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 + # instead of doing extra unneeded work. + if not prospective > spec: + return False + + # This special case is here so that, unless the specifier itself + # includes is a post-release version, that we do not accept + # post-release versions for the version mentioned in the specifier + # (e.g. >3.1 should not match 3.0.post0, but should match 3.2.post0). + if not spec.is_postrelease and prospective.is_postrelease: + if Version(prospective.base_version) == Version(spec.base_version): + 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. + if prospective.local is not None: + if Version(prospective.base_version) == Version(spec.base_version): + return False + + # If we've gotten to here, it means that prospective version is both + # greater than the spec version *and* it's not a pre-release of the + # same version in the spec. + return True + + def _compare_arbitrary(self, prospective, spec): + return str(prospective).lower() == str(spec).lower() + + @property + def prereleases(self): + # If there is an explicit prereleases set for this, then we'll just + # blindly use that. + if self._prereleases is not None: + return self._prereleases + + # Look at all of our specifiers and determine if they are inclusive + # operators, and if they are if they are including an explicit + # prerelease. + operator, version = self._spec + if operator in ["==", ">=", "<=", "~=", "==="]: + # The == specifier can include a trailing .*, if it does we + # want to remove before parsing. + if operator == "==" and version.endswith(".*"): + version = version[:-2] + + # Parse the version, and if it is a pre-release than this + # specifier allows pre-releases. + if parse(version).is_prerelease: + return True + + return False + + @prereleases.setter + def prereleases(self, value): + self._prereleases = value + + +_prefix_regex = re.compile(r"^([0-9]+)((?:a|b|c|rc)[0-9]+)$") + + +def _version_split(version): + result = [] + for item in version.split("."): + match = _prefix_regex.search(item) + if match: + result.extend(match.groups()) + else: + result.append(item) + return result + + +def _pad_version(left, right): + left_split, right_split = [], [] + + # Get the release segment of our versions + left_split.append(list(itertools.takewhile(lambda x: x.isdigit(), left))) + 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]):]) + + # 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])), + ) + + 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. + 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: + try: + parsed.add(Specifier(specifier)) + except InvalidSpecifier: + parsed.add(LegacySpecifier(specifier)) + + # Turn our parsed specifiers into a frozen set and save them for later. + self._specs = frozenset(parsed) + + # Store our prereleases value so we can use it later to determine if + # we accept prereleases or not. + self._prereleases = prereleases + + def __repr__(self): + pre = ( + ", prereleases={0!r}".format(self.prereleases) + if self._prereleases is not None + else "" + ) + + return "<SpecifierSet({0!r}{1})>".format(str(self), pre) + + def __str__(self): + return ",".join(sorted(str(s) for s in self._specs)) + + def __hash__(self): + return hash(self._specs) + + def __and__(self, other): + if isinstance(other, string_types): + other = SpecifierSet(other) + elif not isinstance(other, SpecifierSet): + return NotImplemented + + specifier = SpecifierSet() + specifier._specs = frozenset(self._specs | other._specs) + + if self._prereleases is None and other._prereleases is not None: + specifier._prereleases = other._prereleases + elif self._prereleases is not None and other._prereleases is None: + specifier._prereleases = self._prereleases + elif self._prereleases == other._prereleases: + specifier._prereleases = self._prereleases + else: + raise ValueError( + "Cannot combine SpecifierSets with True and False prerelease " + "overrides." + ) + + return specifier + + def __eq__(self, other): + if isinstance(other, string_types): + other = SpecifierSet(other) + elif isinstance(other, _IndividualSpecifier): + other = SpecifierSet(str(other)) + elif not isinstance(other, SpecifierSet): + return NotImplemented + + return self._specs == other._specs + + def __ne__(self, other): + if isinstance(other, string_types): + other = SpecifierSet(other) + elif isinstance(other, _IndividualSpecifier): + other = SpecifierSet(str(other)) + elif not isinstance(other, SpecifierSet): + return NotImplemented + + return self._specs != other._specs + + def __len__(self): + return len(self._specs) + + def __iter__(self): + return iter(self._specs) + + @property + def prereleases(self): + # If we have been given an explicit prerelease modifier, then we'll + # pass that through here. + if self._prereleases is not None: + return self._prereleases + + # If we don't have any specifiers, and we don't have a forced value, + # then we'll just return None since we don't know if this should have + # pre-releases or not. + if not self._specs: + return None + + # Otherwise we'll see if any of the given specifiers accept + # prereleases, if any of them do we'll return True, otherwise False. + return any(s.prereleases for s in self._specs) + + @prereleases.setter + def prereleases(self, value): + self._prereleases = value + + def __contains__(self, item): + return self.contains(item) + + def contains(self, item, prereleases=None): + # Ensure that our item is a Version or LegacyVersion instance. + if not isinstance(item, (LegacyVersion, Version)): + item = parse(item) + + # 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. + if prereleases is None: + prereleases = self.prereleases + + # We can determine if we're going to allow pre-releases by looking to + # see if any of the underlying items supports them. If none of them do + # and this item is a pre-release then we do not allow it and we can + # short circuit that here. + # Note: This means that 1.0.dev1 would not be contained in something + # like >=1.0.devabc however it would be in >=1.0.debabc,>0.0.dev0 + if not prereleases and item.is_prerelease: + return False + + # We simply dispatch to the underlying specs here to make sure that the + # 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 + ) + + def filter(self, iterable, prereleases=None): + # 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. + if prereleases is None: + prereleases = self.prereleases + + # If we have any specifiers, then we want to wrap our iterable in the + # filter method for each one, this will act as a logical AND amongst + # each specifier. + if self._specs: + for spec in self._specs: + iterable = spec.filter(iterable, prereleases=bool(prereleases)) + return iterable + # If we do not have any specifiers, then we need to have a rough filter + # 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 = [] + + for item in iterable: + # Ensure that we some kind of Version class for this item. + if not isinstance(item, (LegacyVersion, Version)): + parsed_version = parse(item) + else: + parsed_version = item + + # Filter out any item which is parsed as a LegacyVersion + if isinstance(parsed_version, LegacyVersion): + continue + + # Store any item which is a pre-release for later unless we've + # already found a final version or we are accepting prereleases + if parsed_version.is_prerelease and not prereleases: + if not filtered: + found_prereleases.append(item) + else: + filtered.append(item) + + # If we've found no items except for pre-releases, then we'll go + # ahead and use the pre-releases + if not filtered and found_prereleases and prereleases is None: + return found_prereleases + + return filtered diff --git a/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/utils.py b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/utils.py new file mode 100644 index 0000000..942387c --- /dev/null +++ b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/utils.py @@ -0,0 +1,14 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import re + + +_canonicalize_regex = re.compile(r"[-_.]+") + + +def canonicalize_name(name): + # This is taken from PEP 503. + return _canonicalize_regex.sub("-", name).lower() diff --git a/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/version.py b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/version.py new file mode 100644 index 0000000..83b5ee8 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/version.py @@ -0,0 +1,393 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import collections +import itertools +import re + +from ._structures import Infinity + + +__all__ = [ + "parse", "Version", "LegacyVersion", "InvalidVersion", "VERSION_PATTERN" +] + + +_Version = collections.namedtuple( + "_Version", + ["epoch", "release", "dev", "pre", "post", "local"], +) + + +def parse(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 + a valid PEP 440 version or a legacy version. + """ + try: + return Version(version) + except InvalidVersion: + return LegacyVersion(version) + + +class InvalidVersion(ValueError): + """ + An invalid version was found, users should refer to PEP 440. + """ + + +class _BaseVersion(object): + + def __hash__(self): + return hash(self._key) + + def __lt__(self, other): + return self._compare(other, lambda s, o: s < o) + + def __le__(self, other): + return self._compare(other, lambda s, o: s <= o) + + def __eq__(self, other): + return self._compare(other, lambda s, o: s == o) + + def __ge__(self, other): + return self._compare(other, lambda s, o: s >= o) + + def __gt__(self, other): + return self._compare(other, lambda s, o: s > o) + + def __ne__(self, other): + return self._compare(other, lambda s, o: s != o) + + def _compare(self, other, method): + if not isinstance(other, _BaseVersion): + return NotImplemented + + return method(self._key, other._key) + + +class LegacyVersion(_BaseVersion): + + def __init__(self, version): + self._version = str(version) + self._key = _legacy_cmpkey(self._version) + + def __str__(self): + return self._version + + def __repr__(self): + return "<LegacyVersion({0})>".format(repr(str(self))) + + @property + def public(self): + return self._version + + @property + def base_version(self): + return self._version + + @property + def local(self): + return None + + @property + def is_prerelease(self): + return False + + @property + def is_postrelease(self): + return False + + +_legacy_version_component_re = re.compile( + r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE, +) + +_legacy_version_replacement_map = { + "pre": "c", "preview": "c", "-": "final-", "rc": "c", "dev": "@", +} + + +def _parse_version_parts(s): + for part in _legacy_version_component_re.split(s): + part = _legacy_version_replacement_map.get(part, part) + + if not part or part == ".": + continue + + if part[:1] in "0123456789": + # pad for numeric comparison + yield part.zfill(8) + else: + yield "*" + part + + # ensure that alpha/beta/candidate are before final + yield "*final" + + +def _legacy_cmpkey(version): + # 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, + # as before all PEP 440 versions. + epoch = -1 + + # This scheme is taken from pkg_resources.parse_version setuptools prior to + # it's adoption of the packaging library. + parts = [] + for part in _parse_version_parts(version.lower()): + if part.startswith("*"): + # remove "-" before a prerelease tag + if part < "*final": + while parts and parts[-1] == "*final-": + parts.pop() + + # remove trailing zeros from each series of numeric parts + while parts and parts[-1] == "00000000": + parts.pop() + + parts.append(part) + parts = tuple(parts) + + 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""" + v? + (?: + (?:(?P<epoch>[0-9]+)!)? # epoch + (?P<release>[0-9]+(?:\.[0-9]+)*) # release segment + (?P<pre> # pre-release + [-_\.]? + (?P<pre_l>(a|b|c|rc|alpha|beta|pre|preview)) + [-_\.]? + (?P<pre_n>[0-9]+)? + )? + (?P<post> # post release + (?:-(?P<post_n1>[0-9]+)) + | + (?: + [-_\.]? + (?P<post_l>post|rev|r) + [-_\.]? + (?P<post_n2>[0-9]+)? + ) + )? + (?P<dev> # dev release + [-_\.]? + (?P<dev_l>dev) + [-_\.]? + (?P<dev_n>[0-9]+)? + )? + ) + (?:\+(?P<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))? # local version +""" + + +class Version(_BaseVersion): + + _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 + match = self._regex.search(version) + if not match: + raise InvalidVersion("Invalid version: '{0}'".format(version)) + + # Store the parsed out pieces of the version + 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"), + ), + 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"), + ), + local=_parse_local_version(match.group("local")), + ) + + # Generate a key which will be used for sorting + self._key = _cmpkey( + self._version.epoch, + self._version.release, + self._version.pre, + self._version.post, + self._version.dev, + self._version.local, + ) + + def __repr__(self): + return "<Version({0})>".format(repr(str(self))) + + def __str__(self): + parts = [] + + # Epoch + if self._version.epoch != 0: + parts.append("{0}!".format(self._version.epoch)) + + # Release segment + parts.append(".".join(str(x) for x in self._version.release)) + + # Pre-release + if self._version.pre is not None: + parts.append("".join(str(x) for x in self._version.pre)) + + # Post-release + if self._version.post is not None: + parts.append(".post{0}".format(self._version.post[1])) + + # Development release + if self._version.dev is not None: + parts.append(".dev{0}".format(self._version.dev[1])) + + # Local version segment + if self._version.local is not None: + parts.append( + "+{0}".format(".".join(str(x) for x in self._version.local)) + ) + + return "".join(parts) + + @property + def public(self): + return str(self).split("+", 1)[0] + + @property + def base_version(self): + parts = [] + + # Epoch + if self._version.epoch != 0: + parts.append("{0}!".format(self._version.epoch)) + + # Release segment + parts.append(".".join(str(x) for x in self._version.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) + + @property + def is_postrelease(self): + return bool(self._version.post) + + +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. + if number is None: + number = 0 + + # We normalize any letters to their lower case form + letter = letter.lower() + + # We consider some words to be alternate spellings of other words and + # in those cases we want to normalize the spellings to our preferred + # spelling. + if letter == "alpha": + letter = "a" + elif letter == "beta": + letter = "b" + elif letter in ["c", "pre", "preview"]: + letter = "rc" + elif letter in ["rev", "r"]: + letter = "post" + + return letter, int(number) + if not letter and number: + # We assume if we are given a number, but we are not given a letter + # then this is using the implicit post release syntax (e.g. 1.0-1) + letter = "post" + + return letter, int(number) + + +_local_version_seperators = re.compile(r"[\._-]") + + +def _parse_local_version(local): + """ + Takes a string like abc.1.twelve and turns it into ("abc", 1, "twelve"). + """ + if local is not None: + return tuple( + part.lower() if not part.isdigit() else int(part) + for part in _local_version_seperators.split(local) + ) + + +def _cmpkey(epoch, release, pre, post, dev, local): + # 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( + 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. + # We'll do this by abusing the pre segment, but we _only_ want to do this + # 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 + # Versions without a pre-release (except as noted above) should sort after + # those with one. + elif pre is None: + pre = Infinity + + # Versions without a post segment should sort before those with one. + if post is None: + post = -Infinity + + # Versions without a development segment should sort after those with one. + if dev is None: + dev = Infinity + + if local is None: + # Versions without a local segment should sort before those with one. + local = -Infinity + else: + # Versions with a local segment need that segment parsed to implement + # the sorting rules in PEP440. + # - Alpha numeric segments sort before numeric segments + # - Alpha numeric segments sort lexicographically + # - 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 + ) + + return epoch, release, pre, post, dev, local diff --git a/venv/lib/python3.7/site-packages/pkg_resources/_vendor/pyparsing.py b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/pyparsing.py new file mode 100644 index 0000000..cf75e1e --- /dev/null +++ b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/pyparsing.py @@ -0,0 +1,5742 @@ +# module pyparsing.py +# +# Copyright (c) 2003-2018 Paul T. McGuire +# +# 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. +# + +__doc__ = \ +""" +pyparsing module - Classes and methods to define and execute parsing grammars +============================================================================= + +The pyparsing module is an alternative approach to creating and executing simple grammars, +vs. the traditional lex/yacc approach, or the use of regular expressions. With pyparsing, you +don't need to learn a new syntax for defining grammars or matching expressions - the parsing module +provides a library of classes that you use to construct the grammar directly in Python. + +Here is a program to parse "Hello, World!" (or any greeting of the form +C{"<salutation>, <addressee>!"}), built up using L{Word}, L{Literal}, and L{And} elements +(L{'+'<ParserElement.__add__>} operator gives L{And} expressions, strings are auto-converted to +L{Literal} expressions):: + + from pyparsing import Word, alphas + + # define grammar of a greeting + greet = Word(alphas) + "," + Word(alphas) + "!" + + hello = "Hello, World!" + print (hello, "->", greet.parseString(hello)) + +The program outputs the following:: + + Hello, World! -> ['Hello', ',', 'World', '!'] + +The Python representation of the grammar is quite readable, owing to the self-explanatory +class names, and the use of '+', '|' and '^' operators. + +The L{ParseResults} object returned from L{ParserElement.parseString<ParserElement.parseString>} can be accessed as a nested list, a dictionary, or an +object with named attributes. + +The pyparsing module handles some of the problems that are typically vexing when writing text parsers: + - extra or missing whitespace (the above program will also handle "Hello,World!", "Hello , World !", etc.) + - quoted strings + - embedded comments + + +Getting Started - +----------------- +Visit the classes L{ParserElement} and L{ParseResults} to see the base classes that most other pyparsing +classes inherit from. Use the docstrings for examples of how to: + - construct literal match expressions from L{Literal} and L{CaselessLiteral} classes + - construct character word-group expressions using the L{Word} class + - see how to create repetitive expressions using L{ZeroOrMore} and L{OneOrMore} classes + - use L{'+'<And>}, L{'|'<MatchFirst>}, L{'^'<Or>}, and L{'&'<Each>} operators to combine simple expressions into more complex ones + - associate names with your parsed results using L{ParserElement.setResultsName} + - find some helpful expression short-cuts like L{delimitedList} and L{oneOf} + - find more useful common expressions in the L{pyparsing_common} namespace class +""" + +__version__ = "2.2.1" +__versionTime__ = "18 Sep 2018 00:49 UTC" +__author__ = "Paul McGuire <ptmcg@users.sourceforge.net>" + +import string +from weakref import ref as wkref +import copy +import sys +import warnings +import re +import sre_constants +import collections +import pprint +import traceback +import types +from datetime import datetime + +try: + from _thread import RLock +except ImportError: + from threading import RLock + +try: + # Python 3 + from collections.abc import Iterable + from collections.abc import MutableMapping +except ImportError: + # Python 2.7 + from collections import Iterable + from collections import MutableMapping + +try: + from collections import OrderedDict as _OrderedDict +except ImportError: + try: + from ordereddict import OrderedDict as _OrderedDict + except ImportError: + _OrderedDict = None + +#~ sys.stderr.write( "testing pyparsing module, version %s, %s\n" % (__version__,__versionTime__ ) ) + +__all__ = [ +'And', 'CaselessKeyword', 'CaselessLiteral', 'CharsNotIn', 'Combine', 'Dict', 'Each', 'Empty', +'FollowedBy', 'Forward', 'GoToColumn', 'Group', 'Keyword', 'LineEnd', 'LineStart', 'Literal', +'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', +'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', +] + +system_version = tuple(sys.version_info)[:3] +PY_3 = system_version[0] == 3 +if PY_3: + _MAX_INT = sys.maxsize + basestring = str + unichr = chr + _ustr = str + + # build list of single arg builtins, that can be used as parse actions + singleArgBuiltins = [sum, len, sorted, reversed, list, tuple, set, any, all, min, max] + +else: + _MAX_INT = sys.maxint + range = xrange + + def _ustr(obj): + """Drop-in replacement for str(obj) that tries to be Unicode friendly. It first tries + str(obj). If that fails with a UnicodeEncodeError, then it tries unicode(obj). It + then < returns the unicode object | encodes it with the default encoding | ... >. + """ + if isinstance(obj,unicode): + return obj + + try: + # If this works, then _ustr(obj) has the same behaviour as str(obj), so + # it won't break any existing code. + return str(obj) + + except UnicodeEncodeError: + # Else encode it + ret = unicode(obj).encode(sys.getdefaultencoding(), 'xmlcharrefreplace') + xmlcharref = Regex(r'&#\d+;') + xmlcharref.setParseAction(lambda t: '\\u' + hex(int(t[0][2:-1]))[2:]) + return xmlcharref.transformString(ret) + + # 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)) + except AttributeError: + continue + +_generatorType = type((y for y in range(1))) + +def _xml_escape(data): + """Escape &, <, >, ", ', etc. in a string of 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): + data = data.replace(from_, to_) + return data + +class _Constants(object): + pass + +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) + +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 ): + self.loc = loc + if msg is None: + self.msg = pstr + self.pstr = "" + else: + self.msg = msg + self.pstr = pstr + self.parserElement = elem + self.args = (pstr, loc, msg) + + @classmethod + def _from_exception(cls, pe): + """ + internal factory method to simplify creating one type of ParseException + from another - avoids having __init__ signature conflicts among subclasses + """ + return cls(pe.pstr, pe.loc, pe.msg, pe.parserElement) + + 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 ) + 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 ): + return _ustr(self) + def markInputline( self, markerString = ">!<" ): + """Extracts the exception line from the input string, and marks + the location of the exception with a special symbol. + """ + line_str = self.line + line_column = self.column - 1 + if markerString: + line_str = "".join((line_str[:line_column], + markerString, line_str[line_column:])) + return line_str.strip() + def __dir__(self): + return "lineno col line".split() + dir(type(self)) + +class ParseException(ParseBaseException): + """ + Exception thrown when parse expressions don't match class; + 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 + + Example:: + try: + Word(nums).setName("integer").parseString("ABC") + except ParseException as pe: + print(pe) + print("column: {}".format(pe.col)) + + prints:: + Expected integer (at char 0), (line:1, col:1) + column: 1 + """ + pass + +class ParseFatalException(ParseBaseException): + """user-throwable exception thrown when inconsistent parse content + is found; stops all parsing immediately""" + pass + +class ParseSyntaxException(ParseFatalException): + """just like L{ParseFatalException}, but thrown internally when an + L{ErrorStop<And._ErrorStop>} ('-' operator) indicates that parsing is to stop + immediately because an unbacktrackable syntax error has been found""" + pass + +#~ class ReparseException(ParseBaseException): + #~ """Experimental class - parse actions can raise this exception to cause + #~ pyparsing to reparse the input string: + #~ - with a modified input string, and/or + #~ - with a modified start location + #~ Set the values of the ReparseException in the constructor, and raise the + #~ exception in a parse action to cause pyparsing to use the new string/location. + #~ Setting the values as None causes no change to be made. + #~ """ + #~ def __init_( self, newstring, restartLoc ): + #~ self.newParseText = newstring + #~ self.reparseLoc = restartLoc + +class RecursiveGrammarException(Exception): + """exception thrown by L{ParserElement.validate} if the grammar could be improperly recursive""" + def __init__( self, parseElementList ): + self.parseElementTrace = parseElementList + + def __str__( self ): + return "RecursiveGrammarException: %s" % self.parseElementTrace + +class _ParseResultsWithOffset(object): + 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) + +class ParseResults(object): + """ + Structured parse results, to provide multiple means of access to the parsed data: + - as a list (C{len(results)}) + - by list index (C{results[0], results[1]}, etc.) + - by attribute (C{results.<resultsName>} - see L{ParserElement.setResultsName}) + + Example:: + integer = Word(nums) + date_str = (integer.setResultsName("year") + '/' + + integer.setResultsName("month") + '/' + + integer.setResultsName("day")) + # equivalent form: + # date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + # parseString returns a ParseResults object + result = date_str.parseString("1999/12/31") + + def test(s, fn=repr): + print("%s -> %s" % (s, fn(eval(s)))) + test("list(result)") + test("result[0]") + test("result['month']") + test("result.day") + test("'month' in result") + test("'minutes' in result") + test("result.dump()", str) + prints:: + list(result) -> ['1999', '/', '12', '/', '31'] + result[0] -> '1999' + result['month'] -> '12' + result.day -> '31' + 'month' in result -> True + 'minutes' in result -> False + result.dump() -> ['1999', '/', '12', '/', '31'] + - day: 31 + - month: 12 + - year: 1999 + """ + def __new__(cls, toklist=None, name=None, asList=True, modal=True ): + if isinstance(toklist, cls): + return toklist + retobj = object.__new__(cls) + retobj.__doinit = True + return retobj + + # 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 ): + if self.__doinit: + self.__doinit = False + self.__name = None + self.__parent = None + self.__accumNames = {} + self.__asList = asList + self.__modal = modal + if toklist is None: + toklist = [] + if isinstance(toklist, list): + self.__toklist = toklist[:] + elif isinstance(toklist, _generatorType): + self.__toklist = list(toklist) + else: + self.__toklist = [toklist] + self.__tokdict = dict() + + 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 + self.__name = name + if not (isinstance(toklist, (type(None), basestring, list)) and toklist in (None,'',[])): + if isinstance(toklist,basestring): + toklist = [ toklist ] + if asList: + if isinstance(toklist,ParseResults): + self[name] = _ParseResultsWithOffset(toklist.copy(),0) + else: + self[name] = _ParseResultsWithOffset(ParseResults(toklist[0]),0) + self[name].__name = name + else: + try: + self[name] = toklist[0] + except (KeyError,TypeError,IndexError): + self[name] = toklist + + 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] ]) + + 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)): + self.__toklist[k] = v + sub = v + else: + self.__tokdict[k] = self.__tokdict.get(k,list()) + [_ParseResultsWithOffset(v,0)] + sub = v + if isinstance(sub,ParseResults): + sub.__parent = wkref(self) + + 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) + # get removed indices + removed = list(range(*i.indices(mylen))) + removed.reverse() + # fixup indices in token dictionary + 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 ): + return k in self.__tokdict + + 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 ): + if hasattr(self.__tokdict, "iterkeys"): + return self.__tokdict.iterkeys() + else: + return iter(self.__tokdict) + + def _itervalues( self ): + return (self[k] for k in self._iterkeys()) + + def _iteritems( self ): + return ((k, self[k]) for k in self._iterkeys()) + + if PY_3: + keys = _iterkeys + """Returns an iterator of all named result keys (Python 3.x only).""" + + values = _itervalues + """Returns an iterator of all named result values (Python 3.x only).""" + + items = _iteritems + """Returns an iterator of all named result key-value tuples (Python 3.x only).""" + + else: + iterkeys = _iterkeys + """Returns an iterator of all named result keys (Python 2.x only).""" + + itervalues = _itervalues + """Returns an iterator of all named result values (Python 2.x only).""" + + iteritems = _iteritems + """Returns an iterator of all named result key-value tuples (Python 2.x only).""" + + 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 ): + """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 ): + """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 ): + """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): + """ + Removes and returns item at specified index (default=C{last}). + Supports both C{list} and C{dict} semantics for C{pop()}. If passed no + argument or an integer argument, it will use C{list} semantics + and pop tokens from the list of parsed tokens. If passed a + non-integer argument (most likely a string), it will use C{dict} + semantics and pop the corresponding value from any defined + results names. A second default return value argument is + supported, just as in C{dict.pop()}. + + Example:: + def remove_first(tokens): + tokens.pop(0) + print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] + print(OneOrMore(Word(nums)).addParseAction(remove_first).parseString("0 123 321")) # -> ['123', '321'] + + label = Word(alphas) + patt = label("LABEL") + OneOrMore(Word(nums)) + print(patt.parseString("AAB 123 321").dump()) + + # Use pop() in a parse action to remove named result (note that corresponding value is not + # removed from list form of results) + def remove_LABEL(tokens): + tokens.pop("LABEL") + return tokens + patt.addParseAction(remove_LABEL) + print(patt.parseString("AAB 123 321").dump()) + prints:: + ['AAB', '123', '321'] + - LABEL: AAB + + ['AAB', '123', '321'] + """ + if not args: + args = [-1] + 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): + index = args[0] + ret = self[index] + del self[index] + return ret + else: + defaultvalue = args[1] + return defaultvalue + + def get(self, key, defaultValue=None): + """ + Returns named result matching the given key, or if there is no + such name, then returns the given C{defaultValue} or C{None} if no + C{defaultValue} is specified. + + Similar to C{dict.get()}. + + Example:: + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + result = date_str.parseString("1999/12/31") + print(result.get("year")) # -> '1999' + print(result.get("hour", "not specified")) # -> 'not specified' + print(result.get("hour")) # -> None + """ + if key in self: + return self[key] + else: + return defaultValue + + def insert( self, index, insStr ): + """ + Inserts new element at location index in the list of parsed tokens. + + Similar to C{list.insert()}. + + Example:: + print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] + + # use a parse action to insert the parse location in the front of the parsed results + def insert_locn(locn, tokens): + tokens.insert(0, locn) + print(OneOrMore(Word(nums)).addParseAction(insert_locn).parseString("0 123 321")) # -> [0, '0', '123', '321'] + """ + self.__toklist.insert(index, insStr) + # fixup indices in token dictionary + 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 ): + """ + Add single element to end of ParseResults list of elements. + + Example:: + print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] + + # use a parse action to compute the sum of the parsed integers, and add it to the end + def append_sum(tokens): + tokens.append(sum(map(int, tokens))) + print(OneOrMore(Word(nums)).addParseAction(append_sum).parseString("0 123 321")) # -> ['0', '123', '321', 444] + """ + self.__toklist.append(item) + + def extend( self, itemseq ): + """ + Add sequence of elements to end of ParseResults list of elements. + + Example:: + patt = OneOrMore(Word(alphas)) + + # use a parse action to append the reverse of the matched strings, to make a palindrome + def make_palindrome(tokens): + tokens.extend(reversed([t[::-1] for t in tokens])) + return ''.join(tokens) + print(patt.addParseAction(make_palindrome).parseString("lskdj sdlkjf lksd")) # -> 'lskdjsdlkjflksddsklfjkldsjdksl' + """ + if isinstance(itemseq, ParseResults): + self += itemseq + else: + self.__toklist.extend(itemseq) + + def clear( self ): + """ + Clear all elements and results names. + """ + del self.__toklist[:] + self.__tokdict.clear() + + 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 ): + ret = self.copy() + ret += other + return ret + + def __iadd__( self, other ): + if other.__tokdict: + offset = len(self.__toklist) + 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: + self[k] = v + if isinstance(v[0],ParseResults): + v[0].__parent = wkref(self) + + self.__toklist += other.__toklist + self.__accumNames.update( other.__accumNames ) + return self + + def __radd__(self, other): + 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 __str__( self ): + return '[' + ', '.join(_ustr(i) if isinstance(i, ParseResults) else repr(i) for i in self.__toklist) + ']' + + def _asStringList( self, sep='' ): + out = [] + for item in self.__toklist: + if out and sep: + out.append(sep) + if isinstance( item, ParseResults ): + out += item._asStringList() + else: + out.append( _ustr(item) ) + return out + + def asList( self ): + """ + Returns the parse results as a nested list of matching tokens, all converted to strings. + + Example:: + patt = OneOrMore(Word(alphas)) + result = patt.parseString("sldkj lsdkj sldkj") + # even though the result prints in string-like form, it is actually a pyparsing ParseResults + print(type(result), result) # -> <class 'pyparsing.ParseResults'> ['sldkj', 'lsdkj', 'sldkj'] + + # Use asList() to create an actual list + 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] + + def asDict( self ): + """ + Returns the named parse results as a nested dictionary. + + Example:: + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + result = date_str.parseString('12/31/1999') + print(type(result), repr(result)) # -> <class 'pyparsing.ParseResults'> (['12', '/', '31', '/', '1999'], {'day': [('1999', 4)], 'year': [('12', 0)], 'month': [('31', 2)]}) + + result_dict = result.asDict() + print(type(result_dict), repr(result_dict)) # -> <class 'dict'> {'day': '1999', 'year': '12', 'month': '31'} + + # even though a ParseResults supports dict-like access, sometime you just need to have a dict + import json + print(json.dumps(result)) # -> Exception: TypeError: ... is not JSON serializable + print(json.dumps(result.asDict())) # -> {"month": "31", "day": "1999", "year": "12"} + """ + if PY_3: + item_fn = self.items + else: + item_fn = self.iteritems + + def toItem(obj): + if isinstance(obj, ParseResults): + if obj.haskeys(): + return obj.asDict() + else: + return [toItem(v) for v in obj] + else: + return obj + + return dict((k,toItem(v)) for k,v in item_fn()) + + def copy( self ): + """ + Returns a new copy of a C{ParseResults} object. + """ + ret = ParseResults( self.__toklist ) + ret.__tokdict = self.__tokdict.copy() + ret.__parent = self.__parent + ret.__accumNames.update( self.__accumNames ) + ret.__name = self.__name + return ret + + 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) + nextLevelIndent = indent + " " + + # collapse out indents if formatting is not desired + if not formatted: + indent = "" + nextLevelIndent = "" + nl = "" + + selfTag = None + if doctag is not None: + selfTag = doctag + else: + if self.__name: + selfTag = self.__name + + if not selfTag: + if namedItemsOnly: + return "" + else: + selfTag = "ITEM" + + out += [ nl, indent, "<", selfTag, ">" ] + + 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)] + else: + out += [ res.asXML(None, + namedItemsOnly and doctag is None, + nextLevelIndent, + formatted)] + else: + # individual token, see if there is a name for it + resTag = None + if i in namedItems: + resTag = namedItems[i] + if not resTag: + if namedItemsOnly: + continue + else: + resTag = "ITEM" + xmlBodyText = _xml_escape(_ustr(res)) + out += [ nl, nextLevelIndent, "<", resTag, ">", + xmlBodyText, + "</", resTag, ">" ] + + out += [ nl, indent, "</", selfTag, ">" ] + return "".join(out) + + def __lookup(self,sub): + for k,vlist in self.__tokdict.items(): + for v,loc in vlist: + if sub is v: + return k + return None + + def getName(self): + r""" + Returns the results name for this token expression. Useful when several + different expressions might match at a particular location. + + Example:: + integer = Word(nums) + ssn_expr = Regex(r"\d\d\d-\d\d-\d\d\d\d") + house_number_expr = Suppress('#') + Word(nums, alphanums) + user_data = (Group(house_number_expr)("house_number") + | Group(ssn_expr)("ssn") + | Group(integer)("age")) + user_info = OneOrMore(user_data) + + result = user_info.parseString("22 111-22-3333 #221B") + for item in result: + print(item.getName(), ':', item[0]) + prints:: + age : 22 + ssn : 111-22-3333 + house_number : 221B + """ + if self.__name: + return self.__name + elif self.__parent: + par = self.__parent() + if par: + 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)): + return next(iter(self.__tokdict.keys())) + else: + return None + + def dump(self, indent='', depth=0, full=True): + """ + Diagnostic method for listing out the contents of a C{ParseResults}. + Accepts an optional C{indent} argument so that this string can be embedded + in a nested display of other data. + + Example:: + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + result = date_str.parseString('12/31/1999') + print(result.dump()) + prints:: + ['12', '/', '31', '/', '1999'] + - day: 1999 + - month: 31 + - year: 12 + """ + out = [] + NL = '\n' + out.append( indent+_ustr(self.asList()) ) + if full: + if self.haskeys(): + 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): + if v: + out.append( v.dump(indent,depth+1) ) + else: + out.append(_ustr(v)) + else: + out.append(repr(v)) + 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) )) + else: + out.append("\n%s%s[%d]:\n%s%s%s" % (indent,(' '*(depth)),i,indent,(' '*(depth+1)),_ustr(vv))) + + return "".join(out) + + def pprint(self, *args, **kwargs): + """ + Pretty-printer for parsed results as a list, using the C{pprint} module. + Accepts additional positional or keyword args as defined for the + C{pprint.pprint} method. (U{http://docs.python.org/3/library/pprint.html#pprint.pprint}) + + Example:: + ident = Word(alphas, alphanums) + num = Word(nums) + func = Forward() + term = ident | num | Group('(' + func + ')') + func <<= ident + Group(Optional(delimitedList(term))) + result = func.parseString("fna a,b,(fnb c,d,200),100") + result.pprint(width=40) + prints:: + ['fna', + ['a', + 'b', + ['(', 'fnb', ['c', 'd', '200'], ')'], + '100']] + """ + pprint.pprint(self.asList(), *args, **kwargs) + + # 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 ) ) + + def __setstate__(self,state): + self.__toklist = state[0] + (self.__tokdict, + par, + inAccumNames, + self.__name) = state[1] + self.__accumNames = {} + self.__accumNames.update(inAccumNames) + if par is not None: + self.__parent = wkref(par) + else: + self.__parent = None + + def __getnewargs__(self): + return self.__toklist, self.__name, self.__asList, self.__modal + + def __dir__(self): + return (dir(type(self)) + list(self.keys())) + +MutableMapping.register(ParseResults) + +def col (loc,strg): + """Returns current column within a string, counting newlines as line separators. + The first column is number 1. + + Note: the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See L{I{ParserElement.parseString}<ParserElement.parseString>} for more information + on parsing strings containing C{<TAB>}s, and suggested methods to maintain a + consistent view of the parsed string, the parse 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) + +def lineno(loc,strg): + """Returns current line number within a string, counting newlines as line separators. + The first line is number 1. + + Note: the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See L{I{ParserElement.parseString}<ParserElement.parseString>} for more information + on parsing strings containing C{<TAB>}s, and 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 + +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] + else: + 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 _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 nullDebugAction(*args): + """'Do-nothing' debug action, to suppress debugging output during parsing.""" + pass + +# Only works on Python 3.x - nonlocal is toxic to Python 2 installs +#~ 'decorator to trim function calls to match the arity of the target' +#~ def _trim_arity(func, maxargs=3): + #~ if func in singleArgBuiltins: + #~ return lambda s,l,t: func(t) + #~ limit = 0 + #~ foundArity = False + #~ def wrapper(*args): + #~ nonlocal limit,foundArity + #~ while 1: + #~ try: + #~ ret = func(*args[limit:]) + #~ foundArity = True + #~ return ret + #~ except TypeError: + #~ if limit == maxargs or foundArity: + #~ raise + #~ limit += 1 + #~ continue + #~ return wrapper + +# this version is Python 2.x-3.x cross-compatible +'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) + limit = [0] + foundArity = [False] + + # traceback return data structure changed in Py3.5 - normalize back to plain tuples + 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] + return [frame_summary[:2]] + def extract_tb(tb, limit=0): + frames = traceback.extract_tb(tb, limit=limit) + frame_summary = frames[-1] + return [frame_summary[:2]] + else: + extract_stack = traceback.extract_stack + extract_tb = traceback.extract_tb + + # synthesize what would be returned by traceback.extract_stack at the call to + # user's parse action 'func', so that we don't incur call penalty at parse time + + LINE_DIFF = 6 + # 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) + + def wrapper(*args): + while 1: + try: + ret = func(*args[limit[0]:]) + foundArity[0] = True + return ret + except TypeError: + # re-raise TypeErrors if they did not come from our arity testing + if foundArity[0]: + raise + else: + try: + tb = sys.exc_info()[-1] + if not extract_tb(tb, limit=2)[-1][:2] == pa_call_line_synth: + raise + finally: + del tb + + if limit[0] <= maxargs: + limit[0] += 1 + continue + raise + + # copy func name to wrapper for sensible debug output + func_name = "<parse action>" + try: + func_name = getattr(func, '__name__', + getattr(func, '__class__').__name__) + except Exception: + func_name = str(func) + wrapper.__name__ = func_name + + return wrapper + +class ParserElement(object): + """Abstract base level parser element class.""" + DEFAULT_WHITE_CHARS = " \n\t\r" + verbose_stacktrace = False + + @staticmethod + def setDefaultWhitespaceChars( chars ): + r""" + Overrides the default whitespace chars + + Example:: + # default whitespace chars are space, <TAB> and newline + OneOrMore(Word(alphas)).parseString("abc def\nghi jkl") # -> ['abc', 'def', 'ghi', 'jkl'] + + # change to just treat newline as significant + ParserElement.setDefaultWhitespaceChars(" \t") + OneOrMore(Word(alphas)).parseString("abc def\nghi jkl") # -> ['abc', 'def'] + """ + ParserElement.DEFAULT_WHITE_CHARS = chars + + @staticmethod + def inlineLiteralsUsing(cls): + """ + Set class to be used for inclusion of string literals into a parser. + + Example:: + # default literal class used is Literal + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + date_str.parseString("1999/12/31") # -> ['1999', '/', '12', '/', '31'] + + + # change to Suppress + ParserElement.inlineLiteralsUsing(Suppress) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + date_str.parseString("1999/12/31") # -> ['1999', '12', '31'] + """ + ParserElement._literalStringClass = cls + + 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.strRepr = None + self.resultsName = None + self.saveAsList = savelist + self.skipWhitespace = True + self.whiteChars = ParserElement.DEFAULT_WHITE_CHARS + self.copyDefaultWhiteChars = True + self.mayReturnEmpty = False # used when checking for left-recursion + self.keepTabs = False + self.ignoreExprs = list() + self.debug = False + self.streamlined = False + 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.re = None + self.callPreparse = True # used to avoid redundant calls to preParse + self.callDuringTry = False + + def copy( self ): + """ + Make a copy of this C{ParserElement}. Useful for defining different parse actions + for the same parsing pattern, using copies of the original parse element. + + 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") + + print(OneOrMore(integerK | integerM | integer).parseString("5K 100 640K 256M")) + prints:: + [5120, 100, 655360, 268435456] + Equivalent form of C{expr.copy()} is just C{expr()}:: + integerM = integer().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M") + """ + 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 ): + """ + Define name for this expression, makes debugging and exception messages clearer. + + Example:: + Word(nums).parseString("ABC") # -> Exception: Expected W:(0123...) (at char 0), (line:1, col:1) + Word(nums).setName("integer").parseString("ABC") # -> Exception: Expected integer (at char 0), (line:1, col:1) + """ + self.name = name + self.errmsg = "Expected " + self.name + if hasattr(self,"exception"): + self.exception.msg = self.errmsg + return self + + def setResultsName( self, name, listAllMatches=False ): + """ + Define name for referencing matching tokens as a nested attribute + of the returned parse results. + NOTE: this returns a *copy* of the original C{ParserElement} object; + this is so that the client can define a basic element, such as an + integer, and reference it in multiple places with different names. + + You can also set results names using the abbreviated syntax, + C{expr("name")} in place of C{expr.setResultsName("name")} - + see L{I{__call__}<__call__>}. + + Example:: + date_str = (integer.setResultsName("year") + '/' + + integer.setResultsName("month") + '/' + + integer.setResultsName("day")) + + # equivalent form: + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + """ + newself = self.copy() + if name.endswith("*"): + name = name[:-1] + listAllMatches=True + newself.resultsName = name + newself.modalResults = not listAllMatches + return newself + + def setBreak(self,breakFlag = True): + """Method to invoke the Python pdb debugger when this element is + about to be parsed. Set C{breakFlag} to True to enable, False to + disable. + """ + if breakFlag: + _parseMethod = self._parse + def breaker(instring, loc, doActions=True, callPreParse=True): + import pdb + pdb.set_trace() + return _parseMethod( instring, loc, doActions, callPreParse ) + breaker._originalParseMethod = _parseMethod + self._parse = breaker + else: + if hasattr(self._parse,"_originalParseMethod"): + self._parse = self._parse._originalParseMethod + return self + + 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 C{fn(s,loc,toks)}, + C{fn(loc,toks)}, C{fn(toks)}, or just C{fn()}, where: + - s = the original string being parsed (see note below) + - loc = the location of the matching substring + - toks = a list of the matched tokens, packaged as a C{L{ParseResults}} object + If the functions in fns modify the tokens, they can return them as the return + value from fn, and the modified list of tokens will replace the original. + Otherwise, fn does not need to return any value. + + Optional keyword arguments: + - callDuringTry = (default=C{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 L{I{parseString}<parseString>} for more information + on parsing strings containing C{<TAB>}s, and suggested methods to maintain a + consistent view of the parsed string, the parse location, and line and column + positions within the parsed string. + + Example:: + integer = Word(nums) + date_str = integer + '/' + integer + '/' + integer + + date_str.parseString("1999/12/31") # -> ['1999', '/', '12', '/', '31'] + + # use parse action to convert to ints at parse time + integer = Word(nums).setParseAction(lambda toks: int(toks[0])) + date_str = integer + '/' + integer + '/' + integer + + # 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) + return self + + def addParseAction( self, *fns, **kwargs ): + """ + Add one or more parse actions to expression's list of parse actions. See L{I{setParseAction}<setParseAction>}. + + See examples in L{I{copy}<copy>}. + """ + self.parseAction += list(map(_trim_arity, list(fns))) + self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False) + return self + + def addCondition(self, *fns, **kwargs): + """Add a boolean predicate function to expression's list of parse actions. See + L{I{setParseAction}<setParseAction>} for function call signatures. Unlike C{setParseAction}, + functions passed to C{addCondition} need to return boolean success/fail of the condition. + + Optional keyword arguments: + - message = define a custom message to be used in the raised exception + - fatal = if True, will raise ParseFatalException to stop parsing immediately; otherwise will raise ParseException + + Example:: + integer = Word(nums).setParseAction(lambda toks: int(toks[0])) + year_int = integer.copy() + year_int.addCondition(lambda toks: toks[0] >= 2000, message="Only support years 2000 and later") + date_str = year_int + '/' + integer + '/' + integer + + 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: + def pa(s,l,t): + if not bool(_trim_arity(fn)(s,l,t)): + raise exc_type(s,l,msg) + self.parseAction.append(pa) + self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False) + return self + + 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 + C{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 + - err = the exception thrown + The function returns no value. It may throw C{L{ParseFatalException}} + if it is desired to stop parsing immediately.""" + self.failAction = fn + return self + + 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 ) + exprsFound = True + except ParseException: + pass + return loc + + def preParse( self, instring, loc ): + if self.ignoreExprs: + loc = self._skipIgnorables( instring, loc ) + + if self.skipWhitespace: + wt = self.whiteChars + instrlen = len(instring) + while loc < instrlen and instring[loc] in wt: + loc += 1 + + return loc + + def parseImpl( self, instring, loc, doActions=True ): + return loc, [] + + def postParse( self, instring, loc, tokenlist ): + return tokenlist + + #~ @profile + def _parseNoCache( self, instring, loc, doActions=True, callPreParse=True ): + 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 + 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 self.failAction: + self.failAction( instring, tokensStart, self, err ) + raise + else: + 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 ) + + tokens = self.postParse( instring, loc, tokens ) + + 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: + tokens = fn( instring, tokensStart, retTokens ) + if tokens is not None: + 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 ) + raise + else: + for fn in self.parseAction: + tokens = fn( instring, tokensStart, retTokens ) + if tokens is not None: + retTokens = ParseResults( tokens, + self.resultsName, + 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 ) + + return loc, retTokens + + def tryParse( self, instring, loc ): + try: + return self._parse( instring, loc, doActions=False )[0] + except ParseFatalException: + raise ParseException( instring, loc, self.errmsg, self) + + def canParseNext(self, instring, loc): + try: + self.tryParse(instring, loc) + except (ParseException, IndexError): + return False + else: + return True + + class _UnboundedCache(object): + def __init__(self): + cache = {} + self.not_in_cache = not_in_cache = object() + + def get(self, key): + return cache.get(key, not_in_cache) + + def set(self, key, value): + cache[key] = value + + def clear(self): + cache.clear() + + def cache_len(self): + return len(cache) + + self.get = types.MethodType(get, self) + self.set = types.MethodType(set, self) + self.clear = types.MethodType(clear, self) + self.__len__ = types.MethodType(cache_len, self) + + if _OrderedDict is not None: + class _FifoCache(object): + def __init__(self, size): + self.not_in_cache = not_in_cache = object() + + cache = _OrderedDict() + + def get(self, key): + return cache.get(key, not_in_cache) + + def set(self, key, value): + cache[key] = value + while len(cache) > size: + try: + cache.popitem(False) + except KeyError: + pass + + def clear(self): + cache.clear() + + def cache_len(self): + return len(cache) + + self.get = types.MethodType(get, self) + self.set = types.MethodType(set, self) + self.clear = types.MethodType(clear, self) + self.__len__ = types.MethodType(cache_len, self) + + else: + class _FifoCache(object): + def __init__(self, size): + self.not_in_cache = not_in_cache = object() + + cache = {} + key_fifo = collections.deque([], size) + + def get(self, key): + return cache.get(key, not_in_cache) + + def set(self, key, value): + cache[key] = value + while len(key_fifo) > size: + cache.pop(key_fifo.popleft(), None) + key_fifo.append(key) + + def clear(self): + cache.clear() + key_fifo.clear() + + def cache_len(self): + return len(cache) + + self.get = types.MethodType(get, self) + self.set = types.MethodType(set, self) + self.clear = types.MethodType(clear, self) + self.__len__ = types.MethodType(cache_len, self) + + # argument cache for optimizing repeated calls when backtracking through recursive expressions + packrat_cache = {} # this is set later by enabledPackrat(); this is here so that resetCache() doesn't fail + packrat_cache_lock = RLock() + packrat_cache_stats = [0, 0] + + # 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 ): + HIT, MISS = 0, 1 + lookup = (self, instring, loc, callPreParse, doActions) + with ParserElement.packrat_cache_lock: + cache = ParserElement.packrat_cache + value = cache.get(lookup) + if value is cache.not_in_cache: + ParserElement.packrat_cache_stats[MISS] += 1 + try: + value = self._parseNoCache(instring, loc, doActions, callPreParse) + except ParseBaseException as pe: + # cache a copy of the exception, without the traceback + cache.set(lookup, pe.__class__(*pe.args)) + raise + else: + cache.set(lookup, (value[0], value[1].copy())) + return value + else: + ParserElement.packrat_cache_stats[HIT] += 1 + if isinstance(value, Exception): + raise value + return (value[0], value[1].copy()) + + _parse = _parseNoCache + + @staticmethod + def resetCache(): + ParserElement.packrat_cache.clear() + ParserElement.packrat_cache_stats[:] = [0] * len(ParserElement.packrat_cache_stats) + + _packratEnabled = False + @staticmethod + def enablePackrat(cache_size_limit=128): + """Enables "packrat" parsing, which adds memoizing to the parsing logic. + Repeated parse attempts at the same string location (which happens + often in many complex grammars) can immediately return a cached value, + instead of re-executing parsing/validating code. Memoizing is done of + both valid results and parsing exceptions. + + Parameters: + - cache_size_limit - (default=C{128}) - if an integer value is provided + will limit the size of the packrat cache; if None is passed, then + the cache size will be unbounded; if 0 is passed, the cache will + be effectively disabled. + + This speedup may break existing programs that use parse actions that + have side-effects. For this reason, packrat parsing is disabled when + you first import pyparsing. To activate the packrat feature, your + program must call the class method C{ParserElement.enablePackrat()}. If + your program uses C{psyco} to "compile as you go", you must call + C{enablePackrat} before calling C{psyco.full()}. If you do not do this, + Python will crash. For best results, call C{enablePackrat()} immediately + after importing pyparsing. + + Example:: + import pyparsing + pyparsing.ParserElement.enablePackrat() + """ + if not ParserElement._packratEnabled: + ParserElement._packratEnabled = True + if cache_size_limit is None: + ParserElement.packrat_cache = ParserElement._UnboundedCache() + else: + ParserElement.packrat_cache = ParserElement._FifoCache(cache_size_limit) + ParserElement._parse = ParserElement._parseCache + + 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. + + If you want the grammar to require that the entire input string be + successfully parsed, then set C{parseAll} to True (equivalent to ending + the grammar with C{L{StringEnd()}}). + + Note: C{parseString} implicitly calls C{expandtabs()} on the input string, + in order to report proper column numbers in parse actions. + If the input string contains tabs and + the grammar uses parse actions that use the C{loc} argument to index into the + string being parsed, you can ensure you have a consistent view of the input + string by: + - calling C{parseWithTabs} on your grammar before calling C{parseString} + (see L{I{parseWithTabs}<parseWithTabs>}) + - define your parse action using the full C{(s,loc,toks)} signature, and + reference the input string using the parse action's C{s} argument + - explictly expand the tabs in your input string before calling + C{parseString} + + Example:: + Word('a').parseString('aaaaabaaa') # -> ['aaaaa'] + Word('a').parseString('aaaaabaaa', parseAll=True) # -> Exception: Expected end of text + """ + ParserElement.resetCache() + if not self.streamlined: + self.streamline() + #~ self.saveAsList = True + for e in self.ignoreExprs: + e.streamline() + if not self.keepTabs: + instring = instring.expandtabs() + try: + loc, tokens = self._parse( instring, 0 ) + if parseAll: + loc = self.preParse( instring, loc ) + se = Empty() + StringEnd() + 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 + raise exc + else: + return tokens + + 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 + C{maxMatches} argument, to clip scanning after 'n' matches are found. If + C{overlap} is specified, then overlapping matches will be reported. + + Note that the start and end locations are reported relative to the string + being parsed. See L{I{parseString}<parseString>} for more information on parsing + strings with embedded tabs. + + Example:: + source = "sldjf123lsdjjkf345sldkjf879lkjsfd987" + print(source) + for tokens,start,end in Word(alphas).scanString(source): + print(' '*start + '^'*(end-start)) + print(' '*start + tokens[0]) + + prints:: + + sldjf123lsdjjkf345sldkjf879lkjsfd987 + ^^^^^ + sldjf + ^^^^^^^ + lsdjjkf + ^^^^^^ + sldkjf + ^^^^^^ + lkjsfd + """ + if not self.streamlined: + self.streamline() + for e in self.ignoreExprs: + e.streamline() + + if not self.keepTabs: + instring = _ustr(instring).expandtabs() + instrlen = len(instring) + loc = 0 + preparseFn = self.preParse + parseFn = self._parse + ParserElement.resetCache() + matches = 0 + try: + while loc <= instrlen and matches < maxMatches: + try: + preloc = preparseFn( instring, loc ) + nextLoc,tokens = parseFn( instring, preloc, callPreParse=False ) + except ParseException: + loc = preloc+1 + else: + if nextLoc > loc: + matches += 1 + yield tokens, preloc, nextLoc + if overlap: + nextloc = preparseFn( instring, loc ) + if nextloc > loc: + loc = nextLoc + else: + loc += 1 + else: + loc = nextLoc + else: + 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 + raise exc + + def transformString( self, instring ): + """ + Extension to C{L{scanString}}, to modify matching text with modified tokens that may + be returned from a parse action. To use C{transformString}, define a grammar and + attach a parse action to it that modifies the returned token list. + Invoking C{transformString()} on a target string will then scan for matches, + and replace the matched text patterns according to the logic in the parse + action. C{transformString()} returns the resulting transformed string. + + Example:: + wd = Word(alphas) + wd.setParseAction(lambda toks: toks[0].title()) + + print(wd.transformString("now is the winter of our discontent made glorious summer by this sun of york.")) + Prints:: + Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York. + """ + out = [] + lastE = 0 + # force preservation of <TAB>s, to minimize unwanted transformation of string, and to + # 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] ) + if t: + if isinstance(t,ParseResults): + out += t.asList() + 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))) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def searchString( self, instring, maxMatches=_MAX_INT ): + """ + Another extension to C{L{scanString}}, simplifying the access to the tokens found + to match the given parse expression. May be called with optional + C{maxMatches} argument, to clip searching after 'n' matches are found. + + Example:: + # a capitalized word starts with an uppercase letter, followed by zero or more lowercase letters + cap_word = Word(alphas.upper(), alphas.lower()) + + print(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity")) + + # the sum() builtin can be used to merge results into a single ParseResults object + print(sum(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity"))) + prints:: + [['More'], ['Iron'], ['Lead'], ['Gold'], ['I'], ['Electricity']] + ['More', 'Iron', 'Lead', 'Gold', 'I', 'Electricity'] + """ + try: + 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 + raise exc + + def split(self, instring, maxsplit=_MAX_INT, includeSeparators=False): + """ + Generator method to split a string using the given expression as a separator. + May be called with optional C{maxsplit} argument, to limit the number of splits; + and the optional C{includeSeparators} argument (default=C{False}), if the separating + matching text should be included in the split results. + + Example:: + punc = oneOf(list(".,;:/-!?")) + print(list(punc.split("This, this?, this sentence, is badly punctuated!"))) + prints:: + ['This', ' this', '', ' this sentence', ' is badly punctuated', ''] + """ + splits = 0 + last = 0 + 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 ): + """ + Implementation of + operator - returns C{L{And}}. Adding strings to a ParserElement + converts them to L{Literal}s by default. + + Example:: + greet = Word(alphas) + "," + Word(alphas) + "!" + hello = "Hello, World!" + print (hello, "->", greet.parseString(hello)) + 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 ): + """ + Implementation of + operator when left operand is not a C{L{ParserElement}} + """ + 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 other + self + + def __sub__(self, other): + """ + Implementation of - operator, returns C{L{And}} with error stop + """ + 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 self + And._ErrorStop() + other + + def __rsub__(self, other ): + """ + Implementation of - operator when left operand is not a C{L{ParserElement}} + """ + 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 other - self + + def __mul__(self,other): + """ + Implementation of * operator, allows use of C{expr * 3} in place of + C{expr + expr + expr}. Expressions may also me multiplied by a 2-integer + tuple, similar to C{{min,max}} multipliers in regular expressions. Tuples + may also include C{None} as in: + - C{expr*(n,None)} or C{expr*(n,)} is equivalent + to C{expr*n + L{ZeroOrMore}(expr)} + (read as "at least n instances of C{expr}") + - C{expr*(None,n)} is equivalent to C{expr*(0,n)} + (read as "0 to n instances of C{expr}") + - C{expr*(None,None)} is equivalent to C{L{ZeroOrMore}(expr)} + - C{expr*(1,None)} is equivalent to C{L{OneOrMore}(expr)} + + Note that C{expr*(None,n)} does not raise an exception if + more than n exprs exist in the input stream; that is, + C{expr*(None,n)} does not enforce a maximum number of expr + occurrences. If this behavior is desired, then write + C{expr*(None,n) + ~expr} + """ + if isinstance(other,int): + minElements, optElements = other,0 + elif isinstance(other,tuple): + 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 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): + minElements, optElements = other + optElements -= minElements + else: + 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)) + + if minElements < 0: + raise ValueError("cannot multiply ParserElement by negative value") + 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)") + + if (optElements): + def makeOptionalList(n): + 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) + else: + ret = makeOptionalList(optElements) + else: + if minElements == 1: + ret = self + else: + ret = And([self]*minElements) + return ret + + def __rmul__(self, other): + return self.__mul__(other) + + def __or__(self, other ): + """ + Implementation of | operator - returns C{L{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 ] ) + + def __ror__(self, other ): + """ + Implementation of | operator when left operand is not a C{L{ParserElement}} + """ + 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 other | self + + def __xor__(self, other ): + """ + Implementation of ^ operator - returns C{L{Or}} + """ + 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 Or( [ self, other ] ) + + def __rxor__(self, other ): + """ + Implementation of ^ operator when left operand is not a C{L{ParserElement}} + """ + 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 other ^ self + + def __and__(self, other ): + """ + Implementation of & operator - returns C{L{Each}} + """ + 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 Each( [ self, other ] ) + + def __rand__(self, other ): + """ + Implementation of & operator when left operand is not a C{L{ParserElement}} + """ + 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 other & self + + def __invert__( self ): + """ + Implementation of ~ operator - returns C{L{NotAny}} + """ + return NotAny( self ) + + def __call__(self, name=None): + """ + Shortcut for C{L{setResultsName}}, with C{listAllMatches=False}. + + If C{name} is given with a trailing C{'*'} character, then C{listAllMatches} will be + passed as C{True}. + + If C{name} is omitted, same as calling C{L{copy}}. + + Example:: + # these are equivalent + 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) + else: + return self.copy() + + def suppress( self ): + """ + Suppresses the output of this C{ParserElement}; useful to keep punctuation from + cluttering up returned output. + """ + return Suppress( self ) + + def leaveWhitespace( self ): + """ + Disables the skipping of whitespace before matching the characters in the + C{ParserElement}'s defined pattern. This is normally only used internally by + the pyparsing module, but may be needed in some whitespace-sensitive grammars. + """ + self.skipWhitespace = False + return self + + def setWhitespaceChars( self, chars ): + """ + Overrides the default whitespace chars + """ + self.skipWhitespace = True + self.whiteChars = chars + self.copyDefaultWhiteChars = False + return self + + def parseWithTabs( self ): + """ + Overrides default behavior to expand C{<TAB>}s to spaces before parsing the input string. + Must be called before C{parseString} when the input grammar contains elements that + match C{<TAB>} characters. + """ + self.keepTabs = True + return self + + 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 + ignorable patterns. + + Example:: + patt = OneOrMore(Word(alphas)) + patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj'] + + patt.ignore(cStyleComment) + patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj', 'lskjd'] + """ + if isinstance(other, basestring): + other = Suppress(other) + + if isinstance( other, Suppress ): + if other not in self.ignoreExprs: + self.ignoreExprs.append(other) + else: + self.ignoreExprs.append( Suppress( other.copy() ) ) + return self + + def setDebugActions( self, startAction, successAction, exceptionAction ): + """ + Enable display of debugging messages while doing pattern matching. + """ + self.debugActions = (startAction or _defaultStartDebugAction, + successAction or _defaultSuccessDebugAction, + exceptionAction or _defaultExceptionDebugAction) + self.debug = True + return self + + def setDebug( self, flag=True ): + """ + Enable display of debugging messages while doing pattern matching. + Set C{flag} to True to enable, False to disable. + + Example:: + wd = Word(alphas).setName("alphaword") + integer = Word(nums).setName("numword") + term = wd | integer + + # turn on debugging for wd + wd.setDebug() + + OneOrMore(term).parseString("abc 123 xyz 890") + + prints:: + Match alphaword at loc 0(1,1) + Matched alphaword -> ['abc'] + Match alphaword at loc 3(1,4) + Exception raised:Expected alphaword (at char 4), (line:1, col:5) + Match alphaword at loc 7(1,8) + Matched alphaword -> ['xyz'] + Match alphaword at loc 11(1,12) + Exception raised:Expected alphaword (at char 12), (line:1, col:13) + Match alphaword at loc 15(1,16) + Exception raised:Expected alphaword (at char 15), (line:1, col:16) + + The output shown is that produced by the default debug actions - custom debug actions can be + specified using L{setDebugActions}. Prior to attempting + to match the C{wd} expression, the debugging message C{"Match <exprname> at loc <n>(<line>,<col>)"} + is shown. Then if the parse succeeds, a C{"Matched"} message is shown, or an C{"Exception raised"} + message is shown. Also note the use of L{setName} to assign a human-readable name to the expression, + which makes debugging and exception messages easier to understand - for instance, the default + name created for the C{Word} expression without calling C{setName} is C{"W:(ABCD...)"}. + """ + if flag: + self.setDebugActions( _defaultStartDebugAction, _defaultSuccessDebugAction, _defaultExceptionDebugAction ) + else: + self.debug = False + return self + + def __str__( self ): + return self.name + + def __repr__( self ): + return _ustr(self) + + def streamline( self ): + self.streamlined = True + self.strRepr = None + return self + + def checkRecursion( self, parseElementList ): + pass + + def validate( self, validateTrace=[] ): + """ + Check defined expressions for valid structure, check for infinite recursive definitions. + """ + self.checkRecursion( [] ) + + 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), + the entire file is opened, read, and closed before parsing. + """ + try: + file_contents = file_or_filename.read() + except AttributeError: + with open(file_or_filename, "r") as f: + file_contents = f.read() + try: + return self.parseString(file_contents, parseAll) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def __eq__(self,other): + if isinstance(other, ParserElement): + return self is other or vars(self) == vars(other) + elif isinstance(other, basestring): + return self.matches(other) + else: + return super(ParserElement,self)==other + + def __ne__(self,other): + return not (self == other) + + def __hash__(self): + return hash(id(self)) + + def __req__(self,other): + return self == other + + def __rne__(self,other): + return not (self == other) + + def matches(self, testString, parseAll=True): + """ + Method for quick testing of a parser against a test string. Good for simple + inline microtests of sub expressions while building up larger parser. + + Parameters: + - testString - to test against this expression for a match + - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests + + Example:: + expr = Word(nums) + assert expr.matches("100") + """ + try: + self.parseString(_ustr(testString), parseAll=parseAll) + return True + except ParseBaseException: + return False + + def runTests(self, tests, parseAll=True, comment='#', fullDump=True, printResults=True, failureTests=False): + """ + 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 + run a parse expression against a list of sample strings. + + Parameters: + - tests - a list of separate test strings, or a multiline string of test strings + - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests + - comment - (default=C{'#'}) - expression for indicating embedded comments in the test + string; pass None to disable comment filtering + - fullDump - (default=C{True}) - dump results as list followed by results names in nested outline; + if False, only dump nested list + - printResults - (default=C{True}) prints test output to stdout + - failureTests - (default=C{False}) indicates if these tests are expected to fail parsing + + Returns: a (success, results) tuple, where success indicates that all tests succeeded + (or failed if C{failureTests} is True), and the results contain a list of lines of each + test's output + + Example:: + number_expr = pyparsing_common.number.copy() + + result = number_expr.runTests(''' + # unsigned integer + 100 + # negative integer + -100 + # float with scientific notation + 6.02e23 + # integer with scientific notation + 1e-12 + ''') + print("Success" if result[0] else "Failed!") + + result = number_expr.runTests(''' + # stray character + 100Z + # missing leading digit before '.' + -.100 + # too many '.' + 3.14.159 + ''', failureTests=True) + print("Success" if result[0] else "Failed!") + prints:: + # unsigned integer + 100 + [100] + + # negative integer + -100 + [-100] + + # float with scientific notation + 6.02e23 + [6.02e+23] + + # integer with scientific notation + 1e-12 + [1e-12] + + Success + + # stray character + 100Z + ^ + FAIL: Expected end of text (at char 3), (line:1, col:4) + + # missing leading digit before '.' + -.100 + ^ + FAIL: Expected {real number with scientific notation | real number | signed integer} (at char 0), (line:1, col:1) + + # too many '.' + 3.14.159 + ^ + FAIL: Expected end of text (at char 4), (line:1, col:5) + + Success + + Each test string must be on a single line. If you want to test a string that spans multiple + lines, create a test like this:: + + expr.runTest(r"this is a test\\n of strings that spans \\n 3 lines") + + (Note that this is a raw string literal, you must include the leading 'r'.) + """ + if isinstance(tests, basestring): + tests = list(map(str.strip, tests.rstrip().splitlines())) + if isinstance(comment, basestring): + comment = Literal(comment) + allResults = [] + comments = [] + success = True + 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] + comments = [] + try: + t = t.replace(r'\n','\n') + result = self.parseString(t, parseAll=parseAll) + out.append(result.dump(full=fullDump)) + success = success and not failureTests + 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) + else: + out.append(' '*pe.loc + '^' + fatal) + out.append("FAIL: " + str(pe)) + success = success and failureTests + result = pe + except Exception as exc: + out.append("FAIL-EXCEPTION: " + str(exc)) + success = success and failureTests + result = exc + + if printResults: + if fullDump: + out.append('') + print('\n'.join(out)) + + allResults.append((t, result)) + + return success, allResults + + +class Token(ParserElement): + """ + Abstract C{ParserElement} subclass, for defining atomic matching patterns. + """ + 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__() + self.name = "Empty" + self.mayReturnEmpty = True + self.mayIndexError = False + + +class NoMatch(Token): + """ + A token that will never match. + """ + 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 ): + raise ParseException(instring, loc, self.errmsg, self) + + +class Literal(Token): + """ + Token to exactly match a specified string. + + Example:: + Literal('blah').parseString('blah') # -> ['blah'] + Literal('blah').parseString('blahfooblah') # -> ['blah'] + Literal('blah').parseString('bla') # -> Exception: Expected "blah" + + For case-insensitive matching, use L{CaselessLiteral}. + + For keyword matching (force word break before and after the matched string), + use L{Keyword} or L{CaselessKeyword}. + """ + def __init__( self, matchString ): + super(Literal,self).__init__() + self.match = matchString + self.matchLen = len(matchString) + try: + self.firstMatchChar = matchString[0] + except IndexError: + warnings.warn("null string passed to Literal; use Empty() instead", + SyntaxWarning, stacklevel=2) + self.__class__ = Empty + self.name = '"%s"' % _ustr(self.match) + self.errmsg = "Expected " + self.name + 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 + raise ParseException(instring, loc, self.errmsg, self) +_L = Literal +ParserElement._literalStringClass = Literal + +class Keyword(Token): + """ + Token to exactly match a specified string as a keyword, that is, it must be + immediately followed by a non-keyword character. Compare with C{L{Literal}}: + - C{Literal("if")} will match the leading C{'if'} in C{'ifAndOnlyIf'}. + - C{Keyword("if")} will not; it will only match the leading C{'if'} in C{'if x=1'}, or C{'if(y==2)'} + Accepts two optional constructor arguments in addition to the keyword string: + - C{identChars} is a string of characters that would be valid identifier characters, + defaulting to all alphanumerics + "_" and "$" + - C{caseless} allows case-insensitive matching, default is C{False}. + + Example:: + Keyword("start").parseString("start") # -> ['start'] + Keyword("start").parseString("starting") # -> Exception + + For case-insensitive matching, use L{CaselessKeyword}. + """ + DEFAULT_KEYWORD_CHARS = alphanums+"_$" + + def __init__( self, matchString, identChars=None, caseless=False ): + super(Keyword,self).__init__() + if identChars is None: + identChars = Keyword.DEFAULT_KEYWORD_CHARS + self.match = matchString + self.matchLen = len(matchString) + try: + self.firstMatchChar = matchString[0] + except IndexError: + warnings.warn("null string passed to Keyword; use Empty() instead", + SyntaxWarning, stacklevel=2) + self.name = '"%s"' % self.match + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = False + self.mayIndexError = False + self.caseless = caseless + if caseless: + self.caselessmatch = matchString.upper() + identChars = identChars.upper() + self.identChars = set(identChars) + + 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 + 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 + raise ParseException(instring, loc, self.errmsg, self) + + def copy(self): + c = super(Keyword,self).copy() + c.identChars = Keyword.DEFAULT_KEYWORD_CHARS + return c + + @staticmethod + def setDefaultKeywordChars( chars ): + """Overrides the default Keyword chars + """ + Keyword.DEFAULT_KEYWORD_CHARS = chars + +class CaselessLiteral(Literal): + """ + Token to match a specified string, ignoring case of letters. + Note: the matched results will always be in the case of the given + match string, NOT the case of the input text. + + Example:: + OneOrMore(CaselessLiteral("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD', 'CMD'] + + (Contrast with example for L{CaselessKeyword}.) + """ + 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 + raise ParseException(instring, loc, self.errmsg, self) + +class CaselessKeyword(Keyword): + """ + Caseless version of L{Keyword}. + + Example:: + OneOrMore(CaselessKeyword("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD'] + + (Contrast with example for L{CaselessLiteral}.) + """ + def __init__( self, matchString, identChars=None ): + super(CaselessKeyword,self).__init__( matchString, identChars, caseless=True ) + + def parseImpl( self, instring, loc, doActions=True ): + 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) ): + return loc+self.matchLen, self.match + raise ParseException(instring, loc, self.errmsg, self) + +class CloseMatch(Token): + """ + A variation on L{Literal} which matches "close" matches, that is, + strings with at most 'n' mismatching characters. C{CloseMatch} takes parameters: + - C{match_string} - string to be matched + - C{maxMismatches} - (C{default=1}) maximum number of mismatches allowed to count as a match + + The results from a successful parse will contain the matched text from the input string and the following named results: + - C{mismatches} - a list of the positions within the match_string where mismatches were found + - C{original} - the original match_string used to compare against the input string + + If C{mismatches} is an empty list, then the match was an exact match. + + Example:: + patt = CloseMatch("ATCATCGAATGGA") + patt.parseString("ATCATCGAAXGGA") # -> (['ATCATCGAAXGGA'], {'mismatches': [[9]], 'original': ['ATCATCGAATGGA']}) + patt.parseString("ATCAXCGAAXGGA") # -> Exception: Expected 'ATCATCGAATGGA' (with up to 1 mismatches) (at char 0), (line:1, col:1) + + # exact match + patt.parseString("ATCATCGAATGGA") # -> (['ATCATCGAATGGA'], {'mismatches': [[]], 'original': ['ATCATCGAATGGA']}) + + # close match allowing up to 2 mismatches + patt = CloseMatch("ATCATCGAATGGA", maxMismatches=2) + patt.parseString("ATCAXCGAAXGGA") # -> (['ATCAXCGAAXGGA'], {'mismatches': [[4, 9]], 'original': ['ATCATCGAATGGA']}) + """ + def __init__(self, match_string, maxMismatches=1): + super(CloseMatch,self).__init__() + self.name = match_string + self.match_string = match_string + self.maxMismatches = maxMismatches + self.errmsg = "Expected %r (with up to %d mismatches)" % (self.match_string, self.maxMismatches) + self.mayIndexError = False + self.mayReturnEmpty = False + + def parseImpl( self, instring, loc, doActions=True ): + start = loc + instrlen = len(instring) + maxloc = start + len(self.match_string) + + if maxloc <= instrlen: + match_string = self.match_string + match_stringloc = 0 + mismatches = [] + maxMismatches = self.maxMismatches + + for match_stringloc,s_m in enumerate(zip(instring[loc:maxloc], self.match_string)): + src,mat = s_m + if src != mat: + mismatches.append(match_stringloc) + if len(mismatches) > maxMismatches: + break + else: + loc = match_stringloc + 1 + results = ParseResults([instring[start:loc]]) + results['original'] = self.match_string + results['mismatches'] = mismatches + return loc, results + + raise ParseException(instring, loc, self.errmsg, self) + + +class Word(Token): + """ + Token for matching words composed of allowed character sets. + Defined with string containing all allowed initial characters, + an optional string containing allowed body characters (if omitted, + defaults to the initial character set), and an optional minimum, + maximum, and/or exact length. The default value for C{min} is 1 (a + minimum value < 1 is not valid); the default values for C{max} and C{exact} + are 0, meaning no maximum or exact length restriction. An optional + C{excludeChars} parameter can list characters that might be found in + the input C{bodyChars} string; useful to define a word of all printables + except for one or two characters, for instance. + + L{srange} is useful for defining custom character set strings for defining + C{Word} expressions, using range notation from regular expression character sets. + + A common mistake is to use C{Word} to match a specific literal string, as in + C{Word("Address")}. Remember that C{Word} uses the string argument to define + I{sets} of matchable characters. This expression would match "Add", "AAA", + "dAred", or any other word made up of the characters 'A', 'd', 'r', 'e', and 's'. + To match an exact literal string, use L{Literal} or L{Keyword}. + + pyparsing includes helper strings for building Words: + - L{alphas} + - L{nums} + - L{alphanums} + - L{hexnums} + - L{alphas8bit} (alphabetic characters in ASCII range 128-255 - accented, tilded, umlauted, etc.) + - L{punc8bit} (non-alphabetic characters in ASCII range 128-255 - currency, symbols, superscripts, diacriticals, etc.) + - L{printables} (any non-whitespace character) + + Example:: + # a word composed of digits + integer = Word(nums) # equivalent to Word("0123456789") or Word(srange("0-9")) + + # a word with a leading capital, and zero or more lowercase + capital_word = Word(alphas.upper(), alphas.lower()) + + # hostnames are alphanumeric, with leading alpha, and '-' + hostname = Word(alphas, alphanums+'-') + + # roman numeral (not a strict parser, accepts invalid mix of characters) + roman = Word("IVXLCDM") + + # 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__() + if excludeChars: + initChars = ''.join(c for c in initChars if c not in excludeChars) + if bodyChars: + bodyChars = ''.join(c for c in bodyChars if c not in excludeChars) + self.initCharsOrig = initChars + self.initChars = set(initChars) + if bodyChars : + self.bodyCharsOrig = bodyChars + self.bodyChars = set(bodyChars) + else: + self.bodyCharsOrig = initChars + self.bodyChars = set(initChars) + + self.maxSpecified = max > 0 + + if min < 1: + raise ValueError("cannot specify a minimum length < 1; use Optional(Word()) if zero-length word is permitted") + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayIndexError = False + self.asKeyword = asKeyword + + 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),) + else: + self.reString = "[%s][%s]*" % \ + (_escapeRegexRangeChars(self.initCharsOrig), + _escapeRegexRangeChars(self.bodyCharsOrig),) + if self.asKeyword: + self.reString = r"\b"+self.reString+r"\b" + try: + self.re = re.compile( self.reString ) + except Exception: + self.re = None + + 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() + + if not(instring[ loc ] in self.initChars): + raise ParseException(instring, loc, self.errmsg, self) + + start = loc + loc += 1 + instrlen = len(instring) + bodychars = self.bodyChars + maxloc = start + self.maxLen + maxloc = min( maxloc, instrlen ) + while loc < maxloc and instring[loc] in bodychars: + loc += 1 + + throwException = False + if loc - start < self.minLen: + throwException = True + if self.maxSpecified and loc < instrlen and instring[loc] in bodychars: + throwException = True + if self.asKeyword: + if (start>0 and instring[start-1] in bodychars) or (loc<instrlen and instring[loc] in bodychars): + throwException = True + + if throwException: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + def __str__( self ): + try: + return super(Word,self).__str__() + except Exception: + pass + + + if self.strRepr is None: + + def charsAsStr(s): + 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) ) + else: + self.strRepr = "W:(%s)" % charsAsStr(self.initCharsOrig) + + return self.strRepr + + +class Regex(Token): + r""" + Token for matching strings that match a given regular expression. + Defined with string specifying the regular expression in a form recognized by the inbuilt Python re module. + If the given regex contains named groups (defined using C{(?P<name>...)}), these will be preserved as + named parse results. + + Example:: + realnum = Regex(r"[+-]?\d+\.\d*") + date = Regex(r'(?P<year>\d{4})-(?P<month>\d\d?)-(?P<day>\d\d?)') + # ref: http://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?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})") + """ + compiledREtype = type(re.compile("[A-Z]")) + def __init__( self, pattern, flags=0): + """The parameters C{pattern} and C{flags} are passed to the C{re.compile()} function as-is. See the Python C{re} module for an explanation of the acceptable patterns and flags.""" + super(Regex,self).__init__() + + if isinstance(pattern, basestring): + if not pattern: + warnings.warn("null string passed to Regex; use Empty() instead", + SyntaxWarning, stacklevel=2) + + self.pattern = pattern + self.flags = flags + + try: + self.re = re.compile(self.pattern, self.flags) + self.reString = self.pattern + except sre_constants.error: + warnings.warn("invalid pattern (%s) passed to Regex" % pattern, + SyntaxWarning, stacklevel=2) + raise + + elif isinstance(pattern, Regex.compiledREtype): + self.re = pattern + self.pattern = \ + self.reString = str(pattern) + self.flags = flags + + else: + raise ValueError("Regex may only be constructed with a string or a compiled RE object") + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayIndexError = False + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + result = self.re.match(instring,loc) + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + d = result.groupdict() + ret = ParseResults(result.group()) + if d: + for k in d: + ret[k] = d[k] + return loc,ret + + def __str__( self ): + try: + return super(Regex,self).__str__() + except Exception: + pass + + if self.strRepr is None: + self.strRepr = "Re:(%s)" % repr(self.pattern) + + return self.strRepr + + +class QuotedString(Token): + r""" + Token for matching strings that are delimited by quoting characters. + + Defined with the following parameters: + - quoteChar - string of one or more characters defining the quote delimiting string + - escChar - character to escape quotes, typically backslash (default=C{None}) + - escQuote - special quote sequence to escape an embedded quote string (such as SQL's "" to escape an embedded ") (default=C{None}) + - multiline - boolean indicating whether quotes can span multiple lines (default=C{False}) + - unquoteResults - boolean indicating whether the matched text should be unquoted (default=C{True}) + - endQuoteChar - string of one or more characters defining the end of the quote delimited string (default=C{None} => same as quoteChar) + - convertWhitespaceEscapes - convert escaped whitespace (C{'\t'}, C{'\n'}, etc.) to actual whitespace (default=C{True}) + + Example:: + qs = QuotedString('"') + print(qs.searchString('lsjdf "This is the quote" sldjf')) + complex_qs = QuotedString('{{', endQuoteChar='}}') + print(complex_qs.searchString('lsjdf {{This is the "quote"}} sldjf')) + sql_qs = QuotedString('"', escQuote='""') + print(sql_qs.searchString('lsjdf "This is the quote with ""embedded"" quotes" sldjf')) + prints:: + [['This is the quote']] + [['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__() + + # 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) + raise SyntaxError() + + if endQuoteChar is None: + endQuoteChar = quoteChar + else: + endQuoteChar = endQuoteChar.strip() + if not endQuoteChar: + warnings.warn("endQuoteChar cannot be the empty string",SyntaxWarning,stacklevel=2) + raise SyntaxError() + + self.quoteChar = quoteChar + self.quoteCharLen = len(quoteChar) + self.firstQuoteChar = quoteChar[0] + self.endQuoteChar = endQuoteChar + self.endQuoteCharLen = len(endQuoteChar) + self.escChar = escChar + self.escQuote = escQuote + self.unquoteResults = unquoteResults + self.convertWhitespaceEscapes = convertWhitespaceEscapes + + 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 '') ) + 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 '') ) + 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)) + ')' + ) + 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.pattern += (r')*%s' % re.escape(self.endQuoteChar)) + + try: + self.re = re.compile(self.pattern, self.flags) + self.reString = self.pattern + except sre_constants.error: + warnings.warn("invalid pattern (%s) passed to Regex" % self.pattern, + SyntaxWarning, stacklevel=2) + raise + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + 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 + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + ret = result.group() + + if self.unquoteResults: + + # strip off quotes + ret = ret[self.quoteCharLen:-self.endQuoteCharLen] + + 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', + } + for wslit,wschar in ws_map.items(): + ret = ret.replace(wslit, wschar) + + # replace escaped characters + if self.escChar: + ret = re.sub(self.escCharReplacePattern, r"\g<1>", ret) + + # replace escaped quotes + if self.escQuote: + ret = ret.replace(self.escQuote, self.endQuoteChar) + + return loc, ret + + def __str__( self ): + try: + return super(QuotedString,self).__str__() + except Exception: + pass + + if self.strRepr is None: + self.strRepr = "quoted string, starting with %s ending with %s" % (self.quoteChar, self.endQuoteChar) + + return self.strRepr + + +class CharsNotIn(Token): + """ + Token for matching words composed of characters I{not} in a given set (will + include whitespace in matched characters if not listed in the provided exclusion set - see example). + Defined with string containing all disallowed characters, and an optional + minimum, maximum, and/or exact length. The default value for C{min} is 1 (a + minimum value < 1 is not valid); the default values for C{max} and C{exact} + are 0, meaning no maximum or exact length restriction. + + Example:: + # define a comma-separated-value as anything that is not a ',' + csv_value = CharsNotIn(',') + print(delimitedList(csv_value).parseString("dkls,lsdkjf,s12 34,@!#,213")) + prints:: + ['dkls', 'lsdkjf', 's12 34', '@!#', '213'] + """ + 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") + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = ( self.minLen == 0 ) + self.mayIndexError = False + + 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): + loc += 1 + + if loc - start < self.minLen: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + def __str__( self ): + try: + return super(CharsNotIn, self).__str__() + except Exception: + pass + + if self.strRepr is None: + if len(self.notChars) > 4: + self.strRepr = "!W:(%s...)" % self.notChars[:4] + else: + self.strRepr = "!W:(%s)" % self.notChars + + return self.strRepr + +class White(Token): + """ + Special matching class for matching whitespace. Normally, whitespace is ignored + by pyparsing grammars. This class is included when some whitespace structures + are significant. Define with a string containing the whitespace characters to be + matched; default is C{" \\t\\r\\n"}. Also takes optional C{min}, C{max}, and C{exact} arguments, + as defined for the C{L{Word}} class. + """ + whiteStrs = { + " " : "<SPC>", + "\t": "<TAB>", + "\n": "<LF>", + "\r": "<CR>", + "\f": "<FF>", + } + def __init__(self, ws=" \t\r\n", min=1, max=0, exact=0): + 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.name = ("".join(White.whiteStrs[c] for c in self.matchWhite)) + self.mayReturnEmpty = True + self.errmsg = "Expected " + self.name + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + def parseImpl( self, instring, loc, doActions=True ): + if not(instring[ loc ] in self.matchWhite): + raise ParseException(instring, loc, self.errmsg, self) + start = loc + loc += 1 + maxloc = start + self.maxLen + maxloc = min( maxloc, len(instring) ) + while loc < maxloc and instring[loc] in self.matchWhite: + loc += 1 + + if loc - start < self.minLen: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + +class _PositionToken(Token): + def __init__( self ): + super(_PositionToken,self).__init__() + self.name=self.__class__.__name__ + self.mayReturnEmpty = True + self.mayIndexError = False + +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__() + self.col = colno + + 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 += 1 + return loc + + 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 ) + newloc = loc + self.col - thiscol + ret = instring[ loc: newloc ] + return newloc, ret + + +class LineStart(_PositionToken): + """ + Matches if current position is at the beginning of a line within the parse string + + Example:: + + test = '''\ + AAA this line + AAA and this line + AAA but not this one + B AAA and definitely not this one + ''' + + for t in (LineStart() + 'AAA' + restOfLine).searchString(test): + print(t) + + Prints:: + ['AAA', ' this line'] + ['AAA', ' and this line'] + + """ + def __init__( self ): + super(LineStart,self).__init__() + self.errmsg = "Expected start of line" + + def parseImpl( self, instring, loc, doActions=True ): + if col(loc, instring) == 1: + return loc, [] + raise ParseException(instring, loc, self.errmsg, self) + +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","") ) + self.errmsg = "Expected end of line" + + def parseImpl( self, instring, loc, doActions=True ): + if loc<len(instring): + if instring[loc] == "\n": + return loc+1, "\n" + else: + raise ParseException(instring, loc, self.errmsg, self) + elif loc == len(instring): + return loc+1, [] + else: + raise ParseException(instring, loc, self.errmsg, self) + +class StringStart(_PositionToken): + """ + Matches if current position is at the beginning of the parse string + """ + def __init__( self ): + super(StringStart,self).__init__() + self.errmsg = "Expected start of text" + + 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 ): + 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__() + self.errmsg = "Expected end of text" + + 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, [] + elif loc > len(instring): + return loc, [] + else: + raise ParseException(instring, loc, self.errmsg, self) + +class WordStart(_PositionToken): + """ + Matches if the current position is at the beginning of a Word, and + is not preceded by any character in a given set of C{wordChars} + (default=C{printables}). To emulate the C{\b} behavior of regular expressions, + use C{WordStart(alphanums)}. C{WordStart} will also match at the beginning of + the string being parsed, or at the beginning of a line. + """ + 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 ): + if loc != 0: + if (instring[loc-1] in self.wordChars or + instring[loc] not in self.wordChars): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + +class WordEnd(_PositionToken): + """ + Matches if the current position is at the end of a Word, and + is not followed by any character in a given set of C{wordChars} + (default=C{printables}). To emulate the C{\b} behavior of regular expressions, + use C{WordEnd(alphanums)}. C{WordEnd} 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__() + self.wordChars = set(wordChars) + self.skipWhitespace = False + self.errmsg = "Not at the end of a word" + + def parseImpl(self, instring, loc, doActions=True ): + instrlen = len(instring) + if instrlen>0 and loc<instrlen: + if (instring[loc] in self.wordChars or + instring[loc-1] not in self.wordChars): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + + +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 ): + exprs = list(exprs) + + if isinstance( exprs, basestring ): + self.exprs = [ ParserElement._literalStringClass( 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) + self.exprs = list(exprs) + else: + try: + self.exprs = list( exprs ) + except TypeError: + self.exprs = [ exprs ] + self.callPreparse = False + + def __getitem__( self, i ): + return self.exprs[i] + + def append( self, other ): + self.exprs.append( other ) + self.strRepr = None + return self + + def leaveWhitespace( self ): + """Extends C{leaveWhitespace} defined in base class, and also invokes C{leaveWhitespace} on + all contained expressions.""" + self.skipWhitespace = False + 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 ): + if other not in self.ignoreExprs: + super( ParseExpression, self).ignore( other ) + for e in self.exprs: + e.ignore( self.ignoreExprs[-1] ) + else: + super( ParseExpression, self).ignore( other ) + for e in self.exprs: + e.ignore( self.ignoreExprs[-1] ) + return self + + def __str__( self ): + try: + return super(ParseExpression,self).__str__() + except Exception: + pass + + if self.strRepr is None: + self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.exprs) ) + return self.strRepr + + 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 ) + # 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 ): + 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] ] + 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 ): + self.exprs = self.exprs[:-1] + other.exprs[:] + self.strRepr = None + self.mayReturnEmpty |= other.mayReturnEmpty + self.mayIndexError |= other.mayIndexError + + self.errmsg = "Expected " + _ustr(self) + + return self + + def setResultsName( self, name, listAllMatches=False ): + ret = super(ParseExpression,self).setResultsName(name,listAllMatches) + return ret + + def validate( self, validateTrace=[] ): + tmp = validateTrace[:]+[self] + for e in self.exprs: + e.validate(tmp) + self.checkRecursion( [] ) + + def copy(self): + ret = super(ParseExpression,self).copy() + ret.exprs = [e.copy() for e in self.exprs] + return ret + +class And(ParseExpression): + """ + Requires all given C{ParseExpression}s to be found in the given order. + Expressions may be separated by whitespace. + May be constructed using the C{'+'} operator. + May also be constructed using the C{'-'} operator, which will suppress backtracking. + + Example:: + integer = Word(nums) + name_expr = OneOrMore(Word(alphas)) + + 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) + self.name = '-' + self.leaveWhitespace() + + def __init__( self, exprs, savelist = True ): + super(And,self).__init__(exprs, savelist) + self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) + self.setWhitespaceChars( self.exprs[0].whiteChars ) + self.skipWhitespace = self.exprs[0].skipWhitespace + self.callPreparse = 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 ) + errorStop = False + for e in self.exprs[1:]: + if isinstance(e, And._ErrorStop): + errorStop = True + continue + if errorStop: + try: + loc, exprtokens = e._parse( instring, loc, doActions ) + except ParseSyntaxException: + raise + except ParseBaseException as pe: + pe.__traceback__ = None + raise ParseSyntaxException._from_exception(pe) + except IndexError: + raise ParseSyntaxException(instring, len(instring), self.errmsg, self) + else: + 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 checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + if not e.mayReturnEmpty: + break + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + +class Or(ParseExpression): + """ + Requires that at least one C{ParseExpression} is found. + If two expressions match, the expression that matches the longest string will be used. + May be constructed using the C{'^'} operator. + + Example:: + # construct Or using '^' operator + + number = Word(nums) ^ Combine(Word(nums) + '.' + Word(nums)) + print(number.searchString("123 3.1416 789")) + prints:: + [['123'], ['3.1416'], ['789']] + """ + 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: + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + maxExcLoc = -1 + maxException = None + matches = [] + for e in self.exprs: + try: + loc2 = e.tryParse( instring, loc ) + except ParseException as err: + err.__traceback__ = None + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + except IndexError: + if len(instring) > maxExcLoc: + 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: + try: + return e._parse( instring, loc, doActions ) + except ParseException as err: + err.__traceback__ = None + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + + if maxException is not None: + maxException.msg = self.errmsg + raise maxException + else: + 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 __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " ^ ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class MatchFirst(ParseExpression): + """ + Requires that at least one C{ParseExpression} is found. + If two expressions match, the first one listed is the one that will match. + May be constructed using the C{'|'} operator. + + Example:: + # construct MatchFirst using '|' operator + + # watch the order of expressions to match + number = Word(nums) | Combine(Word(nums) + '.' + Word(nums)) + print(number.searchString("123 3.1416 789")) # Fail! -> [['123'], ['3'], ['1416'], ['789']] + + # put more selective expression first + 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) + if self.exprs: + self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs) + else: + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + maxExcLoc = -1 + maxException = None + for e in self.exprs: + try: + ret = e._parse( instring, loc, doActions ) + return ret + except ParseException as err: + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + except IndexError: + if len(instring) > maxExcLoc: + 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 + else: + if maxException is not None: + maxException.msg = self.errmsg + raise maxException + 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 __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " | ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class Each(ParseExpression): + """ + Requires all given C{ParseExpression}s to be found, but in any order. + Expressions may be separated by whitespace. + May be constructed using the C{'&'} operator. + + Example:: + color = oneOf("RED ORANGE YELLOW GREEN BLUE PURPLE BLACK WHITE BROWN") + shape_type = oneOf("SQUARE CIRCLE TRIANGLE STAR HEXAGON OCTAGON") + integer = Word(nums) + shape_attr = "shape:" + shape_type("shape") + posn_attr = "posn:" + Group(integer("x") + ',' + integer("y"))("posn") + color_attr = "color:" + color("color") + size_attr = "size:" + integer("size") + + # use Each (using operator '&') to accept attributes in any order + # (shape and posn are required, color and size are optional) + shape_spec = shape_attr & posn_attr & Optional(color_attr) & Optional(size_attr) + + shape_spec.runTests(''' + shape: SQUARE color: BLACK posn: 100, 120 + shape: CIRCLE size: 50 color: BLUE posn: 50,80 + color:GREEN size:20 shape:TRIANGLE posn:20,40 + ''' + ) + prints:: + shape: SQUARE color: BLACK posn: 100, 120 + ['shape:', 'SQUARE', 'color:', 'BLACK', 'posn:', ['100', ',', '120']] + - color: BLACK + - posn: ['100', ',', '120'] + - x: 100 + - y: 120 + - shape: SQUARE + + + shape: CIRCLE size: 50 color: BLUE posn: 50,80 + ['shape:', 'CIRCLE', 'size:', '50', 'color:', 'BLUE', 'posn:', ['50', ',', '80']] + - color: BLUE + - posn: ['50', ',', '80'] + - x: 50 + - y: 80 + - shape: CIRCLE + - size: 50 + + + color: GREEN size: 20 shape: TRIANGLE posn: 20,40 + ['color:', 'GREEN', 'size:', '20', 'shape:', 'TRIANGLE', 'posn:', ['20', ',', '40']] + - color: GREEN + - posn: ['20', ',', '40'] + - x: 20 + - y: 40 + - shape: TRIANGLE + - size: 20 + """ + 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 + + 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.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.required += self.multirequired + self.initExprGroups = False + tmpLoc = loc + tmpReqd = self.required[:] + tmpOpt = self.optionals[:] + matchOrder = [] + + keepMatching = True + while keepMatching: + tmpExprs = tmpReqd + tmpOpt + self.multioptionals + self.multirequired + failed = [] + for e in tmpExprs: + try: + tmpLoc = e.tryParse( instring, tmpLoc ) + except ParseException: + failed.append(e) + else: + matchOrder.append(self.opt1map.get(id(e),e)) + if e in tmpReqd: + tmpReqd.remove(e) + elif e in tmpOpt: + tmpOpt.remove(e) + if len(failed) == len(tmpExprs): + keepMatching = False + + if tmpReqd: + missing = ", ".join(_ustr(e) for e in tmpReqd) + 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] + + resultlist = [] + for e in matchOrder: + loc,results = e._parse(instring,loc,doActions) + resultlist.append(results) + + finalResults = sum(resultlist, ParseResults([])) + return loc, finalResults + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " & ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class ParseElementEnhance(ParserElement): + """ + Abstract subclass of C{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) + else: + expr = ParserElement._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.skipWhitespace = expr.skipWhitespace + self.saveAsList = expr.saveAsList + self.callPreparse = expr.callPreparse + self.ignoreExprs.extend(expr.ignoreExprs) + + def parseImpl( self, instring, loc, doActions=True ): + if self.expr is not None: + return self.expr._parse( instring, loc, doActions, callPreParse=False ) + else: + raise ParseException("",loc,self.errmsg,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 ): + if other not in self.ignoreExprs: + super( ParseElementEnhance, self).ignore( other ) + if self.expr is not None: + self.expr.ignore( self.ignoreExprs[-1] ) + else: + super( ParseElementEnhance, self).ignore( other ) + if self.expr is not None: + self.expr.ignore( self.ignoreExprs[-1] ) + return self + + def streamline( self ): + super(ParseElementEnhance,self).streamline() + if self.expr is not None: + self.expr.streamline() + return self + + def checkRecursion( self, parseElementList ): + if self in parseElementList: + raise RecursiveGrammarException( parseElementList+[self] ) + subRecCheckList = parseElementList[:] + [ self ] + if self.expr is not None: + self.expr.checkRecursion( subRecCheckList ) + + def validate( self, validateTrace=[] ): + tmp = validateTrace[:]+[self] + if self.expr is not None: + self.expr.validate(tmp) + self.checkRecursion( [] ) + + def __str__( self ): + try: + 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) ) + return self.strRepr + + +class FollowedBy(ParseElementEnhance): + """ + Lookahead matching of the given parse expression. C{FollowedBy} + does I{not} advance the parsing position within the input string, it only + verifies that the specified parse expression matches at the current + position. C{FollowedBy} always returns a null token list. + + Example:: + # use FollowedBy to match a label only if it is followed by a ':' + data_word = Word(alphas) + label = data_word + FollowedBy(':') + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + + OneOrMore(attr_expr).parseString("shape: SQUARE color: BLACK posn: upper left").pprint() + prints:: + [['shape', 'SQUARE'], ['color', 'BLACK'], ['posn', 'upper left']] + """ + def __init__( self, expr ): + super(FollowedBy,self).__init__(expr) + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + self.expr.tryParse( instring, loc ) + return loc, [] + + +class NotAny(ParseElementEnhance): + """ + Lookahead to disallow matching with the given parse expression. C{NotAny} + does I{not} advance the parsing position within the input string, it only + verifies that the specified parse expression does I{not} match at the current + position. Also, C{NotAny} does I{not} skip over leading whitespace. C{NotAny} + always returns a null token list. May be constructed using the '~' operator. + + Example:: + + """ + 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) + + 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"): + return self.name + + if self.strRepr is None: + self.strRepr = "~{" + _ustr(self.expr) + "}" + + return self.strRepr + +class _MultipleMatch(ParseElementEnhance): + 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 + + 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 + if check_ender: + try_not_ender = self.not_ender.tryParse + + # must be at least one (but first see if we are the stopOn sentinel; + # if so, fail) + if check_ender: + try_not_ender(instring, loc) + 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 ) + else: + preloc = loc + loc, tmptokens = self_expr_parse( instring, preloc, doActions ) + if tmptokens or tmptokens.haskeys(): + tokens += tmptokens + except (ParseException,IndexError): + pass + + return loc, tokens + +class OneOrMore(_MultipleMatch): + """ + Repetition of one or more of the given expression. + + Parameters: + - expr - expression that must match one or more times + - stopOn - (default=C{None}) - expression for a terminating sentinel + (only required if the sentinel would ordinarily match the repetition + expression) + + Example:: + data_word = Word(alphas) + label = data_word + FollowedBy(':') + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join)) + + text = "shape: SQUARE posn: upper left color: BLACK" + OneOrMore(attr_expr).parseString(text).pprint() # Fail! read 'color' as data instead of next label -> [['shape', 'SQUARE color']] + + # use stopOn attribute for OneOrMore to avoid reading label string as part of the data + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + OneOrMore(attr_expr).parseString(text).pprint() # Better -> [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'BLACK']] + + # could also be written as + (attr_expr * (1,)).parseString(text).pprint() + """ + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + _ustr(self.expr) + "}..." + + return self.strRepr + +class ZeroOrMore(_MultipleMatch): + """ + Optional repetition of zero or more of the given expression. + + Parameters: + - expr - expression that must match zero or more times + - stopOn - (default=C{None}) - expression for a terminating sentinel + (only required if the sentinel would ordinarily match the repetition + expression) + + Example: similar to L{OneOrMore} + """ + def __init__( self, expr, stopOn=None): + super(ZeroOrMore,self).__init__(expr, stopOn=stopOn) + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + try: + return super(ZeroOrMore, self).parseImpl(instring, loc, doActions) + except (ParseException,IndexError): + return loc, [] + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "[" + _ustr(self.expr) + "]..." + + return self.strRepr + +class _NullToken(object): + def __bool__(self): + return False + __nonzero__ = __bool__ + def __str__(self): + return "" + +_optionalNotMatched = _NullToken() +class Optional(ParseElementEnhance): + """ + Optional matching of the given expression. + + Parameters: + - expr - expression that must match zero or more times + - default (optional) - value to be returned if the optional expression is not found. + + Example:: + # US postal code can be a 5-digit zip, plus optional 4-digit qualifier + zip = Combine(Word(nums, exact=5) + Optional('-' + Word(nums, exact=4))) + zip.runTests(''' + # traditional ZIP code + 12345 + + # ZIP+4 form + 12101-0001 + + # invalid ZIP + 98765- + ''') + prints:: + # traditional ZIP code + 12345 + ['12345'] + + # ZIP+4 form + 12101-0001 + ['12101-0001'] + + # invalid ZIP + 98765- + ^ + 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 ) + self.saveAsList = self.expr.saveAsList + self.defaultValue = default + self.mayReturnEmpty = 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: + if self.expr.resultsName: + tokens = ParseResults([ self.defaultValue ]) + tokens[self.expr.resultsName] = self.defaultValue + else: + tokens = [ self.defaultValue ] + else: + tokens = [] + return loc, tokens + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "[" + _ustr(self.expr) + "]" + + return self.strRepr + +class SkipTo(ParseElementEnhance): + """ + Token for skipping over all undefined text until the matched expression is found. + + Parameters: + - expr - target expression marking the end of the data to be skipped + - include - (default=C{False}) if True, the target expression is also parsed + (the skipped text and target expression are returned as a 2-element list). + - ignore - (default=C{None}) used to define grammars (typically quoted strings and + comments) that might contain false matches to the target expression + - failOn - (default=C{None}) define expressions that are not allowed to be + included in the skipped test; if found before the target expression is found, + the SkipTo is not a match + + Example:: + report = ''' + Outstanding Issues Report - 1 Jan 2000 + + # | Severity | Description | Days Open + -----+----------+-------------------------------------------+----------- + 101 | Critical | Intermittent system crash | 6 + 94 | Cosmetic | Spelling error on Login ('log|n') | 14 + 79 | Minor | System slow when running too many reports | 47 + ''' + integer = Word(nums) + SEP = Suppress('|') + # use SkipTo to simply match everything up until the next SEP + # - ignore quoted strings, so that a '|' character inside a quoted string does not match + # - parse action will call token.strip() for each matched token, i.e., the description body + string_data = SkipTo(SEP, ignore=quotedString) + string_data.setParseAction(tokenMap(str.strip)) + ticket_expr = (integer("issue_num") + SEP + + string_data("sev") + SEP + + string_data("desc") + SEP + + integer("days_open")) + + for tkt in ticket_expr.searchString(report): + print tkt.dump() + prints:: + ['101', 'Critical', 'Intermittent system crash', '6'] + - days_open: 6 + - desc: Intermittent system crash + - issue_num: 101 + - sev: Critical + ['94', 'Cosmetic', "Spelling error on Login ('log|n')", '14'] + - days_open: 14 + - desc: Spelling error on Login ('log|n') + - issue_num: 94 + - sev: Cosmetic + ['79', 'Minor', 'System slow when running too many reports', '47'] + - days_open: 47 + - desc: System slow when running too many reports + - issue_num: 79 + - sev: Minor + """ + 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.asList = False + if isinstance(failOn, basestring): + self.failOn = ParserElement._literalStringClass(failOn) + else: + self.failOn = failOn + self.errmsg = "No match found for "+_ustr(self.expr) + + def parseImpl( self, instring, loc, doActions=True ): + startloc = loc + instrlen = len(instring) + expr = self.expr + expr_parse = self.expr._parse + self_failOn_canParseNext = self.failOn.canParseNext if self.failOn is not None else None + self_ignoreExpr_tryParse = self.ignoreExpr.tryParse if self.ignoreExpr is not None else None + + tmploc = loc + while tmploc <= instrlen: + if self_failOn_canParseNext is not None: + # break if failOn expression matches + if self_failOn_canParseNext(instring, tmploc): + break + + if self_ignoreExpr_tryParse is not None: + # advance past ignore expressions + while 1: + try: + tmploc = self_ignoreExpr_tryParse(instring, tmploc) + except ParseBaseException: + break + + try: + expr_parse(instring, tmploc, doActions=False, callPreParse=False) + except (ParseException, IndexError): + # no match, advance loc in string + tmploc += 1 + else: + # matched skipto expr, done + break + + else: + # ran off the end of the input string without matching skipto expr, fail + raise ParseException(instring, loc, self.errmsg, self) + + # build up return values + loc = tmploc + skiptext = instring[startloc:loc] + skipresult = ParseResults(skiptext) + + if self.includeMatch: + loc, mat = expr_parse(instring,loc,doActions,callPreParse=False) + skipresult += mat + + return loc, skipresult + +class Forward(ParseElementEnhance): + """ + Forward declaration of an expression to be defined later - + used for recursive grammars, such as algebraic infix notation. + When the expression is known, it is assigned to the C{Forward} variable using the '<<' operator. + + Note: take care when assigning to C{Forward} not to overlook precedence of operators. + Specifically, '|' has a lower precedence than '<<', so that:: + fwdExpr << a | b | c + will actually be evaluated as:: + (fwdExpr << a) | b | c + thereby leaving b and c out as parseable alternatives. It is recommended that you + explicitly group the values inserted into the C{Forward}:: + fwdExpr << (a | b | c) + Converting to use the '<<=' operator instead will avoid this problem. + + See L{ParseResults.pprint} for an example of a recursive parser created using + C{Forward}. + """ + def __init__( self, other=None ): + super(Forward,self).__init__( other, savelist=False ) + + def __lshift__( self, other ): + if isinstance( other, basestring ): + other = ParserElement._literalStringClass(other) + self.expr = other + self.strRepr = None + self.mayIndexError = self.expr.mayIndexError + self.mayReturnEmpty = self.expr.mayReturnEmpty + self.setWhitespaceChars( self.expr.whiteChars ) + self.skipWhitespace = self.expr.skipWhitespace + self.saveAsList = self.expr.saveAsList + self.ignoreExprs.extend(self.expr.ignoreExprs) + return self + + def __ilshift__(self, other): + return self << other + + def leaveWhitespace( self ): + self.skipWhitespace = False + return 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=[] ): + if self not in validateTrace: + tmp = validateTrace[:]+[self] + if self.expr is not None: + self.expr.validate(tmp) + self.checkRecursion([]) + + def __str__( self ): + if hasattr(self,"name"): + return self.name + return self.__class__.__name__ + ": ..." + + # stubbed out for now - creates awful memory and perf issues + self._revertClass = self.__class__ + self.__class__ = _ForwardNoRecurse + try: + if self.expr is not None: + retString = _ustr(self.expr) + else: + retString = "None" + finally: + self.__class__ = self._revertClass + return self.__class__.__name__ + ": " + retString + + def copy(self): + if self.expr is not None: + return super(Forward,self).copy() + else: + ret = Forward() + ret <<= self + return ret + +class _ForwardNoRecurse(Forward): + def __str__( self ): + return "..." + +class TokenConverter(ParseElementEnhance): + """ + Abstract subclass of C{ParseExpression}, for converting parsed results. + """ + def __init__( self, expr, savelist=False ): + super(TokenConverter,self).__init__( expr )#, savelist ) + self.saveAsList = False + +class Combine(TokenConverter): + """ + Converter to concatenate all matching tokens to a single string. + By default, the matching patterns must also be contiguous in the input string; + this can be disabled by specifying C{'adjacent=False'} in the constructor. + + Example:: + real = Word(nums) + '.' + Word(nums) + print(real.parseString('3.1416')) # -> ['3', '.', '1416'] + # will also erroneously match the following + print(real.parseString('3. 1416')) # -> ['3', '.', '1416'] + + real = Combine(Word(nums) + '.' + Word(nums)) + print(real.parseString('3.1416')) # -> ['3.1416'] + # 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 ) + # suppress whitespace-stripping in contained parse expressions, but re-enable it on the Combine itself + if adjacent: + self.leaveWhitespace() + self.adjacent = adjacent + self.skipWhitespace = True + self.joinString = joinString + self.callPreparse = True + + def ignore( self, other ): + if self.adjacent: + ParserElement.ignore(self, other) + else: + super( Combine, self).ignore( other ) + return self + + def postParse( self, instring, loc, tokenlist ): + retToks = tokenlist.copy() + del retToks[:] + retToks += ParseResults([ "".join(tokenlist._asStringList(self.joinString)) ], modal=self.modalResults) + + if self.resultsName and retToks.haskeys(): + return [ retToks ] + else: + return retToks + +class Group(TokenConverter): + """ + Converter to return the matched tokens as a list - useful for returning tokens of C{L{ZeroOrMore}} and C{L{OneOrMore}} expressions. + + Example:: + ident = Word(alphas) + num = Word(nums) + term = ident | num + func = ident + Optional(delimitedList(term)) + 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']] + """ + def __init__( self, expr ): + super(Group,self).__init__( expr ) + self.saveAsList = True + + def postParse( self, instring, loc, tokenlist ): + return [ tokenlist ] + +class Dict(TokenConverter): + """ + Converter to return a repetitive expression as a list, but also as a dictionary. + Each element can also be referenced using the first token in the expression as its key. + Useful for tabular report scraping when the first column can be used as a item key. + + Example:: + data_word = Word(alphas) + label = data_word + FollowedBy(':') + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join)) + + text = "shape: SQUARE posn: upper left color: light blue texture: burlap" + attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + + # print attributes as plain groups + print(OneOrMore(attr_expr).parseString(text).dump()) + + # instead of OneOrMore(expr), parse using Dict(OneOrMore(Group(expr))) - Dict will auto-assign names + result = Dict(OneOrMore(Group(attr_expr))).parseString(text) + print(result.dump()) + + # access named fields as dict entries, or output as dict + print(result['shape']) + print(result.asDict()) + prints:: + ['shape', 'SQUARE', 'posn', 'upper left', 'color', 'light blue', 'texture', 'burlap'] + + [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']] + - color: light blue + - posn: upper left + - shape: SQUARE + - texture: burlap + SQUARE + {'color': 'light blue', 'posn': 'upper left', 'texture': 'burlap', 'shape': 'SQUARE'} + See more examples at L{ParseResults} of accessing fields by results name. + """ + def __init__( self, expr ): + super(Dict,self).__init__( expr ) + self.saveAsList = True + + def postParse( self, instring, loc, tokenlist ): + for i,tok in enumerate(tokenlist): + if len(tok) == 0: + continue + ikey = tok[0] + 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) + else: + dictvalue = tok.copy() #ParseResults(i) + del dictvalue[0] + if len(dictvalue)!= 1 or (isinstance(dictvalue,ParseResults) and dictvalue.haskeys()): + tokenlist[ikey] = _ParseResultsWithOffset(dictvalue,i) + else: + tokenlist[ikey] = _ParseResultsWithOffset(dictvalue[0],i) + + if self.resultsName: + return [ tokenlist ] + else: + return tokenlist + + +class Suppress(TokenConverter): + """ + Converter for ignoring the results of a parsed expression. + + Example:: + source = "a, b, c,d" + wd = Word(alphas) + wd_list1 = wd + ZeroOrMore(',' + wd) + print(wd_list1.parseString(source)) + + # often, delimiters that are useful during parsing are just in the + # way afterward - use Suppress to keep them out of the parsed output + wd_list2 = wd + ZeroOrMore(Suppress(',') + wd) + print(wd_list2.parseString(source)) + prints:: + ['a', ',', 'b', ',', 'c', ',', 'd'] + ['a', 'b', 'c', 'd'] + (See also L{delimitedList}.) + """ + def postParse( self, instring, loc, tokenlist ): + return [] + + def suppress( self ): + return self + + +class OnlyOnce(object): + """ + Wrapper for parse actions, to ensure they are only called once. + """ + def __init__(self, methodCall): + self.callable = _trim_arity(methodCall) + self.called = False + def __call__(self,s,l,t): + if not self.called: + results = self.callable(s,l,t) + self.called = True + return results + raise ParseException(s,l,"") + def reset(self): + self.called = False + +def traceParseAction(f): + """ + Decorator for debugging parse actions. + + When the parse action is called, this decorator will print C{">> entering I{method-name}(line:I{current_source_line}, I{parse_location}, I{matched_tokens})".} + When the parse action completes, the decorator will print C{"<<"} followed by the returned value, or any exception that the parse action raised. + + Example:: + wd = Word(alphas) + + @traceParseAction + def remove_duplicate_chars(tokens): + return ''.join(sorted(set(''.join(tokens)))) + + wds = OneOrMore(wd).setParseAction(remove_duplicate_chars) + print(wds.parseString("slkdjs sld sldd sdlf sdljf")) + prints:: + >>entering remove_duplicate_chars(line: 'slkdjs sld sldd sdlf sdljf', 0, (['slkdjs', 'sld', 'sldd', 'sdlf', 'sdljf'], {})) + <<leaving remove_duplicate_chars (ret: 'dfjkls') + ['dfjkls'] + """ + f = _trim_arity(f) + def z(*paArgs): + thisFunc = f.__name__ + 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) ) + try: + ret = f(*paArgs) + except Exception as exc: + sys.stderr.write( "<<leaving %s (exception: %s)\n" % (thisFunc,exc) ) + raise + sys.stderr.write( "<<leaving %s (ret: %r)\n" % (thisFunc,ret) ) + return ret + try: + z.__name__ = f.__name__ + except AttributeError: + pass + return z + +# +# global helpers +# +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 overridden by passing C{combine=True} in the constructor. + If C{combine} is set to C{True}, the matching tokens are returned as a single token + string, with the delimiters included; otherwise, the matching tokens are returned + as a list of tokens, with the delimiters suppressed. + + Example:: + 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)+"]..." + if combine: + return Combine( expr + ZeroOrMore( delim + expr ) ).setName(dlName) + else: + return ( expr + ZeroOrMore( Suppress( delim ) + expr ) ).setName(dlName) + +def countedArray( expr, intExpr=None ): + """ + Helper to define a counted list of expressions. + This helper defines a pattern of the form:: + integer expr expr expr... + where the leading integer tells how many expr expressions follow. + The matched tokens returns the array of expr tokens as a list - the leading count token is suppressed. + + If C{intExpr} is specified, it should be a pyparsing expression that produces an integer value. + + Example:: + countedArray(Word(alphas)).parseString('2 ab cd ef') # -> ['ab', 'cd'] + + # in this parser, the leading integer value is given in binary, + # '10' indicating that 2 values are in the array + binaryConstant = Word('01').setParseAction(lambda t: int(t[0], 2)) + countedArray(Word(alphas), intExpr=binaryConstant).parseString('10 ab cd ef') # -> ['ab', 'cd'] + """ + arrayExpr = Forward() + def countFieldParseAction(s,l,t): + n = t[0] + arrayExpr << (n and Group(And([expr]*n)) or Group(empty)) + return [] + if intExpr is None: + 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) + '...') + +def _flatten(L): + ret = [] + for i in L: + if isinstance(i,list): + ret.extend(_flatten(i)) + else: + ret.append(i) + return ret + +def matchPreviousLiteral(expr): + """ + Helper to define an expression that is indirectly defined from + the tokens matched in a previous expression, that is, it looks + for a 'repeat' of a previous expression. For example:: + first = Word(nums) + second = matchPreviousLiteral(first) + matchExpr = first + ":" + second + will match C{"1:1"}, but not C{"1:2"}. Because this matches a + previous literal, will also match the leading C{"1:1"} in C{"1:10"}. + If this is not desired, use C{matchPreviousExpr}. + Do I{not} use with packrat parsing enabled. + """ + rep = Forward() + def copyTokenToRepeater(s,l,t): + if t: + if len(t) == 1: + rep << t[0] + else: + # flatten t tokens + tflat = _flatten(t.asList()) + rep << And(Literal(tt) for tt in tflat) + else: + rep << Empty() + expr.addParseAction(copyTokenToRepeater, callDuringTry=True) + rep.setName('(prev) ' + _ustr(expr)) + return rep + +def matchPreviousExpr(expr): + """ + Helper to define an expression that is indirectly defined from + the tokens matched in a previous expression, that is, it looks + for a 'repeat' of a previous expression. For example:: + first = Word(nums) + second = matchPreviousExpr(first) + matchExpr = first + ":" + second + will match C{"1:1"}, but not C{"1:2"}. Because this matches by + expressions, will I{not} match the leading C{"1:1"} in C{"1:10"}; + the expressions are evaluated first, and then compared, so + C{"1"} is compared with C{"10"}. + Do I{not} use with packrat parsing enabled. + """ + rep = Forward() + e2 = expr.copy() + rep <<= e2 + def copyTokenToRepeater(s,l,t): + matchTokens = _flatten(t.asList()) + def mustMatchTheseTokens(s,l,t): + theseTokens = _flatten(t.asList()) + 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") + return _ustr(s) + +def oneOf( strs, caseless=False, useRegex=True ): + """ + 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 a C{L{MatchFirst}} for best performance. + + Parameters: + - strs - a string of space-delimited literals, or a collection of string literals + - caseless - (default=C{False}) - treat all literals as caseless + - useRegex - (default=C{True}) - as an optimization, will generate a Regex + object; otherwise, will generate a C{MatchFirst} object (if C{caseless=True}, or + if creating a C{Regex} raises an exception) + + Example:: + comp_oper = oneOf("< = > <= >= !=") + var = Word(alphas) + number = Word(nums) + term = var | number + comparison_expr = term + comp_oper + term + print(comparison_expr.searchString("B = 12 AA=23 B<=AA AA>12")) + prints:: + [['B', '=', '12'], ['AA', '=', '23'], ['B', '<=', 'AA'], ['AA', '>', '12']] + """ + if caseless: + isequal = ( lambda a,b: a.upper() == b.upper() ) + masks = ( lambda a,b: b.upper().startswith(a.upper()) ) + parseElementClass = CaselessLiteral + else: + isequal = ( lambda a,b: a == b ) + masks = ( lambda a,b: b.startswith(a) ) + parseElementClass = Literal + + symbols = [] + 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) + 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)) + 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 ): + """ + Helper to easily and clearly define a dictionary by specifying the respective patterns + for the key and value. Takes care of defining the C{L{Dict}}, C{L{ZeroOrMore}}, and C{L{Group}} tokens + in the proper order. The key pattern can include delimiting markers or punctuation, + as long as they are suppressed, thereby leaving the significant key text. The value + pattern can include named results, so that the C{Dict} results can include named token + fields. + + Example:: + text = "shape: SQUARE posn: upper left color: light blue texture: burlap" + attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + print(OneOrMore(attr_expr).parseString(text).dump()) + + attr_label = label + attr_value = Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join) + + # similar to Dict, but simpler call format + result = dictOf(attr_label, attr_value).parseString(text) + print(result.dump()) + print(result['shape']) + print(result.shape) # object attribute access works too + print(result.asDict()) + prints:: + [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']] + - color: light blue + - posn: upper left + - shape: SQUARE + - texture: burlap + SQUARE + SQUARE + {'color': 'light blue', 'shape': 'SQUARE', 'posn': 'upper left', 'texture': 'burlap'} + """ + return Dict( ZeroOrMore( Group ( key + value ) ) ) + +def originalTextFor(expr, asString=True): + """ + Helper to return the original, untokenized text for a given expression. Useful to + restore the parsed fields of an HTML start tag into the raw tag text itself, or to + revert separate tokens with intervening whitespace back to the original matching + input text. By default, returns astring containing the original parsed text. + + If the optional C{asString} argument is passed as C{False}, then the return value is a + C{L{ParseResults}} containing any results names that were originally matched, and a + single token containing the original matched text from the input string. So if + the expression passed to C{L{originalTextFor}} contains expressions with defined + results names, you must set C{asString} to C{False} if you want to preserve those + results name values. + + Example:: + src = "this is test <b> bold <i>text</i> </b> normal text " + for tag in ("b","i"): + opener,closer = makeHTMLTags(tag) + patt = originalTextFor(opener + SkipTo(closer) + closer) + print(patt.searchString(src)[0]) + prints:: + ['<b> bold <i>text</i> </b>'] + ['<i>text</i>'] + """ + 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] + else: + def extractText(s,l,t): + t[:] = [s[t.pop('_original_start'):t.pop('_original_end')]] + matchExpr.setParseAction(extractText) + matchExpr.ignoreExprs = expr.ignoreExprs + return matchExpr + +def ungroup(expr): + """ + Helper to undo pyparsing's default grouping of And expressions, even + if all but one are non-empty. + """ + return TokenConverter(expr).setParseAction(lambda t:t[0]) + +def locatedExpr(expr): + """ + Helper to decorate a returned token with its starting and ending locations in the input string. + This helper adds the following results names: + - locn_start = location where matched expression begins + - locn_end = location where matched expression ends + - value = the actual parsed results + + Be careful if the input text contains C{<TAB>} characters, you may want to call + C{L{ParserElement.parseWithTabs}} + + Example:: + wd = Word(alphas) + for match in locatedExpr(wd).searchString("ljsdf123lksdjjf123lkkjj1222"): + print(match) + prints:: + [[0, 'ljsdf', 5]] + [[8, 'lksdjjf', 15]] + [[18, 'lkkjj', 23]] + """ + locator = Empty().setParseAction(lambda s,l,t: l) + return Group(locator("locn_start") + expr("value") + locator.copy().leaveWhitespace()("locn_end")) + + +# convenience constants for positional expressions +empty = Empty().setName("empty") +lineStart = LineStart().setName("lineStart") +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))) +_singleChar = _escapedPunc | _escapedHexChar | _escapedOctChar | CharsNotIn(r'\]', exact=1) +_charRange = Group(_singleChar + Suppress("-") + _singleChar) +_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 construction. Borrows + syntax from regexp '[]' string range definitions:: + srange("[0-9]") -> "0123456789" + srange("[a-z]") -> "abcdefghijklmnopqrstuvwxyz" + srange("[a-z$_]") -> "abcdefghijklmnopqrstuvwxyz$_" + The input string must be enclosed in []'s, and the returned string is the expanded + character set joined into a single string. + The values enclosed in the []'s may be: + - a single character + - an escaped character with a leading backslash (such as C{\-} or C{\]}) + - an escaped hex character with a leading C{'\x'} (C{\x21}, which is a C{'!'} character) + (C{\0x##} is also supported for backwards compatibility) + - an escaped octal character with a leading C{'\0'} (C{\041}, which is a C{'!'} character) + - a range of any of the above, separated by a dash (C{'a-z'}, etc.) + - any combination of the above (C{'aeiouy'}, C{'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)) + try: + return "".join(_expanded(part) for part in _reBracketExpr.parseString(s).body) + except Exception: + return "" + +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) + return verifyCol + +def replaceWith(replStr): + """ + Helper method for common parse actions that simply return a literal value. Especially + useful when used with C{L{transformString<ParserElement.transformString>}()}. + + Example:: + num = Word(nums).setParseAction(lambda toks: int(toks[0])) + na = oneOf("N/A NA").setParseAction(replaceWith(math.nan)) + term = na | num + + OneOrMore(term).parseString("324 234 N/A 234") # -> [324, 234, nan, 234] + """ + return lambda s,l,t: [replStr] + +def removeQuotes(s,l,t): + """ + Helper parse action for removing quotation marks from parsed quoted strings. + + Example:: + # by default, quotation marks are included in parsed results + quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["'Now is the Winter of our Discontent'"] + + # use removeQuotes to strip quotation marks from parsed results + quotedString.setParseAction(removeQuotes) + quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["Now is the Winter of our Discontent"] + """ + return t[0][1:-1] + +def tokenMap(func, *args): + """ + Helper to define a parse action by mapping a function to all elements of a ParseResults list.If any additional + args are passed, they are forwarded to the given function as additional arguments after + the token, as in C{hex_integer = Word(hexnums).setParseAction(tokenMap(int, 16))}, which will convert the + parsed data to an integer using base 16. + + Example (compare the last to example in L{ParserElement.transformString}:: + hex_ints = OneOrMore(Word(hexnums)).setParseAction(tokenMap(int, 16)) + hex_ints.runTests(''' + 00 11 22 aa FF 0a 0d 1a + ''') + + upperword = Word(alphas).setParseAction(tokenMap(str.upper)) + OneOrMore(upperword).runTests(''' + my kingdom for a horse + ''') + + wd = Word(alphas).setParseAction(tokenMap(str.title)) + OneOrMore(wd).setParseAction(' '.join).runTests(''' + now is the winter of our discontent made glorious summer by this sun of york + ''') + prints:: + 00 11 22 aa FF 0a 0d 1a + [0, 17, 34, 170, 255, 10, 13, 26] + + my kingdom for a horse + ['MY', 'KINGDOM', 'FOR', 'A', 'HORSE'] + + 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): + return [func(tokn, *args) for tokn in t] + + try: + func_name = getattr(func, '__name__', + getattr(func, '__class__').__name__) + except Exception: + func_name = str(func) + pa.__name__ = func_name + + return pa + +upcaseTokens = tokenMap(lambda t: _ustr(t).upper()) +"""(Deprecated) Helper parse action to convert tokens to upper case. Deprecated in favor of L{pyparsing_common.upcaseTokens}""" + +downcaseTokens = tokenMap(lambda t: _ustr(t).lower()) +"""(Deprecated) Helper parse action to convert tokens to lower case. Deprecated in favor of L{pyparsing_common.downcaseTokens}""" + +def _makeTags(tagStr, xml): + """Internal helper to construct opening and closing tag expressions, given a tag name""" + 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 ) + openTag = Suppress("<") + tagStr("tag") + \ + Dict(ZeroOrMore(Group( tagAttrName + Suppress("=") + tagAttrValue ))) + \ + Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") + else: + printablesLessRAbrack = "".join(c for c in printables if c not in ">") + tagAttrValue = quotedString.copy().setParseAction( removeQuotes ) | Word(printablesLessRAbrack) + openTag = Suppress("<") + tagStr("tag") + \ + Dict(ZeroOrMore(Group( tagAttrName.setParseAction(downcaseTokens) + \ + Optional( Suppress("=") + tagAttrValue ) ))) + \ + Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") + closeTag = Combine(_L("</") + tagStr + ">") + + openTag = openTag.setResultsName("start"+"".join(resname.replace(":"," ").title().split())).setName("<%s>" % resname) + closeTag = closeTag.setResultsName("end"+"".join(resname.replace(":"," ").title().split())).setName("</%s>" % resname) + openTag.tag = resname + closeTag.tag = resname + return openTag, closeTag + +def makeHTMLTags(tagStr): + """ + Helper to construct opening and closing tag expressions for HTML, given a tag name. Matches + tags in either upper or lower case, attributes with namespaces and with quoted or unquoted values. + + Example:: + text = '<td>More info at the <a href="http://pyparsing.wikispaces.com">pyparsing</a> wiki page</td>' + # makeHTMLTags returns pyparsing expressions for the opening and closing tags as a 2-tuple + a,a_end = makeHTMLTags("A") + link_expr = a + SkipTo(a_end)("link_text") + a_end + + for link in link_expr.searchString(text): + # attributes in the <A> tag (like "href" shown here) are also accessible as named results + print(link.link_text, '->', link.href) + prints:: + pyparsing -> http://pyparsing.wikispaces.com + """ + return _makeTags( tagStr, False ) + +def makeXMLTags(tagStr): + """ + Helper to construct opening and closing tag expressions for XML, given a tag name. Matches + tags only in the given upper/lower case. + + Example: similar to L{makeHTMLTags} + """ + return _makeTags( tagStr, True ) + +def withAttribute(*args,**attrDict): + """ + Helper to create a validating parse action to be used with start tags created + with C{L{makeXMLTags}} or C{L{makeHTMLTags}}. Use C{withAttribute} to qualify a starting tag + with a required attribute value, to avoid false matches on common tags such as + C{<TD>} or C{<DIV>}. + + Call C{withAttribute} with a series of attribute names and values. Specify the list + of filter attributes names and values as: + - keyword arguments, as in C{(align="right")}, or + - as an explicit dict with C{**} operator, when an attribute name is also a Python + reserved word, as in C{**{"class":"Customer", "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. + + If just testing for C{class} (with or without a namespace), use C{L{withClass}}. + + To verify that the attribute exists, but without specifying a value, pass + C{withAttribute.ANY_VALUE} as the value. + + Example:: + html = ''' + <div> + Some text + <div type="grid">1 4 0 1 0</div> + <div type="graph">1,3 2,3 1,1</div> + <div>this has no type</div> + </div> + + ''' + div,div_end = makeHTMLTags("div") + + # only match div tag having a type attribute with value "grid" + div_grid = div().setParseAction(withAttribute(type="grid")) + grid_expr = div_grid + SkipTo(div | div_end)("body") + for grid_header in grid_expr.searchString(html): + print(grid_header.body) + + # construct a match with any div tag having a type attribute, regardless of the value + div_any_type = div().setParseAction(withAttribute(type=withAttribute.ANY_VALUE)) + div_expr = div_any_type + SkipTo(div | div_end)("body") + for div_header in div_expr.searchString(html): + print(div_header.body) + prints:: + 1 4 0 1 0 + + 1 4 0 1 0 + 1,3 2,3 1,1 + """ + if args: + attrs = args[:] + else: + attrs = attrDict.items() + 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) + if attrValue != withAttribute.ANY_VALUE and tokens[attrName] != attrValue: + raise ParseException(s,l,"attribute '%s' has value '%s', must be '%s'" % + (attrName, tokens[attrName], attrValue)) + return pa +withAttribute.ANY_VALUE = object() + +def withClass(classname, namespace=''): + """ + Simplified version of C{L{withAttribute}} when matching on a div class - made + difficult because C{class} is a reserved word in Python. + + Example:: + html = ''' + <div> + Some text + <div class="grid">1 4 0 1 0</div> + <div class="graph">1,3 2,3 1,1</div> + <div>this <div> has no class</div> + </div> + + ''' + div,div_end = makeHTMLTags("div") + div_grid = div().setParseAction(withClass("grid")) + + grid_expr = div_grid + SkipTo(div | div_end)("body") + for grid_header in grid_expr.searchString(html): + print(grid_header.body) + + div_any_type = div().setParseAction(withClass(withAttribute.ANY_VALUE)) + div_expr = div_any_type + SkipTo(div | div_end)("body") + for div_header in div_expr.searchString(html): + print(div_header.body) + prints:: + 1 4 0 1 0 + + 1 4 0 1 0 + 1,3 2,3 1,1 + """ + classattr = "%s:class" % namespace if namespace else "class" + return withAttribute(**{classattr : classname}) + +opAssoc = _Constants() +opAssoc.LEFT = object() +opAssoc.RIGHT = object() + +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 attached + to operator expressions. The generated parser will also recognize the use + of parentheses to override operator precedences (see example below). + + Note: if you define a deep operator list, you may see performance issues + when using infixNotation. See L{ParserElement.enablePackrat} for a + mechanism to potentially improve your parser performance. + + Parameters: + - baseExpr - expression representing the most basic element for the nested + - opList - list of tuples, one for each operator precedence level in the + expression grammar; each tuple is of the form + (opExpr, numTerms, rightLeftAssoc, parseAction), where: + - opExpr is the pyparsing expression for the operator; + may also be a string, which will be converted to a Literal; + if numTerms is 3, opExpr is a tuple of two expressions, for the + two operators separating the 3 terms + - numTerms is the number of terms for this operator (must + be 1, 2, or 3) + - rightLeftAssoc is the indicator whether the operator is + right or left associative, using the pyparsing-defined + constants C{opAssoc.RIGHT} and C{opAssoc.LEFT}. + - parseAction is the parse action to be associated with + expressions matching this operator expression (the + parse action tuple member may be omitted); if the parse action + is passed a tuple or list of functions, this is equivalent to + calling C{setParseAction(*fn)} (L{ParserElement.setParseAction}) + - lpar - expression for matching left-parentheses (default=C{Suppress('(')}) + - rpar - expression for matching right-parentheses (default=C{Suppress(')')}) + + Example:: + # simple example of four-function arithmetic with ints and variable names + integer = pyparsing_common.signed_integer + varname = pyparsing_common.identifier + + arith_expr = infixNotation(integer | varname, + [ + ('-', 1, opAssoc.RIGHT), + (oneOf('* /'), 2, opAssoc.LEFT), + (oneOf('+ -'), 2, opAssoc.LEFT), + ]) + + arith_expr.runTests(''' + 5+3*6 + (5+3)*6 + -2--11 + ''', fullDump=False) + prints:: + 5+3*6 + [[5, '+', [3, '*', 6]]] + + (5+3)*6 + [[[5, '+', 3], '*', 6]] + + -2--11 + [[['-', 2], '-', ['-', 11]]] + """ + ret = Forward() + 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: + raise ValueError("if numterms=3, opExpr must be a tuple or list of two expressions") + opExpr1, opExpr2 = opExpr + thisExpr = Forward().setName(termName) + if rightLeftAssoc == opAssoc.LEFT: + if arity == 1: + matchExpr = FollowedBy(lastExpr + opExpr) + Group( lastExpr + OneOrMore( opExpr ) ) + elif arity == 2: + if opExpr is not None: + matchExpr = FollowedBy(lastExpr + opExpr + lastExpr) + Group( lastExpr + OneOrMore( opExpr + lastExpr ) ) + else: + matchExpr = FollowedBy(lastExpr+lastExpr) + Group( lastExpr + OneOrMore(lastExpr) ) + elif arity == 3: + matchExpr = FollowedBy(lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr) + \ + Group( lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr ) + else: + raise ValueError("operator must be unary (1), binary (2), or ternary (3)") + elif rightLeftAssoc == opAssoc.RIGHT: + if arity == 1: + # try to avoid LR with this extra test + if not isinstance(opExpr, Optional): + opExpr = Optional(opExpr) + matchExpr = FollowedBy(opExpr.expr + thisExpr) + Group( opExpr + thisExpr ) + elif arity == 2: + if opExpr is not None: + matchExpr = FollowedBy(lastExpr + opExpr + thisExpr) + Group( lastExpr + OneOrMore( opExpr + thisExpr ) ) + else: + matchExpr = FollowedBy(lastExpr + thisExpr) + Group( lastExpr + OneOrMore( thisExpr ) ) + elif arity == 3: + matchExpr = FollowedBy(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: + raise ValueError("operator must indicate right or left associativity") + if pa: + if isinstance(pa, (tuple, list)): + matchExpr.setParseAction(*pa) + else: + matchExpr.setParseAction(pa) + thisExpr <<= ( matchExpr.setName(termName) | lastExpr ) + lastExpr = thisExpr + ret <<= lastExpr + return ret + +operatorPrecedence = infixNotation +"""(Deprecated) Former name of C{L{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") +unicodeString = Combine(_L('u') + quotedString.copy()).setName("unicode string literal") + +def nestedExpr(opener="(", closer=")", content=None, ignoreExpr=quotedString.copy()): + """ + Helper method for defining nested lists enclosed in opening and closing + delimiters ("(" and ")" are the default). + + Parameters: + - opener - opening character for a nested list (default=C{"("}); can also be a pyparsing expression + - closer - closing character for a nested list (default=C{")"}); can also be a pyparsing expression + - content - expression for items within the nested lists (default=C{None}) + - ignoreExpr - expression for ignoring opening and closing delimiters (default=C{quotedString}) + + If an expression is not provided for the content argument, the nested + expression will capture all whitespace-delimited content between delimiters + as a list of separate values. + + Use the C{ignoreExpr} argument to define expressions that may contain + opening or closing characters that should not be treated as opening + or closing characters for nesting, such as quotedString or a comment + expression. Specify multiple expressions using an C{L{Or}} or C{L{MatchFirst}}. + The default is L{quotedString}, but if no expressions are to be ignored, + then pass C{None} for this argument. + + Example:: + data_type = oneOf("void int short long char float double") + decl_data_type = Combine(data_type + Optional(Word('*'))) + ident = Word(alphas+'_', alphanums+'_') + number = pyparsing_common.number + arg = Group(decl_data_type + ident) + LPAR,RPAR = map(Suppress, "()") + + code_body = nestedExpr('{', '}', ignoreExpr=(quotedString | cStyleComment)) + + c_function = (decl_data_type("type") + + ident("name") + + LPAR + Optional(delimitedList(arg), [])("args") + RPAR + + code_body("body")) + c_function.ignore(cStyleComment) + + source_code = ''' + int is_odd(int x) { + return (x%2); + } + + int dec_to_hex(char hchar) { + if (hchar >= '0' && hchar <= '9') { + return (ord(hchar)-ord('0')); + } else { + return (10+ord(hchar)-ord('A')); + } + } + ''' + for func in c_function.searchString(source_code): + print("%(name)s (%(type)s) args: %(args)s" % func) + + prints:: + is_odd (int) args: [['int', 'x']] + dec_to_hex (int) args: [['char', 'hchar']] + """ + 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 ignoreExpr is not None: + 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())) + 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())) + else: + 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) ) + else: + 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): + """ + Helper method for defining space-delimited indentation blocks, such as + those used to define block statements in Python source code. + + Parameters: + - blockStatementExpr - expression defining syntax of statement that + is repeated within the indented block + - indentStack - list created by caller to manage indentation stack + (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 statements + (default=C{True}) + + A valid block must contain at least one C{blockStatement}. + + Example:: + data = ''' + def A(z): + A1 + B = 100 + G = A2 + A2 + A3 + B + def BB(a,b,c): + BB1 + def BBA(): + bba1 + bba2 + bba3 + C + D + def spam(x,y): + def eggs(z): + pass + ''' + + + indentStack = [1] + stmt = Forward() + + identifier = Word(alphas, alphanums) + funcDecl = ("def" + identifier + Group( "(" + Optional( delimitedList(identifier) ) + ")" ) + ":") + func_body = indentedBlock(stmt, indentStack) + 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 ) + + module_body = OneOrMore(stmt) + + parseTree = module_body.parseString(data) + parseTree.pprint() + prints:: + [['def', + 'A', + ['(', 'z', ')'], + ':', + [['A1'], [['B', '=', '100']], [['G', '=', 'A2']], ['A2'], ['A3']]], + 'B', + ['def', + 'BB', + ['(', 'a', 'b', 'c', ')'], + ':', + [['BB1'], [['def', 'BBA', ['(', ')'], ':', [['bba1'], ['bba2'], ['bba3']]]]]], + 'C', + 'D', + ['def', + 'spam', + ['(', 'x', 'y', ')'], + ':', + [[['def', 'eggs', ['(', 'z', ')'], ':', [['pass']]]]]]] + """ + def checkPeerIndent(s,l,t): + if l >= len(s): return + curCol = col(l,s) + if curCol != indentStack[-1]: + if curCol > indentStack[-1]: + raise ParseFatalException(s,l,"illegal nesting") + raise ParseException(s,l,"not a peer entry") + + def checkSubIndent(s,l,t): + curCol = col(l,s) + if curCol > indentStack[-1]: + indentStack.append( curCol ) + else: + raise ParseException(s,l,"not a subentry") + + 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() + + NL = OneOrMore(LineEnd().setWhitespaceChars("\t ").suppress()) + 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) + else: + smExpr = Group( Optional(NL) + + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) ) + blockStatementExpr.ignore(_bslash + LineEnd()) + return smExpr.setName('indented block') + +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(),'><& "\'')) +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""" + return _htmlEntityMap.get(t.entity) + +# it's easy to get these comment structures wrong - they're very common, so may as well make them available +cStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/').setName("C style comment") +"Comment of the form C{/* ... */}" + +htmlComment = Regex(r"<!--[\s\S]*?-->").setName("HTML comment") +"Comment of the form C{<!-- ... -->}" + +restOfLine = Regex(r".*").leaveWhitespace().setName("rest of line") +dblSlashComment = Regex(r"//(?:\\\n|[^\n])*").setName("// comment") +"Comment of the form C{// ... (to end of line)}" + +cppStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/'| dblSlashComment).setName("C++ style comment") +"Comment of either form C{L{cStyleComment}} or C{L{dblSlashComment}}" + +javaStyleComment = cppStyleComment +"Same as C{L{cppStyleComment}}" + +pythonStyleComment = Regex(r"#.*").setName("Python style comment") +"Comment of the form C{# ... (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") +"""(Deprecated) Predefined expression of 1 or more printable words or quoted strings, separated by commas. + This expression is deprecated in favor of L{pyparsing_common.comma_separated_list}.""" + +# some other useful expressions - using lower-case class name since we are really using this as a namespace +class pyparsing_common: + """ + Here are some common low-level expressions that may be useful in jump-starting parser development: + - numeric forms (L{integers<integer>}, L{reals<real>}, L{scientific notation<sci_real>}) + - common L{programming identifiers<identifier>} + - network addresses (L{MAC<mac_address>}, L{IPv4<ipv4_address>}, L{IPv6<ipv6_address>}) + - ISO8601 L{dates<iso8601_date>} and L{datetime<iso8601_datetime>} + - L{UUID<uuid>} + - L{comma-separated list<comma_separated_list>} + Parse actions: + - C{L{convertToInteger}} + - C{L{convertToFloat}} + - C{L{convertToDate}} + - C{L{convertToDatetime}} + - C{L{stripHTMLTags}} + - C{L{upcaseTokens}} + - C{L{downcaseTokens}} + + Example:: + pyparsing_common.number.runTests(''' + # any int or real number, returned as the appropriate type + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + ''') + + pyparsing_common.fnumber.runTests(''' + # any int or real number, returned as float + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + ''') + + pyparsing_common.hex_integer.runTests(''' + # hex numbers + 100 + FF + ''') + + pyparsing_common.fraction.runTests(''' + # fractions + 1/2 + -3/4 + ''') + + pyparsing_common.mixed_integer.runTests(''' + # mixed fractions + 1 + 1/2 + -3/4 + 1-3/4 + ''') + + import uuid + pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID)) + pyparsing_common.uuid.runTests(''' + # uuid + 12345678-1234-5678-1234-567812345678 + ''') + prints:: + # any int or real number, returned as the appropriate type + 100 + [100] + + -100 + [-100] + + +100 + [100] + + 3.14159 + [3.14159] + + 6.02e23 + [6.02e+23] + + 1e-12 + [1e-12] + + # any int or real number, returned as float + 100 + [100.0] + + -100 + [-100.0] + + +100 + [100.0] + + 3.14159 + [3.14159] + + 6.02e23 + [6.02e+23] + + 1e-12 + [1e-12] + + # hex numbers + 100 + [256] + + FF + [255] + + # fractions + 1/2 + [0.5] + + -3/4 + [-0.75] + + # mixed fractions + 1 + [1] + + 1/2 + [0.5] + + -3/4 + [-0.75] + + 1-3/4 + [1.75] + + # uuid + 12345678-1234-5678-1234-567812345678 + [UUID('12345678-1234-5678-1234-567812345678')] + """ + + convertToInteger = tokenMap(int) + """ + Parse action for converting parsed integers to Python int + """ + + convertToFloat = tokenMap(float) + """ + Parse action for converting parsed numbers to Python float + """ + + 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)) + """expression that parses a hexadecimal integer, returns an int""" + + signed_integer = Regex(r'[+-]?\d+').setName("signed integer").setParseAction(convertToInteger) + """expression that parses an integer with optional leading sign, returns an int""" + + fraction = (signed_integer().setParseAction(convertToFloat) + '/' + signed_integer().setParseAction(convertToFloat)).setName("fraction") + """fractional expression of an integer divided by an integer, returns a float""" + fraction.addParseAction(lambda t: t[0]/t[-1]) + + mixed_integer = (fraction | signed_integer + Optional(Optional('-').suppress() + fraction)).setName("fraction or mixed integer-fraction") + """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) + """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) + """expression that parses a floating point number with optional scientific notation and returns a float""" + + # streamlining this expression makes the docs nicer-looking + number = (sci_real | real | signed_integer).streamline() + """any numeric expression, returns the corresponding Python type""" + + 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") + """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 (C{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") + _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") + "IPv6 address (long, short, or mixed form)" + + mac_address = Regex(r'[0-9a-fA-F]{2}([:.-])[0-9a-fA-F]{2}(?:\1[0-9a-fA-F]{2}){4}').setName("MAC address") + "MAC address xx:xx:xx:xx:xx (may also have '-' or '.' delimiters)" + + @staticmethod + def convertToDate(fmt="%Y-%m-%d"): + """ + Helper to create a parse action for converting parsed date string to Python datetime.date + + Params - + - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%d"}) + + Example:: + date_expr = pyparsing_common.iso8601_date.copy() + date_expr.setParseAction(pyparsing_common.convertToDate()) + print(date_expr.parseString("1999-12-31")) + prints:: + [datetime.date(1999, 12, 31)] + """ + def cvt_fn(s,l,t): + try: + return datetime.strptime(t[0], fmt).date() + except ValueError as ve: + raise ParseException(s, l, str(ve)) + return cvt_fn + + @staticmethod + def convertToDatetime(fmt="%Y-%m-%dT%H:%M:%S.%f"): + """ + Helper to create a parse action for converting parsed datetime string to Python datetime.datetime + + Params - + - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%dT%H:%M:%S.%f"}) + + Example:: + dt_expr = pyparsing_common.iso8601_datetime.copy() + dt_expr.setParseAction(pyparsing_common.convertToDatetime()) + print(dt_expr.parseString("1999-12-31T23:59:59.999")) + prints:: + [datetime.datetime(1999, 12, 31, 23, 59, 59, 999000)] + """ + def cvt_fn(s,l,t): + try: + return datetime.strptime(t[0], fmt) + except ValueError as ve: + raise ParseException(s, l, str(ve)) + return cvt_fn + + iso8601_date = Regex(r'(?P<year>\d{4})(?:-(?P<month>\d\d)(?:-(?P<day>\d\d))?)?').setName("ISO8601 date") + "ISO8601 date (C{yyyy-mm-dd})" + + iso8601_datetime = Regex(r'(?P<year>\d{4})-(?P<month>\d\d)-(?P<day>\d\d)[T ](?P<hour>\d\d):(?P<minute>\d\d)(:(?P<second>\d\d(\.\d*)?)?)?(?P<tz>Z|[+-]\d\d:?\d\d)?').setName("ISO8601 datetime") + "ISO8601 datetime (C{yyyy-mm-ddThh:mm:ss.s(Z|+-00:00)}) - trailing seconds, milliseconds, and timezone optional; accepts separating C{'T'} or C{' '}" + + uuid = Regex(r'[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}').setName("UUID") + "UUID (C{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx})" + + _html_stripper = anyOpenTag.suppress() | anyCloseTag.suppress() + @staticmethod + def stripHTMLTags(s, l, tokens): + """ + Parse action to remove HTML tags from web page HTML source + + Example:: + # strip HTML links from normal text + text = '<td>More info at the <a href="http://pyparsing.wikispaces.com">pyparsing</a> wiki page</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) # -> 'More info at the pyparsing wiki page' + """ + 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") + """Predefined expression of 1 or more printable words or quoted strings, separated by commas.""" + + upcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).upper())) + """Parse action to convert tokens to upper case.""" + + downcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).lower())) + """Parse action to convert tokens to lower case.""" + + +if __name__ == "__main__": + + selectToken = CaselessLiteral("select") + fromToken = CaselessLiteral("from") + + ident = Word(alphas, alphanums + "_$") + + columnName = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens) + columnNameList = Group(delimitedList(columnName)).setName("columns") + columnSpec = ('*' | columnNameList) + + tableName = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens) + tableNameList = Group(delimitedList(tableName)).setName("tables") + + simpleSQL = selectToken("command") + columnSpec("columns") + fromToken + tableNameList("tables") + + # demo runTests method, including embedded comments in test string + simpleSQL.runTests(""" + # '*' as column list and dotted table name + select * from SYS.XYZZY + + # caseless match on "SELECT", and casts back to "select" + SELECT * from XYZZY, ABC + + # list of column names, and mixed case SELECT keyword + Select AA,BB,CC from Sys.dual + + # multiple tables + Select A, B, C from Sys.dual, Table2 + + # invalid SELECT keyword - should fail + Xelect A, B, C from Sys.dual + + # incomplete command - should fail + Select + + # invalid column name - should fail + Select ^^^ frox Sys.dual + + """) + + pyparsing_common.number.runTests(""" + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + """) + + # any int or real number, returned as float + pyparsing_common.fnumber.runTests(""" + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + """) + + pyparsing_common.hex_integer.runTests(""" + 100 + FF + """) + + import uuid + pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID)) + pyparsing_common.uuid.runTests(""" + 12345678-1234-5678-1234-567812345678 + """) diff --git a/venv/lib/python3.7/site-packages/pkg_resources/_vendor/six.py b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/six.py new file mode 100644 index 0000000..190c023 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pkg_resources/_vendor/six.py @@ -0,0 +1,868 @@ +"""Utilities for writing code that runs on Python 2 and 3""" + +# Copyright (c) 2010-2015 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 +# 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. + +from __future__ import absolute_import + +import functools +import itertools +import operator +import sys +import types + +__author__ = "Benjamin Peterson <benjamin@python.org>" +__version__ = "1.10.0" + + +# Useful for very coarse version differentiation. +PY2 = sys.version_info[0] == 2 +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, + text_type = str + binary_type = bytes + + MAXSIZE = sys.maxsize +else: + string_types = basestring, + integer_types = (int, long) + class_types = (type, types.ClassType) + text_type = unicode + binary_type = str + + if sys.platform.startswith("java"): + # Jython always uses 32 bits. + MAXSIZE = int((1 << 31) - 1) + 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: + # 32-bit + MAXSIZE = int((1 << 31) - 1) + else: + # 64-bit + MAXSIZE = int((1 << 63) - 1) + del X + + +def _add_doc(func, doc): + """Add documentation to a function.""" + func.__doc__ = doc + + +def _import_module(name): + """Import module, returning the module after the last dot.""" + __import__(name) + return sys.modules[name] + + +class _LazyDescr(object): + + def __init__(self, name): + self.name = name + + def __get__(self, obj, tp): + result = self._resolve() + setattr(obj, self.name, result) # Invokes __set__. + try: + # This is a bit ugly, but it avoids running this again by + # removing this descriptor. + delattr(obj.__class__, self.name) + except AttributeError: + pass + return result + + +class MovedModule(_LazyDescr): + + def __init__(self, name, old, new=None): + super(MovedModule, self).__init__(name) + if PY3: + if new is None: + new = name + self.mod = new + else: + self.mod = old + + def _resolve(self): + return _import_module(self.mod) + + def __getattr__(self, attr): + _module = self._resolve() + value = getattr(_module, attr) + setattr(self, attr, value) + return value + + +class _LazyModule(types.ModuleType): + + def __init__(self, name): + super(_LazyModule, self).__init__(name) + self.__doc__ = self.__class__.__doc__ + + def __dir__(self): + attrs = ["__doc__", "__name__"] + attrs += [attr.name for attr in self._moved_attributes] + return attrs + + # Subclasses should override this + _moved_attributes = [] + + +class MovedAttribute(_LazyDescr): + + def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): + super(MovedAttribute, self).__init__(name) + if PY3: + if new_mod is None: + new_mod = name + self.mod = new_mod + if new_attr is None: + if old_attr is None: + new_attr = name + else: + new_attr = old_attr + self.attr = new_attr + else: + self.mod = old_mod + if old_attr is None: + old_attr = name + self.attr = old_attr + + def _resolve(self): + module = _import_module(self.mod) + return getattr(module, self.attr) + + +class _SixMetaPathImporter(object): + + """ + A meta path importer to import six.moves and its submodules. + + This class implements a PEP302 finder and loader. It should be compatible + with Python 2.5 and all existing versions of Python3 + """ + + def __init__(self, six_module_name): + self.name = six_module_name + self.known_modules = {} + + def _add_module(self, mod, *fullnames): + for fullname in fullnames: + self.known_modules[self.name + "." + fullname] = mod + + def _get_module(self, fullname): + return self.known_modules[self.name + "." + fullname] + + def find_module(self, fullname, path=None): + if fullname in self.known_modules: + return self + return None + + def __get_module(self, fullname): + try: + return self.known_modules[fullname] + except KeyError: + raise ImportError("This loader does not know module " + fullname) + + def load_module(self, fullname): + try: + # in case of a reload + return sys.modules[fullname] + except KeyError: + pass + mod = self.__get_module(fullname) + if isinstance(mod, MovedModule): + mod = mod._resolve() + else: + mod.__loader__ = self + sys.modules[fullname] = mod + return mod + + def is_package(self, fullname): + """ + Return true, if the named module is a package. + + We need this method to get correct spec objects with + Python 3.4 (see PEP451) + """ + return hasattr(self.__get_module(fullname), "__path__") + + def get_code(self, fullname): + """Return None + + 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("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("range", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"), + MovedAttribute("reduce", "__builtin__", "functools"), + MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), + MovedAttribute("StringIO", "StringIO", "io"), + MovedAttribute("UserDict", "UserDict", "collections"), + MovedAttribute("UserList", "UserList", "collections"), + 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"), + MovedModule("builtins", "__builtin__"), + MovedModule("configparser", "ConfigParser"), + MovedModule("copyreg", "copy_reg"), + MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), + MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"), + MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), + MovedModule("http_cookies", "Cookie", "http.cookies"), + 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("BaseHTTPServer", "BaseHTTPServer", "http.server"), + MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), + MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), + MovedModule("cPickle", "cPickle", "pickle"), + MovedModule("queue", "Queue"), + MovedModule("reprlib", "repr"), + MovedModule("socketserver", "SocketServer"), + MovedModule("_thread", "thread", "_thread"), + MovedModule("tkinter", "Tkinter"), + MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), + MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), + MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), + MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), + MovedModule("tkinter_tix", "Tix", "tkinter.tix"), + 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_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), + MovedModule("tkinter_font", "tkFont", "tkinter.font"), + MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), + 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"), + MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), + MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), + MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"), +] +# Add windows specific modules. +if sys.platform == "win32": + _moved_attributes += [ + MovedModule("winreg", "_winreg"), + ] + +for attr in _moved_attributes: + setattr(_MovedItems, attr.name, attr) + if isinstance(attr, MovedModule): + _importer._add_module(attr, "moves." + attr.name) +del attr + +_MovedItems._moved_attributes = _moved_attributes + +moves = _MovedItems(__name__ + ".moves") +_importer._add_module(moves, "moves") + + +class Module_six_moves_urllib_parse(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_parse""" + + +_urllib_parse_moved_attributes = [ + MovedAttribute("ParseResult", "urlparse", "urllib.parse"), + MovedAttribute("SplitResult", "urlparse", "urllib.parse"), + MovedAttribute("parse_qs", "urlparse", "urllib.parse"), + MovedAttribute("parse_qsl", "urlparse", "urllib.parse"), + MovedAttribute("urldefrag", "urlparse", "urllib.parse"), + MovedAttribute("urljoin", "urlparse", "urllib.parse"), + MovedAttribute("urlparse", "urlparse", "urllib.parse"), + MovedAttribute("urlsplit", "urlparse", "urllib.parse"), + MovedAttribute("urlunparse", "urlparse", "urllib.parse"), + MovedAttribute("urlunsplit", "urlparse", "urllib.parse"), + MovedAttribute("quote", "urllib", "urllib.parse"), + MovedAttribute("quote_plus", "urllib", "urllib.parse"), + MovedAttribute("unquote", "urllib", "urllib.parse"), + MovedAttribute("unquote_plus", "urllib", "urllib.parse"), + MovedAttribute("urlencode", "urllib", "urllib.parse"), + MovedAttribute("splitquery", "urllib", "urllib.parse"), + MovedAttribute("splittag", "urllib", "urllib.parse"), + MovedAttribute("splituser", "urllib", "urllib.parse"), + MovedAttribute("uses_fragment", "urlparse", "urllib.parse"), + MovedAttribute("uses_netloc", "urlparse", "urllib.parse"), + MovedAttribute("uses_params", "urlparse", "urllib.parse"), + MovedAttribute("uses_query", "urlparse", "urllib.parse"), + MovedAttribute("uses_relative", "urlparse", "urllib.parse"), +] +for attr in _urllib_parse_moved_attributes: + setattr(Module_six_moves_urllib_parse, attr.name, attr) +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") + + +class Module_six_moves_urllib_error(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_error""" + + +_urllib_error_moved_attributes = [ + MovedAttribute("URLError", "urllib2", "urllib.error"), + MovedAttribute("HTTPError", "urllib2", "urllib.error"), + MovedAttribute("ContentTooShortError", "urllib", "urllib.error"), +] +for attr in _urllib_error_moved_attributes: + setattr(Module_six_moves_urllib_error, attr.name, attr) +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") + + +class Module_six_moves_urllib_request(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_request""" + + +_urllib_request_moved_attributes = [ + MovedAttribute("urlopen", "urllib2", "urllib.request"), + MovedAttribute("install_opener", "urllib2", "urllib.request"), + MovedAttribute("build_opener", "urllib2", "urllib.request"), + MovedAttribute("pathname2url", "urllib", "urllib.request"), + MovedAttribute("url2pathname", "urllib", "urllib.request"), + MovedAttribute("getproxies", "urllib", "urllib.request"), + MovedAttribute("Request", "urllib2", "urllib.request"), + MovedAttribute("OpenerDirector", "urllib2", "urllib.request"), + MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"), + MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), + MovedAttribute("BaseHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), + MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"), + MovedAttribute("FileHandler", "urllib2", "urllib.request"), + MovedAttribute("FTPHandler", "urllib2", "urllib.request"), + MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"), + MovedAttribute("UnknownHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"), + MovedAttribute("urlretrieve", "urllib", "urllib.request"), + MovedAttribute("urlcleanup", "urllib", "urllib.request"), + MovedAttribute("URLopener", "urllib", "urllib.request"), + MovedAttribute("FancyURLopener", "urllib", "urllib.request"), + MovedAttribute("proxy_bypass", "urllib", "urllib.request"), +] +for attr in _urllib_request_moved_attributes: + setattr(Module_six_moves_urllib_request, attr.name, attr) +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") + + +class Module_six_moves_urllib_response(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_response""" + + +_urllib_response_moved_attributes = [ + MovedAttribute("addbase", "urllib", "urllib.response"), + MovedAttribute("addclosehook", "urllib", "urllib.response"), + MovedAttribute("addinfo", "urllib", "urllib.response"), + MovedAttribute("addinfourl", "urllib", "urllib.response"), +] +for attr in _urllib_response_moved_attributes: + setattr(Module_six_moves_urllib_response, attr.name, attr) +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") + + +class Module_six_moves_urllib_robotparser(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_robotparser""" + + +_urllib_robotparser_moved_attributes = [ + 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 + +_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") + request = _importer._get_module("moves.urllib_request") + response = _importer._get_module("moves.urllib_response") + robotparser = _importer._get_module("moves.urllib_robotparser") + + def __dir__(self): + return ['parse', 'error', 'request', 'response', 'robotparser'] + +_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"), + "moves.urllib") + + +def add_move(move): + """Add an item to six.moves.""" + setattr(_MovedItems, move.name, move) + + +def remove_move(name): + """Remove item from six.moves.""" + try: + delattr(_MovedItems, name) + except AttributeError: + try: + del moves.__dict__[name] + except KeyError: + raise AttributeError("no such move, %r" % (name,)) + + +if PY3: + _meth_func = "__func__" + _meth_self = "__self__" + + _func_closure = "__closure__" + _func_code = "__code__" + _func_defaults = "__defaults__" + _func_globals = "__globals__" +else: + _meth_func = "im_func" + _meth_self = "im_self" + + _func_closure = "func_closure" + _func_code = "func_code" + _func_defaults = "func_defaults" + _func_globals = "func_globals" + + +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 + + create_bound_method = types.MethodType + + def create_unbound_method(func, cls): + return func + + Iterator = object +else: + def get_unbound_function(unbound): + return unbound.im_func + + def create_bound_method(func, obj): + return types.MethodType(func, obj, obj.__class__) + + def create_unbound_method(func, cls): + 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""") + + +get_method_function = operator.attrgetter(_meth_func) +get_method_self = operator.attrgetter(_meth_self) +get_function_closure = operator.attrgetter(_func_closure) +get_function_code = operator.attrgetter(_func_code) +get_function_defaults = operator.attrgetter(_func_defaults) +get_function_globals = operator.attrgetter(_func_globals) + + +if PY3: + def iterkeys(d, **kw): + return iter(d.keys(**kw)) + + def itervalues(d, **kw): + return iter(d.values(**kw)) + + def iteritems(d, **kw): + return iter(d.items(**kw)) + + def iterlists(d, **kw): + return iter(d.lists(**kw)) + + viewkeys = operator.methodcaller("keys") + + viewvalues = operator.methodcaller("values") + + viewitems = operator.methodcaller("items") +else: + def iterkeys(d, **kw): + return d.iterkeys(**kw) + + def itervalues(d, **kw): + return d.itervalues(**kw) + + def iteritems(d, **kw): + return d.iteritems(**kw) + + def iterlists(d, **kw): + return d.iterlists(**kw) + + viewkeys = operator.methodcaller("viewkeys") + + viewvalues = operator.methodcaller("viewvalues") + + viewitems = operator.methodcaller("viewitems") + +_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.") + + +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 + _assertCountEqual = "assertCountEqual" + if sys.version_info[1] <= 1: + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" + else: + _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") + unichr = unichr + int2byte = chr + + def byte2int(bs): + return ord(bs[0]) + + def indexbytes(buf, i): + return ord(buf[i]) + iterbytes = functools.partial(itertools.imap, ord) + import StringIO + StringIO = BytesIO = StringIO.StringIO + _assertCountEqual = "assertItemsEqual" + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" +_add_doc(b, """Byte literal""") +_add_doc(u, """Text literal""") + + +def assertCountEqual(self, *args, **kwargs): + return getattr(self, _assertCountEqual)(*args, **kwargs) + + +def assertRaisesRegex(self, *args, **kwargs): + return getattr(self, _assertRaisesRegex)(*args, **kwargs) + + +def assertRegex(self, *args, **kwargs): + return getattr(self, _assertRegex)(*args, **kwargs) + + +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 + +else: + def exec_(_code_, _globs_=None, _locs_=None): + """Execute code in a namespace.""" + if _globs_ is None: + frame = sys._getframe(1) + _globs_ = frame.f_globals + if _locs_ is None: + _locs_ = frame.f_locals + del frame + elif _locs_ is None: + _locs_ = _globs_ + exec("""exec _code_ in _globs_, _locs_""") + + exec_("""def reraise(tp, value, tb=None): + raise tp, value, tb +""") + + +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 +""") +elif sys.version_info[:2] > (3, 2): + exec_("""def raise_from(value, from_value): + raise value from from_value +""") +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) + if fp is None: + return + + def write(data): + 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): + 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: + if isinstance(sep, unicode): + want_unicode = True + elif not isinstance(sep, str): + raise TypeError("sep must be None or a string") + end = kwargs.pop("end", None) + if end is not None: + if isinstance(end, unicode): + want_unicode = True + elif not isinstance(end, str): + raise TypeError("end must be None or a string") + if kwargs: + raise TypeError("invalid keyword arguments to print()") + if not want_unicode: + for arg in args: + if isinstance(arg, unicode): + want_unicode = True + break + if want_unicode: + newline = unicode("\n") + space = unicode(" ") + else: + newline = "\n" + space = " " + if sep is None: + sep = space + if end is None: + end = newline + for i, arg in enumerate(args): + if i: + write(sep) + write(arg) + write(end) +if sys.version_info[:2] < (3, 3): + _print = print_ + + def print_(*args, **kwargs): + fp = kwargs.get("file", sys.stdout) + flush = kwargs.pop("flush", False) + _print(*args, **kwargs) + 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 wrapper(f): + f = functools.wraps(wrapped, assigned, updated)(f) + f.__wrapped__ = wrapped + return f + return wrapper +else: + wraps = functools.wraps + + +def with_metaclass(meta, *bases): + """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): + + def __new__(cls, name, this_bases, d): + return meta(name, bases, d) + 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__') + 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) + return metaclass(cls.__name__, cls.__bases__, orig_vars) + return wrapper + + +def python_2_unicode_compatible(klass): + """ + A 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 + 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__) + klass.__unicode__ = klass.__str__ + klass.__str__ = lambda self: self.__unicode__().encode('utf-8') + return klass + + +# Complete the moves implementation. +# This code is at the end of this module to speed up module loading. +# Turn this module into a package. +__path__ = [] # required for PEP 302 and PEP 451 +__package__ = __name__ # see PEP 366 @ReservedAssignment +if globals().get("__spec__") is not None: + __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable +# Remove other six meta path importers, since they cause problems. This can +# happen if six is removed from sys.modules and then reloaded. (Setuptools does +# this for some reason.) +if sys.meta_path: + for i, importer in enumerate(sys.meta_path): + # Here's some real nastiness: Another "instance" of the six module might + # 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__): + del sys.meta_path[i] + break + del i, importer +# Finally, add the importer to the meta path import hook. +sys.meta_path.append(_importer) diff --git a/venv/lib/python3.7/site-packages/pkg_resources/extern/__init__.py b/venv/lib/python3.7/site-packages/pkg_resources/extern/__init__.py new file mode 100644 index 0000000..c1eb9e9 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pkg_resources/extern/__init__.py @@ -0,0 +1,73 @@ +import sys + + +class VendorImporter: + """ + A PEP 302 meta path importer for finding optionally-vendored + or otherwise naturally-installed packages from root_name. + """ + + def __init__(self, root_name, vendored_names=(), vendor_pkg=None): + self.root_name = root_name + self.vendored_names = set(vendored_names) + self.vendor_pkg = vendor_pkg or root_name.replace('extern', '_vendor') + + @property + def search_path(self): + """ + Search first the vendor package then as a natural package. + """ + yield self.vendor_pkg + '.' + yield '' + + def find_module(self, fullname, path=None): + """ + Return self when fullname starts with root_name and the + target module is one vendored through this importer. + """ + root, base, target = fullname.partition(self.root_name + '.') + if root: + return + if not any(map(target.startswith, self.vendored_names)): + return + return self + + def load_module(self, fullname): + """ + Iterate over the search path to locate and load fullname. + """ + root, base, target = fullname.partition(self.root_name + '.') + for prefix in self.search_path: + try: + extant = prefix + target + __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 + else: + raise ImportError( + "The '{target}' package is required; " + "normally this is bundled with this package so if you get " + "this warning, consult the packager of your " + "distribution.".format(**locals()) + ) + + def install(self): + """ + Install this importer into sys.meta_path if not already present. + """ + if self not in sys.meta_path: + sys.meta_path.append(self) + + +names = 'packaging', 'pyparsing', 'six', 'appdirs' +VendorImporter(__name__, names).install() diff --git a/venv/lib/python3.7/site-packages/pkg_resources/extern/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/pkg_resources/extern/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bca63532b0f5ce43132cb9edaf7e1b4ec287b7a6 GIT binary patch literal 2428 zcmZ`)TW=dh6rS0e9mh#4gc4dH8VN+P)W)UdR#B=#TOkCBs-`N%Dy%l1v9rl~XFD@a zVzYk15l;y5!h7?`-{5D=D^L9kJaNvf?X-<Lt2r~fJGXPb?|k$1%1VPk`TgykC;u!F z@-M#3iw~XKQ1xXnoN$_v4*7;~kNd}j`%|w&dC>6$6~6GM-m~C@P#CpMTH$k;LAJVR z=Vh_lZTKPx%q1O<(~i$qdBDSC+6hF+BVIcuQ`(96IbP>W@U_MpeEFDk>b%KUpk3lV z>~P+$J`y>X>f1pfl@V%u++a|?V)yUeXV<S@V*_ClRwQPZrL!TdCl%|ZIZyLGlZ8oT zo@CkR%7I%*aJK*qk!Dw@!&D2FCuXSJm^9Z0I)cNJ-TkC5H0vojU`k38=gB~9y4in& z)4|MRY_Z;fsy_fz(vrl)(9)Y?&nx|6qomJ#PPupD!Iyv&aLwQ9MB)fs%55#K&ejU; z(qbp;Yhmo_{M2rDZEH#tS<)4@QT>RE{eCO3ffiX$g|NG-p#hAELMWX1Z`3YSdXN~= zK1fu%Co?XTZVz_b-H(d+#`wnG)x+yOKGvUJKTy|>%y@7WN<VKuY!_*9WfqhxpM18n zyFc9Nx8Y#J!bq9vHf$d&q2*9@g>F~=wBtC<QxnIV#mLs@FGxTgfgv=a4LV+b^b)X} z^Ko5@W1wK`K}CA$H83UF1KzEZN60_VS>#AC{@#Ityx10r>h1#iN*f0FvMNe*H1Si; z63vo1=JP)luDFDyo0e>~sEZ*qc<$3ss%3b!%i8S|Bk#`P@f;b#CLLdV#j6(vb`cLO z7=#65K8F`z2RcX5xfA-tpZJqt5|+N&;NCVdp7G0YFMtu@6gZ_n#;>L0(D=87>kj}F zl`|v)J482o!z@F}GN80FnjNN)Bnx`6B<C28#e5jl7lsWaA7+B3n#p_~K1c_%tK_i1 z3oZPaXWD7d)C#z<)r#y=0ehvGbB>MHPx6uV2T5TY)iLlCj-#!}h1S;R=d=Na(*}4% z8|)-n*r+<xnebzF$JI&KVPo9{L&7y0!1D&wGcdd`p^KctQiqCpatEsZ6U-SHJOtv% zK;XT*<fq4zaCEB-%V3>MB7h{CQc6s)7naclGO3j{*QYm08LFS5A8~I#a6K6DB`Is$ zfV!#eH<Y2kU`l=@Pd6Sz{Q<smf3MynW@$?Ppi}xQC@$*j_`3x>--1#=0yB9a6ygRz zJE}YBGm>Spi@y=oOeTDR{wo-@yyr+mbrH<?uZOVCrC+KbPcF@K0l`<|=`dA-f5CF8 z2B?iQ=r!9J<{TB$@yYRFrj<-fmiE|44jD4Z{W?rk4my09b!D!HS(TKt@gTu&v|>Ef zMx{GL<jv+*tD(;08J(PAdf5hugH!i723Z_|3|8Q4+k|jvm<5W{lXkhfChjREm5tyY z7$n9<7@ADC>QySgiA$rLD5Q>h3)hbdC3@+R6XYZ}Kv>DokPgE-Bi(y2NpFB5!5VE+ zkJjO7&_=WhZ9rFP!}Dn5pP}IkOS~j=2#KR1!cr0gTCiVJYuG-68{-6s<}O@s{NR)j z)m8O!MzS;qE<l7f@m_TLgplOYuq0C=;UfmFYLS~$UTn2|^$zT7mlktuloSQX^K0a< zHoFmS!>mgB0uc1ISEO$?sO7mxf}#Sjcpac70gixa1tRpDar|_cIJJVeS{!rPjbnvr zZR>@Sg-~XskP7Mon)lIMLgUDMYEYdOCOGP=lZAQ^c#W`GZ#3)gx<7DRf=J=z4!nf! y2oy_W*VpNht%2hlZjV;zV&Z1l5Ra_Yhq(CbcD41Jl{>fa-f|aR-Cw;M(EkBWyn}B5 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/pkg_resources/py31compat.py b/venv/lib/python3.7/site-packages/pkg_resources/py31compat.py new file mode 100644 index 0000000..a381c42 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pkg_resources/py31compat.py @@ -0,0 +1,23 @@ +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.7/site-packages/setuptools-40.6.2.dist-info/INSTALLER b/venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/LICENSE b/venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/LICENSE new file mode 100644 index 0000000..6e0693b --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/LICENSE @@ -0,0 +1,19 @@ +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.7/site-packages/setuptools-40.6.2.dist-info/METADATA b/venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/METADATA new file mode 100644 index 0000000..5a5fde1 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/METADATA @@ -0,0 +1,73 @@ +Metadata-Version: 2.1 +Name: setuptools +Version: 40.6.2 +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://readthedocs.org/projects/setuptools/badge/?version=latest + :target: https://setuptools.readthedocs.io + +.. image:: https://img.shields.io/travis/pypa/setuptools/master.svg?label=Linux%20build%20%40%20Travis%20CI + :target: https://travis-ci.org/pypa/setuptools + +.. image:: https://img.shields.io/appveyor/ci/pypa/setuptools/master.svg?label=Windows%20build%20%40%20Appveyor + :target: https://ci.appveyor.com/project/pypa/setuptools/branch/master + +.. image:: https://img.shields.io/codecov/c/github/pypa/setuptools/master.svg + :target: https://codecov.io/gh/pypa/setuptools + +.. image:: https://img.shields.io/pypi/pyversions/setuptools.svg + +.. image:: https://tidelift.com/badges/github/pypa/setuptools + :target: https://tidelift.com/subscription/pkg/pypi-setuptools?utm_source=pypi-setuptools&utm_medium=readme + +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>`_. + + +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.7/site-packages/setuptools-40.6.2.dist-info/RECORD b/venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/RECORD new file mode 100644 index 0000000..422e20a --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/RECORD @@ -0,0 +1,188 @@ +../../../bin/easy_install,sha256=ovDDVM_jQ_AZ0XYhNZJRpuZqSrw_0MH92vbh2VVL5mU,286 +../../../bin/easy_install-3.7,sha256=ovDDVM_jQ_AZ0XYhNZJRpuZqSrw_0MH92vbh2VVL5mU,286 +__pycache__/easy_install.cpython-37.pyc,, +easy_install.py,sha256=MDC9vt5AxDsXX5qcKlBz2TnW6Tpuv_AobnfhCJ9X3PM,126 +pkg_resources/__init__.py,sha256=d7w_yqCD39lZE0-qxhWXPYoc-pZc3G2mD7EU2xhRLpM,104720 +pkg_resources/__pycache__/__init__.cpython-37.pyc,, +pkg_resources/__pycache__/py31compat.cpython-37.pyc,, +pkg_resources/_vendor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pkg_resources/_vendor/__pycache__/__init__.cpython-37.pyc,, +pkg_resources/_vendor/__pycache__/appdirs.cpython-37.pyc,, +pkg_resources/_vendor/__pycache__/pyparsing.cpython-37.pyc,, +pkg_resources/_vendor/__pycache__/six.cpython-37.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-37.pyc,, +pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-37.pyc,, +pkg_resources/_vendor/packaging/__pycache__/_compat.cpython-37.pyc,, +pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-37.pyc,, +pkg_resources/_vendor/packaging/__pycache__/markers.cpython-37.pyc,, +pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-37.pyc,, +pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc,, +pkg_resources/_vendor/packaging/__pycache__/utils.cpython-37.pyc,, +pkg_resources/_vendor/packaging/__pycache__/version.cpython-37.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-37.pyc,, +pkg_resources/py31compat.py,sha256=-WQ0e4c3RG_acdhwC3gLiXhP_lg4G5q7XYkZkQg0gxU,558 +setuptools-40.6.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +setuptools-40.6.2.dist-info/LICENSE,sha256=wyo6w5WvYyHv0ovnPQagDw22q4h9HCHU_sRhKNIFbVo,1078 +setuptools-40.6.2.dist-info/METADATA,sha256=xD5qjTNmFccxhrkNSRwX2ksMINOFNLCysl5ESfOrYRE,3092 +setuptools-40.6.2.dist-info/RECORD,, +setuptools-40.6.2.dist-info/WHEEL,sha256=CihQvCnsGZQBGAHLEUMf0IdA4fRduS_NBUTMgCTtvPM,110 +setuptools-40.6.2.dist-info/dependency_links.txt,sha256=HlkCFkoK5TbZ5EMLbLKYhLcY_E31kBWD8TqW2EgmatQ,239 +setuptools-40.6.2.dist-info/entry_points.txt,sha256=jBqCYDlVjl__sjYFGXo1JQGIMAYFJE-prYWUtnMZEew,2990 +setuptools-40.6.2.dist-info/top_level.txt,sha256=2HUXVVwA4Pff1xgTFr3GsTXXKaPaO6vlG6oNJ_4u4Tg,38 +setuptools-40.6.2.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1 +setuptools/__init__.py,sha256=ipsF2yFkfHmryPP8ASJEtOj9N9OuYkk8HxxIJyOHtj0,6001 +setuptools/__pycache__/__init__.cpython-37.pyc,, +setuptools/__pycache__/_deprecation_warning.cpython-37.pyc,, +setuptools/__pycache__/archive_util.cpython-37.pyc,, +setuptools/__pycache__/build_meta.cpython-37.pyc,, +setuptools/__pycache__/config.cpython-37.pyc,, +setuptools/__pycache__/dep_util.cpython-37.pyc,, +setuptools/__pycache__/depends.cpython-37.pyc,, +setuptools/__pycache__/dist.cpython-37.pyc,, +setuptools/__pycache__/extension.cpython-37.pyc,, +setuptools/__pycache__/glibc.cpython-37.pyc,, +setuptools/__pycache__/glob.cpython-37.pyc,, +setuptools/__pycache__/launch.cpython-37.pyc,, +setuptools/__pycache__/lib2to3_ex.cpython-37.pyc,, +setuptools/__pycache__/monkey.cpython-37.pyc,, +setuptools/__pycache__/msvc.cpython-37.pyc,, +setuptools/__pycache__/namespaces.cpython-37.pyc,, +setuptools/__pycache__/package_index.cpython-37.pyc,, +setuptools/__pycache__/pep425tags.cpython-37.pyc,, +setuptools/__pycache__/py27compat.cpython-37.pyc,, +setuptools/__pycache__/py31compat.cpython-37.pyc,, +setuptools/__pycache__/py33compat.cpython-37.pyc,, +setuptools/__pycache__/py36compat.cpython-37.pyc,, +setuptools/__pycache__/sandbox.cpython-37.pyc,, +setuptools/__pycache__/site-patch.cpython-37.pyc,, +setuptools/__pycache__/ssl_support.cpython-37.pyc,, +setuptools/__pycache__/unicode_utils.cpython-37.pyc,, +setuptools/__pycache__/version.cpython-37.pyc,, +setuptools/__pycache__/wheel.cpython-37.pyc,, +setuptools/__pycache__/windows_support.cpython-37.pyc,, +setuptools/_deprecation_warning.py,sha256=jU9-dtfv6cKmtQJOXN8nP1mm7gONw5kKEtiPtbwnZyI,218 +setuptools/_vendor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +setuptools/_vendor/__pycache__/__init__.cpython-37.pyc,, +setuptools/_vendor/__pycache__/pyparsing.cpython-37.pyc,, +setuptools/_vendor/__pycache__/six.cpython-37.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-37.pyc,, +setuptools/_vendor/packaging/__pycache__/__init__.cpython-37.pyc,, +setuptools/_vendor/packaging/__pycache__/_compat.cpython-37.pyc,, +setuptools/_vendor/packaging/__pycache__/_structures.cpython-37.pyc,, +setuptools/_vendor/packaging/__pycache__/markers.cpython-37.pyc,, +setuptools/_vendor/packaging/__pycache__/requirements.cpython-37.pyc,, +setuptools/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc,, +setuptools/_vendor/packaging/__pycache__/utils.cpython-37.pyc,, +setuptools/_vendor/packaging/__pycache__/version.cpython-37.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=qg4RfvgZF1uZPuO1VMioG8JRhNMp5fHrwgpgkYpnzc8,6021 +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-37.pyc,, +setuptools/command/__pycache__/alias.cpython-37.pyc,, +setuptools/command/__pycache__/bdist_egg.cpython-37.pyc,, +setuptools/command/__pycache__/bdist_rpm.cpython-37.pyc,, +setuptools/command/__pycache__/bdist_wininst.cpython-37.pyc,, +setuptools/command/__pycache__/build_clib.cpython-37.pyc,, +setuptools/command/__pycache__/build_ext.cpython-37.pyc,, +setuptools/command/__pycache__/build_py.cpython-37.pyc,, +setuptools/command/__pycache__/develop.cpython-37.pyc,, +setuptools/command/__pycache__/dist_info.cpython-37.pyc,, +setuptools/command/__pycache__/easy_install.cpython-37.pyc,, +setuptools/command/__pycache__/egg_info.cpython-37.pyc,, +setuptools/command/__pycache__/install.cpython-37.pyc,, +setuptools/command/__pycache__/install_egg_info.cpython-37.pyc,, +setuptools/command/__pycache__/install_lib.cpython-37.pyc,, +setuptools/command/__pycache__/install_scripts.cpython-37.pyc,, +setuptools/command/__pycache__/py36compat.cpython-37.pyc,, +setuptools/command/__pycache__/register.cpython-37.pyc,, +setuptools/command/__pycache__/rotate.cpython-37.pyc,, +setuptools/command/__pycache__/saveopts.cpython-37.pyc,, +setuptools/command/__pycache__/sdist.cpython-37.pyc,, +setuptools/command/__pycache__/setopt.cpython-37.pyc,, +setuptools/command/__pycache__/test.cpython-37.pyc,, +setuptools/command/__pycache__/upload.cpython-37.pyc,, +setuptools/command/__pycache__/upload_docs.cpython-37.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=81CTgsqjBjNl_HOgCJ1lQ5vv1NIM3RBpcoVGpqT4N1M,12897 +setuptools/command/build_py.py,sha256=yWyYaaS9F3o9JbIczn064A5g1C5_UiKRDxGaTqYbtLE,9596 +setuptools/command/develop.py,sha256=Sl1iMOORbAnp5BqiXmyMBD0uuvEnhSfOCqbxIPRiJPc,8060 +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=3lsuTHQFjmAw6slzRrB3HjLiF2TaImpWHREllAPhyv8,25541 +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=11mxf0Ch12NsuYwS8PHwXBRvyh671QAM4cTRh7epzG0,3840 +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=obDTe2BmWt2PlnFPZZh7e0LWvemEsbCCO9MzhrTZjm8,6711 +setuptools/command/setopt.py,sha256=NTWDyx-gjDF-txf4dO577s7LOzHVoKR0Mq33rFxaRr8,5085 +setuptools/command/test.py,sha256=fSl5OsZWSmFR3QJRvyy2OxbcYkuIkPvykWNOhFvAcUA,9228 +setuptools/command/upload.py,sha256=BpQCjKtJZ4kEb0qIOiTjlJtbpapmNacC27nG2ZlSxTY,6825 +setuptools/command/upload_docs.py,sha256=oXiGplM_cUKLwE4CWWw98RzCufAu8tBhMC97GegFcms,7311 +setuptools/config.py,sha256=nCkzIQRWTpVwvtSlFm1kOeSLMMHXmB7hENxwZUT6X9Q,19751 +setuptools/dep_util.py,sha256=fgixvC1R7sH3r13ktyf7N0FALoqEXL1cBarmNpSEoWg,935 +setuptools/depends.py,sha256=hC8QIDcM3VDpRXvRVA6OfL9AaQfxvhxHcN_w6sAyNq8,5837 +setuptools/dist.py,sha256=HyRYLlPp_gkcnvQf8o1RsGq99LtghAeAfxWxbf40KxA,44675 +setuptools/extension.py,sha256=uc6nHI-MxwmNCNPbUiBnybSyqhpJqjbhvOQ-emdvt_E,1729 +setuptools/extern/__init__.py,sha256=TxeNKFMSfBMzBpBDiHx8Dh3RzsdVmvWaXhtZ03DZMs0,2499 +setuptools/extern/__pycache__/__init__.cpython-37.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=yeifZQhJVRwPSaQmRrVPxbXRy-1lF5KdTFV8NAb3YcE,40342 +setuptools/pep425tags.py,sha256=bSGwlybcIpssx9kAv_hqAUJzfEpXSzYRp2u-nDYPdbk,10862 +setuptools/py27compat.py,sha256=3mwxRMDk5Q5O1rSXOERbQDXhFqwDJhhUitfMW_qpUCo,536 +setuptools/py31compat.py,sha256=REvrUBibUHgqI9S-ww0C9bhU-n8PyaQ8Slr1_NRxaaE,820 +setuptools/py33compat.py,sha256=OubjldHJH1KGE1CKt1kRU-Q55keftHT3ea1YoL0ZSco,1195 +setuptools/py36compat.py,sha256=VUDWxmu5rt4QHlGTRtAFu6W5jvfL6WBjeDAzeoBy0OM,2891 +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=YBDJsCZjSp62CWjxmSkke9kn9rhHHj25Cus6zhJRW3c,8492 +setuptools/unicode_utils.py,sha256=NOiZ_5hD72A6w-4wVj8awHFM3n51Kmw1Ic_vx15XFqw,996 +setuptools/version.py,sha256=og_cuZQb0QI6ukKZFfZWPlr1HgJBPPn2vO2m_bI9ZTE,144 +setuptools/wheel.py,sha256=A8hKSqHWZ5KM0-VP_DtptxpMxVF9pQwjWZcHGklxq2o,8102 +setuptools/windows_support.py,sha256=5GrfqSP2-dLGJoZTq2g6dCKkyQxxa2n5IQiXlJCoYEE,714 diff --git a/venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/WHEEL b/venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/WHEEL new file mode 100644 index 0000000..dea0e20 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.32.2) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/dependency_links.txt b/venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/dependency_links.txt new file mode 100644 index 0000000..e87d021 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/dependency_links.txt @@ -0,0 +1,2 @@ +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.7/site-packages/setuptools-40.6.2.dist-info/entry_points.txt b/venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/entry_points.txt new file mode 100644 index 0000000..4159fd0 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/entry_points.txt @@ -0,0 +1,65 @@ +[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.7/site-packages/setuptools-40.6.2.dist-info/top_level.txt b/venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/top_level.txt new file mode 100644 index 0000000..4577c6a --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/top_level.txt @@ -0,0 +1,3 @@ +easy_install +pkg_resources +setuptools diff --git a/venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/zip-safe b/venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/zip-safe new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools-40.6.2.dist-info/zip-safe @@ -0,0 +1 @@ + diff --git a/venv/lib/python3.7/site-packages/setuptools/__init__.py b/venv/lib/python3.7/site-packages/setuptools/__init__.py new file mode 100644 index 0000000..e438036 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/__init__.py @@ -0,0 +1,195 @@ +"""Extensions to the 'distutils' for large or complex distributions""" + +import os +import sys +import functools +import distutils.core +import distutils.filelist +from distutils.util import convert_path +from fnmatch import fnmatchcase + +from ._deprecation_warning import SetuptoolsDeprecationWarning + +from setuptools.extern.six import PY3 +from setuptools.extern.six.moves import filter, map + +import setuptools.version +from setuptools.extension import Extension +from setuptools.dist import Distribution, Feature +from setuptools.depends import Require +from . import monkey + +__metaclass__ = type + + +__all__ = [ + 'setup', 'Distribution', 'Feature', 'Command', 'Extension', 'Require', + 'SetuptoolsDeprecationWarning', + 'find_packages' +] + +if PY3: + __all__.append('find_namespace_packages') + +__version__ = setuptools.version.__version__ + +bootstrap_install_from = None + +# If we run 2to3 on .py files, should we also convert docstrings? +# Default: yes; assume that we can detect doctests reliably +run_2to3_on_doctests = True +# Standard package names for fixer packages +lib2to3_fixer_packages = ['lib2to3.fixes'] + + +class PackageFinder: + """ + Generate a list of all Python packages found within a directory + """ + + @classmethod + def find(cls, where='.', exclude=(), include=('*',)): + """Return a list all Python packages found within directory 'where' + + 'where' is the root directory which will be searched for packages. It + should be supplied as a "cross-platform" (i.e. URL-style) path; it will + be converted to the appropriate local path syntax. + + 'exclude' is a sequence of package names to exclude; '*' can be used + as a wildcard in the names, such that 'foo.*' will exclude all + subpackages of 'foo' (but not 'foo' itself). + + 'include' is a sequence of package names to include. If it's + specified, only the named packages will be included. If it's not + specified, all found packages will be included. 'include' can contain + shell style wildcard patterns just like 'exclude'. + """ + + return list(cls._find_packages_iter( + convert_path(where), + cls._build_filter('ez_setup', '*__pycache__', *exclude), + cls._build_filter(*include))) + + @classmethod + def _find_packages_iter(cls, where, exclude, include): + """ + All the packages found in 'where' that pass the 'include' filter, but + not the 'exclude' filter. + """ + for root, dirs, files in os.walk(where, followlinks=True): + # Copy dirs to iterate over it, then empty dirs. + all_dirs = dirs[:] + dirs[:] = [] + + for dir in all_dirs: + full_path = os.path.join(root, dir) + rel_path = os.path.relpath(full_path, where) + package = rel_path.replace(os.path.sep, '.') + + # Skip directory trees that are not valid packages + if ('.' in dir or not cls._looks_like_package(full_path)): + continue + + # Should this package be included? + if include(package) and not exclude(package): + yield package + + # Keep searching subdirectories, as there may be more packages + # down there, even if the parent was excluded. + dirs.append(dir) + + @staticmethod + def _looks_like_package(path): + """Does a directory look like a package?""" + return os.path.isfile(os.path.join(path, '__init__.py')) + + @staticmethod + def _build_filter(*patterns): + """ + Given a list of patterns, return a callable that will be true only if + the input matches at least one of the patterns. + """ + return lambda name: any(fnmatchcase(name, pat=pat) for pat in patterns) + + +class PEP420PackageFinder(PackageFinder): + @staticmethod + def _looks_like_package(path): + return True + + +find_packages = PackageFinder.find + +if PY3: + 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') + )) + # Honor setup.cfg's options. + dist.parse_config_files(ignore_option_errors=True) + if dist.setup_requires: + dist.fetch_build_eggs(dist.setup_requires) + + +def setup(**attrs): + # Make sure we have any requirements needed to interpret 'attrs'. + _install_setup_requires(attrs) + return distutils.core.setup(**attrs) + +setup.__doc__ = distutils.core.setup.__doc__ + + +_Command = monkey.get_unpatched(distutils.core.Command) + + +class Command(_Command): + __doc__ = _Command.__doc__ + + command_consumes_arguments = False + + def __init__(self, dist, **kw): + """ + Construct the command for dist, updating + vars(self) with any keyword parameters. + """ + _Command.__init__(self, dist) + vars(self).update(kw) + + def reinitialize_command(self, command, reinit_subcommands=0, **kw): + cmd = _Command.reinitialize_command(self, command, reinit_subcommands) + vars(cmd).update(kw) + return cmd + + +def _find_all_simple(path): + """ + Find all files under 'path' + """ + results = ( + os.path.join(base, file) + for base, dirs, files in os.walk(path, followlinks=True) + for file in files + ) + return filter(os.path.isfile, results) + + +def findall(dir=os.curdir): + """ + Find all files under 'dir' and return the list of full filenames. + Unless dir is '.', return full filenames with dir prepended. + """ + files = _find_all_simple(dir) + if dir == os.curdir: + make_rel = functools.partial(os.path.relpath, start=dir) + files = map(make_rel, files) + return list(files) + + +# Apply monkey patches +monkey.patch_all() diff --git a/venv/lib/python3.7/site-packages/setuptools/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a3d95850b35a0c8f02c426dc95f6ad35c3307260 GIT binary patch literal 6533 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 M&YJZjc5Qa%-&d8O$^ZZW literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/__pycache__/_deprecation_warning.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/__pycache__/_deprecation_warning.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2d025cccf34a2cb424a533b4881b97ec0c4ef850 GIT binary patch literal 564 zcmZWm!Ab)$5KUXLr6_ptriWY$wp$eyL8OS_t(O*rB4o3hY#YrcYi4(~^{7X`!kfRe zSO3D3(`{`9AI$8_%)Hsj<Z64nNf7UQ!CishuleB@8%TO+u#4`72qG$PXp+3vMio&V zkX9|k%nB7`Jv7)sCkfV&QB_n%wMA{QKagpbq}FP<mWh)gPn9*d+!<xYvyUc4Tyc;z z)Et0D*3qX$l8SXbP-Up^!>X6>H%sYoqF^aSVr+^kr*bK1<ZO(R|3CHp1Imq{94KVr zgeoXI<qA}wB@L$7BI21&J7v7z+9(=~86Hc<iY8;R6`7v%Eyf-*u9ulQW5R}veG<2c zt0>*~i<jUuJe6L~oflb+(}5RHyznq#=d<(s?$dE3W^j6(yQAlH7IzV2;|;w;C2eIO z<yyB-&VtE97L2|1{r^(-XHjgqyiPK8^QV~`RM9my%X7a~E$Ykdmx1-L3s%S4qH(df K<Yg(x2>Ai$TA?HW literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/__pycache__/archive_util.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/__pycache__/archive_util.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a5f62ebc3dfb3333b79a8d4095b740a524910269 GIT binary patch literal 5145 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/__pycache__/build_meta.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/__pycache__/build_meta.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..66ec24ec7ff05c712d190d68f725083c26cf00d9 GIT binary patch literal 6281 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 NT5{>{oME~r{|(S<JL3QV literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/__pycache__/config.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/__pycache__/config.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..644d60aca550328a24f4bf3922ec320a17d82f36 GIT binary patch literal 17013 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/__pycache__/dep_util.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/__pycache__/dep_util.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0d7c09ffdad185d48327aa6404ba62eb91f65e86 GIT binary patch literal 871 zcmY*XPjAyO6t|PMjP8$6#bJnxZ(XFV8Jh;0gb*5V<p79D6{vD!H}UG&!FJkFWf#hk z4*@5{SIU(WUjZ(>B(2oF%CGP5?`OZ4i{0HW0{QlE{NbmM(C^AwiwDMYICdWtLkvrl z;vvR}dCdQch8}CZMM3)yWKn?2ZN=x@jAEnnEUJ1dX|K);__q?2Lj_u5(0GZbzS(z} zf%OH)=*ENNUtc({safKe=;O&v%lQQ=S`VP3(o4?_3h#TXiT!}v6h3%$uJS$&E>YnX z{=|d3d5eFSR8GlQyM#~^=P6gt5}`;&4V9A1L*lq~Ld8T(2&Yj(tj<luN&O5WEU91B zB_J-LiU{bBv@zUfTCu9p0Wfz1@`k(IC`%}S3q$mTNMWJ+ph2|FWb9#sRX5py%oA?- ziWF|P;%m4X<U>LuU~ITFWT2d<R5=mZ8Vi{E8?!$M`hz;YIP2e{?h~pQ={KmhPtx2v zGUg2;O*xTV#V!fjr4LrweNSc1Um2rK*)~+g+*DgFJ2cC<VnKVjcMIN@cUI8lT{T*z zDsvsh;ukX80P$CcnGrMUcsQdboM_3ov0<8o(W7j1zBs=+o}W(G!ahEonUia`NRL5c z6}}5IksS$T9W3wY?8!Kp=HocDF!{`BE$ybscs9zNkb~@VdB2%YwV1iEyjex3`X+mz zQ0E@r@>{rtd+^)CJ<sey^mX8uJqA0hQ0!ohS5KiXs2{VTcA%-;dYWpMOa2UlXRC?r GwEqL3e*e?} literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/__pycache__/depends.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/__pycache__/depends.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fdd634b413add704e5b6ecb0f6c78744995981f6 GIT binary patch literal 5280 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/__pycache__/dist.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/__pycache__/dist.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f5bb56ff1101c295175d49ec5ca076327939ba55 GIT binary patch literal 38455 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 BgY5tS literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/__pycache__/extension.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/__pycache__/extension.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2eac6fed1f44b4db18f4c57cac6a83e5b910fc23 GIT binary patch literal 1991 zcmaJ?UymC#5VyUXWRtt3M_VDFl`yoTMC~O<D=3u!RTPSZ&>_)#fEChevv!ir?LTbq z-DQ<~x;_FQ0kw~O48DfN8&CZTJTbG$?X^;cBag@Sto@sr-#B0P`#l2f*K3oX|7sKR z4^GaT3(7<2dIdrdK@;MyN9xmh&U~jH-ObplN0zkHj^Cj~IKoZ5wCi_4Z;AF(;`e0F z-;!PFEVdW@GwKh%A)+I^r$l&iaOU`Zn0G}F<~`Ym`6WT0km1$~KtT3~)H-Qcyr3`v zy+4yCD6=9o(OilMO|apv2mKLreHVnFr(}86kQEVZMuqbmTTlSxJ|QkK?69ZqQ22<F zpGd}j1fXzXyV~n<Xg^3(s*E3~Qu27pA1%#1&v+DOd;$w;kt-v`s5Y(MS?`X%inS?C zoaoV{j1v*a6JxuL3b?(g%F_g_4jvC3+Y5sAK|!EefYx@uK8a*u;yfEte=Dl5M3dxC zqPk%4Z!s=Zd=wfvJ_^-%nkPakJx=H2=%XTdP(4`e9p9UZN`G?iNZma#Rk{almW>a_ zMO^I0nKogP?0$TIGCwRQv#|yr3zO%Gepv<7GSdKJR4nawFb|Jpu*R~DaUFmlu1gu) zp)MWJHdR}&(j)=58T5zHH3uOHa>i$Z0!Nr|fD5j0MGHn?286tWj&JU)?l&qo^U&~8 zOU-YMqFa0#C!od|FOo2lJfFgHu{_yqL=Ieq4I_#C{T{mh5X8!T21F3-Ia`r{8n$p& zWJOnO>a3hU*vkDKDM0{-vu_8*GDzYyhTH~W5kDTf)+zEr_2C@ISA)%Zkh?54K`?At zSIcB--7HL{?dZHzk<``=)l6G<cwA?0EwJF!4u~7jHG(A0fL52AV@KzwMo49BXoMcs zl->u$kTarsSQ{&{pv7guPU(t1W6z=H4w<?s+>D9VDKpM9*R&RG(O$9V&Z%QM##@2s zi|!daqY#O1U0<E*@0!DF%C954ae*JlX3jChT%M;#bCdH|_RU;!1HMYroRfsvtPE%J z;<FJyn8%u@GMa~3tWyp&%#Ss1EW;AYORY~Yiy~PzhZRchMtOE5vEG`iC#69ousM|q zh$7cGH^|myi7xG1QaRD>+m$<tilSnpsA{1{H;28Nwbna_U|WDlD%+iwSyb1A?G&Lh zahO=9q;+&Tu`brGLUyYwAcn4b0|r<IkNw^{3|RH*I+|d~UL@XL4>o=T03g^v4NM;3 z*F&(?SYM>wW-jf~t8|A}AH2kj|M_@-*hWGk0fPXal{6P+g8Ft4{8EO=W~UPbB9Gv; zK@O^SQCwiGwVI&_gG1Nww?I7VGOw+0?UfQof<A<<@vK)%981Y|zKbU+RLkn~Z%b`> z5+6z)awTVF5-Q&Kb%$dr@r^V*)L@aUKZ82gMuuV^V$9(N^&X1%QQScBI@~v5<5TDw z6Xa2a^Wl!V27`JVgdK?HfsS&>X}6jCJB>P$N&yw^m6uk|>F-~=crr&=6e=6(_+*sk zM^e|k@Y`vg9m=J`!mTOh_v#n4SSop9UA(srrn-a%2=R5kSnsoS4!^)S>o-Aobn|1| NY}@fJxgdAm`VUEj4$1%k literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/__pycache__/glibc.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/__pycache__/glibc.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..55c50b1abfb5d823e130fd655830f8d6c1ea8472 GIT binary patch literal 1556 zcmZ8hTW{Mo6ecNIR@EfEEGvd}*a$2IA~cD!b{Aymx=Yt!7y_ec3UtU?2(n1qiX~Aa zDW^7+r|fZW`vb}2{t{pJw7;;Y9nuMw<QTm8ko<J`edq9p<>d&0{c(Tr=I14Z{<eQE zjKJhOXzC~E7-G0UB|gB|&PhQIh#S2F&yD_p&phV;jt)Ak!vYus)@31#U3P;-Foulm zqxj}OfQDjhZlwbyibnG!FKZ!nKeG$gJZK@bXVBCO=rlUT44>g+G>ckvNRIJqRIU0* zdy`16V`P5}@1tK}=b_)?q|@RPbWC*665Tx^YOf`y@OeNWtqsDP@4V!?k(HvOA|GUQ z%B9LhMU|F$HQJy;(!QuT&4;uSnl=i&i>+II(@9m9=kW~_WO`O}W&CG9?(Lb?QPm_P zt`m!xoFkf*?=@f!;GWN=6w-uQl8sZD)TS%Bvgb{d1H95{m2u-i1SViS6O6~6xl>D# zaix+fExD@GjLQHBF*ncQ6WIP2lDEM3Z_%q|K20_6O;gz$ih{wVdgZv6eO4zs^PR)( zqsK!wS6@D!%17_?yxayGRlQfeI<Gff1Vyp=#aDyzq#2BQ3J9vT5QVxtb#!gjGq~;L zYuY$~BAZNV6*|<7Fu@UC@d7Wz0f}%#<Q?#5R$OcTd2=G$3|olYqBC;rwVqnj<kVxN zMfZ^Q&j<+Y?IYc3z0-jCXZQrSctXVPxu@eiWYPg~gZ_MN{o5B$%Jfjkr@wA*?!0{% zzu9uGy!ziY|K|C-nrE7`Ye{gF>oI*qGXZ&7@k%S|pteeTdV`LH{+d2eyQbsZFj#-w zHAHgj)7jXBN2#oU5XcQXGb=BfO6Mhiy>J^Zue9lmq-g5cmn(36vm*I#O)fc07O=|z zo0m<QICz6gr}Cn^Z4bPcjd?anuIR7^3(CTw?h^KK02284E|wpIC$j}@%}QYDchuVz zjcm2FP|%Z5-nEsaaSPN#6#?ln>F>r1^&C#@$@_3feq=lQt?PlkKTfASvGk=n9~68M z;^(ka*|J6uRtRCqPhg%|hcyh%26#0n)IwpqprCA-*P@{vA;8$5|M^PJs1}rQ%_We; zsUGvIQbrL4yD0UPLPi&yis5;kE4mIzym3+eF+CdR*%$zaX;Wy6&C6QPE_OSxyrNmE z7T+p_m^3vVrg@>Z+-g5221yF{0CjDF#Mq@hym!l2gu2dIcu`GzaCSjc;AkT9Q}DoJ z6D7&8fj5gMiL^vXE1|T-ChytKR+rPq@#;=p`iOlYq)VIdNhw%U@TVTQT&^sU5CjRm K@Wb$S_`!dcK$cSg literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/__pycache__/glob.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/__pycache__/glob.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..364f4ddbcb4181f2228326e4e378cc98e9fae7f6 GIT binary patch literal 3766 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/__pycache__/launch.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/__pycache__/launch.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..70d2536f2d71dcbb959094bfd2b86d7aa425318c GIT binary patch literal 870 zcmYjQ&2G~`5Z*s0ZrXA|h*n(o8l=W8RY8?1gy4#*3OJ=f*2cR@wzb#RdL0@oIR$R; z4(*Xw@|9CxffKVah|X%pGdtti@3Uv$?(X&w$oFUC(PN6xFCY990?r%IasWo6A(B{< z6c6#{NrpsH$-bf?RZIrg#6DMajWCkrBkFhR%ieoYnPkS@O!13_o8^X=iPeSU;Q7rY z&oW^oPqk58Oq{a4Qn{*dd7hSBmwcS(u5?xug_3-(1=m@TTQ}(410Zysc<ZGD8i2k7 zEiD)aFdV)j67QoGa&!rxJlG#}h1-2ezmfg6hI;=DIpzWxxXzlc$dWA48sB#B(26eU zZ74gkdq-BxZ7mt}3ZW)&y=Ab(YXXER5Z<aUdK~0K)sp*5RRifoIS_U_zdZWP1@M}1 z?f6W{P5D?U!?l^`*Fez-S6Pv!i@_#$kAX@P#&IUJiR1G=^}$4^DvrHpMCQG29Lqcb zhvkJbH5=KHsmaJROx>uYzuoM_@wn2d)24(f3V0gk0X0nO#5LWia>6;=gbq*`T`Sx5 z2Q#aLY`RtzsYq1Qh2K@c**1h^zte2D3^yp6Esv!vd|lvC#7(D754TNjv$zc!mgG|X zMD{7P_?<<C)pOxgG#56S<f&A)jIvpj92N0teR_5H<#;0N^5yZ|zPNF9b_g;x(Wj`; z#Q~6U@Tm??UX5qh)p#2HADxG8x|zX2v1q8R%r2Z;?twu8!#zwkD<pel2e-@aL(alQ sK>fh_v9gc6@pq(6`7ztTe_(vWCOpe>S*7YVgQ)Z`upq=C4WESg53%X*y#N3J literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/__pycache__/lib2to3_ex.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/__pycache__/lib2to3_ex.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bd8df06765a8a75eead86b5669fba3f7533caa7e GIT binary patch literal 2449 zcmbVNTaOzx6t?G*OlGr}whLWtDU3>0DN>u1R$Ph@s%Y7Y2LghXiblX_5<A(+&LwL* z+ia9RZ6AT3fU=MLB}+W<#9!zW=QxvWTD1k?k&o>eUyi@?oo~KaU-t==U#@h1{Ig2P zUpQD42Riqm${)Zm5)ww4mD0=#ZHj$6buu?}P2Wi?Sv9O?Ug(*zo7TeGBf=`I`i!tD zub$eW4`YwjU|i!ij4kGVPa6K@#D6f7s>qTFXTjIWILYs*;%*>E!(k!Rr@kND3S!3O z;!V&iM9?krV=h#Z_XAdR6_-l-zQ2Ev$RI1&DCL2O6Uk)|=fPJQZuF%Pu&&61Z%@<# zG<TZ*-*7R~pt`m^6$W-%^c$Am{EqkHt||l^v0oIazTD?3>Lp_?WYiNy77gR>Vch5K zF7C1@7If}ImDj;=5>f!pLg1c}&}KGspmmtbD$u&D3IKR|=V2n%NF}L!>C7(fh6O`m zL;VJ-+y<k_fKF+TPOaaq-v~fXU?<vcSOTYMm*Zs{j&>wZd)m%qUpukrOKlxK`Gbf$ zOnQFQ8j9pNR=jl_i&n2l8C<QE9kjY145NFKdxP6g?)KP3esuR(+!?D$b{k4RZ|%2+ z$?#T^OBJW-tq(u$92|~1{g&ivG*p0;T<xYw2csGBadUX0Yk+NJe7lG@G1sG$Yp=V1 zb2)v91YQs8BV7L<kZ_W`S2S$l!F*9egM>E#%*{Fs^%@?OaVa65Z^4U&XV>58S-IeU z`{pv<8TJ3wIRl!Ry0hZin?W<v+l`9$q9~6u9!1)ZqIqUOzaB+Lqd1*^5gUle78;Do z3N}a+fdGjLm<v!Pc0B6Yo^9TBVYn<9m-|rV4KPdY*O<lZXB5~Eyf^GOq5$moF#QFR zV6Tg7u^`j&j0aGq05c^6;5ws+HL-;(pHjJlt+Hk|?mTm*^o(96XOzO+nR^D=0Byyz zmguPJz!SNu!9M;eeQHnb!P*q|gU9(5ge<SC`fPm)`<_{49=YxPNp%l}s2@D10f>S7 zL?nub>kFxgiab4OZ0I_J%oRxolDEi1ZzOqyY&S_LHo<%C42mSzSEHrEL{Vpyq-?Gv zCN@&<u72j@ZaQMTlp5`y=T*2ZM!7iv&W{$pm^kP)qfF&~o+z~og1$UhdyCZ#$E1UH zdr8V==q+~ARICKw#65sJT!ku;dc>|%$2{8<H~_s0_31@xa&dV`b8$wO;sPibUKgqf zXa_nNP~l?;`_PZb_+3Q@)<g2s_EU=AX10Qmo<dM5Iof%Q^W8y(5g@?N<6u5|&FsC$ zOChWZbX&XwCVYD#LUW8t-Ilt-$BO4npnC!@7;Y{iSfUSlio&7k@FifvORtDy6Q)Yc zBLcu6ICZ)Wb%Rc>o&)rXbxW);2`~W+R&D4gxILqNa%vlF04IaPjVYbkfCP*YrSY{X z1w?kAT2l+&I)@c;6Wf_PHQ$eJmbh5$aN|XKfkIT_zZNSc<_KI~BJkow@jkd?Fx3^o zv*MVSx)pAg6H7|V&_Ac*%cyNd@FQ5I_b0HcM42G~6hh_0Gud5*>%|4_2Hk5^#3l3w z<zJv&ivZ0onk#6GZk-#$WaJ^Tp;R#cf;X3*#+t51m`osx8<@`KN8Chfq)EI7i*#-I sW&VTRDk;@mWSYRZ&6$L!n52A_AKLqDuEL)qvCP#S3$MOqdG^-YKNhcBPXGV_ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/__pycache__/monkey.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/__pycache__/monkey.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0220f9b3b777abcb71f2e877e4a8d2d6789c66b0 GIT binary patch literal 4650 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/__pycache__/msvc.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/__pycache__/msvc.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f99c6838944ec0f5fe1728520b832a175f480253 GIT binary patch literal 34447 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ℑLoB{4*@h)@ynQsD!UPk)9n3Qp%90}6wZ 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 PMSBQ<n5ek^{9sZp?3V=A<u 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 R9~=Dg;8zkETwh7t`(H)@T%iB} literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/__pycache__/namespaces.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/__pycache__/namespaces.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a44b8dae3bca2fd7a6566394c9e6e3e1e3163360 GIT binary patch literal 3628 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 I=dA7h53icAPyhe` literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/__pycache__/package_index.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/__pycache__/package_index.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cb0250cc5265e0bb520b2b4ac056786e7db9bb37 GIT binary patch literal 32482 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/__pycache__/pep425tags.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/__pycache__/pep425tags.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dc2a81b1c33c0902a5d055d96de4cd18daa23735 GIT binary patch literal 7219 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 J4>Xo5{SSK$1}Xpm literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/__pycache__/py27compat.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/__pycache__/py27compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0e61ad2eef15daf5b4c0c8c32eba94458581f077 GIT binary patch literal 827 zcma)4O>Yx15Vd!c-R+X9zzL}rUn9|MNd-|Q6d`&b2dE-77gk6sXYFj<ct5b6kVH9h z<VUne{?cAK@fSET-ULx`Vx$>=jo-XC_S@s*5P^L=oql@eAoRm7{ur#$8*n{=z)*}B zW{$)$hS8Ny?#3=gti{@2QQYG0ZCmx2cUa*&?;bIK;gmyr68qd&BOVkU3)m6lA2H_! zb;E5xyejjG8Zi}8m<_pER#mACnU#u+H)dWIq~9A5S}?+?l7g%7C$K@+U0l0btW!(U znjKy6D{yT!?a&?C;d=~a@OBguuy<m`3&0|y$z=S2YfUr$oG5OV3bv&rb50pon&i}^ zb5Uf3lB~J2;G13p0cHJ+n*_4EPVMJ=klKZW??`!2_t)pBQes67k5*Jgvr<~fD4$2^ ziz>O?Uf!O6xtOu7es!@@{k7TV=U`b8O`=LvXQI#sz|UR|rt`&ennfDuRi-SZemJc* z{XyDvu2*g9lLMvXAi(O^O=nsvfcgJ*$@Vk^qytFTQ7yQu+BR5a`{3J|1$_#>FM{j# zdr>UcDTXa;cC_9+h6ULn`wZ6&0#w24e*o*?wWRr!(cvj%YjC7G5V~RQCkZRlB&mZ+ zQUm`YkDvVQNsq4$SB0`-8&<VD{@AZQz0ro}@rks&66jV!bt(k>8KdGyDmRMrMAI36 jK%~)V<pG<#WJ}41_D5+ewB-a&#|?ZB2kj2_+{gGgU6jgG literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/__pycache__/py31compat.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/__pycache__/py31compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6e4bbb9583b0282a6b992517bcdbdfa54fa182fd GIT binary patch literal 1213 zcmZ`&OK%e~5VpNevP}t~iUU$P><JMG8fbY4389LI5F83pD+((l%UL_=Qtt!XNt>uQ zdgMp6H~33?<-}j$#LOmv@|xAojP3D!^YWukr%ix9t@hvD4hZ>*iv@+CY{Kte0UMH- zXd1K0MMV@fLB?ZF$u7y)Inj;%wtYbfesIc6Gj7&0h=XTD1&SXN#Xqu`za=?)0~Xt) z+xP}vNtaeDJ31>1EA8Y-YIWiZJK0L`Y(Wf^P59k4V4B2Kk(enO2a2iSn8aLh)d1O0 zP1OR~R3Z3ZvUqR$xgE{vwYHPUrCDio<QI^UT3|*=k$ZjUqfF*<sO{R%i@T{Yk%!B^ zh?F+k>qri~wg=Lx>rsE?qXV>%#uZUI%nPfdm)nud6{4j^+Mk}ZwS{$2k<a|3Mg9vV zp%5+-N(}um{O%GkMUIFdo}RGNT2lnlqg&me;<?Op6=F7n)aa^}?JHbBRk_n<@P*hG zIQagdSK4$ez3z>r?F|Z}v~|5~ub12^#r^61_csqV25Rc=Zj9~vp`T_qfrfc+r&p%s zjWl;&8gt{$z5d?*s6XsE?MJ0A3ggbI<z(YlQe>s{YvrU0g-G+%3xOFp4vf$yov!}f z?6rmEZxz5Q)D>ugazx(GbEY<cb(dP)u9KTFoYiVc2n{{7LR^NW!y*zoz4A}UxnWXA z26iaXNsYM<%4Efp6AH*MYNxCo^-G-i07m`lY}Dt&j6Gp>PuSK@msd@<H}a{enl|%R z>pI}7^>X_uHowd3$g7q<O#GzOaR|y-n$b-2Rwnw-w4jvw5KFlVVY&LfQbt$k`TrMm zX1~>KVIOcvgs9p=WQ7_T)Xxd=VI<A`q$PwZ5+Upo09XXD7m(rXoMBj=`cZX2akvT_ zoP|6L>RkW>M=&VhpJQ%S2N1QFiIL8McPw#jSuH=u7w_we*k#=Q2UHb4n8o`LXThBZ P#u*P7y9k+wG-N*jmP07- literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/__pycache__/py33compat.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/__pycache__/py33compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ac4224d66a4cc7d015ad94588e571ccc9e926a3c GIT binary patch literal 1436 zcmZux-EZ7P5Z@2`&gb~jrbM)*2w6pHIH}DQBB&}=Ra1Iuk!U~=`e9YFeBRB)7oY9y zZbI(ldm(-7GvYCMK|=5s?JH0D7kGggpCT&goMt>bo|&8Z&8#1GyFLMWb8YzQcZZNa z@o-KaC=Y=3&maU5G$+yGNh8{vS;VG6qw$D8C&d+qNN3Mi_b9=ipb>vb3ibk{Snf_* zQ46d@@Vq_oB99W;iG0aUmV_hRQx*k}iD-%TYa-gmEb7W-NrWf6$2__KIu{-3om@O6 z;}x*12>Lzg`DaiY+3Hctb#?@grCl@0<0?^FD(ikzZK~1CFRQc^GECGcMfY=JpgaK9 zAA*nsn~IpAg1sgY7hE{-gu>u&TK2-jsgal^PRmJ^m=uGN@QM5-utqRzT9X*MgfNPQ zIT+Pr*3mNGQ7!QJjVQ$Sul;_dvcts4{$Zl}J7q4U(*4P9KmD|d@6PUyZ~wTlBWC)G zjYIX>k(o_y1C5IQcE8H1TUnt^lIOQRzcbw3I~b1oTAG8(lx42pR;%g8#-il)YHGbW z&Wg;$@q1Wq(*vDd`A=`_=T0dFFC;7%)`K8?`VSC>oWOW%GNxm8%I4JYg?>!uOt3iz zc8-3kdCm5S`V}DISIOM1UE_@1Jy*R!i{O{ZRfG$WMoqY@<T9y2pSQr)x<lr?iD>OH z^^0kbJ<*0N?YdRBg?CI>$=un$Q3RsX_;d6(o!YHi$Ltxb-~Nr~M09XTX7^uaG8f_6 zCuMaLwxG8bR!OG9ol=D|Nq57tk}5G-S%g^;HoH;|$1*kH8Xndx9V&$4tPzOX8RREt z9JRlJG6LtVo^Rbmsbtzr*|yUXmPJU*b6Hp}GHtt0HlGdR&F>!n@N}@XZG*v!?ZMWg z!6P&&%xk+@VdO}v*i0*_6@uRLR2yHpLs&s=xh!`quZ*&RJTkHnQpC`cWo2bKC{ZUb zi%}Ebtl2_zFau8CK<@Z`IOz}s;TLJZ9O^KidB7nBNqrhnhdZFZb2pk4TRj)^70E=# zvGwD4Qi_8d^&pP-50ZTGM&XrEAECe{dP`tM$^~%=SYx9e^>|~k-uXsa@1T%6O)A;D zq*gIv1%zEn%RGnqz{Iq5@XFhzuO?Ng%s{D9MJxZ_g>?i;6%D%4wg1`I;j^(mDGvc_ zoThaUciV+_q)E~|(HgtMUIg5(Ts9L~6xkkui!n-F$3Xwd_S3JwZN59|V=VL??ON~N e0;T)7Ncsa1&@;fy0Ptn%vjB&|0=|4b;Qs&(=Wf*i literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/__pycache__/py36compat.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/__pycache__/py36compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..36522ae31dc4fe966c32a3448f0c0a3adec6904a GIT binary patch literal 2208 zcmZuy&2QT_6elHFmK51Z(=^=|FrmPJ8d&1C+4?aQL)WG&uwhxTbxmh<5M+^dnCL4c zo!W-H!_vbJ+tA|<J0!;eJMJ*_9~r>wPW=~p+M^sd30exI9v>gy`|<I;$J>pDhoJrP zZujw*a|r#XC$nY(aSOV52m?U`C#a+UMuJnLV_;32iJ4j*tD>!>mf9T~qkD+di2W21 zd*A5PDcW{OeFyPxfbSgh3H}zf+!vr5ZM3jjT4zEIBum8Cg=Belm-Czh-xZR}yqo6< zOls?QZ+~|$)_Z2{70P#jLs174)G-L|n1I0~)>GWEhyj*t^}e>iSr?4tSy)6|&@j%k z9_xoamQXSN*9)M1#fB>^3ksg^F~YKb(98Lgh?A8#Pm4&hE=!mkX>QOPWU*EjRUDZI zU0SJNS)2?AB|&!-5Za3di45{AxIdCx@LOBGw(3=K>v@pnGN6RXKyJ|>&It{`w%lSO zh?7W&fDU6?z-k^03KB_r+GeFC5&=t#gr+o;U=#L}nJZT-fsNQW@>Uc64d{2Ei+?a& zD~9VtDW1S}N@LrEZta--x^|tuL{f(<bBRahh))`%N#^^FiJ4h_G%;nZH23kuEWzbF z4u4Rh1N#t7u&nbg&<<HR#2A$Zgvps-@x&VbUgCB1!?Q^ZBz~?W7R%Z)s-&y~x2$Pu z*ek6A?+}4xXJP|ASK5boQU`gzqMYHavJR`)CvNGIvw-$_>6YeB9sbrqqqIx+(3p6o zd(b3H<Q&kTx%7HQ>6GqGwEKJ$?f$WeKz9BRVYJIP5m_$L_QH<+4D-K-2bw0!Z=-`V z6^h>;g9hkxpc8E`f&~}w_@mEDALJj(vn48hxm0@l*hl*&M%hKcb-vQZt5tWpTCMq0 z4oHLKCdxjvkUY2Jfu_GOnlvyP`*OK#?Bky>;DT?`__6T_eUCEZ5qgGqFK8}=^IIDn zt`9*@_;;!pzOUn%kA0R2870X|HxhKbFq;)gBrDF`jFYhLcz!m~%cmIwPERqmXhbL% z$6G|qSs}%-L5R*s*#)OPHXP5<A&pn26J>4XDOJ`0@F|Puxg1|OnTo5gr{cxdCvdU` zgMj8m4&Wfk#(ofRK%rCe1EHKS%%YTr;Y+-taH#Bll6Rw|WvKcd<=tFRRVRED@<G-* zul#AESC%-p!E?$KBf;yMn$w;MkHES;o{woJs8nZqEF-5%1h=%j6J=QrsSjt;fRrO> zRR)Br=T+?zYQ9fpIGu!q#ZsBTP<2kh)36V~vy90wRP#_((g@7VcGj4rsZf4K`*7?% zsuxrp;6ze#uB)B$9!AN4Rt1vl%x*Q6C1}!9uC8O+D`I-YChKQ8uT+2o1>8;*B+8k| zX~h+EuB)eVz}695ZPnb15^xibRSha!B$Szo{-20n0@;_l?SivCs7UR-h_`!rqQj$| zZnfjfMR;R;WBbyRwH_IZt807w%21BeOVIjR`$4;41r*q6lzx1zyR|du_S<m4K_Q{a zi<4wATDv+eyQ{@WExsNo^8iJB0RzIm=^Hk-v4efXG91Ifj$vWX@UVw1+=NkgJzu~+ zd`p&J^YME?8L(>!))tKgyokqFP6p>2-ibHFYYT6*YTO4H$_v9ZCxZkcQ~6=IJBX5L zoT_>lk~|JWeg)(zC!QECYhDco9g#wZnNzoL#cAOe`r2dYubR&NThN8JdHm`@VKAya z8!fYf!`EP)f20R}YbS<R2DSHu4kHJ*Tz(da&cg8nLiIB&sxVW{W43;%r@=UX%p|ls r=vOIHVNgCKqR?+G%iy(qgMH=PociiheIB7-C%8TRna$5UqiOvQnp$~$ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/__pycache__/sandbox.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/__pycache__/sandbox.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ac10cd00228447f45977af1c9a81f448cf6b0e3d GIT binary patch literal 15552 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/__pycache__/site-patch.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/__pycache__/site-patch.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7b2a6f0edd0220da28d11d40fece5ea9be13acc6 GIT binary patch literal 1518 zcmY*ZPjBNy6rUM8j^j9Ko2F$89CARaa%fXpL3gF90(KG0rL44-x*J*<*W)B^9NU?h z{)@&JvT)*1BtAfTgD-&g$cNxGCnQdL;RE!5c;l$6WukdA@6G%3dw=3DYBdMJ`ssty z<9}_0{?^R>B5?T(HvbR^MHIh6T@+$UhJ-x`(G+3yEuzMA)HVaqDAo$l3hc+QxeFdB zrYJ`F{KPqy_>9a9N^WsZB%x?%^KFUFOlpAFhm!DzeUy{Lm1I@|T}$hUvP9I3(A3Bc z(6vQHk}3H8fvln21TA~!h$?87u3k&?2|D>Tx1=RYL&Al$_>W^DjhP{}ud*yd%nExg z%QKgjKw?X~ko+#~SxrkYdWOd0x>X>r=M`Den$qgyTXJmVPF~I3Bb2O~NGuE;_78?S zV00;7qJ+Fa($P7wyRn!w!4f=5M^>eKYhrW+Rg}(b@fP%76j6@A2eqd7dn}e{ncA<A z&hH7D;wjE+Mcx&PA@4fH5_yfQRY@SfdTxnj33eFW;PK%RSefXoA?v${fR<=Vlj1e- za!m4te37Dj398z-is#->PQkvZ?csenZ_1`z9FiN%{*X%=y}m(>8-QU6-fBbZ2J=7P zzWpT|vlU%UjFKkYSLG6L1S8OJb|DsE`UNmGbTpV7=+hohn3L+k8$Bh;dG_+~={E<@ zK0kb_N|#Zxv#pjhUktoxl%-6B%nSTr5Gs>LBAk5mI6aSPvMyS^D4{Je2wN=l<JP)< zU2lz2dLD-X)}CSMsWo9ghh0o=AF6ZG%&|Zcs!GusVCj*c$=C!$_>Hz}V`Y#0VW=^* zi6Wa@$^_q|-w@M(kGpXvW6^~#!p?=yI=wWeA>*CVpc8zYd5<QK&bBUhdUV1+-ML`f zS7I{Sg4Itthn+0SHll<JKaMv(**zT$&rkau9*Xl!q-o6mcZG->fFKxbX4iMlUL0`| zq@!%VtuxVSS!nXU=bfgh*xZZLz>oPpT<+CW)$_uBAEJd!FiWTPo-+6~S0v@C93~eL zOA}@EL!s;}_C+scBUR#A90^s{sq-*XWq9_5V9L}IWyE2k$~0n$KMIxYdA%qOJx^72 zE4+E>RW(liw~PTjRMoGGMt;dy%2X+cQx46fQ6N|ia4E;9R5uU&va%LfewKv^Rn{DR zdxh0O%oa4!nRksW3c6)3s7BQ-jjpw+{?I7<erA-VVT6q7&y}*cfFT*NRn3%W$OERT z!z8^-ydqU)K^HS945nR@&~9ZO+4G?|NqAW(DV!;iWW@~3Nwsi2?|~j1{v8m6ZTPu( z6<fq5E^c6#IKUI^fE+e(CLwTtfa`@W!GttHY7rYw7fuJ)Nu4ZW6Et10Z|WE98ZOA$ n2E<?`AP4O^qZ^?c;(702)04^yfcD<JG5ZBXJqh+#Hn#A8Rg00~ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/__pycache__/ssl_support.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/__pycache__/ssl_support.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..475735c856da40ce4da3f67a5b234509614ddebf GIT binary patch literal 6807 zcmb7I&2Jk?cJJzLl1+-DWsNL<j;HM%Z%mC%&Ubd4nTZ|SV;h;s6Un=tbY`}<#VSgq zn%#6&(Uu76vT`sEkXh_8*gdRt2#^5z19Av*$~8a`AUX6QmmmvljydFzQ+}_SAM!`C z8xmbzUG?hKtM~ot_vYs-7Jh$rcH^rn7cA@F=wtGmL+3gk^|#EjxW!p)1^Jr=%zWE{ zZQf4cn713ac-wKIR}6~1Qc&u7f!8YsWk&0qxYC;o=6cnj%B<b0Sur2XKeUolt|e;Q z6{(p;f6jvWKe7`0ON+a_z>B=Zz0E>!jF%4<4y}XZhgPt-yC{m?*Sbr=k|=dg1Sf#y z9Iz|{%irZ##7Wl*mVy&GCNa<1b~*hgaZ)Ua6K#9D6r9>!0u7aTzIQq}-8&PUVHU8g z<+S{i$!j^D-E)ANi_a32IY$-!3H13X^!roVPlNt5`L5%=PydvuwL2D{=e4I6uZeT} zPH<YB!DyGi!58@Pr!07#FY?!(TEQ8>EpZocu2=%xd3>MX%lKXvC-D6S_xVZgVTI36 z@zYpwL0sTx_}Qn{J_|1LbG(4D@9@|8dA#4`Y~89~_!Y@?weDucfsEtMMmD#lbw6yy z9g*nF=|%ml*zUwy$hw^!TN5gc2fC9cx1~&FcI@_!mQiaqaN-9-cG|n0Wb^KW2Vbn; zjS?OUnbq2zgomvt+!)Y6R_&-TdK`7)XairBmXJE^M|w+Tm9#GsA;WemBOBUPX$swH z_P0At9jhh*qK&TRcp5FKa{#5{*(5=A+MQOUg~~w&N;cJ2Bt`Q%z@u0QBu-mVJO-R@ zCDT;DyiubsdX?t-uF|5{{JgUvBe~nW58Bt)Kc7$nGIFs06Zh3bjj5!Q8v3T^qfNl~ zg`2Yz<&3ZOBHh{ww^F5(s3+=7&O?rP)$nSOOea6^Ft^nzI>I9Rgl&@SZL?;z?qpsV z5|%K`Dq+}5`5>l#H4GmOqBx)VD@!f{foc9*Hv6*k80>96j%2f)##~6%>}@q$@ASiu zh97m`e)3+M57me7J(ln8=wa_|{5F&3gJ!?ezuHNZj^g<02fw|swLRF_Y$~A#eVwKd z@X@Y{LpA94Q{v*Tq4fh$plmc=e%@cv;aUzF`jNjX;<<@O{TG@|YtI>3s!FFFSqJbx zhiuOsx!gHz?G^Bb5BU=t{o<%_z<3d}rBP{QZ@cnyZS#`G>V0++&yU%tq<#b(?x8he z)Nb3r2@kYwOFeQ93fwzn%t}55rXnvNGW85_rYC<!^SX54jS7d%K%F`|a!}?KK6eP( zn6-0mRJ>(<y|m{|A%K@=9{tTj3pgsg%I6Q}M$RGV;<b|)>sAl#z4EAhFh2q$<a%t_ z{{zwv7@;4vTB+pJ)2YAq*-ih$ci#Qrim!yRS^vYv`;GT16@UCA)4$ei8c{SlLbn^K z+-z>?Ufh)J7A^hGc;(f6<z(S!8EZ%qhFn6knz5DP6=3muQL^hl>BPJhNv`}(;vcb1 z|JLfdPug|O9~S=jhmEh_8oE2l)vH7MtCf6U1>GBX8hC<wEi0&g+|gN~l@1bZG$M1Q z=*z4Sr%&K!icudH$g>I*436SSM{i}e6j@QIR@4_+3BYmGLZ_AX`W?6)x0`m7ta9(p z>ixCbH*c)p&I-n|>XppqN#;!qEST>_JK^*sfeUY?vO=G>3A|Xebq}VPm8IxKaCM-i zJO$3&wv0A22TNu)BwqugvRcR!Wem*h`a2j?D`>2O%kXzA%wts>ZNX+W$7Krz&#AJd z!lHA^sjwyc9FuPWx<xiYzY-n~k1>J&M2FO0BW#ii!yIg=Fyl6Npfb+R+am|ccKIuN z&&|yN%6w7Vqr!;o+wwXuK*j9?htw7dc<~{=)X#Q4GdPNb1FJvWD*_KG?F>%|c)C+O z&tAaOeP})U5tP{-+53!pFt)$f1zsL8UO6c0lJ+nTV`$sU#_*DrDWolb3COt-8`->i z+L}Um7@emR(oXeS^a(UEk3+uRinPB%O1I))hWc^QO1a=Z!V5U=N6MFQJ~F}3#_rS( z;KSF`*0#`%O`-cjNJ4PAUWY!zu7m<w;jc_|W2NC6(|Y%N?|jckz?<6H6rY4cRX)NG z_KitZ`4xX-p#6Ja_z~w)C^eo=Qqa_DiN4NhJi5uuOka!!eh0^hItpvj#BU?44y0)K z_Y+?YfJ~_?hT!%fF;+h#%N$+#*p-|`V>&TBDSCaq>!%WPM@=@Xsli4U&f`X`S7EtE zpEC!ByqcB9QwZm2ua_ofp4`FkyAw|Nm!!{Ap_1RyIV*hu6BW`=+x{grw6FNXbN@T+ zC23sD@DtDkLzgLn5Mq!&+l~l+o<P6d5ivXuyaO>G*+;#cRelh~1Ca+(2NE_mB+r7> z%!x%}9E-ewPw7%~8cn^FxugX05<z)mt5un!q9k*+#co!3Oh_>>*m%LpO-xR)PBqY2 zo(rRPS(VlBuAo<AuCoa9&c7Bh<JxCTyJ){0&&kxU<551ESv*Ic4YNjGXQCS3h)pnt zk|cL9{A9h;>&L=>Jju@dtvoZkMgooodJ8dOu+fSmQbnjsrzg^ZMh`hjW9nXLZ;H0Y zy^v^OidJZ8b^ymhPJ&z5lTk`hK9cM`mkJ`+=p-E-hRADNCE~XH2#8)}8F|8=<5465 zixt`M{3|od#su4QG#0Ri=u|}GGerJxtTy9td`~^ZNJQ?sv)ZC?MZd|RNd9U8jfU5J zW_96#M(igPP;nqTTYP^1n`x35%IO%Svzfj91o_v;K#(8CIC$^lIO=Wi=+i^Oj>j6l z`#hp?irk>st3t|t8y}lIRDFt0zPQe^5>L$}vNqZxbEJ4=_L=NywyVsr{DL;jx#zN> z|LZngtrz7nERn<kd7QQ=g&|K{VJJx$l4O2FN+ubkJ&l6>IXa4RFKD*yxh?djzyGho zeu9<5>n|y63k=V*mfuWgN&fUB7Eu59@u)LsG(<as=0d#APoT3S=x&H=b)vb)jJlG1 z^X>BElakimT)dy6pKI;!Qg50Uo0x9E{}SV4<}a|}+2@&0sAqaRQA4708oK`l9~z;0 zWOYGZ*J;}bf(YZ>+NaRXbOB!olk%<^M~%Jj$h*cGiwMu9L)6Mx=k3`EzPt9GtqZ!$ zU98yA<!%LIbG+~^Lw@XZt0tfpza>5tlV!|f1ns<mDt(JAI4tfi=^DO^2gi^BV`ozl zH(X0EpsxPMyuvl}$HCu4@&)GWHKOFl*0^RT9($_@BIy7jH5|u2D4HIC+c7GRykqK` zY`G-`{CmhnI~v3~ga&A_qhSoiR)m@qRZn(I3Hcc1;v{Oo8q4ITLzsukJUAixQuU>* zs7yr9j*qd<^huIDGnWdDtb}k7X)UwTR-{bFrFHTSK;&J5b5Nnld-O>vk<C4kQ9m5x zp1*l}?LoM9`wzc=Z|(Li<GZuDBPoQ5ESaaa2AZc&lB~Rb_xpgq^>7V2ZJa7G(Xe%c z8ih6Lubdf9OYgj(X_UnpCH-qat2fbDh$g4pWw=YP;Mqkajy1N3v~kh4*%JCS#GB!n zS7_rH(aTOi-U8O#0=}l+OxI@)fDHC8@EmaflE$VUmQ<Y7n_P%Gg@#P<z^3x5zo6ZH z<avjzOSu~xUcV!d0{OU%AXj*~j{MA|>^)pZ<k{SSlBH>Mp-e6hYgF&!Vgi1QJPzgh zj|KvMxw<hx0b-n|kj7idG6A@>0lep{!VlHT|9~gAVY|qtXCd5l7IG<LcXGg<A^6Qg z%s$&=BZ?acGJrC_NsxI1U+NqhjSz#h+*ZraU?~)6o>?KDE-kcSBT@V$+EvhFN>3Hs z{u)-v2n|J?NN%dExc!9QFawuzyIeRX4wOhM`$Cc*F=DZx3sp8ektQuMi!Wm+G8&T{ zQVE_FXp}bOw4tDeWDQQ40fXNqJpW9{i5C`IF32sspF1u&GsC4X(ZQu2oL6k^(M8%4 z+y;Z&@W&Tpa0_2rck&=jNsPy#8C`qd`BN}y-y&`vINUW(g?gqQ8L_SlRuxxGQaIfi zdzoG7t*)S%q)6Y8gzP*C2%Pa3us-zy_Zx^bApI*0FTz|==OxB(kdv8li_-4TFf!Ez z(rY>)u|%CmLqf%sfqlTp?P;o=tgfMZ5?%_ZVFwV5F)7rmaA+uKJt;OjxJi;S0G4q? zhg7`DmRUK(l^l{YMB|y^QC$8d?VSsu#)fbGdg@<}Jah~amN^EoY<KbbgN#LHLuB90 zMRvrWQ?@5NSY>F>O83`IVm&>CjA^b%&5Uw7=6~Q(w6Dc%hWwWeFaHMA=Wg=FTqXBV zgf*KVbE+lcc+4%(LPX$Y$e?qYfqzHG@Xlj3*NkNL%^R7!cK`l^dLgSq4NUaVDee&F z?)4}_n8O*^z(f2}X3nJ&9u^~kFesDym~|7oF&r><v+&{x|CLA}zF2V4R1y^J<+&o< zbcM+QMyGl`(Y2ej;7v3dHq^Dd4*aLRXX(Pe)xW3_?8&L1SK6mwYY$h}i~~Vk>O<9( zrmLWvH&A`jJ*-c6u2-mPT1^wNTK8lDm@_+72#1);iXBBZAnC&2(380dLNM+v=zzFm z4WFQVLm&>0V>n6>q$&8)T9u1?CUbJSbSsz3+^)f^R@n4>m@pT3=6ps8$M+UwOY5*t zjd-Emw)09Qgu^V2DT3f|iHULt!onqH!4N1F&`U~CC0&smA#FzA5EHQ4nNH%Og-IHP z;!q($b-*S07(Ka4O_!S2scEAL&d%;G8(@ZzNkesZ8ol(fP$ncvhhWK8b2iWSw>RP6 z^JGXJq3!{J5XF>&<EE63p|tGu<w=?`!uTQeu2FNF0Bbjpv~+N%FfMD0sVUPX-HGP) zEL{u-=Qg6&HgQHZkj8}OI%AqU$+roZ?vwH;NikejsUhEP#BU;};mNC5n0X)Pm&c!y zwyH1Cc&KsB-#%q8j8(jXO1D_8;)^O?WF_{JL;1-9{6H1$0<xF|WG@RYGMM+h`ojFe N<%;K(tEarm{{RiRs&xPW literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/__pycache__/unicode_utils.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/__pycache__/unicode_utils.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9f793ddda2ce320748fe237efe027e009f5a5aa5 GIT binary patch literal 1185 zcmZ8hTW`}a6t<l-O|!0oZ6E{^%EJWe#FoJXY!X5URvrt|fNd41%3`<8mO8<9dQ<xZ zkNk-Bk-wBzc;PSb#BtJHgd?Bh%kkxW-{-tuUUm?aANNi^|27c%r8^geK;souxeJCO ziX+r2JZ@p=lZf<<mVps9sQDeWOj@EA_!2Es8@xsF0jgL2z-rX2<IIrZD8RZ0MSC0S z8>sRV7=@-t;ZyRBh&#$SHz}T?IXOV%^(i_pQ8LFfbTvMM=yR(WJw$xXM5=t|i1!#a z#^@Mvas&}@ywPkK&A0oLQmQ(eyLCHrLK$+Yd>$~NGt4TAjZ|BW6P7KdJPcyWsIUC2 z!ei0*qj179i!wc&S&Zkt`mu;>2oVd&%uIaM`-#L7?DtoBi3kV2V&1?PUMG$y6VmJV zyx?)t-ka>5ZVz`lbRwVa48)U>n)J7!bh-DzOTuI`zgrY-K7D@DJ4;Wxo@6RbR2)b0 zdUJ8ncB;ZiZYATaqOaIbV#zeBas>>+Rrm;Yz}DciuvmuCOA1WrRG{V*96{q61vfN! z8tyqt?ovF%Q%rG(%*beKO7_v02Qy>rXkw<u99RbUEr7pSz(3qLMqf9MpdNxsGzpVq z$A!}1G8N2KJzs%gZZ{k-?rQMdP`U-k^idw#eAjHa!yZiY*kz-H1&UEO$3Ns<cNmK^ znFlVIZPv>I1dMV{g-#9hHkR3~E>oQ_V$fEsf3aSab->Dk#{Hb#f=pBB2hp-RvJJtR z6Zo8lpa&*10|s)63scow)E0ZUi_5RUSb@D&#U`m@n>aZGH7r(PF3^h8Mf*$nuR|wC z6HV~~O$=z>FVNJl=m=gP;7BH(N(FZp>|enVauvJ2+evw#!kGJ!D`JoaXU#eh`kc#L z8@YmuTuEk0B>+yL<??@OjuK;y0SNygOiR5DB3e$6%x!1`;w5mR2BvlMN~c@!o|xbT n6IyY3>iLpuXXv*gat!Sk{g|c^d#V2kQp0ZpZdKE++N=KnMBO7$ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/__pycache__/version.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/__pycache__/version.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a63fddedeaafb66871351c151ea5874b68faf586 GIT binary patch literal 344 zcmYjN!AiqG5Zz5GO(T&U1;3z&y3t~#AR+~?UKG?IEJ=5prb%{}-A&r&8$9?4di0m} z>d9a5<VGs`hM9Q-Z<xo-g1`qB&qwLgi|rrX@C(n9E1PO!3jqX{AO_ozf>%hKH@I?Q z_a3mr9-zI#mk|VA5I1%o0dpR#{uT^-pLQ4A7++Cc3(a|{OuuFY<7+nDGl3{FEUDtP zoKt1OjA~4BrDdMhI_J#v8!A;t_A%a3jLqPBGpC{xyaPF~2Y$*ILqg_FqA6+;i59#h zb{SPmG(Qn|+D=!|db}X5nv5HHy3uVFS!4{|A(4ww&Xi8da&&f{E{i(N(4Xc1bm!t& YY>jtOaZ;D`5?TwYdza@pFoXy28x&?`C;$Ke literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/__pycache__/wheel.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/__pycache__/wheel.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..69e33c4cae9b5696fd8c02fa4defe4d0d788cff0 GIT binary patch literal 7032 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 JwJmSu{{X}xDw_ZR literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/__pycache__/windows_support.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/__pycache__/windows_support.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..44f4e08f05a3389bc47e44b685259549d115ec10 GIT binary patch literal 1027 zcmZWo-A>yu6t<HPLV^9DZJIP`%H?`N1FgoygwS9u0tuA~I#r4$g*0|)+9b|wr=?Z7 z8Qg6T0hfD~Jwk4G#VhP;$En!Rb|jzk**gAw{P}oydAWqZzP;#t`k^88Q%&wn2k;Jt zcm<9if+OV4B6cy+h<=4!jcUXob64mRyE?%qsBGRsHfjb~1uzwX8NG)go`aL<8s7lh zK<7_pEGKA+V5iZ{=i6aI*hmDBSD4zV7(5ul07q0NZhl8)EjN6ACUSEyQjx223-@d2 zq&yt@k~%}5J6#qL%7qj6oM1imHYc0?wNb50CSs#D<kfRIiPyl+5~t;)VY(V7Li$m( z`ua_$H^@3?j-WD2C1a7e4@a{~J&~m;<Fb;Db89Q|;|}q+=T)^Z(B$P^8cU*aWh-KV zABk-MvqZRrl}5hoG9Krq7z;_`GR}=|mIQw<#7&^em+n)|sT0&P!b{k~d=bze$(2q@ zjY9H6021WB#2883*ZO+jxWIts`exzhyV?|cR)H4)m56o$D^oPpF0~7Ns*8PzuNQC7 z7ff{ZOp~uA8|;KiTlT2k3kji#?MunSP9~|%U}AT}2oSeP$Y~%MA6H7nu076TyC-G( z)^R}RV8DiycOy2c1T1zwXH>|LCBj+X+^AO9Yc*%K?KJge@6?VnA?*&eB|Vpwf^YIL zkmHn!3aC?nTh%hn@={*%yf9Wz<9WF`OUg~9VHD-ofbxV!wW_-U*Vuzvckap;ZP&Wv za?QgJ?UUBAJ6CTX9oKUU8m&0QHFl4V4)b{q<-+N%)ee&e=Zu$)+)$;ukN@M%pY9zT zHoToy>-b>zW2@oqAJprOX0CH8|9$HP5S4mLL-nxY5jeD9;SyfKCC$)E*ueZ5td$LJ jLEsORQ>n%3J+|Ug6zyYe#f)ST-B#bJXdMe%x@G<bT+s|L literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/_deprecation_warning.py b/venv/lib/python3.7/site-packages/setuptools/_deprecation_warning.py new file mode 100644 index 0000000..086b64d --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/_deprecation_warning.py @@ -0,0 +1,7 @@ +class SetuptoolsDeprecationWarning(Warning): + """ + Base class for warning deprecations in ``setuptools`` + + This class is not derived from ``DeprecationWarning``, and as such is + visible by default. + """ diff --git a/venv/lib/python3.7/site-packages/setuptools/_vendor/__init__.py b/venv/lib/python3.7/site-packages/setuptools/_vendor/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.7/site-packages/setuptools/_vendor/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/_vendor/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..87060513ea3897922f027eafb8acfd82f5fdde4e GIT binary patch literal 206 zcmZ?b<>g`kf*$Fl7!ds!M8E(ekl_Ht#VkM~g&~+hlhJP_LlH<ALHsJ$FDS|^ODsv% zFH0=aPs`6qNi8bY&&|+JHY|v@tg_59C^t?^sVX)zE-NysD5=Ud0D|;9{Sf_v%mUra zyyB9?oE%+K^Q4UI(xi0#;?$DTf|C6FoML2Vd|7H<N`8@ke0*kJW=VX!UP0w84x8Nk Pl+v73JCK8lftUdR-jz6J literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/_vendor/__pycache__/pyparsing.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/_vendor/__pycache__/pyparsing.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..44920ffe04fb288817f6b211a1120e4fa6f81379 GIT binary patch literal 203049 zcmeFad3+qlbtgVI1_Ka0#Y>db1P=fb0G^^K3Zg}Vq(qy7WRkLENb+caYJdX_X29+S z34jA10%cK-<tWG6j^iYt6FYX|#EI=3b}lD&oXc^X#AnAzY{$EaHpl*QXSF%@`+e2t z01zo#+1)>Wz-PL<s;ldK_3G8T>gb9Ug#`ZIdgIVz7vGXj{22rOUl|Yg;AeliC6Q2x z!GuZ<CRJ)MrP70Gl~LJBW-x<$u9BU|4K^hc5|<y$%e{H9S?-0wg4|mMTjbt4*edrG zgDd3THrOWjm4hqgzG`q4?oE}|6RQVTClfOa<tu9@)();sCLT^yjZDH^H(s#bpG@#y z-rk_!zBW-!J(8H&g1F|&`iTvL8{~Zf&l?9f%GcfA*MAp$-CS7_Nx4F&^m1a^EqK3a zaI<`URDb<k(mJ8Pm)f;dZVXav4pQ9Xm5?3WtaH;>)v8vgHnmc%QmfS(wN|ZDH>mY$ zgW9Mzsm<y}wME^eZdSJ_Lv2;<YMa`wcBq}ILv^Yyb*s8fb*moLt9Gf~YLD8h_No2q zc6C7Ap$@7$)gg74>Qi^C!|E049(6<=RsHIiI<8Krd)0mFq<W=#l{%&FR|Dz+^`LsS zI<3yAv+5!B8uhSxM7>rGsz=ph>T&ftRa8%?k{VLON-0x~s8MxJmDQLUR~0p(s;Z_Y z)p=zpTREfU!7b)ZX7kw1^GTIeQ%|KfB?fOXZ&8^|2{kpI8Z=Dfxs)}D6k7+|&259* z%^ia~aqloY%`Wp+^ER^^-}jik<}P!$xo5OxaBp=8srMoE{=wVT1$FUqVz6U0F}N4w zk*ypUJTQG!O)uPWHE}HQ_<_NLGwaN~3wN4_%me1Z`P9{<j1@=XuJHm&{%t)H&!sND zQ;)%Osq^oAIAQjw88v%3VcxDT%_ol~=9BZu!Mjym&7riz_a@Zq)f+A+)EmrK%%=zM zF*9RF@H@I8G1#x(IC#uFrrw0-<7U5k4EGb}4)r9yzgNvK+@~%}zL~L;%=Kz=@Ri8z zDYXr`Z8Kkm+)g3<X0-$19p)*7???D))q!w_ga;75qPh_7G6(Sf0fe7X-3WKf_YWfc z7WEwne}~lW)d;^;bt2p;;nU{Eg)`=9_Jn#?y#nnytKOy_#Qh=lo$7wvU!$H=--Y|b z>buqV;QomEUiDvaf314EdKmY?=aPW2cdGBZoE&@<xxY)@irjCN+#f^u`_*2A_nMEP zc8??cZnYNSwdUgpzYgIaP&XlblZ1;1|Dd`N;Tt9Vg!#l^$$Y|mtT==>KcqI|%|>}M zjPQbLL%7X+0y!y!uc{RYuP}!ZHW7Z0vJkc;{RqN8tZqm6b_tIn{3EId;T{Q}L-@Vw zHiU1Ja2etEsg($?l<*kBKdSa4ykElO2)|!_0O1cvxPtJHsr3l2H!CQA0^uK5n-ShD z;VQx(RGSdqB;gvuKcRLbyj#MP2>+zoh43y3pGWvZ>JEhOkg$dDPpJb4ACRz(@K39q z2=A1hbrAlrYDKu!bWr{j!XHuX2)9f40>U3vTM*tN;fo0Wj9P>68VOG${IhC1!rLXk z8H9gMtwVU7IfMLW5&n5~Gr~7Z_!7b&Qy)k8;}WhT{0r(9gl{qHNI!@0FRFtGAC&Ox z5&k9h%LxCnK*k%)H_Rsn--y^>QCktaRdRU~!k<vR2=_|(NrZn@-GJ~75}rr+*VHEw z{-imNQZ6I>DYXybee(V(gnwPFLU@(=6yCoX;ZLg#2yc+^(+K~DT8;2(3130@H`N}5 z_el5|gnvsJ2pdw%x2WG%=K$m10T|z{epj6UjK3And(>yuQ9M7ZeouW4@870=Up<8T zcd9>7XK{Z{{h|6i?%##9d({`!YmxT5)tA)0i2EMI?NeV?6Nvj>^%Ye`+<#H7n#BF> z=IiDY3-3@TfeGGeR^|BtJb#~Alji|EzssDI=TSU=zj<DsNAUb^bJV<7{gHZy`s%ak zg&$CVtp4P30`Wg+o>PB1pG3^pyqF(C%-1F68(z$U`Ge*U9Zi@E_>HMQQ<soO>S$u{ zs`<2e)qF;Mb3VBtVP4$;95whJ^9l7|=ac4})PF-BKdk=zD&IYA&YABquO1cLh}gei zta={!?nl&rS0>u_UiFvi4DRn!f2D?S|55eV>IvN6ul`2axPQR>fchV-56bv4JpX^* z^N*{)Rey)~A5?#@UXA-tsDDtWasNs6k7^wE4`HMd=7)+ug?`<y{z;ujzy7p&51{MA z^5(<Ek9hZwq9y-~nm?odWj;BQQvXxckoITHpBemF^Udg!7qBY*FSZdQ@UQ5(pOe^s zL+rnMvHyYCpO2=+SKfQJeBm9a1N;1ANK?Wy)(P`t3;C-F{XJr^<_vyZ{j>TPmDO)X zGKfv9*Ptf9fT!E>%cu%Mzi7S}&sp@wFUeC5Prq#b1V*{vJb^b&$TKA+=C7ih$5Mm8 zGWZGeSIu9;yJoI<xEJPA`0A79IXt)E*Sc_@`N@S(T}2%?@coLQUTvt?uOnuqDxpt5 z%{C&mYCehU>LAq`r1}kcv({_vI>h{@#N2?G-?|Fu#TV-l``Z$`!ArLhF~8H8tNA-Y zuWiEn&zPSX{9XBKv-j1Fi2W?SnnSB!seT7JZ+SLlzR4WL(@p5xC)DrECs(3(IX`$O zoN{$u_&u*CHzSA7nQz56G7jeFjwaMRzP{yI^bE%N9=!kkd)XI;axm|m`PASan16`y z*74MHE!O8vh39tkqJG+jr!NF!upOnP2ET~>zlc;j)E98w$=PTA81nrRX2o00FG+pa zD;<dYGVYz`moc}#vdmYmeB}mTb>XW&GCz;+Zbgf~!hB>legUoiBZRsb8vLsH)rCJs z=r*q8<{ymxiG;en(4WRaUz1RetofvpzCQSMeDQVE`UB?I$G$;2MDqB$r0bP**)xgG z1Ia|9^ws7>qA)o#S+eYMb<~)ssi}%-^cek>l5Lx|QK~9q!gS8nlx;XQLzyGxswuJN zv^hNGn1=u9s8yPnKsJTDU(UZm;p{n-(OAJUYi5)xj%ig(PWb|=G&yP2O2g+^%VEnz zB$~t8>v}R|mnSCCIKQIZg$s7C;UIg*Dygzlu2oAFqhe0)nkfwr2N`x7HA_-W*``q& zF)VX*s#3C$@1$kgHoihG#=~XjTv*L+W2QD$P_=4@V^mF3u~HSYWTDCkUo`BQs#BUa zMv$}gC~N0ei^WZpoZ)kfj1+=FVO{<1)+1Fwqc4;d2g<0Fhpdt{!#WOoqvxC}IjoAo zy0c?YS;v|hb|fpWL_?J=bJ(fO80D(*;0(sP+FK~xXIiGgZZ=Q^Q}TNjZW`_PnUzYd z+jzKURn*pYqZ2hQRcFuw)0A#U4Omq)Z^9__Uuy5OOO+`HLsF|A?l$^L3RE1R%RIcb zeXgt97@8_q9Ajz{wPc%5T|&lct{V@h${65M1<xGGQ<siZ)tq5g%n7sV*hZoA)TNHw zI{F@Dt*qlZy0=(F{>9?qIiog-j~!HQ6aZoepNHetZJ;+$BwC5amZqFq4|?c=X*n`v zg|GtAf#^DPs8BHQH)7Q$!Z9}hT{X*LuPD^FGI_3K>vY@vY2$Y|`ll51mSiPeXWT6x zcj|AujN6R%?si<6V>EJWyUzC<hXEfojE7`6iFP?grzGh%+ItSSck2>+Wem?qyY=g? zE^m@~<6N6^Ca2K7dI(X(MRbwh=Gf31J%^1)J0z;3+vw=#MSy}2TRR@t`D&2Dyy1Mo zzzG}>N?Cy4C4jW^Qy6U|E2+{@#l*B@xr92Vv(3s#4`xH9g!x{xW(or0Mzu6y+8R2T z%A2A93RIxpAyCutx{d%6YykFIq&sy<VCJ-GPgNWnkTNue8Gy2#DXWUHmyz`n1%MUl zxCW4myaCt^12YW)oQ8)9<jN><5>-u`KvgN*4yubOH!S$Zni2F;susK|TqGW0tMHwJ zK^g*z^=rKd3!cNQr~tC<+JvAcb^&H9dT)Zmhq+I<c4j8a!=(!5_XTsBU3&4HSv4+N zz<BImbK24K+OiK7fMgK1N`i#Sz;2Qp<6=*ihE1cBC6tD0z_&hDxLB@K0PS|o(6#ZQ zQQ%-JpiV=lVRQpY5@8qyV@+qcw~NJ{pQ^EAyoo3km>4q2djPhYkcnO>6z(-0sqGo3 zB$KnJ(9`%=cum<ZYsBWGzlIT<^RP&K>;YgvMFM0)C15xIW9h$%n(Y`hwAu<Mx&}RT zd%22u6iI05H69|0Mfa%Mu#Z)U-_7X~R~?%Gf39{B@GQL?V&aO%aT@1G@r)0JJ`(h5 z-;YWnKRbx_D$K46a~(ccvP#3ip2kIBkDgJh2K*XbO*F1$g*|+$8_rzV9lEM|CFP`? z1ZJ0Yc5xo3E)AMi?E&llnq~T3{6N+8BO=w~^wcODi2Sf%c+Aqi`?=bkC|kDU#l5bh z?*WU?8tZrL?C3j=r9Fbug%|;R43Qe~*7a!3fc$D8W&r(2gzld<YM6m+9LSp5aJd9b zBe=tm35O*T1I%Sap{;@xg2hOnB|rkU>3CRU0F!i%If5br{BjBc+fI&5RU-Xt*ype& z^ng&ZG55#Wd}UV36Bu)K3b?@UFVyaVkuW!@IeLqkaTe67kvs`_0%@l%1sI{IQ_bl{ z$y}9wFU)55_U`T7Gke3HgT@(i(%8Ej54(3C+JC3<(AoakTOTZ;i2H}{odOMD^i4Vw z!=v}0V9V~c(I>+uKzP*bt(wl^=fMz840I*kv}KOqmRIORr#xZeIeYq4ZFroKC%Iq) z0pYpreysU;ydR_)@CagB9<UV13Uv(F&rJgc+?75wzsj5;poS41c)NvuK(akhb52&> zrhYx*Zbov*5GdU2@rg-i#x0zvaj7!Z(HXbtM9sQbLT-h7YiDcywaU~))y>|^Ip8+= zB{iJ_>>NiOn)x7z#YLPD9Bv_mNw;aBCLuS6S{$j)xXl4{yZHyIm6->s!zP|4H3jLW z9<bas0yRf5RgX^(oASn8D{&r~a=Z$3iO<?}WRPg37xrmO@2e9fr&I~EYL!$TAiC=$ zbVg{(FwF{y^#RvyeYGH3z3{u6PJ?&{$$!DTSCj4GciGd}4^6wdGvnpSvo*I_f5DDw z(T}>T@@J+%aRU#z*|W8Av+B0Vt>2@cEI0e`IdrC*0n%4)6R*<Qe9$=*LbTyF3(ZrV zny}rRCV$+5z8@SaJ8lce%l=BuHqVwu@uE8Oz@%B_^NQg!&P>GwTyUju)5EojyM}Y2 z1YidS^ro4+O3#n`&fb6Ocompz#%&$0O;z#wh-H;#+?B(Vld+sus-a4(#~5)2Wc4|} ztQE0|?B=+nKQQ99soKTrFa}<_1HEGkcs89gr=@u<=bVX(pU0}P(uGp2+)M?)=r-{x z-NgspT{%8hYi{dAY20K((0<!(VdxPr&?fr^g5(hgQ17mm@Pn3lp<J7?kAv`a*Ttd& zaM$FCq*z&<s#K1dLsO$ighp{QQtzywD7UFLd4w3$UE@>N$bQ&VCV?5d5g=a9dE3oT zPF06x@YYPqo+8%FR=w<d(Aa936QC)izioFlR+|c_jmTiNcv0MCxdlKSdioSQYNb6I zAEumbm8zqr+iVMkD`2Z1buX?0aWibn)bN_OVyapmt|{~~w*qeK)MRAzR&aSZ;uB)- z3ZQzx8IVi`_|9Efv&y4o>>AI4Xadf0o2II=(lX&lc^ddah+Ve@$q9?n!OhIGpF1=l zHv+ZBE_sL32*}c1)ri)gPXqN1W4kVY4CL|a$IpHO7bj6qILY~x)mBfONzCM(R6Q}D zJd?;IoHXQRgIWsWBpJJqak2}!tB~kjP0b~pCY72`&ZX+9g*>=c8FCnt351&K;2NAs zJd#l06m;cEH=yuiR&BBeOOH1eoN%&(MfY}sdhOB_CwdXY4pv`~zz^x31tC*5L8;F4 z8Yl4y7kX^DkxX_f+)3fj&jo3?GXU*6QYu$$y*`)xtd3VXRL3o=W_5E7tQsWwq)2ZV zr7A2anz^Lx^XPlMv+<Jqq<`H21S4xKu8uBKXgPBP>!YLJkru8Sy}iB0;ocx~clGo{ zg~S#XMXzIKb33;^rf$0{7%&c84!<+_+1qhZNe2T~Pbdh?*zFXYkwJv#1fMq`X;*e& zHucz)#gCs)@$w(|>q@z4U=lZtd4>fw>3kqzP2=SY)4MSDE&#@MT_{<*Mrsu-wDzuv zbGwH3Ocw8)y>o2$#eE}c);_TBg0*+rnVr~;ztQThv%4nC990|ZOQq-bJBH4UPYsRk z0+};4>C|c!JNj6>fMKjzy8`&^ot$y=eU;M0kSZPian!@cFEP8JIECTt?IYAz?8A7_ zDF(U<ZUIy}OC!F(bdjm&rjguT<AF<LjNP0b6(pFk-8G}819k~VM4~YuRu{^1+fd!; zlwOHRUbR8GOq`KP-IaFJfKXB{&R`)jVC*{SKWm2hWToEk!lS(gmqfOZ%%oE3e5x(A zE}2iZC9O9jcJ_chH34=`6-1wGMu1<@*&rRcyED*nU^1abpk8ONGpZO9m^2fm=>Q%$ zn*0spCk53Lj~C{W_2g?H);^z79R1{g)C=RC>fP-oXLK#4zO3pC&3&V0l@#ycpJOh} zE|ajH!R>iMOi)%90saJ89L9r6&Vg;M(qN8e77`Ss5&=xN10Iw0)O-qp)pd`h=F)SS zdSW3}PuDX*6p8cg4+F^%Dra{cw}(rUrm+*8oNfdB9PH+>-R6dlglWm!%5lE~3bE8X zo85W1ue~Fv5v!WUkDy|2#s#fkgE}SZ6fxlE^+F1zrC&(yd?9(4-xt=?NbV->hR%>? z|1z`F-7tG|5o265rJfNe^m}Y}Ew*IFsAFJea~%S!uVw>Avi4*J#726y3^LK1%w1VG z!)Cax+~pPRnTa7x3b)|Yg6FKfanp!usF>RlsmRAzLD9L$WRh!=>yoRI*4q(BC<y*I zcK6_Cx8h<ZpmmXe)&(#z0HII>amAVA*aN6-zF6cArdY&_qUHwTxwTk4KUJ#eH<9WD zkYl|AIe(Hxu(R?>3A=^ed-m?zfBS(u4&FJ~dgN&TvEwI7L&KPC&p(D#ZU|5Q=&{!J z7F;lT>j=9}Vk|k{WThIQ81>F!a&u)ZTqHp#jD)U~H<ZJXDiW?`D1V1}>!FNwP8#v| z@ZE#Bgq;JGl(ke3fRH6)W>ro#iO?yh@~Roak0w=6Ex6~YfPs566fdBJfz$;mVj!kP zrP0ARShpbC**k;@VEP2P-WAI_$EggOQg|X3Xh&>)uq*SZds`6oz%b_;|9EG8`|-0m z@9J2Ti-|fg{CM8lg1MF`LZF0es@jTKhLFUi>X>)MH0NSHJ;L~m;DgkF^#jNS;Ftzh zb<-2}sGFH2+FZdp1?*2ZQ?f>FLM^xiBi0Y&8|x}B@4>~*kayb9<piX1wd@p&zmFvL zDqIrD9MBzpsT{7k<m`=tU1QrB@LBa&!yGC8@gAU>^$654rN{U~)5ZW8W9j(}IyyP~ z6T$L{WsDsB3Ksievh_S!1L+6Z)t5(RLT)}NP%^WG)g=`QHZ4Ywp>Xa>Rn4-&ZvR59 z49Ug0(gm*GewC5;DA<To!XBuOR6x0dM~7WDWCT+~0mDKQCPr7Lp&P9qLE`|}>0w}k z6qw8n%gD;2V1xiRzKY}m&xzb@`%*m_Paf;g0EPzGp@5k2l(n7&A38NL27G;nv8nN# z)$IUUVzFtYJ?a3S!dNF;2c7XGgpwGD?Cd|=*u?2YEaWyCLo>ogAoCEss>ojtRygiK z!1U0pQcX%R(!eHR2;3%*tsAsm_=^phV3XF617fg6e<^uLnM+gy95AN@z{F6JfLo>> z)+rf5>n_~foG#ruiNHWtPTuJ`BeRET<el3VYy^Y=1rmE7zt4gtJ+TM~T8c%GE9})` z@ta6yx8ah=k&5tsso9&C0*3IjV9DgF5X`KN2oP~#W_bgPdwL|Zp38G;V77gSZFGWs zCQ)kaP>`>5va=5DfK&o4#k~s<O?03e$*!<Ih)Y*e+S3TlO~oS6OtJX)NMdJjNhDLr z+09E<T@uEsO{5?=kUJK_EjK2hZcrF$sb$IpO2Yb!LjMVA^we1n3F&k%qz`ZH3nmV0 z*@T}I+=mDD7Ir!4FO}Swm;-vX_Nx@g8xTVEG)ZoaaFsldq_65dQTi(TG&B3uaq`58 zB;qh7Kqwf8@#QMSCLZ;pS(gxpj>k4ROeR}FNWvCR6=6k|413Z9gR%l4A!&_pt6{wb zEs<4V00T&9m0@!;W3@8aTU=!)@j_q{Oag1%w9e?2H_wW46tNNIlLzn(Xln((Imt#a z(Z3*np+XXwToQCJ;C4-N)>vZLW1qzapW`57unrF@NpjOk>fI@&+!|h2vNYfnR7%iG zSK4|TlDlb$CEX11{W3rTz(kT_F@@>j!^qNLDanv8=g|N`@56ZLYPH^poArIXkmh%p zVQm<o_kM<2WF645Z;N{y>qET!6fZx`%g^)j3%rCKDNjPkkeK*g{A5ARCo}0nOKU#A zGLPLvp)iaW!5?dN4}Ov|M%D-kY;DE6(f}rspwV#6bIw^{HEC(iBx!&ck5~(zh1;WP zn7icj>qPk99;T-t;#)@Xy6A=lf-r(iuLrk#y(Cf>NG<*4%duv{03*qW>?CWes~4NK z0if{Cc9J8brq$jRlajWBAZ~}S%KOu6ik=DKXh6z0*|1y+H>?xz8+^(fbZonxgNKYu zbM3v{sg@k1>_sfZv3^OsOF+J{!`6V01bHQPoL+@Pgugq$_j@$D-xFr%7r96BBoc{F z0P7b4X-fh#K`;wA75txHlS#fL0N#eLXRDMd^a#w7K^R?`BXC>>6Q*io8%^et25OEv zLVl+}P&@+8t-1@Cwl)c}Ekc!-!39>7?Nnx7O6yoZsCj#>OTEO_?O^NvbPOC1pf8c| z2#$<%>><m7Bp1tvOj)1mg-BLpu@L`yLw@R#kQQgqv_8m3dW%62!mrMbo=}wCg|P?A z8I9$tg!P`iMY0DSMCuti1XOXPU%-|dE>R8#A@x*ss5Cszm2F&x#M4SK$z21<Y$Gk0 z9Man_r90Unw*=jpZs<-D1oz-)8@R-=9hnkhSCGXW8#$~GO;#t8%??KBINgPyQ5&SY zy%$QAGG$V8Mmerq08T%|&frHvLjyca(?Y+4X|3fS0nxyU@z;-^?9*jGmhiYSV79Fm zc=Y5qXURtPDZo|HHx%ndCXp-#Tu}D2OISc6IorOh_$Ay{A-VkV9;=ro{(N%pre(7_ zWbCl9){!x?^a?6#*&UH;ZCy4mR12*t7D*p3g*4bey)-Vh7IF;tvYZ?quofos=@<fG z^X|dV?#3mA36%mIq%~g}Z~=%AxM)&&+;gfK@KJC#6lJ=3vM>q=9vB$`LLW{eFaGf! z^dE_El6oVu8xO}e4Xzys1fiW$lY6kM+q={l-WBOAW0``(5oD?S<2|SWIY1;w>&Z<d zfP@nMRmAzQlq@$C3?>q{1Yn&^6pMF9DzI(&3Iyq6<QRLRA3xcO=sl!DErcQme*sx@ zSDPV4ZAq1u+z<%y^NL74UZf*5alZ5vBTdMTU=`}n-vz5fPd2|QNnHuO%d$R&<c&Sk zjB(bZeI!z!t;_XGka_@kr2&csfPbB32yOQp@zMmSWhQ?DFAlM=JRb7kknrDP>@a@8 zA9ri_;Ag)ZX+wwxG(YOIs=$QB?n9-`?1*MsB>~eO%L;MO_66H28DU$&b_j4^p#2c; zEwmxRz13`mJr!(;@Z3gwBHUNfrU>^{v@61WHEoM<Ut_Md-fgZLTxYHxyun;ExW2j_ zp$!OaL}(MOkC18|Es$`(fmTSkucsvv?we_ig!_%K6oO3>>b8Y;Nr<_Lwn@0(O#39< zZ=sD6?gs6YaNkN>CEVL-uY~(H+AQI|opwvO@1X4x?mJ<D1p6iA+(8>A#B|b*3HL4q zTPECZg@qFAnULZ(+B6}in|4jO_rP)qwoQ1`OZz6o?4pem?z?H{g!>-aI^n*T_D;C( zQ>3q-u(o5IN+&U5vIt|#1pP>`hLlHtK-x$pF^HR>|ERSsjS0k*$>yIhA!y)EPHTHH z4flAm9-te+I1Y$Ts-76s(gdN<*?$T0gHA8&uDO6l>ml<+l2Fn(&4gZ}M|VHoja5tP z^5~w&K~Q)qRGM;-4+9=f<h$NJ?;}#UAR@GSPvhE&sc~B8&19&L^u=+lyA;x$0ln#I zDhm1R(=KeT>@tnJjZTj+C21YWxU+o*TCnX@ZS2_95zr?d@e|%|^9x$^J(zUPxo;-} zRhns!kl5P{6MBar9Xx5~L@-_k)HcHgdF^RvKv2)l_ISl2FQh=-pKRbZ4IBV75^Fvi zt)#aTURQZS$)IEP2%=m43dOf4d+xmR&Ru)<?%KBpyOiJ~Fz>;9vz<<W?nw1+qT;Tw zajc5B69K;ndYn7#c4LR36L*^EkWRY`e?fMVRXah`1KY01mPo(U)dZj}_ohQSsbjhK zy}GMdHU8;Ly>9>z9`rBDyaVzzYDspyNE%(WUNto_+1Ukw6^I$#w8ov4Og_JbTECUu zOMTK^yzJQ<Jnq{A4Od-N!>b$G&Tl&8lg4*`>vf8~9S!f<dU=I>gI9}M&lG2^DKnB{ zQR|uJ1O%^PqFD3!`cYlQYqhEe5I1wk*r#`lY-<m+>M#Qj8GH5yRp>D|s}Y5clE{Ix zfgFSsUqE-XBLKPs%u7*L04LB%f(ZwugSjlI+AQQAR5wTsoW<Vs5)!*Ptrknx4D{w9 z-?|~TxRYT+DFmp}4={NXbSMa-&{+W*gDMfUBoWF&JXWf>Im|ZX*FZ&BzlATyxulD5 zPIz4f3O%%1)oG0uLDfkGhS?zg@y-u~pc=yGq-CrNBGLgJLxGN5Q)NDb%Scg<2zS7O z7a`Dr(F6o%2st@)$AgU3;(w%Us@^Pb@^~}i<jAy_*nB-XDo;-HJo7DpgP9m_hF$XO z>M6Nq?C(|R(y??s)t5jXDW?T_yw7Qca96mR_)3?$LV@&i+ML`-8Yw;}<)=pzBkA$n zb4mMkQhpoWe2rzIrfKBgDX}Z(Sys+jRZlLghAs)j5Rmntyy|*qm9vrp36hmzJcVC% z#1)g(12g!F@AVh3>)sAMl{L;<XB|o|Am7Kdz6!yFd3x5<!igO?Ayldsh23ENHu~RP z+W-+V@{M4E1sMq5-PDj4tM=3cS3G+WV0oakuHg#}Nzl>)Sgmh(=L26G==G{LJva;Y zB?QRScU&Sh<E;y5gz&<xkFz-i${&HAusR53BDAHO8Lm;)0=kRB5OABBv3@L^B&8tF zm<HUzSQMaIpW%fZNb9q_a5^<YK8aq3kbe{p6#7N~xlb!VNL@&_rby_nl5jx;gWD0y zw5`c?sr7iDLb~<I*&Cu;v8DGx0ZW)NT;c*Ughv2C)<ywZ*%fi<$1;#6@5dbz1X?ou z0ce0Ra(YAPzoGsDcQCS-%MMr$@)aNnwm#f?u~<>R;jUv8u=jW?h1M#uDe+yY^CFeh zkVQ&AkWOD{=&%<GeH?h`5>6g|5BrT-=MuBs4ebuLUlHYl;6v;^WGp!D;Mzm@Xj)&y zv-JnOe1#WMq~3mTseO;deaiQT7^^K=NEMQ6QnMSEtH&_g&p+-<f+2V-0>Dcthv;}W zI+Vyb>7?fqS0Nc01&5w-^<*FBAqQYCQ$2?CNe4P)GGqgs*JHp=Oo6vM<9T3s@!fnw zPEag?Qi;=qGOsv!3WVyJVzV#gMys%^7oeBEaMS2a>kEk06XolClI~(Bx!H^3RJ@|( zx+|-<@5yoNPnk&8k2K`D4TH%2G^kR&pZ*c{B4Hu{h~9!9`ZAeIwF|5->d)Y_U`NXp zfIC511wM_37)XCyM6wydy8!5V@^0@v+I}CPFFBsD4v`&k2UY^eMF^28+8`p7CDvbP zs>8zcZRjJ&tkSeRO(v#ahhA=8D2NY)6HwL3%w?zh>S-wM?4Qd`_c|?gSeYW!j(1J? z<>#7#{qyx^{O86q8<9V-cvD~E{97JQoUh|o1s29gj6v(~ZatCGnjIh_r>+$tz*_8o zs34eCJqR2aH>*`Hn}i_=R0`c0QHat5m}O7fZnKHa0+FIAgNrd1RP`yzU;;Y4Q18}i zph{4e+foB^hFTpI#cVe@W_?pqf-s$evNaTT#9(iUv87tB@JfD~V@nm4gp6uFP22_9 zYibR!**c8#`sDV-b0+va7-LRy{$z|f;DVkK<K#~Y`-XGYpRTNBW2K;z<B2ZpV)4_g z6|(~ya8tv44O0ck3#sFU1HdpTeJN_n`g0b@39&SfkCYSowpjcvmWyPGMRbk4jups4 z!`6bXX~n<a+7~GcV%s6;3>J%Uyx|qrxFqQJvC?9F+t55WgR!(;tbNp8L6TzeGs~8# z-^a=%9+Vbx?&~s1eW~PA>5w7j;2p;GpK*J!8en*R4ZvdYcY|6q4sMtxR+F?}6XG+k zCe-C!uW>0Q&|0x0SmaUzZk|mVH)rgwjN1fGJvaV(>3D&aWsR2shi2(5e)?I~lvHd2 z%XlF*yFLz#ehG^z%L?1;ad|ocCKV9Y<@}X|uSp0XNe={{aAcW$pZ^Kg-L|>p70jSb zzM7wgE15Fhx+^n1R(;{TJ%dcXz&bP6Ok(!7#q|~BU`G~RU*iwC{VTqTX6ipPZ!8IH zuKxV<ei@jc4GU_RC}<)QOA}vWuVnC<^h&4zS@-&7B(;<psOZbRNY8xPuQhrGMm>-Q z2OAgG8o!BerDF=xG4l17{1VVF8<r_yQMdG?ouWlR$X-ZZ#Y#pzGW(j-Vrr?yccj>T zyDNjB32|n?D#O0tGa%jDI}No8yr9yzCa<~U_ulU7o$l%d1PQ6YS>O+FD3Fk$&ai;L z3EGmHT^(x+-(Ghs9$B^(8kD}>c0gG=0Lx{XlhY;rU8F(U&d48r{r<X}G_q`y&@(-Y zn?-#uDm;r(+DjfNx0wwT@LIZk)?Z>I|0&WqZCK?uPQHw_ZP~?S_PH|<E}H^hon0a0 zEd(YS6hL^YH9jat_09PJWJ7R3Al9$}(*wK^+6!peYo%5jr(9Y)3V@X@1=uKzjA1B& zi;aH(;<h%@1F*UoE{B4+mu|iwcY@>#K^LSO)^A|{7|fCyC3blLKl{6JsVD7%k{$f? z0a$j3%J<{9f-a<rcN(gLDQhq2PON+N%m^sY^XnX_2iDW;F;|~N=-~t@Q@+Q}AZ4F} zLLtZxl^w^k_Z?^<>q-4Qm&L9<i@idQ_q!8yP)T^hn5KFYwrL{OEqx3NaL|>f#rlU6 zn^=G**tEhhCtv}sm7zw;qUs<FanAtYZg9{`u%GM-^`mHz23<yot)cyC;5|k`+gJ8q z;!b-GO8FDeo-PmTq3XXhSpzq4PApD1yeOnv3u*;DS`e&IL%^sK<!IFqC`Ib%Zfz(6 z?E^~F{nCOG!fenelmp2Ctb0%}eFlgc7-~oOm?W;Ig9yHkR;3iO$E&p}Of*C_B`DwM z6x(E~96+31^7PK2{UP=%LA9jeL1lvKNncB~Agvg#fy}liYtSbEOIqf*u4fc>gFKLw z@(>S*jU(t)(5(=5c(yWn1ifth-r{r$atL&gx(!jA08Ymg(}UFOjY-JIUMz$lAClZ{ zy<I4ZK~bmfzy=OCQ+hqie0PWJY`)R_@4%R|Gt>xb(Er&DZs$H@-(K+7yTHH~{^@Sb z4c^Ba-b7fz*UB31DP+mf_GjQV)Amib;yTJjO~N9BE@hdO(vVp(;yxr|2_``%;=QEn zY(I76=<!n`Nm;T7;$MOt1^py^AD28FIdU}Y8jrgk5kat4+r%(lMwO!scOs&y25m~} zKtf)o+b`f05CNS~;Pz1KQospdLV{Qgw|V(^z8g6AiH|2Z#XN|O4}JuIq$jQmfc#F2 z70p(9K(Apf_EtJ==^>YL<F(QtdA%LYlKHnth{4E5J1{yg3Zy-T)ZmbTgyDR<_P4@g zbDO*gFMPAv9zDXNw5FkE5loY`h8h;9i_o+S@m9wUyF>U21K`+jdAI(Umw+cGJKC<i zW)Hj<uiV@?jJZc`p?-z8<7P!VYCXlbtzJC@Z#8bc)2P;eaP7PqNfYfE@GP<W2M=Hs zcml2XCr2O$E3bTVc2$fJ#D`0(kZeRo<N#pJTZJ_aI~lBSkR)p>ol+STNB{snF%_e5 zMJJP(mdgNL(^N^6h#wHGxCFBVf$$(3dkTJyn1^Tc=r59C20)$~{l13$5jZrlfKLZt zFd@oNkyWiRAqo<GV=l39j>5s`-x;_lppzraPY*AH4ac=IND(|Nji3GHYDqycOYlXR zKuBKNZ&kL++`PZA0gTY|9tHSi#gSJ`Z0hI0yPkyl>t43olUjSYzd^dU^cUygJ%P?o zfTzL^4wjFOSac}vdy%~Sm4|~G^u1>o=P53w0Y<@e5I|^{4%RmSyZZp3df&gAZ2bnX zM{@(PCn*`I(GL>r!3tUclM+lxC|ysVKsdDkC3!F#4{CxE>_-T>0`_ATvAMY>Se@kR zAph#g@eJ9U5QAmGe(VP8ar49e#JMFpaZXmDElMH-&a!B;L^=%AV4yp%wIi^eEKf=W zofJI8fSM~rFDy|}jKFn}YH4_WnQ4WfG>-T-At4v9jJkHxM7?N6nlG^+CP|-aZAVGs zub?rj10j}lW<_LC?c{~}EF?LXr<lCX+1<@<uP(JtElD`^HY|3Lg0D^9ps<eRDJyCp zlKtrBbf%i+C2PoEAzCw*y_ExAsdYMNT4-6=|6mf~&;Bi+{*IS8bHHlFM<+Qy2>OXO zn*Bno72i<nqGQ})GJk~ALE|}pl8B!@aywF`e@C{#h#yh#76bH89cT}-fn{M>&4G+A zL0S(8kzO*ofg-r@@Bavp>Z0^DD4D_K0G5I=x&-8;q>XeOGCef!x$6RyaI4}eOriO) z5=foFZ49D|$mp81nNHftq!Xn{Djx;l9Z_Ln)n9BLHvn!}{<YzD5zuxU`}gk;)k6lr znbMG}b48Hi4`FXN8f02+0GG!Jh4>{Btqt&}Ggun_JRUNHs^B26BXt7FQUV61f~e`! zA?c&rby0LHFbPE{pK0Mk9Ea!SflR&iXh0aAqq{h2iNV2gkfu990L|m8`@kmD6*kmb zgs#>0=p#jT9xx+O*no!%C_#d-#uUX#D3I&-*918D`#`^7@1`yPJ0Eo(J#?sN&*Pd0 z#Ep)|u8%i>AItOh3LPE2G~DuwiZxq9=~7#VhKe>oX2l*?V}`9N<6|R6W!zRF#UZcs z8@^EXcx7a4yrOKlcDE}b2|`VOp~VSH9?a_2`Y_uhTsQN4Bl27YupKAZicn!ifkK5i z>eTtf_;ms5)QoVd149Ut0^>-;(G+-U!g}_OpojYDN>dC!0yx#IqbOq{NDW(gX@)0_ z9OlPMbK9&nXu%v?Kn7YO)0&)(vm52x*vt!Lza#iy1~OE=AAm+n0-jg4XiXM2;1Ss~ zz(hU=O&zK?q@dn#jExla2B<cW!$w(;=m$&l`NmgosAiapNXc{B6#Qk>bkG9xhPCi( zXwlo)8Tc)u<Up}gu^5rJgh~z>>#O)oFVLdcKydOPNH50?#nHI#GK*V-2b!4DN;U_* z25L5JUM!~tp{k1y#)F{5y2?sSxgI1A;C9lxjo?AteHrE-;jORkpA}ni*-JJ+G-an) z6N<&}X1%nijQhm~4y>0bs0R}gfLI^<Ib3K3Z&m5=1qR#6XOd4ReZko?@{T0*TuQ`g z^ud#_r#R|!>FNC<)$axo4H-XV_TbR=B|u<j$xn5%!10HnC4jU#rr31;Fx_-yP!28b z??87HQz$i0e?DXID-GX1fU&MzD53+zOQ)@6Wp$^CT0-j;B&;W{XkRp*O1|_D-OiM7 z$<@TpLid?S=w^|}yVzB@CuTdMv<#Jjq${JqqMgD7=zx9JjGt6xKORI+hpiXAHEc3& zrsXaqNonfsK#G{w<_q&sAo{NK`Bmqs$CJ`}Ja57GnB||~EfWgQ-0TIyr~o|L(2P1Q zYR1>_&AZtQ0u%HAyRO*~<S05pQZzIhzJd=!!MtX2ggEuj_?8+gqVePArY5;R^>w#! z)(Mor1SSQ~x^41IKCXmAE{GltC{E!EYdtR_;G#fWy80b#1JNoqyP(B|A2lGf{rMW< zfGpP7k}m^LW)BdIWlHVD13F(57n{M<r!Rud^b$iMHIW)kdSi+_=?Gg#=A38D!A3St zHrjkk=|9SP>)Ey@l}|6KqfQlo4YHEyCUqophTfHkSfSj=JEq)7%D0xvckTd50J|v6 z{!b%qxH2rWB+we<L#z<H0+P>0eFo3Mg_YnR?+|V14kOQr0`diM@^o1$#hER>^s{3B zoEvx{`RHs4rkZ{ZEQd3JlgRGG1u}C3`apiiZ=^J4K3UB{D**SHtT?uGzZu_38!;uG z=JTg`X~4P^s(-|99z@5DlNM7YhTwgH`U}a&k?lvA<MR3-Vi5LWKX-IqqeiXdF3Ow% z#Ifl?2U156O0p^8G?2^C2LzC^+F`!m4pA1CPNFn)NSdN4s8Zo+A#*hWqBnIO3a<-L zqpGLb;qa@}3e@N=0D2cGbaqJVxGRb!`-~`Fo+651|Di+Qha22anUioKHRV_<F;0!0 zXdv!q*i3H!5>Oo@TalBEsz#otgwwtnakPwJ&^h=Vc!6Q&B6<}B7$E?F*3zYUBnXHa zpRvfDmTdfeCifz5!=#Htj-zb(Aw`FL2tu2{)3r}6Uwemn{d9c5eOt`Uwkv9U%&6GB z%5y}g-@qS?GRPH$C-SLLICMuFz08Cz7HJU%2z%%rvA89lU*uk3W<st2_eUZT3%r!Y zcGW=_vLH=o)5n0X^6%T&c)Y$oaROj;1bOvF7lRHe(n|x#XP5TyLC1ufKb90LR?9@R zhB0K(*kp;vdhAgkAdv>h-aqz@?tvm#FK{$<sMpUTmU2;}<ReH1BUv;wkGWoFV*;2Z zymF?V!Ow2TMV9N$5mbdWf@?z+2umy3>J`gd6t?3N(NFg96TP!7^6d3BB>F5$@`=zm ze$vg4k`(?*3~c@)c!^rkpYU@{v^DHfbgr>>5-V{Xv=89oBrI;Ip%PyO@ihkWB-Dg@ z1_XSBkW0=71bkPv^hsn9j8t?6Yw^JH^H>&toK9fPTyui{ALP3SO<4rr8qk(wyu*eD zrb@fSMkc=XUj(@Vw3C)UIUAsM*-6<6^Ol&M4ko3x-k~WE?C36az^<j^knw1zZwIr# z3(+04WAUQ-{cefWMoW?yra9fl-mb?(gFUuAKDoVF#xaXd)ME&DUZc72XEN->+pMD+ z8qQ>xu6`^0Hu%-|8t>P;1GSzDS%<7}9KkjipLybWTb$Hu46CghVKxQciTFL^nGzzq z_fNNghb^El`6LDx-k}I%b}jI6zzTSnm(e0Nwi|{x@T+mi2rL~AiSJD<`!!y9=79ld z9$0XcQ=X;wf>@~<kQU_*e5r@Q7p7eD%=Qi$?J%B$xP}&J2oN?I6l+C>_qM}1xAzxd z2Cmw~3bJ9*n89<z+N-Hzp^n9gP>3Pw-ils@UoMYYZqS${vXLyg9rJA!s53bqMWY&* zdZZl{-nk`nYA2yLqv;dbl6?&?{@TZMuvEAsx_o)v5#mq%c^D3@9b%Ma1`Vfe75fs1 z_OcXiZAWaRWCs6&B~xRX+VvDRtxL^ryN((JJ<Q%^ckIJYM7SV^*Lxd6s!IxOA0vVN zB}ORTZ{jm=tJhdP625=ycMJ&MoiAFgz}Y7BZ8HzPwzyC4>F9aL`Z99D5+-z_u*Qlb zRb7juE>s3$2a<j+=#I5;fso3jTALRwJ?zt<`A8pbzYZecZ){+@f`x~CgL+bS_|VCM zby;#OyTBzWt9SZi5V#fbBiCd0NC3b7%A=2>p<xke#1aI((LV4G#Rw(7kjZaH9l|Y> z#VuX9leIRnJ3favuRE6FsmM2f&yHwC!bFDqQoSc_P{d@tP6TFz^xM#aUq62KgD6MA zWDr|}oCC8U`VHZNOkzXx%b;rpPRfSFT)v*M531~38oxY#u(Y28FGS_Wo2^&YlXK0& z8&6xW!S`vrX|_kO!5E^~W7ULk4qTVCg6)KA9?fD~k(>UwIMmY?79RvC7Uo*OgJ}_a zmT%Mx^(JumehuHXEaV~ZEI_L+Rr{!vn1>BU=4xh?Joy~#`y`FZ;r-_qzdwH&HEs3s z`zM_f!mY5(gUuhU@6KNaPq1mO)oFGL^%fdI&8?97=272P)m&ep3cQatv%K?{vHj7l zDTJ+2*@c#Rj-H;oT4tXPAf)pc&uS5m)m?@UE=z7T;CZ~)pd)fR3-qX1sNhf$QtP{s zF-z*wb5bMA1Q_mc=M;!4Jx#KpbT?TDW&kHYe>Q*qZaBgbT0^@Sa)anWLJ&b49O$w= zDXn9oXJUi{WNjdniiOY;d*KW)j&Of7<oxW2P6%L2wl;KX?C*tVQ{d^-Ip=_zIeGT@ z{Vyc@UPvCEP4(@9i!ow{h?tVI!xC8~$<xT@Gb_1^Ls)GL_z}GCYSU;X2e)Jnyxq46 zp-2>O)5$x<pmay>HggArotdfJRJCHYqlIoEOzW<MI*xM+d#cJw{Xr9*gJRe;PhcC< z!#LJPjN1a&xkqbihAz!DI+tz|B-V|D|IWF47L`lDjcq2m5gZ!c@t*=x1IHG2fq0T| zYK_?0<c0T?5<9{IIJ>R*LhId7^M>2yR>ZF2W;xDpmp%zt138w7pWuK)cmRJ?6cR)M zVJDyhI<3=Ngl9?@#^jm8whZo8H*@1pRRb~sgh2(nom4n1KJV?nB2&#@3xVV+<KmD) zkEzu7otnIh;G!3}b;4MK$e@u!q*DeEO`IOI;*AKf4YHvi6Af6*BJluCdD<t!-qtga z20j8*R|jYdLd#mP-ll!)GA~4nF<6-`G*QbQX&_G!2jdxFq-n7y<6GE}c?OfnPi9KC z)QM&U(=R&TH7%=kJw5ei&|fmOBhKdJ>>D0cBF?OA%EaKlFvw7qM@De!2Q(GvuNo&t zK=BW1*5%Q2j(6w{G&@B50jjxjw3@Hy@a^w*Y`a=ysi4H=Sc^`p{V}*Nc}(>L7d|xb zAHa98&7$^b>VHn{VphJhV_OIPR|LwU<fh=Pued7=l8SVARs?Iegu*-J@R80%8FzKI zN8_N58FZUZZu<ASq4V&YgirC<P;);q@BRngmJsPnqh{3i1rtdnaaaM*5eucWLDl0M zmRQ|1Y~ZsXi@18#-o3`2J$rig?(Nx!KV#e8y?c%})RyZ6nc9?>>g?hUDp)~H$}<&J zu?C<7*NGic$02OQ7zvLHVI3uH#7!Q*H_&L~kg+#(SHMX093mt2i#07eB=YT^qrv+D z?S>PWFpxDkd~O!XN2sAiw&WTGXo<jAkQnX>h+W07EQy?~|IoQ<UgIPV6KFs<O<vQF z65nh@;>3Dwsx3y^K)J2JJ~z_@IL>1AJ`=gbFtHB*NJo*L>c`I>Lh+!ZAYBBu%q$3( zS#MtGp;PEc+WkL*I8d9`C!CD(=&glpKyBrwXX`nzXDwjeCemDxaWXGWhvEtL1h4_9 zr`9FvO(U=@5Vmcuo)@a=gY~@iZb_d9%>?B#l|#vLn)msSGaiz&{Jdu3-Y4PaFbvDp zcRB^tq-j7+{ptG7<)>c{TUdPQ)vS5001R1RnMiRfa{{I0*NapkYRIxt%R;m!BRO5; z^WS)}Z&1quL=8b&tTfFFt)TcwjTB1v0r3YwbgWz&t>S30^004i!l^(yiF%>nGYiv` z=Ab~E+P_dEc^=Z`M~3NxT<oH1-WfzltVsjdKlo-0IH67a1d5T1W}o^;)tTOjYeD@) zQQJGRPL<&nAFfHTM-WLAwJA&AK4$iHGJ!xm1m&w)dd`6&E_8&G5jg#cyx?{{oc^5H zK@%7VP?TR-3`1Ru52e2jwAz^=|CU5DFV1j^Rm$_J5;#lIxkfyzM7*u=UEp0M#9&ru zGIGQNaDrw|az0b$6mF6!HG*^)^3m8P8JqSwq=O7BzD;gGJK~K0^+Y+EXqnv}qlf8C zXDM>Hu*2SA_dv*Y$Pm()qS!^`j}Y|4WT@<_kY^mPW-26*L9Vf`Zt6m#QwFK!TOzew zEfsilhkE>wJngWxzmOGL;PYl=qy1uNK88NTqd`aupB-qOh|k<K%wROlE;M<I(B#%G z41t?fn0e>i42U0(>`o1w(pi0z#mF|}Q+(<}^2Y8xjJQ!&yc;PJ@T!`Dwjn+5uLm}# z^No%8k;GmFGI|}J)&S4%PxUt1EV8OW2m8<<_Ft6#;$Q}JGAYUtP?SFiEr_=zeWjYx zKSr?<PI7XbnH~XfxN;{-!detP6E85!?8d6^tFXh4N<NwMP7huJGpXQsUEgpY1R}DJ z7zY4<f#c}y3|Tbyo595K%jgY?k~4{Wjn0QIopYSYL%VkI+(n#6Bgfa`(7Ijwc6kTl z?$Y1%^5Cs)-m{lY#8zc#jY=G?3%WICQ?o3+2MW+nxtJIn!D(1{dqN*f*T4vd4J1F+ zh1KZ>KOo*ZIy-<5<!ks%>*|POJBjb>^FO`KBN6?h=sIIZly$P0s7o(mmjFdFs~CE0 zAE}m%Quk1I=SX$P817cxdw0XT@Sfef8&Ix?Cv}&0UMwr;+}-;lrdG=!Ol05D9Skt* z0%6*sD5GPjF%^<^Qp|>G;r3|9FawGgRFK?#bkpMvIm0Cv--R+c?El=HuCf+FX&rj& zy_~GMB_?Y>;=b3%GKm`+7<W3SU=kv2D8=qYfSWvS?#QCT9V`nlpl;Sg)ucg3QE(3e z#@z@^Fv+g-HJ$YywSmtjEVd<mbMp8X(0n)~2A=qeA7pj)?vxvDVvt2HC&JXhKAUu6 zAc7xY<)P|9e@!^P1Ut`7iN{dYB6M=Vdx3tD=idsAT7cE4P>kY}$~p$&I~cS`ldI;$ z7Z$E)T+FvfQ-qx;%n?x*6Helvp=j;d#goFr#Xa4J(EX;{TCRfb@tij`AXfGQT(x+; z@DcU`>0L0PGwXm~$#85<E$WHzi`X!-H~R7Ol%pC?UC@J-(XEgM{2>xspT}isjS{y_ zh6siYv}r09Kf&s8eT9C6K4#^#uPVTy4AL!KDXyUUEHQ5Cp$Q>my60RUP?WJgh7{si zN?XRuPGd>f5m)vUQTnxsZzViu`(2rVfwO0|-xE2ICIg>bd^ihgf_K?#obB4*=wMZR zi~klAh$htg`Sk0&{5M|yo|k{%<sW(ZCtT>K2Zpb+I9nE)LI1+&|H%s-IavS3%fIuo zlXI1=vXXofV}KVJq%Mvn9D1(vRx>Z(;0r4GYf^w3tD^L&UHh+Na0@Rt@j}%f?bDbF z9-3qz8(*`%$qTa%@<OM;7T0o%IKn!{%e}nZ$ICA;m+AOLm}%P)$F%l2Jmhy`y>DLE zk#BBYk-q_l1OP@glPsS@2n@4K8vn@@ulUbr<UgC=Us#`Cmv76j$v5Ge&9BPmnZD41 zr)~L`!rh49QRvBU#C-+aE(@fgK#a4vuoKWefdH7{DLSvq;1%2wZ2{?s$&07`RrFtV z9bG-C)JCvc70;Ey@fl=SQO5@UxbWT8^hQqZOeupRd>)c^;DfVB^!YA4;6k<*diy~K z^*l!jTONQpUHl6Xzz2x-Kzi_`Z&*EGWjG6BKp!0FWkoTdK5=G`-ir*tV)T#@4Im=q z&_2>G%zMb>@jsv_gmpzG6q(XErcxA1NM=M&?qF#{JoXlK;9=7~mE-3I7qC3nyB9Wc zI41ejrIT7};-9k`T|(zx^q6qcIC9P}xi4hjf-T0vVHN9_rMt<ds*ZoCP5-67vqz2| zp7X3I?5WXFc#8uwUArw1-|rJR0Eg*~67$2yzC-;BWtdaNjWYa^2)X+{^9^*4@a{1f ze9-;Q41E$#pUsG3f^U7Tdl|A&4^y@)AmINTU<PMVJTDo@;wnQKls{@ci^s?uk?C<4 z;(n9ZhzK}QfERfmba@ZfCu$3WM+#0Ry&hhLKV{LY%aody07HQ+4{TlzSd{$!e@GPg z_<tD^xm^yy5rXopARd4ufzWytUxz4K!0!}Zd?8p23jy#E8Ux_dcrye(sG28%4~Y#) z9MQQ(md-W6RsvY+gN8&?R>Jz+PcY%Bww#>}Jg;y%31o4mf=?Ko{+OI{I_bBDMKO5| znT%m)P!94+v>$s|PRmT#BW{ikHu_JyIWjBzPdE0^N%X|m*+W8MrfE){hY%;Q9>uHB zdh{Ry5Y<9=n5zoTd4!ugJcDMzbDAox^a)FqR^F+v3p>#ywyCnF49w>4=Na+FY~Hg1 zHD;SSaiEo)W#wjNhoQx095*@Eizg()R8Kq7<S^s#I|u?ATH$UiddtNbBKyd($A1|N ze$qOF4hlrk9Q^<SxQKi0f}W|@F4(t{S;}zGhV;N}UfKXuJ)5Bm3G_7u*}B?utTxrs zU=#mp4o6-V9}G8-KvlR~rx~4r?4?mj&fOfeVQQFbQ=}Dt6KTc6Y=vM`l*2oJ{rCxK z8*N2UYaA!GI#9(itWp`wfJ1<opyFr*tE-_#YM91R9gUs5#jjwHSEP!68>!-JSw+-H z{_sp1E^#k@vI>Z_Dm8m=$FW)u45&d$jCO!!Ff=tvtw}7OH2Q<#AvR;^1^oucGYdnN zM{}tu@wx4-uDzb|bW-p68s`5Q6#5TA%~F<)aDW7w5Xj?)_X(RDmMid~2`SsUr&GRV z2c~s;H2Dm)5O4+9E1aavbH<=~khM<0Uq4T=Ajx%uYF35I$!B1t=cJ&6kis?dOhUC# z)fs1Av_6|uE9iT(p3y#fR2%kUKqn)qXR=Qxo=!fUdOH1d=IQK6PL8$AL&stDTyAEg zlf9BsYvj6iJ~ft`PtWDRE#Cs$q$b!VeOlWlIr%G?kaIchWtSQPMf`w})(^yHG8f&o zY%bfaHE(3=BSVeVoJ+WytXLOu2Z9Ahtm=V*pwn4IuLiua8xylP6)`O*iY0h{nu%}_ zy;Fh(Ih~Lm2dJIL2hVf91sfptI)5A@+ea)QNn2H_3d9O#qMSC_0`e3S68<h#_F14B z^dWd(7>69kVU%3?CfbIv0Qwx(E5!5vhEtZG|94!p?@O!|75GAMbam1=YIp|Z)&x#M z260)dy3IU3$K*LW?h49u0Ejp#1wrIoWTrICa95025M0re6^ErYp5<#%2D5>klS5S! zFwEGD6JnO^qF4z5IQny0I%GSt;90CRMN`RVArwcW(O|78p%1u|#%FjCnpBbUE5Ex- ztZu<C#~FgcQ_2~VbZ$;sVOt!DhAD0-!~wK?!wnjl%--^%ZE%L3XM1Cn5LPiF<&R_B zjNb<Q>;+t=-!)@g0hM<}?0&Sb?6*Nqu2NUf)IKy=&OE2(-P<*EGky~`XHO=o`)7OU zZ2T(bB_V+zOiR0G0Wp}BfD=N+6?(NAdouAbVqTwm#4G7aW;|&<$5ON0{^afe`1K_& zrk+f^7RNO|f*;chJPGWc)uwrbb-#6N7$D-0akJiti<<|U!~v=!HN?J`u}|@0q8Fiz zz|M3Fa`4g-&JpWT_BhANZNfp)WE{9_CQC(}u3dq0H_!H)fm3!pCY*0>(?yFWvQ`g= zq#ZG|s7rwb#BF68yq(}&Yb@AXsH>4`h4*G0>9}Rd;qo$?ZR;c6#9lx!?P1y8yUp-y z%7g5SMKl!EV|(S+?5@@}?nkWAqf=#^mQl5>C)f%Cm_WR4B_*4*<MZ+h76>h%Xwoeo z^S^PMPn{e%UOaa4#0kticx#i^TNS*A5)4p|9Eq%PlI}*U%x{DKvm~o=#z{Z5MB2QP zeRZq!6*X2MU`@mOb+$E&r)&lU4t!m2#1<TH)__4z>qLv*vxoVK|3^&4Kbtm#v4dYy zIKn7Bm^E|Sz;ix1*o0^QwBo#avmE}C#QDVfyyAj)UU7?hTJh+Y<Y241A}1Cnap22Z zwGKy^v|;&JkNZlsL2bl+mD;2><GxzmsJ7s~M%|=t#(k}NM%|(e<grd|RqcqmLA^z7 zQ`-@<UhPmj5wk&cs7~BB-kVTe>ekB%b*s5)K0UbEyiwf-ZspeyFUP#79*N&lU4@ul z9{l3RlyMY{dGkCEfZ3&Xjizt_%y-C9Fv-EK=K8^Qv{w#<LEE>XFSaB6R&~2Na2a$U z4uN@A-JuSmMmx<8l^#i{JJlhCI@MjO5B2IYJFvLktqvpZRxgD<Eao<)4~yyc4vXpW z4vXnk_p1Bw<t}wny%P7`>Q(9#?t9ezY5@1Wa$pP(g3$-Y?Dr0gx!pT3=74u#%pFP} z7;{j)4afI9hVt*kK{c;K4u^2)%oDiZrAlfD_dYeO6z+E`Q;pz$SdFT4xW7Vurz)#4 ze0h%=R~5t@Q4^|)`%zU>leqV*^9q`@gU3ecRn=Aw(jHgOsVQ{<PbWlw_@bJ=oFBYb z&8S(VyiZ+Hb=*&?IrVznU#Z@p-iZ6F)OV>jsVDK(DfQjzvU&<n_dg9{Z*Tx8>U*r6 zfX>;jBSRpKF_(=YxSPje_RtN}!XC?aH=$3B>;<t}XkKw5SbYKTp{Wu{f2ch3tOKs6 zsnYM`HF*T`_W%}23qlR*{+X2R2wNsR1ze7(wL{JHrA06}hGm&AMd#3-#QKY)=*bn4 zji|>;3TnZsgqkg)w&VL9h%#%S9Wyk{q8_V`o+}$LjfcP)it^&@4X;GVV2<#H_q-uV zgV(oMncLXBDwIz^lZvXmW0_EN@~TH^7f+!skKhcy@N`4zw+D%61BMd#(#LcMJRF># z-jB0=?ap@NF{eQm^D;IxCMyxBao6Hl_#+RUI$M1BJ}5dC`|mq)`i$(RS)B%oz}>WL z#m^GalAuhi@C**G-Pr4dzo(FGFbZc(?47whaR`P?Dk^E+R5${yKz^yu;MH41?6@IX zz@aJBMyMH{Gaf6HWd^xk3rf9=ypp9%u!v6S?1Nl5(4O9d@qg1t){>eLV*lWuC=^Tr zG1vjzFL@45IE&e`DD3-+bFrq!LA+cg5#x1{{SYaKPXDvGz|*fT`s~}(8euiPzj)pK zBI3w_jbFA$w6PJ)Y?hicAW;Oe&Il`_pYRAO=>vfN#u>AAiGJXQUC))Zvs<s(Yr&R) zvx~oe{Ol)j!5I&f;9(z1nVnqIa)o9VVtD)x<aAEc7<^dZGzNwW<fs-~<l5?ezd}N7 za$PB@R^bHgL~*q|uYsOdqPSM_T_-U&NXqp>9cKs5YEcm+fH;MDg9xPD79lH-2vrH1 zw^Xip&rO(^r=f@LwrByfP2E4YV8hVph(6Y*%^ojLhDcFxlr@DF$SuesBUsYCftCbO z4638sCQ36}OmTc-(!tp(<EA-z7D55H1!x)U|Ks2m+0^g=f5B}*Wz5n9!Bn|8D0_yA z)cVjBFla1m!X9;7<!l&FdPhHO_)xdSc2kz=wvt?jj)gSXUBS>X;YggdX0XwHA4Umm zA2g48U=6S#M^aA{7CMnE0Ww|`tx2TvId<0}UOk`g0d|FF034PCnw^U{{|F-7W(k<| z;lW8P06=ga698Zgi#mO=P`MsQ2EpJY5(a3DrLBWbhUc?@WuTY;?Z_;c=l5%`JHCO5 z=$&~sCVq|JdzbD(sXI(@2v%QI5Dc48Wmr1P+jN9Z&6t=pg$<Ahq$RX7HZ3rLv}y{< zEray%#2q!O3|0`dPIQKz<CyD4?@OU-o=x{4mufx8otk|??PzE|;RAa1v8kULM`2!8 zuL@BZPJN!7>FjEBoEFQ^%j?!XyZ7#=`mv85JKJB?KmvIA-~X-WzeFMTHxv>KGEu0o zUpqt6BWPjWN7DC0pT&!9@K|*Fs|;vn7zg(6ewDHJ_5&y<?5(90M{eJ<7hdA<QMYm6 z_S^Rzz<uw5gZua0zW??EA^trcKh=+5(0_>xV6U_1C=C>{Oh>~9VC0xXwrX)dzJwvV zMi=q`Qc>!d#Z0s=^YSKMNSg}=v)+iHj}+3wlZ$vp{Q5hI4_fh%SjB^yRtYZfOep*r zCe4j43&DKnR#%We`0|*|;IjaEiw*$~?y`0g18|nZu#C)&bZG>23I-k+m2z5InS_=B z>|n57g%wLrRZ%7^g@|B!Kw*xA7mnPrp_vWYCjBv)*H35#diM>0BxkgHv`WB5I0Q#| zo*&wW4|VQ_@8sUz-mdFAEuAnBDGZZcl+R!EjQAHR-vg)XD|@y%s5cJI@jDH&fzM#f ztSbbS|HY^0`1Bq;d7!eCXC)WLK2r7f5nQ-qOXR5pLkAU}u}T0eUdn*;i!Z|UVLt-U zFQH2%$Z06&x=KGBV83auA{cQQO2F!Am?WlJ!KCJ~cYvI1>A~o_&<Hs=z=`G|!$kZL zgAbFhPb^Az>7sDxDI$|iRK_Xlp{cKj+o84ypYfpWHE#FFg%Gz7JaG0nRRb{NbyDPO z+)AW->!RhMae?xV;=C(>d&velh3eF>d#jYGCWwukUc$g7<Gvc&-QGF_%W1msWoxQI zP98*PIlJEpP)2ZodcqTCp?eLPjtKoC%Oa;;)F0$)VUNw?v4MdE1p6MZ6SQqzL|L;m zGz6!0W#~~sSP!OQX*$%D^DtpMGjHz#hJ+>pOOGH=WbF|+dNTM)dyJr2wx<>WGK1{N z;#{BqbQtb~gJer@qkQ5Ui&v-DKZ}ll{eR^M*`O)J6fbg)EMG_3<u&Wu)^>N3x9ZdG zcvvQv1Mrlq%BEg}HAlSg3@&&@x>E3h+eX6jNTs6XkT|Ccya*eHfDN=JWE`<k{wVQ= zDA28=TbovJkV$mTZV}=qiaR2paW+_UxZe19#J&dsn6+_jNkGU20T#Gjz#o^JHA^0J zCMe4y50b<k-T*ULiTe1&wFnA`T#0hC@4H{rf4Q$OS1$ln2sP*(KQgI?FbzR`k3xxA zOwwe|dQ%bWesthULt<?q`~g89suzkq4u}QJlhXK!N@;YC#qi8k-pwkV4Rq`CRS^-* z3ziam86uvu+`Y*k*~0v-#ZPqfK}shoBGp?+(#av@5nPPnz-V5)m<7kNr_mgj2c3gc zjk)N_hehD(HmjPy!SFX1dQ9HIp-(~&QktYYOOLXa4oKTf>q{Kj94m<N#E5F|D$x-= z%1#JHbl!LFx}r}{OL@A0t`rml({4@|YW)CVkgF6V9J04*4tmsjH{Vg>ik&bIGW0x` zp_NkL=UA^*tXGz>)|LUhK}v!3N*_|SsD{CYhQP*t7VURZQ&f(0Af2VE!8|0L03yg$ z7hvzC;KUjsc-0f)W+Q~U!C-nzR1E}<uccLz9jdUBAXlNrmS^s$W$v^9m<g9J>31Ld zd;1#FJt1sJ$9WqYoX<>hv;-7h!RZWgt~m7AmB#wJd-erZJW%^$8X#}1CH<F1syMJ2 z$^qTn9(2t`Q8`{kUg)%5Dz?cZeUS>Eu_cxnvAx3~;Xqn<%dGN8+Vc?wMjF>=X`sS+ z(ZKeQ#hZw()Gmg!JIq#4yq5)@M7_;lZG%-Fr!!)!i~NF~$9JqHKJ<=C_ttp%1kKiT zK{v`D9tZs>{ZK;dyaUZW3^eC^F9`BIshwm~M#OOt)xQy%q1Le1oRNn5Sz}{4Ba5jf z7WfWF(P$>NjtX*(oRu<yji=}pVp}Si^2{0{TxqnXW-gZDcMA*vSyZ`y_4_siiw6*G zU4)(m5A8No4NE_|7hGd$yGOsEpc#F@N@PLxmHwkf6>@-$9UIsf+X3AS8v)_V<3Jrb zGkUHIC>0K7Kp_}7jz9yl27beaVPr*-m1<3)a$22&#*L+OW=WB_!FW`-3Fp^5zneoF z^w!I%qRB-S6~R2bZaqzD${7K-IW5f8fx~mMfmuoyQ%ZTc6*48$mt8AUa=lK~Oi3FI z%hHsXzh8L?%;`qMy~c0|39Num61@aI>(ZQOX^nT${-R?*i$xoqO;>kZztJqfspG*l zeHjJ)z$}((^|#39@!N+v=I06vo?SHOStcCspKThiip{3~0Z!?F$7YdxRcjZeG2Mb6 zG!~6fHZP%r$=voB`+N3!5Bv6n%oOWctkEZ+m>|c!rr}~;1mBi$FTR0QRucH@d>VLl zNfR3Kp}!H39PRX¨nLV8~L7E$dXel4V`*L*e9BFYRfqN65up9NvPE8p}*}W040_ z+gs#44#w<9g26rl_w&)^Jqj|i$cL<q4m-f(u~Z}!wFWromPoDV`r=`3dwduT9{8y_ zU7GNZ&Z8nZccgQDyhc9>I$wHQjyJqYl8LGZ@=mN8yw11Y!`K`zafLRw4Zc+)mCS=m z(xhK*3)Dgy$043L7zdKG{H?^#9>N8^EUMR6Q_o<}k7p>nT}{DyAX$YX+cSx2IIw{E zwE?HcqN+9mM?5NbIS&p(#9-+BPB^E5_0!~_<k7@D0@5sB`a@8494~CDaa^8>Z7#S> z-V)_6=$zZvJ7mEiu+!sXwRr4gZ3s%?>M3&D5?Bt{fg2A&bcO9le`7w~;fC1%*ap&( zL*`J`{!8fLexA5SYGkf)efQf5t^pM~cTp_j6Hh>9`m2||_Ipe>U?eR1<lceeoU$F9 zNaw#n)qFvzr`WHRK10r3(0QQLMqmkE0cZomjmQoOl%$Y2R20=-H%~B0z>ni7p}a{! zza%5e6FB;l+=$A|UD~{yw9lekf(*jagQx3XzP?37PJROfCo}`~@UX{24ywS}?WZCa zKN#4!On`(f<N?OvyA4<>f^Y5h`rYmH<|B%$IKNPGvL%HOR2B4&)xds_tSx@Ijf-t# zIKH?5c5#Rw0Rg!~VbQwgDjW>KA!t)vqqf(_<b*DpW&+RNMEC}QOHU#_8Z>Ee;=#F_ z6*xN)a3z5b!p-z{1h~n&lH}%&Tj+UcV%vt^P(!&j{Uo;9*y1Ir>Yny7C-9|MoeVNU zlvbfH4o+*4&S2dXT)2^~8rd_aCQCbsGl~8Z#F*M+T(A|54tuy^#)84M6HBKoliQf* zR$c^|^Pms?-ec2**!%r_B|Bv7p85Qvyhxp73*Q<oZw)IZ9Gcaws2YR;&|E_mHw(gF zvWfwFCWYGY*N>lYhqXvRcE!n33toAfVQ&wB8SL+Wz3l<#F$YlSD$QyM!~o&ShbeM` zSPa>KpkB1$^^qiYTcFMyksWY{<h!qkkv5TyFL8c11h8ONHf~~3BKNU(FST)vO<jMh z8f;S~r^s@m_w~j_@^2wyguEEQ%FT|3+lI_oC6vnAWB7s1!gWcvZt1Tq|06)5CnNzU zuXeE-&HgMh4Z6x_W>;(8X3#KB(xno&v-mLF6~~eA+*~wA3?ezsl+@T|EUPbuqI<!v zxdb@$r40g;4Rpo|ET|mlBeKu#38qW|;%IH(8o*;LWiY$RkD}VI0OTMZ6puo9u%5Qg zDmwT&N^T%%ii2~RnVY9K!qx)H-8_*@9Dsr5n@gX+`C+K=o?oAVZ*V9BpVG>}P}W@! zW!?3714Vf81)hdV0x*FH;C_%3Y%9w1y@3UW4b+E*F2D&GD=If>LMH%v+>H`BcV&_4 z2q&pKKo*XDh)rLQ{OA!Jj?Tb1r3&sU+^IY|dsBRJHhdj)2XYaTOS*&BEo{EE27(x` z*$}xvG;iI9YkDrNPv@P>OdH@OW?;T~f}KN)0oW&;fX*|BWH?9f^f~|sJG=#Xf~zQf z@RRI=H}FFFqdti-t2xMFZ=^0do@q_R)SfOQXfhAdOd57Cn=d>(G`^Ky;lN>BPs8g5 z9-jX}z$+z&4KNbT4eBW<MQXEnjS@X<8C1#oKGwDY5SwN4odkt_hE-vX!O7(T2nK0l zr6V^Deyoa!u#%p!NMp&+LMCfx35^Z68JlsvEqKj~l<%hr%!??`rI1d>`-`YG$D5~r z*f?zx-r@d=qb*wP-To6t7-myg+u(WW7-G}B!Wv(u1$<3r>Ntk4j)VASj?Jvc8~Vk| z!B#&lQzj3qkWNgM9Hz=!^;B`-HPnG`Brd6A&B#0RWKvs*AnhYaTR_^sNG9fBRXux1 z>H!$DKH)zh|0XQP&GQ-5iM9Ts2d@%)6|q{!ULl9qH$MVB`YQD3tIyRl@XQ1aq%r!O z!hNYW;B5=MVD7BvbPdO|NISMnyKdF(LJA14`M-S2s+>~|J%gB5>D~O*^jzLq0S}&u zu{Qix;s?#AXESpJJgt5X>N|DR+5TCC)<`Ie>mxI#r%&-c(ACkomU@fyO97TR@C8a2 z5UAIuqq#npto^IA7Jji-IO|3rgbz!3E_wdbL~7L&y7!U$S+D;oOc4_g#1T2lb94lj z?CXJR)GTE^5vy6M_V#6JmOB3gunF7ySt&iUDG_~^nxG}{j+F&8r0NBk%ULbq@a;}$ z`(}NX7r{q2SWj_EbFs1B!V3Ts7Wuq<n3q3c%B{ToIWHm+zlBdv^X*4@Az`QmVXtS9 z(lAYRks#Af2)LPsk4{P_B4%uYOx}e=kgtds2?P#&g;-#454$azODxuc^tVhYwVMV3 z;x=PBJ}Y5Ot2Lmb6<RDZQ0p%ZpEC!E5++eD&Sps!aLUmdP;G4~x&Y!LK?guL!<e!F zDlUg5V|@xshP+)bZ&xL^z_(^wYP~oNN?}Q%bcA2iQP3L5N^o!?u3;>cLl9n{YFvY3 zwF(xUG%7~SD@f=t9%gWu99&-jp^&HYEX=HVSQS7q2}A%d2r{)O`zOd^ZyzEI&w}#= zNC)Xy^ed&3vf6ILvmQkbpwGex(RxD{<{fKB)|RX6J=Tv_Ey6}>SX2Cju?7W1#a?_k z18lk=4Y~>+5tvsS*%&7^LV}@FH;6jzkHAzFwtONZ8aP2G7r#jG*~*#|2(MXb2<EC% z=>Zs3{U|FgDj2BvDhzrq)kvgAlMkbS;ExN~J@|>WW@uTWQqcLwcwmQ<SwvGjRE2mG znu<z*E@0!J7NJP?^$3(9jHQNW2H3jD6RN<hfdK}F8mt<9ya5<Hc-E&>c`O_e-qMaS zKbLXfjT*xb!)N56LwM3`9C-(zkWfxSV8}_RNqV+<AhsRhsw;w0u7y`*n64zRY61XY z^bN%N6lj5PlY%`rCzaa@Q3-bHP&_~=BueCqkFx98hadv>$$$hzKr!A;JgZ97B*SeS zjFe)a#Q71_uufyLWS<5SpHT4J39)|G-?G9<>zDZ~AT2vMoGIh{+_zIHd>@P`vKE>t zs1&>HDyF5s^-YSO6V!spZc%0A<;NqHx&5W~kUkoZ)!<*OI-IBu#&MoHqS%EeHC?$( zRorG7y&`DKUy4-d&X-&v!T@uD+w$K;4Xj^5rQ9sH_qJQm5^EkUpf~29z)S53hW=+j z4$GQANVCFMzsf`$KtP`iCbJaLwW#O*6sx-qujL4!R9m`L{z>eE+;3nPEC+LR+4D{o z`+dB;i<kHF5~9Kof>t(U@*%&!@=5DcsM^3w#vdCSdig|oM6XxD{N(P8^OG|mP%QV+ zhLf5HB8ednAPg8qL&HPRhdvucqmN7kePkUvj|vfnxRMGG215bDkdzSG3;F;N1(^DF z(MM!3gU%JO_>AA7z#01BpAcsRU2`4if-^v7=21NO=wf=mo)lMbD7Mu%(}o!<Ds^0q z&KIy6aV7GWR%~4h*t!-xJJZwvcdev++$Nk;Pd~VF+@il2g;+-eD%`A;;YTTK9AWzR z*f?TXDu1+LJrXc|Db0Mj5zv<+-MxD`NL-@3UpCxhafZ8*TI_!*wFnSSa|GeE79X$_ zlq(bucCdbp2;-ByG@us2IysGXKE1^I5cQ-Z&?+gpm<W#e4OU#^AMCe*f7<fIKpy_t zdd;T16x35F2JruBzrTQWeiK#y&qg}Wp}i4W1^(wiyMX!_g|#-sP^4Xma5U{g^pku# z4Y5;zfP}JH3I%1b`}0vy&SA)>S(+r|qoBNmd=%9DpNoS2yWhLtCJG8@s)Ojh00kL9 zLD=M9NdX0Q5&>P&Ci1|pI57|C24RqObn5355*fYY!p2`CpNcu+h&Q#x$VY=JEo)|q zBUnl3b0R_k$;$fIY#;HX#zJ6PzbqJt)4(Tz(1sTwg}kNwx8qe?gW%t@YV0>wZT9~j zLi*<j2z+Y@sSrU(EpX&jF|`sDt($P@_sfBnG8!#OHwsx4$4%d48#FVt75ms$V5e2N zw#<JHb`mu7XMV2%EnzT2|2=en9vme@XM!pTHdq!6GT9D-(nybF=bGq4<2%0yh7lMl zWY=IGG{G(kN5s_gV?0#i<9L&;=fouhj@qS52=0<`01tP;X&&`5*NlzjK`iBTxB{0H zb6A*XHzO}O8U~ED!dT&LGS>nYP2u%e=&{`Y4GxUf>6*puOEZ0VEVRIhFF4&`qcr0% z2oMmcK{i?gr?uYftbop}TW@|ciGyCSPscU*_6&#%m3VdHG&i=So!|u|CH<q_+LQSr zK^#4@6VG%rF+2`Oe0ooXV=w6FBo?QaGNG>5#$M15iep>9z?mhy8KI;n7<?~_q0X}A z!%QNs%k!%o?*2nQOd96KZsz`zXU@PWl^ndGp^Y0W>&JKz(k7s9;5u@Wk{8+a=0LLA z+mT3P7+TB8q0*pu)`7(WhDnNUFvx((`2JBtGB3<0wyqH^^y4Sycmx%C76Fn>jwYQn z!kPKxI)Y9{p_`vdd7DG;7-eiP*tgba*%ibz8m0aopTdTOttmiSYdX@HTi6)EN#G65 zHjwLKvghB3{9~I#((6*;gLq(t?fpC_mv(*dQkI7~ot)!~m^2&_k?{&EK!%Vui+hf2 z5ZC~{9n<Q#=s?>>yEokJ273uyGAfdmY3G3B<ssajsFi0a9E8Zw7ltudsg0J0V}e1L zdBQXvvM1?nU&iLi6Fn<Gt>HwaQmsnbsf#*CHz(DYbg(u8ulW$wLlOoxNgm8xF{h1D zc;JEa9lJ|ZJ0p4rfleh}V9ThqEG<-}HK-K^pFbri42>Xhk2!4)Pl;bhui3kx23m$7 zosAo=DHBGG_XmxqWK9%}Mxs);A-Jz%LFMoiB+3)L3`1=T?fnu}kiTdS55hg>gbCGv zsCp+-_2_04N%6z<7_N&D6;blsv-coWJbS3I0Yw^Lu}mwnqONdnc>yjPRJ17MDry}% zHx4B;_w`XcAkf9$#e4_YUgjn0E^x|q&Ws5$ksmXW?$%jJ_EbFa`Bjq7?uJafFPONY zdid1DAv0LjU_CnnI~h^LS1}+96>?DiSsDY`lhCT2niPqt=%%CJy(1XV4Fnh}{X!fK zy#yaLJ?&veN9!QxTG{Bh9$gRm2R$K1swf9K^f>2G>nsD62BVBueoaM}Jena7Skw+r zy%Q9}!!A*KI4EFSF=xD)B{<p`!7PGWQn!Jxt!Qpub6`~jePq#Lk^vCk2mm6gnl~6e z^=d<h2Q~JGk~kW4G6updgW$q`Vh>RtebSy8u8F-wJLesgI;c3!wv5(ro+2NDDn#oC z%Ok-lUU752W-qJCS>@&2OD%i9E|Qz7iTWdMR6K}HTF)9pKx^14+2_0=8G>3ehJ^Yr zo;E$Qj}?y+qKZk;ik5&|;7E325{f#kSU4)tRMF?9)sp~%jpG{q2(KeqW2#5|fizS# z`0Ol=N@dMniPcX4;<$9G5@wKIZMZ?R{*V_k;9(-NN@igMTSQhMVN<S%mA8ZIk1!2x z)DqoRNEI4o3b8K&zA1@(vc6>%`mn4*+Vq7&Bb#E$G?&n6JdI@_Fl(j9G95>GK4P<W zAM6fuus=-Bz$Rz`LQ2>mQtr>AzEai&#PI+bXb*xR-8>I5<vgrfDf(nu#tW-|Hz=|e zP-O21Mb-q0Y|a1X?#-j)y6!tqpin3jKmY_uh@xa!E`gE&NF+^avrJ2rAdr-pa5D*8 ziZ&QTfeQ!%<g21c77I$+lpSS}<1CYLJeh>_BtGu$EN&;0<IZuGnMtSpM>^wk(mipP zGj4a5?sU3mCP^o!Gn!<2KHuNH@4ok{3LvRv(rJ)*c=hVOyWiiwfaCh3A0bFszTWfk zPADW)Xv;mX_LyR_041h$fDZpX1^x?DzQ-^@d<L6LJ>-aGr}G3rY0(>@BoN6U5D-8I zQ2~1m6i3J9Zs+l3>{SRx*@CUAz7W(je3o*8Oj(zl<ggu^qp@QOxs|dH+;`kg%LO9M zxGp(lsFor)0PH?^EV~;Tz>`s*(=m~$G>qAsBszZ=;j6i_gYf2d$U)VkiG_v4Yidj_ zfMDbzNrO14adJX^YSQCo=k6k34riFZXR*vtTpmvi#JLdoR$M8a)w2tyW=~at`~nyP zL`(|!R56})m@zm~GwC5Epn|Dil8DAlh7Pu%8iHY_dg1(;MIUF{JVtDAaWsNtEt%ft z`gz%6Ftfl4G)-sPj@aO4rdGEQ!Z@mO@-hTZDv1yChj#|#42avPs!*$^kJ8>b4&cfy z6bcEvV0*wP>ZN<_qC(pgwbXg3#e>8HWv%tI>~qD<uxU1=5HF{9&qx7rmG`R_8UfUq z7m<u{Z6-p6&PgNwxGSA>nIt;Sg4JOm)f@X#C5cJ2N14Hli&SE~YwkMfUL-EKEsL4d znO-Xl!?F8KRwt=!t8Bj5liHGQE81$>R$#wbr_;N!3Ew3Zm1x15Y@W4Hq&<Ey$91x4 zWS!(kXY_N7UsBkG*j9R$id-YybKTcP%(!#@xI81{+EPZMdt%3X&byI{s6Ruejm11T zKH&JEe=dCVNiIZp31L>8LDCg_nw(~*H#R!}*`P=F>muf|u^tbPV@ss%v*?@7SF)I> z_8Y~x!_m*Exodjy%c?yGZhcOV64uKQp9@Um=KUF=J>wzYBmPm&hzbx`gohl0Yt$zf ze<9z6iv703nw!8wrq*xPST~wh=Y<Ss`K>%f>!3GGI6+{Y0SV>|38MON&t$kpsjdn^ zS7e!UwOfdgjAq;u^OYE`eA`3j+m87nwko|>`y5BQ+<WO~E`DB-T~BvnZ<0rVkvrX? zyGtdkbg%@vLKa&rTgYD~SKK#b6|`oVOqmudR*3S8ogij}4t<tWmsqjqJ_b@Gb1Y)R zHxV!7u_^1VD_iZF<6TPOgt6XVgt`an<fWzLpVZfohxV`P1VB_qT9B<ie=M$5RwT6f zP`;zuf4YzUJqCKlLbf(s?VTUs^Ozy%K||2p<nkSSbuhLZQoi2t!ptX`-mu4x3h=d@ zWTcQfk<fn@|I4`*idx?T^9LeUlxZUw6X(BBV{lt^W*<29D`s?HNuB?nwtLK^Qtbh( zG2u=G17R(VCWw=?g?cA16V&s7nx0ER6ANYx4RE$pVI&q7$5Ef7i=(ciklf0;YjHwp zDn*`8US8rjEX<q*IU1icOPslYsQq_m1;qUXxG~dFyc5BIbFfaKd&0R6D`_^}n8mE7 zN9uYKzf3JytwZ+2qzuP8jq}q;ijK!_G^vAfBMy40ObMZ{t|1>TAx>*&C^$8s_8_wY zKLd^Rcxj}vP@X?dtdNCDd4B%%@dqDzm?x*_k3af>4=$XZuN*Ib@X-&9geC<qT?8Cg zL&^u1Z?xb1cCne;qFDn47=-n42)Aj09iSQWb)*ok>gUHbF<KhE&#eHyWG|22H%4_^ z?LjJTj(efqE3PM*oS9)9Ezx$uH>&SO<|OmN%lgSYu_`i8;*MI`rqc0uei7Qf7ndoO zTn*PL<W})Ig+iS-RAngbHb$u15S(nDWJhMA)q_Y>h2x@ssmp7+2)ViN?+x9VC7Yo( zGma7~7a3~2OLrzg{RZX6*QT&qUjjKAJ^oxf1P9D^Sgz3rw6mkNcM)~5P?K)_!H<54 za*6~&f@p%w8%DHGz_7Mxu`k)IHDN`mv^(w;E(8l&CQ^kMcFduS*<`TRX9jHwJFHU5 zY^V5TeJCkq14a3+W>IF+NU%J}@Q+fTlD0Gl+9S&XCPy8Ye&XUup-*Y6K%CFN*d?wI zq?o&EF=^@+e%;bj<)es91No|AOH3iFN7Z+&LuS#7ciM9hVsui^?HTFTsev?}ptS<F z<#)(*+STde-k5fbP|~mQTnR|&75ruu6ii}vyb`aF%G7M-gi3!e@SOeg1JPGgJSQs3 zz;j{@YZhHSGsh9!hF!JiB9cwRTM+-^lags##*3ea-km+cRIIDRI>9I1!2k!)@f8S_ z8}RpmbdE>(g!velo~{N?Pc4}wZ1OVH)nWz6cE$lMnhySCG3}pbc<`AJa?RGK-Xfbc zw$t~`F~bh=f-J40=6adpv=r^bF&|Bx@O<73z&^rUD|Y%YTn^rX0T(?WaO`(}!T}1I zaYTYwzAHcnG<iO%90+c97CupJ({o`$lVb~(>w}%EFqh6(hAC^AD|IvW+t7PX5M{N- zlgiK?8cT*9DsGRuE|fuAX^axe3qD;auj=^5G|MY(TNMVH+{#(>m8r;~AgXJg`Vn(R zcFT7`BIQUFzvP3+H^m5x^*=LHhSOgl<N?{WadyM=FDf0AuZl<%;tBA|rKRZfwsZ)% z!_W=Y=8Vn<@om{xv7AuPy4DUIFCC(_-AQW))Y{W=Ye!vcPhE0?-=nm~E8n5k!Uzpy zPaO<elN=z1!-tX#C?|dL3CM4xQa~7p=*}O^oy#9hF%78EzMDdg&ZQ<sBKj7O|3IKp zH5NK*I}T^qgQm$$j1C`@SAoPmyIlU#L5DE@jQ~4zvDcl6D{;BWWX&A?f-cwe?I*b- zQ~hx$G3MXl55p;jL{h9#G$ItxjWD>n$6Vo@XPmJ~Z5X5I3KjoP8qXLvWOV?17Yxv^ zH_$#P^%~l#BA}g^=`cn(zjQU5rZ$Z_ND0Lt1u5ZSK3uw8nMq{j>Y%$keO#JngQ+r- z`Zi!{m&x(E=JU}b22=6+Lyjky+VyHzU=z$rcIIbU*0Ago*o<N<3RAEuY^|7(>G&l( zshnG&0W3re3Or0TN<7poaBTd9&bbo;8k9)!A3%tAgh9YV)rC!4jY9|>3peed$z~w+ z><m_AsHbXTS^#^F?DupvaFiS?bJ45|9j>UGL@U9pVCe$IInv767Xs(#X}V}eSEq)i zt$_>x+h+AE(Yqs&w^=1O0G#6LfOwh`PgIW_P?!)<&0=X^Bu$LP`moRY(d(r@KfOeN zlYPz~dyniSB1sm>GM!2lE1<gBpgvG+Y}`p(!2?1tU{Pdu=0yj5Bl@@3G&q6X4C1H7 z6KF*Y1RQZn2p?iDtct34pjOqtiz7-veGBccKD_Y4sOC)>RbLp@ytzBgn7h+l`ET8y z)P$vTty*QSE`m!~P5iZb_-nQ3xninkY6vqDV6vbC0(b|LWlmx+c@SF9r6X;H%6XUK zS{}YBu$C3|7=-@MDG1$Uf|TA%?ZERv6#52+4Ky2}o&egk$JoCTTy6tW8~y1f{)2jA zI+pc0Qo(rm+2qTcej!Me<l&$xn&r3h92dxAB3&(aU$hWvNO(|eyaD)p={}|me=rPN zI_ur_9tHXJa+_VqXULgipU5S2ZWH7#WgMxir_R-2<^`}>SfHop773nCwnnu6rcDI) zku@Irjva5jKc^xFoemVHgfMceO%gsP7<m=Y2w?^1V@)LTSEGOvCAClV2U%g|DoG4S z5qtv5u_T7tEF^q+?r2CmnN*wBp8F6<TcqYz4L(gJLkn|}rM;7oNxlW+{_Rzp9}gaq zL5F$*aMtnBPxwY3&JxH9q7O~`q2psB6vjrjZTZm7_iw%Hi8TFWMMXooGJ0#9&BoY> z6j0LKoT@zG{xBF(YRaYnMRshajPP17RL{#c<1VVb9>5q?ojS%=t!~1HP`N#6Q@@o? zg`DB2$WK8>MlJ(7TI0Pb&bJt^e`8(C+BFJp#T$7MHO(|l)8YRV4fXVJV9Z%{0CI*y z=kl*(_O~HRtXaK*B^5y@a5TwpWiJ=SnXAI^MZ?Y?MuD{L8NPg#oeGwX(Tz!LH)0g# zq^+DN2uXYydG`eDB9hGR8H~k})3r|)EN57p5Jc^Mwyr;LTLU{GhHzrByo{=Tf`scZ zD(>hRl``W{PArrTdkN}Xp^=PsKO=Hx|79PCf0;diDTRv;w%Yy-b!oGmh~{9vGRR!v zsz<hra80u)dU#h>igt1i5`uR}p3%(~6<=WAW$HIfRT{IRTS_BacVSjwZDs;k*w?A; z+Ln#TwBqu7*dy)4ExK6yy16T*9;rPvi8PjwY*6OM6hmdst&Qn8@FywV<Ef;~#&K?r zol<b1nzwW-2ieY-*)vf?7eg2qS@lMd#L$xVRvLNTS?=b>z)_3U`mFmZk}M>4f!e@J z%`C?-&)%y&Z9yUWW$%W2A-`C--ID1T=JZ%=5usIkSwERQ{S*)0`kn@FpnlhWt|bS1 z)y-_tI%QGp_P0c(F8<w&i90eqPlYjfTWb>iUrg3PyoA~;M)aqe+&|Ohmzj#_&$(M| z-jz3cN0|3~X5O1z6v=75%EW)$+nad6$<^L#On#jll(qmL4yUMf0k#HcvZWQ6IO!1% zt{``X?g{n06O-O|qmynszR@?mNBuZTH&$7NMi1%V&mWtfetd<MXgL8^`rSGKmKJ;U z6Ob%`*@2Oc>F??ZK;SSP*>vt(Ve(s#L3Z|qPa%MvgPFw90sd^1xlax;?Q+-RAI4af zcnAmwZneN;qGBbU5&cS%@?!K1f$clX-M3*h?eMU^G5mbhJ-1T2*BhPWkbI@uC5H$l z>9uF%1B|}6ns?7$_jP00Yo&Cw&b_IggnED5KGCAJ^4oQpmRl;|dhSt#6qLsEL==GD zxMH+``iGDhfyLq=-}X5A;7ShjZN%HAsqKeWC|>F0Ntb_eCr^6q38v<jvOR}}^bw7L zzfW1p_9A8a+*>^RQSX+wrriHp@p}+e^X&U+fe~_7eZ3PWR!d>KoG18l@pUYj>$zci zmU>=v_msFZy!rXp;W6lW>J8;81?UXS{887cR1DGAJryH99~Qr2@?{8i7m2)dU+F;< zm`N1!0DJuR_nRmMN<z$pEEM+y%`W!GXkINGItdESVC;7adfSO7W=aoimE4f{(4ofa zd1x#&x){tZ%$P0E<mJm}PAzVM%p{s@s30;splI&Ic@;~T7^#q_R7WD-2p#bBDWj5Q zER2QfNNM=C`tja3wzx$lWU&;bp2-}sQcA3-LZ?M=VM{ArfO>M@B2%&d^7BYv4n<<! zm&f#YJQMGS7sfD1EvpwJn0ygW4|_<NpFx^H{9DEpSKo3v>R8fAb#cpLbEi_>7~8I| zn|hfvx?M$Yx<NlNnTc?1u0G<V-#g;TZCl47IH~NUg#jcAa6ivuVG2TkUJH{ai|QnL z)2YN<Hjy`}0I`I)!n0{_ixmu}K%^M@5KmZ^v@z?-t<I4^R7&d^cKgLsXU?DT#%dx) z)lL|~((LT{NJ$nHvk*%GW6%&*VGVYQy~d3A@K0g|QI=dF?Py~2*VF-a*{iBOSz?o& zkLO71WQ49MJZm379wtKBpPfskY<Tfei=Z_&dJi0<F5_MfR;g{jkr(w!c;o%eZ)7M% z@iB{YC!9rsS-RJrtjxjrAO+Bobr%25G8y?D>;w!iDh$r|x$^`#WV<?3>{RL6{nu@B zyK3MpY#$HuE6`aIxlZD9yf5Vbdx!k+0Iq!61jtq1a9Bd~&GW%0;y_KE(R+Cf!`;qB z;vNhs$x0mfc|SYKG04W@nqTODqQy@N6APuv0cJQ?dw*tfU;tR4>FGqU)m&%Hr@TT9 zIM8dxqKCMT-lL19v=wpO==<o*!udI)&>Vx}z39cDG}Zu15$=hLCBqhim-vHAe5)Qq z(y6;{2xfu>A!mL2h(@rRA|1oZKcHkcGP$~)Un!J}#6h`(yT06=#6*$iLBBjf9X&|) zRz+6XWKmY|ifzLHSsNMh54`1=dZ{ANJAmS)!*$UM{+dp%Mt+I}vMPT}-8R0eC2)OQ zB-84<B1)+33qYWi@~;OBj7LbUmXsXffD{*dPeqmLJIrRa<$2q&S<xn@ezj>XOp}CQ zdiuv#pfiV?cex6;pYFHM<v!(@tkt;O)Kvc+=W@kg!G%pve_@5GZ{e@3bo;q~C#7b! ziB-1x%PVd5L($*b7Qgd4Tbzl$sEPi?8=Yt?-F~9q{wANe{w7aN^56AME+}r(`Rgl8 zek&up%Iv?R+kA4BZGP`c+g$doe`_0EV#w8CIU60F%=GkctuWUu5XDNrTO0k!>u>bb zH2>GI(QP`vzQW|UZge;MkU{pNzoK$X3nIxhG7uwR$2)6#R@thruC!I*w<Z=Zr8X=2 zpWCUIKcDAMldv19Ao04S#F(D`Lk+<wu6(maVNxiwZ33kySS+y&neG(`(o=l0Il0Dm zD2w{b%?wa?7}3#_SW4pwY(`~fjh9KAC5t?>_r`|@${d#{BdX>qk2@t|8<h%t+2m!V zR5OO(=}E1MnG*Igr@SlV=zXKhmO33PGg)33!`9pg;gA)HJ>|INgU`eEPhOVKMk*@- zGJ!CvY#)~JA4d6yV1!;tWRN)X?05MJuAkG*OeN%>gAK+CLJUkMA{?k^niNN}Tk}Q| z>2!1OpQcGd!CSe1Wb4RyOS#I@EDYY_Qd)q)AXjK+%xAo7sdsE7sfgE;pD<gBo*-SF z1v7{t+;6qnq@WW`-SqUIXp0&*HYkpzIT~(UEW<Lcbh=&-{fN`SBEFG8ft+S%*_cQH z%(|}0w|DtNnhCt4#MvtCaZvLrGpB4nL%rllmwAtri8x9J(@a-?vV%F9TUS1y#R}#; zD7q_u6OLzh^SI+8?Z+)P%<@SCS?nMdne)&|%>FFmvJG89n9Z|+!CMyS3eK=fPlcpJ zo|bWbNoHx5wDop|Os2=Yg&LbD3{Nj-;VKt>O~|6eeKK6+KLMZ5u(X#@#&a?2AG1m% z+c2MxB^I_?ncy%iQ{D3tIg-)RWR*xBl;sH#B~qcv62~p+{#I1;6;eguQQ-}2Q-J|w zX8xVb#|q$aEfT(0=AJ!?K*y#c4~TXlBnpJ&Zi+(PR5k-D!!DHJjb9BkeB>0*apjkl z>8d>%Ch-t3Il?90ZAq_4P7TWDKM|K&ByNo(`Yv7mo<`)dVn?s&K~`<wSPyJS24y+D z2Q)Gvpbiqo>0d3Y^cI+CdgaEpTkYSq8B{!=AVlLZAr%8R0$?ATns{m#8g!o7q{}bY zHsD!oKXsb47lPQ22gzAFARm1;gLfJ7?`7Qpoth}ABeuGhtu4O9h!?%6g?3Vb3T*d> z-lg_`()tv;=!&MkJ+3A63;qModY8|QnXS|m-91w>vyp<FV?Rq}iX53ttS956T-k!b zMD&mp$n#yNdt7jH1%sBY{i0&g5))A6Wx0RFp8A9Zzf0f4V(oT5qLNj5e=pX9sdWk7 z$zC_N?Zh@R>Mdc5j9hA5n-g(hc}Xke4|=F91|1)YPpe-bEXOT)$-*U2@ltFFj{ry- z2lLlf<&p)Op=qekI$_EFViWUZ6+)q41QebK3F!q;We{19r41_*Bb~Tt#x!D-CTHeL z@4qh|cIm$Nmli6g=gUZ7H#;*3E0VH#P(>{r*yd(&Z1!mN(!$)No5OdkajY&}rxKY8 zarqM!z0i&GqA^qGZ}2gO7Hte78U@$c_i4kLO~e2qLPUiU4H9##Nm%3x2eUev)CD?m zgb(%3vjz5T?rcA~r@GFvbB_}$ZW`qrS0d*KMb)OljJYrjvW3UT05ox&O``Oq+GRck z3N|CHTQ6X%WMfQWYIs!8@L65HLznN>MbWZ-uGhvI^9P%-NF|K{@2~Gat_|u5_n;Z7 zt_4KyR_EN;l}9vT!oCiq%IUQkWi-9f{-itVI#PTr3$t7$_&g^WQ^RD&W<CX3^lnVr zQOoCwA^eFXD1m@=Q!3Xu7|V4%1zX%LgjgJbYUaupFqm$lJiWRxrf)^L8rAB_+Vf}H zyaSnWh8Jk94ywqiD_c$^L^e6F<r10fEjhbfNa7CY9p?*TD?HX@(VRdNHJo)EADKBe zTf!r<bn#NH^ymk-r$!eRtgQ|40W*LPv!cv<IF^;RkL}p9BMU36B*afrcIz(ej%m0F z5Uo(<gH-uYw#wj*UUEsScJ7IN(vwEU=#l8a(nA=VV<fpaw{wRu!otpnvz4vT><4J} z(KaPpN5a(I*hqHl(Cj>rt@NhG!plvA+3{eux)nyV<6$-ZNVe?FHT`f)(^MBW$yCCe zU>SP>EwHFV)_{;3<@2*nKQFo_rmk!^dl$5df?K(KW!cB5;y~-65#l;Ie`kns!C3s{ zvQQ0E0W1PJ9Y6t*^Ca}4TzH?SXM*F#<mC(HWmBd)62kcH)FF#Ar%hfSag+L($PF>^ zyW-vc*y64+oOu@Kc5NZM-@>l(kwkOK_-!J#$(@PmaAw6uJ1J-UEF1w=x-x%r)z6hj zutuOOB)`?<*~^57iKKg`Q1fD?nreOvGf`!WM@1{&2=iMIZnD`DTryxu2rsZ99XNTO zaB5p+Ibbx42B_)NiwS*|_|$>U%%A==<bMK@L>$kB^hN>qVS;c9g)7x5SUpN7l_R|z zql(QE;%T>BwPB^K7qh0XB^i?zl<rJk7CDq&Gn2z8&vzod@DSSsElk_9JI5xTn%uo@ z+cp*_LAQHBw}bFK%{bT4tz%9ac_Ef&JX(x*+>=6}{C0F~&J%4A^w}g%iwkBr5wN)v zr%6x%wJVCkBBx8V(4I7pzQ|Xn)SCD-qQ$nzOwkS_T~O8f(ci$)se_5sPWINH<jD#R z{Ug3wNHx?nAmrwAXIE@VM%IpZEHf~L9~7~4a0=qhyrb(PWZLo`<~Y5ic1?QX7`&zk zhzt=E3LUi!84{*bl$;M_YbzF$jK9Y7<|P~?9K-DCBgFcHV}q|sjkqcEeYRkx<v=!y z=oImDg0PBMe49A2HXk<fq}meDqw6{%F~d@^U5(8GfdU!ad5rND-_2U|=Yv;Z?UBt` zN0AU%EtXd@B_z<Au4BFZh#Lb|Cw2}~$|~PH_G0|)g)r)T^Tv&f1lK(+i`-Tw`L)pS zm&l!?(7VfB#PxU}58;Qi-YyqQM9f<mw(kc9Wi1w$D(75iQkM^i_X!F{C{<kk%-Ju` z`)rWqZgckQo-afv&DpOz1nug6wL3WbS-`H^*TNjH8m-HRh;lO5<KhB=Ci*K7lK=#y zqch>L!QX&u#!^utT^VnlGM+$1gO)D7mbC!@#{`Zgm*K4((FFKr7YJj6A6-UZkaVHZ z84>BNk=F~+&obAIyy}R)$u4j9@^lf!8$)VL+VXfnazpQE4A^7I49qH{^LSg|B$r2P zFEuP{GguJcLJqTwL4G&k_^H@8=Hhwl;f!OeAu+wzaw2ppD$j5U%>RhIA5Is~me?0C z^iC9TniaGXU5E!BVK0~ffM?yXT^(dc!rIZB#{e8XcX+SO$Sd^38P@-SM%s;daW0Ba zyBI`{gGHhZrZNre3FgjCPye6>X&evC;U<2O(KfM%u3%<V0g^g{5%sL!0qqQ&Y0H{U zPcP0*PybjrX)WxiE0BTQ0j}u4DgC8pEl#kJYvhRpce0T?Rc;STWu>bUSWl!{ZGq#i zNc(Z}9`MYq0I2D@qm<2nruQdP4Ypt?E788ao1a&;sEPgDsx7KSfMA+c4Q!I%%62Zw zDyB5kmI)1O+&2gys6c?gGC3aK=U|yU;t1Fvo7e7{-(hnFkmJ&f7@#Hw9uOWGti_Fl z&hp_9Alyz!WG7cSee0ceww0b<A}Xh78go6KO9U{dNH>Sy$(d8L5u{rM-yLehh&qEd zoH#*o0L>E!;XU@M7`(bb1yKS{U<yNbIln+V*uQj4*{#;Cqt1(u572z-X54F2FeC`e zdMtB9<m{ndXgLE0=)ky51*0`Rl%mm!hEmm1Qt7YMY4(b17YkfdvqtA#AS4@hQhj<1 z?ImXFAiT86$&C5VysS921aeZLZPxR-%Gk(`?P)fbgCv+awf7)#?hVw6LNa*k1K&6L z)GOCtE8B!rBSE5{)@C&5GLXYRJ`WIWCe(Zf-t62wi@L;qL^Oqv<$pyr3EZsah&PR2 znG1}0wFhx1K4d0DB{4d1^C3LTu<KqXKf-bkzeW5($vb!PXX>51i30Z0=ZO792o=<x z#|XDcNb)jS6e{!eBH=XqDzDUwSNrOHqFK&8!{_?BXUh4jYwE>oL<>7XoG{gRX=lCf zYCnm+6?jwm@CJwkMi7)Ya?AboHN4+X&b)lN=M5*Q?OpnfdZC|)VNeBs%1K&l(Y}!J zFAsp%KgHMvszdbrPs+u`T)B67u$-^=oi1RdzD>1N*VPB+*ON_-uquRP;YqoV%yj-) zdCjJd;f``Yt}lbP8m+as$(2!w>^Js&fM{w1GP$(cn3<)I5$2`0KA;F_c<AMp2VNa8 znqoJ79k#yWmax2*zTRy$3{u0|Obws28rFsy*1oznrb@_@*BO1&@*IB6-tJYq)mv;< z*IWaJGo~KRdA*-d?>6sv;P%#gENkA{nFoRRVe?*(q?y6(GCJjKy6x0LL&E98QHpOA zZ#;)tNT^Ol9HV7tFNsYJ6yp4u4}Ba7*(I^vR{F5PHDl~%Dwj$Z5O7wPLX8~Q7|^A_ zQve<_7T(3+*NmJTV~@p~22T<Vq$+b>ymM)Q%9t4ikV%4h1E6j$)OdPoLf79NpjAqK z(k*!vL>4-ZZXUHz-A&My0HCK71YN6l=Ga_WD#KWXA>E;fOdC<sfHmsI`ymHoWx*~$ zi%{D5`M3j+guwr_G(^yuK$^SHpE;ZDUI5;t!<BB>A}Y&9K;{nMfg~P8{GDiN)3q+L z(dacSxmF@^%yyH55X4L*6!jJjs#WjbP}Rw>Kr8ZXKH{5hhgzIe(#?n0iZkj;wakZf zMcU4=R#S9LdntvZyvsK;Ytya)n2<&hTCKF%HN=udDpys8?=*{{jU#gs&{lS`1;@Nh zUPQl5+PJerSNMD#GXHg|MH7*sPWCN&!B8qn`<S>D+GSGd9r>|S!!a3$7E9qY;4id4 z;uY}<!_?W)f*3_1$dHf*8Y)_FH-%wP;if&-bsqTB9{C2<_p~<K(&9Gv^|slivzMBM z(XM}B>{J!o04BCRW22*^q2>5IZANw^QI%$(jj&wB!02sW3!VWhy|%Ued&d`+kXxF0 zPG$BK926lIXC+NDFYT6w9@)12fw>1BY<a#p?(U6OwPSAUjt5#QVp6hlTig0$BS$4g ztW-v{G2FBg?Fj`j`*&ooZ5dqqlYOd*dMmRJbOH1SlZuw^F^SK&JlqTwi+~YGhT(w` zs^wEBh#KK}-_dQY>%4Va`{k%ENoq^NhjuSLxNXNn+jczs!Ilm%X@ssx9TpePHdF4V z=26q99|w1Kro6m(c%41kJg^sd@KSbVHYbiO?Y3*nR((NFTI#rot=n$fzF-gUf8fEE zihZAMY%8~J;}`5vQ>}jgW|k!LVY8@)755(FZ`pU*xRiS*_U+#(*FmEF06i3-(`W*M zzXk2kgUwnER838txT&4ox{Fus(`AG`3$bt4N+1U{VY*n|LR}}|a5)*x_U6%`i)$Lq zipOciqqOP(+D>Xam0PA8@zRHf7Nl3G$P<deXAAKiv@U=I8d4Z+n|$1qZo-AUk9pSk zHN&SE=3prk8)}3$3;`lyWiAn`dZv8g)M?N?249@$P*UgIct($y#-b79hLP&I*Iu-s zc8>1ydM?)}Up#32thCdl;$E0U+@&(BFPga!_nx>q1pin_<<p2gOoiHGNIDvgZc7lt z)WN+<Yur)Gy}0OkS^iAuNzd5ciK&VG;}&J^&CZf}@4eaia;@M_Mr}xcx9)jva?jzZ zeTNS2ERAnWSz=h&xocDuEyJcpzsRLgK!+2ZI!m|<1-Y>qjc(Pq;(=Z8Itx_yX+1M; z8nLjKUT)U2eY#xJ<wLqCK~!{@%lMF)0ON)x(#wf4dpzyhD8_VZqu;>q5l3A$`qKcu z(FYwBe^ZR<=0=avRF#Sg7Gn|d3Jwjr1XDk)9z3T@lO0+yrb@mn*8U*9?ReG+4iyJg z{{}nnK#Z8<PB}JpmF!f(@z(QCslV^eZL&L3ciZ2M=!u-$+WHm)(YU$sPVD~pkHHqo zlPUMx8T|`QlAa^*=PN7FJr&)9fN}~8yF<;%Wxt~7J+E;oEFgiXM83?rC{ED@J-?*O z7gS6}Hqj62qnW&3)!oPS?0?YR-`C|I=<;*ASRmUk>FyVGu`FO;(cQ1;@>RX|8@l_a z_EDGL)<qhc=%4BCf7M0OG#B&TBH{jT`uKHSv}q7y9+-G;df&k*3lC(038O#Jx1Uli z3W5?TB1iNWy8NXsf33^k=<@&S@}G5)8Z08PKu46*rAwE*F5S8mbm`Hhs7tRdeY%)l za7cGwRBO_Tx!Ar^vqT$oxm}m{>T;(pcj+>s%Vu5dEIi0vV*nYXa`DU(_eO3fs!A75 zs0pdfl~aQ4LrhQQhq&>3E7!la|CYX6i?<dB`|jvlU%a>2SA0)#fPejcUB!Ig)5Suu zIJA*ajPD(KucGqu?ACm)zuR`<NZ$j4PZ#g+f6w5?;&8Fw{_QSy`8)Ty(6^!3Q|z^W zw-)>Q#`(Uh*j?=EFZ2!f7wr>I`ZmnctMJq1?<ys3l3eA_yZpboa@T9c=gI$@?|5E; z+w;*jig|;niDSa%vsIWF#F0rD{bh+bZI%>kkjSFam5FjB>=>fZU@HaZWd^!l_chB3 z+mHULTlzI6hL@V>=5v<Pz7xr=B=%k8*6oZwMRDYMcW9l|IXeJ6|2+5cssz=6efcE8 z*J9P{;MCITxy6vF7S+UORL76$@>yN%)Y+MOL@l&maJBoGYSo!2cI7+Y))Xt_K+S2Q zCU8Q><UxWOx+yOOILny@L^q0>fZ*1NU)oRI-P99LU7YmJY~N7aOy|q8gX{L01tYZy z&?&fiw1f>dXlb#dkL&Dxx8`}ZX?;c$P^5eZ@X~C02luG&Z+CLlncdf)-1{iD(*7;? zAo47{*7<z5?c@TRrx@MF3$-yL5hmRHLN*wm$Q&=uVG@1)DORJ`onp)kNy?`k+kMbl zo!VPl_mM?gKa=R#;*t`|_OQC;fOvN9qt~yu07o@RCb9MlfC<CU!KDMXPvlf{3cs7F zjICs_?^V=XiK>-WcU~&0{Kq@J`W;=|UFwsypN^4uO;0WLV>lHq#kz3G^Xd#IM)nQs z;!c>XQohZ?cs(m0HA6<LoHxzUAvI9oM(3@+r~Qe$=}jThXXb14-}Z$82g%;%E&}He zaM_xbX0Q~G?Uo$L=#HVi(<)!_QQF2vG3Pzmoae<o3n^agV`4~q-B*t<Exo-OLVB5C zj+A1sMpU<p>Sklx3p7_KSz@vzZVomlfcGtOsK6#^k^%%*srbHo8=dezDTZZ1nP7o2 za0G52_R!__^D+fVz+9AE5zE#LJd&Gmuc>z}e!HvEVzDIc$4@<ow7tmc>aU=bVVBpq z$(~;svXe^F^0o*-UK(@}fOLk@g4~yPDPlkBZ6k{Fq-?FCi7Dsb=t4WNhI0MRCZgP3 z9pEsb(b*{bnZdHMzM$#ger=iDFVjPIU1!Ivc+diK)E-z=CL}jT6aO+|_Me|i^9Cvz zR3(_Lw_@-C>nu20EkANkWu(>{SmeFq>m67znqDBi(QPwnISd+vW(0}spIdAUTHK5S z`X~>L=$jNxIs5-PN5YVVBXdlnX7EW+A%!5krPUg%_o%5b+9Tlw9bdT$I&2}TTj|e5 zOUp{Z%$JA!umc8J0eF2IwFq>PKo=b_aiFk3n8#-2bgptQ+BShSvrOT+fj6zee3!H| zT4#Gkj_?5T;s73n=z~J}k8-hSfW%%DLmz!WPw&$F+#E>!P7OImkee7}ZCyOTcM33S zm0u2kkqDXnS!z%8iGC{kxumh>TwbBMp6@OXes{-l0&#&Yd!H|q*OrUrUhrm*J?$&6 zff_8%^_Kg~1FvDm@O+=)(>0*Bp-3oX=0%Rx&4Es-A!hJxGpHby7ARQZPLVBI0!nW! znoa|oR#?m+$6eeS1C=1u#OZ62c<d7Rn-E4?>KGs`dr_a_4f$tdBd3m!5GTp#E8Dwt zBw^4eFOQx&jw>fB8@ruYEFVJOv5#k7|E0P-z{%8wkeLLj5<YXRO-FM5+DjK7-!Y0y zD!|rS8@u%Q;}49FI!n|EM8szm1oQ%NyD^4c!gmdw5>^Q^IpY;<2hN+1jCxDlLNhND z4AFq%d2#?IH4iv{Emn2#No!<63=e`3uZ21Fa*+#5=Lx)xZ;rEdvp1Eq2-Fa~^b$L& zlF0uVY4TtI=!H}xX48$j0PWRm1y|0I=@C<RjNI)bh-x;4XM{!w!sP;vt%7)b6YBZo z<tCrq6_9dREOWuYG1ZQsgIG9|DqYmbctFecIb{=m18+0lP(i@0P9k+vXw*05H(D(> zefPn=85%Aiv!CMtHX*ZIxr5+(cT_v)yOuG+0_o(d7$98HT_J_qdO&S=gW8Ii%Dn7R zTkkwc#;R*#)D|N(Kxf_%TE8JQsqZ_c2Mm=B+I1~vfFL&#i(LiyuDho1*OP~ZyX73} ze~cb@GJGRw&yW4BpuJlh+7nPRYPxaD?mc@aKC*vm`rG$>$Fqly?4F){X5z?E2h9Ji zN(s(8h~EzPwLx}`V!THi-4+GEF%UnnLmvG)xUtcf94+tm6YW$>PwMhGm-hJavx4Fh zBnUq$lbtYQj3Zr8B|XEMkLN@`9`bW_JzQC!Pb^_aR5#4$@uA`|ibWJ&1b_Z{Jr`3z z^MtuN-Cf!5@g&w4p=3Aiev~vkJFoA{xlJwKQX}thEePK(zM^u5r+cg&;prTB`g3d* z;wsOR1n643_P?5LpK|H8e?MtE`G&hxyVYL*J~l4_&v!YR%Y>-pwAWg=O|VOMPv~MB z!&b_WzR?38(id+5{r|jH)NC?YwL3cR>%6mbJwdKEb>3^C<7?~U6%52cVC!iyk%)+B zN*{A9h&bN$PTbji;H&P`-Zx3$W9qVo5!+Q>rH<Bpr?S5iQx9(6)%xRJN%tE%#3nLA zdXm4!a@Oe*?#0endP{qMVqcS?iNu*$e))Dv)k*q<bx}&pVhm+tqnX|t8u67Fs`{VR zSItdFzIJEa&-O(zTsHx0e_N*WVXBC1l0+d##(vtwJ*0`7&}9{FRK5Rhb)}!1;!qxU z#lc(p2K&2b`5b;AjO?d!(>$qI`k4i$B}-U2LSm+c7lm{>fup<dt-z5qWD9c=w0Sw3 zR2Dmp8n7B*Fr4&U!LSWEn{-LOx6VK%u0-^M8C_d9T<eZX*it%pXv%6#mvuhV%FN{5 z^jbON#F1?>%QTLSOdi-x82c<%o;`!Z_JQ4{$us30Sp1=+HODg^DfD;hPr^W3U&kgf zoF=chw*i2eHwz}oCfl%!P7{-{Z57$9^{YI>B{_S*tgdU$8qH9vyd^wx?3Snfe77M- zC;RC-Sj#ICVv0G7MLt?!C-M>GY4p3`4UQIx0^*6!uCPbz+11AV9c@C#U<_M+x7wzr zdA%NXc#>KSQmXd^r8c}kSQS12rK2szD=Ap@YWx!ljY0~L8svORXXq^e%|-%_?hwax zTl0VduzZ^$C9T0%<Hm}8Eh44BIc=d}nsX`_jW<F70LPRs_m&Igo{XfiFQVEG@7)l0 zzl3<v(!+5&_s5(AG~No-YU@Gq;O?y+l(%w1V*bhNDi3Ciu_Z~gBa%i>^P)MO&>rE4 zQG8uE5Oq4b#|!N>JGT41b#6i)wcq7`tW{z=NwOIBcMScnBj%jvtyT8-N1=Pbq#{t~ zJB;qx>*)seJamsc33=!qO1cxmwc8{KM2fa&NOl5+!AU5lPC`49;w_wsf3FE}$6RDY z`c%ZzkUABnU3?p|RxQuJQi~>QEutjt%HXxPb1)XEd*&ir$F}_h9A$LMY_jAXoiOYe z+c_6Sgi~0&jhNfbh?fW=DhM(ItH$A^H~|(?ge3sKW#T<mF|1{nF|exJU>PUn$8$ik zFFYxU(^^6F)?{BVmek%RYqfCeGNy;_PFyY6(!PxC{9Nga2Yic47L29h<YmvOKE4BM z(bhP?*rm8ykcfDbOzNIpI!{mvlakoCHb}cnfstd}?ejo--MAtK*&c8>J+>Vb3itiQ zJ`t-KdrME#0ZxMHp_8*{x?~O-=!BHmAnCCNn3(md%Ck#~gM(y(K45I&hzV=mPocM= zOzJ3+e#|FHw((IV>5(Js%n)*@0aY7+b_0p4vRFPgSx)Ga_&j9CmP{U2C#-0gaVPeO z)on6fHS_9JuQ5<zT@)2sI!_zOs$zd1`Xkv}V<Qt&ll*^rVq)s)rzcYOBr2LEbwbJK ztfV7##$FiBJXb2O%cIE{Mt714?1L}ybTpnNJxX3uv!gF9C$=W-8-7k*Og9|l7b)F9 zQ>~>jle6Ky!Yb^Lv7p;%glY+<S*sc|ZB9?DTYijo+IKKDhpjW?2H9q2Ze(IY!<(IR zpIc{l9CZ-f_#Q}&FT8Qx^(J{8$-~3MAk)jd+qwZ-*1>Op@VxB?cxX%MhWCK+z8O3& z9Bz30DQ*%{_ZnWvAUISbcFhabp*=Q&*P%d@2^B2B6zP)qw&?MF?cSh`xQ8g)scmu( zTA(l;<9mr-Z5mKvg+v3|=ug9p#z1BcO#*MKY12W(6vU*c&D~tuQxJU+doH$2P?WBR zC$DWt&T1P%S$gQ8FBMf@&n@SrGsR`6n;gX=in+hFgG|PSdiUwh=*xPt+=ClW5$Bs; zKH+q8@w?;(WW+*2<h8wpOpH`-+etxDTwYUO!{7epfqH*^;B;4XxZZoUTW&n4mvAqE zIO!t}`QgJI=MF#HQ7=kvk6caU2dknQPpC(Os<%E^?s`lvDLCfvH&-7tQl-aQ@0ds6 z5=a$P({PwB0d}JpgO5gEYJqy4I3!GN^dI!X59nf%eeTv>LeHd<UpxCSsfzLMlxQ{j zqV5Z<rIJ^x#>U$8GVAHyco7?2mFY8FqS;0lg&I8`=OxA%iQ0LCmUfJebRZZj5;91l zGnsZ3awB|Jym3@ZJe4^YpYa$?EqaP<a#EqUr>53M{<A<jZGv>_&5%x_sPt2LluL%E z7%-kfoP>CaLAZ)O$5Wu2v9uu17fkcggXU#zw1d}YhH1#)iBnpOxwRP;)RJzMfRHFe z%wHLvBc?Bc$R78jsuvLK_P*_QQaz31DF{{OB=|0asB8*ONdXbaDJS^{O$Oye+ZtT{ z(WP?A4!u$u!|pu}V`)S2<dXRrIx3~9IrZB6N~D`4g1u5KxW0HgYm3O5_cJRFf8#EG zqI%L|1J1=N3ZGp-Qzz13(P)Al;4kZpuhbWM3?zrT0sW5CgN!R1L{m*JB!J~VM2mqo zTiF>P9-Jmex~c8pgt-|rj#`vayvq#H)Jf5J(3}<}ibx>I)LOSxC$S&Pb0!j7PAFHT zKZ{tdLi{GH<4EN*r%s%-z;%`dS8^V!$<45$QBGby#?tr--TI{iQL-#@Yn^dAd$*gM z8NJL|oM?|up{FwYFZnMqBx$UYo;cGmsj!vGBt=LO)P(ffCtP4v$U2d-S`lkh`_IRf z2~}wicv9R=cqr-TN3Nvl7$a~DF4~N>6Z}9NG2EIjCh2tQj9AqZ=FA1F0+1BjpbY`_ zBcp^kvI!sU6f#-fW@MH%F{5DLXZEEzTBSM*p;#`n=$IT6|K<p(7;qkA0;L*_E2a_Y z<6=L&p!QP--1=CB`xH<I?t?|LemD=Za9S11hEB^gn&uQ!)M@uzpVbYL_Ki$TOpLg* zG*X_3h->2<^zh(t37Ne;2Wh+^k7!BV3d>U|jZR2BSJoxcWsZwZ!)RsHt@~7%q?o#H zo+3?YiXUV<v<OXt&l3CD&O@a{Zb4!RWcEgIv(~1FeW$llo9QGg?qtGg?7xhDGW{{u zS*D+zoV(brROQiQr>e5yUpRYm=GYuYy6M^Av`rkH+_#TNSL|{^bv?TEfrlR!_k?B_ zcPK(j;Pr^7AiMO;!pwPlGFP3AEyUF~<@)rENc(-04f*^s1VOA^I&*Akf%9NN7b>$D zf>-%eJ~hKF{U#~XmQr)u^5e5}t|77q)B_lF%)BjpYgl;isIbRLTT}iu%35t(CXJBH zn<&u=#O^6+M{r2}Bq*`=xz=!OWINH$9(wqZ4?OxoM8fP0d+J~aUvA}TLTB5VfUTe^ z-v>i-Fs|OIi5$+#rtLOp`{dZ64qx`Bl46IKH<wN#mvC;D!UXaDl1|)5qmKJzU-=`m zHF2|w-!ElScv4Q=PW$ry(XA;zvsBB34F)xs0v_BwCL9KMG8E&a2862CZj_w?@wzRf z&6!gdb+p6kR+33|)%jkG?EC0*`zLoFNO8BRmbG6zJwRnE?Hp~o1bvWmDAX`pd1adZ zoS%yaZQcX68||Hd2OlSmsq5iEqvVXZ-8*YiGpHr~)o&NSmEVFE&2l=gcSL*32=|Q& zGaG2R;9tQho}_iT)OT3XzE-T~{CAReW;E=ST`*3m2d%r)dlwgntdyQWr;AU*;lBH{ zj6{2J?=PIjW*>vH9+wV|r)%8z(a%8NV_ddakXhMuKZ%}sEBZ~6Lfa>mtU~o$o!IR_ z|F1Rm!%!K{V|pDt33~Xloc^h2zUS7C(>*x2f7RMlV!5wcJMK<(yE{ti4g2(Hc@6q| zK6#V2;l*dFx46&rTjh_J`>PwT-l}KUI;||@IG!`!aCq_d@<9B4^LM<lp7%df7T+>V zl0auDH+*S5^=;BK!WeW+Z^TaF4(t?eGw1%_be0Mho@%4FPmr1I+JojG6SS2u61LJ0 zYPBVwu6Mk&Ug-y4XAUA(P06y)VJpGANr05^reJiH3n`rX(=?XjJ1*(#@8R+>u^eh5 z-%&H*6L`lYQPX252pt5H-Sy7(DLN?r$SiL|SB@oJNw~S%^FIHTBS1*C2fbqSF;GuL za0y!0nOMa6sa%xWaZC)4mjnd2`ho_vp%=iaF4}xbnYA~%mk!msU%038(*3obdn&rQ zuhy$S?l$-0vGLm-i!YAFvG{T>Y7B^vn1m{+975XX>?V4{v&KN6M)h^0H++<A;NsEP z7B~989aDK~Q3j1-F8LchtZ8bpSClP#qj#p_#pR8S({mM|`P>l_4PHDVylkCm6r;JL zChc{c@Ap~#u4qHPOlNW9HjgL7{GZp54y&;vT;NnsEs9;e*yuKzKl-S?(wcdh1b=J= zZSlUq%P(p1rnr&jJ&#?0er5F`Z;*cUd3_|t63Z&~)m^dwATq9OB@4OjytN)>K#n)o z=W;N&L-woSC8!7ngcifjObjV$G?8lTW`LYEbm6*Q<%Gx_Lt(!vV+!<S3J$D$BsHk# zujXaZ!?XO=?rS9OR4Pty+)?0MJ>T+14mnA#-1z~?E094TrI1N%ak)n@Y`zycMzPvg zFV+iJkb_(-QF9S!_yu2U&*=j9{{3^``z#?pkg4SA-J8_sHI)4Ia+gV2`U%^Ss|%8T zGxhE_{kH?anLB}=`O|ssG%Dm+GF++C!lyecx4U<(lpBvdkM6Yh2|Gfdmgc#zTAcJn z^B_b2?`2~5PT4UWAB?nhnhZx9UAS5{x=%z)=g+#0W7a0xJ<&&Wc|n&cU5@Ia4K&{8 z_SuJ3-8EWp_V*9y`=@m=xr!YSVd_fs3=bQF7_BZ{*b_%{Y$rGQVQoHXw>#KO+I~Z9 zvVP1{hH{dlNQ$Bm%o}+oH#sF<*Yk%u^K8taTy4;{SCF4%z+6DIRjR)<m`1f0pQ#I@ zGu-&}&jE3kGjE1#i}Lq*O_^fRvhiC$9QHDfEA|;gr@w`OVDgJY#Gmos8Ojl&%iD5< z4l!|t3y$))B8ipcc2}@mQEor7`gN2$B}0=`js488mty`q>A7lM3Om_p(11U0@Th4r z8+|tK6BXdbuW3$A#v_yFTtE&GK<OlY$qTh!f?M8G*>X>1yjHN=@z_Mb0H%4boz>FU zbvdL3|1g)>GC(#99=fCugWmcjbwze69kC5r7qFzz-+4!lj`e%kU>zGTq$nmwHkk^s z*w%7JfXms-Sm#!;lF<mZsT<l3#ck}ONBTC;avy$zCUGy1(&DhW{9N}{M9Ye~^L$Tv zjge&#O$f(|m?D#L7vWg1J(ZxWm@-Qqh{maG=F`lK5s__#V~iTHf;VoBnRORkuvHk~ z7}niwBxD}DN<tz2xAj%YS%@}B3JSiQT{^LNs)kODgqKe4BF?m0I((^m5-uEuz$Kk< z?V+nuq0p(hi!%9j`2(D4&Y%bqG{^dvy?|r#^4JrHA5)24+PKSz%BTlk+AMugT8izT zi(a802qA2OTy;)&$d?%IA{Df6S{XU{u){?_iyPv^srrTcx4!hmi{<-Y-1cJmz7z{U z#u$<8zSyXGb!l!U+Vx`j@<YqxTlJYRBh`~Uc(MG1dr+Ra<Ugjkn9WSh@tviU)#}-u z?|(m1m)X-xm{JfX;R4Y~&b<HJd1Pf$I==sbM?Uc22S50Jf+uY)FKxxae5<YPRvBS$ zHJ)axF)mv@A5_^YR&eVKfpaZm@YX~qV#62L7;`%Da1UJGzU86ivB?AV$=&tcPfYUh z!R7I>=O*jV?XT~D;yM3$-*feSAFY4%iGA*~pBG4_iLKASWJfHcf(h_acBpA+i2?xF zSIrY~>y!1)%9bi|HOrmkj)p~fqsuF3U`HU7doSHt?IZe^3Hj%Huj!dcf7pU)qGg@? zGDP&i{2-7Q=RW<jx`3V=@o$Oi`#A9U+?SstBB-_7Ilq>czbFVh-B*Q;xzd>jM8d#` z0kKvWi`8}IZm}*^QZpGVvcb%RHyA52YzD%&h&h?wSndTf_tk!Oik;1V^Wp3ea7mFy z-j-Nos(^E{0_RNl#7MCIIu4V>TF|143LC?C|2R?+tv!2r>nW1w9-W)Ba{f%II02b0 zmy1ah;elD>g_%Wfa^Mb`V|-0c<~t&-FY*1<jcv8<?HzP%M_k`d`R<sV_Enbv_v5Ky zSv9pu`-8yFC#vC~a@>JaSom{Py~x7BElE6POtfzyg^uj;p-j`1`P9MjTOHjkVCd-X z%ergm@~6Tjf2PZyb7}PWt~I)C#Ex=#Ua00dE@UZ)=7<Vpa$EAlc9S?}DQXP*Whfun zQ@sRtVDSY+j<=({Gpf3>YM$fLinxSZz9EdUjhhb37b{Y@PcHWmxa);gjVkHONv8w3 z+oePi<~lTJQ`m;y)!_<SyfPm+6j@4lq=mYRDP5y;m%Gum<t==l=-2M(#fzKj-DvNI zjE?Prjx5xB9_u*w4B9!UP@@OU5a|0fA6e(2=w;1muR(8OR#hWWB+;~{!*djED7{8! z*`?zBLlti0d-*pBwvS0UCEt~$IGn&*H#M!a8r@5TBD?u;Q?%MHAd%5%UN{ibUb%y{ zo+ERjYXUK2yReCv`Av;Qn}K~GR;qP7=!HIFD|*eXw}ofHp<o8$<#r@Yrz5-3-nF;) z{be;~%V8V)B+a^0@g*(M^(Yy2|DS1!`Ryq7iyj^v=^Mz<GDi0Cb*pO6Q7_KHDj%p9 z9FtM)IqD@*?F~eu)G_l9V+*P4Q7?j#<++7ZFz1f6ICp-@9B)KpqIe26z=qK>REz*> zV(*i{V{hyO^4nTcZN?dMA44BBc22!xiPMvI5`B$owm0Lhi9~X*2gJIy1Xn#tC#gBq zArY@*w%z-P1pzLSN-J3xn7=|KhLh<4a0ls2%DTmB{jfT%4oggcxYKo|f+Sfv)>CZ= z9mGNUd?BL@EePC65lBZryq~~oBO@!kg!nlXjIO0GNjSr;rDID=NOwshkOT-Mpd2$5 z`JtNfP7!EA)Em@B3ip<3!H2s`P2%}Q>-donWp9;sv@Avuu~W<zj5w3tvCCIO)+NYE z`EEV#^AIL7U#51kY*Xu3?dJAF9Av0@YtR>8QL1U1$<pJyLS{o7q}omQ2b=^Un93Tq z$3!}oiNby5Hxmdn(N<uSH~L~#-gdfK)Q#yow8R`3<&;mCZkZ38{8q~NTm@>^rl)+= zHqqGVNQ#PeamvnB$VM|0&7O>lEL7&p$4euol9MVio}H0WWuZKOd^DxV5WZcQyExsZ zq05)iuccS#@zLewmd29`+IHgd<#aDbY{o~3?c36k%DIJhofuIcDzi2PkB^SD4&J@j zw(Zsla3s&jNPIpyg4QEK<z+h563Xp`7e>?Lu$M+(N{pYIzW3u?rG(YsyAyijI}^Wl zaPL$`(I7O@C0rnRpXmA5iTvvVaySnHiJ~jp6&n~F3ZLt!`D)LV4#aGD58%SLs}8ZT zI8raj<3I*Rm5*8Zd`o$1pDxPZ>5A_9@Lun}t%JKY^#a#^zCmKb-9SCZb+F#Wb#1+y z>rlOi>$-YA`s3>Q`3?LIKczQsDHp2iuWo!D?g63xt^6f|@NJ^*5t$Q>`1h)}O1W|N zo8_M4T^serrp3p~su4<mwKox^-R|D~bm!SSlDDh9Y6GE6uZif+zK&>pep4Cu<EytB zo|OA>v3h$_Zc_&?%Y#?CoFWGG0jiG=;Gs0Vsoq5^pYk;fsW<hmYj8RKTPZDm)qlIr zzD3Fqf9v}`c&)R%{#K3aJ-#G!WAo9Ul!f0~fAtRfy@}sju4!)9yHC^aMQO1ee(TQp z_o24PMfZA+OY1$XGVoks)x~oy=AP@Qme?g)r@P9xQ06Xcf27PROm8l;2Ge(&U~1FB z+TFG%4GeohKm3AVhl?EJ;AtjEz-Sse2-8Rd*zP4!gth*ADq~OVeBtGLDoFB8u~Hif zk6v7SG1BAjRmpsvg0=2({Rsj$_IyVVzovY7h#QnITb2nfQibehWI2ooP2|SjVlT>N zKzmC{Bd?ZmPG!<4(1(`};zjv=BGbNuno-Q8&`|U&j}V5L=H@qO%F~i5Vc7TZ^f?ic z>Q+8i8~d=x0}rGFyU<2)6G?daX6JaVN28O3uIO&Ijn}%yxa7z0yQfmSF$OOcpJ8hJ z9><!A(sM-UFY2y|D_e8)67rsldyL!a4J&Sv$VPwoEX9Y5<Y42{rie~!p4O)4Nu_!` z!PO|nV7f7wB_A4_Rzj&Z|Bc=Qc+>9Nzwh9lMq&3M!qV+GKF-#~R>H{nND7|lkGV8% z@l76?gXx}~JM7r}DDaliae5k^(B+eQDR@4m3_Lwow5URnE?US&Z=kKBsvc^{(RnVO zi-`9@(6zi@Ti`g2plj(;gf8-8An?|&yLaMlUFBmdhErs|bSsjX7X00vdavsdK1)-h z$Z)rN##GFy%Ufvd=q+ux*=$}t;HQ`0z?6QS56D;$LW?!U>k6^-yrNj}>{{;Zo#hTw z$UG#OjHE77=X!-qw<%=uR}1_VFV+)%%~UH=2KTNpZ!Xx^zIu0c4U(L%aq_xRs{9n+ z_D4S@yi-Q1S}y!}ez}19rEqoNS_h2nFy^Q|%f)*4)xmlXhN!4<&V4`3Eehu7m#dvu zhqzmZWT*RDm$kZHtx^`1F25U8o_?B_%y{wOo1HJd+1YCm4&UtTf3tI7JWr&<s-hk8 zdz{~>*8Sp%$9C)*ACAsyA?>uc;hT+5b_>3wa_4kO<QiK4=-)G$(WiB>-SS7eyQnX; zZ)~4nbu4}}YQtz7m)$5_!2ERPY@_=^1+yf5oYk>v!*`$6t{S7Vj?R+yk<-(4tw(P+ z$iC3OVh(Lw7b+9|5-~8dFRsIq@1^3KV#%LmfxY6y>)=yN`8ER@F};lmknD2Bnwfa% z9*n}^O_GnXBErB_6Yp-PQD@GdGk@w*U{^2vux4kFo1lY$cPDD%aApps<<T)cjTQnj zO1@%KNJ2itOKoGa-4MU7E^k!hlKm8AhC8v6=HXFFq%{v2UBmUcbsFiI`3ok(*n&3P zx)kVHLtO18$C;P*T?P+ZkdYZL>X&6B2J;IGR$m-CG{umhQiyrDR7Gg*h0$gE2}4C0 zQ3IsydxcO0mep+m`$y!YsvgD|F)1o)@e|`Kt2e*}(l=;F$N*Tu=)H?l(y+5pf@h6w zf34fz*ucCW%qsW44ny3Plp>qG`K6P}o|z#bxTGnpgtQJ=E}0h*Y939c_gu5(nklVh z=`_h6sT^FY?pqwANW%0wHZll&_Osq&!9uFZce;EUTfT)#`SkqpEtMS)lpcI&%aeC) z-txeX2V?uVR_19`FUexly{9|(s_uAOf2hF6MM><eW`)c2qrc*OjQbHz&uTLSo)U)= z;y`pn_f@;gM9hNkkv^e-aT03!=t&DH(u3)fGzUExD(UI-W)Q_Em4vSmM*_!F7Ut_S zeS`EL1<I<fers*OsOAD8c8y{^e)Fa=sl{kDkkMHn?>icO*#ZYM852jQB=Q&pn5T>2 zg`@eDO}$a%)LQjs$>LQ1W(n}Hkd@{yMH3}K8M_?<`+F*6HUlr}?j<g*fcOhk^7Dd) zC2nMBBGM){C&?O>^vfY8?7To5C#EAk)DWnaAK^oaYAHl_Di@Q{C(ORlCo&{~+L!qU z>jH%W1!D;5R<uvzS26n#-Qi3(%Dy&5`Y6Zmo!e_d^}LyU$iU;Z)>e4WJHnXgJ&xwp z6WIjaML(U_kWH0M@4wYE8Crnk+R*~Ctgyw=@>ZPN3YJA}D1d*esog|%np$T%QRo~t zs?ix!;BJyk>2>gZnQCqd-@hCS;LV!hh=m|PeBdk^oI%85zv6z*7c%A%`Ge6hhFI&n z%Zv`BDz5do`yjKot=fe5ZQeAitK$8yYfjeNoFp>)!Oo4j{#<Q+YBplb-<1H8AjW^Y zB!GJVlj?_&0Ba!uHubHWRiEOYg1@Oe#!ZF<2xM`&=f}J8#u+jZguHNiiI=tx@0_)m zA0$Hi_0e{!nE3%twBbLqPeYDqh+073LgShSGCWF9IvyzpF%giATS-QOSvBCq<vMp+ zqA?pt4Bk(mJUzqCG;bCPx(4)yvxJw#lZ>^MB@)4=s)W#TSt^~`wUh@+%c0~LGmBL! za|(hcePfCc5LuC`Pp89^GDuH-+%`|1d`MVPqGZ8EvbdIBtiBk%xJU-qlFM!D+^%E7 zfg+F%CY8m6j=yQ|nc(YC@y<rdTkFzs%27nUQn)u6wIH#y$#8T{t^2W~hbMROXKLc9 zUA6pU`}gWPc|_N}dv}pSRyK^$WnIQ3V_4Q*oy(i~Qtv=tvNJO%PJqx*oZ>w<3-}P# zAlA5=$DY_JdDu^{6%lk4oUlrMefkd8tLrs{O!Hod#d}1p<ytHwxRbpu_t?8}RT{7! z5Mb4WcWXe4{XCVOu%3RZo_C*A($F2jCI5SRmJ!LQzb2BogBwIL!_FQShO^Zo76aHm zTgPX$A7cT_RbKQ5KSk+F!17l*X-t|dV(+qd0`_PlS!wB3g*Od|(ybxoN5hd3nNY?^ zmrm%EHF|CTAwaLByVVSu)u}g=PEDmyu>&y!4j-#ZhmSv@g|{%`CcpSDZ3dG^7}{0b z$0qd5-Vy3(<Sta&BjI?ef(+s>)gf6UJ2YG(vb@=O26T)^>R@*E65K0rwG!^_xeo3X z&h5h3vKu$l?tpo_FOG;y2dBoESJH<<3is}Q8@Siz^Da8=aIc|VL%<2{bs12b`Eavp zloez1nu_)7?Pm&ING;GUEVukS6;jJ1+qG``0-i;5_?oH`?Pm*r9R%}96&A_lOx#wn zZqv^BH(JmkZi+p5&+d!i9~{mg8XY|SRCMrSL}MsLwvI&wUMJYPtQNZ(gVTq75C!8U z!%1Q230*zLhb&#K^_5h}IcO7mTJ&#^H)JHrHxU6fu-C)rEOfmw*~uQiZoKc?HTlA) z+P{*M)o#spHynD-hE@J!lyy<nZBAF2PIc`z)z4od=v!CY&*B3Vh-b0fnGIVnY1V5B zYTD~<1QR6P7l|UN9ZNCl()g8MkvF0#{}O*a62YH8WBEankXFGR(lE}<vGe5Y#5C>f z63Hp?qr!`5@q|M<GRm|c{ng^@*T7rTq8T$}i-ffZ#;BCHPPz^FA>IPS8I0+sM~h4C ziTk@XYbIA@RcafaUYc5(wEl<H2)1S_rQb<)=wn<kg+<CpwqBk5uINRVO?6oWV=lVS zGCZ3MayfT#J0-h-70){=U8dj|d}rT(K2Ysj1UcBzF)iNha)sF0e@(Ddc_<n^B$$#5 zSsW%Yk;uuax%vG6Bc6?Euuh~TV|TzO!Suwpq=t=&<6&r{xde6!T?g2?J2h^}Rc-8f z(!&_{BA(IlE_x163Fm<{Q+!Rg%!FkC<V}3Ab9v8{VyZ~=g3JZeGMA;uZ6DT7OKAS_ z?b(b*4>ExYr5lCCxeM}u|Aby>!)5Hyu=(ZW$tYWKlNt1Ide9ni9B6$N;#re;UD&3R zQc{yT>=tc3U(7nPYfJ0r=40Clc+dPAy|9CLKp}WAazKFPoD{1eij3$+++Ri99h)N{ zj7g&KAydp53{WJrj0Ig9yEh}STJ4h6(c2?zS}aRn>G2ZD#q>!(IJ?pct*PEnPESRH zwtnN@IEL4>7T&(c3MIVwlvSu#jYfrj!g!@^Nu|mQuNhd;HX7ScH;zg+OT_Q{@ui)Z z809afxz$6*_1$<@hpucp<B8FZM&!gqRVO#H77ojYQwfsvwSI^ZL%oP|k^!co-6r2= zreO3Xz3Teh9yN&*&O$jS@-ZmKf!VkxJ|rf6woru{l81iU91i-4;98N%6f!xa{TaaC z`Y>q$>LtftrNZ&Q&wA*<o&uRh8|%3f=F8G7Snz!|+JQJD;V|E15b&ews4<(ITH>~D zNV=MkDQ_?Agr;q0+)QzpP<HuQ9)+JSe|Phz^%mZ&eZ+RnjU82V2wKz|IHZ{kr1?=V zD_gi^H;}N9EFbU(fL^+0d3P<9iKA~2Wf<coey27ZwwLe6f;N|@el!-hxs1%eS063A z(x-KI-3|9*Ji(%VhKawcb=<Sq&c!OT;f_%|QRXac4EXaAhd*uW-3`9P?WBzEo5=J{ z(zC^}@K!E5=t{1#QHgD9^B_u>-D;Tjt}w70&f+nnQ91<M502?ad!?%a*SpcaQ+rmc z@mxHmhGX8T=&9O5wF5V?XEW%<G$+jnC9_wxPi?Qh1z;z;yBOH1pEn5X&T66pup5T^ zh1xV6aXoM+Hbqn!)E)bYv&23ucV5fsbMuai0imciz^}HEkqd8O8&%a|$0`)D)5Zw- zmUO4zsZFFQTu@VjAC6F&<u3eane=n>fbV|Zsy%%Zo5%y4cX0c(0JHSwQU7jm^L%G! z^Q?F4a07trWts>eh%{-<+hy^w@U0SXu*q)iZ~!Vi&qv=DZ>r|Eo3QI!g;!TJxENj; ztO8yU<Y_}P%y(+DY059Jvf1o>QpUU&(j4ks{&=VH`w|37gd8WQO1RTvB+=ZAT>YB& zoOaZW)5em4n()-Bfv6Sb2}d+LCrvOyWCdgha$C`xY1K2Bd-AeW)+VKQu~AZXxkgvI zNFd_`lEGLTGaNa3sgIMFi_1{zCud$cg-n*3BIi~mz6jz~`e!e`O~U0kGB?DpQ1BZU z?#90G**S<w62ir_@&h(bwO?_z+sEc4akn*RBIGO6`VM0jVXzvzKEiTj=@41pn7$Fg zu1Q*O6$Mh(Za>Hj`$hs$>tc<>+10eR?y&wk3ycUeo?%CII3_=O1OC4~i~rxmyUqz- zYU{PiHw6Blq-78O9~I%@0`?orTd0gVQp7&>M2|L~(D>w%cF&2<JZYhRrlP*xFlq5w zjiQeZbwCCy#U@x`Lo$-gF>TMmKF7Om9>2sqt`?zPGyX<AYe?rhhqBbg+dHcgLCrjW z^JmrLh#3nS(Q-;NNpAj2I;G$W7urZMW|A|?;}uV+8|jUn%`h+5JC$Qh{B=&HB%g8o z^}V%Cslyps(eaC|o3xb4(X=xdNi~0iC-d)Xk2yNWi$sUCqnVmEgqe8Iz=s~Tp$Mc% z2xa=)XCTn>un5nDbJ=;iP|2R#PP8@8wD_xe4mNvI^NtB<I<DS!AQ81$KEHPIHl4Ab z*ZBCgGdskYwa^ml;xWFXXI4vbEpuiI8DcJ++1DtT#;@gD4ZFqx+2v^^8L+&>J4k6I zAFB?Z(8`5UEL!=2@*vW8=S9A@JR~pj@+SLcU3ootdd&%WXl*DDqwMXs=eLwMQi@QG z`HtrYf&RBeLK8KYT{|R4jdP(22ObtD5$#zZqT3?zg(c*{5963OtAbZ1K4Wz&mRhsI zkO6Tak0$%4kIuL^$Zti?YP0EY<>$C0X8}vm&Xl+Ch|}_*OOyXF;WeVisy*aeA)wI- zVXxlBllDy?-&_o3*SP2lF7(lr&S;_9U+uwzSaurn^>g^IcX10w3gMFv&@+H%@#mbK zd)>F;1N104(4dif`GbLx0*9C=x}u?ok&0D+beHCuRe!<AGgkT?(HXtSd+uU7HYxpn zQya)tUc29BACZ73Kf;l0qm$fAR814WYegMEur_~JAOD3e<~nOagNwASATMVLx1sag z=t6lPT~m+#ca{8p?&83-pQ0}=W3A5@Y<&(Y!LO*hck)sP*wC2|yT6X@cIFd^^*60F zl#H@L<DTT#u&mI!w5aS;)C;&o@U7P;M883y=GprvJo{QadqmoQPivDW2yIuLJ3~ff zwWJ^Y)o!#_C5BR~3L|4mZaz%|k6jPCtOqV|tfE=Oec7OSYg$P~m;Id>6m&q*qifpO z+@G1VX94M%9TmDFw*w>7i0dIOJKeH)UUaDQ;zsxBrG9C^om<Yi5(*1-G+%pl&&4YB z%4h+Py;tT;qiAZ1<zRIH*?dfyR(#H52}zAg#o3#K+xFF^MZ<;?pz_0pi32*Afo8l# zE8F&F1|*nwlwS+wae^-TPIp}E_`%#cbcQx_tnN1`6rYWsX)~kW;``r=SGUknd$4&n zo5q?tBC;x#^Vlx-w4p}Z(><x})UH8&|8+HJ6d%UVjybEn?>Y^Kt);cp>C)dyjf+HR zf(?;UG@zgY6TV`RmE~LoIMSB8c$janv%tE6I7K`)caz&JWy?8~Qj6PL-nes>H(vI; z0)dFUK_D6oC~W0EGBs8LGA!@7ov|)wQfB*FGt)}btL(ql+(^;lR60uVwGl~4zeI~I zTiqD~g`GjA2_D$bhnq4QBhVc~CXxgpnegyRqUrEST4?!i-&1k^+de?|2yHkoX>q77 z7)_!={-nOOp|9r2{eNh{j#E#p!Zx8pZr%{yEG$jp4Ho`XAPq5y#4whWU855e! zao+f>GJW#g0{zJ6OFk7{Wohto;4YvNafEVsLgeOqD!LZU>rQvQ_PGl)I`f~f_qr5h z8*Lz_Jr;b9$QpR4t)cXqL-IPq?v&5O#F+25&;9mRKHHl0g7yeGbw}Kye@2igo~ef& z<-7$6&)L28;AYx&IcOD>Tv*pY8sU9}WfLCG_HxQ1CWHF^r54yuxQS$JzuQvR^u@9+ zpU}ku5(Se~XRB&5bie%#Cg=>bZhtlLpR^k!oP?z%m_vWJ(4OGD><aGS7oj2E0@9cu z&mnV~doq}--QK)kVEpH1&WLpggp#&P*fK&($(9jqje|;8y(>mb$r=7pb=UK=zr|b8 zk7%Ty;I4HLDtp@igHSsiK)2eREghSy9&wJ@2Z?nO09)L-N#3jM<bp&t>^1E&wCxIj zC{LV0brgJR)ZMw;1&*#l>^tll55QJy12838$0Z)XdhQ!t)iY<KcHmjX->dFB=0(7{ z9hqTabCB?a!^mrP5bZGD&4*-WaX~_~tngjh$g*`KMIGcP-Rx>5{N6FFc8^A(Zh_Ut znwLO1?AoF-uW%gUJ;R+D@~Hia3&n0$V-hw?62qDgw`*{`lgx7>C_kgx6C0SX=;If3 z5v}DYA)(30aK{(*%ub)SR%Gj`CRY=4sQX{mNzxvd{CjYikSN{7-v0jnzW$NHeE$k8 z)D-2@EY#DUPAYfJ<*#(XJgqf`C(a5?;%W=I)#I6|qQ#^q<$GC7R7WcO*1AX=YG#08 z8NG8v0eqpqjpA|PtR^ovP1>>r(LUxA!AK@4d7di_Gd&kML0v+~S1eKvF9c5uNjA+e z&<HhG{s7T*D1-Sb5W)r0aZ$jXv~u+RQKDpHu|Go+-Q*3U<5qiZYw9&K*quFzF#_}) zA(f4cvq%+WpPM~xCP6k0Sz`oIfbHTP2MSR!xu(TnlpZe~TAVu+9axIyT#QZ=mJ(Sd zu^jN_CXmv+;A<r#ad~8XOQ>dSM7KN%-_M-j<4cKW$!6jtVGcYuQ#pmX!UcjsLj>cw zl2{D*W<m{W0lS2jHh31wSSvQFS$0ME5%AE@4Oqn01{v43X>)@;T3tFD0Fmm@uab0F z+Ef7|e2F0jl^e63`xNA$u>jBkSGz?ic$LGOom*qUtoCa3A9dX9SQ^YX!qy|PpVs#U zzHf#9df|f!G#Ca!)o#u9HSn7^Zw{wEJsJZx%;EHTDxf!wJD|5Cd`N(>LvNA<1W=q8 zC^pG8<nUDm;KcCwHVlk~MZzcf*%XPUh-|>-sXGg@InN!&s}FM%vmx_MCc2$2(3AJa zZijZnqCXjr3uEE;*^Esq@@qOmVu+q=M9UOGFbzrDa@k7#fWW5VJtIL(q5oZ4M`KXF zUn}O9&<cG@585)|yVMyclwMD;ONpgx{pn848h)qSz5HVD=~&$y6$(X{VX$Sa3_%HT zNf?JbuCutk5UI5L;@7Q2-jR_Y^WR)9Ah|14G1U|oQ|`vCc02K;zIJINuD8CHYh6|Y z`I*oCejYa࿄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%0DDhGmPRn}=<v>FM~$ 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 TOjma<%WtMDn`3r&G7A46rkxM} literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/_vendor/__pycache__/six.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/_vendor/__pycache__/six.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6b82c2a2d5a00a442808bdb382598b7269e9b8cc GIT binary patch literal 24407 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__about__.py b/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__about__.py new file mode 100644 index 0000000..95d330e --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__about__.py @@ -0,0 +1,21 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +__all__ = [ + "__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" + +__author__ = "Donald Stufft and individual contributors" +__email__ = "donald@stufft.io" + +__license__ = "BSD or Apache License, Version 2.0" +__copyright__ = "Copyright 2014-2016 %s" % __author__ diff --git a/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__init__.py b/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__init__.py new file mode 100644 index 0000000..5ee6220 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__init__.py @@ -0,0 +1,14 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +from .__about__ import ( + __author__, __copyright__, __email__, __license__, __summary__, __title__, + __uri__, __version__ +) + +__all__ = [ + "__title__", "__summary__", "__uri__", "__version__", "__author__", + "__email__", "__license__", "__copyright__", +] diff --git a/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/__about__.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/__about__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4d8d6091ea309d187d0f8c3495a5296ff7944e8e GIT binary patch literal 742 zcmYk4OK;RL5P*}-w)^U~1*%@Sm`WU0qU+rj3PlK&wnv026>*4=tR&+krimT-v9LLE z=8y1iIPaAce}NO@uBtMYKh0R<@jQG!9uEVQACJ?|zdAwi+Z%V%N97E+xk5kyVHMP2 z9M+w<Q%7+W2GD^By08J8(1Sh<ihkUMVY~sOcoVkb9*pBYY{vuGiHEQokKh3x><94{ zJiHDjkN#lPU=po%lGLcmS<Xb=C~a4L5DQ_1lB?}T3u#&IWM;iRV9W|zamH37#*C}$ zL@&|kG3K;bpDwuechML!mN;7~jXK`sbt0;@PbD%gjSn+sEK|)=i=wpNtx2+*q!6-b z4=$AE#92`ZE4U%K(&TE1;Url*ann92t!>O}N(*62mrgTP(`MNu^gc{?elmU4PA-*9 zDj?U^<+&w^1R|s_6I@b}Oi8On>a5bH-Gy7%Gjr=Y6{<ZrzrG~+`a6tTa`Jwi{4?@t zT`4)5&f5KpyDG@hZ2tTZaYCM&50kNPL+-58Sgytq2RicTB7EPH3VWhA{L!XI&%;k% z4?O(u&?Ap6#LqzQdfnsicZ$<lB$m@fqG_%wz<g+3(rn(a)Asbs?CWt3tvNYf=%a78 zt!F5Oq#tP`nnNLt#kUV%yiCg*mlo7;>l&+6W&T&$f=f{PzM<PL;!9O`GMa|E5;p XD*o1&WA+ex(J&lF-4Is?muL77$tU1* literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b7e3bf833098bae3ec7cd3e188d80499a686dd22 GIT binary patch literal 580 zcmYjN%Wl*_5FFdPey)R%xbXw*Axt0w6bVI$58y&hBc#^Y<Mj^lc&vFi?B2NNNBAXQ zIpr5P(UTP@ElsK0>aHr+=ejNl*8R)oTND%WI}HCS$L140dxIc|hz6n}7O9xUDq%@P zL@bhFrPge%QkJTWWh!U6Dp;XPR;r3sYQr|Tw-RfSicI995T&U4oYi9Um2B$=WG35W zdBz*72k$zNYSP9nxsbE8Qjg2oWaQ{z=f~FJ{1AnUd?^9AcYAFBmKvbd)4|Ao?{F*t zI>qIHZ3QsMwi|7C8mw1}o5N|zNjHS=8GtwPv@mxjr~;S@bxa7yYy#8)(f}bAQv}Em zzHHBemz{UsAeq4siAe&i5P}!pXpgo|$Km7&!z2Hr(tnX)hYx7}7ctMnc7Q)WDaJ5! z*U_09y3>O|qg3r_`(}cx<JI?zyUU$8+V_{UdHcg1)df~R(i=L->0FN1A?NwK56%A8 zH$AnT^OMthuuof<yHRLEC*I!jUXDElkfTKNucyP3e^grdp}P)0W<wM&;#X-I{RIUR BpG*J% literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/_compat.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/_compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..734cebd41263f49105112407464b9030e4185ca1 GIT binary patch literal 1032 zcmah{&1w`u5bmGZ-O0My91H=ChxH=tAv-ZaB@lwB;4KJ>;1FnLr+YV(%%9yo8+VBy zB#<0@2tE2ref5-A@MP6&vPL{uP&HN6(_dA6)i0Kp+XUq6`taa@6Y>*-8)4u)2Q}}( zNFr%UG8)p1g)HMCr<h}@7kbJ&YDjXANPf)1<|6VSYN?ifrTh^Mm-41+<5xCh^PGft zBzsHxtt-GLeePDGp()bJDv@Mmp{?^}GD%EQ<gQ!lB)4Kz<*|i${|Xzsf^JDn@iqts zP0$voc?9M)xgZyG#3YsM+?VW<p7GDjl5g~sNiMyFeD|PyV-~b~ATPCwtm;L*VPsS< zP9tM_Cy70TOr~s9CkFMOF@P@w%c7Y3U=#_dBq6(9IOLK;8E^Iw(ZnCD-L#0K)a(rw zso1Nb2*EGvT~N~jb4gF>B{}712u1gQ0G{J<YMhrxnR0D=m>7YL8%JfIxyIc05LzQ6 zzrF-O;RGfOCXo(CMJkmxL3S9#k4v#L+d0}i*&fN6dAdE(Tc7MK+XNZs!MmVL%8ev9 zHcHctC(nk5$JKBg7-g%{7DZ}qyJDhpS?HjQ;^SzX<l{iZMOH?3P)=P-h+Lfr@c@Uy z{Si9r|Cf`&^{suF*asiR6~eWJ$O>7d=y!zpSViglM6UpDJ#n9DWKJ*NBy<-%x3pk; z9m2W~pK2u9tyqQcF49v`Z~Gd?d3IW=8o1Bra5XUA`L|MCr2F?+t5~VtZEKC|HHi8h z9AQ-1O2Y^m+0gisH2&qdnHtxbz=GhdizFWvj=%Y^g=QNLt#%zSK(D~gjBD51t}``y d-PJ8q_vG)+8Qa4W22-od=Uv+MJnFM1{|%I)2^#<a literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/_structures.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/_structures.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f07ca1690a9de827e64ec90f1aef866b82aff340 GIT binary patch literal 2884 zcmcImOOM+&5GEyCmc8CxZ?es!K??L#2<S#>g0u}%1ltE1^x{kQWE3D|k+!vwC55Ei z#>mZk=plb3e@WM#`WJfY482P2g%r7u&>)A>ko;zbGoSq3{(g@@dvj;}^KWfJe#eKh zwP11zUHt$9C!EG)PDgZZjjXvnvMG5+xW(-Y!fnx7*`u~-ugItkZ(F<#Z`<arBOG|^ zaOXMkI)A`P#IuXTV64(O*Mdd!ES0)&d9;XBlqSVNCZj~NNuGono<rPGHVY=F(A60X zf{Z99Ba2gRU67H@ZQcS2*xUix<{j>Wba<EdKz8^Z?}K#tK0g52<%fI#vd543HIRG! zI#_sIxIZP6D2eo|kOBxcl-R$At}rN^!b)o>Az<V!@o3RfBA!SG9?kIQg%3_F0xkSS zApJ=ib0L*KpZVbz8GF2Ze189zhZDY3Up`#O2fym&{64g4;-C3hl$}J0(m@=bJo;)p zdy$W)z7jgmbehI$bIKMX;i>eqAbb%_qh#tcrDY!KTncqBdsVoMNs&p$x@b7Yj?m>% z>E69kyXB`1i;SOrm}sKuYqFv%^p_4jt7y#vH7i<ptVd-B*8J_Ybm0*}aSda5Ko#g( z8ya(93CgPA{%8*NECW)sQ#}*%Dwe}otQkApKswxT4|V?xNAAN>RVae7Yjr4~+d{b# z!q*VObGow15cVL=@q&|36kXUF2TCz^>1dq+;w57r)fj-fY6A{nhbE-~eR64n9H5s+ zFf^bh;M%PkRMc&uR$b!R<|WqoHic`tQ-gxK{|N=`{iF^BeL?%Nq1^ICU&f6VgQ1uP zI$DS_$!cn#!&oAwjC~46l_fAJ_dwkl<<RS6u_VD9(2E{p^OWZ?&ijnL%!7EXkyyME zi%H^jN=$Z%xhSvWaEt?HhP;WxI|^FQup$jhVWleE<yx-2{WJOyRPP#=<SFzI$g=VV zoL?XEOM+c?Ps*sR6RDDNOoTkN*Ki75-oAQG|Ay)$ei!8)4AqxxuH^Fu)E&95u}sX> z`x{_4D_q=(?wX-6!5%b0VZoSa!$Oqr=e(T=$0YTm2H+3Fb*7ZQZh+p2@V35MRfJ~> z_DKWOPOR4qg|zUr32Ha$GbB+{2uM8NZou5C$jy@RBz{ihZ5%$v;Xjib^2le<>&OlD zL$8DUI?3^$5&Y}Hgq4`F693E<PC7mpp*AiWUaDfz!u@8=&rflWLSj9(2X`Ile*s<4 B2H*ey literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/markers.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/markers.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c4688a417bc41489227bbddac0f360628f6c7a60 GIT binary patch literal 8889 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 PK-S0)<d5X@`HBAnr0&?c literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/requirements.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/requirements.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d0e59bb9752dcf2024538522ee4457ff2ccfacd2 GIT binary patch literal 3891 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 NO#mNO=|fsh|1Umg?sEVD literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eaa2c9602a6a5cd03032f4f61b529680ceae24e1 GIT binary patch literal 19810 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/utils.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/utils.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6f99b8a26d48db7c15f36c7429b03b2c55e78532 GIT binary patch literal 511 zcmY*WyG|T26tz9G%W4xy5b5}WRkWCZ2ttaY2zr{N8i*{<*gF{flI<DD2&JOrBX$dl z{F2*L`2{L$BqVaAdwid|4<E0uPeH={c76T;0r;DZ7ZgePmc;KRVt_#j6s({^6;ef2 z!0bb^tV&)kN32-EYRpPDx&zf3L*Kz{{4dpkSrOmS+8fygPK2_?g*aiN7hV`0H>?vn zkVU7PknGc8d^RULKR-5Um}lg-OmdRMzfTmv5;AxTR%nS<AhkiKk8qy4Y>|d)qeVld z7&vjf<u|eLT^&c#Tyr;rvD8%YKfvXkAAjT2yQhKUo;tiRl5yv;y1>mROOA%4%iZh! z1snY5{od`}ghA~lv>N}wR@k}FK2Ry=2Z!~=Radvz^U&E~jP$Qn(sRv>!<IHzv=zF= zT@cdm*k5t;zj5<qZ}W~Q5kM~Mvq_wibeqsQPKe79mp{ejgGA(bTx*Q7LUK3G?p*V{ Z+bepLQzu`PVV&e(bD__<AJC+j7EiUEiS7UZ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/version.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/version.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9d63dad45be4a81a0e2a852c09f24f7c594d8b7e GIT binary patch literal 10577 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 Y_$jCobKJD|+c!*OeA)iAVA!Mo52$L2djJ3c literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/_compat.py b/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/_compat.py new file mode 100644 index 0000000..210bb80 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/_compat.py @@ -0,0 +1,30 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import sys + + +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 + +# flake8: noqa + +if PY3: + string_types = str, +else: + string_types = basestring, + + +def with_metaclass(meta, *bases): + """ + 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): + def __new__(cls, name, this_bases, d): + return meta(name, bases, d) + return type.__new__(metaclass, 'temporary_class', (), {}) diff --git a/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/_structures.py b/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/_structures.py new file mode 100644 index 0000000..ccc2786 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/_structures.py @@ -0,0 +1,68 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + + +class Infinity(object): + + def __repr__(self): + return "Infinity" + + def __hash__(self): + return hash(repr(self)) + + def __lt__(self, other): + return False + + def __le__(self, other): + return False + + def __eq__(self, other): + return isinstance(other, self.__class__) + + def __ne__(self, other): + return not isinstance(other, self.__class__) + + def __gt__(self, other): + return True + + def __ge__(self, other): + return True + + def __neg__(self): + return NegativeInfinity + +Infinity = Infinity() + + +class NegativeInfinity(object): + + def __repr__(self): + return "-Infinity" + + def __hash__(self): + return hash(repr(self)) + + def __lt__(self, other): + return True + + def __le__(self, other): + return True + + def __eq__(self, other): + return isinstance(other, self.__class__) + + def __ne__(self, other): + return not isinstance(other, self.__class__) + + def __gt__(self, other): + return False + + def __ge__(self, other): + return False + + def __neg__(self): + return Infinity + +NegativeInfinity = NegativeInfinity() diff --git a/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/markers.py b/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/markers.py new file mode 100644 index 0000000..031332a --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/markers.py @@ -0,0 +1,301 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import operator +import os +import platform +import sys + +from setuptools.extern.pyparsing import ParseException, ParseResults, stringStart, stringEnd +from setuptools.extern.pyparsing import ZeroOrMore, Group, Forward, QuotedString +from setuptools.extern.pyparsing import Literal as L # noqa + +from ._compat import string_types +from .specifiers import Specifier, InvalidSpecifier + + +__all__ = [ + "InvalidMarker", "UndefinedComparison", "UndefinedEnvironmentName", + "Marker", "default_environment", +] + + +class InvalidMarker(ValueError): + """ + An invalid marker was found, users should refer to PEP 508. + """ + + +class UndefinedComparison(ValueError): + """ + An invalid operation was attempted on a value that doesn't support it. + """ + + +class UndefinedEnvironmentName(ValueError): + """ + A name was attempted to be used that does not exist inside of the + environment. + """ + + +class Node(object): + + def __init__(self, value): + self.value = value + + def __str__(self): + return str(self.value) + + def __repr__(self): + return "<{0}({1!r})>".format(self.__class__.__name__, str(self)) + + def serialize(self): + raise NotImplementedError + + +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") +) +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' +} +VARIABLE.setParseAction(lambda s, l, t: Variable(ALIASES.get(t[0], t[0]))) + +VERSION_CMP = ( + L("===") | + L("==") | + L(">=") | + L("<=") | + L("!=") | + L("~=") | + L(">") | + L("<") +) + +MARKER_OP = VERSION_CMP | L("not in") | L("in") +MARKER_OP.setParseAction(lambda s, l, t: Op(t[0])) + +MARKER_VALUE = QuotedString("'") | QuotedString('"') +MARKER_VALUE.setParseAction(lambda s, l, t: Value(t[0])) + +BOOLOP = L("and") | L("or") + +MARKER_VAR = VARIABLE | MARKER_VALUE + +MARKER_ITEM = Group(MARKER_VAR + MARKER_OP + MARKER_VAR) +MARKER_ITEM.setParseAction(lambda s, l, t: tuple(t[0])) + +LPAREN = L("(").suppress() +RPAREN = L(")").suppress() + +MARKER_EXPR = Forward() +MARKER_ATOM = MARKER_ITEM | Group(LPAREN + MARKER_EXPR + RPAREN) +MARKER_EXPR << MARKER_ATOM + ZeroOrMore(BOOLOP + MARKER_EXPR) + +MARKER = stringStart + MARKER_EXPR + stringEnd + + +def _coerce_parse_result(results): + if isinstance(results, ParseResults): + return [_coerce_parse_result(i) for i in results] + else: + return results + + +def _format_marker(marker, first=True): + assert isinstance(marker, (list, tuple, string_types)) + + # Sometimes we have a structure like [[...]] which is a single item list + # 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))): + return _format_marker(marker[0]) + + if isinstance(marker, list): + inner = (_format_marker(m, first=False) for m in marker) + if first: + return " ".join(inner) + else: + return "(" + " ".join(inner) + ")" + elif isinstance(marker, tuple): + return " ".join([m.serialize() for m in marker]) + else: + return marker + + +_operators = { + "in": lambda lhs, rhs: lhs in rhs, + "not in": lambda lhs, rhs: lhs not in rhs, + "<": operator.lt, + "<=": operator.le, + "==": operator.eq, + "!=": operator.ne, + ">=": operator.ge, + ">": operator.gt, +} + + +def _eval_op(lhs, op, rhs): + try: + spec = Specifier("".join([op.serialize(), rhs])) + except InvalidSpecifier: + pass + else: + return spec.contains(lhs) + + oper = _operators.get(op.serialize()) + if oper is None: + raise UndefinedComparison( + "Undefined {0!r} on {1!r} and {2!r}.".format(op, lhs, rhs) + ) + + return oper(lhs, rhs) + + +_undefined = object() + + +def _get_env(environment, name): + value = environment.get(name, _undefined) + + if value is _undefined: + raise UndefinedEnvironmentName( + "{0!r} does not exist in evaluation environment.".format(name) + ) + + return value + + +def _evaluate_markers(markers, environment): + groups = [[]] + + for marker in markers: + assert isinstance(marker, (list, tuple, string_types)) + + if isinstance(marker, list): + groups[-1].append(_evaluate_markers(marker, environment)) + elif isinstance(marker, tuple): + lhs, op, rhs = marker + + if isinstance(lhs, Variable): + lhs_value = _get_env(environment, lhs.value) + rhs_value = rhs.value + else: + lhs_value = lhs.value + rhs_value = _get_env(environment, rhs.value) + + groups[-1].append(_eval_op(lhs_value, op, rhs_value)) + else: + assert marker in ["and", "or"] + if marker == "or": + groups.append([]) + + return any(all(item) for item in groups) + + +def format_full_version(info): + version = '{0.major}.{0.minor}.{0.micro}'.format(info) + kind = info.releaselevel + if kind != 'final': + version += kind[0] + str(info.serial) + return version + + +def default_environment(): + if hasattr(sys, 'implementation'): + iver = format_full_version(sys.implementation.version) + implementation_name = sys.implementation.name + else: + iver = '0' + implementation_name = '' + + return { + "implementation_name": implementation_name, + "implementation_version": iver, + "os_name": os.name, + "platform_machine": platform.machine(), + "platform_release": platform.release(), + "platform_system": platform.system(), + "platform_version": platform.version(), + "python_full_version": platform.python_version(), + "platform_python_implementation": platform.python_implementation(), + "python_version": platform.python_version()[:3], + "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]) + raise InvalidMarker(err_str) + + def __str__(self): + return _format_marker(self._markers) + + def __repr__(self): + return "<Marker({0!r})>".format(str(self)) + + def evaluate(self, environment=None): + """Evaluate a marker. + + Return the boolean from evaluating the given marker against the + environment. environment is an optional argument to override all or + part of the determined environment. + + The environment is determined from the current Python process. + """ + current_environment = default_environment() + if environment is not None: + current_environment.update(environment) + + return _evaluate_markers(self._markers, current_environment) diff --git a/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/requirements.py b/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/requirements.py new file mode 100644 index 0000000..5b49341 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/requirements.py @@ -0,0 +1,127 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import string +import re + +from setuptools.extern.pyparsing import stringStart, stringEnd, originalTextFor, ParseException +from setuptools.extern.pyparsing import ZeroOrMore, Word, Optional, Regex, Combine +from setuptools.extern.pyparsing import Literal as L # noqa +from setuptools.extern.six.moves.urllib import parse as urlparse + +from .markers import MARKER_EXPR, Marker +from .specifiers import LegacySpecifier, Specifier, SpecifierSet + + +class InvalidRequirement(ValueError): + """ + An invalid requirement was found, users should refer to PEP 508. + """ + + +ALPHANUM = Word(string.ascii_letters + string.digits) + +LBRACKET = L("[").suppress() +RBRACKET = L("]").suppress() +LPAREN = L("(").suppress() +RPAREN = L(")").suppress() +COMMA = L(",").suppress() +SEMICOLON = L(";").suppress() +AT = L("@").suppress() + +PUNCTUATION = Word("-_.") +IDENTIFIER_END = ALPHANUM | (ZeroOrMore(PUNCTUATION) + ALPHANUM) +IDENTIFIER = Combine(ALPHANUM + ZeroOrMore(IDENTIFIER_END)) + +NAME = IDENTIFIER("name") +EXTRA = IDENTIFIER + +URI = Regex(r'[^ ]+')("url") +URL = (AT + URI) + +EXTRAS_LIST = EXTRA + ZeroOrMore(COMMA + EXTRA) +EXTRAS = (LBRACKET + Optional(EXTRAS_LIST) + RBRACKET)("extras") + +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_SPEC = Optional(((LPAREN + VERSION_MANY + RPAREN) | VERSION_MANY)) +_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]) +) +MARKER_SEPERATOR = SEMICOLON +MARKER = MARKER_SEPERATOR + 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) + +REQUIREMENT = stringStart + NAMED_REQUIREMENT + stringEnd + + +class Requirement(object): + """Parse a requirement. + + Parse a given requirement string into its parts, such as name, specifier, + URL, and extras. Raises InvalidRequirement on a badly-formed requirement + string. + """ + + # TODO: Can we test whether something is contained within a requirement? + # If so how do we do that? Do we need to test against the _name_ of + # the thing as well as the version? What about the markers? + # TODO: Can we normalize the name and extra name? + + def __init__(self, requirement_string): + try: + 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])) + + 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") + self.url = req.url + else: + self.url = None + self.extras = set(req.extras.asList() if req.extras else []) + self.specifier = SpecifierSet(req.specifier) + self.marker = req.marker if req.marker else None + + def __str__(self): + parts = [self.name] + + if self.extras: + parts.append("[{0}]".format(",".join(sorted(self.extras)))) + + if self.specifier: + parts.append(str(self.specifier)) + + if self.url: + parts.append("@ {0}".format(self.url)) + + if self.marker: + parts.append("; {0}".format(self.marker)) + + return "".join(parts) + + def __repr__(self): + return "<Requirement({0!r})>".format(str(self)) diff --git a/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/specifiers.py b/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/specifiers.py new file mode 100644 index 0000000..7f5a76c --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/specifiers.py @@ -0,0 +1,774 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import abc +import functools +import itertools +import re + +from ._compat import string_types, with_metaclass +from .version import Version, LegacyVersion, parse + + +class InvalidSpecifier(ValueError): + """ + An invalid specifier was found, users should refer to PEP 440. + """ + + +class BaseSpecifier(with_metaclass(abc.ABCMeta, object)): + + @abc.abstractmethod + def __str__(self): + """ + Returns the str representation of this Specifier like object. This + should be representative of the Specifier itself. + """ + + @abc.abstractmethod + def __hash__(self): + """ + Returns a hash value for this Specifier like object. + """ + + @abc.abstractmethod + def __eq__(self, other): + """ + Returns a boolean representing whether or not the two Specifier like + objects are equal. + """ + + @abc.abstractmethod + def __ne__(self, other): + """ + Returns a boolean representing whether or not the two Specifier like + objects are not equal. + """ + + @abc.abstractproperty + def prereleases(self): + """ + Returns whether or not pre-releases as a whole are allowed by this + specifier. + """ + + @prereleases.setter + def prereleases(self, value): + """ + Sets whether or not pre-releases as a whole are allowed by this + specifier. + """ + + @abc.abstractmethod + def contains(self, item, prereleases=None): + """ + Determines if the given item is contained within this specifier. + """ + + @abc.abstractmethod + def filter(self, iterable, prereleases=None): + """ + Takes an iterable of items and filters them so that only items which + are contained within this specifier are allowed in it. + """ + + +class _IndividualSpecifier(BaseSpecifier): + + _operators = {} + + def __init__(self, spec="", prereleases=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(), + ) + + # Store whether or not this Specifier should accept prereleases + self._prereleases = prereleases + + def __repr__(self): + pre = ( + ", prereleases={0!r}".format(self.prereleases) + if self._prereleases is not None + else "" + ) + + return "<{0}({1!r}{2})>".format( + self.__class__.__name__, + str(self), + pre, + ) + + def __str__(self): + return "{0}{1}".format(*self._spec) + + def __hash__(self): + return hash(self._spec) + + def __eq__(self, other): + if isinstance(other, string_types): + try: + other = self.__class__(other) + except InvalidSpecifier: + return NotImplemented + elif not isinstance(other, self.__class__): + return NotImplemented + + return self._spec == other._spec + + def __ne__(self, other): + if isinstance(other, string_types): + try: + other = self.__class__(other) + except InvalidSpecifier: + return NotImplemented + elif not isinstance(other, self.__class__): + return NotImplemented + + return self._spec != other._spec + + def _get_operator(self, op): + return getattr(self, "_compare_{0}".format(self._operators[op])) + + def _coerce_version(self, version): + if not isinstance(version, (LegacyVersion, Version)): + version = parse(version) + return version + + @property + def operator(self): + return self._spec[0] + + @property + def version(self): + return self._spec[1] + + @property + def prereleases(self): + return self._prereleases + + @prereleases.setter + def prereleases(self, value): + self._prereleases = value + + def __contains__(self, item): + return self.contains(item) + + def contains(self, item, prereleases=None): + # 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) + + # 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: + 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) + + def filter(self, iterable, prereleases=None): + yielded = False + found_prereleases = [] + + kw = {"prereleases": prereleases if prereleases is not None else True} + + # Attempt to iterate over all the values in the iterable and if any of + # them match, yield them. + for version in iterable: + parsed_version = self._coerce_version(version) + + if self.contains(parsed_version, **kw): + # 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)): + found_prereleases.append(version) + # Either this is not a prerelease, or we should have been + # accepting prereleases from the begining. + else: + yielded = True + yield version + + # Now that we've iterated over everything, determine if we've yielded + # any values, and if we have not and we have any prereleases stored up + # then we will go ahead and yield the prereleases. + if not yielded and found_prereleases: + for version in found_prereleases: + yield version + + +class LegacySpecifier(_IndividualSpecifier): + + _regex_str = ( + r""" + (?P<operator>(==|!=|<=|>=|<|>)) + \s* + (?P<version> + [^,;\s)]* # Since this is a "legacy" specifier, and the version + # string can be just about anything, we match everything + # except for whitespace, a semi-colon for marker support, + # a closing paren since versions can be enclosed in + # them, and a comma since it's a version separator. + ) + """ + ) + + _regex = re.compile( + r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) + + _operators = { + "==": "equal", + "!=": "not_equal", + "<=": "less_than_equal", + ">=": "greater_than_equal", + "<": "less_than", + ">": "greater_than", + } + + def _coerce_version(self, version): + if not isinstance(version, LegacyVersion): + version = LegacyVersion(str(version)) + return version + + def _compare_equal(self, prospective, spec): + return prospective == self._coerce_version(spec) + + def _compare_not_equal(self, prospective, spec): + return prospective != self._coerce_version(spec) + + def _compare_less_than_equal(self, prospective, spec): + return prospective <= self._coerce_version(spec) + + def _compare_greater_than_equal(self, prospective, spec): + return prospective >= self._coerce_version(spec) + + def _compare_less_than(self, prospective, spec): + return prospective < self._coerce_version(spec) + + def _compare_greater_than(self, prospective, spec): + return prospective > self._coerce_version(spec) + + +def _require_version_compare(fn): + @functools.wraps(fn) + def wrapped(self, prospective, spec): + if not isinstance(prospective, Version): + return False + return fn(self, prospective, spec) + return wrapped + + +class Specifier(_IndividualSpecifier): + + _regex_str = ( + r""" + (?P<operator>(~=|==|!=|<=|>=|<|>|===)) + (?P<version> + (?: + # The identity operators allow for an escape hatch that will + # do an exact string match of the version you wish to install. + # This will not be parsed by PEP 440 and we cannot determine + # any semantic meaning from it. This operator is discouraged + # but included entirely as an escape hatch. + (?<====) # Only match for the identity operator + \s* + [^\s]* # We just match everything, except for whitespace + # since we are only testing for strict identity. + ) + | + (?: + # The (non)equality operators allow for wild card and local + # versions to be specified so we have to define these two + # operators separately to enable that. + (?<===|!=) # Only match for equals and not equals + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)* # release + (?: # pre release + [-_\.]? + (a|b|c|rc|alpha|beta|pre|preview) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + + # You cannot use a wild card and a dev or local version + # together so group them with a | and make them optional. + (?: + (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + (?:\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*)? # local + | + \.\* # Wild card syntax of .* + )? + ) + | + (?: + # The compatible operator requires at least two digits in the + # release segment. + (?<=~=) # Only match for the compatible operator + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)+ # release (We have a + instead of a *) + (?: # pre release + [-_\.]? + (a|b|c|rc|alpha|beta|pre|preview) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + ) + | + (?: + # All other operators only allow a sub set of what the + # (non)equality operators do. Specifically they do not allow + # local versions to be specified nor do they allow the prefix + # matching wild cards. + (?<!==|!=|~=) # We have special cases for these + # operators so we want to make sure they + # don't match here. + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)* # release + (?: # pre release + [-_\.]? + (a|b|c|rc|alpha|beta|pre|preview) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + ) + ) + """ + ) + + _regex = re.compile( + r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) + + _operators = { + "~=": "compatible", + "==": "equal", + "!=": "not_equal", + "<=": "less_than_equal", + ">=": "greater_than_equal", + "<": "less_than", + ">": "greater_than", + "===": "arbitrary", + } + + @_require_version_compare + def _compare_compatible(self, prospective, spec): + # 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 + # implementing it ourselves. The only thing we need to do is construct + # the other specifiers. + + # We want everything but the last item in the version, but we want to + # ignore post and dev releases and we want to treat the pre-release as + # it's own separate segment. + prefix = ".".join( + list( + itertools.takewhile( + lambda x: (not x.startswith("post") and not + x.startswith("dev")), + _version_split(spec), + ) + )[:-1] + ) + + # Add the prefix notation to the end of our string + prefix += ".*" + + return (self._get_operator(">=")(prospective, spec) and + self._get_operator("==")(prospective, prefix)) + + @_require_version_compare + def _compare_equal(self, prospective, spec): + # 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 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)) + + # 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)] + + # Pad out our two sides with zeros so that they both equal the same + # length. + spec, prospective = _pad_version(spec, prospective) + else: + # Convert our spec string into a Version + spec = 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: + prospective = Version(prospective.public) + + return prospective == spec + + @_require_version_compare + def _compare_not_equal(self, prospective, spec): + return not self._compare_equal(prospective, spec) + + @_require_version_compare + def _compare_less_than_equal(self, prospective, spec): + return prospective <= Version(spec) + + @_require_version_compare + def _compare_greater_than_equal(self, prospective, spec): + return prospective >= Version(spec) + + @_require_version_compare + def _compare_less_than(self, prospective, spec): + # Convert our spec to a Version instance, since we'll want to work with + # it as a version. + spec = Version(spec) + + # 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 + # instead of doing extra unneeded work. + if not prospective < spec: + return False + + # This special case is here so that, unless the specifier itself + # includes is a pre-release version, that we do not accept pre-release + # versions for the version mentioned in the specifier (e.g. <3.1 should + # not match 3.1.dev0, but should match 3.0.dev0). + if not spec.is_prerelease and prospective.is_prerelease: + if Version(prospective.base_version) == Version(spec.base_version): + return False + + # If we've gotten to here, it means that prospective version is both + # less than the spec version *and* it's not a pre-release of the same + # version in the spec. + return True + + @_require_version_compare + def _compare_greater_than(self, prospective, spec): + # Convert our spec to a Version instance, since we'll want to work with + # it as a version. + spec = Version(spec) + + # 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 + # instead of doing extra unneeded work. + if not prospective > spec: + return False + + # This special case is here so that, unless the specifier itself + # includes is a post-release version, that we do not accept + # post-release versions for the version mentioned in the specifier + # (e.g. >3.1 should not match 3.0.post0, but should match 3.2.post0). + if not spec.is_postrelease and prospective.is_postrelease: + if Version(prospective.base_version) == Version(spec.base_version): + 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. + if prospective.local is not None: + if Version(prospective.base_version) == Version(spec.base_version): + return False + + # If we've gotten to here, it means that prospective version is both + # greater than the spec version *and* it's not a pre-release of the + # same version in the spec. + return True + + def _compare_arbitrary(self, prospective, spec): + return str(prospective).lower() == str(spec).lower() + + @property + def prereleases(self): + # If there is an explicit prereleases set for this, then we'll just + # blindly use that. + if self._prereleases is not None: + return self._prereleases + + # Look at all of our specifiers and determine if they are inclusive + # operators, and if they are if they are including an explicit + # prerelease. + operator, version = self._spec + if operator in ["==", ">=", "<=", "~=", "==="]: + # The == specifier can include a trailing .*, if it does we + # want to remove before parsing. + if operator == "==" and version.endswith(".*"): + version = version[:-2] + + # Parse the version, and if it is a pre-release than this + # specifier allows pre-releases. + if parse(version).is_prerelease: + return True + + return False + + @prereleases.setter + def prereleases(self, value): + self._prereleases = value + + +_prefix_regex = re.compile(r"^([0-9]+)((?:a|b|c|rc)[0-9]+)$") + + +def _version_split(version): + result = [] + for item in version.split("."): + match = _prefix_regex.search(item) + if match: + result.extend(match.groups()) + else: + result.append(item) + return result + + +def _pad_version(left, right): + left_split, right_split = [], [] + + # Get the release segment of our versions + left_split.append(list(itertools.takewhile(lambda x: x.isdigit(), left))) + 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]):]) + + # 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])), + ) + + 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. + 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: + try: + parsed.add(Specifier(specifier)) + except InvalidSpecifier: + parsed.add(LegacySpecifier(specifier)) + + # Turn our parsed specifiers into a frozen set and save them for later. + self._specs = frozenset(parsed) + + # Store our prereleases value so we can use it later to determine if + # we accept prereleases or not. + self._prereleases = prereleases + + def __repr__(self): + pre = ( + ", prereleases={0!r}".format(self.prereleases) + if self._prereleases is not None + else "" + ) + + return "<SpecifierSet({0!r}{1})>".format(str(self), pre) + + def __str__(self): + return ",".join(sorted(str(s) for s in self._specs)) + + def __hash__(self): + return hash(self._specs) + + def __and__(self, other): + if isinstance(other, string_types): + other = SpecifierSet(other) + elif not isinstance(other, SpecifierSet): + return NotImplemented + + specifier = SpecifierSet() + specifier._specs = frozenset(self._specs | other._specs) + + if self._prereleases is None and other._prereleases is not None: + specifier._prereleases = other._prereleases + elif self._prereleases is not None and other._prereleases is None: + specifier._prereleases = self._prereleases + elif self._prereleases == other._prereleases: + specifier._prereleases = self._prereleases + else: + raise ValueError( + "Cannot combine SpecifierSets with True and False prerelease " + "overrides." + ) + + return specifier + + def __eq__(self, other): + if isinstance(other, string_types): + other = SpecifierSet(other) + elif isinstance(other, _IndividualSpecifier): + other = SpecifierSet(str(other)) + elif not isinstance(other, SpecifierSet): + return NotImplemented + + return self._specs == other._specs + + def __ne__(self, other): + if isinstance(other, string_types): + other = SpecifierSet(other) + elif isinstance(other, _IndividualSpecifier): + other = SpecifierSet(str(other)) + elif not isinstance(other, SpecifierSet): + return NotImplemented + + return self._specs != other._specs + + def __len__(self): + return len(self._specs) + + def __iter__(self): + return iter(self._specs) + + @property + def prereleases(self): + # If we have been given an explicit prerelease modifier, then we'll + # pass that through here. + if self._prereleases is not None: + return self._prereleases + + # If we don't have any specifiers, and we don't have a forced value, + # then we'll just return None since we don't know if this should have + # pre-releases or not. + if not self._specs: + return None + + # Otherwise we'll see if any of the given specifiers accept + # prereleases, if any of them do we'll return True, otherwise False. + return any(s.prereleases for s in self._specs) + + @prereleases.setter + def prereleases(self, value): + self._prereleases = value + + def __contains__(self, item): + return self.contains(item) + + def contains(self, item, prereleases=None): + # Ensure that our item is a Version or LegacyVersion instance. + if not isinstance(item, (LegacyVersion, Version)): + item = parse(item) + + # 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. + if prereleases is None: + prereleases = self.prereleases + + # We can determine if we're going to allow pre-releases by looking to + # see if any of the underlying items supports them. If none of them do + # and this item is a pre-release then we do not allow it and we can + # short circuit that here. + # Note: This means that 1.0.dev1 would not be contained in something + # like >=1.0.devabc however it would be in >=1.0.debabc,>0.0.dev0 + if not prereleases and item.is_prerelease: + return False + + # We simply dispatch to the underlying specs here to make sure that the + # 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 + ) + + def filter(self, iterable, prereleases=None): + # 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. + if prereleases is None: + prereleases = self.prereleases + + # If we have any specifiers, then we want to wrap our iterable in the + # filter method for each one, this will act as a logical AND amongst + # each specifier. + if self._specs: + for spec in self._specs: + iterable = spec.filter(iterable, prereleases=bool(prereleases)) + return iterable + # If we do not have any specifiers, then we need to have a rough filter + # 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 = [] + + for item in iterable: + # Ensure that we some kind of Version class for this item. + if not isinstance(item, (LegacyVersion, Version)): + parsed_version = parse(item) + else: + parsed_version = item + + # Filter out any item which is parsed as a LegacyVersion + if isinstance(parsed_version, LegacyVersion): + continue + + # Store any item which is a pre-release for later unless we've + # already found a final version or we are accepting prereleases + if parsed_version.is_prerelease and not prereleases: + if not filtered: + found_prereleases.append(item) + else: + filtered.append(item) + + # If we've found no items except for pre-releases, then we'll go + # ahead and use the pre-releases + if not filtered and found_prereleases and prereleases is None: + return found_prereleases + + return filtered diff --git a/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/utils.py b/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/utils.py new file mode 100644 index 0000000..942387c --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/utils.py @@ -0,0 +1,14 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import re + + +_canonicalize_regex = re.compile(r"[-_.]+") + + +def canonicalize_name(name): + # This is taken from PEP 503. + return _canonicalize_regex.sub("-", name).lower() diff --git a/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/version.py b/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/version.py new file mode 100644 index 0000000..83b5ee8 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/version.py @@ -0,0 +1,393 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import collections +import itertools +import re + +from ._structures import Infinity + + +__all__ = [ + "parse", "Version", "LegacyVersion", "InvalidVersion", "VERSION_PATTERN" +] + + +_Version = collections.namedtuple( + "_Version", + ["epoch", "release", "dev", "pre", "post", "local"], +) + + +def parse(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 + a valid PEP 440 version or a legacy version. + """ + try: + return Version(version) + except InvalidVersion: + return LegacyVersion(version) + + +class InvalidVersion(ValueError): + """ + An invalid version was found, users should refer to PEP 440. + """ + + +class _BaseVersion(object): + + def __hash__(self): + return hash(self._key) + + def __lt__(self, other): + return self._compare(other, lambda s, o: s < o) + + def __le__(self, other): + return self._compare(other, lambda s, o: s <= o) + + def __eq__(self, other): + return self._compare(other, lambda s, o: s == o) + + def __ge__(self, other): + return self._compare(other, lambda s, o: s >= o) + + def __gt__(self, other): + return self._compare(other, lambda s, o: s > o) + + def __ne__(self, other): + return self._compare(other, lambda s, o: s != o) + + def _compare(self, other, method): + if not isinstance(other, _BaseVersion): + return NotImplemented + + return method(self._key, other._key) + + +class LegacyVersion(_BaseVersion): + + def __init__(self, version): + self._version = str(version) + self._key = _legacy_cmpkey(self._version) + + def __str__(self): + return self._version + + def __repr__(self): + return "<LegacyVersion({0})>".format(repr(str(self))) + + @property + def public(self): + return self._version + + @property + def base_version(self): + return self._version + + @property + def local(self): + return None + + @property + def is_prerelease(self): + return False + + @property + def is_postrelease(self): + return False + + +_legacy_version_component_re = re.compile( + r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE, +) + +_legacy_version_replacement_map = { + "pre": "c", "preview": "c", "-": "final-", "rc": "c", "dev": "@", +} + + +def _parse_version_parts(s): + for part in _legacy_version_component_re.split(s): + part = _legacy_version_replacement_map.get(part, part) + + if not part or part == ".": + continue + + if part[:1] in "0123456789": + # pad for numeric comparison + yield part.zfill(8) + else: + yield "*" + part + + # ensure that alpha/beta/candidate are before final + yield "*final" + + +def _legacy_cmpkey(version): + # 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, + # as before all PEP 440 versions. + epoch = -1 + + # This scheme is taken from pkg_resources.parse_version setuptools prior to + # it's adoption of the packaging library. + parts = [] + for part in _parse_version_parts(version.lower()): + if part.startswith("*"): + # remove "-" before a prerelease tag + if part < "*final": + while parts and parts[-1] == "*final-": + parts.pop() + + # remove trailing zeros from each series of numeric parts + while parts and parts[-1] == "00000000": + parts.pop() + + parts.append(part) + parts = tuple(parts) + + 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""" + v? + (?: + (?:(?P<epoch>[0-9]+)!)? # epoch + (?P<release>[0-9]+(?:\.[0-9]+)*) # release segment + (?P<pre> # pre-release + [-_\.]? + (?P<pre_l>(a|b|c|rc|alpha|beta|pre|preview)) + [-_\.]? + (?P<pre_n>[0-9]+)? + )? + (?P<post> # post release + (?:-(?P<post_n1>[0-9]+)) + | + (?: + [-_\.]? + (?P<post_l>post|rev|r) + [-_\.]? + (?P<post_n2>[0-9]+)? + ) + )? + (?P<dev> # dev release + [-_\.]? + (?P<dev_l>dev) + [-_\.]? + (?P<dev_n>[0-9]+)? + )? + ) + (?:\+(?P<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))? # local version +""" + + +class Version(_BaseVersion): + + _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 + match = self._regex.search(version) + if not match: + raise InvalidVersion("Invalid version: '{0}'".format(version)) + + # Store the parsed out pieces of the version + 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"), + ), + 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"), + ), + local=_parse_local_version(match.group("local")), + ) + + # Generate a key which will be used for sorting + self._key = _cmpkey( + self._version.epoch, + self._version.release, + self._version.pre, + self._version.post, + self._version.dev, + self._version.local, + ) + + def __repr__(self): + return "<Version({0})>".format(repr(str(self))) + + def __str__(self): + parts = [] + + # Epoch + if self._version.epoch != 0: + parts.append("{0}!".format(self._version.epoch)) + + # Release segment + parts.append(".".join(str(x) for x in self._version.release)) + + # Pre-release + if self._version.pre is not None: + parts.append("".join(str(x) for x in self._version.pre)) + + # Post-release + if self._version.post is not None: + parts.append(".post{0}".format(self._version.post[1])) + + # Development release + if self._version.dev is not None: + parts.append(".dev{0}".format(self._version.dev[1])) + + # Local version segment + if self._version.local is not None: + parts.append( + "+{0}".format(".".join(str(x) for x in self._version.local)) + ) + + return "".join(parts) + + @property + def public(self): + return str(self).split("+", 1)[0] + + @property + def base_version(self): + parts = [] + + # Epoch + if self._version.epoch != 0: + parts.append("{0}!".format(self._version.epoch)) + + # Release segment + parts.append(".".join(str(x) for x in self._version.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) + + @property + def is_postrelease(self): + return bool(self._version.post) + + +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. + if number is None: + number = 0 + + # We normalize any letters to their lower case form + letter = letter.lower() + + # We consider some words to be alternate spellings of other words and + # in those cases we want to normalize the spellings to our preferred + # spelling. + if letter == "alpha": + letter = "a" + elif letter == "beta": + letter = "b" + elif letter in ["c", "pre", "preview"]: + letter = "rc" + elif letter in ["rev", "r"]: + letter = "post" + + return letter, int(number) + if not letter and number: + # We assume if we are given a number, but we are not given a letter + # then this is using the implicit post release syntax (e.g. 1.0-1) + letter = "post" + + return letter, int(number) + + +_local_version_seperators = re.compile(r"[\._-]") + + +def _parse_local_version(local): + """ + Takes a string like abc.1.twelve and turns it into ("abc", 1, "twelve"). + """ + if local is not None: + return tuple( + part.lower() if not part.isdigit() else int(part) + for part in _local_version_seperators.split(local) + ) + + +def _cmpkey(epoch, release, pre, post, dev, local): + # 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( + 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. + # We'll do this by abusing the pre segment, but we _only_ want to do this + # 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 + # Versions without a pre-release (except as noted above) should sort after + # those with one. + elif pre is None: + pre = Infinity + + # Versions without a post segment should sort before those with one. + if post is None: + post = -Infinity + + # Versions without a development segment should sort after those with one. + if dev is None: + dev = Infinity + + if local is None: + # Versions without a local segment should sort before those with one. + local = -Infinity + else: + # Versions with a local segment need that segment parsed to implement + # the sorting rules in PEP440. + # - Alpha numeric segments sort before numeric segments + # - Alpha numeric segments sort lexicographically + # - 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 + ) + + return epoch, release, pre, post, dev, local diff --git a/venv/lib/python3.7/site-packages/setuptools/_vendor/pyparsing.py b/venv/lib/python3.7/site-packages/setuptools/_vendor/pyparsing.py new file mode 100644 index 0000000..cf75e1e --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/_vendor/pyparsing.py @@ -0,0 +1,5742 @@ +# module pyparsing.py +# +# Copyright (c) 2003-2018 Paul T. McGuire +# +# 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. +# + +__doc__ = \ +""" +pyparsing module - Classes and methods to define and execute parsing grammars +============================================================================= + +The pyparsing module is an alternative approach to creating and executing simple grammars, +vs. the traditional lex/yacc approach, or the use of regular expressions. With pyparsing, you +don't need to learn a new syntax for defining grammars or matching expressions - the parsing module +provides a library of classes that you use to construct the grammar directly in Python. + +Here is a program to parse "Hello, World!" (or any greeting of the form +C{"<salutation>, <addressee>!"}), built up using L{Word}, L{Literal}, and L{And} elements +(L{'+'<ParserElement.__add__>} operator gives L{And} expressions, strings are auto-converted to +L{Literal} expressions):: + + from pyparsing import Word, alphas + + # define grammar of a greeting + greet = Word(alphas) + "," + Word(alphas) + "!" + + hello = "Hello, World!" + print (hello, "->", greet.parseString(hello)) + +The program outputs the following:: + + Hello, World! -> ['Hello', ',', 'World', '!'] + +The Python representation of the grammar is quite readable, owing to the self-explanatory +class names, and the use of '+', '|' and '^' operators. + +The L{ParseResults} object returned from L{ParserElement.parseString<ParserElement.parseString>} can be accessed as a nested list, a dictionary, or an +object with named attributes. + +The pyparsing module handles some of the problems that are typically vexing when writing text parsers: + - extra or missing whitespace (the above program will also handle "Hello,World!", "Hello , World !", etc.) + - quoted strings + - embedded comments + + +Getting Started - +----------------- +Visit the classes L{ParserElement} and L{ParseResults} to see the base classes that most other pyparsing +classes inherit from. Use the docstrings for examples of how to: + - construct literal match expressions from L{Literal} and L{CaselessLiteral} classes + - construct character word-group expressions using the L{Word} class + - see how to create repetitive expressions using L{ZeroOrMore} and L{OneOrMore} classes + - use L{'+'<And>}, L{'|'<MatchFirst>}, L{'^'<Or>}, and L{'&'<Each>} operators to combine simple expressions into more complex ones + - associate names with your parsed results using L{ParserElement.setResultsName} + - find some helpful expression short-cuts like L{delimitedList} and L{oneOf} + - find more useful common expressions in the L{pyparsing_common} namespace class +""" + +__version__ = "2.2.1" +__versionTime__ = "18 Sep 2018 00:49 UTC" +__author__ = "Paul McGuire <ptmcg@users.sourceforge.net>" + +import string +from weakref import ref as wkref +import copy +import sys +import warnings +import re +import sre_constants +import collections +import pprint +import traceback +import types +from datetime import datetime + +try: + from _thread import RLock +except ImportError: + from threading import RLock + +try: + # Python 3 + from collections.abc import Iterable + from collections.abc import MutableMapping +except ImportError: + # Python 2.7 + from collections import Iterable + from collections import MutableMapping + +try: + from collections import OrderedDict as _OrderedDict +except ImportError: + try: + from ordereddict import OrderedDict as _OrderedDict + except ImportError: + _OrderedDict = None + +#~ sys.stderr.write( "testing pyparsing module, version %s, %s\n" % (__version__,__versionTime__ ) ) + +__all__ = [ +'And', 'CaselessKeyword', 'CaselessLiteral', 'CharsNotIn', 'Combine', 'Dict', 'Each', 'Empty', +'FollowedBy', 'Forward', 'GoToColumn', 'Group', 'Keyword', 'LineEnd', 'LineStart', 'Literal', +'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', +'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', +] + +system_version = tuple(sys.version_info)[:3] +PY_3 = system_version[0] == 3 +if PY_3: + _MAX_INT = sys.maxsize + basestring = str + unichr = chr + _ustr = str + + # build list of single arg builtins, that can be used as parse actions + singleArgBuiltins = [sum, len, sorted, reversed, list, tuple, set, any, all, min, max] + +else: + _MAX_INT = sys.maxint + range = xrange + + def _ustr(obj): + """Drop-in replacement for str(obj) that tries to be Unicode friendly. It first tries + str(obj). If that fails with a UnicodeEncodeError, then it tries unicode(obj). It + then < returns the unicode object | encodes it with the default encoding | ... >. + """ + if isinstance(obj,unicode): + return obj + + try: + # If this works, then _ustr(obj) has the same behaviour as str(obj), so + # it won't break any existing code. + return str(obj) + + except UnicodeEncodeError: + # Else encode it + ret = unicode(obj).encode(sys.getdefaultencoding(), 'xmlcharrefreplace') + xmlcharref = Regex(r'&#\d+;') + xmlcharref.setParseAction(lambda t: '\\u' + hex(int(t[0][2:-1]))[2:]) + return xmlcharref.transformString(ret) + + # 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)) + except AttributeError: + continue + +_generatorType = type((y for y in range(1))) + +def _xml_escape(data): + """Escape &, <, >, ", ', etc. in a string of 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): + data = data.replace(from_, to_) + return data + +class _Constants(object): + pass + +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) + +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 ): + self.loc = loc + if msg is None: + self.msg = pstr + self.pstr = "" + else: + self.msg = msg + self.pstr = pstr + self.parserElement = elem + self.args = (pstr, loc, msg) + + @classmethod + def _from_exception(cls, pe): + """ + internal factory method to simplify creating one type of ParseException + from another - avoids having __init__ signature conflicts among subclasses + """ + return cls(pe.pstr, pe.loc, pe.msg, pe.parserElement) + + 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 ) + 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 ): + return _ustr(self) + def markInputline( self, markerString = ">!<" ): + """Extracts the exception line from the input string, and marks + the location of the exception with a special symbol. + """ + line_str = self.line + line_column = self.column - 1 + if markerString: + line_str = "".join((line_str[:line_column], + markerString, line_str[line_column:])) + return line_str.strip() + def __dir__(self): + return "lineno col line".split() + dir(type(self)) + +class ParseException(ParseBaseException): + """ + Exception thrown when parse expressions don't match class; + 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 + + Example:: + try: + Word(nums).setName("integer").parseString("ABC") + except ParseException as pe: + print(pe) + print("column: {}".format(pe.col)) + + prints:: + Expected integer (at char 0), (line:1, col:1) + column: 1 + """ + pass + +class ParseFatalException(ParseBaseException): + """user-throwable exception thrown when inconsistent parse content + is found; stops all parsing immediately""" + pass + +class ParseSyntaxException(ParseFatalException): + """just like L{ParseFatalException}, but thrown internally when an + L{ErrorStop<And._ErrorStop>} ('-' operator) indicates that parsing is to stop + immediately because an unbacktrackable syntax error has been found""" + pass + +#~ class ReparseException(ParseBaseException): + #~ """Experimental class - parse actions can raise this exception to cause + #~ pyparsing to reparse the input string: + #~ - with a modified input string, and/or + #~ - with a modified start location + #~ Set the values of the ReparseException in the constructor, and raise the + #~ exception in a parse action to cause pyparsing to use the new string/location. + #~ Setting the values as None causes no change to be made. + #~ """ + #~ def __init_( self, newstring, restartLoc ): + #~ self.newParseText = newstring + #~ self.reparseLoc = restartLoc + +class RecursiveGrammarException(Exception): + """exception thrown by L{ParserElement.validate} if the grammar could be improperly recursive""" + def __init__( self, parseElementList ): + self.parseElementTrace = parseElementList + + def __str__( self ): + return "RecursiveGrammarException: %s" % self.parseElementTrace + +class _ParseResultsWithOffset(object): + 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) + +class ParseResults(object): + """ + Structured parse results, to provide multiple means of access to the parsed data: + - as a list (C{len(results)}) + - by list index (C{results[0], results[1]}, etc.) + - by attribute (C{results.<resultsName>} - see L{ParserElement.setResultsName}) + + Example:: + integer = Word(nums) + date_str = (integer.setResultsName("year") + '/' + + integer.setResultsName("month") + '/' + + integer.setResultsName("day")) + # equivalent form: + # date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + # parseString returns a ParseResults object + result = date_str.parseString("1999/12/31") + + def test(s, fn=repr): + print("%s -> %s" % (s, fn(eval(s)))) + test("list(result)") + test("result[0]") + test("result['month']") + test("result.day") + test("'month' in result") + test("'minutes' in result") + test("result.dump()", str) + prints:: + list(result) -> ['1999', '/', '12', '/', '31'] + result[0] -> '1999' + result['month'] -> '12' + result.day -> '31' + 'month' in result -> True + 'minutes' in result -> False + result.dump() -> ['1999', '/', '12', '/', '31'] + - day: 31 + - month: 12 + - year: 1999 + """ + def __new__(cls, toklist=None, name=None, asList=True, modal=True ): + if isinstance(toklist, cls): + return toklist + retobj = object.__new__(cls) + retobj.__doinit = True + return retobj + + # 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 ): + if self.__doinit: + self.__doinit = False + self.__name = None + self.__parent = None + self.__accumNames = {} + self.__asList = asList + self.__modal = modal + if toklist is None: + toklist = [] + if isinstance(toklist, list): + self.__toklist = toklist[:] + elif isinstance(toklist, _generatorType): + self.__toklist = list(toklist) + else: + self.__toklist = [toklist] + self.__tokdict = dict() + + 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 + self.__name = name + if not (isinstance(toklist, (type(None), basestring, list)) and toklist in (None,'',[])): + if isinstance(toklist,basestring): + toklist = [ toklist ] + if asList: + if isinstance(toklist,ParseResults): + self[name] = _ParseResultsWithOffset(toklist.copy(),0) + else: + self[name] = _ParseResultsWithOffset(ParseResults(toklist[0]),0) + self[name].__name = name + else: + try: + self[name] = toklist[0] + except (KeyError,TypeError,IndexError): + self[name] = toklist + + 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] ]) + + 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)): + self.__toklist[k] = v + sub = v + else: + self.__tokdict[k] = self.__tokdict.get(k,list()) + [_ParseResultsWithOffset(v,0)] + sub = v + if isinstance(sub,ParseResults): + sub.__parent = wkref(self) + + 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) + # get removed indices + removed = list(range(*i.indices(mylen))) + removed.reverse() + # fixup indices in token dictionary + 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 ): + return k in self.__tokdict + + 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 ): + if hasattr(self.__tokdict, "iterkeys"): + return self.__tokdict.iterkeys() + else: + return iter(self.__tokdict) + + def _itervalues( self ): + return (self[k] for k in self._iterkeys()) + + def _iteritems( self ): + return ((k, self[k]) for k in self._iterkeys()) + + if PY_3: + keys = _iterkeys + """Returns an iterator of all named result keys (Python 3.x only).""" + + values = _itervalues + """Returns an iterator of all named result values (Python 3.x only).""" + + items = _iteritems + """Returns an iterator of all named result key-value tuples (Python 3.x only).""" + + else: + iterkeys = _iterkeys + """Returns an iterator of all named result keys (Python 2.x only).""" + + itervalues = _itervalues + """Returns an iterator of all named result values (Python 2.x only).""" + + iteritems = _iteritems + """Returns an iterator of all named result key-value tuples (Python 2.x only).""" + + 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 ): + """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 ): + """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 ): + """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): + """ + Removes and returns item at specified index (default=C{last}). + Supports both C{list} and C{dict} semantics for C{pop()}. If passed no + argument or an integer argument, it will use C{list} semantics + and pop tokens from the list of parsed tokens. If passed a + non-integer argument (most likely a string), it will use C{dict} + semantics and pop the corresponding value from any defined + results names. A second default return value argument is + supported, just as in C{dict.pop()}. + + Example:: + def remove_first(tokens): + tokens.pop(0) + print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] + print(OneOrMore(Word(nums)).addParseAction(remove_first).parseString("0 123 321")) # -> ['123', '321'] + + label = Word(alphas) + patt = label("LABEL") + OneOrMore(Word(nums)) + print(patt.parseString("AAB 123 321").dump()) + + # Use pop() in a parse action to remove named result (note that corresponding value is not + # removed from list form of results) + def remove_LABEL(tokens): + tokens.pop("LABEL") + return tokens + patt.addParseAction(remove_LABEL) + print(patt.parseString("AAB 123 321").dump()) + prints:: + ['AAB', '123', '321'] + - LABEL: AAB + + ['AAB', '123', '321'] + """ + if not args: + args = [-1] + 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): + index = args[0] + ret = self[index] + del self[index] + return ret + else: + defaultvalue = args[1] + return defaultvalue + + def get(self, key, defaultValue=None): + """ + Returns named result matching the given key, or if there is no + such name, then returns the given C{defaultValue} or C{None} if no + C{defaultValue} is specified. + + Similar to C{dict.get()}. + + Example:: + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + result = date_str.parseString("1999/12/31") + print(result.get("year")) # -> '1999' + print(result.get("hour", "not specified")) # -> 'not specified' + print(result.get("hour")) # -> None + """ + if key in self: + return self[key] + else: + return defaultValue + + def insert( self, index, insStr ): + """ + Inserts new element at location index in the list of parsed tokens. + + Similar to C{list.insert()}. + + Example:: + print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] + + # use a parse action to insert the parse location in the front of the parsed results + def insert_locn(locn, tokens): + tokens.insert(0, locn) + print(OneOrMore(Word(nums)).addParseAction(insert_locn).parseString("0 123 321")) # -> [0, '0', '123', '321'] + """ + self.__toklist.insert(index, insStr) + # fixup indices in token dictionary + 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 ): + """ + Add single element to end of ParseResults list of elements. + + Example:: + print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] + + # use a parse action to compute the sum of the parsed integers, and add it to the end + def append_sum(tokens): + tokens.append(sum(map(int, tokens))) + print(OneOrMore(Word(nums)).addParseAction(append_sum).parseString("0 123 321")) # -> ['0', '123', '321', 444] + """ + self.__toklist.append(item) + + def extend( self, itemseq ): + """ + Add sequence of elements to end of ParseResults list of elements. + + Example:: + patt = OneOrMore(Word(alphas)) + + # use a parse action to append the reverse of the matched strings, to make a palindrome + def make_palindrome(tokens): + tokens.extend(reversed([t[::-1] for t in tokens])) + return ''.join(tokens) + print(patt.addParseAction(make_palindrome).parseString("lskdj sdlkjf lksd")) # -> 'lskdjsdlkjflksddsklfjkldsjdksl' + """ + if isinstance(itemseq, ParseResults): + self += itemseq + else: + self.__toklist.extend(itemseq) + + def clear( self ): + """ + Clear all elements and results names. + """ + del self.__toklist[:] + self.__tokdict.clear() + + 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 ): + ret = self.copy() + ret += other + return ret + + def __iadd__( self, other ): + if other.__tokdict: + offset = len(self.__toklist) + 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: + self[k] = v + if isinstance(v[0],ParseResults): + v[0].__parent = wkref(self) + + self.__toklist += other.__toklist + self.__accumNames.update( other.__accumNames ) + return self + + def __radd__(self, other): + 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 __str__( self ): + return '[' + ', '.join(_ustr(i) if isinstance(i, ParseResults) else repr(i) for i in self.__toklist) + ']' + + def _asStringList( self, sep='' ): + out = [] + for item in self.__toklist: + if out and sep: + out.append(sep) + if isinstance( item, ParseResults ): + out += item._asStringList() + else: + out.append( _ustr(item) ) + return out + + def asList( self ): + """ + Returns the parse results as a nested list of matching tokens, all converted to strings. + + Example:: + patt = OneOrMore(Word(alphas)) + result = patt.parseString("sldkj lsdkj sldkj") + # even though the result prints in string-like form, it is actually a pyparsing ParseResults + print(type(result), result) # -> <class 'pyparsing.ParseResults'> ['sldkj', 'lsdkj', 'sldkj'] + + # Use asList() to create an actual list + 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] + + def asDict( self ): + """ + Returns the named parse results as a nested dictionary. + + Example:: + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + result = date_str.parseString('12/31/1999') + print(type(result), repr(result)) # -> <class 'pyparsing.ParseResults'> (['12', '/', '31', '/', '1999'], {'day': [('1999', 4)], 'year': [('12', 0)], 'month': [('31', 2)]}) + + result_dict = result.asDict() + print(type(result_dict), repr(result_dict)) # -> <class 'dict'> {'day': '1999', 'year': '12', 'month': '31'} + + # even though a ParseResults supports dict-like access, sometime you just need to have a dict + import json + print(json.dumps(result)) # -> Exception: TypeError: ... is not JSON serializable + print(json.dumps(result.asDict())) # -> {"month": "31", "day": "1999", "year": "12"} + """ + if PY_3: + item_fn = self.items + else: + item_fn = self.iteritems + + def toItem(obj): + if isinstance(obj, ParseResults): + if obj.haskeys(): + return obj.asDict() + else: + return [toItem(v) for v in obj] + else: + return obj + + return dict((k,toItem(v)) for k,v in item_fn()) + + def copy( self ): + """ + Returns a new copy of a C{ParseResults} object. + """ + ret = ParseResults( self.__toklist ) + ret.__tokdict = self.__tokdict.copy() + ret.__parent = self.__parent + ret.__accumNames.update( self.__accumNames ) + ret.__name = self.__name + return ret + + 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) + nextLevelIndent = indent + " " + + # collapse out indents if formatting is not desired + if not formatted: + indent = "" + nextLevelIndent = "" + nl = "" + + selfTag = None + if doctag is not None: + selfTag = doctag + else: + if self.__name: + selfTag = self.__name + + if not selfTag: + if namedItemsOnly: + return "" + else: + selfTag = "ITEM" + + out += [ nl, indent, "<", selfTag, ">" ] + + 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)] + else: + out += [ res.asXML(None, + namedItemsOnly and doctag is None, + nextLevelIndent, + formatted)] + else: + # individual token, see if there is a name for it + resTag = None + if i in namedItems: + resTag = namedItems[i] + if not resTag: + if namedItemsOnly: + continue + else: + resTag = "ITEM" + xmlBodyText = _xml_escape(_ustr(res)) + out += [ nl, nextLevelIndent, "<", resTag, ">", + xmlBodyText, + "</", resTag, ">" ] + + out += [ nl, indent, "</", selfTag, ">" ] + return "".join(out) + + def __lookup(self,sub): + for k,vlist in self.__tokdict.items(): + for v,loc in vlist: + if sub is v: + return k + return None + + def getName(self): + r""" + Returns the results name for this token expression. Useful when several + different expressions might match at a particular location. + + Example:: + integer = Word(nums) + ssn_expr = Regex(r"\d\d\d-\d\d-\d\d\d\d") + house_number_expr = Suppress('#') + Word(nums, alphanums) + user_data = (Group(house_number_expr)("house_number") + | Group(ssn_expr)("ssn") + | Group(integer)("age")) + user_info = OneOrMore(user_data) + + result = user_info.parseString("22 111-22-3333 #221B") + for item in result: + print(item.getName(), ':', item[0]) + prints:: + age : 22 + ssn : 111-22-3333 + house_number : 221B + """ + if self.__name: + return self.__name + elif self.__parent: + par = self.__parent() + if par: + 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)): + return next(iter(self.__tokdict.keys())) + else: + return None + + def dump(self, indent='', depth=0, full=True): + """ + Diagnostic method for listing out the contents of a C{ParseResults}. + Accepts an optional C{indent} argument so that this string can be embedded + in a nested display of other data. + + Example:: + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + result = date_str.parseString('12/31/1999') + print(result.dump()) + prints:: + ['12', '/', '31', '/', '1999'] + - day: 1999 + - month: 31 + - year: 12 + """ + out = [] + NL = '\n' + out.append( indent+_ustr(self.asList()) ) + if full: + if self.haskeys(): + 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): + if v: + out.append( v.dump(indent,depth+1) ) + else: + out.append(_ustr(v)) + else: + out.append(repr(v)) + 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) )) + else: + out.append("\n%s%s[%d]:\n%s%s%s" % (indent,(' '*(depth)),i,indent,(' '*(depth+1)),_ustr(vv))) + + return "".join(out) + + def pprint(self, *args, **kwargs): + """ + Pretty-printer for parsed results as a list, using the C{pprint} module. + Accepts additional positional or keyword args as defined for the + C{pprint.pprint} method. (U{http://docs.python.org/3/library/pprint.html#pprint.pprint}) + + Example:: + ident = Word(alphas, alphanums) + num = Word(nums) + func = Forward() + term = ident | num | Group('(' + func + ')') + func <<= ident + Group(Optional(delimitedList(term))) + result = func.parseString("fna a,b,(fnb c,d,200),100") + result.pprint(width=40) + prints:: + ['fna', + ['a', + 'b', + ['(', 'fnb', ['c', 'd', '200'], ')'], + '100']] + """ + pprint.pprint(self.asList(), *args, **kwargs) + + # 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 ) ) + + def __setstate__(self,state): + self.__toklist = state[0] + (self.__tokdict, + par, + inAccumNames, + self.__name) = state[1] + self.__accumNames = {} + self.__accumNames.update(inAccumNames) + if par is not None: + self.__parent = wkref(par) + else: + self.__parent = None + + def __getnewargs__(self): + return self.__toklist, self.__name, self.__asList, self.__modal + + def __dir__(self): + return (dir(type(self)) + list(self.keys())) + +MutableMapping.register(ParseResults) + +def col (loc,strg): + """Returns current column within a string, counting newlines as line separators. + The first column is number 1. + + Note: the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See L{I{ParserElement.parseString}<ParserElement.parseString>} for more information + on parsing strings containing C{<TAB>}s, and suggested methods to maintain a + consistent view of the parsed string, the parse 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) + +def lineno(loc,strg): + """Returns current line number within a string, counting newlines as line separators. + The first line is number 1. + + Note: the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See L{I{ParserElement.parseString}<ParserElement.parseString>} for more information + on parsing strings containing C{<TAB>}s, and 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 + +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] + else: + 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 _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 nullDebugAction(*args): + """'Do-nothing' debug action, to suppress debugging output during parsing.""" + pass + +# Only works on Python 3.x - nonlocal is toxic to Python 2 installs +#~ 'decorator to trim function calls to match the arity of the target' +#~ def _trim_arity(func, maxargs=3): + #~ if func in singleArgBuiltins: + #~ return lambda s,l,t: func(t) + #~ limit = 0 + #~ foundArity = False + #~ def wrapper(*args): + #~ nonlocal limit,foundArity + #~ while 1: + #~ try: + #~ ret = func(*args[limit:]) + #~ foundArity = True + #~ return ret + #~ except TypeError: + #~ if limit == maxargs or foundArity: + #~ raise + #~ limit += 1 + #~ continue + #~ return wrapper + +# this version is Python 2.x-3.x cross-compatible +'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) + limit = [0] + foundArity = [False] + + # traceback return data structure changed in Py3.5 - normalize back to plain tuples + 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] + return [frame_summary[:2]] + def extract_tb(tb, limit=0): + frames = traceback.extract_tb(tb, limit=limit) + frame_summary = frames[-1] + return [frame_summary[:2]] + else: + extract_stack = traceback.extract_stack + extract_tb = traceback.extract_tb + + # synthesize what would be returned by traceback.extract_stack at the call to + # user's parse action 'func', so that we don't incur call penalty at parse time + + LINE_DIFF = 6 + # 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) + + def wrapper(*args): + while 1: + try: + ret = func(*args[limit[0]:]) + foundArity[0] = True + return ret + except TypeError: + # re-raise TypeErrors if they did not come from our arity testing + if foundArity[0]: + raise + else: + try: + tb = sys.exc_info()[-1] + if not extract_tb(tb, limit=2)[-1][:2] == pa_call_line_synth: + raise + finally: + del tb + + if limit[0] <= maxargs: + limit[0] += 1 + continue + raise + + # copy func name to wrapper for sensible debug output + func_name = "<parse action>" + try: + func_name = getattr(func, '__name__', + getattr(func, '__class__').__name__) + except Exception: + func_name = str(func) + wrapper.__name__ = func_name + + return wrapper + +class ParserElement(object): + """Abstract base level parser element class.""" + DEFAULT_WHITE_CHARS = " \n\t\r" + verbose_stacktrace = False + + @staticmethod + def setDefaultWhitespaceChars( chars ): + r""" + Overrides the default whitespace chars + + Example:: + # default whitespace chars are space, <TAB> and newline + OneOrMore(Word(alphas)).parseString("abc def\nghi jkl") # -> ['abc', 'def', 'ghi', 'jkl'] + + # change to just treat newline as significant + ParserElement.setDefaultWhitespaceChars(" \t") + OneOrMore(Word(alphas)).parseString("abc def\nghi jkl") # -> ['abc', 'def'] + """ + ParserElement.DEFAULT_WHITE_CHARS = chars + + @staticmethod + def inlineLiteralsUsing(cls): + """ + Set class to be used for inclusion of string literals into a parser. + + Example:: + # default literal class used is Literal + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + date_str.parseString("1999/12/31") # -> ['1999', '/', '12', '/', '31'] + + + # change to Suppress + ParserElement.inlineLiteralsUsing(Suppress) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + date_str.parseString("1999/12/31") # -> ['1999', '12', '31'] + """ + ParserElement._literalStringClass = cls + + 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.strRepr = None + self.resultsName = None + self.saveAsList = savelist + self.skipWhitespace = True + self.whiteChars = ParserElement.DEFAULT_WHITE_CHARS + self.copyDefaultWhiteChars = True + self.mayReturnEmpty = False # used when checking for left-recursion + self.keepTabs = False + self.ignoreExprs = list() + self.debug = False + self.streamlined = False + 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.re = None + self.callPreparse = True # used to avoid redundant calls to preParse + self.callDuringTry = False + + def copy( self ): + """ + Make a copy of this C{ParserElement}. Useful for defining different parse actions + for the same parsing pattern, using copies of the original parse element. + + 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") + + print(OneOrMore(integerK | integerM | integer).parseString("5K 100 640K 256M")) + prints:: + [5120, 100, 655360, 268435456] + Equivalent form of C{expr.copy()} is just C{expr()}:: + integerM = integer().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M") + """ + 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 ): + """ + Define name for this expression, makes debugging and exception messages clearer. + + Example:: + Word(nums).parseString("ABC") # -> Exception: Expected W:(0123...) (at char 0), (line:1, col:1) + Word(nums).setName("integer").parseString("ABC") # -> Exception: Expected integer (at char 0), (line:1, col:1) + """ + self.name = name + self.errmsg = "Expected " + self.name + if hasattr(self,"exception"): + self.exception.msg = self.errmsg + return self + + def setResultsName( self, name, listAllMatches=False ): + """ + Define name for referencing matching tokens as a nested attribute + of the returned parse results. + NOTE: this returns a *copy* of the original C{ParserElement} object; + this is so that the client can define a basic element, such as an + integer, and reference it in multiple places with different names. + + You can also set results names using the abbreviated syntax, + C{expr("name")} in place of C{expr.setResultsName("name")} - + see L{I{__call__}<__call__>}. + + Example:: + date_str = (integer.setResultsName("year") + '/' + + integer.setResultsName("month") + '/' + + integer.setResultsName("day")) + + # equivalent form: + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + """ + newself = self.copy() + if name.endswith("*"): + name = name[:-1] + listAllMatches=True + newself.resultsName = name + newself.modalResults = not listAllMatches + return newself + + def setBreak(self,breakFlag = True): + """Method to invoke the Python pdb debugger when this element is + about to be parsed. Set C{breakFlag} to True to enable, False to + disable. + """ + if breakFlag: + _parseMethod = self._parse + def breaker(instring, loc, doActions=True, callPreParse=True): + import pdb + pdb.set_trace() + return _parseMethod( instring, loc, doActions, callPreParse ) + breaker._originalParseMethod = _parseMethod + self._parse = breaker + else: + if hasattr(self._parse,"_originalParseMethod"): + self._parse = self._parse._originalParseMethod + return self + + 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 C{fn(s,loc,toks)}, + C{fn(loc,toks)}, C{fn(toks)}, or just C{fn()}, where: + - s = the original string being parsed (see note below) + - loc = the location of the matching substring + - toks = a list of the matched tokens, packaged as a C{L{ParseResults}} object + If the functions in fns modify the tokens, they can return them as the return + value from fn, and the modified list of tokens will replace the original. + Otherwise, fn does not need to return any value. + + Optional keyword arguments: + - callDuringTry = (default=C{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 L{I{parseString}<parseString>} for more information + on parsing strings containing C{<TAB>}s, and suggested methods to maintain a + consistent view of the parsed string, the parse location, and line and column + positions within the parsed string. + + Example:: + integer = Word(nums) + date_str = integer + '/' + integer + '/' + integer + + date_str.parseString("1999/12/31") # -> ['1999', '/', '12', '/', '31'] + + # use parse action to convert to ints at parse time + integer = Word(nums).setParseAction(lambda toks: int(toks[0])) + date_str = integer + '/' + integer + '/' + integer + + # 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) + return self + + def addParseAction( self, *fns, **kwargs ): + """ + Add one or more parse actions to expression's list of parse actions. See L{I{setParseAction}<setParseAction>}. + + See examples in L{I{copy}<copy>}. + """ + self.parseAction += list(map(_trim_arity, list(fns))) + self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False) + return self + + def addCondition(self, *fns, **kwargs): + """Add a boolean predicate function to expression's list of parse actions. See + L{I{setParseAction}<setParseAction>} for function call signatures. Unlike C{setParseAction}, + functions passed to C{addCondition} need to return boolean success/fail of the condition. + + Optional keyword arguments: + - message = define a custom message to be used in the raised exception + - fatal = if True, will raise ParseFatalException to stop parsing immediately; otherwise will raise ParseException + + Example:: + integer = Word(nums).setParseAction(lambda toks: int(toks[0])) + year_int = integer.copy() + year_int.addCondition(lambda toks: toks[0] >= 2000, message="Only support years 2000 and later") + date_str = year_int + '/' + integer + '/' + integer + + 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: + def pa(s,l,t): + if not bool(_trim_arity(fn)(s,l,t)): + raise exc_type(s,l,msg) + self.parseAction.append(pa) + self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False) + return self + + 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 + C{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 + - err = the exception thrown + The function returns no value. It may throw C{L{ParseFatalException}} + if it is desired to stop parsing immediately.""" + self.failAction = fn + return self + + 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 ) + exprsFound = True + except ParseException: + pass + return loc + + def preParse( self, instring, loc ): + if self.ignoreExprs: + loc = self._skipIgnorables( instring, loc ) + + if self.skipWhitespace: + wt = self.whiteChars + instrlen = len(instring) + while loc < instrlen and instring[loc] in wt: + loc += 1 + + return loc + + def parseImpl( self, instring, loc, doActions=True ): + return loc, [] + + def postParse( self, instring, loc, tokenlist ): + return tokenlist + + #~ @profile + def _parseNoCache( self, instring, loc, doActions=True, callPreParse=True ): + 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 + 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 self.failAction: + self.failAction( instring, tokensStart, self, err ) + raise + else: + 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 ) + + tokens = self.postParse( instring, loc, tokens ) + + 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: + tokens = fn( instring, tokensStart, retTokens ) + if tokens is not None: + 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 ) + raise + else: + for fn in self.parseAction: + tokens = fn( instring, tokensStart, retTokens ) + if tokens is not None: + retTokens = ParseResults( tokens, + self.resultsName, + 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 ) + + return loc, retTokens + + def tryParse( self, instring, loc ): + try: + return self._parse( instring, loc, doActions=False )[0] + except ParseFatalException: + raise ParseException( instring, loc, self.errmsg, self) + + def canParseNext(self, instring, loc): + try: + self.tryParse(instring, loc) + except (ParseException, IndexError): + return False + else: + return True + + class _UnboundedCache(object): + def __init__(self): + cache = {} + self.not_in_cache = not_in_cache = object() + + def get(self, key): + return cache.get(key, not_in_cache) + + def set(self, key, value): + cache[key] = value + + def clear(self): + cache.clear() + + def cache_len(self): + return len(cache) + + self.get = types.MethodType(get, self) + self.set = types.MethodType(set, self) + self.clear = types.MethodType(clear, self) + self.__len__ = types.MethodType(cache_len, self) + + if _OrderedDict is not None: + class _FifoCache(object): + def __init__(self, size): + self.not_in_cache = not_in_cache = object() + + cache = _OrderedDict() + + def get(self, key): + return cache.get(key, not_in_cache) + + def set(self, key, value): + cache[key] = value + while len(cache) > size: + try: + cache.popitem(False) + except KeyError: + pass + + def clear(self): + cache.clear() + + def cache_len(self): + return len(cache) + + self.get = types.MethodType(get, self) + self.set = types.MethodType(set, self) + self.clear = types.MethodType(clear, self) + self.__len__ = types.MethodType(cache_len, self) + + else: + class _FifoCache(object): + def __init__(self, size): + self.not_in_cache = not_in_cache = object() + + cache = {} + key_fifo = collections.deque([], size) + + def get(self, key): + return cache.get(key, not_in_cache) + + def set(self, key, value): + cache[key] = value + while len(key_fifo) > size: + cache.pop(key_fifo.popleft(), None) + key_fifo.append(key) + + def clear(self): + cache.clear() + key_fifo.clear() + + def cache_len(self): + return len(cache) + + self.get = types.MethodType(get, self) + self.set = types.MethodType(set, self) + self.clear = types.MethodType(clear, self) + self.__len__ = types.MethodType(cache_len, self) + + # argument cache for optimizing repeated calls when backtracking through recursive expressions + packrat_cache = {} # this is set later by enabledPackrat(); this is here so that resetCache() doesn't fail + packrat_cache_lock = RLock() + packrat_cache_stats = [0, 0] + + # 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 ): + HIT, MISS = 0, 1 + lookup = (self, instring, loc, callPreParse, doActions) + with ParserElement.packrat_cache_lock: + cache = ParserElement.packrat_cache + value = cache.get(lookup) + if value is cache.not_in_cache: + ParserElement.packrat_cache_stats[MISS] += 1 + try: + value = self._parseNoCache(instring, loc, doActions, callPreParse) + except ParseBaseException as pe: + # cache a copy of the exception, without the traceback + cache.set(lookup, pe.__class__(*pe.args)) + raise + else: + cache.set(lookup, (value[0], value[1].copy())) + return value + else: + ParserElement.packrat_cache_stats[HIT] += 1 + if isinstance(value, Exception): + raise value + return (value[0], value[1].copy()) + + _parse = _parseNoCache + + @staticmethod + def resetCache(): + ParserElement.packrat_cache.clear() + ParserElement.packrat_cache_stats[:] = [0] * len(ParserElement.packrat_cache_stats) + + _packratEnabled = False + @staticmethod + def enablePackrat(cache_size_limit=128): + """Enables "packrat" parsing, which adds memoizing to the parsing logic. + Repeated parse attempts at the same string location (which happens + often in many complex grammars) can immediately return a cached value, + instead of re-executing parsing/validating code. Memoizing is done of + both valid results and parsing exceptions. + + Parameters: + - cache_size_limit - (default=C{128}) - if an integer value is provided + will limit the size of the packrat cache; if None is passed, then + the cache size will be unbounded; if 0 is passed, the cache will + be effectively disabled. + + This speedup may break existing programs that use parse actions that + have side-effects. For this reason, packrat parsing is disabled when + you first import pyparsing. To activate the packrat feature, your + program must call the class method C{ParserElement.enablePackrat()}. If + your program uses C{psyco} to "compile as you go", you must call + C{enablePackrat} before calling C{psyco.full()}. If you do not do this, + Python will crash. For best results, call C{enablePackrat()} immediately + after importing pyparsing. + + Example:: + import pyparsing + pyparsing.ParserElement.enablePackrat() + """ + if not ParserElement._packratEnabled: + ParserElement._packratEnabled = True + if cache_size_limit is None: + ParserElement.packrat_cache = ParserElement._UnboundedCache() + else: + ParserElement.packrat_cache = ParserElement._FifoCache(cache_size_limit) + ParserElement._parse = ParserElement._parseCache + + 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. + + If you want the grammar to require that the entire input string be + successfully parsed, then set C{parseAll} to True (equivalent to ending + the grammar with C{L{StringEnd()}}). + + Note: C{parseString} implicitly calls C{expandtabs()} on the input string, + in order to report proper column numbers in parse actions. + If the input string contains tabs and + the grammar uses parse actions that use the C{loc} argument to index into the + string being parsed, you can ensure you have a consistent view of the input + string by: + - calling C{parseWithTabs} on your grammar before calling C{parseString} + (see L{I{parseWithTabs}<parseWithTabs>}) + - define your parse action using the full C{(s,loc,toks)} signature, and + reference the input string using the parse action's C{s} argument + - explictly expand the tabs in your input string before calling + C{parseString} + + Example:: + Word('a').parseString('aaaaabaaa') # -> ['aaaaa'] + Word('a').parseString('aaaaabaaa', parseAll=True) # -> Exception: Expected end of text + """ + ParserElement.resetCache() + if not self.streamlined: + self.streamline() + #~ self.saveAsList = True + for e in self.ignoreExprs: + e.streamline() + if not self.keepTabs: + instring = instring.expandtabs() + try: + loc, tokens = self._parse( instring, 0 ) + if parseAll: + loc = self.preParse( instring, loc ) + se = Empty() + StringEnd() + 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 + raise exc + else: + return tokens + + 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 + C{maxMatches} argument, to clip scanning after 'n' matches are found. If + C{overlap} is specified, then overlapping matches will be reported. + + Note that the start and end locations are reported relative to the string + being parsed. See L{I{parseString}<parseString>} for more information on parsing + strings with embedded tabs. + + Example:: + source = "sldjf123lsdjjkf345sldkjf879lkjsfd987" + print(source) + for tokens,start,end in Word(alphas).scanString(source): + print(' '*start + '^'*(end-start)) + print(' '*start + tokens[0]) + + prints:: + + sldjf123lsdjjkf345sldkjf879lkjsfd987 + ^^^^^ + sldjf + ^^^^^^^ + lsdjjkf + ^^^^^^ + sldkjf + ^^^^^^ + lkjsfd + """ + if not self.streamlined: + self.streamline() + for e in self.ignoreExprs: + e.streamline() + + if not self.keepTabs: + instring = _ustr(instring).expandtabs() + instrlen = len(instring) + loc = 0 + preparseFn = self.preParse + parseFn = self._parse + ParserElement.resetCache() + matches = 0 + try: + while loc <= instrlen and matches < maxMatches: + try: + preloc = preparseFn( instring, loc ) + nextLoc,tokens = parseFn( instring, preloc, callPreParse=False ) + except ParseException: + loc = preloc+1 + else: + if nextLoc > loc: + matches += 1 + yield tokens, preloc, nextLoc + if overlap: + nextloc = preparseFn( instring, loc ) + if nextloc > loc: + loc = nextLoc + else: + loc += 1 + else: + loc = nextLoc + else: + 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 + raise exc + + def transformString( self, instring ): + """ + Extension to C{L{scanString}}, to modify matching text with modified tokens that may + be returned from a parse action. To use C{transformString}, define a grammar and + attach a parse action to it that modifies the returned token list. + Invoking C{transformString()} on a target string will then scan for matches, + and replace the matched text patterns according to the logic in the parse + action. C{transformString()} returns the resulting transformed string. + + Example:: + wd = Word(alphas) + wd.setParseAction(lambda toks: toks[0].title()) + + print(wd.transformString("now is the winter of our discontent made glorious summer by this sun of york.")) + Prints:: + Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York. + """ + out = [] + lastE = 0 + # force preservation of <TAB>s, to minimize unwanted transformation of string, and to + # 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] ) + if t: + if isinstance(t,ParseResults): + out += t.asList() + 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))) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def searchString( self, instring, maxMatches=_MAX_INT ): + """ + Another extension to C{L{scanString}}, simplifying the access to the tokens found + to match the given parse expression. May be called with optional + C{maxMatches} argument, to clip searching after 'n' matches are found. + + Example:: + # a capitalized word starts with an uppercase letter, followed by zero or more lowercase letters + cap_word = Word(alphas.upper(), alphas.lower()) + + print(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity")) + + # the sum() builtin can be used to merge results into a single ParseResults object + print(sum(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity"))) + prints:: + [['More'], ['Iron'], ['Lead'], ['Gold'], ['I'], ['Electricity']] + ['More', 'Iron', 'Lead', 'Gold', 'I', 'Electricity'] + """ + try: + 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 + raise exc + + def split(self, instring, maxsplit=_MAX_INT, includeSeparators=False): + """ + Generator method to split a string using the given expression as a separator. + May be called with optional C{maxsplit} argument, to limit the number of splits; + and the optional C{includeSeparators} argument (default=C{False}), if the separating + matching text should be included in the split results. + + Example:: + punc = oneOf(list(".,;:/-!?")) + print(list(punc.split("This, this?, this sentence, is badly punctuated!"))) + prints:: + ['This', ' this', '', ' this sentence', ' is badly punctuated', ''] + """ + splits = 0 + last = 0 + 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 ): + """ + Implementation of + operator - returns C{L{And}}. Adding strings to a ParserElement + converts them to L{Literal}s by default. + + Example:: + greet = Word(alphas) + "," + Word(alphas) + "!" + hello = "Hello, World!" + print (hello, "->", greet.parseString(hello)) + 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 ): + """ + Implementation of + operator when left operand is not a C{L{ParserElement}} + """ + 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 other + self + + def __sub__(self, other): + """ + Implementation of - operator, returns C{L{And}} with error stop + """ + 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 self + And._ErrorStop() + other + + def __rsub__(self, other ): + """ + Implementation of - operator when left operand is not a C{L{ParserElement}} + """ + 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 other - self + + def __mul__(self,other): + """ + Implementation of * operator, allows use of C{expr * 3} in place of + C{expr + expr + expr}. Expressions may also me multiplied by a 2-integer + tuple, similar to C{{min,max}} multipliers in regular expressions. Tuples + may also include C{None} as in: + - C{expr*(n,None)} or C{expr*(n,)} is equivalent + to C{expr*n + L{ZeroOrMore}(expr)} + (read as "at least n instances of C{expr}") + - C{expr*(None,n)} is equivalent to C{expr*(0,n)} + (read as "0 to n instances of C{expr}") + - C{expr*(None,None)} is equivalent to C{L{ZeroOrMore}(expr)} + - C{expr*(1,None)} is equivalent to C{L{OneOrMore}(expr)} + + Note that C{expr*(None,n)} does not raise an exception if + more than n exprs exist in the input stream; that is, + C{expr*(None,n)} does not enforce a maximum number of expr + occurrences. If this behavior is desired, then write + C{expr*(None,n) + ~expr} + """ + if isinstance(other,int): + minElements, optElements = other,0 + elif isinstance(other,tuple): + 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 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): + minElements, optElements = other + optElements -= minElements + else: + 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)) + + if minElements < 0: + raise ValueError("cannot multiply ParserElement by negative value") + 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)") + + if (optElements): + def makeOptionalList(n): + 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) + else: + ret = makeOptionalList(optElements) + else: + if minElements == 1: + ret = self + else: + ret = And([self]*minElements) + return ret + + def __rmul__(self, other): + return self.__mul__(other) + + def __or__(self, other ): + """ + Implementation of | operator - returns C{L{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 ] ) + + def __ror__(self, other ): + """ + Implementation of | operator when left operand is not a C{L{ParserElement}} + """ + 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 other | self + + def __xor__(self, other ): + """ + Implementation of ^ operator - returns C{L{Or}} + """ + 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 Or( [ self, other ] ) + + def __rxor__(self, other ): + """ + Implementation of ^ operator when left operand is not a C{L{ParserElement}} + """ + 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 other ^ self + + def __and__(self, other ): + """ + Implementation of & operator - returns C{L{Each}} + """ + 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 Each( [ self, other ] ) + + def __rand__(self, other ): + """ + Implementation of & operator when left operand is not a C{L{ParserElement}} + """ + 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 other & self + + def __invert__( self ): + """ + Implementation of ~ operator - returns C{L{NotAny}} + """ + return NotAny( self ) + + def __call__(self, name=None): + """ + Shortcut for C{L{setResultsName}}, with C{listAllMatches=False}. + + If C{name} is given with a trailing C{'*'} character, then C{listAllMatches} will be + passed as C{True}. + + If C{name} is omitted, same as calling C{L{copy}}. + + Example:: + # these are equivalent + 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) + else: + return self.copy() + + def suppress( self ): + """ + Suppresses the output of this C{ParserElement}; useful to keep punctuation from + cluttering up returned output. + """ + return Suppress( self ) + + def leaveWhitespace( self ): + """ + Disables the skipping of whitespace before matching the characters in the + C{ParserElement}'s defined pattern. This is normally only used internally by + the pyparsing module, but may be needed in some whitespace-sensitive grammars. + """ + self.skipWhitespace = False + return self + + def setWhitespaceChars( self, chars ): + """ + Overrides the default whitespace chars + """ + self.skipWhitespace = True + self.whiteChars = chars + self.copyDefaultWhiteChars = False + return self + + def parseWithTabs( self ): + """ + Overrides default behavior to expand C{<TAB>}s to spaces before parsing the input string. + Must be called before C{parseString} when the input grammar contains elements that + match C{<TAB>} characters. + """ + self.keepTabs = True + return self + + 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 + ignorable patterns. + + Example:: + patt = OneOrMore(Word(alphas)) + patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj'] + + patt.ignore(cStyleComment) + patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj', 'lskjd'] + """ + if isinstance(other, basestring): + other = Suppress(other) + + if isinstance( other, Suppress ): + if other not in self.ignoreExprs: + self.ignoreExprs.append(other) + else: + self.ignoreExprs.append( Suppress( other.copy() ) ) + return self + + def setDebugActions( self, startAction, successAction, exceptionAction ): + """ + Enable display of debugging messages while doing pattern matching. + """ + self.debugActions = (startAction or _defaultStartDebugAction, + successAction or _defaultSuccessDebugAction, + exceptionAction or _defaultExceptionDebugAction) + self.debug = True + return self + + def setDebug( self, flag=True ): + """ + Enable display of debugging messages while doing pattern matching. + Set C{flag} to True to enable, False to disable. + + Example:: + wd = Word(alphas).setName("alphaword") + integer = Word(nums).setName("numword") + term = wd | integer + + # turn on debugging for wd + wd.setDebug() + + OneOrMore(term).parseString("abc 123 xyz 890") + + prints:: + Match alphaword at loc 0(1,1) + Matched alphaword -> ['abc'] + Match alphaword at loc 3(1,4) + Exception raised:Expected alphaword (at char 4), (line:1, col:5) + Match alphaword at loc 7(1,8) + Matched alphaword -> ['xyz'] + Match alphaword at loc 11(1,12) + Exception raised:Expected alphaword (at char 12), (line:1, col:13) + Match alphaword at loc 15(1,16) + Exception raised:Expected alphaword (at char 15), (line:1, col:16) + + The output shown is that produced by the default debug actions - custom debug actions can be + specified using L{setDebugActions}. Prior to attempting + to match the C{wd} expression, the debugging message C{"Match <exprname> at loc <n>(<line>,<col>)"} + is shown. Then if the parse succeeds, a C{"Matched"} message is shown, or an C{"Exception raised"} + message is shown. Also note the use of L{setName} to assign a human-readable name to the expression, + which makes debugging and exception messages easier to understand - for instance, the default + name created for the C{Word} expression without calling C{setName} is C{"W:(ABCD...)"}. + """ + if flag: + self.setDebugActions( _defaultStartDebugAction, _defaultSuccessDebugAction, _defaultExceptionDebugAction ) + else: + self.debug = False + return self + + def __str__( self ): + return self.name + + def __repr__( self ): + return _ustr(self) + + def streamline( self ): + self.streamlined = True + self.strRepr = None + return self + + def checkRecursion( self, parseElementList ): + pass + + def validate( self, validateTrace=[] ): + """ + Check defined expressions for valid structure, check for infinite recursive definitions. + """ + self.checkRecursion( [] ) + + 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), + the entire file is opened, read, and closed before parsing. + """ + try: + file_contents = file_or_filename.read() + except AttributeError: + with open(file_or_filename, "r") as f: + file_contents = f.read() + try: + return self.parseString(file_contents, parseAll) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def __eq__(self,other): + if isinstance(other, ParserElement): + return self is other or vars(self) == vars(other) + elif isinstance(other, basestring): + return self.matches(other) + else: + return super(ParserElement,self)==other + + def __ne__(self,other): + return not (self == other) + + def __hash__(self): + return hash(id(self)) + + def __req__(self,other): + return self == other + + def __rne__(self,other): + return not (self == other) + + def matches(self, testString, parseAll=True): + """ + Method for quick testing of a parser against a test string. Good for simple + inline microtests of sub expressions while building up larger parser. + + Parameters: + - testString - to test against this expression for a match + - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests + + Example:: + expr = Word(nums) + assert expr.matches("100") + """ + try: + self.parseString(_ustr(testString), parseAll=parseAll) + return True + except ParseBaseException: + return False + + def runTests(self, tests, parseAll=True, comment='#', fullDump=True, printResults=True, failureTests=False): + """ + 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 + run a parse expression against a list of sample strings. + + Parameters: + - tests - a list of separate test strings, or a multiline string of test strings + - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests + - comment - (default=C{'#'}) - expression for indicating embedded comments in the test + string; pass None to disable comment filtering + - fullDump - (default=C{True}) - dump results as list followed by results names in nested outline; + if False, only dump nested list + - printResults - (default=C{True}) prints test output to stdout + - failureTests - (default=C{False}) indicates if these tests are expected to fail parsing + + Returns: a (success, results) tuple, where success indicates that all tests succeeded + (or failed if C{failureTests} is True), and the results contain a list of lines of each + test's output + + Example:: + number_expr = pyparsing_common.number.copy() + + result = number_expr.runTests(''' + # unsigned integer + 100 + # negative integer + -100 + # float with scientific notation + 6.02e23 + # integer with scientific notation + 1e-12 + ''') + print("Success" if result[0] else "Failed!") + + result = number_expr.runTests(''' + # stray character + 100Z + # missing leading digit before '.' + -.100 + # too many '.' + 3.14.159 + ''', failureTests=True) + print("Success" if result[0] else "Failed!") + prints:: + # unsigned integer + 100 + [100] + + # negative integer + -100 + [-100] + + # float with scientific notation + 6.02e23 + [6.02e+23] + + # integer with scientific notation + 1e-12 + [1e-12] + + Success + + # stray character + 100Z + ^ + FAIL: Expected end of text (at char 3), (line:1, col:4) + + # missing leading digit before '.' + -.100 + ^ + FAIL: Expected {real number with scientific notation | real number | signed integer} (at char 0), (line:1, col:1) + + # too many '.' + 3.14.159 + ^ + FAIL: Expected end of text (at char 4), (line:1, col:5) + + Success + + Each test string must be on a single line. If you want to test a string that spans multiple + lines, create a test like this:: + + expr.runTest(r"this is a test\\n of strings that spans \\n 3 lines") + + (Note that this is a raw string literal, you must include the leading 'r'.) + """ + if isinstance(tests, basestring): + tests = list(map(str.strip, tests.rstrip().splitlines())) + if isinstance(comment, basestring): + comment = Literal(comment) + allResults = [] + comments = [] + success = True + 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] + comments = [] + try: + t = t.replace(r'\n','\n') + result = self.parseString(t, parseAll=parseAll) + out.append(result.dump(full=fullDump)) + success = success and not failureTests + 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) + else: + out.append(' '*pe.loc + '^' + fatal) + out.append("FAIL: " + str(pe)) + success = success and failureTests + result = pe + except Exception as exc: + out.append("FAIL-EXCEPTION: " + str(exc)) + success = success and failureTests + result = exc + + if printResults: + if fullDump: + out.append('') + print('\n'.join(out)) + + allResults.append((t, result)) + + return success, allResults + + +class Token(ParserElement): + """ + Abstract C{ParserElement} subclass, for defining atomic matching patterns. + """ + 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__() + self.name = "Empty" + self.mayReturnEmpty = True + self.mayIndexError = False + + +class NoMatch(Token): + """ + A token that will never match. + """ + 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 ): + raise ParseException(instring, loc, self.errmsg, self) + + +class Literal(Token): + """ + Token to exactly match a specified string. + + Example:: + Literal('blah').parseString('blah') # -> ['blah'] + Literal('blah').parseString('blahfooblah') # -> ['blah'] + Literal('blah').parseString('bla') # -> Exception: Expected "blah" + + For case-insensitive matching, use L{CaselessLiteral}. + + For keyword matching (force word break before and after the matched string), + use L{Keyword} or L{CaselessKeyword}. + """ + def __init__( self, matchString ): + super(Literal,self).__init__() + self.match = matchString + self.matchLen = len(matchString) + try: + self.firstMatchChar = matchString[0] + except IndexError: + warnings.warn("null string passed to Literal; use Empty() instead", + SyntaxWarning, stacklevel=2) + self.__class__ = Empty + self.name = '"%s"' % _ustr(self.match) + self.errmsg = "Expected " + self.name + 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 + raise ParseException(instring, loc, self.errmsg, self) +_L = Literal +ParserElement._literalStringClass = Literal + +class Keyword(Token): + """ + Token to exactly match a specified string as a keyword, that is, it must be + immediately followed by a non-keyword character. Compare with C{L{Literal}}: + - C{Literal("if")} will match the leading C{'if'} in C{'ifAndOnlyIf'}. + - C{Keyword("if")} will not; it will only match the leading C{'if'} in C{'if x=1'}, or C{'if(y==2)'} + Accepts two optional constructor arguments in addition to the keyword string: + - C{identChars} is a string of characters that would be valid identifier characters, + defaulting to all alphanumerics + "_" and "$" + - C{caseless} allows case-insensitive matching, default is C{False}. + + Example:: + Keyword("start").parseString("start") # -> ['start'] + Keyword("start").parseString("starting") # -> Exception + + For case-insensitive matching, use L{CaselessKeyword}. + """ + DEFAULT_KEYWORD_CHARS = alphanums+"_$" + + def __init__( self, matchString, identChars=None, caseless=False ): + super(Keyword,self).__init__() + if identChars is None: + identChars = Keyword.DEFAULT_KEYWORD_CHARS + self.match = matchString + self.matchLen = len(matchString) + try: + self.firstMatchChar = matchString[0] + except IndexError: + warnings.warn("null string passed to Keyword; use Empty() instead", + SyntaxWarning, stacklevel=2) + self.name = '"%s"' % self.match + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = False + self.mayIndexError = False + self.caseless = caseless + if caseless: + self.caselessmatch = matchString.upper() + identChars = identChars.upper() + self.identChars = set(identChars) + + 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 + 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 + raise ParseException(instring, loc, self.errmsg, self) + + def copy(self): + c = super(Keyword,self).copy() + c.identChars = Keyword.DEFAULT_KEYWORD_CHARS + return c + + @staticmethod + def setDefaultKeywordChars( chars ): + """Overrides the default Keyword chars + """ + Keyword.DEFAULT_KEYWORD_CHARS = chars + +class CaselessLiteral(Literal): + """ + Token to match a specified string, ignoring case of letters. + Note: the matched results will always be in the case of the given + match string, NOT the case of the input text. + + Example:: + OneOrMore(CaselessLiteral("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD', 'CMD'] + + (Contrast with example for L{CaselessKeyword}.) + """ + 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 + raise ParseException(instring, loc, self.errmsg, self) + +class CaselessKeyword(Keyword): + """ + Caseless version of L{Keyword}. + + Example:: + OneOrMore(CaselessKeyword("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD'] + + (Contrast with example for L{CaselessLiteral}.) + """ + def __init__( self, matchString, identChars=None ): + super(CaselessKeyword,self).__init__( matchString, identChars, caseless=True ) + + def parseImpl( self, instring, loc, doActions=True ): + 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) ): + return loc+self.matchLen, self.match + raise ParseException(instring, loc, self.errmsg, self) + +class CloseMatch(Token): + """ + A variation on L{Literal} which matches "close" matches, that is, + strings with at most 'n' mismatching characters. C{CloseMatch} takes parameters: + - C{match_string} - string to be matched + - C{maxMismatches} - (C{default=1}) maximum number of mismatches allowed to count as a match + + The results from a successful parse will contain the matched text from the input string and the following named results: + - C{mismatches} - a list of the positions within the match_string where mismatches were found + - C{original} - the original match_string used to compare against the input string + + If C{mismatches} is an empty list, then the match was an exact match. + + Example:: + patt = CloseMatch("ATCATCGAATGGA") + patt.parseString("ATCATCGAAXGGA") # -> (['ATCATCGAAXGGA'], {'mismatches': [[9]], 'original': ['ATCATCGAATGGA']}) + patt.parseString("ATCAXCGAAXGGA") # -> Exception: Expected 'ATCATCGAATGGA' (with up to 1 mismatches) (at char 0), (line:1, col:1) + + # exact match + patt.parseString("ATCATCGAATGGA") # -> (['ATCATCGAATGGA'], {'mismatches': [[]], 'original': ['ATCATCGAATGGA']}) + + # close match allowing up to 2 mismatches + patt = CloseMatch("ATCATCGAATGGA", maxMismatches=2) + patt.parseString("ATCAXCGAAXGGA") # -> (['ATCAXCGAAXGGA'], {'mismatches': [[4, 9]], 'original': ['ATCATCGAATGGA']}) + """ + def __init__(self, match_string, maxMismatches=1): + super(CloseMatch,self).__init__() + self.name = match_string + self.match_string = match_string + self.maxMismatches = maxMismatches + self.errmsg = "Expected %r (with up to %d mismatches)" % (self.match_string, self.maxMismatches) + self.mayIndexError = False + self.mayReturnEmpty = False + + def parseImpl( self, instring, loc, doActions=True ): + start = loc + instrlen = len(instring) + maxloc = start + len(self.match_string) + + if maxloc <= instrlen: + match_string = self.match_string + match_stringloc = 0 + mismatches = [] + maxMismatches = self.maxMismatches + + for match_stringloc,s_m in enumerate(zip(instring[loc:maxloc], self.match_string)): + src,mat = s_m + if src != mat: + mismatches.append(match_stringloc) + if len(mismatches) > maxMismatches: + break + else: + loc = match_stringloc + 1 + results = ParseResults([instring[start:loc]]) + results['original'] = self.match_string + results['mismatches'] = mismatches + return loc, results + + raise ParseException(instring, loc, self.errmsg, self) + + +class Word(Token): + """ + Token for matching words composed of allowed character sets. + Defined with string containing all allowed initial characters, + an optional string containing allowed body characters (if omitted, + defaults to the initial character set), and an optional minimum, + maximum, and/or exact length. The default value for C{min} is 1 (a + minimum value < 1 is not valid); the default values for C{max} and C{exact} + are 0, meaning no maximum or exact length restriction. An optional + C{excludeChars} parameter can list characters that might be found in + the input C{bodyChars} string; useful to define a word of all printables + except for one or two characters, for instance. + + L{srange} is useful for defining custom character set strings for defining + C{Word} expressions, using range notation from regular expression character sets. + + A common mistake is to use C{Word} to match a specific literal string, as in + C{Word("Address")}. Remember that C{Word} uses the string argument to define + I{sets} of matchable characters. This expression would match "Add", "AAA", + "dAred", or any other word made up of the characters 'A', 'd', 'r', 'e', and 's'. + To match an exact literal string, use L{Literal} or L{Keyword}. + + pyparsing includes helper strings for building Words: + - L{alphas} + - L{nums} + - L{alphanums} + - L{hexnums} + - L{alphas8bit} (alphabetic characters in ASCII range 128-255 - accented, tilded, umlauted, etc.) + - L{punc8bit} (non-alphabetic characters in ASCII range 128-255 - currency, symbols, superscripts, diacriticals, etc.) + - L{printables} (any non-whitespace character) + + Example:: + # a word composed of digits + integer = Word(nums) # equivalent to Word("0123456789") or Word(srange("0-9")) + + # a word with a leading capital, and zero or more lowercase + capital_word = Word(alphas.upper(), alphas.lower()) + + # hostnames are alphanumeric, with leading alpha, and '-' + hostname = Word(alphas, alphanums+'-') + + # roman numeral (not a strict parser, accepts invalid mix of characters) + roman = Word("IVXLCDM") + + # 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__() + if excludeChars: + initChars = ''.join(c for c in initChars if c not in excludeChars) + if bodyChars: + bodyChars = ''.join(c for c in bodyChars if c not in excludeChars) + self.initCharsOrig = initChars + self.initChars = set(initChars) + if bodyChars : + self.bodyCharsOrig = bodyChars + self.bodyChars = set(bodyChars) + else: + self.bodyCharsOrig = initChars + self.bodyChars = set(initChars) + + self.maxSpecified = max > 0 + + if min < 1: + raise ValueError("cannot specify a minimum length < 1; use Optional(Word()) if zero-length word is permitted") + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayIndexError = False + self.asKeyword = asKeyword + + 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),) + else: + self.reString = "[%s][%s]*" % \ + (_escapeRegexRangeChars(self.initCharsOrig), + _escapeRegexRangeChars(self.bodyCharsOrig),) + if self.asKeyword: + self.reString = r"\b"+self.reString+r"\b" + try: + self.re = re.compile( self.reString ) + except Exception: + self.re = None + + 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() + + if not(instring[ loc ] in self.initChars): + raise ParseException(instring, loc, self.errmsg, self) + + start = loc + loc += 1 + instrlen = len(instring) + bodychars = self.bodyChars + maxloc = start + self.maxLen + maxloc = min( maxloc, instrlen ) + while loc < maxloc and instring[loc] in bodychars: + loc += 1 + + throwException = False + if loc - start < self.minLen: + throwException = True + if self.maxSpecified and loc < instrlen and instring[loc] in bodychars: + throwException = True + if self.asKeyword: + if (start>0 and instring[start-1] in bodychars) or (loc<instrlen and instring[loc] in bodychars): + throwException = True + + if throwException: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + def __str__( self ): + try: + return super(Word,self).__str__() + except Exception: + pass + + + if self.strRepr is None: + + def charsAsStr(s): + 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) ) + else: + self.strRepr = "W:(%s)" % charsAsStr(self.initCharsOrig) + + return self.strRepr + + +class Regex(Token): + r""" + Token for matching strings that match a given regular expression. + Defined with string specifying the regular expression in a form recognized by the inbuilt Python re module. + If the given regex contains named groups (defined using C{(?P<name>...)}), these will be preserved as + named parse results. + + Example:: + realnum = Regex(r"[+-]?\d+\.\d*") + date = Regex(r'(?P<year>\d{4})-(?P<month>\d\d?)-(?P<day>\d\d?)') + # ref: http://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?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})") + """ + compiledREtype = type(re.compile("[A-Z]")) + def __init__( self, pattern, flags=0): + """The parameters C{pattern} and C{flags} are passed to the C{re.compile()} function as-is. See the Python C{re} module for an explanation of the acceptable patterns and flags.""" + super(Regex,self).__init__() + + if isinstance(pattern, basestring): + if not pattern: + warnings.warn("null string passed to Regex; use Empty() instead", + SyntaxWarning, stacklevel=2) + + self.pattern = pattern + self.flags = flags + + try: + self.re = re.compile(self.pattern, self.flags) + self.reString = self.pattern + except sre_constants.error: + warnings.warn("invalid pattern (%s) passed to Regex" % pattern, + SyntaxWarning, stacklevel=2) + raise + + elif isinstance(pattern, Regex.compiledREtype): + self.re = pattern + self.pattern = \ + self.reString = str(pattern) + self.flags = flags + + else: + raise ValueError("Regex may only be constructed with a string or a compiled RE object") + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayIndexError = False + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + result = self.re.match(instring,loc) + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + d = result.groupdict() + ret = ParseResults(result.group()) + if d: + for k in d: + ret[k] = d[k] + return loc,ret + + def __str__( self ): + try: + return super(Regex,self).__str__() + except Exception: + pass + + if self.strRepr is None: + self.strRepr = "Re:(%s)" % repr(self.pattern) + + return self.strRepr + + +class QuotedString(Token): + r""" + Token for matching strings that are delimited by quoting characters. + + Defined with the following parameters: + - quoteChar - string of one or more characters defining the quote delimiting string + - escChar - character to escape quotes, typically backslash (default=C{None}) + - escQuote - special quote sequence to escape an embedded quote string (such as SQL's "" to escape an embedded ") (default=C{None}) + - multiline - boolean indicating whether quotes can span multiple lines (default=C{False}) + - unquoteResults - boolean indicating whether the matched text should be unquoted (default=C{True}) + - endQuoteChar - string of one or more characters defining the end of the quote delimited string (default=C{None} => same as quoteChar) + - convertWhitespaceEscapes - convert escaped whitespace (C{'\t'}, C{'\n'}, etc.) to actual whitespace (default=C{True}) + + Example:: + qs = QuotedString('"') + print(qs.searchString('lsjdf "This is the quote" sldjf')) + complex_qs = QuotedString('{{', endQuoteChar='}}') + print(complex_qs.searchString('lsjdf {{This is the "quote"}} sldjf')) + sql_qs = QuotedString('"', escQuote='""') + print(sql_qs.searchString('lsjdf "This is the quote with ""embedded"" quotes" sldjf')) + prints:: + [['This is the quote']] + [['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__() + + # 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) + raise SyntaxError() + + if endQuoteChar is None: + endQuoteChar = quoteChar + else: + endQuoteChar = endQuoteChar.strip() + if not endQuoteChar: + warnings.warn("endQuoteChar cannot be the empty string",SyntaxWarning,stacklevel=2) + raise SyntaxError() + + self.quoteChar = quoteChar + self.quoteCharLen = len(quoteChar) + self.firstQuoteChar = quoteChar[0] + self.endQuoteChar = endQuoteChar + self.endQuoteCharLen = len(endQuoteChar) + self.escChar = escChar + self.escQuote = escQuote + self.unquoteResults = unquoteResults + self.convertWhitespaceEscapes = convertWhitespaceEscapes + + 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 '') ) + 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 '') ) + 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)) + ')' + ) + 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.pattern += (r')*%s' % re.escape(self.endQuoteChar)) + + try: + self.re = re.compile(self.pattern, self.flags) + self.reString = self.pattern + except sre_constants.error: + warnings.warn("invalid pattern (%s) passed to Regex" % self.pattern, + SyntaxWarning, stacklevel=2) + raise + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + 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 + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + ret = result.group() + + if self.unquoteResults: + + # strip off quotes + ret = ret[self.quoteCharLen:-self.endQuoteCharLen] + + 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', + } + for wslit,wschar in ws_map.items(): + ret = ret.replace(wslit, wschar) + + # replace escaped characters + if self.escChar: + ret = re.sub(self.escCharReplacePattern, r"\g<1>", ret) + + # replace escaped quotes + if self.escQuote: + ret = ret.replace(self.escQuote, self.endQuoteChar) + + return loc, ret + + def __str__( self ): + try: + return super(QuotedString,self).__str__() + except Exception: + pass + + if self.strRepr is None: + self.strRepr = "quoted string, starting with %s ending with %s" % (self.quoteChar, self.endQuoteChar) + + return self.strRepr + + +class CharsNotIn(Token): + """ + Token for matching words composed of characters I{not} in a given set (will + include whitespace in matched characters if not listed in the provided exclusion set - see example). + Defined with string containing all disallowed characters, and an optional + minimum, maximum, and/or exact length. The default value for C{min} is 1 (a + minimum value < 1 is not valid); the default values for C{max} and C{exact} + are 0, meaning no maximum or exact length restriction. + + Example:: + # define a comma-separated-value as anything that is not a ',' + csv_value = CharsNotIn(',') + print(delimitedList(csv_value).parseString("dkls,lsdkjf,s12 34,@!#,213")) + prints:: + ['dkls', 'lsdkjf', 's12 34', '@!#', '213'] + """ + 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") + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = ( self.minLen == 0 ) + self.mayIndexError = False + + 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): + loc += 1 + + if loc - start < self.minLen: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + def __str__( self ): + try: + return super(CharsNotIn, self).__str__() + except Exception: + pass + + if self.strRepr is None: + if len(self.notChars) > 4: + self.strRepr = "!W:(%s...)" % self.notChars[:4] + else: + self.strRepr = "!W:(%s)" % self.notChars + + return self.strRepr + +class White(Token): + """ + Special matching class for matching whitespace. Normally, whitespace is ignored + by pyparsing grammars. This class is included when some whitespace structures + are significant. Define with a string containing the whitespace characters to be + matched; default is C{" \\t\\r\\n"}. Also takes optional C{min}, C{max}, and C{exact} arguments, + as defined for the C{L{Word}} class. + """ + whiteStrs = { + " " : "<SPC>", + "\t": "<TAB>", + "\n": "<LF>", + "\r": "<CR>", + "\f": "<FF>", + } + def __init__(self, ws=" \t\r\n", min=1, max=0, exact=0): + 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.name = ("".join(White.whiteStrs[c] for c in self.matchWhite)) + self.mayReturnEmpty = True + self.errmsg = "Expected " + self.name + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + def parseImpl( self, instring, loc, doActions=True ): + if not(instring[ loc ] in self.matchWhite): + raise ParseException(instring, loc, self.errmsg, self) + start = loc + loc += 1 + maxloc = start + self.maxLen + maxloc = min( maxloc, len(instring) ) + while loc < maxloc and instring[loc] in self.matchWhite: + loc += 1 + + if loc - start < self.minLen: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + +class _PositionToken(Token): + def __init__( self ): + super(_PositionToken,self).__init__() + self.name=self.__class__.__name__ + self.mayReturnEmpty = True + self.mayIndexError = False + +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__() + self.col = colno + + 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 += 1 + return loc + + 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 ) + newloc = loc + self.col - thiscol + ret = instring[ loc: newloc ] + return newloc, ret + + +class LineStart(_PositionToken): + """ + Matches if current position is at the beginning of a line within the parse string + + Example:: + + test = '''\ + AAA this line + AAA and this line + AAA but not this one + B AAA and definitely not this one + ''' + + for t in (LineStart() + 'AAA' + restOfLine).searchString(test): + print(t) + + Prints:: + ['AAA', ' this line'] + ['AAA', ' and this line'] + + """ + def __init__( self ): + super(LineStart,self).__init__() + self.errmsg = "Expected start of line" + + def parseImpl( self, instring, loc, doActions=True ): + if col(loc, instring) == 1: + return loc, [] + raise ParseException(instring, loc, self.errmsg, self) + +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","") ) + self.errmsg = "Expected end of line" + + def parseImpl( self, instring, loc, doActions=True ): + if loc<len(instring): + if instring[loc] == "\n": + return loc+1, "\n" + else: + raise ParseException(instring, loc, self.errmsg, self) + elif loc == len(instring): + return loc+1, [] + else: + raise ParseException(instring, loc, self.errmsg, self) + +class StringStart(_PositionToken): + """ + Matches if current position is at the beginning of the parse string + """ + def __init__( self ): + super(StringStart,self).__init__() + self.errmsg = "Expected start of text" + + 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 ): + 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__() + self.errmsg = "Expected end of text" + + 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, [] + elif loc > len(instring): + return loc, [] + else: + raise ParseException(instring, loc, self.errmsg, self) + +class WordStart(_PositionToken): + """ + Matches if the current position is at the beginning of a Word, and + is not preceded by any character in a given set of C{wordChars} + (default=C{printables}). To emulate the C{\b} behavior of regular expressions, + use C{WordStart(alphanums)}. C{WordStart} will also match at the beginning of + the string being parsed, or at the beginning of a line. + """ + 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 ): + if loc != 0: + if (instring[loc-1] in self.wordChars or + instring[loc] not in self.wordChars): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + +class WordEnd(_PositionToken): + """ + Matches if the current position is at the end of a Word, and + is not followed by any character in a given set of C{wordChars} + (default=C{printables}). To emulate the C{\b} behavior of regular expressions, + use C{WordEnd(alphanums)}. C{WordEnd} 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__() + self.wordChars = set(wordChars) + self.skipWhitespace = False + self.errmsg = "Not at the end of a word" + + def parseImpl(self, instring, loc, doActions=True ): + instrlen = len(instring) + if instrlen>0 and loc<instrlen: + if (instring[loc] in self.wordChars or + instring[loc-1] not in self.wordChars): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + + +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 ): + exprs = list(exprs) + + if isinstance( exprs, basestring ): + self.exprs = [ ParserElement._literalStringClass( 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) + self.exprs = list(exprs) + else: + try: + self.exprs = list( exprs ) + except TypeError: + self.exprs = [ exprs ] + self.callPreparse = False + + def __getitem__( self, i ): + return self.exprs[i] + + def append( self, other ): + self.exprs.append( other ) + self.strRepr = None + return self + + def leaveWhitespace( self ): + """Extends C{leaveWhitespace} defined in base class, and also invokes C{leaveWhitespace} on + all contained expressions.""" + self.skipWhitespace = False + 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 ): + if other not in self.ignoreExprs: + super( ParseExpression, self).ignore( other ) + for e in self.exprs: + e.ignore( self.ignoreExprs[-1] ) + else: + super( ParseExpression, self).ignore( other ) + for e in self.exprs: + e.ignore( self.ignoreExprs[-1] ) + return self + + def __str__( self ): + try: + return super(ParseExpression,self).__str__() + except Exception: + pass + + if self.strRepr is None: + self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.exprs) ) + return self.strRepr + + 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 ) + # 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 ): + 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] ] + 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 ): + self.exprs = self.exprs[:-1] + other.exprs[:] + self.strRepr = None + self.mayReturnEmpty |= other.mayReturnEmpty + self.mayIndexError |= other.mayIndexError + + self.errmsg = "Expected " + _ustr(self) + + return self + + def setResultsName( self, name, listAllMatches=False ): + ret = super(ParseExpression,self).setResultsName(name,listAllMatches) + return ret + + def validate( self, validateTrace=[] ): + tmp = validateTrace[:]+[self] + for e in self.exprs: + e.validate(tmp) + self.checkRecursion( [] ) + + def copy(self): + ret = super(ParseExpression,self).copy() + ret.exprs = [e.copy() for e in self.exprs] + return ret + +class And(ParseExpression): + """ + Requires all given C{ParseExpression}s to be found in the given order. + Expressions may be separated by whitespace. + May be constructed using the C{'+'} operator. + May also be constructed using the C{'-'} operator, which will suppress backtracking. + + Example:: + integer = Word(nums) + name_expr = OneOrMore(Word(alphas)) + + 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) + self.name = '-' + self.leaveWhitespace() + + def __init__( self, exprs, savelist = True ): + super(And,self).__init__(exprs, savelist) + self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) + self.setWhitespaceChars( self.exprs[0].whiteChars ) + self.skipWhitespace = self.exprs[0].skipWhitespace + self.callPreparse = 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 ) + errorStop = False + for e in self.exprs[1:]: + if isinstance(e, And._ErrorStop): + errorStop = True + continue + if errorStop: + try: + loc, exprtokens = e._parse( instring, loc, doActions ) + except ParseSyntaxException: + raise + except ParseBaseException as pe: + pe.__traceback__ = None + raise ParseSyntaxException._from_exception(pe) + except IndexError: + raise ParseSyntaxException(instring, len(instring), self.errmsg, self) + else: + 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 checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + if not e.mayReturnEmpty: + break + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + +class Or(ParseExpression): + """ + Requires that at least one C{ParseExpression} is found. + If two expressions match, the expression that matches the longest string will be used. + May be constructed using the C{'^'} operator. + + Example:: + # construct Or using '^' operator + + number = Word(nums) ^ Combine(Word(nums) + '.' + Word(nums)) + print(number.searchString("123 3.1416 789")) + prints:: + [['123'], ['3.1416'], ['789']] + """ + 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: + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + maxExcLoc = -1 + maxException = None + matches = [] + for e in self.exprs: + try: + loc2 = e.tryParse( instring, loc ) + except ParseException as err: + err.__traceback__ = None + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + except IndexError: + if len(instring) > maxExcLoc: + 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: + try: + return e._parse( instring, loc, doActions ) + except ParseException as err: + err.__traceback__ = None + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + + if maxException is not None: + maxException.msg = self.errmsg + raise maxException + else: + 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 __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " ^ ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class MatchFirst(ParseExpression): + """ + Requires that at least one C{ParseExpression} is found. + If two expressions match, the first one listed is the one that will match. + May be constructed using the C{'|'} operator. + + Example:: + # construct MatchFirst using '|' operator + + # watch the order of expressions to match + number = Word(nums) | Combine(Word(nums) + '.' + Word(nums)) + print(number.searchString("123 3.1416 789")) # Fail! -> [['123'], ['3'], ['1416'], ['789']] + + # put more selective expression first + 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) + if self.exprs: + self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs) + else: + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + maxExcLoc = -1 + maxException = None + for e in self.exprs: + try: + ret = e._parse( instring, loc, doActions ) + return ret + except ParseException as err: + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + except IndexError: + if len(instring) > maxExcLoc: + 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 + else: + if maxException is not None: + maxException.msg = self.errmsg + raise maxException + 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 __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " | ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class Each(ParseExpression): + """ + Requires all given C{ParseExpression}s to be found, but in any order. + Expressions may be separated by whitespace. + May be constructed using the C{'&'} operator. + + Example:: + color = oneOf("RED ORANGE YELLOW GREEN BLUE PURPLE BLACK WHITE BROWN") + shape_type = oneOf("SQUARE CIRCLE TRIANGLE STAR HEXAGON OCTAGON") + integer = Word(nums) + shape_attr = "shape:" + shape_type("shape") + posn_attr = "posn:" + Group(integer("x") + ',' + integer("y"))("posn") + color_attr = "color:" + color("color") + size_attr = "size:" + integer("size") + + # use Each (using operator '&') to accept attributes in any order + # (shape and posn are required, color and size are optional) + shape_spec = shape_attr & posn_attr & Optional(color_attr) & Optional(size_attr) + + shape_spec.runTests(''' + shape: SQUARE color: BLACK posn: 100, 120 + shape: CIRCLE size: 50 color: BLUE posn: 50,80 + color:GREEN size:20 shape:TRIANGLE posn:20,40 + ''' + ) + prints:: + shape: SQUARE color: BLACK posn: 100, 120 + ['shape:', 'SQUARE', 'color:', 'BLACK', 'posn:', ['100', ',', '120']] + - color: BLACK + - posn: ['100', ',', '120'] + - x: 100 + - y: 120 + - shape: SQUARE + + + shape: CIRCLE size: 50 color: BLUE posn: 50,80 + ['shape:', 'CIRCLE', 'size:', '50', 'color:', 'BLUE', 'posn:', ['50', ',', '80']] + - color: BLUE + - posn: ['50', ',', '80'] + - x: 50 + - y: 80 + - shape: CIRCLE + - size: 50 + + + color: GREEN size: 20 shape: TRIANGLE posn: 20,40 + ['color:', 'GREEN', 'size:', '20', 'shape:', 'TRIANGLE', 'posn:', ['20', ',', '40']] + - color: GREEN + - posn: ['20', ',', '40'] + - x: 20 + - y: 40 + - shape: TRIANGLE + - size: 20 + """ + 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 + + 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.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.required += self.multirequired + self.initExprGroups = False + tmpLoc = loc + tmpReqd = self.required[:] + tmpOpt = self.optionals[:] + matchOrder = [] + + keepMatching = True + while keepMatching: + tmpExprs = tmpReqd + tmpOpt + self.multioptionals + self.multirequired + failed = [] + for e in tmpExprs: + try: + tmpLoc = e.tryParse( instring, tmpLoc ) + except ParseException: + failed.append(e) + else: + matchOrder.append(self.opt1map.get(id(e),e)) + if e in tmpReqd: + tmpReqd.remove(e) + elif e in tmpOpt: + tmpOpt.remove(e) + if len(failed) == len(tmpExprs): + keepMatching = False + + if tmpReqd: + missing = ", ".join(_ustr(e) for e in tmpReqd) + 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] + + resultlist = [] + for e in matchOrder: + loc,results = e._parse(instring,loc,doActions) + resultlist.append(results) + + finalResults = sum(resultlist, ParseResults([])) + return loc, finalResults + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " & ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class ParseElementEnhance(ParserElement): + """ + Abstract subclass of C{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) + else: + expr = ParserElement._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.skipWhitespace = expr.skipWhitespace + self.saveAsList = expr.saveAsList + self.callPreparse = expr.callPreparse + self.ignoreExprs.extend(expr.ignoreExprs) + + def parseImpl( self, instring, loc, doActions=True ): + if self.expr is not None: + return self.expr._parse( instring, loc, doActions, callPreParse=False ) + else: + raise ParseException("",loc,self.errmsg,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 ): + if other not in self.ignoreExprs: + super( ParseElementEnhance, self).ignore( other ) + if self.expr is not None: + self.expr.ignore( self.ignoreExprs[-1] ) + else: + super( ParseElementEnhance, self).ignore( other ) + if self.expr is not None: + self.expr.ignore( self.ignoreExprs[-1] ) + return self + + def streamline( self ): + super(ParseElementEnhance,self).streamline() + if self.expr is not None: + self.expr.streamline() + return self + + def checkRecursion( self, parseElementList ): + if self in parseElementList: + raise RecursiveGrammarException( parseElementList+[self] ) + subRecCheckList = parseElementList[:] + [ self ] + if self.expr is not None: + self.expr.checkRecursion( subRecCheckList ) + + def validate( self, validateTrace=[] ): + tmp = validateTrace[:]+[self] + if self.expr is not None: + self.expr.validate(tmp) + self.checkRecursion( [] ) + + def __str__( self ): + try: + 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) ) + return self.strRepr + + +class FollowedBy(ParseElementEnhance): + """ + Lookahead matching of the given parse expression. C{FollowedBy} + does I{not} advance the parsing position within the input string, it only + verifies that the specified parse expression matches at the current + position. C{FollowedBy} always returns a null token list. + + Example:: + # use FollowedBy to match a label only if it is followed by a ':' + data_word = Word(alphas) + label = data_word + FollowedBy(':') + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + + OneOrMore(attr_expr).parseString("shape: SQUARE color: BLACK posn: upper left").pprint() + prints:: + [['shape', 'SQUARE'], ['color', 'BLACK'], ['posn', 'upper left']] + """ + def __init__( self, expr ): + super(FollowedBy,self).__init__(expr) + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + self.expr.tryParse( instring, loc ) + return loc, [] + + +class NotAny(ParseElementEnhance): + """ + Lookahead to disallow matching with the given parse expression. C{NotAny} + does I{not} advance the parsing position within the input string, it only + verifies that the specified parse expression does I{not} match at the current + position. Also, C{NotAny} does I{not} skip over leading whitespace. C{NotAny} + always returns a null token list. May be constructed using the '~' operator. + + Example:: + + """ + 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) + + 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"): + return self.name + + if self.strRepr is None: + self.strRepr = "~{" + _ustr(self.expr) + "}" + + return self.strRepr + +class _MultipleMatch(ParseElementEnhance): + 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 + + 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 + if check_ender: + try_not_ender = self.not_ender.tryParse + + # must be at least one (but first see if we are the stopOn sentinel; + # if so, fail) + if check_ender: + try_not_ender(instring, loc) + 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 ) + else: + preloc = loc + loc, tmptokens = self_expr_parse( instring, preloc, doActions ) + if tmptokens or tmptokens.haskeys(): + tokens += tmptokens + except (ParseException,IndexError): + pass + + return loc, tokens + +class OneOrMore(_MultipleMatch): + """ + Repetition of one or more of the given expression. + + Parameters: + - expr - expression that must match one or more times + - stopOn - (default=C{None}) - expression for a terminating sentinel + (only required if the sentinel would ordinarily match the repetition + expression) + + Example:: + data_word = Word(alphas) + label = data_word + FollowedBy(':') + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join)) + + text = "shape: SQUARE posn: upper left color: BLACK" + OneOrMore(attr_expr).parseString(text).pprint() # Fail! read 'color' as data instead of next label -> [['shape', 'SQUARE color']] + + # use stopOn attribute for OneOrMore to avoid reading label string as part of the data + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + OneOrMore(attr_expr).parseString(text).pprint() # Better -> [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'BLACK']] + + # could also be written as + (attr_expr * (1,)).parseString(text).pprint() + """ + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + _ustr(self.expr) + "}..." + + return self.strRepr + +class ZeroOrMore(_MultipleMatch): + """ + Optional repetition of zero or more of the given expression. + + Parameters: + - expr - expression that must match zero or more times + - stopOn - (default=C{None}) - expression for a terminating sentinel + (only required if the sentinel would ordinarily match the repetition + expression) + + Example: similar to L{OneOrMore} + """ + def __init__( self, expr, stopOn=None): + super(ZeroOrMore,self).__init__(expr, stopOn=stopOn) + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + try: + return super(ZeroOrMore, self).parseImpl(instring, loc, doActions) + except (ParseException,IndexError): + return loc, [] + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "[" + _ustr(self.expr) + "]..." + + return self.strRepr + +class _NullToken(object): + def __bool__(self): + return False + __nonzero__ = __bool__ + def __str__(self): + return "" + +_optionalNotMatched = _NullToken() +class Optional(ParseElementEnhance): + """ + Optional matching of the given expression. + + Parameters: + - expr - expression that must match zero or more times + - default (optional) - value to be returned if the optional expression is not found. + + Example:: + # US postal code can be a 5-digit zip, plus optional 4-digit qualifier + zip = Combine(Word(nums, exact=5) + Optional('-' + Word(nums, exact=4))) + zip.runTests(''' + # traditional ZIP code + 12345 + + # ZIP+4 form + 12101-0001 + + # invalid ZIP + 98765- + ''') + prints:: + # traditional ZIP code + 12345 + ['12345'] + + # ZIP+4 form + 12101-0001 + ['12101-0001'] + + # invalid ZIP + 98765- + ^ + 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 ) + self.saveAsList = self.expr.saveAsList + self.defaultValue = default + self.mayReturnEmpty = 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: + if self.expr.resultsName: + tokens = ParseResults([ self.defaultValue ]) + tokens[self.expr.resultsName] = self.defaultValue + else: + tokens = [ self.defaultValue ] + else: + tokens = [] + return loc, tokens + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "[" + _ustr(self.expr) + "]" + + return self.strRepr + +class SkipTo(ParseElementEnhance): + """ + Token for skipping over all undefined text until the matched expression is found. + + Parameters: + - expr - target expression marking the end of the data to be skipped + - include - (default=C{False}) if True, the target expression is also parsed + (the skipped text and target expression are returned as a 2-element list). + - ignore - (default=C{None}) used to define grammars (typically quoted strings and + comments) that might contain false matches to the target expression + - failOn - (default=C{None}) define expressions that are not allowed to be + included in the skipped test; if found before the target expression is found, + the SkipTo is not a match + + Example:: + report = ''' + Outstanding Issues Report - 1 Jan 2000 + + # | Severity | Description | Days Open + -----+----------+-------------------------------------------+----------- + 101 | Critical | Intermittent system crash | 6 + 94 | Cosmetic | Spelling error on Login ('log|n') | 14 + 79 | Minor | System slow when running too many reports | 47 + ''' + integer = Word(nums) + SEP = Suppress('|') + # use SkipTo to simply match everything up until the next SEP + # - ignore quoted strings, so that a '|' character inside a quoted string does not match + # - parse action will call token.strip() for each matched token, i.e., the description body + string_data = SkipTo(SEP, ignore=quotedString) + string_data.setParseAction(tokenMap(str.strip)) + ticket_expr = (integer("issue_num") + SEP + + string_data("sev") + SEP + + string_data("desc") + SEP + + integer("days_open")) + + for tkt in ticket_expr.searchString(report): + print tkt.dump() + prints:: + ['101', 'Critical', 'Intermittent system crash', '6'] + - days_open: 6 + - desc: Intermittent system crash + - issue_num: 101 + - sev: Critical + ['94', 'Cosmetic', "Spelling error on Login ('log|n')", '14'] + - days_open: 14 + - desc: Spelling error on Login ('log|n') + - issue_num: 94 + - sev: Cosmetic + ['79', 'Minor', 'System slow when running too many reports', '47'] + - days_open: 47 + - desc: System slow when running too many reports + - issue_num: 79 + - sev: Minor + """ + 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.asList = False + if isinstance(failOn, basestring): + self.failOn = ParserElement._literalStringClass(failOn) + else: + self.failOn = failOn + self.errmsg = "No match found for "+_ustr(self.expr) + + def parseImpl( self, instring, loc, doActions=True ): + startloc = loc + instrlen = len(instring) + expr = self.expr + expr_parse = self.expr._parse + self_failOn_canParseNext = self.failOn.canParseNext if self.failOn is not None else None + self_ignoreExpr_tryParse = self.ignoreExpr.tryParse if self.ignoreExpr is not None else None + + tmploc = loc + while tmploc <= instrlen: + if self_failOn_canParseNext is not None: + # break if failOn expression matches + if self_failOn_canParseNext(instring, tmploc): + break + + if self_ignoreExpr_tryParse is not None: + # advance past ignore expressions + while 1: + try: + tmploc = self_ignoreExpr_tryParse(instring, tmploc) + except ParseBaseException: + break + + try: + expr_parse(instring, tmploc, doActions=False, callPreParse=False) + except (ParseException, IndexError): + # no match, advance loc in string + tmploc += 1 + else: + # matched skipto expr, done + break + + else: + # ran off the end of the input string without matching skipto expr, fail + raise ParseException(instring, loc, self.errmsg, self) + + # build up return values + loc = tmploc + skiptext = instring[startloc:loc] + skipresult = ParseResults(skiptext) + + if self.includeMatch: + loc, mat = expr_parse(instring,loc,doActions,callPreParse=False) + skipresult += mat + + return loc, skipresult + +class Forward(ParseElementEnhance): + """ + Forward declaration of an expression to be defined later - + used for recursive grammars, such as algebraic infix notation. + When the expression is known, it is assigned to the C{Forward} variable using the '<<' operator. + + Note: take care when assigning to C{Forward} not to overlook precedence of operators. + Specifically, '|' has a lower precedence than '<<', so that:: + fwdExpr << a | b | c + will actually be evaluated as:: + (fwdExpr << a) | b | c + thereby leaving b and c out as parseable alternatives. It is recommended that you + explicitly group the values inserted into the C{Forward}:: + fwdExpr << (a | b | c) + Converting to use the '<<=' operator instead will avoid this problem. + + See L{ParseResults.pprint} for an example of a recursive parser created using + C{Forward}. + """ + def __init__( self, other=None ): + super(Forward,self).__init__( other, savelist=False ) + + def __lshift__( self, other ): + if isinstance( other, basestring ): + other = ParserElement._literalStringClass(other) + self.expr = other + self.strRepr = None + self.mayIndexError = self.expr.mayIndexError + self.mayReturnEmpty = self.expr.mayReturnEmpty + self.setWhitespaceChars( self.expr.whiteChars ) + self.skipWhitespace = self.expr.skipWhitespace + self.saveAsList = self.expr.saveAsList + self.ignoreExprs.extend(self.expr.ignoreExprs) + return self + + def __ilshift__(self, other): + return self << other + + def leaveWhitespace( self ): + self.skipWhitespace = False + return 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=[] ): + if self not in validateTrace: + tmp = validateTrace[:]+[self] + if self.expr is not None: + self.expr.validate(tmp) + self.checkRecursion([]) + + def __str__( self ): + if hasattr(self,"name"): + return self.name + return self.__class__.__name__ + ": ..." + + # stubbed out for now - creates awful memory and perf issues + self._revertClass = self.__class__ + self.__class__ = _ForwardNoRecurse + try: + if self.expr is not None: + retString = _ustr(self.expr) + else: + retString = "None" + finally: + self.__class__ = self._revertClass + return self.__class__.__name__ + ": " + retString + + def copy(self): + if self.expr is not None: + return super(Forward,self).copy() + else: + ret = Forward() + ret <<= self + return ret + +class _ForwardNoRecurse(Forward): + def __str__( self ): + return "..." + +class TokenConverter(ParseElementEnhance): + """ + Abstract subclass of C{ParseExpression}, for converting parsed results. + """ + def __init__( self, expr, savelist=False ): + super(TokenConverter,self).__init__( expr )#, savelist ) + self.saveAsList = False + +class Combine(TokenConverter): + """ + Converter to concatenate all matching tokens to a single string. + By default, the matching patterns must also be contiguous in the input string; + this can be disabled by specifying C{'adjacent=False'} in the constructor. + + Example:: + real = Word(nums) + '.' + Word(nums) + print(real.parseString('3.1416')) # -> ['3', '.', '1416'] + # will also erroneously match the following + print(real.parseString('3. 1416')) # -> ['3', '.', '1416'] + + real = Combine(Word(nums) + '.' + Word(nums)) + print(real.parseString('3.1416')) # -> ['3.1416'] + # 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 ) + # suppress whitespace-stripping in contained parse expressions, but re-enable it on the Combine itself + if adjacent: + self.leaveWhitespace() + self.adjacent = adjacent + self.skipWhitespace = True + self.joinString = joinString + self.callPreparse = True + + def ignore( self, other ): + if self.adjacent: + ParserElement.ignore(self, other) + else: + super( Combine, self).ignore( other ) + return self + + def postParse( self, instring, loc, tokenlist ): + retToks = tokenlist.copy() + del retToks[:] + retToks += ParseResults([ "".join(tokenlist._asStringList(self.joinString)) ], modal=self.modalResults) + + if self.resultsName and retToks.haskeys(): + return [ retToks ] + else: + return retToks + +class Group(TokenConverter): + """ + Converter to return the matched tokens as a list - useful for returning tokens of C{L{ZeroOrMore}} and C{L{OneOrMore}} expressions. + + Example:: + ident = Word(alphas) + num = Word(nums) + term = ident | num + func = ident + Optional(delimitedList(term)) + 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']] + """ + def __init__( self, expr ): + super(Group,self).__init__( expr ) + self.saveAsList = True + + def postParse( self, instring, loc, tokenlist ): + return [ tokenlist ] + +class Dict(TokenConverter): + """ + Converter to return a repetitive expression as a list, but also as a dictionary. + Each element can also be referenced using the first token in the expression as its key. + Useful for tabular report scraping when the first column can be used as a item key. + + Example:: + data_word = Word(alphas) + label = data_word + FollowedBy(':') + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join)) + + text = "shape: SQUARE posn: upper left color: light blue texture: burlap" + attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + + # print attributes as plain groups + print(OneOrMore(attr_expr).parseString(text).dump()) + + # instead of OneOrMore(expr), parse using Dict(OneOrMore(Group(expr))) - Dict will auto-assign names + result = Dict(OneOrMore(Group(attr_expr))).parseString(text) + print(result.dump()) + + # access named fields as dict entries, or output as dict + print(result['shape']) + print(result.asDict()) + prints:: + ['shape', 'SQUARE', 'posn', 'upper left', 'color', 'light blue', 'texture', 'burlap'] + + [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']] + - color: light blue + - posn: upper left + - shape: SQUARE + - texture: burlap + SQUARE + {'color': 'light blue', 'posn': 'upper left', 'texture': 'burlap', 'shape': 'SQUARE'} + See more examples at L{ParseResults} of accessing fields by results name. + """ + def __init__( self, expr ): + super(Dict,self).__init__( expr ) + self.saveAsList = True + + def postParse( self, instring, loc, tokenlist ): + for i,tok in enumerate(tokenlist): + if len(tok) == 0: + continue + ikey = tok[0] + 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) + else: + dictvalue = tok.copy() #ParseResults(i) + del dictvalue[0] + if len(dictvalue)!= 1 or (isinstance(dictvalue,ParseResults) and dictvalue.haskeys()): + tokenlist[ikey] = _ParseResultsWithOffset(dictvalue,i) + else: + tokenlist[ikey] = _ParseResultsWithOffset(dictvalue[0],i) + + if self.resultsName: + return [ tokenlist ] + else: + return tokenlist + + +class Suppress(TokenConverter): + """ + Converter for ignoring the results of a parsed expression. + + Example:: + source = "a, b, c,d" + wd = Word(alphas) + wd_list1 = wd + ZeroOrMore(',' + wd) + print(wd_list1.parseString(source)) + + # often, delimiters that are useful during parsing are just in the + # way afterward - use Suppress to keep them out of the parsed output + wd_list2 = wd + ZeroOrMore(Suppress(',') + wd) + print(wd_list2.parseString(source)) + prints:: + ['a', ',', 'b', ',', 'c', ',', 'd'] + ['a', 'b', 'c', 'd'] + (See also L{delimitedList}.) + """ + def postParse( self, instring, loc, tokenlist ): + return [] + + def suppress( self ): + return self + + +class OnlyOnce(object): + """ + Wrapper for parse actions, to ensure they are only called once. + """ + def __init__(self, methodCall): + self.callable = _trim_arity(methodCall) + self.called = False + def __call__(self,s,l,t): + if not self.called: + results = self.callable(s,l,t) + self.called = True + return results + raise ParseException(s,l,"") + def reset(self): + self.called = False + +def traceParseAction(f): + """ + Decorator for debugging parse actions. + + When the parse action is called, this decorator will print C{">> entering I{method-name}(line:I{current_source_line}, I{parse_location}, I{matched_tokens})".} + When the parse action completes, the decorator will print C{"<<"} followed by the returned value, or any exception that the parse action raised. + + Example:: + wd = Word(alphas) + + @traceParseAction + def remove_duplicate_chars(tokens): + return ''.join(sorted(set(''.join(tokens)))) + + wds = OneOrMore(wd).setParseAction(remove_duplicate_chars) + print(wds.parseString("slkdjs sld sldd sdlf sdljf")) + prints:: + >>entering remove_duplicate_chars(line: 'slkdjs sld sldd sdlf sdljf', 0, (['slkdjs', 'sld', 'sldd', 'sdlf', 'sdljf'], {})) + <<leaving remove_duplicate_chars (ret: 'dfjkls') + ['dfjkls'] + """ + f = _trim_arity(f) + def z(*paArgs): + thisFunc = f.__name__ + 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) ) + try: + ret = f(*paArgs) + except Exception as exc: + sys.stderr.write( "<<leaving %s (exception: %s)\n" % (thisFunc,exc) ) + raise + sys.stderr.write( "<<leaving %s (ret: %r)\n" % (thisFunc,ret) ) + return ret + try: + z.__name__ = f.__name__ + except AttributeError: + pass + return z + +# +# global helpers +# +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 overridden by passing C{combine=True} in the constructor. + If C{combine} is set to C{True}, the matching tokens are returned as a single token + string, with the delimiters included; otherwise, the matching tokens are returned + as a list of tokens, with the delimiters suppressed. + + Example:: + 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)+"]..." + if combine: + return Combine( expr + ZeroOrMore( delim + expr ) ).setName(dlName) + else: + return ( expr + ZeroOrMore( Suppress( delim ) + expr ) ).setName(dlName) + +def countedArray( expr, intExpr=None ): + """ + Helper to define a counted list of expressions. + This helper defines a pattern of the form:: + integer expr expr expr... + where the leading integer tells how many expr expressions follow. + The matched tokens returns the array of expr tokens as a list - the leading count token is suppressed. + + If C{intExpr} is specified, it should be a pyparsing expression that produces an integer value. + + Example:: + countedArray(Word(alphas)).parseString('2 ab cd ef') # -> ['ab', 'cd'] + + # in this parser, the leading integer value is given in binary, + # '10' indicating that 2 values are in the array + binaryConstant = Word('01').setParseAction(lambda t: int(t[0], 2)) + countedArray(Word(alphas), intExpr=binaryConstant).parseString('10 ab cd ef') # -> ['ab', 'cd'] + """ + arrayExpr = Forward() + def countFieldParseAction(s,l,t): + n = t[0] + arrayExpr << (n and Group(And([expr]*n)) or Group(empty)) + return [] + if intExpr is None: + 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) + '...') + +def _flatten(L): + ret = [] + for i in L: + if isinstance(i,list): + ret.extend(_flatten(i)) + else: + ret.append(i) + return ret + +def matchPreviousLiteral(expr): + """ + Helper to define an expression that is indirectly defined from + the tokens matched in a previous expression, that is, it looks + for a 'repeat' of a previous expression. For example:: + first = Word(nums) + second = matchPreviousLiteral(first) + matchExpr = first + ":" + second + will match C{"1:1"}, but not C{"1:2"}. Because this matches a + previous literal, will also match the leading C{"1:1"} in C{"1:10"}. + If this is not desired, use C{matchPreviousExpr}. + Do I{not} use with packrat parsing enabled. + """ + rep = Forward() + def copyTokenToRepeater(s,l,t): + if t: + if len(t) == 1: + rep << t[0] + else: + # flatten t tokens + tflat = _flatten(t.asList()) + rep << And(Literal(tt) for tt in tflat) + else: + rep << Empty() + expr.addParseAction(copyTokenToRepeater, callDuringTry=True) + rep.setName('(prev) ' + _ustr(expr)) + return rep + +def matchPreviousExpr(expr): + """ + Helper to define an expression that is indirectly defined from + the tokens matched in a previous expression, that is, it looks + for a 'repeat' of a previous expression. For example:: + first = Word(nums) + second = matchPreviousExpr(first) + matchExpr = first + ":" + second + will match C{"1:1"}, but not C{"1:2"}. Because this matches by + expressions, will I{not} match the leading C{"1:1"} in C{"1:10"}; + the expressions are evaluated first, and then compared, so + C{"1"} is compared with C{"10"}. + Do I{not} use with packrat parsing enabled. + """ + rep = Forward() + e2 = expr.copy() + rep <<= e2 + def copyTokenToRepeater(s,l,t): + matchTokens = _flatten(t.asList()) + def mustMatchTheseTokens(s,l,t): + theseTokens = _flatten(t.asList()) + 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") + return _ustr(s) + +def oneOf( strs, caseless=False, useRegex=True ): + """ + 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 a C{L{MatchFirst}} for best performance. + + Parameters: + - strs - a string of space-delimited literals, or a collection of string literals + - caseless - (default=C{False}) - treat all literals as caseless + - useRegex - (default=C{True}) - as an optimization, will generate a Regex + object; otherwise, will generate a C{MatchFirst} object (if C{caseless=True}, or + if creating a C{Regex} raises an exception) + + Example:: + comp_oper = oneOf("< = > <= >= !=") + var = Word(alphas) + number = Word(nums) + term = var | number + comparison_expr = term + comp_oper + term + print(comparison_expr.searchString("B = 12 AA=23 B<=AA AA>12")) + prints:: + [['B', '=', '12'], ['AA', '=', '23'], ['B', '<=', 'AA'], ['AA', '>', '12']] + """ + if caseless: + isequal = ( lambda a,b: a.upper() == b.upper() ) + masks = ( lambda a,b: b.upper().startswith(a.upper()) ) + parseElementClass = CaselessLiteral + else: + isequal = ( lambda a,b: a == b ) + masks = ( lambda a,b: b.startswith(a) ) + parseElementClass = Literal + + symbols = [] + 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) + 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)) + 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 ): + """ + Helper to easily and clearly define a dictionary by specifying the respective patterns + for the key and value. Takes care of defining the C{L{Dict}}, C{L{ZeroOrMore}}, and C{L{Group}} tokens + in the proper order. The key pattern can include delimiting markers or punctuation, + as long as they are suppressed, thereby leaving the significant key text. The value + pattern can include named results, so that the C{Dict} results can include named token + fields. + + Example:: + text = "shape: SQUARE posn: upper left color: light blue texture: burlap" + attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + print(OneOrMore(attr_expr).parseString(text).dump()) + + attr_label = label + attr_value = Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join) + + # similar to Dict, but simpler call format + result = dictOf(attr_label, attr_value).parseString(text) + print(result.dump()) + print(result['shape']) + print(result.shape) # object attribute access works too + print(result.asDict()) + prints:: + [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']] + - color: light blue + - posn: upper left + - shape: SQUARE + - texture: burlap + SQUARE + SQUARE + {'color': 'light blue', 'shape': 'SQUARE', 'posn': 'upper left', 'texture': 'burlap'} + """ + return Dict( ZeroOrMore( Group ( key + value ) ) ) + +def originalTextFor(expr, asString=True): + """ + Helper to return the original, untokenized text for a given expression. Useful to + restore the parsed fields of an HTML start tag into the raw tag text itself, or to + revert separate tokens with intervening whitespace back to the original matching + input text. By default, returns astring containing the original parsed text. + + If the optional C{asString} argument is passed as C{False}, then the return value is a + C{L{ParseResults}} containing any results names that were originally matched, and a + single token containing the original matched text from the input string. So if + the expression passed to C{L{originalTextFor}} contains expressions with defined + results names, you must set C{asString} to C{False} if you want to preserve those + results name values. + + Example:: + src = "this is test <b> bold <i>text</i> </b> normal text " + for tag in ("b","i"): + opener,closer = makeHTMLTags(tag) + patt = originalTextFor(opener + SkipTo(closer) + closer) + print(patt.searchString(src)[0]) + prints:: + ['<b> bold <i>text</i> </b>'] + ['<i>text</i>'] + """ + 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] + else: + def extractText(s,l,t): + t[:] = [s[t.pop('_original_start'):t.pop('_original_end')]] + matchExpr.setParseAction(extractText) + matchExpr.ignoreExprs = expr.ignoreExprs + return matchExpr + +def ungroup(expr): + """ + Helper to undo pyparsing's default grouping of And expressions, even + if all but one are non-empty. + """ + return TokenConverter(expr).setParseAction(lambda t:t[0]) + +def locatedExpr(expr): + """ + Helper to decorate a returned token with its starting and ending locations in the input string. + This helper adds the following results names: + - locn_start = location where matched expression begins + - locn_end = location where matched expression ends + - value = the actual parsed results + + Be careful if the input text contains C{<TAB>} characters, you may want to call + C{L{ParserElement.parseWithTabs}} + + Example:: + wd = Word(alphas) + for match in locatedExpr(wd).searchString("ljsdf123lksdjjf123lkkjj1222"): + print(match) + prints:: + [[0, 'ljsdf', 5]] + [[8, 'lksdjjf', 15]] + [[18, 'lkkjj', 23]] + """ + locator = Empty().setParseAction(lambda s,l,t: l) + return Group(locator("locn_start") + expr("value") + locator.copy().leaveWhitespace()("locn_end")) + + +# convenience constants for positional expressions +empty = Empty().setName("empty") +lineStart = LineStart().setName("lineStart") +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))) +_singleChar = _escapedPunc | _escapedHexChar | _escapedOctChar | CharsNotIn(r'\]', exact=1) +_charRange = Group(_singleChar + Suppress("-") + _singleChar) +_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 construction. Borrows + syntax from regexp '[]' string range definitions:: + srange("[0-9]") -> "0123456789" + srange("[a-z]") -> "abcdefghijklmnopqrstuvwxyz" + srange("[a-z$_]") -> "abcdefghijklmnopqrstuvwxyz$_" + The input string must be enclosed in []'s, and the returned string is the expanded + character set joined into a single string. + The values enclosed in the []'s may be: + - a single character + - an escaped character with a leading backslash (such as C{\-} or C{\]}) + - an escaped hex character with a leading C{'\x'} (C{\x21}, which is a C{'!'} character) + (C{\0x##} is also supported for backwards compatibility) + - an escaped octal character with a leading C{'\0'} (C{\041}, which is a C{'!'} character) + - a range of any of the above, separated by a dash (C{'a-z'}, etc.) + - any combination of the above (C{'aeiouy'}, C{'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)) + try: + return "".join(_expanded(part) for part in _reBracketExpr.parseString(s).body) + except Exception: + return "" + +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) + return verifyCol + +def replaceWith(replStr): + """ + Helper method for common parse actions that simply return a literal value. Especially + useful when used with C{L{transformString<ParserElement.transformString>}()}. + + Example:: + num = Word(nums).setParseAction(lambda toks: int(toks[0])) + na = oneOf("N/A NA").setParseAction(replaceWith(math.nan)) + term = na | num + + OneOrMore(term).parseString("324 234 N/A 234") # -> [324, 234, nan, 234] + """ + return lambda s,l,t: [replStr] + +def removeQuotes(s,l,t): + """ + Helper parse action for removing quotation marks from parsed quoted strings. + + Example:: + # by default, quotation marks are included in parsed results + quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["'Now is the Winter of our Discontent'"] + + # use removeQuotes to strip quotation marks from parsed results + quotedString.setParseAction(removeQuotes) + quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["Now is the Winter of our Discontent"] + """ + return t[0][1:-1] + +def tokenMap(func, *args): + """ + Helper to define a parse action by mapping a function to all elements of a ParseResults list.If any additional + args are passed, they are forwarded to the given function as additional arguments after + the token, as in C{hex_integer = Word(hexnums).setParseAction(tokenMap(int, 16))}, which will convert the + parsed data to an integer using base 16. + + Example (compare the last to example in L{ParserElement.transformString}:: + hex_ints = OneOrMore(Word(hexnums)).setParseAction(tokenMap(int, 16)) + hex_ints.runTests(''' + 00 11 22 aa FF 0a 0d 1a + ''') + + upperword = Word(alphas).setParseAction(tokenMap(str.upper)) + OneOrMore(upperword).runTests(''' + my kingdom for a horse + ''') + + wd = Word(alphas).setParseAction(tokenMap(str.title)) + OneOrMore(wd).setParseAction(' '.join).runTests(''' + now is the winter of our discontent made glorious summer by this sun of york + ''') + prints:: + 00 11 22 aa FF 0a 0d 1a + [0, 17, 34, 170, 255, 10, 13, 26] + + my kingdom for a horse + ['MY', 'KINGDOM', 'FOR', 'A', 'HORSE'] + + 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): + return [func(tokn, *args) for tokn in t] + + try: + func_name = getattr(func, '__name__', + getattr(func, '__class__').__name__) + except Exception: + func_name = str(func) + pa.__name__ = func_name + + return pa + +upcaseTokens = tokenMap(lambda t: _ustr(t).upper()) +"""(Deprecated) Helper parse action to convert tokens to upper case. Deprecated in favor of L{pyparsing_common.upcaseTokens}""" + +downcaseTokens = tokenMap(lambda t: _ustr(t).lower()) +"""(Deprecated) Helper parse action to convert tokens to lower case. Deprecated in favor of L{pyparsing_common.downcaseTokens}""" + +def _makeTags(tagStr, xml): + """Internal helper to construct opening and closing tag expressions, given a tag name""" + 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 ) + openTag = Suppress("<") + tagStr("tag") + \ + Dict(ZeroOrMore(Group( tagAttrName + Suppress("=") + tagAttrValue ))) + \ + Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") + else: + printablesLessRAbrack = "".join(c for c in printables if c not in ">") + tagAttrValue = quotedString.copy().setParseAction( removeQuotes ) | Word(printablesLessRAbrack) + openTag = Suppress("<") + tagStr("tag") + \ + Dict(ZeroOrMore(Group( tagAttrName.setParseAction(downcaseTokens) + \ + Optional( Suppress("=") + tagAttrValue ) ))) + \ + Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") + closeTag = Combine(_L("</") + tagStr + ">") + + openTag = openTag.setResultsName("start"+"".join(resname.replace(":"," ").title().split())).setName("<%s>" % resname) + closeTag = closeTag.setResultsName("end"+"".join(resname.replace(":"," ").title().split())).setName("</%s>" % resname) + openTag.tag = resname + closeTag.tag = resname + return openTag, closeTag + +def makeHTMLTags(tagStr): + """ + Helper to construct opening and closing tag expressions for HTML, given a tag name. Matches + tags in either upper or lower case, attributes with namespaces and with quoted or unquoted values. + + Example:: + text = '<td>More info at the <a href="http://pyparsing.wikispaces.com">pyparsing</a> wiki page</td>' + # makeHTMLTags returns pyparsing expressions for the opening and closing tags as a 2-tuple + a,a_end = makeHTMLTags("A") + link_expr = a + SkipTo(a_end)("link_text") + a_end + + for link in link_expr.searchString(text): + # attributes in the <A> tag (like "href" shown here) are also accessible as named results + print(link.link_text, '->', link.href) + prints:: + pyparsing -> http://pyparsing.wikispaces.com + """ + return _makeTags( tagStr, False ) + +def makeXMLTags(tagStr): + """ + Helper to construct opening and closing tag expressions for XML, given a tag name. Matches + tags only in the given upper/lower case. + + Example: similar to L{makeHTMLTags} + """ + return _makeTags( tagStr, True ) + +def withAttribute(*args,**attrDict): + """ + Helper to create a validating parse action to be used with start tags created + with C{L{makeXMLTags}} or C{L{makeHTMLTags}}. Use C{withAttribute} to qualify a starting tag + with a required attribute value, to avoid false matches on common tags such as + C{<TD>} or C{<DIV>}. + + Call C{withAttribute} with a series of attribute names and values. Specify the list + of filter attributes names and values as: + - keyword arguments, as in C{(align="right")}, or + - as an explicit dict with C{**} operator, when an attribute name is also a Python + reserved word, as in C{**{"class":"Customer", "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. + + If just testing for C{class} (with or without a namespace), use C{L{withClass}}. + + To verify that the attribute exists, but without specifying a value, pass + C{withAttribute.ANY_VALUE} as the value. + + Example:: + html = ''' + <div> + Some text + <div type="grid">1 4 0 1 0</div> + <div type="graph">1,3 2,3 1,1</div> + <div>this has no type</div> + </div> + + ''' + div,div_end = makeHTMLTags("div") + + # only match div tag having a type attribute with value "grid" + div_grid = div().setParseAction(withAttribute(type="grid")) + grid_expr = div_grid + SkipTo(div | div_end)("body") + for grid_header in grid_expr.searchString(html): + print(grid_header.body) + + # construct a match with any div tag having a type attribute, regardless of the value + div_any_type = div().setParseAction(withAttribute(type=withAttribute.ANY_VALUE)) + div_expr = div_any_type + SkipTo(div | div_end)("body") + for div_header in div_expr.searchString(html): + print(div_header.body) + prints:: + 1 4 0 1 0 + + 1 4 0 1 0 + 1,3 2,3 1,1 + """ + if args: + attrs = args[:] + else: + attrs = attrDict.items() + 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) + if attrValue != withAttribute.ANY_VALUE and tokens[attrName] != attrValue: + raise ParseException(s,l,"attribute '%s' has value '%s', must be '%s'" % + (attrName, tokens[attrName], attrValue)) + return pa +withAttribute.ANY_VALUE = object() + +def withClass(classname, namespace=''): + """ + Simplified version of C{L{withAttribute}} when matching on a div class - made + difficult because C{class} is a reserved word in Python. + + Example:: + html = ''' + <div> + Some text + <div class="grid">1 4 0 1 0</div> + <div class="graph">1,3 2,3 1,1</div> + <div>this <div> has no class</div> + </div> + + ''' + div,div_end = makeHTMLTags("div") + div_grid = div().setParseAction(withClass("grid")) + + grid_expr = div_grid + SkipTo(div | div_end)("body") + for grid_header in grid_expr.searchString(html): + print(grid_header.body) + + div_any_type = div().setParseAction(withClass(withAttribute.ANY_VALUE)) + div_expr = div_any_type + SkipTo(div | div_end)("body") + for div_header in div_expr.searchString(html): + print(div_header.body) + prints:: + 1 4 0 1 0 + + 1 4 0 1 0 + 1,3 2,3 1,1 + """ + classattr = "%s:class" % namespace if namespace else "class" + return withAttribute(**{classattr : classname}) + +opAssoc = _Constants() +opAssoc.LEFT = object() +opAssoc.RIGHT = object() + +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 attached + to operator expressions. The generated parser will also recognize the use + of parentheses to override operator precedences (see example below). + + Note: if you define a deep operator list, you may see performance issues + when using infixNotation. See L{ParserElement.enablePackrat} for a + mechanism to potentially improve your parser performance. + + Parameters: + - baseExpr - expression representing the most basic element for the nested + - opList - list of tuples, one for each operator precedence level in the + expression grammar; each tuple is of the form + (opExpr, numTerms, rightLeftAssoc, parseAction), where: + - opExpr is the pyparsing expression for the operator; + may also be a string, which will be converted to a Literal; + if numTerms is 3, opExpr is a tuple of two expressions, for the + two operators separating the 3 terms + - numTerms is the number of terms for this operator (must + be 1, 2, or 3) + - rightLeftAssoc is the indicator whether the operator is + right or left associative, using the pyparsing-defined + constants C{opAssoc.RIGHT} and C{opAssoc.LEFT}. + - parseAction is the parse action to be associated with + expressions matching this operator expression (the + parse action tuple member may be omitted); if the parse action + is passed a tuple or list of functions, this is equivalent to + calling C{setParseAction(*fn)} (L{ParserElement.setParseAction}) + - lpar - expression for matching left-parentheses (default=C{Suppress('(')}) + - rpar - expression for matching right-parentheses (default=C{Suppress(')')}) + + Example:: + # simple example of four-function arithmetic with ints and variable names + integer = pyparsing_common.signed_integer + varname = pyparsing_common.identifier + + arith_expr = infixNotation(integer | varname, + [ + ('-', 1, opAssoc.RIGHT), + (oneOf('* /'), 2, opAssoc.LEFT), + (oneOf('+ -'), 2, opAssoc.LEFT), + ]) + + arith_expr.runTests(''' + 5+3*6 + (5+3)*6 + -2--11 + ''', fullDump=False) + prints:: + 5+3*6 + [[5, '+', [3, '*', 6]]] + + (5+3)*6 + [[[5, '+', 3], '*', 6]] + + -2--11 + [[['-', 2], '-', ['-', 11]]] + """ + ret = Forward() + 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: + raise ValueError("if numterms=3, opExpr must be a tuple or list of two expressions") + opExpr1, opExpr2 = opExpr + thisExpr = Forward().setName(termName) + if rightLeftAssoc == opAssoc.LEFT: + if arity == 1: + matchExpr = FollowedBy(lastExpr + opExpr) + Group( lastExpr + OneOrMore( opExpr ) ) + elif arity == 2: + if opExpr is not None: + matchExpr = FollowedBy(lastExpr + opExpr + lastExpr) + Group( lastExpr + OneOrMore( opExpr + lastExpr ) ) + else: + matchExpr = FollowedBy(lastExpr+lastExpr) + Group( lastExpr + OneOrMore(lastExpr) ) + elif arity == 3: + matchExpr = FollowedBy(lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr) + \ + Group( lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr ) + else: + raise ValueError("operator must be unary (1), binary (2), or ternary (3)") + elif rightLeftAssoc == opAssoc.RIGHT: + if arity == 1: + # try to avoid LR with this extra test + if not isinstance(opExpr, Optional): + opExpr = Optional(opExpr) + matchExpr = FollowedBy(opExpr.expr + thisExpr) + Group( opExpr + thisExpr ) + elif arity == 2: + if opExpr is not None: + matchExpr = FollowedBy(lastExpr + opExpr + thisExpr) + Group( lastExpr + OneOrMore( opExpr + thisExpr ) ) + else: + matchExpr = FollowedBy(lastExpr + thisExpr) + Group( lastExpr + OneOrMore( thisExpr ) ) + elif arity == 3: + matchExpr = FollowedBy(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: + raise ValueError("operator must indicate right or left associativity") + if pa: + if isinstance(pa, (tuple, list)): + matchExpr.setParseAction(*pa) + else: + matchExpr.setParseAction(pa) + thisExpr <<= ( matchExpr.setName(termName) | lastExpr ) + lastExpr = thisExpr + ret <<= lastExpr + return ret + +operatorPrecedence = infixNotation +"""(Deprecated) Former name of C{L{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") +unicodeString = Combine(_L('u') + quotedString.copy()).setName("unicode string literal") + +def nestedExpr(opener="(", closer=")", content=None, ignoreExpr=quotedString.copy()): + """ + Helper method for defining nested lists enclosed in opening and closing + delimiters ("(" and ")" are the default). + + Parameters: + - opener - opening character for a nested list (default=C{"("}); can also be a pyparsing expression + - closer - closing character for a nested list (default=C{")"}); can also be a pyparsing expression + - content - expression for items within the nested lists (default=C{None}) + - ignoreExpr - expression for ignoring opening and closing delimiters (default=C{quotedString}) + + If an expression is not provided for the content argument, the nested + expression will capture all whitespace-delimited content between delimiters + as a list of separate values. + + Use the C{ignoreExpr} argument to define expressions that may contain + opening or closing characters that should not be treated as opening + or closing characters for nesting, such as quotedString or a comment + expression. Specify multiple expressions using an C{L{Or}} or C{L{MatchFirst}}. + The default is L{quotedString}, but if no expressions are to be ignored, + then pass C{None} for this argument. + + Example:: + data_type = oneOf("void int short long char float double") + decl_data_type = Combine(data_type + Optional(Word('*'))) + ident = Word(alphas+'_', alphanums+'_') + number = pyparsing_common.number + arg = Group(decl_data_type + ident) + LPAR,RPAR = map(Suppress, "()") + + code_body = nestedExpr('{', '}', ignoreExpr=(quotedString | cStyleComment)) + + c_function = (decl_data_type("type") + + ident("name") + + LPAR + Optional(delimitedList(arg), [])("args") + RPAR + + code_body("body")) + c_function.ignore(cStyleComment) + + source_code = ''' + int is_odd(int x) { + return (x%2); + } + + int dec_to_hex(char hchar) { + if (hchar >= '0' && hchar <= '9') { + return (ord(hchar)-ord('0')); + } else { + return (10+ord(hchar)-ord('A')); + } + } + ''' + for func in c_function.searchString(source_code): + print("%(name)s (%(type)s) args: %(args)s" % func) + + prints:: + is_odd (int) args: [['int', 'x']] + dec_to_hex (int) args: [['char', 'hchar']] + """ + 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 ignoreExpr is not None: + 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())) + 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())) + else: + 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) ) + else: + 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): + """ + Helper method for defining space-delimited indentation blocks, such as + those used to define block statements in Python source code. + + Parameters: + - blockStatementExpr - expression defining syntax of statement that + is repeated within the indented block + - indentStack - list created by caller to manage indentation stack + (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 statements + (default=C{True}) + + A valid block must contain at least one C{blockStatement}. + + Example:: + data = ''' + def A(z): + A1 + B = 100 + G = A2 + A2 + A3 + B + def BB(a,b,c): + BB1 + def BBA(): + bba1 + bba2 + bba3 + C + D + def spam(x,y): + def eggs(z): + pass + ''' + + + indentStack = [1] + stmt = Forward() + + identifier = Word(alphas, alphanums) + funcDecl = ("def" + identifier + Group( "(" + Optional( delimitedList(identifier) ) + ")" ) + ":") + func_body = indentedBlock(stmt, indentStack) + 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 ) + + module_body = OneOrMore(stmt) + + parseTree = module_body.parseString(data) + parseTree.pprint() + prints:: + [['def', + 'A', + ['(', 'z', ')'], + ':', + [['A1'], [['B', '=', '100']], [['G', '=', 'A2']], ['A2'], ['A3']]], + 'B', + ['def', + 'BB', + ['(', 'a', 'b', 'c', ')'], + ':', + [['BB1'], [['def', 'BBA', ['(', ')'], ':', [['bba1'], ['bba2'], ['bba3']]]]]], + 'C', + 'D', + ['def', + 'spam', + ['(', 'x', 'y', ')'], + ':', + [[['def', 'eggs', ['(', 'z', ')'], ':', [['pass']]]]]]] + """ + def checkPeerIndent(s,l,t): + if l >= len(s): return + curCol = col(l,s) + if curCol != indentStack[-1]: + if curCol > indentStack[-1]: + raise ParseFatalException(s,l,"illegal nesting") + raise ParseException(s,l,"not a peer entry") + + def checkSubIndent(s,l,t): + curCol = col(l,s) + if curCol > indentStack[-1]: + indentStack.append( curCol ) + else: + raise ParseException(s,l,"not a subentry") + + 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() + + NL = OneOrMore(LineEnd().setWhitespaceChars("\t ").suppress()) + 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) + else: + smExpr = Group( Optional(NL) + + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) ) + blockStatementExpr.ignore(_bslash + LineEnd()) + return smExpr.setName('indented block') + +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(),'><& "\'')) +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""" + return _htmlEntityMap.get(t.entity) + +# it's easy to get these comment structures wrong - they're very common, so may as well make them available +cStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/').setName("C style comment") +"Comment of the form C{/* ... */}" + +htmlComment = Regex(r"<!--[\s\S]*?-->").setName("HTML comment") +"Comment of the form C{<!-- ... -->}" + +restOfLine = Regex(r".*").leaveWhitespace().setName("rest of line") +dblSlashComment = Regex(r"//(?:\\\n|[^\n])*").setName("// comment") +"Comment of the form C{// ... (to end of line)}" + +cppStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/'| dblSlashComment).setName("C++ style comment") +"Comment of either form C{L{cStyleComment}} or C{L{dblSlashComment}}" + +javaStyleComment = cppStyleComment +"Same as C{L{cppStyleComment}}" + +pythonStyleComment = Regex(r"#.*").setName("Python style comment") +"Comment of the form C{# ... (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") +"""(Deprecated) Predefined expression of 1 or more printable words or quoted strings, separated by commas. + This expression is deprecated in favor of L{pyparsing_common.comma_separated_list}.""" + +# some other useful expressions - using lower-case class name since we are really using this as a namespace +class pyparsing_common: + """ + Here are some common low-level expressions that may be useful in jump-starting parser development: + - numeric forms (L{integers<integer>}, L{reals<real>}, L{scientific notation<sci_real>}) + - common L{programming identifiers<identifier>} + - network addresses (L{MAC<mac_address>}, L{IPv4<ipv4_address>}, L{IPv6<ipv6_address>}) + - ISO8601 L{dates<iso8601_date>} and L{datetime<iso8601_datetime>} + - L{UUID<uuid>} + - L{comma-separated list<comma_separated_list>} + Parse actions: + - C{L{convertToInteger}} + - C{L{convertToFloat}} + - C{L{convertToDate}} + - C{L{convertToDatetime}} + - C{L{stripHTMLTags}} + - C{L{upcaseTokens}} + - C{L{downcaseTokens}} + + Example:: + pyparsing_common.number.runTests(''' + # any int or real number, returned as the appropriate type + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + ''') + + pyparsing_common.fnumber.runTests(''' + # any int or real number, returned as float + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + ''') + + pyparsing_common.hex_integer.runTests(''' + # hex numbers + 100 + FF + ''') + + pyparsing_common.fraction.runTests(''' + # fractions + 1/2 + -3/4 + ''') + + pyparsing_common.mixed_integer.runTests(''' + # mixed fractions + 1 + 1/2 + -3/4 + 1-3/4 + ''') + + import uuid + pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID)) + pyparsing_common.uuid.runTests(''' + # uuid + 12345678-1234-5678-1234-567812345678 + ''') + prints:: + # any int or real number, returned as the appropriate type + 100 + [100] + + -100 + [-100] + + +100 + [100] + + 3.14159 + [3.14159] + + 6.02e23 + [6.02e+23] + + 1e-12 + [1e-12] + + # any int or real number, returned as float + 100 + [100.0] + + -100 + [-100.0] + + +100 + [100.0] + + 3.14159 + [3.14159] + + 6.02e23 + [6.02e+23] + + 1e-12 + [1e-12] + + # hex numbers + 100 + [256] + + FF + [255] + + # fractions + 1/2 + [0.5] + + -3/4 + [-0.75] + + # mixed fractions + 1 + [1] + + 1/2 + [0.5] + + -3/4 + [-0.75] + + 1-3/4 + [1.75] + + # uuid + 12345678-1234-5678-1234-567812345678 + [UUID('12345678-1234-5678-1234-567812345678')] + """ + + convertToInteger = tokenMap(int) + """ + Parse action for converting parsed integers to Python int + """ + + convertToFloat = tokenMap(float) + """ + Parse action for converting parsed numbers to Python float + """ + + 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)) + """expression that parses a hexadecimal integer, returns an int""" + + signed_integer = Regex(r'[+-]?\d+').setName("signed integer").setParseAction(convertToInteger) + """expression that parses an integer with optional leading sign, returns an int""" + + fraction = (signed_integer().setParseAction(convertToFloat) + '/' + signed_integer().setParseAction(convertToFloat)).setName("fraction") + """fractional expression of an integer divided by an integer, returns a float""" + fraction.addParseAction(lambda t: t[0]/t[-1]) + + mixed_integer = (fraction | signed_integer + Optional(Optional('-').suppress() + fraction)).setName("fraction or mixed integer-fraction") + """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) + """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) + """expression that parses a floating point number with optional scientific notation and returns a float""" + + # streamlining this expression makes the docs nicer-looking + number = (sci_real | real | signed_integer).streamline() + """any numeric expression, returns the corresponding Python type""" + + 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") + """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 (C{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") + _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") + "IPv6 address (long, short, or mixed form)" + + mac_address = Regex(r'[0-9a-fA-F]{2}([:.-])[0-9a-fA-F]{2}(?:\1[0-9a-fA-F]{2}){4}').setName("MAC address") + "MAC address xx:xx:xx:xx:xx (may also have '-' or '.' delimiters)" + + @staticmethod + def convertToDate(fmt="%Y-%m-%d"): + """ + Helper to create a parse action for converting parsed date string to Python datetime.date + + Params - + - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%d"}) + + Example:: + date_expr = pyparsing_common.iso8601_date.copy() + date_expr.setParseAction(pyparsing_common.convertToDate()) + print(date_expr.parseString("1999-12-31")) + prints:: + [datetime.date(1999, 12, 31)] + """ + def cvt_fn(s,l,t): + try: + return datetime.strptime(t[0], fmt).date() + except ValueError as ve: + raise ParseException(s, l, str(ve)) + return cvt_fn + + @staticmethod + def convertToDatetime(fmt="%Y-%m-%dT%H:%M:%S.%f"): + """ + Helper to create a parse action for converting parsed datetime string to Python datetime.datetime + + Params - + - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%dT%H:%M:%S.%f"}) + + Example:: + dt_expr = pyparsing_common.iso8601_datetime.copy() + dt_expr.setParseAction(pyparsing_common.convertToDatetime()) + print(dt_expr.parseString("1999-12-31T23:59:59.999")) + prints:: + [datetime.datetime(1999, 12, 31, 23, 59, 59, 999000)] + """ + def cvt_fn(s,l,t): + try: + return datetime.strptime(t[0], fmt) + except ValueError as ve: + raise ParseException(s, l, str(ve)) + return cvt_fn + + iso8601_date = Regex(r'(?P<year>\d{4})(?:-(?P<month>\d\d)(?:-(?P<day>\d\d))?)?').setName("ISO8601 date") + "ISO8601 date (C{yyyy-mm-dd})" + + iso8601_datetime = Regex(r'(?P<year>\d{4})-(?P<month>\d\d)-(?P<day>\d\d)[T ](?P<hour>\d\d):(?P<minute>\d\d)(:(?P<second>\d\d(\.\d*)?)?)?(?P<tz>Z|[+-]\d\d:?\d\d)?').setName("ISO8601 datetime") + "ISO8601 datetime (C{yyyy-mm-ddThh:mm:ss.s(Z|+-00:00)}) - trailing seconds, milliseconds, and timezone optional; accepts separating C{'T'} or C{' '}" + + uuid = Regex(r'[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}').setName("UUID") + "UUID (C{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx})" + + _html_stripper = anyOpenTag.suppress() | anyCloseTag.suppress() + @staticmethod + def stripHTMLTags(s, l, tokens): + """ + Parse action to remove HTML tags from web page HTML source + + Example:: + # strip HTML links from normal text + text = '<td>More info at the <a href="http://pyparsing.wikispaces.com">pyparsing</a> wiki page</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) # -> 'More info at the pyparsing wiki page' + """ + 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") + """Predefined expression of 1 or more printable words or quoted strings, separated by commas.""" + + upcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).upper())) + """Parse action to convert tokens to upper case.""" + + downcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).lower())) + """Parse action to convert tokens to lower case.""" + + +if __name__ == "__main__": + + selectToken = CaselessLiteral("select") + fromToken = CaselessLiteral("from") + + ident = Word(alphas, alphanums + "_$") + + columnName = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens) + columnNameList = Group(delimitedList(columnName)).setName("columns") + columnSpec = ('*' | columnNameList) + + tableName = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens) + tableNameList = Group(delimitedList(tableName)).setName("tables") + + simpleSQL = selectToken("command") + columnSpec("columns") + fromToken + tableNameList("tables") + + # demo runTests method, including embedded comments in test string + simpleSQL.runTests(""" + # '*' as column list and dotted table name + select * from SYS.XYZZY + + # caseless match on "SELECT", and casts back to "select" + SELECT * from XYZZY, ABC + + # list of column names, and mixed case SELECT keyword + Select AA,BB,CC from Sys.dual + + # multiple tables + Select A, B, C from Sys.dual, Table2 + + # invalid SELECT keyword - should fail + Xelect A, B, C from Sys.dual + + # incomplete command - should fail + Select + + # invalid column name - should fail + Select ^^^ frox Sys.dual + + """) + + pyparsing_common.number.runTests(""" + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + """) + + # any int or real number, returned as float + pyparsing_common.fnumber.runTests(""" + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + """) + + pyparsing_common.hex_integer.runTests(""" + 100 + FF + """) + + import uuid + pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID)) + pyparsing_common.uuid.runTests(""" + 12345678-1234-5678-1234-567812345678 + """) diff --git a/venv/lib/python3.7/site-packages/setuptools/_vendor/six.py b/venv/lib/python3.7/site-packages/setuptools/_vendor/six.py new file mode 100644 index 0000000..190c023 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/_vendor/six.py @@ -0,0 +1,868 @@ +"""Utilities for writing code that runs on Python 2 and 3""" + +# Copyright (c) 2010-2015 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 +# 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. + +from __future__ import absolute_import + +import functools +import itertools +import operator +import sys +import types + +__author__ = "Benjamin Peterson <benjamin@python.org>" +__version__ = "1.10.0" + + +# Useful for very coarse version differentiation. +PY2 = sys.version_info[0] == 2 +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, + text_type = str + binary_type = bytes + + MAXSIZE = sys.maxsize +else: + string_types = basestring, + integer_types = (int, long) + class_types = (type, types.ClassType) + text_type = unicode + binary_type = str + + if sys.platform.startswith("java"): + # Jython always uses 32 bits. + MAXSIZE = int((1 << 31) - 1) + 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: + # 32-bit + MAXSIZE = int((1 << 31) - 1) + else: + # 64-bit + MAXSIZE = int((1 << 63) - 1) + del X + + +def _add_doc(func, doc): + """Add documentation to a function.""" + func.__doc__ = doc + + +def _import_module(name): + """Import module, returning the module after the last dot.""" + __import__(name) + return sys.modules[name] + + +class _LazyDescr(object): + + def __init__(self, name): + self.name = name + + def __get__(self, obj, tp): + result = self._resolve() + setattr(obj, self.name, result) # Invokes __set__. + try: + # This is a bit ugly, but it avoids running this again by + # removing this descriptor. + delattr(obj.__class__, self.name) + except AttributeError: + pass + return result + + +class MovedModule(_LazyDescr): + + def __init__(self, name, old, new=None): + super(MovedModule, self).__init__(name) + if PY3: + if new is None: + new = name + self.mod = new + else: + self.mod = old + + def _resolve(self): + return _import_module(self.mod) + + def __getattr__(self, attr): + _module = self._resolve() + value = getattr(_module, attr) + setattr(self, attr, value) + return value + + +class _LazyModule(types.ModuleType): + + def __init__(self, name): + super(_LazyModule, self).__init__(name) + self.__doc__ = self.__class__.__doc__ + + def __dir__(self): + attrs = ["__doc__", "__name__"] + attrs += [attr.name for attr in self._moved_attributes] + return attrs + + # Subclasses should override this + _moved_attributes = [] + + +class MovedAttribute(_LazyDescr): + + def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): + super(MovedAttribute, self).__init__(name) + if PY3: + if new_mod is None: + new_mod = name + self.mod = new_mod + if new_attr is None: + if old_attr is None: + new_attr = name + else: + new_attr = old_attr + self.attr = new_attr + else: + self.mod = old_mod + if old_attr is None: + old_attr = name + self.attr = old_attr + + def _resolve(self): + module = _import_module(self.mod) + return getattr(module, self.attr) + + +class _SixMetaPathImporter(object): + + """ + A meta path importer to import six.moves and its submodules. + + This class implements a PEP302 finder and loader. It should be compatible + with Python 2.5 and all existing versions of Python3 + """ + + def __init__(self, six_module_name): + self.name = six_module_name + self.known_modules = {} + + def _add_module(self, mod, *fullnames): + for fullname in fullnames: + self.known_modules[self.name + "." + fullname] = mod + + def _get_module(self, fullname): + return self.known_modules[self.name + "." + fullname] + + def find_module(self, fullname, path=None): + if fullname in self.known_modules: + return self + return None + + def __get_module(self, fullname): + try: + return self.known_modules[fullname] + except KeyError: + raise ImportError("This loader does not know module " + fullname) + + def load_module(self, fullname): + try: + # in case of a reload + return sys.modules[fullname] + except KeyError: + pass + mod = self.__get_module(fullname) + if isinstance(mod, MovedModule): + mod = mod._resolve() + else: + mod.__loader__ = self + sys.modules[fullname] = mod + return mod + + def is_package(self, fullname): + """ + Return true, if the named module is a package. + + We need this method to get correct spec objects with + Python 3.4 (see PEP451) + """ + return hasattr(self.__get_module(fullname), "__path__") + + def get_code(self, fullname): + """Return None + + 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("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("range", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"), + MovedAttribute("reduce", "__builtin__", "functools"), + MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), + MovedAttribute("StringIO", "StringIO", "io"), + MovedAttribute("UserDict", "UserDict", "collections"), + MovedAttribute("UserList", "UserList", "collections"), + 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"), + MovedModule("builtins", "__builtin__"), + MovedModule("configparser", "ConfigParser"), + MovedModule("copyreg", "copy_reg"), + MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), + MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"), + MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), + MovedModule("http_cookies", "Cookie", "http.cookies"), + 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("BaseHTTPServer", "BaseHTTPServer", "http.server"), + MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), + MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), + MovedModule("cPickle", "cPickle", "pickle"), + MovedModule("queue", "Queue"), + MovedModule("reprlib", "repr"), + MovedModule("socketserver", "SocketServer"), + MovedModule("_thread", "thread", "_thread"), + MovedModule("tkinter", "Tkinter"), + MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), + MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), + MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), + MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), + MovedModule("tkinter_tix", "Tix", "tkinter.tix"), + 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_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), + MovedModule("tkinter_font", "tkFont", "tkinter.font"), + MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), + 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"), + MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), + MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), + MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"), +] +# Add windows specific modules. +if sys.platform == "win32": + _moved_attributes += [ + MovedModule("winreg", "_winreg"), + ] + +for attr in _moved_attributes: + setattr(_MovedItems, attr.name, attr) + if isinstance(attr, MovedModule): + _importer._add_module(attr, "moves." + attr.name) +del attr + +_MovedItems._moved_attributes = _moved_attributes + +moves = _MovedItems(__name__ + ".moves") +_importer._add_module(moves, "moves") + + +class Module_six_moves_urllib_parse(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_parse""" + + +_urllib_parse_moved_attributes = [ + MovedAttribute("ParseResult", "urlparse", "urllib.parse"), + MovedAttribute("SplitResult", "urlparse", "urllib.parse"), + MovedAttribute("parse_qs", "urlparse", "urllib.parse"), + MovedAttribute("parse_qsl", "urlparse", "urllib.parse"), + MovedAttribute("urldefrag", "urlparse", "urllib.parse"), + MovedAttribute("urljoin", "urlparse", "urllib.parse"), + MovedAttribute("urlparse", "urlparse", "urllib.parse"), + MovedAttribute("urlsplit", "urlparse", "urllib.parse"), + MovedAttribute("urlunparse", "urlparse", "urllib.parse"), + MovedAttribute("urlunsplit", "urlparse", "urllib.parse"), + MovedAttribute("quote", "urllib", "urllib.parse"), + MovedAttribute("quote_plus", "urllib", "urllib.parse"), + MovedAttribute("unquote", "urllib", "urllib.parse"), + MovedAttribute("unquote_plus", "urllib", "urllib.parse"), + MovedAttribute("urlencode", "urllib", "urllib.parse"), + MovedAttribute("splitquery", "urllib", "urllib.parse"), + MovedAttribute("splittag", "urllib", "urllib.parse"), + MovedAttribute("splituser", "urllib", "urllib.parse"), + MovedAttribute("uses_fragment", "urlparse", "urllib.parse"), + MovedAttribute("uses_netloc", "urlparse", "urllib.parse"), + MovedAttribute("uses_params", "urlparse", "urllib.parse"), + MovedAttribute("uses_query", "urlparse", "urllib.parse"), + MovedAttribute("uses_relative", "urlparse", "urllib.parse"), +] +for attr in _urllib_parse_moved_attributes: + setattr(Module_six_moves_urllib_parse, attr.name, attr) +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") + + +class Module_six_moves_urllib_error(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_error""" + + +_urllib_error_moved_attributes = [ + MovedAttribute("URLError", "urllib2", "urllib.error"), + MovedAttribute("HTTPError", "urllib2", "urllib.error"), + MovedAttribute("ContentTooShortError", "urllib", "urllib.error"), +] +for attr in _urllib_error_moved_attributes: + setattr(Module_six_moves_urllib_error, attr.name, attr) +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") + + +class Module_six_moves_urllib_request(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_request""" + + +_urllib_request_moved_attributes = [ + MovedAttribute("urlopen", "urllib2", "urllib.request"), + MovedAttribute("install_opener", "urllib2", "urllib.request"), + MovedAttribute("build_opener", "urllib2", "urllib.request"), + MovedAttribute("pathname2url", "urllib", "urllib.request"), + MovedAttribute("url2pathname", "urllib", "urllib.request"), + MovedAttribute("getproxies", "urllib", "urllib.request"), + MovedAttribute("Request", "urllib2", "urllib.request"), + MovedAttribute("OpenerDirector", "urllib2", "urllib.request"), + MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"), + MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), + MovedAttribute("BaseHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), + MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"), + MovedAttribute("FileHandler", "urllib2", "urllib.request"), + MovedAttribute("FTPHandler", "urllib2", "urllib.request"), + MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"), + MovedAttribute("UnknownHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"), + MovedAttribute("urlretrieve", "urllib", "urllib.request"), + MovedAttribute("urlcleanup", "urllib", "urllib.request"), + MovedAttribute("URLopener", "urllib", "urllib.request"), + MovedAttribute("FancyURLopener", "urllib", "urllib.request"), + MovedAttribute("proxy_bypass", "urllib", "urllib.request"), +] +for attr in _urllib_request_moved_attributes: + setattr(Module_six_moves_urllib_request, attr.name, attr) +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") + + +class Module_six_moves_urllib_response(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_response""" + + +_urllib_response_moved_attributes = [ + MovedAttribute("addbase", "urllib", "urllib.response"), + MovedAttribute("addclosehook", "urllib", "urllib.response"), + MovedAttribute("addinfo", "urllib", "urllib.response"), + MovedAttribute("addinfourl", "urllib", "urllib.response"), +] +for attr in _urllib_response_moved_attributes: + setattr(Module_six_moves_urllib_response, attr.name, attr) +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") + + +class Module_six_moves_urllib_robotparser(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_robotparser""" + + +_urllib_robotparser_moved_attributes = [ + 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 + +_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") + request = _importer._get_module("moves.urllib_request") + response = _importer._get_module("moves.urllib_response") + robotparser = _importer._get_module("moves.urllib_robotparser") + + def __dir__(self): + return ['parse', 'error', 'request', 'response', 'robotparser'] + +_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"), + "moves.urllib") + + +def add_move(move): + """Add an item to six.moves.""" + setattr(_MovedItems, move.name, move) + + +def remove_move(name): + """Remove item from six.moves.""" + try: + delattr(_MovedItems, name) + except AttributeError: + try: + del moves.__dict__[name] + except KeyError: + raise AttributeError("no such move, %r" % (name,)) + + +if PY3: + _meth_func = "__func__" + _meth_self = "__self__" + + _func_closure = "__closure__" + _func_code = "__code__" + _func_defaults = "__defaults__" + _func_globals = "__globals__" +else: + _meth_func = "im_func" + _meth_self = "im_self" + + _func_closure = "func_closure" + _func_code = "func_code" + _func_defaults = "func_defaults" + _func_globals = "func_globals" + + +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 + + create_bound_method = types.MethodType + + def create_unbound_method(func, cls): + return func + + Iterator = object +else: + def get_unbound_function(unbound): + return unbound.im_func + + def create_bound_method(func, obj): + return types.MethodType(func, obj, obj.__class__) + + def create_unbound_method(func, cls): + 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""") + + +get_method_function = operator.attrgetter(_meth_func) +get_method_self = operator.attrgetter(_meth_self) +get_function_closure = operator.attrgetter(_func_closure) +get_function_code = operator.attrgetter(_func_code) +get_function_defaults = operator.attrgetter(_func_defaults) +get_function_globals = operator.attrgetter(_func_globals) + + +if PY3: + def iterkeys(d, **kw): + return iter(d.keys(**kw)) + + def itervalues(d, **kw): + return iter(d.values(**kw)) + + def iteritems(d, **kw): + return iter(d.items(**kw)) + + def iterlists(d, **kw): + return iter(d.lists(**kw)) + + viewkeys = operator.methodcaller("keys") + + viewvalues = operator.methodcaller("values") + + viewitems = operator.methodcaller("items") +else: + def iterkeys(d, **kw): + return d.iterkeys(**kw) + + def itervalues(d, **kw): + return d.itervalues(**kw) + + def iteritems(d, **kw): + return d.iteritems(**kw) + + def iterlists(d, **kw): + return d.iterlists(**kw) + + viewkeys = operator.methodcaller("viewkeys") + + viewvalues = operator.methodcaller("viewvalues") + + viewitems = operator.methodcaller("viewitems") + +_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.") + + +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 + _assertCountEqual = "assertCountEqual" + if sys.version_info[1] <= 1: + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" + else: + _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") + unichr = unichr + int2byte = chr + + def byte2int(bs): + return ord(bs[0]) + + def indexbytes(buf, i): + return ord(buf[i]) + iterbytes = functools.partial(itertools.imap, ord) + import StringIO + StringIO = BytesIO = StringIO.StringIO + _assertCountEqual = "assertItemsEqual" + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" +_add_doc(b, """Byte literal""") +_add_doc(u, """Text literal""") + + +def assertCountEqual(self, *args, **kwargs): + return getattr(self, _assertCountEqual)(*args, **kwargs) + + +def assertRaisesRegex(self, *args, **kwargs): + return getattr(self, _assertRaisesRegex)(*args, **kwargs) + + +def assertRegex(self, *args, **kwargs): + return getattr(self, _assertRegex)(*args, **kwargs) + + +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 + +else: + def exec_(_code_, _globs_=None, _locs_=None): + """Execute code in a namespace.""" + if _globs_ is None: + frame = sys._getframe(1) + _globs_ = frame.f_globals + if _locs_ is None: + _locs_ = frame.f_locals + del frame + elif _locs_ is None: + _locs_ = _globs_ + exec("""exec _code_ in _globs_, _locs_""") + + exec_("""def reraise(tp, value, tb=None): + raise tp, value, tb +""") + + +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 +""") +elif sys.version_info[:2] > (3, 2): + exec_("""def raise_from(value, from_value): + raise value from from_value +""") +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) + if fp is None: + return + + def write(data): + 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): + 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: + if isinstance(sep, unicode): + want_unicode = True + elif not isinstance(sep, str): + raise TypeError("sep must be None or a string") + end = kwargs.pop("end", None) + if end is not None: + if isinstance(end, unicode): + want_unicode = True + elif not isinstance(end, str): + raise TypeError("end must be None or a string") + if kwargs: + raise TypeError("invalid keyword arguments to print()") + if not want_unicode: + for arg in args: + if isinstance(arg, unicode): + want_unicode = True + break + if want_unicode: + newline = unicode("\n") + space = unicode(" ") + else: + newline = "\n" + space = " " + if sep is None: + sep = space + if end is None: + end = newline + for i, arg in enumerate(args): + if i: + write(sep) + write(arg) + write(end) +if sys.version_info[:2] < (3, 3): + _print = print_ + + def print_(*args, **kwargs): + fp = kwargs.get("file", sys.stdout) + flush = kwargs.pop("flush", False) + _print(*args, **kwargs) + 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 wrapper(f): + f = functools.wraps(wrapped, assigned, updated)(f) + f.__wrapped__ = wrapped + return f + return wrapper +else: + wraps = functools.wraps + + +def with_metaclass(meta, *bases): + """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): + + def __new__(cls, name, this_bases, d): + return meta(name, bases, d) + 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__') + 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) + return metaclass(cls.__name__, cls.__bases__, orig_vars) + return wrapper + + +def python_2_unicode_compatible(klass): + """ + A 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 + 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__) + klass.__unicode__ = klass.__str__ + klass.__str__ = lambda self: self.__unicode__().encode('utf-8') + return klass + + +# Complete the moves implementation. +# This code is at the end of this module to speed up module loading. +# Turn this module into a package. +__path__ = [] # required for PEP 302 and PEP 451 +__package__ = __name__ # see PEP 366 @ReservedAssignment +if globals().get("__spec__") is not None: + __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable +# Remove other six meta path importers, since they cause problems. This can +# happen if six is removed from sys.modules and then reloaded. (Setuptools does +# this for some reason.) +if sys.meta_path: + for i, importer in enumerate(sys.meta_path): + # Here's some real nastiness: Another "instance" of the six module might + # 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__): + del sys.meta_path[i] + break + del i, importer +# Finally, add the importer to the meta path import hook. +sys.meta_path.append(_importer) diff --git a/venv/lib/python3.7/site-packages/setuptools/archive_util.py b/venv/lib/python3.7/site-packages/setuptools/archive_util.py new file mode 100644 index 0000000..8143604 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/archive_util.py @@ -0,0 +1,173 @@ +"""Utilities for extracting common archive formats""" + +import zipfile +import tarfile +import os +import shutil +import posixpath +import contextlib +from distutils.errors import DistutilsError + +from pkg_resources import ensure_directory + +__all__ = [ + "unpack_archive", "unpack_zipfile", "unpack_tarfile", "default_filter", + "UnrecognizedFormat", "extraction_drivers", "unpack_directory", +] + + +class UnrecognizedFormat(DistutilsError): + """Couldn't recognize the archive type""" + + +def default_filter(src, dst): + """The default progress/filter callback; returns True for all files""" + return dst + + +def unpack_archive(filename, extract_dir, progress_filter=default_filter, + drivers=None): + """Unpack `filename` to `extract_dir`, or raise ``UnrecognizedFormat`` + + `progress_filter` is a function taking two arguments: a source path + internal to the archive ('/'-separated), and a filesystem path where it + will be extracted. The callback must return the desired extract path + (which may be the same as the one passed in), or else ``None`` to skip + that file or directory. The callback can thus be used to report on the + progress of the extraction, as well as to filter the items extracted or + alter their extraction paths. + + `drivers`, if supplied, must be a non-empty sequence of functions with the + same signature as this function (minus the `drivers` argument), that raise + ``UnrecognizedFormat`` if they do not support extracting the designated + archive type. The `drivers` are tried in sequence until one is found that + does not raise an error, or until all are exhausted (in which case + ``UnrecognizedFormat`` is raised). If you do not supply a sequence of + drivers, the module's ``extraction_drivers`` constant will be used, which + means that ``unpack_zipfile`` and ``unpack_tarfile`` will be tried, in that + order. + """ + for driver in drivers or extraction_drivers: + try: + driver(filename, extract_dir, progress_filter) + except UnrecognizedFormat: + continue + else: + return + else: + raise UnrecognizedFormat( + "Not a recognized archive type: %s" % filename + ) + + +def unpack_directory(filename, extract_dir, progress_filter=default_filter): + """"Unpack" a directory, using the same interface as for archives + + Raises ``UnrecognizedFormat`` if `filename` is not a directory + """ + if not os.path.isdir(filename): + raise UnrecognizedFormat("%s is not a directory" % filename) + + paths = { + filename: ('', extract_dir), + } + for base, dirs, files in os.walk(filename): + src, dst = paths[base] + for d in dirs: + paths[os.path.join(base, d)] = src + d + '/', os.path.join(dst, d) + for f in files: + target = os.path.join(dst, f) + target = progress_filter(src + f, target) + if not target: + # skip non-files + continue + ensure_directory(target) + f = os.path.join(base, f) + shutil.copyfile(f, target) + shutil.copystat(f, target) + + +def unpack_zipfile(filename, extract_dir, progress_filter=default_filter): + """Unpack zip `filename` to `extract_dir` + + Raises ``UnrecognizedFormat`` if `filename` is not a zipfile (as determined + by ``zipfile.is_zipfile()``). See ``unpack_archive()`` for an explanation + of the `progress_filter` argument. + """ + + if not zipfile.is_zipfile(filename): + raise UnrecognizedFormat("%s is not a zip file" % (filename,)) + + with zipfile.ZipFile(filename) as z: + for info in z.infolist(): + name = info.filename + + # don't extract absolute paths or ones with .. in them + if name.startswith('/') or '..' in name.split('/'): + continue + + target = os.path.join(extract_dir, *name.split('/')) + target = progress_filter(name, target) + if not target: + continue + if name.endswith('/'): + # directory + ensure_directory(target) + else: + # file + ensure_directory(target) + data = z.read(info.filename) + with open(target, 'wb') as f: + f.write(data) + unix_attributes = info.external_attr >> 16 + if unix_attributes: + os.chmod(target, unix_attributes) + + +def unpack_tarfile(filename, extract_dir, progress_filter=default_filter): + """Unpack tar/tar.gz/tar.bz2 `filename` to `extract_dir` + + Raises ``UnrecognizedFormat`` if `filename` is not a tarfile (as determined + by ``tarfile.open()``). See ``unpack_archive()`` for an explanation + of the `progress_filter` argument. + """ + try: + tarobj = tarfile.open(filename) + except tarfile.TarError: + raise UnrecognizedFormat( + "%s is not a compressed or uncompressed tar file" % (filename,) + ) + with contextlib.closing(tarobj): + # don't do any chowning! + tarobj.chown = lambda *args: None + for member in tarobj: + name = member.name + # don't extract absolute paths or ones with .. in them + if not name.startswith('/') and '..' not in name.split('/'): + prelim_dst = os.path.join(extract_dir, *name.split('/')) + + # resolve any links and to extract the link targets as normal + # files + while member is not None and (member.islnk() or member.issym()): + linkpath = member.linkname + if member.issym(): + base = posixpath.dirname(member.name) + linkpath = posixpath.join(base, linkpath) + linkpath = posixpath.normpath(linkpath) + member = tarobj._getmember(linkpath) + + if member is not None and (member.isfile() or member.isdir()): + final_dst = progress_filter(name, prelim_dst) + if final_dst: + if final_dst.endswith(os.sep): + final_dst = final_dst[:-1] + try: + # XXX Ugh + tarobj._extract_member(member, final_dst) + except tarfile.ExtractError: + # chown/chmod/mkfifo/mknode/makedev failed + pass + return True + + +extraction_drivers = unpack_directory, unpack_zipfile, unpack_tarfile diff --git a/venv/lib/python3.7/site-packages/setuptools/build_meta.py b/venv/lib/python3.7/site-packages/setuptools/build_meta.py new file mode 100644 index 0000000..0067a7a --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/build_meta.py @@ -0,0 +1,182 @@ +"""A PEP 517 interface to setuptools + +Previously, when a user or a command line tool (let's call it a "frontend") +needed to make a request of setuptools to take a certain action, for +example, generating a list of installation requirements, the frontend would +would call "setup.py egg_info" or "setup.py bdist_wheel" on the command line. + +PEP 517 defines a different method of interfacing with setuptools. Rather +than calling "setup.py" directly, the frontend should: + + 1. Set the current directory to the directory with a setup.py file + 2. Import this module into a safe python interpreter (one in which + setuptools can potentially set global variables or crash hard). + 3. Call one of the functions defined in PEP 517. + +What each function does is defined in PEP 517. However, here is a "casual" +definition of the functions (this definition should not be relied on for +bug reports or API stability): + + - `build_wheel`: build a wheel in the folder and return the basename + - `get_requires_for_build_wheel`: get the `setup_requires` to build + - `prepare_metadata_for_build_wheel`: get the `install_requires` + - `build_sdist`: build an sdist in the folder and return the basename + - `get_requires_for_build_sdist`: get the `setup_requires` to build + +Again, this is not a formal definition! Just a "taste" of the module. +""" + +import os +import sys +import tokenize +import shutil +import contextlib + +import setuptools +import distutils + + +class SetupRequirementsError(BaseException): + def __init__(self, specifiers): + self.specifiers = specifiers + + +class Distribution(setuptools.dist.Distribution): + def fetch_build_eggs(self, specifiers): + raise SetupRequirementsError(specifiers) + + @classmethod + @contextlib.contextmanager + def patch(cls): + """ + Replace + distutils.dist.Distribution with this class + for the duration of this context. + """ + orig = distutils.core.Distribution + distutils.core.Distribution = cls + try: + yield + finally: + distutils.core.Distribution = orig + + +def _to_str(s): + """ + Convert a filename to a string (on Python 2, explicitly + a byte string, not Unicode) as distutils checks for the + exact type str. + """ + if sys.version_info[0] == 2 and not isinstance(s, str): + # Assume it's Unicode, as that's what the PEP says + # should be provided. + return s.encode(sys.getfilesystemencoding()) + return s + + +def _run_setup(setup_script='setup.py'): + # Note that we can reuse our build directory between calls + # Correctness comes first, then optimization later + __file__ = setup_script + __name__ = '__main__' + f = getattr(tokenize, 'open', open)(__file__) + code = f.read().replace('\\r\\n', '\\n') + f.close() + exec(compile(code, __file__, 'exec'), locals()) + + +def _fix_config(config_settings): + config_settings = config_settings or {} + config_settings.setdefault('--global-option', []) + return config_settings + + +def _get_build_requires(config_settings, requirements): + config_settings = _fix_config(config_settings) + + sys.argv = sys.argv[:1] + ['egg_info'] + \ + config_settings["--global-option"] + try: + with Distribution.patch(): + _run_setup() + except SetupRequirementsError as e: + requirements += e.specifiers + + return requirements + + +def _get_immediate_subdirectories(a_dir): + return [name for name in os.listdir(a_dir) + if os.path.isdir(os.path.join(a_dir, name))] + + +def get_requires_for_build_wheel(config_settings=None): + config_settings = _fix_config(config_settings) + return _get_build_requires(config_settings, requirements=['setuptools', 'wheel']) + + +def get_requires_for_build_sdist(config_settings=None): + config_settings = _fix_config(config_settings) + return _get_build_requires(config_settings, requirements=['setuptools']) + + +def prepare_metadata_for_build_wheel(metadata_directory, config_settings=None): + sys.argv = sys.argv[:1] + ['dist_info', '--egg-base', _to_str(metadata_directory)] + _run_setup() + + dist_info_directory = metadata_directory + while True: + 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: + dist_info_directory = os.path.join( + dist_info_directory, os.listdir(dist_info_directory)[0]) + continue + + assert len(dist_infos) == 1 + break + + # PEP 517 requires that the .dist-info directory be placed in the + # metadata_directory. To comply, we MUST copy the directory to the root + if dist_info_directory != metadata_directory: + shutil.move( + os.path.join(dist_info_directory, dist_infos[0]), + metadata_directory) + shutil.rmtree(dist_info_directory, ignore_errors=True) + + return dist_infos[0] + + +def build_wheel(wheel_directory, config_settings=None, + metadata_directory=None): + config_settings = _fix_config(config_settings) + wheel_directory = os.path.abspath(wheel_directory) + sys.argv = sys.argv[:1] + ['bdist_wheel'] + \ + config_settings["--global-option"] + _run_setup() + if wheel_directory != 'dist': + shutil.rmtree(wheel_directory) + shutil.copytree('dist', wheel_directory) + + wheels = [f for f in os.listdir(wheel_directory) + if f.endswith('.whl')] + + assert len(wheels) == 1 + return wheels[0] + + +def build_sdist(sdist_directory, config_settings=None): + config_settings = _fix_config(config_settings) + sdist_directory = os.path.abspath(sdist_directory) + sys.argv = sys.argv[:1] + ['sdist'] + \ + config_settings["--global-option"] + \ + ["--dist-dir", sdist_directory] + _run_setup() + + sdists = [f for f in os.listdir(sdist_directory) + if f.endswith('.tar.gz')] + + assert len(sdists) == 1 + return sdists[0] diff --git a/venv/lib/python3.7/site-packages/setuptools/cli-32.exe b/venv/lib/python3.7/site-packages/setuptools/cli-32.exe new file mode 100644 index 0000000000000000000000000000000000000000..b1487b7819e7286577a043c7726fbe0ca1543083 GIT binary patch literal 65536 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[c}i<OXTz6k>I#RErv3nvcIClH@!{vM)zJ_weD zu_-L8NU*G<xQC7$Bg`f~d>lC{d0L!!VW10^+~>qmNB~Y8H+F}!P8_d(PpvjzMJQmr z)F<LB!IdzF`7%cck^aLb_J<@DD#CfB0B$E^bzV@-Vr`q!&`=<s^68_Wa_GZ_v^?aY zU=VZGXAzm5x{LcyVkUd8JxnNsqtS!3fw-nje@5tui@0AmI$b-*P5O7)s<z9AVj!{a zusK!aLirXkGmKBs9|=}}+<^)RB1ao<^{^>kX;2B~<|3JfJeWv@IXo~nTtp$}Gjie> zs8UDG*kid(%i5QCBp~MA;#I186PI-nZ&k7!k8BiLJSuR>h7ArSYHD~<iO|JiNP|OD zR=9Lm@@Ua+Eq87EAwAZBPGrH*)zP)xEF>B0I<PUu3WRluor4HwG59U@*GT3C4#)*> z=T6L{zqglekt0JjG5z&|GWb4?+B5+{p^fgTufl_KesA{@I&g7rNq==^SGc5GcM%$N zDBG2)qExz*Z;jGN_-iD-y8i2BCq)p}2lKcspLg>w-;qwg(()HXrZa3jd!}spuwBVX zwmX!iwU<Qo&ds@10tJ4pnneT?LI)M|HS1v7YY$x9Bv-SsJ$Cl+xPAV;6Eqk-srxG9 z{LT5_#k!V#{GO}ibh%Xvw5jxHs@yzGY~@?`(yJD$GqsX;X$pypI5DT^o5eVu9#Z@z zw!tumU}_j8#vZXTB&Vb!;K(WYBw))aIfHo=I@urFFfxYS9PyXWVFQN5U;5Dw%tIz$ zw`nTQR_c;mZr;Y5QwPf3_^KR#GvcZKkFXD~jQGWdi~_bGh!>?#7uoQnunw|OlU~+c z^L5Ak3zWhaA4B^FhMMboO0k*O2GL)lD9_<$5b>czbCvKcSt+u*gA*=%dH>Q-Bc11h zzO7jbXN)&5mBf=w2anK6P$YcJZQoWa2#E!v{hFKxxm7Fc)Fc9iC35{|Lp7bIDjrhC zgMiGf4r2yquH{U7WdMio;XS4Y%Ry{q7#kv#gZ07i`7eo#MMh_o68E*Fd_#nrri^4b zX+slbsv>+8pmck%oLDU<yTk`c&RTk8mVQAOK~qMQ#2raos*zaqlvJZo>L()8NRJ#Z z8DReF_eq2zsjEXGs)yS{k}ykS1B!ZrY0f6O65^lslJv3g&wfpDg-&EwF8wrc=hSwm zPlV&n%%yE_@onOwK?)`GNJ6MQ0drMuBYWCH5dkD)uErh@*k}#GcFl<-;;TN+5vb|b zctkCv;*zL7f)A;QuO%(81r0)&aUz4EQu;kA!k@7i8RZ)koMaWW`5cC6n@{w!!J$5d zx}l)4VP4xL=BKi&c^{n_Qi`q@G{vimblcVR53b#<Dz&@nl0LRIeY=p^I1%{g=J)$y zJ4tny{}tcKG0i7qLLJtU;jl;LnJu8bQak(kB&;UDjom{#=dp=&3s}YXYz3C()*?Ie zpOr>*X$FUOQFm!A8JKahNSiBdY+x3bJZfD8n{--FLUM4+Mx@{vM<W!B9QJEa7>_ep zkk)U=K8R(rhU(X_faI*ZO}cn`5t*O}lx^j8|0rt-)o=Axn^DGcQTi!#7hxLTq?|HQ zB;T6(nrsCeYK0_o%)IO+CP{n#+|;w1ZmvD2c-J{i88bp63RjyKOE!B!D3U{RCs*Zh z&^%65VM(J34230U4bHS}M@SYS9TEK}c%)2<$h1|T;##zRtjRt@#1T%J=kAhOiw+Z% z7DpyWVK@6%9K^uVD9LDKj)dR^aZK6$@Lt)l;sj@`QSzBm{TlLG{JKM_^60Zr2w~nr zr>P-BaV8OjjWm?hQ3$ZCx+lyD%q`~4iNF9xWKi$t&pzBhwN9Dq-o^v9@=abLR#|<P zZAhQVQAqt{KX8b!o72`jV*h~V{I<6~6`|CSYi!tcFRq-OP_ri!l#8;keBk$FyRh37 zh-vx<nho1V<uSlQEH;(ry7_afSZop_PK$8boQKoq+i)shoyMOs4}aFK<j<xGJnq14 zb2)CC*WtE#b4An68qy4#ciQ16Pbjcq3r`~(syir#2qbbvYtKWddcXwdfk_9bi9C9n ze)1pT^3siP-~5MsCpR}_o2eh^LneJBm*p>KZqkLal4YCRR9VNhIM|rBqmzzcImvcx z66fD`zj4}M-A;gyA17cSC-oI$`q?*q&8~)Qv|C#(aSFd|hYbf}FFVB?n3Q?Svt+Td z#AW4x=9X}?aizE|`r{}3l-H&b6-{_j#STR!lD001vu;K>KT;*^ChCevBwCMFpg{JI zv``4YsjK1&142Pl%%A#u3rbGso1<_fngd1`+}!pMu@z5Me_5UFxiPYKqFL4_`WXmY zeWJrZUKzrrMuBcHupOq4Wr12sE*T-*CXh;FA=)Q+BMN(?DJ!kq?%Ww`xlG3e;lz2t zY?tl;i?gHO_79VwJ_cThq^>FqRUPlqS?IuI+CfSbNkv_1l~7eGaCwRmuOF|ic1ac2 z9ldo$TN~LhX~J01P75nyi&d8=Y@QNZ5e<=6v_R3rM}nN}5ae`^LV&sAD<=;*z=!~` zvJ0@i!orMuT*5kyXNzJnxfU!+#FTW(syy@yj7XX8#zD_9TWBSg(;KZ25VO;is;-&R zf(29n3U}agkC`j4sjX{=`D1EkCC@enOA~v{GOLYQKAdPN6+?W+QE4fLMhrW4RG<SI z@?qI-KY>bH5^K(rm4T}`=ra<6GP2}cRBE9K8^r(O+ZvKpJDL~qNguPmwQZp-8m7V@ zN^KFU8@Q*E7UJswZD=OYtct4KqA&NDKSOfc-#M>@o#)4;YLqtENdFS^3K9&dFBr|M z*loqE3X2sMmi8hv#7H5<kgna*Z>rqGc_y=ShEbHT^m7S`?4d%B+(-6dYGI-*t5E+< z^P3gqvBIHjFQNKiDKj-p;Y*MmMAXOK^8{gVhrBn?Un}%9(JqaGPiann?Ll$aX-{n1 z!AnT<v!xN*zo+dH+)yR$d)}fNUUOcJ)Xz$%vH5mur0%L;@p((;IW$raH52Q@7``Z{ z?rO>WyjwZ7y=hrziEYVZVX)-}D^!8a+Bc<5#*3h1xvWqS7I$WL>iwNNvp;P<;TX`| zOF6ZibFB4T(YJC~mj~?Ev*ln|9sgYVFTcLiEi{YE;!ZWj>X*aK9|va;HulW-D`RH9 zw=O#R&of(j+rwMS%oCi;+oFskQ}@q2q4x)O3<fKs&%WtzzFD};-G{Hxx)V?F$WHWF z7(*i07&g=2&}`P4G>k5e6yDx`kLvQs@M`+D)vGA+`X6%Dl9YOA?Qrurfg>XqT9E@^ zgWxOT&hX+yo>7=HCb!3BO$p54I3{j@qbN!+nu>Ti*O~vw`5RU!f_JXS+*x#-zFp@m zr}GGVhgT1=p-TFp#dtAVjM3QdpDoi{l*z?1s=d~(E;Fkn=*i8+oB<M)E&5W?I^M)M zknOw+hdKDcP%Q}tuai)WoEa!7&-Iumsf3KA>cJ3Ib?Vh+rZWNZ$pO`dl8LcBv_cAA zc18lYB|rc<0u%wEdTGEup|%_S`L>@ui4LTkvnNApm<q=y*er!iCv8V>#>+b4WIF<} z^J}=w7L&$J%unXCb|Wy{z3WVlMDNhz3o7S-3)6oqjx)7WX0HTEH<C-Do)>{-=9>q+ zXXtoVPHKfVJMk8bt&h;MII}u~0l79^#`5CdW6Ef!eb|E&Q{UJ$n$yP;^Jd)qhw~ej zB?c~nN*%0zm%$}MD%|<q*x?^2$-sGY)_qDIsjoQeKH{k^*%_~Mm`JG>VZuS8W+Qtf zS+Uu?;oSPL<h#s;p3UgxZ3c;@9(LZhh9?&RH`z;Ufi?^GL|RbrQ|i$u#k>L}G`jMH zn3`(J{6K%B(Gykos(!d}z)Wr!%sjC6=V@s)qG1MJN~uoVlq{jeI#XKPMI;@L^`RBZ z<X%K$e<C_&9&p~HQ%fuI$-p5?U{jDsR}QoVqzzw}E77mP5v&U`27f1F&0F8zlxE2) ze=M@fh-;2;q_!ewec2frY%fKQkh6Y#Ck=~JBu;z6vOFXzd7O1mkt`yaC)8Gn>0Fhm zEI{|uQr0z1gk4W{mj*%4Z*00DBL5ko{4X}2{Dl0wAi#aSmq_r~FBHL|;}P&0k>OU! zhx64h5vSKwffV0W4JQs2dFBrfQx(B{AK=BGc`U!}S&BFnE6QSvw?`~m^}8j(4$IzQ z_WzjR?fD!VI8Aa=N;O96$f<JeDN}@@k24)dnpa7nV{o~|y480HWd%qi09M-w5HA7H z5t)dJA9OeU2(Ddz+nofIxgaM#sfN{v)}n+p872aEFyGb(<(TUTpJ(1Bv9RRP<lWbe zn*X9W;yA^EqlAv1#u2Gg|1wrNw~{@z1W#o_GFNuVYLs|BsZ*hkg_h`Il0YDiCHm+W zmS~Y0wwCC%sMd>IWzW@IV2KtfOm4MwFVU~FM5pwL+-yY-+$4mvEEjvjP+5JUm8n(w zTE>U0(q9W!VAi2soP~_07HUw%Pt_tTYxD^79a6Fw-(PjP4xwLxv3Ycv!%RV}m`xvC zX`nx*(H@IF+EJ)392Ul)-t@Oj>L>VGb7%C~V}eWde6yYkCcYR2>L5_BFiz*D#3I_* zY)|v0XvW#xv=Y0=d;t!!=&NUW2H8t2>2H>>rUwQga=@Hd8s$Z+x+rNk0%K7J*cGvn za#2GFTwHgcx}(hY&AoeJJ>OtvvdouZfGLkWz?5@JX6KrhfDJ0`xz(qU+f2hY)2ykx zl5dMrs#`m^OO;aljpVNpXHI7j?NBazjFr-P<5NZ{lysyym6ILI!i}auR#r=s8-sHH zo|F}x&aDr!mLdRfA3dBON<#lrL!uSm7=o9syd*hDuX`F0HkX``(5Ixonj|KOyUg3^ zQc-Q1zi|oXoEJ7t`z@l)r8HbVnV=3@R147(4T%Z?MF>|u+vhb+dmd}f?PMV8SW8Om zNGeF;<~ukE61hiT7Fejt`7XmU^|R{ev+p#`i$*Qly)%e2TjDu=LV)p<*h6u5gyTBv zF2X}pxW+%<Fj!P}AZas9RZ`k$Jvv1owwn8%W?{}x!+bkqQCghlz9l!;d?w_cXMXg@ z&=}JPT7tF@L2ahnMB72@q!wG|Y3@>;eRIVAvq#45Tg=WlQSFR|)0f>5G`p(9xM7}| zFKtPEbWZkN=1qLjD*3c&W=C5QZ78nOyIt7^bEIKqkTQs5B8y0Tx?-c7F3RU`pPOs` z_?hl<U&@p~CMd0Mfz5AN1#S&Vwsi0NvWloHbK|_KEOMjJm}q8E=E&9JuvOv6IZ8ov zcoQ8$o#cQM?=kPAi}LePW480inT%^k+4bRRjjowT_3NF_?RV~cwfUrD02;pIjR9GK zQO@U%q%4cq2SOIu>A-(AYe*|k@#n%-mt4P66m+?M)nmWXqWP-^>As_PEzQPQQFQR8 z8-h3Q39C3Q91oVz2*#A-KL%2bY;8!cmJ9uHA`|<v{z~0`eQ`+GHZb5=o_|mCd#>C8 z$NX`>3!Xc-34zzMQ(s0p^HbkPL0@}t>MK)QkhQHnsYONA8Y3sjLq95yD8o_vXX;;L z>_rtUVz~Yrx{&>y!BX_$%=h%m(WLsmNbc^@hvIY`rx=`G3p{Y^ZC06YKwy@l-|)Hh zU=6u>PjJFvP!kJ(Tc+sbM_EIjrY|G=W}4NvvWB>k^nM4`K&TNt=8t0byviN1Lph6= zm_yLKL?eam;`vUGWXllNQpvgH+$3sPb_yL=Bg|EjmK*vv&mK-$JqW8%=|ASK>2#&P z_Hr|Y5Dkgu7#^X*C_?v-?p6bh!n7?WmSW!JeSwnSm}M7T5((zV1Sgd@d05#6N@`iq zIof-m%Wyrh&Os_zmvwFpf)UBIy{<8BeDtovo%NaL&_|tBV$bJ-C;E$apFPY)zG1$1 z&owMVml>CDJKAdL5zE6EYkt$pYmLfF?wDG0`I8N*#DQu4-A7E6KcN`U27=18Fz;s6 zgRIKZJ=&bE;>8osoUL9Ryh=TbC>SSDx$a_ae4Sb3Y{(ciQKVJ&x*C=an(TMl4xLH2 zXX$$5{C?<{&`X7#bw|C!?@WU>(wf=M60Egk4C)t`yyBd`(C=(qFld4VoFf6R4+pHN zK8Ll6cJ>?zJRuIOK|)?8A%{uGgm6egv3W?S%i_2=V{%GzdHk`#X)(c}lhxAXtow#+ zFHp)}cHUdTEBD@=-@HTIVx!PQ#~t7^T8*<#^hS~|xc9~6%di^At;m{`IHO;U1JyJ& z?$6LV#Y%45gWjnIu3a5-`VNydN5;meS;L)mKjUK-hMMbbbJA&Cbq9~|S=gw!q$wS} z<Z(t^y7;u%;xGk;LG3lcOw_zt$NHvB?!ZTuJIo+vtIY)W*7UDg7nZYhgoJ`|`U@?# zf&SRW>>!$M`UNJWuIMmgl*gmkLk_ZS(?`c%lMZ(&XFK8NP#)0^vSl6vFEG>}Yt=qY z>WCarV-#iQR(@uObO3d9Zj~Ae<}6f(n;Hky?Oz`=r|lj-I0#^gmZN5;ee)19uN-uf zbLW7xnioz$Qqpv@afoy00q1WU<dahvrqv*^Tb#kb-RY_O47=@EAgz1AjGqJEU%$BD z#{P{%{LcENgC^i$Gs0h&&6#v8aM9Ug50ykMQMk~#qpD^cswS=IIHD-)jLMD@Eu?Zl zXzx^j#tYp#^O##HK)x^gH2Y8oBzw6P^DLtqvNE>|&pEgH8343To6masFPXZZ+i2fw zw(TOJh6NWV1zH#tgBTU7eP2E-U^0`E%lVvRweM3##v6R|Hc)r2ZWu6UP8uu_SKF^7 z5Ei+b&tX|(bW>KeN_C)b7q?VhC2@*pFT<#gaK20zQb%f_ppm8Xf&=AdHBgp?2g=0N zzUt06{THYVS>0fh!O|&%MP5GTWr9DpB_rmtxWJV%cw()<Th-`+9pNw^epR)x<&H5y zNn}p<5E>yvDADh1(g)ek#K;gD6diD^_G>B>y~3*2ri=>?y@k#|fr6r^y=jEkKl3E7 z4M}aqf+KgXac<4$1&vT`xA250AV##H0=5ek@I!)vK3Iwme$0oDmHS)WNy*wIdYTYj zZRu7LFxIS58JMfP!&x-K4>+HK()5vW=nSz9Me#w3T`4{giqU44ixK<NS-`KgQcF~+ z$)Xx~#$%3oPu5N7C1^%ShRb#_>rd!tunBaOeaO;`@Gg0VSi}FyYeUlc*jfuoTFFEd zOR8Z4RTBHrnM_v=qLS_KTIyGvYt1|?i!+C4y??`sV=b9MS0Ju6Q)C6T`W3;Z%o85d ziENh~l0#_RtCgzGELP8JHB9M!#^AHfT3W1T^h?P+q1$V+gEe9y%{FPzuSsRs@Ay-r z&&$%MWa*cg*GZ8R;SHL@d5gHczoSYe+a|;+l&uAZooROH4pP=g`GeNXPLfFzb`#S1 z2_-JE19Kg4B`^wb`OGw9drEbu!t~n%qeIJiU}$Ld55)5#)skz}?aZlPlQ8z#UJ#-| zYO^vmzd2P;V*j5ETWQQ}A;NIjCB|%xCEmF;jXrG6JdLv!xSAK@X@Sdl!B-26nk^;Q zowGGGn&>N2cRRN_tq77S`L(hZ^0u`V19Af$;OpSM*@-NJvG_<B4C7r?o87^iy*8Wb zMrpq6c67@_sMBrzt2>@@hy5J^v<IIiJ1y|!Q!YK$isdqQoTPDML_TG>d5CVZ8v5tF zwQ7lkRx1I6-#=R@`m)Md`q#Na+?08k)vz7fn~b?P7;2Kt8t}>IiMVUrKGxYujGZWb zLanz`MzcgG7IDuLahiX|7e$b)I}hh9p%{<(HOiH54&kp~Ytv~>ArTCn#S8~^$oQ)X zh^?`%yGTMs6NUtL_ntBL;MAmDP#8v#36b}%i_U$y`ln#i)B;*>S*Pvjco$ClL? z%=q~elnuXpj0WVh4c6?B5^b?x@W;C;BYJ#|yQV(-^BV8xS@qdyP_7}XGtF%KKWAjn zLectNCDB|O$s?N`pgU^fn(!runKLO{ZL*IDdN#goZ=z)9FDy|a4b+7tIf&rq{hz40 z&UP~#62@?Yv#|LPJJk&HQ3e)?F*x^tH_b5TT8Z=h%QKll3XntrekU{W1ucz%R_!vl zu6JTwtI@B2wku%k4*@aLHLf+aS<jd)!%M#cTQ)o{<ty6y;vrvlB!}@s{CO0_`ltZs z3fJ>dHs*_rgZ{Wh2W%`KXEPa`u}qU^8Nd`Gtzm`f-1-zBi0iySJ$H?3COIw5Sts}8 z<+Vm%m)h*yTBpLCW?Q^x1F!Vd+Cd-yYm=~2?%cW>C+BZ7&rJ<xIqNRtBg?sU36IuH zGk8uOY8JK)$4P80(iq7HrP*8qcI&NRs5o4XL)iMFv+i5c$~Hy3oMB$wp_-Th?yNKL zAangr28eU(Pbpw+wfW(1ey17vQuDUsxUj8DIfV^QQ0G0jGyEy5^P3)CLis=cawvai z-5gx4GVHJ%DF#_>{WkI2`jH<!Izhz8W}oAaF^s~#^M*_X2XtOm#D*kvo)l8G*-}>+ z<t5PsS#I^dD)cT0YpM^@RaIwOUV(>b9w~ZgNut<T7H`U!4Nfz|w82YY^r-kX#J6>( zRG;4bHiKMr_Jpiv$aIiF9yPwvac%awnv<K8gmQS^5Q443>2~cp8C&!2=C}j(2#tMi zjAaHm5bPpSUwa%RYp-#*{ngfz;(tXArj2S*S=&8{L(57D#>Sy>ye}&aBu|6{WXYoR zJy=+9jhe&f&&Pd^I=}K3&D!?hXM~&KKNL|-rI@I}J}9IBm%CT4Pr(h2lA`RU!W}#z zTt1O71J@X3uEEEm16dpYC#BMwiUd{3p3PQWl4fnzvSl_Q9@M}hNeE;-!hE}nWGGc1 zPd%s4GDneKLvjGcS1HB`9XaviNE~IJ5)rQKQ@w;(FbQa{p*Dyv{NvkHXAi;5a-v(C z`r^gH3Wfzd%G^(xROzgOnu~kNc%v|Y{{$u`D4$wu6mDT|WDAsPz{x$PmVRmi?cZF+ z-U3yHJ4XL3ya%Jx{3B1Os@RU`W_KkhwTO`EP<`_mS~KR8U+7dTIE{Ja&Tt#Gon$nl zE(dWJp-%nLFGR6dIAy<_TXIXDnE(n>ay2-K8OIy5nAx_qmLyOgtQ6Fj%*-=qe@HKi z0nCq$syuW4!}7)5RiQ;?m+>J6id0FQbux>KbU4=#b?)3Fg%G{}A@pSk=NYO@J@Gx( z+{gD5$inzGt&2vIBM=9%&Ys$We)D#=;$X>?T(d~*H3&8|nSsg$L4-o()4BCDnT9d8 zE_0<UD}u4Lw;fd;UFHK1Sw-$AMSfUDn)r(v5hd^Sk`)Y2*Ymsk6l$eaD9LZJB+_ZC z?#wseq9VdWMx##Wq_ehmu!z%RL@#$oFo~*F_DyBDl?uh~G*>`&P_=OS)^ylwt2<5* zvwCk}v{^^0RD(Mo4Ce-R%T811{Z?J%>mVhkZSqsZUab`AH#ms$5NI#mLjx`}s<cDr zd(bT?x#j~c4Ean`t;tA{$e7DliznxUyYchy8+U-d7c;x*N+iTJseQy>ob@d<%w|L( zocFxQ+iwIN$`Lbg(^wA>sk1CDaCHq1dn;88aoAtv)vqavty0V_rw}n1A$&%RTW^fp zY)}2T(vF=bG5SC~B*4=@Q8ksK&3H(1Umvsi=+-mqUO_!8b(bJ>RT_kck`^w4=oz2- zwmQq2dD6<s{fq(TOjQ^`MAUW8j=)Q)pKZQtBiUBnNhi3h<-*+j`^bGNgVvX9{sEGR zNO&hvNz2S>)<X=Yal0`ZAdBD?=G#SKJjZ;G*RVweNW@0_IHN=HbIvdd$%?KtCDDXl zS-puTv{HE}Vwupja?ML6W68l~ZcsT0fl8=k*}`^H<U@)jw_TZWQdA3@6ACGl0(xdK zv6O82hzlWrpNr9j5G_^2VwJ3Rizru3uw+-GLsw+ulN!^ZTID%+Zm>hOs(rtPvK;BG z{Y=ms-NO?H{RW<b%v>f<@R!l@1ap~PGv8k0k3-q__{PCC@7C5Fh^ikPxV*RPmYM_6 z0kfvSzBw?k$ERj&%~qlI8?ow$vto~Q!31rW=wT=8P}xDGS$oy?u<(xFOYiHeWgsP# zT)aFG=O0)ID^^KfcN36{h|5_lk9ol<i^Xs#!VJ1=)5TyRo4{4=Mm$HcD9|-JJ&<fh zkv<f^_enN#g)O(Tku&Sh7?;YX7>2Erhw1%VG`GJQ^J0PAl8jr?Yx*E!U4=K2it(Ud zQ6rhrtZtLI1dW*3;fTHQ-7(GY#w6b|7=sK8vsi6UF!k;QP1I`7T{{)D%r}j9f6JY_ z`axh=-H>^}`P?qy;<rl2GrJD5de^xKlln23Oy<F+EPK<&BrJD#Zc35s&LNx|Ji}&J zXm_K>er7j3=la1cXR(2P^}~G5U@)^Y9R^W~(Yf&ei6pNG>XS)n>Z@{y@SU?&+x_PP zwi4TIm{g4?h9h`GI^_u<CDQ?3teJ-(%{L@AWgch0dr;Ksu;h1GD-v@Vd?KD%8=f^m z;~-ZoK9U+x<NkT(4r1pAmLrJ72_nawwuDKdgr0<*Fp4!2$;P1$QjoiH>ccL{tvDS( zC7i=<#ERSNqK5joFl%3Dof%|KBvEU5qQ@ea%d`kN0xVuIHgfZRyPgfKsk;4%Cssd! zRZy@kcG~O{Xfb=dB)TDUpTCpV$~J|+y5e-hioLf6Tpsh<?=bFK?P5~WABz$q<20L1 zgK^Njk^zL6F8vdO>o_n_hSP(E;qsV|s#j?^8BAB(5Hf@{N#z(eFM>tMXu;~1uk&K# zE;Rzpm%)M=;(^<h1j!5clYZyCd5BydPFZnUI5nru$8oe_LALrZ21JRzsDzD_MOjK( zk00E|rj4;t{uou#?P7|O!p$-N?LHWDp|9zbIyggai<?WN4itPete-Y-G=orT;ji9@ zLZ=ymGJHhw=e8|l=poY$b}_LL$-0_PXX|5f%|!A;LiZHb1)@|=P1CS_a;kCA%$JSh zxHn`U3rtF09;IJZvp#yJae2*p+iYVjBMKEb-&RqNfxq_i50rAjaJMzrB+u3l!Dye9 ziMZoyHmr2-3XD;W@iY-=yLLglF9DNcS7U9=rn>O${@GT2SY*Q<WH6{6fu7s|*TK2< zT3P#Nn0GR%^BYE+f1!axn_2WK8jB`q6;Wudt(Y3NX71&$7WkD1)-24lgPvS-^RHD$ z_24>}7pOi8US|%YNHQuI9Dx}gPKACg9BY2xSRbtn$9iuY9oSBsmKgV3c(wEn=%-nK zD|%o2NhvE{vveJc2sn-K3I^M)_Ob0-oNJyT-AUD_7&*4H{_58PGyIvmsB7>#GLE9O zM_%Yt+6~?L-bud7E~=~mV~m!R6?=_4{MCo0O}Rex{k}23X2mR8`5ssCbIoY$sMFI9 zV=R9en4=k(1bGJ`JxbOSr0X_SY1>&{IxnuM;$(R1rZhlZsNjrRzXB)?&li~var z?B}%klDLWDf^4)nO#Q>nX4L#{frSueKHj{6e&Bw?L>`d{`ZHFsWS3ZmQoc`R>p!Zt z)MWNo*@Q0+(@KUAHQ#)n2!1ZmKjktmg>5tXOlEwvo@l;@bE{CFH1qfBRZ%~VD0^FK zYxkW_5R7B$+uR~XI@m1DA|0`t2h;L9#E9HeM)1wN?ybHta2K0&yD%+>v34#tOPGE6 z`4T2CtnhJRUgKcr&fU(Poo6zxgN->hy>T#X%%RSme-YWd)|AY6<Q>vM0lNYNQ&yn% zUR-P#5K5nU)Yx-dWQHOQ5Jo1y$g%9Mk}!8IeeMr47nESfX>;2=StXRpPm!JqVOg!O zss1JtXWbeChf1w%MT>HGxYweE6iHzp10k|K23P|lvUm(HB!wrCOfHOAC+sN2t35LB zOh)u5<f*#!IgOW4DXvp=1(w6XCDf~{2e47@U+w>B9syRTR=6tT`Fqj2nANt5guo2m zFRo1DZ{oTuaTy*M?|e>p@X=?|N4fNYq|h*m3`rtjb3S)K(tr~W*Ak!p*pjtM&|QE` z1g;w|3YQ_Trwmq5RfH^6ge+BrELDUoRfH^6gsiVr1gXj)W9({XO@BJWxitVf8QE40 zLOB<V*u~}OEb%~M+|m&GzUoKm-f$<4BQ9%Yue(_y!71{a^buyY_Xq#|XDDPs%>2Ws z#?1K7`D%?yj@5<1AMJ1LLKc%*@PGU7yMNKNXMh&qIPd`w1JXJYm<B8WRsu!9-9SC? zFz__+B5(jW4s-yHF5&^nKrT=M+zs3V+z<Q!*a;j0jsd5DGl2bbjG6(Xfr&seun_n< zPy*Z!JPqsx{seRYgCIwZ1g-=!fTchQPzP)SegOOo_$_c4I0bY7age!&1CxR40S|CH zPzG!S?gbtLegW(T4g>E39l%IX`-wm@a3j$7_kLoU_KWm1ZQ4y~+M(s#*}g5UJIHUI zPSYM7*7F_qSY1$D>MeBZ<?cJYy4$<HSa+`~FZ8-sSC+4FS5%g-@>W$%;b7krZdIkX zK=(%axhGU<{MY7`8>NNrvT{ksyGmSfD<~6()x~9nZqEk2sJu*h8hXL)rCx%Nv^H*R zh4Ps~G%44(vEA{?E4*bY)KyihDvK-hDHR(epUO-M>aj|vX=}79ZIxE8Rcc=TP0<Rq zQvT7GTA603_bVh>ZDN^GT57!tV<JYH(52a8w3uj@Ju@@2pZumLX&x2Wo$Og2>(H)C zO3L#<8gjb@-_RT@i&pZ}wDlG1`8fyy(bwVN;ozTqYEO+#*R)Fkeo@gjd%u`iNB_71 z@dF1rU4t(gk}&k*OA?0-A2D*&=rQiGmyR1h;j+soUUB85$yZIeI_a8gr%szb<GSRO znW?j8U;nkV^c&`6WX_$JHUGw&7Gy76<XOBVXDJptm*;=|=37?WdfUo^+gBBOSKm=o zTykgWnzHhWyDF=6W9_>28}9zb#_CO*6`47+OuE!lUR<VoD=E`WTBf!{Tgcx9+EndY zS}cRN1**Im-riy7mR8NJ^m;X(IbJ=tpwv+B^CI5UOH0dFN#shSOfO#Jb$cr-%PZZQ zHjvI;x?oXGj^!esTF(51^CCXAj78b$^B4BGESZrsb=ttV^fGrrMMY`xssg>3AyZUP z<z7?3uq?n`*S%{hbQ!Xx<pm7gBCmUnJDhiE@$Hobl^fi})VZ?KyGk$JFeT1Y>Mf}9 zGO)|^f>p#MMnvkDSGlW<ii+||e7pr~+^Z@4n(|67Y4Ey6m0*f0Jmr`2O&u6_l{>ws z7zSx)=geOaF>~~y;wpDRRh4(m?WG&sg+^s@*&XgOl3FXppd!U(#d>i;Y4P1E`M9ML zo;e~F_7c;5yKx8K?hWNeWn@{WxaaF`g03mA(%q%ScX~-(s#EE$GD>xK`D*v7g3?mS zjFyrzUA3xwO@*4`6R%!XT6u+gwNbW8wW*rn1wDl-tI{itRXUaDzw*o|EzK?{E>m@v zdS5H`R@1wz+_<C2T~$%Aij{)k41fZrb3}thw%0X%+N-<nUaRw#EVbHOFQU-pWvjeX zzIuB|K2o+M$zu*FN%?v*C=B^un=JlDnOb!iIXxlVMc#r6tF)wZ?R8&L$92UK5mmqS z#G7%!cvX7gm&BVc@hS{P+uGtv-6$yS=^*Jzm4TFtIdOruzpcDXmhGz<II?=Hg|)j} z*Q7|io_eeGlzC89PInc0*A}nx_Jj?!k#~Is^M*}9TBc`as&>9cwU0rLp)hM0cEx%T zdqSa%f;;<$zi_*RA{7?s1r%YR)#VY>Qce0w?_GwsN(v*Rd`W15p#xdT))X_L7<AI# zGTe<aqe>cZUBTaR%G35qstwOO?!9I7T6x(TZ<$UVB&=$~^M);`yu*-yRjR=yteQ`& zS;TaiuobdCcdtZ}ge-4fHG(xQyLeS)c~$vp-JM&kYB^`pr0(`uU@dwqPg)%FVak*# z+AQ|&J1SYt$_iMKjj}t-%GZ@$PalSwFjLm(v2k&1q7rPTTO#x0<g^R2zWR;gT^RfF zdm!SyiFdUb;*JiC?svpDyWh7(yu<A4cIU1@_xpDu-eYQN?y0G*VMDgvQ*+OjnuLD+ z*patx-AaLyl4?9P^_oMQczLoXuZI1WP1)nACwuqAn)(`IX>7|yMMVxr?D~p|brlu8 z_G7&NzyG<lzW*kIA6ftU`ke1O3ry+D{?%z;{MS2tt=97|O8aX6B2(C+_56#5xcycB zh2y*bzwdwT3;pj#!{h(q5fD||{SSfXuk;J|pggxk_56#D`fC5e@y|D=|6^`{Z3akA z3H%G^C|^DAE)ntm5B&Ou|7x}E3FXpy-mSN&D47H`wOf33TkrX1eM6)F-llKex9!{a zf9Jd3d*J&IKJ@TEJo1k}_~E15AKUTx6Hor=sUQE3pFI83pZ(J_KmWxqfA#Fn=bnGz z*S~r3rQiN;SM%;Ydw<{3x^Mr1mk<8o&?|?Jyn6JtKfeCPu{Ym(`}jZq>75fN-+k}Y zzx?@qv+Z94r~mDP58FTb_m4Y1Idiu2)4zPy#pTGq`9O5x1J74F5dCM@|35qbzq$SY z+JW@K{^~&bpI!f~teI=p%&Zd9gjUFJvOAlfTV6Ks)3UR#E-bv77k-{>O-lzj6LXGJ zM`vwe`P%OHMVywzImcVUk<<#1Zrov1>6&(<QL56o5nNf)O0TFa7MetMLFK9<o^!po zR~j5t#qY*~GWAM6lD<Z|lBPylk`7QtybY3u#Fw}dN6RVDjmkniB)!UF^|rLgsH_UP z<#`LsyrGY!pwZ%-U0$YqbBxflK$o~0@if9~gp)8D{u+n;5RD~|qiOlN99<oH#C=(n zw{p?#C7cuH_Z*Ui;(_0Sf+{_oGv-=I4i!d)a<jgzWVCE(N(Fa#Zzx}%t}V;STr&0A zDH#hOKaeL`QvwP?c_<b&wAzO%Q*#=CcAz<E6&i;&qN!*xX*hm!7A;(~Z0UGy3TIyV z4%3sS+^&+reNCZqzlFRuaH?3dq`X`*;Fo1R{+IsNT$HXIhC^v1_TlT;X^TN)A3A?h zkaeNtX&N+m^$dT%0qstH;qQHY{9hc`+y7vM|Bol6X)git3&+1V!hhEEG%XE?^zWPh zdoz3cAC8DG@qV7#+dndY@lTy?`OAAO@8NRv&1cv3R=5lKfBdxz`;SUb(^3HWT`2xl z^LqRDE$3%9_V({vzB?Cwx&Kc+J#~9A;{8~k_9|b}6Yd)k?|t)|p5Hsa$aLQRdYbkj zAir>ZBmJ+sIZe9;i1gppryTXS_V$nL*F@;USBGfC;q?2K?~0NO$CrF(miG4V8~^$Z zz5OHem-q{7zuf=oExrBw_UHKT_4e<Z{!8Ega{r~<d;9k-|I1JG_U}6{zx^Z2U*q?O zCwuz5Z#fqHtamzn{fl<@_U~KI0SD5wrJs^X=r>3MojVc!>izt0p32|GQ&|!<&s*lL zgt#=vqLj_iD@!xiLc4)ag`Y0mhdDx04|5>O?0E&n`rPu$94I-ZUTbI6zNgJmypm8b zw#R?6K}3&8G^?PjuoMj96G=6@ywE81&V^XJ5Sk64-_kOLVn3%6QZdB99CllX;qZc@ z7kCTSdcWZQm!4Ftg!43Ql0B!?3odbKG&x8?(hCbA7K8uvi;85TR7l)8<!jbZq6Nie zWZy1jwbFsHBXz%C(#X*ZEk}505=Y9rbVG$#n`QYHK*g*Oq##}U9hg(8msadkf$Qu` z!_>R(7W^M7e*=<zSs3Zivh2&sic|{~X0Bfal11&wPBAgY*eTrwy<d->UzOp7hJJ^) z(nEEn>)w|f1UFHnFHL(gIt%)yVs2=UsdtN!af>R6N2;LxK6<|NfDkslh4af`eF+6m z)0!jQ!9K$7ITAO0jz`lHq%{_0X3P5tN(1MlxKNE5FdyxD`_j@X0$BW%S@IR)qI^x> zyE!eh<x3T@LwX~k^goMeuceCoIv?ET`}REAT8$y?O!NZihau7+qv_X_ImC15+au{^ zg*g?)WmY%e6eSsE_E0u+bm3l9rE9w+&o6pt3oZ~NPph-%6&HHv6cto1EzcH8@eLbv zueSUA=`dO!SN&kk8ci#(=UOyz)dKmp#fG<XgU4H`xH7N_RC$>_CDPVQi&xzl8mB*r zXq(Ugqj7T7_*7`$Qn*y<Rchq&raf$1qL(f!TL+S>{aBS?iP!3mTf-#?^-i5iIkYIy zvkydkGkwAIZ-|;(YE%_T+BX=hS9>d&X@8DhFekg9!fHo)VvMc3EtZyt8%Q%FL(vv# z)_jt-m-$7!IlWy7(<b>ZP|O!=%4zS*IFa1D*?m7zHOeWzo6==yb4tsryrBtvuQggi z>ruM)a71ku8G41G%jkWeSExKKMrK~bDzG86%1Nf!ErdI}rlO$I+g;n--Y%5-n3OSM z9OV{N77Jr0UArlB$->M9oCgX^IV_dgmcUk!bT#ddR-D2`tF7<Lq%A_7EAtph04cpH zgwBAy-GGlqoBj9i|LzvpB?|HQ$<v}xh05y+JtH0nS_#&3!JqgG{P*v_Ti~m<z`{SL z{pRPxewXpD<I>dFDt#B-`T)nMV2ubY{4f4woL&rs$D}RvZs(Z@^aBP0$f0Qcfmk3O zaD<-XCf`y7@e`h0*iX`xxbj3Rhsr~yi?|I2E((F<Jr)r6>41EvhrZ{8zFFW^oFyUm zoY0eHTBV=QQ}SjxR_Uza=>}MEkw-%21CX*xJ)}G}fRwp5^xVQz{C$A<*8x%<xd3<t z@Pp9zcAiqc#{tRjM}UNT4v;z>0>u9fK>QPF6ltGuoAKJcHblus#4r3Eeullm-+iBb z{ri6ZweT1652y2A@9DbW&#J5Yg1`S7ZE<0ygjK%_6UF~))L&|G!66XZ$uBqr-2Zjj zfSUY2J`{?Ef`>)h9gnkNt=zI<%h*uoJo%3Gvi%9`S^L8iUGkQ;sYX4YB7F0Xw|2NK z?=SqVMfO#GX`$z{Uom`oDEv;szw+3r$A)YF@|gM9%~oO&f4kG)v|Ysz-BF9*y7eu$ zcH3JeZ(SP^(t52udhAappr>84$%<L}Zx-!tPAFt}4gW&KztLga@bq3O{H@<o&c0<8 zd)47zQ6Nog|1eFf_$W=QADON_Nd6LDp3>KX=g3d?)=o1`;TQ*b%AWlwPua^IJY^Ce ze?Lv_#ZU7T9HXA+5T3X26r5%}&tW{f{+y-_=ed{X2%h)y6kMT@=V+c8Jjd`n@h@qb zo99zJ$MSsURGP91=Hj`YZ;j^$9_{a?X?OEH!BYm?ah^e*2YDWXzWY^x;iK><NmuF= zT9h<tpA!21!H?6l?*iL^dx3hO4yXav0~J6Ka0}o8vVd7YGB6ED0wx0!f$@MF7zrc- z34jZT2kb!Sztbmx2}t-8JdXi~fxW<sz%#((z@xw;z&2nbPyzI}_w>2+=@jadL7(4y z#b1Zbp`VPADB?+6d4_+|PVRo+k#0QiPsT~)ucpF^-~N%s&+_Cfjr9Hxzk4$Nw)lss zmkZ@sGN!|sN4^W6LqL8q7E^(*12QhY4?GLJ27C+*reTtRg@9a?3CEd<Up}x7cmVhn sa1{7=KrVY;4P*nQ!2j#Nzb3L0-REZu{lfJw?Z8eMa0{>$=sSM?C)~1m4*&oF literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/cli-64.exe b/venv/lib/python3.7/site-packages/setuptools/cli-64.exe new file mode 100644 index 0000000000000000000000000000000000000000..675e6bf3743f3d3011c238657e7128ee9960ef7f GIT binary patch literal 74752 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 &sjKl@1{;unAiW2w^OujNoW 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/cli.exe b/venv/lib/python3.7/site-packages/setuptools/cli.exe new file mode 100644 index 0000000000000000000000000000000000000000..b1487b7819e7286577a043c7726fbe0ca1543083 GIT binary patch literal 65536 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[c}i<OXTz6k>I#RErv3nvcIClH@!{vM)zJ_weD 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/command/__init__.py b/venv/lib/python3.7/site-packages/setuptools/command/__init__.py new file mode 100644 index 0000000..fe619e2 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/command/__init__.py @@ -0,0 +1,18 @@ +__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', +] + +from distutils.command.bdist import bdist +import sys + +from setuptools.command import install_scripts + +if 'egg' not in bdist.format_commands: + bdist.format_command['egg'] = ('bdist_egg', "Python .egg file") + bdist.format_commands.append('egg') + +del bdist, sys diff --git a/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..15802d5b2d6497531bd60cc2f6c29f40468429ee GIT binary patch literal 752 zcmY*W%Wl&^6!jx^oWyBDp$#P<b(=-wLItQ&g%BTr5U_HQMo#X;nRe_M&5V;K-@r$} zl3$uFD}I3$*LhGF%XiK_nscA;y4|*e=j(9t<)h~~KWk@y1_<8buh(e60T(>*p#cGe z(1ZwD(1s4g(1io&K_4E#Av}afa0JKsAa!5>kGWfTspr=Cg!`$F_Y>YIf;2#GNWGiz zwy6|6Mbw1hl~Xg{A{c&mUFX`n_Tl7{GkRu&jI&JJ)&!U~gy#7kDp??`7zaY{jE%NX zu51(Nf^s2kOf$VAtkfps+(xKHXC`cOPjz;Ha5k}_5+*Y=jdZr4LK<xYUFS?gO%3|C zVW>8?zt{W?*V{9Cs#vXy6wOgcmF;e;Ub3=&lXfb}MFs@KRNHXt*!H&YDb|p-Hci$= z{=&ICBi9C-2=7O(>LHQ(n04eST$i)%e^{BhC{M@8oz57iqn2$Fg1r)w4(dpiVO)== zqA0Qw#+yj$2&LB7E1e!<UzIdM+`ri->CJ>HGDCJkogVy8*f5ilmhi(-Cm3yGelHWL z*a8QbEHahM1P7{gQp}U-b4f1OmpA9jiy5r-tBZwtac9=WIi9>sJ|~jNv)u^KUcR2p xZ>ve3+}HLm+*OniTqHAujB(x3RUx3_^i4e!eT*h{W4Dc8=*Mp4#a@kL?+>}U@2CI( literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/alias.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/alias.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..179c8700ce2d1045861d47c659bb8fe344886b90 GIT binary patch literal 2420 zcmZuzOK%%D5GJ_~ttB~jQ#X#CAXqeyT5V;yP5KDX7HQ(9z0_^t009;*7AujG*WQOr zQjWclFHw5yu|FU=_8;_z^t9KW@)vyS3|Cg12L;ZOv*hgXn{S4?KR;h5(EhyA-6`e> z`41;&&4$4}=;~JxoN$_ulm?XIm?bQ=0?Ul8#7>>SN!`FrYe5ZkHg}$p!26MKm)D*V zUK8%b3g)=S=RjZQ^=;B>yacPHMa!klSm}|D6ZOkb$9eXHl(_`Gl}5vsRW<~Vb=b?Z zemp1}xmgl+BPGg4r40LVB6<|9L1WM@=ntT)uR$DL<#dz$zH~yzbWHYL>1r}26S_?f z+{Z9_PG5i=(0xnZIeRlE;2<mR{5Hz9@T1I+<Y1JFO#A&@`bngP^oNmDaW?R~$G+N4 z#L>DMCb3>?wd_;+;VJ#-l<u6;>n&E=QVeD3nAb41z*b3ne-pU?-ks{sP{xN~v2z&7 zPCrk$kgAjJc6y%;!@I@Zy^SZg`@B$J-aeF{AL%09fHufFk2=G6*p4%$qa<m6@l|(s zf7Bgxl+dH0&htc_ANKMzjWXVek~mW9!{f51b`S7u9-`C)L0Fx7v`H_3l<&d3hsv{t zpx%S7egYv#KsgB*r-8*;U~?;QxILi4-K#B=0Aju8ac4kb>{anUA9>yY1~hmR0G=-$ z<4|#XQ}p8ufCeOUse2>s>)lBEadw#R3+3nV4scI%Dg5bCRI$O|-jq+bymQARAd@Ra znjeai%Hnc0^w&lifYyR9f&++;d>;-u;}h~~#-~-7Xkg5kyfA4nCL!a%p3vgR7`oN6 zr2}iqi*Xj~7|azStSGBW8v<V$2Xfm=Bz?nxN-V-I`2mP)(3J~<&^mQ#ak+}w+xFh= z;m5G?m4{=p$K)+-!PA~ljvT+G9nL27DTEL_wzgj40gHz}kCgV+Q1s&du`iCIo=%Pp ziZkY~%>eSVC>1UL$*#!!k;#E}y8^T2R>xn2aK3hUgK23cB9oWkdlCuNqH-C>m<H!S zSb^zv=nA=sAS_Wvi%S&@Z`z%KfVHXy{Q-3KF9<j?1d7ua6cQg`P@5XqI)Sjk)57P` z)p1oA7-(#5kJ*?`*o0AXu=W^g+&0k;?gZeReJ20H@eVy<@N{LLlN0OUAKU{a<>{Li z%x;UjV|EEj4OYo*lHEWHytYD4826snw5R8c#^K}-wn8Qhe6@5PbPZ0yvK7-9eQ!>z z%0g>ytE?Fygen#uR7vfBkEBIK`}I~_FvS4Ueah?0088O-<<-<T`2#G?GpK5#jGNka zQ%WSnDfJ;en;a^$jJr^r^Q>GL2t6fp$m5<ikt`i3UzskOP#DulhsHaJc~XVk-pk`m zVgi|}A~8;-hZP%1RMxmW4&^9=yfIw3f(tL=n%Xqc-=Ifn!Rk+7fw~2P&?a-CVtIxp zHpA-W!q20N)MicULRDL3#au-m*tykemR=a*x5KckhhduYQG(-U7#@tGWcsEShCJ_q zy1|9&$=KXF!Rpi}yp0sx2P!<v4ps5KIZ{H-5`Lizby!5%nZo3^M1ISgC|(iYj7$l@ zvtw5%JUE0+ZOf(}YckLAJcCUSvj-c3Ijc<pOz?(VAv^4ZomgY0;mV#+pzbven(R}f z0qTQhgWI54H5$ig?sFG39<L!~f#g8*Wx~B>GPahnQULYbL6Uc)q*!dXt5LhUfc?_O za~BudZG6tOPLlVcq$I_ByL}e%Z-HP}!Ba?nEOITov=MTNfiGQ^k7Q5C8!$PCjseC8 z-9zXG7>GOk+_TQ$&cgRwtwykjoHhR@)&>5NP^Q)dS6*F=>*5IR?`&PgN9%YQC_~R+ y<=l#CoYz4G)!UHP1lago5gFrSK6=j4Sr|+2n~GT9VKOQFi`9e(E?HiE@y`E6WM8xZ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/bdist_egg.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/bdist_egg.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2027339fb8c44553e46451d7db05e809bf406c4b GIT binary patch literal 14208 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/bdist_rpm.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/bdist_rpm.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3f5b0fbf338c6e5921e982647cfe880cadbbfe16 GIT binary patch literal 1799 zcma)6OOM+&5GE;E)+*j6Y0(Bv3Y3>^;)CqXZqp*cVv#<8p1LiPo{SWNEYh|%)FY&{ z4@EvDKvJNW{sZr^e@WN&lE1L04k_Ea?Y2N^a5$!hGatX1;n$m+9)j`fo$<3jI|%)u z|Ez`$%43-79tegQ7AV04VU&=Oh0%A25oWzc%;MG|d1Z|V!%tD)eh1d*AkuO*2q=$X zDhh(55oSnRkF3_i$YwU{yhfuAbHGEl*%-4}6@ko?aDox?D2yMDxRf#Dw3u<q_#`Yv zLDzP4%xB?IoJm?_lx4<fk_nL=$LaKuXFS{=&?jX|`E(k@=>%*t%2QR!)@2$doQ5f* z5J$yXN<;XN%Pi+ooYE*1Q7OWLvw`uoGoW9I<M32b2`=x(sVYJt?$T00JnH*;5!_$; z^7%=@WeOIjeiEkPlrxBK9Kp@tuHjg44NTEErB8nRUhfq$9+w3mQEkXwfX{OgMsWR5 z&FFDl%xIZ1fE#6i6;5huR`Am@8N(+!0ZzuefcV<+DrS@=d052bSj5F?>pudf&Csg_ z^Bb7zHi#N6Ap2(+qXHk2g;gW1GX%LJ2aUTTv~M@pfQ<lr!zEc`XEL5jo%_au{XTAN z#l_@zBwg4$KN;pSJ_1UIN1+@-vh+=c$!r+i&x426!^7?4-3hDI7rRGt=cK5TZ5Y#Z z_|q_tbAQRW|KQ8<?0Gq!4izuTyvQ=4E~`r{!*!ty@>A(R`0Fs0u5d&=Qf*#*2c&Bz zw4t`qY$ySuMu%vD&(Iv#cmWm6$QhZF!aB4U9nH$zVpffBp<kdYY62^MgWli?G4<`% z*0<;t*wog-c?*0p=N6jVtgBDVJFwfW?YeVDFsd!!);&1KeuIPR#un6joL=O14N#M- zL4KeCZiAQt#GmgOc&25~2&4|$)U42CdVPx^IQfmdupx+3efl&jWyH51(XE%d3FiLR z%ViPG2Sq5W{=XQMDWn)GoCSX~y=k%l978plj-b_pD_j4kJ1S?(oU1--SL&yi;9ZRl z#nqK<cl1d^2HTA-fHBY=z3%KT*UwGu$qk_D+}jh-Wx5mgKhgXdGQG;bsD&U2pYuTF zJPIbU;DbGp!9$?-L0O%Ar@N)Py~@xPWVG)#z02L)T$}P@#hUEFX$cQ6YWw8+KO#1r z7#jSfaez)Pi@qbfVB2(;q>ns!B9}Te7vLOutz`g6M>nsaF}Lp%sjFY!&_XjIKLnwt z`UnKV9`3=<#V+Z2E_n~M9<DzAPg)N8PU8lFuALxgydX$2Rtl~6g5X6NishGX5U?x? z0@HscW}6KC8eF8s5TTn+>B4q5Y~ng*uWyg;Xd>ZF6l$<+?7<pU(_L;E<CfD4&qmXC QZQQ*U-o8$p$@%-%U+3ohbN~PV literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/bdist_wininst.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/bdist_wininst.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..24d0def7d5fa397ec11d04ffff933b0a8a3ee227 GIT binary patch literal 990 zcmZuvOK;Oa5Z;ILP|~1MaRWhwIN(F$KE$I4p$a6p<<d%^2x(<!-NcDs?5<m|+!H<W zBibW>X|J643!Ip7+|r_sHRI3gd3-xFZwG@O0r_!1_<YI;`Gp^s;sDqO)lb1lB56z# z$_OP1n{Y}#5XmGzBa(-F!M^helk|YN&TsH0<0;xp;Q;nQ^+PZrnNUf<yHm&0373v+ zoso$n+YsNigFr^wh?6LdQf(B4m?>sJK~AXeK=lwzMHb|oR<vRl?37nj(q&sckgVbY z6!P(M(Hk~$P~>?WCShuZDunbV^5dus#WYJ2Kb1q14No$)9QrCNQh60NHzt4Oc|kGL zqx_qhXXz+YGcVG*2zRz#Ztq=ry3BTvv>(T|-vALu!Pw<?4R58QpfFLE+IzPVP<S=h zv5pSoBim_c*^QO2&_&Q3Y0IaH{7F<F0{&E9uA*b#gx;~QyrV3Zq0(M5_omyq*emxI zTPM3mveeIakJZjsQzly=v(!8E@+jYIXl_1x5zLoGF!OY1iri#btgpkSvUg)R&<@oG z3N27wZ&IsGyYRGW`S_;iZTFqxY*Fyt1+B;W1c0O!5u{u<bivMfMJ^~MA8`p8o__*_ zqa7c<cb!RJL|UjKg>{)(CsWZ(!73BW;moC~1Gw(f%B<n%9Wd*l8jBKO%jh~Q@BYWQ zNXHP5+}xJ!3X%FrD1_|^kz}%n5w8jHrSRj`pSl%w?rZgMLaHu`q;S9*O_%oiHBGp{ oBisyFi&&4EE{|?7QOL4(Rs%$J%6|rv+wSWXr#DDfW2p`P7en6o>Hq)$ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/build_clib.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/build_clib.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e2865b8b1f432640517db021144d976dba3035ab GIT binary patch literal 2469 zcma)8TaVl{6n30UCX=1rZZ8xB1^ER{r($P%5ujG6Do})wP(doFDB3DyV$V!=lQ^}V z-JMnDh3zAi`V)3}g1?kkc;PSb#IZA%-HHc1igSE&E}xIjIi4>zH+=--*Y`%dFE1nX zr(P_F1H>bE<hL+UM6DEM7Dg7za9~@SgHtDK1ua9{shhQfwxONW%Q`{FLSG}=qV7vX zU1sm$6Fb1vdW!n(zriAU(zoiXj}xg%m89}1Q)Tg$5L^J;PWc30*K&5qL|8<LI7}o9 zCxVwntaX<I1MvtR`3_7B1r|lxM_^M-?UyKUs0035wLdD8l!kGdjG_Zj@(GOZ4ww)L zWkgLGp==zLsUmAZGGf!{AmODTiWAC>*qEm&KTPt;1K-%VGa%n&ManXkD-sb=(nOPy zm=Oh(R8dy!j3UV>cqmv-Ssu@boJqwpV*qeSPI@uViX>$>`#tc)WZqL?D<=#fHkJlP z`tE>yPASQ_U}T@oq(-LE_ZrwqKIUK`iB-aL!0=${g4`l}v=;&dNp^@VSe%S!YeWf? zWXuI&Q9RXxELLQJh&GOOye<qiO(c<1UZxZR1zTTxC0SGy5F%g##ubDM>W7J%8srk< z8#6M7&F4`DXTd=&g{&Za{NJjpI0EVc`B8#%2vk-mh^rFXuinZe<)bM59~M?3w@5rr zqlpBZ>kzH5kciU6gf%6N7$7YosgGb~;=&g7xh#SxnjpqHUG><8rvuNI@W{$S=(TmE zD(f-4pYQGBIiA~<eF`OaX3d?-p=jTeca>E+3M+ezPq2Kb9EvM^9i3ReSPECp2}r8e zsY~q&pJ59beMhxV&>5b$K(_@nmIt8MTIx;E+^t&R$5q(KwLz}E^6}ew*`uE-=P`Qz z{oJd(i8b$3ol~!BpIP7uEL7gYf)5t_m4&~~TQC~F(Qr>eUsErBe}*cw=kIM)4!pax z{R+=F)Mn*Y8z*>zCTNWJ?bnvrHT&@(9$iC$_I%S&U~#@>Y-}|)s&2JeY0f3O@yeZF zGT*kVjS2&G+3>rs9PsTugC+*;Ve?7dZqiU5kCUAApi78IKzj8EFZ7v{n+<D5dLPPO z|0B{{$oEKALaIUm6oN_919B+O1#g`^Z)CYVe#;cBPF8IZ5?*_p)!wp7k9Yqkkfp*J z$%RtnW1?mSG>8Vl15;YP8bNpUd8vw0g)|Yhn?<qUvhF5%oR*YnrmWqjAo?w#lU3-e zLTtbkY_TIHqOjo5-^4`LEy_maq>mf9O%Ul{sqG0<wV%i&2dO+}wWG_rZb6?<nb4&m zY?x|Ccdgpd{iAllFf_^9g$|<M-m-v#?WQe-%SIuWJslcpA@p5Ux0k{iKyW!0EK)24 z=PHRq9pM)6``fi6Svsyet5Xg<AVb}Kg2g?d5eXNhMO&Ndo^Lt9M$=kMGp*ewu7M{- zY&e16#74K;V4EF5t5uAK4SKnbq3CMM?FIi2ByPa^pV_bw$pOF~9z<dYmknh?4zuYn zzEgzvkMHl@KD;-k$MTbV2jcFLI?isxnB>DBhDB2Bm`JDT&c~mQru*e+GL-sKRh*~t zJPBdSqMQ!bSKXkP)t8#(Dk^US9{Dp&$hu<r)^!V87<-n7yR9u)H!H{4vbGx9@hunl ztF@-F3*UVE8hq0~y>hg)=DK>N*T?Uk1M&ulCvbOrp*fo{to<;|I4x5KbT<rNlu@cr z4OZ<iq&yBo@d4m9p*%OeuX+0H^<he#D&CfZn{4od8+7>>WUvU#V2#J*ln$1Wt{pCt zNwB@vfIkpiNR!NUXT>&o9b8>Ue*oDK>c2TAQO`lshb}a}+WV~8+C#Vvkn~`>Vs-V; F{uc~uxm5rF literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/build_ext.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/build_ext.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..30ef516521707fca2484cd765518f5059a9c46a9 GIT binary patch literal 9723 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/build_py.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/build_py.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..63723e55bb4cabf0915d21aa8f69613bd90cbbc6 GIT binary patch literal 8599 zcmb7JO>Ep&e&-`O9L{Jo8q2c$5wDjqoXF$KlGo{G8^h~(<HTvVt>8`ECLyw6sd*fU zqnY98J&r96IBm8vu-Rg}?H;%2VRS6eQx8SaLxBRl_S9lgu)X!Pr(Sx>slWf@heoo| zqBD3Od?eq;|MU0%^S#Bzx`y9RU)%mXc|+6wlP-#%jm|?9`ERJW##vt*Xs*VnulLzN zcXib_`o_T2F+QlcRz6a7t9Z)j+pewJnp;zC-L0#3!ELB^(OpDq_M3wxcS*fl>9+>w z+;f9vcX@E$J<qhm7M`&BD}xK}1*UzX4X>M8u)0?lf6cHa(>~OAmD?{gZXfCHh0nC1 z{wa;scpYQ)!0J_k3rD6~;Y)mhH(oIJB46aq7n*yC8y{=!)~|3nt<6$%ryp&jZFHjH zvp~e&$d7loFkr~=plzhaz#pYnH|)oONEfoU>-S}VM{2(t9)!cYar9P)W-ERMIuB9g zDyl$p8P{B$SGdj%?8D$D*0%)F`Durqr608n<q?WBQE`T+^hupZ&M=C1!{N@>UuoEn zDT97DtzaX81eK#s9LQLT8eUP=*UvXcB7Ek@!R9kxY<8nQ4}{zt>~40xHS*q>ywkh$ z{H-pZ$hY5mChi`@lffPQc7~fzH%H;<b~u!=-|yf4_II{-_r}{hn=**Uqd1ECa=zP% z1_OV{H@C-OpL?UjjnQFhi}BDSVw|Tl=%_R{SuRPmQQQV`pSI1^_Pn7#2s|&Xd)^@8 z<39Bpp0_{t``I0_Se)wQe4;^PM7(7bwT#WwbqCkwkLdXjMgA03$pfN3aY1uUZt@D+ z3b%L_t;KC#LtEu_zJS)|4ZeuB#+!TzZJoFHIkXFWnV(17;4AzB+C{#~FQRSoOZ+n0 zC4Pm!hPK78@^7F$7cBE@{F^VdBj%px4tV-{Y8O=VKLyJ_81DMRPQabDVtCET$?L?s ze(Z$9PJhe;>2N>x9mRO(c^L0HBfqof?*y`5ckp|<8_Yl9i@=eipc8gO%>69%9p72Y z-|%RrHOCh_<3TWtoj7vV6rXRl*EZB-9|u7`q*%YfLm6+pk4l8w<2a0lYfd*3&LF}n zJc#|UFE_Gne6KH~b!<G84%A8FQ77u+8uPt;K1f>hTsnu*nD&ru_t4pfysKTTjSh3k zkl5`IBr1-)2CAq@B}B+kdv~HyAbi?ec7zV86aA<qad?CxAES!39-HZjcFdTTXg#B6 zCYpzWUS;Hj81pKe;o91>#M{(z_FZj<#;dA^aU<p2O6x>OPqCz3OU+1xJK`KxNL$@- z==Z}(;6)?al1v*!!h(8fW1bV~N^qc94BMkPs`x_+!oyAsrMTo3r1QM-2x|sBTlCbO z!WJkUY%@V7{;b}tVC;1i*+QkU2CFlhS$RFVTr9J3cKfG@Y2j5x%mZ{l9?XWC$rjlx zx)#?GZKfZC@-!}f9alznH8b<Jf;$%1kKs#jH@h<CuByDavg2B>-djlEFL>oobz+*b zjn?Gd_sIG{2+4NH^->?!m8^84(c!#8K)}@T93G0G6G!53>+w@T!qH}KD_1ga`!EhV z5f9ppw0<Iesa*)3yO_}^U({{pB+FGXT|RZK7@1kI%UDQUL6tUW4G$_lf(;jBEHjx| z*a>1U8poq?EMLvO)PN2BHN2oai>5c2sawpZg1X7@Hz$pJ2Zv;EJIV~>4Qk1)D89Xk zPQp0b)5RrFUpod5JQ8^DFV=g;49bwOV_kWm%YA<m_7BM>VQ2F;Mvw(=SJEYqc7CD? zYJC1+9zEd4vGBaMuH-T`>GG^}UdMdzqDV6Dnr=fbEjC#x4>UJVhYmwO62?*>zmE&j zZgDl%69YZtNEcTV9Eh`HHZ|f(&ze=~a0%`oo1g1bb6QC%;yoPRp4Adl*#tAGbk*Uv zQnt~q3tB5Ro_uyUt%p*1NEqz2LHa!0@#4c#Ak&H*^}~4X)HxqAK@r6M)bdB8V94S8 zNjFm~yXP)sty1Z<noC+*g(#3^Ni9e+Z1`DXwK2tG6xl?jv1Prk)Y(KmxlocU>tqX@ zQsPn=uHo%W2$&W#&<#{WF-Mm;JJOFb81n9i!H}$L;Phd}$fB>^%s09&MF)mTtY=G6 zkG4%7T(;L7pa&?Y+B`(1<-;r<!Yl$kgk2z))T9YT1)E6ED>)kN?aa&4Ror>CHV86g zPf!$IB5|2qD$jjJBuhP@W7A^f5G08U9UZdHeuBgIAp3Om9hR^eT);8AsQpZv>Oa=H zOyLF_Pg@E5N;}ryhew|p)F)Bu5~ee^#0|_?l9_alL{s4*QhjnBKU|)&+ySY1ey;E1 z-Hbj)sz)+434x|n5%j6k)>D1sPHGZO0XeHVwKHiTEcA8#K9P{r^T8LmR*(p4bLTWI zPLp-xen08}#Xdl%c)49omq?LIClm^C7ZZxNP^D%s3WsSeo3tNpi<>mM1V_Q=*wr>O zx3f++^M@f3X{{8A?4(S5hh|n-?px^n9*QKT(Db@-#jLZIKDqk89iRlxWGYJi{}dOB zp|Am@<HrVcUXP6gc3^78X0HPFLC2?+xEk9%IF_V>J63Ee7ql>IBy0!FO{`;m3Og}d zRF<N8Od$iCy!{ctuox-~rsP|JpqyT7rvMt@$y&~;wRSUI%|yHJ$AC=(iZKvQ45gq5 zK?%PgVM%Kth85yUE1g{*1YhimXyDPXzYT9eC!J%86-s3ynuR*$u)qKx)8ztHoLJ_z zeZn5a0dj2FR@^29LedKkMnGBtcNeqkfgg8v5o*-wGMip3&@Re|Bje(IjCD|Q*JLu2 z>CDpWa8gb58|cre=NYjnRfa^MilW@qpQCf|Cs0W3eeH)|er`_LRG%7C^FSmfMta~P zRCWgLCKd3@0>4Z(QUU*<ykyVReO=urep*SDcniC4PiyLKHK{@#s!2^;!993^UJa=4 z3VQX~LSoY_`&T~E_U%uKknF~zGsq$wz5-jc8<`s{HAvjUabWZJGWCX5kO-wU!YR4w z_qQe86c_NMd!YzODWviWaHk-IxP=Gcmxx+|R4vn{?^5pps?;vjEwy5xd<X;C4J9fj zxfQWNkDlS+H!v2XNCJtPz5?&tWXmWma8J3F*Gi4dJ9BWgWFZMh$-@7}MF`*le4$Mh z!szL8mEdy-yLxZ~WHv@OI0HLZVNH!hkAXd)jK(oLV)wQEH$NeTCZq^PpjV|HMBpzH zlURlKeg-iBKAbi1X5|QM2Xn0{@(@!ysZMJL_YzC|U1BBno}pTOuS)II&fX$XQE$}M z^<q+oKtTETzr@N`qC*(INGh`?@F)|%goxCDntr+e1w6zOEWdRbR{dC?wIE_7DqlcM zC^&#GAo8Ymu(RWZ!)`P&5F@wGiT5#@F?glGoTb4<Fd@j_rAxk)l#755KtzK$>Kz(g zpa?n-4bux`stcIT%VEWN<x-WBo=6{=>r4b~KoCg*WLihy#DlIs?#G!(Ehv$4^+DIQ zbL%CQfVox>dYu8!d;#Mr>%vco;F)V8!O%r|qkC4IHnHH3P$aFasStyVLQ7u-QX$b= z!IjBYX$)d!qv&id1UZWoN&zFtPDR-W^5=@+EF<`<p+eduYMt1@U*N4GLvgVb>eJ7Z z9)^UOc&XO=TXYWVWRnth8H_ezV~~`(Mky(#Wof7r2%UK#h_!nDzLpr`G5SEE^7{#V z%E5Ye1u?!lH4`%dB$va)1V#lszlaD`Jbj|=KZPjb>6j2I5*Ww&pEU`!&g#e7)Plen zKhQqXK1G0(SP<^Ni5Gf}*&?qbtjkt0#~(9#yKPN=<I!%=*>jZZg3twJ#I)vk5YiB_ zrt)Y!==704Q27~Hq)wo4O{$CSElJ_+OZO-LxJ7Vpeokj3B6zI9J?9PSAQ|AlyzDvx zGNd<Ri3Cu#I#k5r5mFsUc{#u*eIysoY~^PAb>~Sx@MQoue1Nw%>NhD{K^caVT$KZd zh%}NjhAR`!^^@H_$pf|P`9ZVPMZ10-PP&EttAvUNkJs4?cxwN4aQJ}`k(k5vi|S^9 zk}_3ZE=gL9ODGq#InESK4<lp;fc;Zb1U^q|lng)~r7u$}p!sFmr0j|sQVX`LC)Pb( z$TvnX+pQ{6A>U>I(g{L5sSQ^VBat(g2F#o?;laN|k#C~XbY1D4rMDQlWfKwOD%>)) zq<<FEjk-QrE%o8lK~Jflf!UNg5Pne!lfu=iq)M)k0E3_7{v7R=Y472w#K@}^R)l!* z?@=;rPhsGR^Lcra65i9s$Rw!E-9e|w^-wrFRk2Oa<l0_MtQWDM%Kt#8kh-9lk8J@Y zl|i{Oycv&`K@?FGpWrWLPus>ErwozDI+-<8_?B$<KcHk$Eeu}+<etMqWOn8lTt>Ep zY|BuE2pMZ%!72U(ZgfVjRL>Ev`D5rgM}YFeCR~KDq!J^i1t$uZ1Z-<17T(fS5CiM+ z!u|^G7Ee`UEe85I!kpx=CT~AhN$&qIx-A8R5G?JN!Uaj;P7&<PC`bbRe;*cdUoV71 zPpjRbLYE5FA~Eo7yhHJ?0;G_O6PQVK{JM632SMn;NIdvwT7i}`*<_;>*O%e$T$EG1 zdTO^MEoXL10Uc~8XnSh6ik-z4_3n_q4{ZB+Os=>*z+C@I`y%lp><cj>0Th(b5ErR> zNY(eKdJh#oFaVdeyzwyH9|vAQ+0q~wz68-TGJJ?P+=e2Tw<DtQNT$^SnpgLN0J+aR z$ks(fODN*0oju0oKcUD=s3=U%vAKcVpV2_#2(3A%UN6(JbcJ*_a)(4XNf<I#qBzre z7B(U4mjzHzHe)VoHb~%<ko|{B>^k@zh5?dyqdX+Ko#(1M@JTAQokb<iO*sx@3VoEl zrWmB00Qu+c5QzlDCvAtqB*%B?f!o_~4qRoE>GjU8<ID0T`g*caY8xfgF^w85jy->~ zUB0K5LAIxGnUsId5mJ_JrX!^<$NoyZ98e0%aH)v=ztRwrLha6~gn7oa2%>W?b)rxG zJZ@IVy%f7&;ZC6rcT076b;S7!m4E?zh#4};{D4+5@s$am4o*S~w;}xJCs8XcUu;F~ zf@J*PQL+%;Hp$N*h@X7(|Jcn|dqq(CN-R;;LX}pL^^Q88CnyRL4prBwYE$((Rg^Cf z_o<?YMG(#uE>-01l;g;(Hpx9D>42a+gCO3Gc&3Yrcqf%Q0HGSvQR$$vZBw`F_KICa zU9p??IeXE*WE=K1+q5nFqDt46E{8&L;!_7j_E5#z5n`J}@2UI{vaGhackl#>HI-dD z(gF6C0rrf<JYtAxOl4@U;|u5d!L5Ws-Rro^=q`agL?Bi1kV4$KryrKV=x_cGU;|(d z*$^iH-Xa))R5<)lAfA!HMgkCM!}$oe2HOBbgsO@M9kMzQ|6sVW1#dmV?o-3(T#%B} zw>Sb8NJB^@ZmrZV(h#Y!7aY=;$Y6*#0kwyB(rP|y%J$C20{fWmzfiK|fN8;>6W+I3 zgN%>*3woxs&O}fukLV=|oC`mGjL!@Sa5woo`T#uz31eh+C_I~0kD+F(M116aj(~fM zP>jL_nC$Z<#`>7PYAT>L`Il11)%CsnYm)4Ua1@uH&;VeE4&w8uPdRY1QTMX%U8MK) zdn5l0M}37uZ??-1Y|<Hw!KGV%|G9rCZ#mn6vw2$vBcC#=uz{FOIz_BUU%~)p%U!9- z6fiEnTdX^`hQzpAr#FNzaI`r6;6%#EFRg?U8&6v$=G@32r}#rqCAH(=Abu|BBR8@> zke<})Q(}7rvp~ixd&(HdowH2+0q!zTR+0wMw<P2UbhFxIg6<HIx}0UTnkOq0z*Sbw zy>c>`hqR?9PpkQeQnU<=spITnUhyNU{(!14sUo#g_RBq|D3yJ$#F>y^Q;B=`wU@>> z@M(Wz5IqA{Bfyen)kx&s3v<sR$*EE=!GZd`oG$#<U=)d1Nr{qHb<R1eD4RmWNbUPs k#{B^ap1gsop-^8Y>Z%3+UjZO*v8KLKS@|RFv-<M?01UZ_-v9sr literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/develop.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/develop.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f17014bcdf42ee22eb3bc79b596368c471793d87 GIT binary patch literal 6440 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 I8|~Hq1Ar{Am;e9( literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/dist_info.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/dist_info.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d89a5390d24288db0547aa3d22733212552d245a GIT binary patch literal 1395 zcmZuxPm|j;6qhU~cANw{FdY^OGrpA^HZJY(rwlNKWrhp07dUyC(KwcpIM|kv<ZWxR zr<NNZB75Xp@Huql#8=?Nd(I}?Ehr=D=~>eI{oea2-%O_wf%f~o#ZP}SLjJ<Vq4{7u zfo?v7L6DRPD!h`W6lPX>6-yaKpI`dbARSQh9T5XDd`ZMmvKK5J3hxIp3%YNkGc7YK z<17}1vAn343M?&itMv2eYZD8(ENUs@qK@ra#!uH$ma%DMUM!0|vxTaozX1a|pHUZ_ zsjA9q0VXTeDo6jJd0;$&ZsssZ0!T^f37RtDt!U~CCj6Hq9qds8zCeVq4#Ws>Ms9RO z*L{#55YN$hdK>bLbtAc2oh~vXzjRb~-yhk;xvFhe)J46D=eXzA$wHd=Lm->ArTsj% zs)^OIXKYlfa~WGL<t(QF9vjZc=nT5SG6}LJ97aG(F%=;M;0OY2-^g<L2hkzy`{!BG z=;8uWo?K))S*lV<ZIWu8<R3Nsarb!h;OV2K=*%aNF7(4^wyPdMTh+;rNmDcc+1RWs zPe1;2vHrPTtP&$_+gPPa^QxKe>yR9?HgBH0w}84Wva;wTR}EIq+(r1vgV65%o6Y~- zc#Ala?}?)duPOKBW>g2@>h1k7f~C6y3c3~c1iXi^@7;ubecLf8#=(pGpfwm<vIBKr z(M!4|8@i<&`p&z8vcSyt^Trp%4utoDj>&J{yF{>e$fak8yFmE6(2h3IZoKub;Fc>2 z=kUe>+{m_UH`&sS58pg^Ls-$_`M#bgm~M2`P8Z!Mu$%U>L~Y&w_42+OFM3}6bD2%u z-IcWbz)$e&`sg8W(PJ1K(`~IMy;aIuGqik+=Y~tAtIRr28Rs{dUArJ#7&KB8*+Yyo z^Y@9z3)1N^qa3uar{H_7BKl46-GgrKz(8n3!~S<dPrQhBHy6wS)%h%RA?I~gNzPrw zd8I^KqCMgKmo_V}zl?=6xh{HPxk+oJKB!FN1L<k@fnNcGFG8b6G?p0A_m3&`d^Yq$ z7P8(y3tYgtP&w!NZP?@9K!&X?N;A)umKqhj|BL9IefIj3{};-IU+futg)t36@V(HR H&<Xn&bIWcm literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/easy_install.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/easy_install.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dd4a76bd3b8276ce766be42c95c449ef705c3a74 GIT binary patch literal 64851 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 N@2?IG9oV_={{ekN?z8{^ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/egg_info.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/egg_info.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..83dee10a5fca2d6a589c1008c8f35e9e8696e369 GIT binary patch literal 21672 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/install.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/install.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1e70cf5d3eb5881a3fff8d10f932a643b6288d9d GIT binary patch literal 4027 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/install_egg_info.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/install_egg_info.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ecd60b50992179f37cb7edea7663c9b89c166f2c GIT binary patch literal 2428 zcmZ`*Uysv95ck@S<NQ0W6u3fZ6;zdyN+eL!Rv?NHhg$J+52d1#MP)hJP0l&T4!ibo zXC3MTNbN)W3EGF`v0rIl`_!+%Q-8CGkE2H&?d<G$c4u~eGvhqybea~P-##2Z{lmAc zziClDH8A%v)Kd^{ah6y!7O<He*o@Y8;sg$6Cvj)Bpk`z)crWk_UrXvUKk(POjiB+J z#XVksW%0W3rcF_M=>{!sKel@QKd@l+Z0#i3MEg9JVUfqlPLJvOb~c+uDF@q3qnS|i zXe1O?8$}9sFO1}9H{KT`I-z=OF!wRk0}x>aj9Y=t8N6kI%k2pZYTV)OD=YALjeD5u zyv}{hK5y_Q<_2%^Hs&Vpz`qT>8K)|bk|Y$9Nf@W&tn5EpNxD(m?L&H<q+Pf!MtLR= zyW>oD^Ig#;C!>kzIc0l&#&sxtqZu!^-e~7pcm1}TXCnr;>7kkKvW=k#C~h5DAt-!e z6rEP(7EZ#_RU#SxWyuy)U;jLq%XmM^#b7^@gK?H{A=O~EI~d)Zhquey(;Lrkjd`iQ zy0tIAILOP{4Lp-{@WWsp&v6@b-|Js~J>1<ZhLeF3c`?tkEKw)f(F&bG<wq5s{`^p% zjng=fqa-dxn9cJzOV#^y5xSAZ%1=)1Ijw&j2?tv|3=@ebV2-Q>GLqX%<RW;+oh5t0 za(h7;X&teti&0y;3wLR8cguQVW9=b&_1vE}7R@7T+B(8+NZJ#MYR5#iw(};YNj&V? zvH@d;XurB#**FFqsc{~W35%4AahwWX-Bh2SKn#(&KM&V|(w+I<B$PsBg+w0f_QP1^ zG9Dt`vvg&FvOH*!t$hFnu{;A8w71%#?M!KR9_72*on~>ma?Q&l346Mp75Ti#RnL)> zE`cZFa5UrEA4W>h!6r3Uq)n%8RvuP<Uw~Ad1+kciUz54)EM_0HymAV$|L#7<i!!&4 zVetAB%nGk1V^+?lKnd}8mrUL<tJ-R%?&RLIPCSOs?cafIdd+Aw*7`%7(}bi&>oHKL zdCOWllm$~?<#~J2S?QX*Ae=Y2%gMqSl8@~RYwgA65(Q>Z_jXK-Q9*Ss4?|g`W#fA> z%l6}R(lya4H@CC-AuT^us8G<}d%6Y13Rp>jlUpFV7Ausayhywkt0YeMB;_yk=}Zyk zQV98xc`XirztVMaAVx(lv{$4?pAgWSB2|SH;c=VL{s>-}?dPEopu$#N>11a#$p05- z2d-Yh7IhB90<4$WIkv$r0opbo{=hEJRcBRM-p7`=@FYwPo>Yj4Wz~h`C9HewopxJP z1?!~jL#-<Q%crcJP&~Fuox;VS=&3HqFBULI)xYvl>(;N<lwqK<Ujl!Fq_Z<J?Pa}* zK4GTkd<*8_DrXO^pFTz_K=VNHGu7qxk-de>?0M3o1D<(5nqwC@)Fi93a4E^Kq7-9j zyzWlVE^B?YpAJfQ`^n?MYc_aCden3i*vMQxkMms<BJD-<xk$Mr4|R=;VKM1B+EH?( z9j<b;@4a~bRv=A{)*+subZ=psB8lZT*#(qj8wi%4pNeFaBmKKcHi{B;ufIM3U4fvJ zlshIp(cY*{$QwlHqfr?rEAlGHO$<d4Sa!QrUi@EMJH3|n!;tbY40SUMXBjUN;@e^P ztca5Jn|c`XYy@$O3pJ9l`7G#mp@ghDknF&kyiDXXBG-tJFDG)Ee3iyYYBF>OwF%-g z*LEGx@g2YAcYH_E+g@8YII4{PQ7998Q;nuzfzk12P0}?bWlXU3M%rKhzc7DDR^c<X i*?6=nJt2*ecloCMyQ?VNqslSJZ8G0(1GhHwoqqwqDRaL7 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/install_lib.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/install_lib.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b8564de336aeb6d823bcc3f37a0802132c95decc GIT binary patch literal 4104 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 Sto7bOyBKbb|JC~Rs`X!!4<<+e literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/install_scripts.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/install_scripts.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eb530c1ef85607d599fadd3b99170cf7eaa44e4f GIT binary patch literal 2307 zcmZuyOOG5i5Vre0uk2>?Bniq86wn~DlZOCBAQXit5eHUCAO*ERR!`eA+r9mY?a5|G zJvp$ExFCMR>=AwfKgCzL@E3A{s-Bt6vfz=c?Q%`IT>ifD!(OjVp#6Mx^!-mQLjJ(X zx;Zd-09}0tf)h?NlGBh<99x-{+ZLfDcS3ii@j|az@k1ZJb{6EVu$8yNcHRj)lsqBa z;qEKKUE!wAp&dHh`i2a=zrZ^gP-AE1WM^QT?xRF$nT)17DGSs6I?}se2_5lBM`lwL zYAOZei4?Ie<w1;pUN;*C51^|LKnN02PC|>*(B>AmUlG`_2_STNoBKR?MIqo8gwQb? zNuhL<WlY5~skEAX`l##|rOczOzf|>C79aMjY^wTEanKi&2}_D`+25B@RSCJWR569^ zvEdhE`U1MT2tt#TF07gyVG?Ogn9T|7Z|yuDIL0YuGLasbnXRNqbP{FBOt7-TJSgK9 zB@-3o$x$L3|4L*BEMLDIRx)`WX)$~r$>F%nxR7d??+)WT6}vyXpWfcTH|8_-@xABr z?h8H3Z$q0D!*7RGQr%je>DEV|jCS{?qsdSSJ*{+EX6ocHF7rGp`0!McwyOgfKoDK% z3c*5Xm(FgSw)*c`juV7OaG^H|dJO{(SB5BSkY&vwO*L7-^<lzlk~*m??`kjg7r`=# zg*O2`Yr$GuKEz~#eFyF5mhRS8+S6xHLf<&FKyE@md+5yV#?A&iM{m^#4034C-A3zz z)&s4_J??|nuW5R29@M`4jR#;u)AKNM^@a4}o+W>;-3bM4u()(YKp&)+akO}=MnA0= zH(=#TZP%^E)gy9bJt9AxnYSU{Yjyh<K*+N{p8}r%1g#y3crn2mR;D+aCK+Et(zL}3 z5l?kA$^<NNAPL)t+yZdJ4oei1(*kCb$Fp{Ipm)n+8|(*fo9l1xbbED?+agj20Nn=i z#$Rbo_h0G`_+!UQxZN=){S`~34*@R`YlF23%BdbFnNSi+2{9KYLbGvFG&tsKUlJJ+ zHm4j#N=O8b?4f<5E23P49n8UVKr&VUAKXM*%dq=RL(Zo%(L#pjo+bq^_ti<IvDJZ+ z8|cg#2}sP=>HthtB4%+GDP`JYS>~*YWR!;ih8W3-3R{t4yCMSmnC?FAu*&<OBe6mn zOC+Hu5*Fv&IGByl8!4QH&AqJrd87TM4(?-hImT<;Nn<yE#myS(E(LN&UIMWRUEKvi z=$6%{0X<`R)UzBITXd6l;oGIyJ?g;Eqix%>0$907XXj2+4ljf1xZxyt!~-DBo<LVW zf&iLXNVB<{TXT;RZ7&>d*HDpC_sE9%ief2%{m23WkhHaE*M37o?+{^5(vErw6!Q;( znz~o}+^OwL<j|V80O~-x#<sQCI0BH@F02DZF2g!hJ`dpT&+arA36-?}2H1UsPhXdP zy(`w`w0~Ue8-ffh<Hoyr$xSbwN+}A>rg^0HW>>yk0vb5bzp2(`8+_eVhVCbS1G{zx zoANB2U%rRpeH0c5<6s#NJL@#UhQ=zDaVmIwjFXm0AupqyhjqT-#^>??`6e-|P`E*9 z+~%4gwyacQ&|adZvt$ZGRGT0!3k~stV+db_elme4M({V$7*7K}ga!jRk)h+$NVyLC z-Gkn|CdAsbHXCdJQV=nKkATjut&g!{>GnxD?+mEC2@VFn30M;rW2Vg*1T@VAjJu3I zn?@N13^SiGUdD_yb-ux=#1Kw|g(X}zD8`oyd9UzI2&iKPPVjD19R^*~Ldw94o~b6| z;XB9k<DzsbY`KM=(dn|x;F~V5fiS&lZ^EQd<y6K{Yp|Xys|eo4|Al6P&z9%=94o9s OI&|q4<SMYv+y4M@N`d$Q literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/py36compat.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/py36compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4cfd2024e6db99e2ff7ce14ade0762f94e899aa8 GIT binary patch literal 4640 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 A^8f$< literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/register.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/register.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5f1fad5571703820fc166271d21678065c517075 GIT binary patch literal 797 zcmZ8f&u`N(6t<nD4P7T84jcxD9I3?W!Ukv)Li{*PTzVKtLjlQ3V>eAm;$SB&i*{p2 z{)p|!zvL??{sm4vr|mTHB)|9h*?!;mp8R%qcYwftKA3&EPZ0WTH(PT7yoRL@!EwZK zjtU%NY%$46;ShvT;f5YYCx|=Ty+qs<UgrLALYI>dXypBYmuQ5Ilgnfp+s)R1Y+d{z z0D(fxQAmW7xtSMw9CLDs!X9^^h--W$l2q41#d!1FMl1XsEIk3&?p>fOka!L9YMhZP z=K@)L24dj^<kVi)yCxWYf(%r3rp6aZ!qRds+s|ijPN(muC&$6*hAAzRAk_gEl@f7O z3;sB0v<T`|T7s8BQ{^(^L0W<=h>sR^UFl;=tMe)yOO?=yc6aG$)Hge-DOoIwA}YCY zrAia!fM(-B-uO{j%BGBkvLi9Bl>!rUwaDkcklKOd-xaM?x&#??87VrKITuRPVnO34 z6+3E=vdQXT&RhNbV5y#duiIh*mX!1(t<q}Wij4An|JjS#;%hTYs1|io)l%mAHrxoL z+hLEZbJYiSAC?}1Lzs{OzDrz)?eOLrG%<xHea6bD5R91tV};~RZt;+@Z%vf1PgD<z ztXuCh#%0V{$Ivx-%UQDSng>AJZ|Gy6beU1l+~M#SnmWyOH?eT<W<TDvFy3l2{Y|EO YyQa4T{g2D|FV})!*?-j$4)HzbAKVzpegFUf literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/rotate.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/rotate.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..15b9ce4be1c3aa97e83bb615860a06f2a3616395 GIT binary patch literal 2546 zcmZ`*OLH4V5T4nWRu3nR<GdiGwjeHBB$iB4gbHO+DPoEf1}YQ*RZ@$j8Odw!%QGX# z-jXgjRB_0Ke;^&XaOT9X;51iG{Dqw89$9{bWVfcLw`ZoOyXWhk{d{h&Lg0D%Zs)1; z3Hb*<W{(5RLum3RAdD~?lZ3V?Mc#_7#BSM!w__)9Tdv`q*lT$(?!={533@m7lX9zU z#=N+aR9jU_z9g)~{1=4zyn1N2YRq{|>g9i77gDFX*3HsAE>xJe)fRl)an^@!aU+sy zprTlQovSEIzYro5n>a3`edtP$vLtDztcz-9j}6R2X!27aoU|w-EsN2X&8(KgZ00bx zZ@1h&0i!)udO^TwpOvBaS%p=hFS8mLH>W+3skY+9I~zRaiU(QDxCj{7B%%(Om8G({ z!`?b}JJ{hokJ5gy8KnF<mn!H*F_(3_@RGLbZhfX{Qd|d@6&I-tR2CR<up;>GAQGI_ zVQLxoTV;`e*{oOshIdsa4ua=fT<}0`@v{~MZNXugi+jV8onj>&Bpt9j>rK_8L1%ox zjd6CDLcs9B-h%cBn!F5zks%4E6ru^d#Rx=*Zq{w>8k@C`DnqbNJE#i|$B{hl{Z7Pr zQ1EKd%tf>Z!EEleMYCrjDVxbwv-?pV-Y@QNuRXupV}-nTcTe2eS4FZ0Pd{yb*UY1Q zHA<yw$MNdNpLDi%2AzIWay7_Rmc{Zk+nu7JIX$*UexMhkG*VGJjtU-T214>GI^_W& z)PuLUb~O9{Gta~W5@i~XUx68tZHUH>FBTMK^pO5cK>{%W$xV=0C^?u{HcAg+EVQ1G z^twZovr`e@PzW$3Fwe$$Ka$k?fhZSsDsQ`VXo-Eq=nJ#U*k|5^ZV;mdB;zus(Zs^! z!UWnZzWr(dz>+!dM!ka|O97@LNHT!NiiyXn<at{_<XQa)UdMo2;f;PHSZ)+izKpAu z8@%6Nt`|4Ys62s>LGKJL#kJK{Jn108{X0Bpr$Lk|-sj>ta0nt7+GA)Y@O^OM+5Ctq zGNfZV0k?j$cA*j&kkl=K3$%;*mDeq8HP$rE&DfO8!|<!hdJIql-|`2yP%p0WNO9}v z9D7lE=DZv0an^0e@&Pcjb+71c?RF5cuxAa{8&a=`D)LwZ#T*cAgG0LVeLEg-Q+jkI zk_L-umkV@E*U;9qAF6|#ORzkTBc(3^Ji|fCIM~A340v@a&Y@<^hZA@7{Obn42jeDK zgjT3UJ-b4E=;!G<e66ciapf(p9>*Qwjm;$R-@pKHpq5Xtj$6!*X+lT9@BfJa-5}5Y z7+JvCV`l<Y{0bRbR|rU`a<{#42}b;(H31-xZ00f#fN3KjNA}PjmnQ&a=quQ(>bS;A zYHkR?h7~rB!0L01{9;`rBYS@XS3X;RYK@$cYi9dH7r_j(&dZl(zj=^Q@t3+VUO<kL zU67A2&iE%}_r{YM__Ys!4WqP|39MOIboz1D(e%UPP@I9_b(mxzxQGzkrekn&LWi_x zora;UtxReMuOjXDxk^-&Z~)3hSgmRAwF4BFKzt9{42U<5PDc#VH({^1yu{2sup*BV z5)1N@EUM;~nSRt4brsf!M-@#3px=N~*G`viV_ulH6E5Dz86N=A&UO~12GCG~Gof@z zaJX9~7kD#j2g3yyEKjExFEMct!d}{qB$jVaZsCm!mtUd;=h_>jag^@Vy(xMF)KNMr zA=))1K~p7`K>k`}v<+&TAeXoZ(Ok1?bb&4cj(zG|3kK0OD8e-uDJmy%+pJf#9~#HP zP*=h*$=D#~z}LcXchHW}W%w$EA<MeJR2i3DC>nSt>)HT(on@Uq-+^m_x6_$GTmW0d z4J3GKr))Nfi6usqfM8jW3qXA8SdL|xRCFxg^%u-I{2!ddvoOCW4W!fRW$tSuH1TfD zpG@NT`y!|H#hlj~sBc|3xy%}TAAbd=rKNHr7nsau*EgA~{q<>l9$*qkEHV&KcrnNj Ga{E8w->5zS literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/saveopts.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/saveopts.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..15ad45d5959d551b6b55e65ce8c956073c561bb5 GIT binary patch literal 941 zcmYjPOHUL*5bnq9Ls)`AO*C?tL@s+^XORdYA;zfD8!^FzWP<6;PWLVi^V;s71vaxM zIC}CIz|p_dS5N*0PgXCpx}8)_bydw*RbTb{wY3!l=ljdS=?{X?FLzlS4~%ypdJ7as z949EnAx=q1F#3!*;q(@9D##5DDff<1xA7Y?QJ2_N!KGnwo(<*5uI7c2dBz5j7O_iM z94PouU=s|1Ld;P}I0i5hdK@5cQP|)O0B+j0jwS+t^z_v+Sbm(RX_WEpL}tQ&D4>0l z`;kACiJ0!YbYGW6kx0Rp6SOd8(Tj&8KUaQk&V&Li*XR7l7}w3U;OpcAh%P`?=p4<k zL^E>rrNZa<Bl`AfMk~tk1yTNZ<7%(Mcch~C_>SHqh;E&dnFrFCHLC_Ekkzl66}j^& zD$zZuyhAkZpP=!^2{H{phZyMA4aGn<%uJ7z+rYF_kLtToyKURyQX3@)r6bj@*HKn; zVAn^&)ECBOY-~dsk!rgFgL5&A%ETx~ylp$8vM3d{#nm-aW!7z3Pm5$|Jy!xK7skkJ zq%Dn8ZYfl-RIAw1NtFCV>ItCyxeN*=Cy^1sBvQdJPq<JzNY8?Jr(g%ugY*97?vPLQ z-tI)bzB1Fa4`-AGUxPvx+cMK8N|Nn2`-8KKaxe<!+c9~b=w-8>F<88TUU6+HH2erU z&>Nr-ZeovgNE;KfiQD)&nRfmqL*kKpL5#U+8M7;lr8zGXXLlGImr+tjT8!~L2KOo# zI#zQ2aMd#?FrRiwJ#{{}A1AsAstp}@WbQladf|)zqx9<jd*A{R=kzPO09XQbj4Fq0 R+lLPwzIE?WyL~;Te*r_-1*HH0 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/sdist.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/sdist.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5a0926d49a2da8cd3ed87f15db24aaad22125878 GIT binary patch literal 6237 zcmZ`-&y(B6l|};~3352pXf&4Ov8`Y&%Q77eNB$+pE?ecq8hM@Cj1x(=6s&D5hTY_V z1Occ4j%FCnB~q1lQ>n^sa!!hKTp#wdhy7dnnv?E1`Ly3_fSl0}lZ8eD{R6LGzxTcG z^)Hr}8wP%Vd}-(F_ty>M@ANSLRZ#f^SM~@6H#m!o5%U<Mx*3@x%QToVvb{?Ars`F7 zOU<k4yW=_fUia#_TTx@Q<Sn7E%_~uJwCpXH<62%zobp!q60dRR5%W%eX7D<1JTiDg zEQ`v(erS6(H*Xv5=3_`=w3)J^q`yt~EZl$0ig&9S53}44IQO~e1>-2sl+mR|`dQ`G z#XWl$#eOF@W{k5VcEk9_J!JdqQ#Lb?jH&UE-ZT!)sreNac>ls(<9_olmJ9)`$)%fN z%-tZ0++G-o%pJ#ENLPxzFbk8|?Iv+9lW1}-6ZtsJlO)PI)Y0!@n2_0a+fvKvu<uKe zC1cqYnK~WjLiz&Z4*WC;V~A}>Nx;#w#zPqgBcV)@DjWSq|82-+2>(OAnaXf4$i?Pf zAUAtSM3Zlhb~n3krTzz#4+d8sywl^8?Akkf^6mY6GP;UiKi<5vnTF{`7-u<_u<_pe zJG;a2PJi=Q+LP68G8zRj-_(ljqz9_`Ac%$#eXpC#=rn1vio!5g*ea8!P$TUwes)>Q z{(*`xJjM;r<jk|U$t`a8Ezb@Oufi+5N;}`Ty{f1cJ1?p?uni9xENF>09~rQqW!}QQ z!B6oO+?V)izKVMj7SbA=;%E5UqhiDge}SJx%W1JXIK$5kjr4!`d8*s6fgwx&lfO7L zVw-FiE$b&*zUME^Tf8-~CjU>I_FmvG^H(t2+3$=V;}`f(9y#7Q?(%=ayYu{2ei8Q< z`D^?V?(6(@ei`?dzB6pYdl}~PhN@`YO+LOo3S{o;2RGjha#&ByGdGA2^4&1*yV*ER z6PXL{?i@U0O)xvBm&j3&XCH4*u9a06cegMimn>g~JL8;e@D06h8<|K02@BzFgw{4D zsSkxnH(*7nV#CQN^aNqVlcRGfgd4~NhV2GDn5Ns6BFIU|Kz4V-J)tfCjZDu-AKrkK zeykXu+(bom^F$uFdE%zyT+jYI5zCn{i5tf5zn1>`p_b$uNk%oXJ2J~r=CEF?GvW(R zHqlC^r9JsPDpTW|l|vZU%$UNPwa>!Lpnh{wzqR%A8^7B6-PJ=vi)x{{wyDg{Rb`3& zTsu=yv@p{T^^f`@7W=8Z-o|5Ad}?y4aDYYILKG5|u1~4+-%v~;1VIX;ng*9cHe~~I zYWTPY=FH0NL1k9OyBar-%(AC*1ZxBU8MFG40q|)7d}ukk{r=6nG+TrE<V%>P$*sQe z&^omC-^A0hhA*2?b!zvl!^*TWwT3mhH??Ngv_fCFzX$j-ppfdeazwxHhjA~NEZzR% z%Uhpr-6jpIhQ>|}X>tV%(R<KtsU<m%{SpV%3w@CjkOfgV5q$C5p<!fWsv4xJh`BNo zU|1UDyUHE_(d0SIsG8kf(IxZ<I1p`x=E}x9^I3p{qhKifla{P%=oI9+RLzsGz2(w; zAPXS4T~&4_q8`vA^t&Uj927pmrX=f7HuX|A5Axut?N%06_fz!A5c&**HSl-XdFEIx z)-oNl#hUufq+S>RdM~z~;);b!Z#{h{HwK6wQ={Bci?&NEoo%;mWhXN1Yt5?FFb?xj z>(Eb9@>r~W9<uyA@%s}<+Gg?+W_?OxNzz`&m1%HgO>=U-knPz?pAeNSS&K?5B~dvW zR%D9=<Yu3deQIH??RMoct?Mz_wWL)ldk4E9>4U0L$Yvq%9%QPyhoA%bwLPg?iAz5s z`4x=U641nk*<dz9l%##_JhS*GM6b^WzJ?09#gXx+Rk#A&3I?wA4fAHdF>V?6aMyl+ zso|EtyNMi@XhwK>@x8aME!t>fPQf5Y$)50&%#Xr&DBr|a3Kw`4wI5jwHGPh&*ao|? zSjsat+(j?_qa7fwMK7{%QGn$zZi3~Q56wgDNzOQy1HWbmPR{<#ylcd3wvk)IhP=jL zOw9PL5u5jnNrT%2a#*xI#m)`u@?LK1(d?ncNC`HSP?>zTSm@`m8)#|*$h(5@LJLOh z;izVSYvCqYhZgUKJvYo<v5#HJ7NZwSfYA7ENeY{&90zr+_1DYod{U#GkD{a-MA`Mu zcJfsajRkQa$JZX}`>NslqlAw^k$lzk{rlq}BH#7>6Q)m;M-o7*S~<sEJZN}!nEV+v z*d#xUS6-yPuTb#;y{~WWcZK#cRRhZ*G-;c9i06<``g=ii;!E@qN%Zj7xUw}AMy+Kv znF(NMu`2Ej(_xbrp1ab8*;*Lp;QAC-_Ae+7R!+hLcJ^Aivp0*K&Fxv`$oLw2k3Wd# zpgO1x9L`?U5rG-MFZW*is0kFOARZyOw;RU>tCk5{{dtr85FeIrp#bRbcS|SDcYFl6 z95d|rJxScs>G{P5sY*9WGSRj)@+jsjGv9eiH{KdH=HyrW-Jm-Zv`#VzqhhiZD5?cQ zI9V^1^qc{0>oNJm;~EONg#vrBL3J`O2%zhPIFG5AH|maMBh@t~EtF0@30p|{*$xT> zM+D&`Lw*a?03$epa`DcZ!EH$01yT=;K{fk!|0;!Kgwof)whzt!Fb>T_I3xAd#1Dk^ zku$Z3l<I)`E;*levNeP#O^#A9Igl?Ml9aPE4kPZT2Mg(Fxg^~gl8!*Q5Ba`XJ!FMp z{5x?M^S{jdm{qGBO3+4p0bS)!P(TS}j@T}QGx87+np!5ih?uh2B+XzNA5kPm#7?h& zhwj=(s%+9J_u^!B1o24ZWB)uJy4`jp!L3@^4KhC+OHn#$CP{Yr617!fM~L=b5z2Ko zQ$%EMEsVR-m<vCJaRhxtbp&5<43uTewu|WY&omi%iK@?+l@-fp@|V=6oqp|!q^=Zu zisp=(DV8+YO2uJou)T%VJ!hqh%^)iy|J0^(0~HWf#6-E4FG5P($nA&5Oows!>jn60 z1xS3o^w;XFR`9$6lS{vxynehyjkf_ZEu@HGl;Fi+;>pecl?>XYPb=%!zkOR)sCNFz zB_2<M3}T!Lsp@wQQn4jvA|;uUvL6I8E~67Hq3-+LD9ExoY-$|4g^qu~Rk$Xws|vzE z&N;d8Jaahy=t5C*tEDZ<2v7FkC9i^?tif`N2n>&qNc3+T_Z>}CZ3=6%3iUf;=d_oV z)M9c4X=ls>$+erfae_RE5{(btY&RK4+}#Zjn35P*&z+c8TyVQuLEy8{^>1t|F? z1e*KCCDaw`Jq1_N#p}P|Dpk+~qjO9fs+bhV1)Y<mv`d>pKY|k47QJkW)pPVlyfu$3 zkPmAB#GVqv2T<hI969YnQ~pxFuT3qe1oaspqojj%&QLdXUeMrpJ6kH+v}){aP)s^7 z=yZF19k(=PZZ}VWdqIz-h(wSHpR%-Ljc6sP8hn-Fo4f~!RdpOwNL2N1k{)QU)2{2C z&Y)xeBy(#Q&Ir(=nE@xNQlOa4K@XnRsE5h_imTM<3b^uFt3gb(WOJGVos@H7O{Crh zoBIS0bF~hjkZhH>8wEnbT}qDr)S~2RRy_h5Qvy>kyeY7FRy#6=7Vy{JzNt*PGx_Po z!lFLg+TObL^E+END2*m=iHtbPuDCpLx4*dK3LfSSINt(URW;0Lt;)ecN7%!1l^G^r z>qujiLxB!D6fn5BoA5<sG<&IP^g`sPL>a|X8dB^2d@?`Gd>FY;Nu^H3zh5X0erW4+ z6PRLgF3|b$Vb9m#pS1=l&4k9FFEUH2X+p{N2U7+=-8nQV<&@tZw5H~)N~TBJj9&ww z)c|N;mw;x>9MDPgtoGLjZUJi;frOL@$*jSVN@niV%=YfP_{!3(S*E8hyq?XLk3bE1 z6?;;fe18jy)4Bg#5ykGjL19aua9pN@tut@E+}31toC#u|d9q-h*qVqA2#W5sQ54)R zU(s_@m2g7aDjhhKL5Bv=sYY?`u$b#)2H9D>ovhO))8WQkm_pRcm$J(;fPyELFYnyk z_}S#uOH$*NesZ~hJp?<Ea5pyGY#62~ruczf+-|o@c%~Fvb}@kzRFLTt+`pr$daO{Z zU&bLB)eV}eM0Nr+06va#U|_&XnP(5ed{>8C`7+J(3lt?m)3a;d`-}w^L~y>M|HYV$ zMjI8K(V9eKDGaoLg+yzKvrWzvAwiS7`N;Mw@;wZb*Qj_Og{t{JPr5|av0HMHzcyph z#~Bf&QEBd-E+E_Ax_4)5`}XHwY~NNDfLkOa(RN8kD>{*tloQHVY2GGQn}^+z03+e5 zLC2_I7g4yQT4fzFfk{YB&b@VCOZz-7su{0*8<TpPyZ|qU2Vki&$M-*`4-&PP6dQGP zkOXLQKt+Z^EtiqBE23x~O)39Cto@2Q>Bve)B$V`L^c{!UmT8(+wPKr1wrV<OoQhL* zYEbK%v(jMeY#kxTHl0?p?lhcbr=jypOh|;Vy{hU9q|(NN1I9UWb;_fcg1)I*`B>zq zZ(?)-Wkm8Nr{VwwApZF9nK+t^wf%XG^x&OqL=A&nvkpo0n=B~Hy_H20ULNo2^V}2A fcASGb9~B83xDYgO76n#~{7C=JCjJPqR-^X+?zuXL literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/setopt.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/setopt.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fdefd166086617ebb36f40d19a4d236cacd384a5 GIT binary patch literal 4539 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%0DR4j zFuI02!L_K<sq9?-=oH!PXvh&doyzctb8_#>`N?mMX-sI#U(%G0;eS|$0_HDhGs~Pu zK3!(ztF>iLNA28c(%rzE<~0loLPgrQjfNthGj1Q#*h^SK@BL>EowV8icdVmX4~kR1 zH*h3pitC0HqcrY|O8GTVyj*$hpv?Fh%Zj8}z#NyoW*h&dL&f4odqMsTOY#Hi?ovlb zs28|UeVLfZt87QxkPoOk!I4jB`Z6#fFH+PfrvXfCz=^>;+>Pv(9W;UlG$!C~vya-# zdg&yW)4vDIeNX-X%chp=E}typGMGzM9o;J+=)Qq-7>~?7ZB0Bagv{1(k6oi$PF2+( zg=<YADd%YbCT@DYUWNC@z{WjD>z8du2k%$Vdxw18?5PC|r_zgdgFh!c7yfwp%6|b8 CYR{tp literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/test.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/test.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..16a2cb1146f1254403ece4e1a8630f515a9e7489 GIT binary patch literal 8134 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/upload.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/upload.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d0975095d3989e5f19ea213bb325fe945ffb9ebf GIT binary patch literal 5220 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/upload_docs.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/command/__pycache__/upload_docs.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dd09bf75066ffa259f8fca800cc481f929b8bd14 GIT binary patch literal 6150 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 aKi1|?$$Hg(SO!rILdJ<dWD6uWUHi|Gr;&aD literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/command/alias.py b/venv/lib/python3.7/site-packages/setuptools/command/alias.py new file mode 100644 index 0000000..4532b1c --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/command/alias.py @@ -0,0 +1,80 @@ +from distutils.errors import DistutilsOptionError + +from setuptools.extern.six.moves import map + +from setuptools.command.setopt import edit_config, option_base, config_file + + +def shquote(arg): + """Quote an argument for later parsing by shlex.split()""" + for c in '"', "'", "\\", "#": + if c in arg: + return repr(arg) + if arg.split() != [arg]: + return repr(arg) + return arg + + +class alias(option_base): + """Define a shortcut that invokes one or more commands""" + + description = "define a shortcut to invoke one or more commands" + command_consumes_arguments = True + + user_options = [ + ('remove', 'r', 'remove (unset) the alias'), + ] + option_base.user_options + + boolean_options = option_base.boolean_options + ['remove'] + + def initialize_options(self): + option_base.initialize_options(self) + self.args = None + self.remove = None + + def finalize_options(self): + option_base.finalize_options(self) + if self.remove and len(self.args) != 1: + raise DistutilsOptionError( + "Must specify exactly one argument (the alias name) when " + "using --remove" + ) + + def run(self): + aliases = self.distribution.get_option_dict('aliases') + + if not self.args: + print("Command Aliases") + print("---------------") + for alias in aliases: + print("setup.py alias", format_alias(alias, aliases)) + return + + elif len(self.args) == 1: + alias, = self.args + if self.remove: + command = None + elif alias in aliases: + print("setup.py alias", format_alias(alias, aliases)) + return + else: + print("No alias definition found for %r" % alias) + return + else: + alias = self.args[0] + command = ' '.join(map(shquote, self.args[1:])) + + edit_config(self.filename, {'aliases': {alias: command}}, self.dry_run) + + +def format_alias(name, aliases): + source, command = aliases[name] + if source == config_file('global'): + source = '--global-config ' + elif source == config_file('user'): + source = '--user-config ' + elif source == config_file('local'): + source = '' + else: + source = '--filename=%r' % source + return source + name + ' ' + command diff --git a/venv/lib/python3.7/site-packages/setuptools/command/bdist_egg.py b/venv/lib/python3.7/site-packages/setuptools/command/bdist_egg.py new file mode 100644 index 0000000..9f8df91 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/command/bdist_egg.py @@ -0,0 +1,502 @@ +"""setuptools.command.bdist_egg + +Build .egg distributions""" + +from distutils.errors import DistutilsSetupError +from distutils.dir_util import remove_tree, mkpath +from distutils import log +from types import CodeType +import sys +import os +import re +import textwrap +import marshal + +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 + +try: + # Python 2.7 or >=3.2 + from sysconfig import get_path, get_python_version + + def _get_purelib(): + return get_path("purelib") +except ImportError: + from distutils.sysconfig import get_python_lib, get_python_version + + def _get_purelib(): + return get_python_lib(False) + + +def strip_module(filename): + if '.' in filename: + filename = os.path.splitext(filename)[0] + if filename.endswith('module'): + filename = filename[:-6] + return filename + + +def sorted_walk(dir): + """Do os.walk in a reproducible way, + independent of indeterministic filesystem readdir order + """ + for base, dirs, files in os.walk(dir): + dirs.sort() + files.sort() + yield base, dirs, files + + +def write_stub(resource, pyfile): + _stub_template = textwrap.dedent(""" + def __bootstrap__(): + global __bootstrap__, __loader__, __file__ + import sys, pkg_resources, imp + __file__ = pkg_resources.resource_filename(__name__, %r) + __loader__ = None; del __bootstrap__, __loader__ + imp.load_dynamic(__name__,__file__) + __bootstrap__() + """).lstrip() + with open(pyfile, 'w') as f: + f.write(_stub_template % resource) + + +class bdist_egg(Command): + description = "create an \"egg\" distribution" + + user_options = [ + ('bdist-dir=', 'b', + "temporary directory for creating the distribution"), + ('plat-name=', 'p', "platform name to embed in generated filenames " + "(default: %s)" % get_build_platform()), + ('exclude-source-files', None, + "remove all .py files from the generated egg"), + ('keep-temp', 'k', + "keep the pseudo-installation tree around after " + + "creating the distribution archive"), + ('dist-dir=', 'd', + "directory to put final built distributions in"), + ('skip-build', None, + "skip rebuilding everything (for testing/debugging)"), + ] + + boolean_options = [ + 'keep-temp', 'skip-build', 'exclude-source-files' + ] + + def initialize_options(self): + self.bdist_dir = None + self.plat_name = None + self.keep_temp = 0 + self.dist_dir = None + self.skip_build = 0 + self.egg_output = None + self.exclude_source_files = None + + def finalize_options(self): + ei_cmd = self.ei_cmd = self.get_finalized_command("egg_info") + self.egg_info = ei_cmd.egg_info + + if self.bdist_dir is None: + bdist_base = self.get_finalized_command('bdist').bdist_base + self.bdist_dir = os.path.join(bdist_base, 'egg') + + if self.plat_name is None: + self.plat_name = get_build_platform() + + self.set_undefined_options('bdist', ('dist_dir', 'dist_dir')) + + if self.egg_output is None: + + # Compute filename of the output egg + basename = Distribution( + None, None, ei_cmd.egg_name, ei_cmd.egg_version, + get_python_version(), + self.distribution.has_ext_modules() and self.plat_name + ).egg_name() + + self.egg_output = os.path.join(self.dist_dir, basename + '.egg') + + def do_install_data(self): + # Hack for packages that install data to install's --install-lib + self.get_finalized_command('install').install_lib = self.bdist_dir + + site_packages = os.path.normcase(os.path.realpath(_get_purelib())) + old, self.distribution.data_files = self.distribution.data_files, [] + + for item in old: + if isinstance(item, tuple) and len(item) == 2: + if os.path.isabs(item[0]): + realpath = os.path.realpath(item[0]) + normalized = os.path.normcase(realpath) + if normalized == site_packages or normalized.startswith( + site_packages + os.sep + ): + item = realpath[len(site_packages) + 1:], item[1] + # XXX else: raise ??? + self.distribution.data_files.append(item) + + try: + log.info("installing package data to %s", self.bdist_dir) + self.call_command('install_data', force=0, root=None) + finally: + self.distribution.data_files = old + + def get_outputs(self): + return [self.egg_output] + + def call_command(self, cmdname, **kw): + """Invoke reinitialized command `cmdname` with keyword args""" + for dirname in INSTALL_DIRECTORY_ATTRS: + kw.setdefault(dirname, self.bdist_dir) + kw.setdefault('skip_build', self.skip_build) + kw.setdefault('dry_run', self.dry_run) + cmd = self.reinitialize_command(cmdname, **kw) + self.run_command(cmdname) + return cmd + + def run(self): + # Generate metadata first + self.run_command("egg_info") + # We run install_lib before install_data, because some data hacks + # pull their data path from the install_lib command. + log.info("installing library code to %s", self.bdist_dir) + instcmd = self.get_finalized_command('install') + old_root = instcmd.root + instcmd.root = None + if self.distribution.has_c_libraries() and not self.skip_build: + self.run_command('build_clib') + cmd = self.call_command('install_lib', warn_dir=0) + instcmd.root = old_root + + all_outputs, ext_outputs = self.get_ext_outputs() + self.stubs = [] + to_compile = [] + for (p, ext_name) in enumerate(ext_outputs): + filename, ext = os.path.splitext(ext_name) + pyfile = os.path.join(self.bdist_dir, strip_module(filename) + + '.py') + self.stubs.append(pyfile) + log.info("creating stub loader for %s", ext_name) + if not self.dry_run: + write_stub(os.path.basename(ext_name), pyfile) + to_compile.append(pyfile) + ext_outputs[p] = ext_name.replace(os.sep, '/') + + if to_compile: + cmd.byte_compile(to_compile) + if self.distribution.data_files: + self.do_install_data() + + # Make the EGG-INFO directory + archive_root = self.bdist_dir + egg_info = os.path.join(archive_root, 'EGG-INFO') + self.mkpath(egg_info) + if self.distribution.scripts: + script_dir = os.path.join(egg_info, 'scripts') + log.info("installing scripts to %s", script_dir) + self.call_command('install_scripts', install_dir=script_dir, + no_ep=1) + + self.copy_metadata_to(egg_info) + native_libs = os.path.join(egg_info, "native_libs.txt") + if all_outputs: + log.info("writing %s", native_libs) + if not self.dry_run: + ensure_directory(native_libs) + libs_file = open(native_libs, 'wt') + libs_file.write('\n'.join(all_outputs)) + libs_file.write('\n') + libs_file.close() + elif os.path.isfile(native_libs): + log.info("removing %s", native_libs) + if not self.dry_run: + os.unlink(native_libs) + + write_safety_flag( + os.path.join(archive_root, 'EGG-INFO'), self.zip_safe() + ) + + if os.path.exists(os.path.join(self.egg_info, 'depends.txt')): + log.warn( + "WARNING: 'depends.txt' will not be used by setuptools 0.6!\n" + "Use the install_requires/extras_require setup() args instead." + ) + + if self.exclude_source_files: + self.zap_pyfiles() + + # Make the archive + make_zipfile(self.egg_output, archive_root, verbose=self.verbose, + dry_run=self.dry_run, mode=self.gen_header()) + if not self.keep_temp: + remove_tree(self.bdist_dir, dry_run=self.dry_run) + + # Add to 'Distribution.dist_files' so that the "upload" command works + getattr(self.distribution, 'dist_files', []).append( + ('bdist_egg', get_python_version(), self.egg_output)) + + def zap_pyfiles(self): + log.info("Removing .py files from temporary directory") + for base, dirs, files in walk_egg(self.bdist_dir): + for name in files: + path = os.path.join(base, name) + + if name.endswith('.py'): + log.debug("Deleting %s", path) + os.unlink(path) + + if base.endswith('__pycache__'): + path_old = path + + pattern = r'(?P<name>.+)\.(?P<magic>[^.]+)\.pyc' + m = re.match(pattern, name) + path_new = os.path.join( + base, os.pardir, m.group('name') + '.pyc') + log.info( + "Renaming file from [%s] to [%s]" + % (path_old, path_new)) + try: + os.remove(path_new) + except OSError: + pass + os.rename(path_old, path_new) + + def zip_safe(self): + safe = getattr(self.distribution, 'zip_safe', None) + if safe is not None: + return safe + log.warn("zip_safe flag not set; analyzing archive contents...") + return analyze_egg(self.bdist_dir, self.stubs) + + def gen_header(self): + epm = EntryPoint.parse_map(self.distribution.entry_points or '') + ep = epm.get('setuptools.installation', {}).get('eggsecutable') + if ep is None: + return 'w' # not an eggsecutable, do it the usual way. + + 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] + pkg = ep.module_name + full = '.'.join(ep.attrs) + base = ep.attrs[0] + basename = os.path.basename(self.egg_output) + + header = ( + "#!/bin/sh\n" + 'if [ `basename $0` = "%(basename)s" ]\n' + 'then exec python%(pyver)s -c "' + "import sys, os; sys.path.insert(0, os.path.abspath('$0')); " + "from %(pkg)s import %(base)s; sys.exit(%(full)s())" + '" "$@"\n' + 'else\n' + ' echo $0 is not the correct name for this egg file.\n' + ' echo Please rename it back to %(basename)s and try again.\n' + ' exec false\n' + 'fi\n' + ) % locals() + + if not self.dry_run: + mkpath(os.path.dirname(self.egg_output), dry_run=self.dry_run) + f = open(self.egg_output, 'w') + f.write(header) + f.close() + return 'a' + + def copy_metadata_to(self, target_dir): + "Copy metadata (egg info) to the target_dir" + # normalize the path (so that a forward-slash in egg_info will + # match using startswith below) + norm_egg_info = os.path.normpath(self.egg_info) + prefix = os.path.join(norm_egg_info, '') + for path in self.ei_cmd.filelist.files: + if path.startswith(prefix): + target = os.path.join(target_dir, path[len(prefix):]) + ensure_directory(target) + self.copy_file(path, target) + + def get_ext_outputs(self): + """Get a list of relative paths to C extensions in the output distro""" + + all_outputs = [] + ext_outputs = [] + + paths = {self.bdist_dir: ''} + for base, dirs, files in sorted_walk(self.bdist_dir): + for filename in files: + if os.path.splitext(filename)[1].lower() in NATIVE_EXTENSIONS: + all_outputs.append(paths[base] + filename) + for filename in dirs: + paths[os.path.join(base, filename)] = (paths[base] + + filename + '/') + + if self.distribution.has_ext_modules(): + build_cmd = self.get_finalized_command('build_ext') + for ext in build_cmd.extensions: + if isinstance(ext, Library): + continue + fullname = build_cmd.get_ext_fullname(ext.name) + filename = build_cmd.get_ext_filename(fullname) + if not os.path.basename(filename).startswith('dl-'): + if os.path.exists(os.path.join(self.bdist_dir, filename)): + ext_outputs.append(filename) + + return all_outputs, ext_outputs + + +NATIVE_EXTENSIONS = dict.fromkeys('.dll .so .dylib .pyd'.split()) + + +def walk_egg(egg_dir): + """Walk an unpacked egg's contents, skipping the metadata directory""" + walker = sorted_walk(egg_dir) + base, dirs, files = next(walker) + if 'EGG-INFO' in dirs: + dirs.remove('EGG-INFO') + yield base, dirs, files + for bdf in walker: + yield bdf + + +def analyze_egg(egg_dir, stubs): + # check for existing flag in EGG-INFO + for flag, fn in safety_flags.items(): + if os.path.exists(os.path.join(egg_dir, 'EGG-INFO', fn)): + return flag + if not can_scan(): + return False + safe = True + for base, dirs, files in walk_egg(egg_dir): + for name in files: + if name.endswith('.py') or name.endswith('.pyw'): + continue + elif name.endswith('.pyc') or name.endswith('.pyo'): + # always scan, even if we already know we're not safe + safe = scan_module(egg_dir, base, name, stubs) and safe + return safe + + +def write_safety_flag(egg_dir, safe): + # Write or remove zip safety flag file(s) + for flag, fn in safety_flags.items(): + fn = os.path.join(egg_dir, fn) + if os.path.exists(fn): + if safe is None or bool(safe) != flag: + os.unlink(fn) + elif safe is not None and bool(safe) == flag: + f = open(fn, 'wt') + f.write('\n') + f.close() + + +safety_flags = { + True: 'zip-safe', + False: 'not-zip-safe', +} + + +def scan_module(egg_dir, base, name, stubs): + """Check whether module possibly uses unsafe-for-zipfile stuff""" + + filename = os.path.join(base, name) + if filename[:-1] in stubs: + return True # Extension module + pkg = base[len(egg_dir) + 1:].replace(os.sep, '.') + module = pkg + (pkg and '.' or '') + os.path.splitext(name)[0] + if six.PY2: + skip = 8 # skip magic & date + elif sys.version_info < (3, 7): + skip = 12 # skip magic & date & file size + else: + skip = 16 # skip magic & reserved? & date & file size + f = open(filename, 'rb') + f.read(skip) + code = marshal.load(f) + f.close() + safe = True + symbols = dict.fromkeys(iter_symbols(code)) + for bad in ['__file__', '__path__']: + if bad in symbols: + log.warn("%s: module references %s", module, bad) + safe = False + if 'inspect' in symbols: + for bad in [ + 'getsource', 'getabsfile', 'getsourcefile', 'getfile' + 'getsourcelines', 'findsource', 'getcomments', 'getframeinfo', + 'getinnerframes', 'getouterframes', 'stack', 'trace' + ]: + if bad in symbols: + log.warn("%s: module MAY be using inspect.%s", module, bad) + safe = False + return safe + + +def iter_symbols(code): + """Yield names and strings used by `code` and its nested code objects""" + for name in code.co_names: + yield name + for const in code.co_consts: + if isinstance(const, six.string_types): + yield const + elif isinstance(const, CodeType): + for name in iter_symbols(const): + yield name + + +def can_scan(): + if not sys.platform.startswith('java') and sys.platform != 'cli': + # CPython, PyPy, etc. + return True + log.warn("Unable to analyze compiled code on this platform.") + log.warn("Please ask the author to include a 'zip_safe'" + " setting (either True or False) in the package's setup.py") + + +# Attribute names of options for commands that might need to be convinced to +# install to the egg build directory + +INSTALL_DIRECTORY_ATTRS = [ + 'install_lib', 'install_dir', 'install_data', 'install_base' +] + + +def make_zipfile(zip_filename, base_dir, verbose=0, dry_run=0, compress=True, + mode='w'): + """Create a zip file from all the files under 'base_dir'. The output + zip file will be named 'base_dir' + ".zip". Uses either the "zipfile" + Python module (if available) or the InfoZIP "zip" utility (if installed + and found on the default search path). If neither tool is available, + raises DistutilsExecError. Returns the name of the output zip file. + """ + import zipfile + + mkpath(os.path.dirname(zip_filename), dry_run=dry_run) + log.info("creating '%s' and adding '%s' to it", zip_filename, base_dir) + + def visit(z, dirname, names): + for name in names: + path = os.path.normpath(os.path.join(dirname, name)) + if os.path.isfile(path): + p = path[len(base_dir) + 1:] + if not dry_run: + z.write(path, p) + log.debug("adding '%s'", p) + + compression = zipfile.ZIP_DEFLATED if compress else zipfile.ZIP_STORED + if not dry_run: + z = zipfile.ZipFile(zip_filename, mode, compression=compression) + for dirname, dirs, files in sorted_walk(base_dir): + visit(z, dirname, files) + z.close() + else: + for dirname, dirs, files in sorted_walk(base_dir): + visit(None, dirname, files) + return zip_filename diff --git a/venv/lib/python3.7/site-packages/setuptools/command/bdist_rpm.py b/venv/lib/python3.7/site-packages/setuptools/command/bdist_rpm.py new file mode 100644 index 0000000..7073092 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/command/bdist_rpm.py @@ -0,0 +1,43 @@ +import distutils.command.bdist_rpm as orig + + +class bdist_rpm(orig.bdist_rpm): + """ + Override the default bdist_rpm behavior to do the following: + + 1. Run egg_info to ensure the name and version are properly calculated. + 2. Always run 'install' using --single-version-externally-managed to + disable eggs in RPM distributions. + 3. Replace dash with underscore in the version numbers for better RPM + compatibility. + """ + + def run(self): + # ensure distro name is up-to-date + self.run_command('egg_info') + + orig.bdist_rpm.run(self) + + def _make_spec_file(self): + version = self.distribution.get_version() + rpmversion = version.replace('-', '_') + spec = orig.bdist_rpm._make_spec_file(self) + line23 = '%define version ' + version + line24 = '%define version ' + rpmversion + spec = [ + line.replace( + "Source0: %{name}-%{version}.tar", + "Source0: %{name}-%{unmangled_version}.tar" + ).replace( + "setup.py install ", + "setup.py install --single-version-externally-managed " + ).replace( + "%setup", + "%setup -n %{name}-%{unmangled_version}" + ).replace(line23, line24) + for line in spec + ] + insert_loc = spec.index(line24) + 1 + unmangled_version = "%define unmangled_version " + version + spec.insert(insert_loc, unmangled_version) + return spec diff --git a/venv/lib/python3.7/site-packages/setuptools/command/bdist_wininst.py b/venv/lib/python3.7/site-packages/setuptools/command/bdist_wininst.py new file mode 100644 index 0000000..073de97 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/command/bdist_wininst.py @@ -0,0 +1,21 @@ +import distutils.command.bdist_wininst as orig + + +class bdist_wininst(orig.bdist_wininst): + def reinitialize_command(self, command, reinit_subcommands=0): + """ + Supplement reinitialize_command to work around + http://bugs.python.org/issue20819 + """ + cmd = self.distribution.reinitialize_command( + command, reinit_subcommands) + if command in ('install', 'install_lib'): + cmd.install_lib = None + return cmd + + def run(self): + self._is_running = True + try: + orig.bdist_wininst.run(self) + finally: + self._is_running = False diff --git a/venv/lib/python3.7/site-packages/setuptools/command/build_clib.py b/venv/lib/python3.7/site-packages/setuptools/command/build_clib.py new file mode 100644 index 0000000..09caff6 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/command/build_clib.py @@ -0,0 +1,98 @@ +import distutils.command.build_clib as orig +from distutils.errors import DistutilsSetupError +from distutils import log +from setuptools.dep_util import newer_pairwise_group + + +class build_clib(orig.build_clib): + """ + Override the default build_clib behaviour to do the following: + + 1. Implement a rudimentary timestamp-based dependency system + so 'compile()' doesn't run every time. + 2. Add more keys to the 'build_info' dictionary: + * obj_deps - specify dependencies for each object compiled. + this should be a dictionary mapping a key + with the source filename to a list of + dependencies. Use an empty string for global + dependencies. + * cflags - specify a list of additional flags to pass to + the compiler. + """ + + def build_libraries(self, libraries): + for (lib_name, build_info) in libraries: + 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) + sources = list(sources) + + log.info("building '%s' library", lib_name) + + # Make sure everything is the correct type. + # obj_deps should be a dictionary of keys as sources + # and a list/tuple of files that are its dependencies. + 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) + dependencies = [] + + # Get the global dependencies that are specified by the '' key. + # These will go into every source's dependency list. + 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) + + # Build the list to be used by newer_pairwise_group + # each source will be auto-added to its dependencies. + for source in sources: + src_deps = [source] + src_deps.extend(global_deps) + 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) + src_deps.extend(extra_deps) + dependencies.append(src_deps) + + expected_objects = self.compiler.object_filenames( + sources, + output_dir=self.build_temp + ) + + 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 + ) + + # 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 + ) diff --git a/venv/lib/python3.7/site-packages/setuptools/command/build_ext.py b/venv/lib/python3.7/site-packages/setuptools/command/build_ext.py new file mode 100644 index 0000000..60a8a32 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/command/build_ext.py @@ -0,0 +1,321 @@ +import os +import sys +import itertools +import imp +from distutils.command.build_ext import build_ext as _du_build_ext +from distutils.file_util import copy_file +from distutils.ccompiler import new_compiler +from distutils.sysconfig import customize_compiler, get_config_var +from distutils.errors import DistutilsError +from distutils import log + +from setuptools.extension import Library +from setuptools.extern import six + +try: + # Attempt to use Cython for building extensions, if available + from Cython.Distutils.build_ext import build_ext as _build_ext + # Additionally, assert that the compiler module will load + # also. Ref #1229. + __import__('Cython.Compiler.Main') +except ImportError: + _build_ext = _du_build_ext + +# make sure _config_vars is initialized +get_config_var("LDSHARED") +from distutils.sysconfig import _config_vars as _CONFIG_VARS + + +def _customize_compiler_for_shlib(compiler): + if sys.platform == "darwin": + # building .dylib requires additional compiler flags on OSX; here we + # temporarily substitute the pyconfig.h variables so that distutils' + # 'customize_compiler' uses them before we build the shared libraries. + tmp = _CONFIG_VARS.copy() + try: + # XXX Help! I don't have any idea whether these are right... + _CONFIG_VARS['LDSHARED'] = ( + "gcc -Wl,-x -dynamiclib -undefined dynamic_lookup") + _CONFIG_VARS['CCSHARED'] = " -dynamiclib" + _CONFIG_VARS['SO'] = ".dylib" + customize_compiler(compiler) + finally: + _CONFIG_VARS.clear() + _CONFIG_VARS.update(tmp) + else: + customize_compiler(compiler) + + +have_rtld = False +use_stubs = False +libtype = 'shared' + +if sys.platform == "darwin": + use_stubs = True +elif os.name != 'nt': + try: + import dl + use_stubs = have_rtld = hasattr(dl, 'RTLD_NOW') + except ImportError: + pass + +if_dl = lambda s: s if have_rtld else '' + + +def get_abi3_suffix(): + """Return the file extension for an abi3-compliant Extension()""" + for suffix, _, _ in (s for s in imp.get_suffixes() if s[2] == imp.C_EXTENSION): + if '.abi3' in suffix: # Unix + return suffix + elif suffix == '.pyd': # Windows + return suffix + + +class build_ext(_build_ext): + def run(self): + """Build extensions in build directory, then copy if --inplace""" + old_inplace, self.inplace = self.inplace, 0 + _build_ext.run(self) + self.inplace = old_inplace + if old_inplace: + self.copy_extensions_to_source() + + def copy_extensions_to_source(self): + build_py = self.get_finalized_command('build_py') + for ext in self.extensions: + fullname = self.get_ext_fullname(ext.name) + filename = self.get_ext_filename(fullname) + modpath = fullname.split('.') + package = '.'.join(modpath[:-1]) + package_dir = build_py.get_package_dir(package) + dest_filename = os.path.join(package_dir, + os.path.basename(filename)) + src_filename = os.path.join(self.build_lib, filename) + + # Always copy, even if source is older than destination, to ensure + # that the right extensions for the current Python/platform are + # used. + copy_file( + src_filename, dest_filename, verbose=self.verbose, + dry_run=self.dry_run + ) + if ext._needs_stub: + self.write_stub(package_dir or os.curdir, ext, True) + + def get_ext_filename(self, fullname): + filename = _build_ext.get_ext_filename(self, fullname) + if fullname in self.ext_map: + ext = self.ext_map[fullname] + use_abi3 = ( + six.PY3 + and getattr(ext, 'py_limited_api') + and get_abi3_suffix() + ) + if use_abi3: + so_ext = get_config_var('EXT_SUFFIX') + filename = filename[:-len(so_ext)] + filename = filename + get_abi3_suffix() + if isinstance(ext, Library): + fn, ext = os.path.splitext(filename) + return self.shlib_compiler.library_filename(fn, libtype) + elif use_stubs and ext._links_to_dynamic: + d, fn = os.path.split(filename) + return os.path.join(d, 'dl-' + fn) + return filename + + def initialize_options(self): + _build_ext.initialize_options(self) + self.shlib_compiler = None + self.shlibs = [] + self.ext_map = {} + + def finalize_options(self): + _build_ext.finalize_options(self) + self.extensions = self.extensions or [] + self.check_extensions_list(self.extensions) + self.shlibs = [ext for ext in self.extensions + if isinstance(ext, Library)] + if self.shlibs: + self.setup_shlib_compiler() + for ext in self.extensions: + ext._full_name = self.get_ext_fullname(ext.name) + for ext in self.extensions: + fullname = ext._full_name + self.ext_map[fullname] = ext + + # distutils 3.1 will also ask for module names + # XXX what to do with conflicts? + self.ext_map[fullname.split('.')[-1]] = ext + + ltd = self.shlibs and self.links_to_dynamic(ext) or False + ns = ltd and use_stubs and not isinstance(ext, Library) + ext._links_to_dynamic = ltd + ext._needs_stub = ns + filename = ext._file_name = self.get_ext_filename(fullname) + libdir = os.path.dirname(os.path.join(self.build_lib, filename)) + if ltd and libdir not in ext.library_dirs: + ext.library_dirs.append(libdir) + if ltd and use_stubs and os.curdir not in ext.runtime_library_dirs: + ext.runtime_library_dirs.append(os.curdir) + + def setup_shlib_compiler(self): + compiler = self.shlib_compiler = new_compiler( + compiler=self.compiler, dry_run=self.dry_run, force=self.force + ) + _customize_compiler_for_shlib(compiler) + + if self.include_dirs is not None: + compiler.set_include_dirs(self.include_dirs) + if self.define is not None: + # 'define' option is a list of (name,value) tuples + for (name, value) in self.define: + compiler.define_macro(name, value) + if self.undef is not None: + for macro in self.undef: + compiler.undefine_macro(macro) + if self.libraries is not None: + compiler.set_libraries(self.libraries) + if self.library_dirs is not None: + compiler.set_library_dirs(self.library_dirs) + if self.rpath is not None: + compiler.set_runtime_library_dirs(self.rpath) + if self.link_objects is not None: + compiler.set_link_objects(self.link_objects) + + # hack so distutils' build_extension() builds a library instead + compiler.link_shared_object = link_shared_object.__get__(compiler) + + def get_export_symbols(self, ext): + if isinstance(ext, Library): + return ext.export_symbols + return _build_ext.get_export_symbols(self, ext) + + def build_extension(self, ext): + ext._convert_pyx_sources_to_lang() + _compiler = self.compiler + try: + if isinstance(ext, Library): + self.compiler = self.shlib_compiler + _build_ext.build_extension(self, ext) + if ext._needs_stub: + cmd = self.get_finalized_command('build_py').build_lib + self.write_stub(cmd, ext) + finally: + self.compiler = _compiler + + def links_to_dynamic(self, ext): + """Return true if 'ext' links to a dynamic lib in the same package""" + # XXX this should check to ensure the lib is actually being built + # XXX as dynamic, and not just using a locally-found version or a + # XXX static-compiled version + libnames = dict.fromkeys([lib._full_name for lib in self.shlibs]) + pkg = '.'.join(ext._full_name.split('.')[:-1] + ['']) + return any(pkg + libname in libnames for libname in ext.libraries) + + def get_outputs(self): + return _build_ext.get_outputs(self) + self.__get_stubs_outputs() + + def __get_stubs_outputs(self): + # assemble the base name for each extension that needs a stub + ns_ext_bases = ( + os.path.join(self.build_lib, *ext._full_name.split('.')) + for ext in self.extensions + if ext._needs_stub + ) + # pair each base with the extension + pairs = itertools.product(ns_ext_bases, self.__get_output_extensions()) + return list(base + fnext for base, fnext in pairs) + + def __get_output_extensions(self): + yield '.py' + yield '.pyc' + if self.get_finalized_command('build_py').optimize: + yield '.pyo' + + def write_stub(self, output_dir, ext, compile=False): + log.info("writing stub loader for %s to %s", ext._full_name, + output_dir) + stub_file = (os.path.join(output_dir, *ext._full_name.split('.')) + + '.py') + if compile and os.path.exists(stub_file): + raise DistutilsError(stub_file + " already exists! Please delete.") + if not self.dry_run: + f = open(stub_file, 'w') + f.write( + '\n'.join([ + "def __bootstrap__():", + " global __bootstrap__, __file__, __loader__", + " import sys, os, pkg_resources, imp" + if_dl(", dl"), + " __file__ = pkg_resources.resource_filename" + "(__name__,%r)" + % os.path.basename(ext._file_name), + " del __bootstrap__", + " if '__loader__' in globals():", + " del __loader__", + if_dl(" old_flags = sys.getdlopenflags()"), + " old_dir = os.getcwd()", + " try:", + " os.chdir(os.path.dirname(__file__))", + if_dl(" sys.setdlopenflags(dl.RTLD_NOW)"), + " imp.load_dynamic(__name__,__file__)", + " finally:", + if_dl(" sys.setdlopenflags(old_flags)"), + " os.chdir(old_dir)", + "__bootstrap__()", + "" # terminal \n + ]) + ) + f.close() + if compile: + from distutils.util import byte_compile + + byte_compile([stub_file], optimize=0, + force=True, dry_run=self.dry_run) + optimize = self.get_finalized_command('install_lib').optimize + if optimize > 0: + byte_compile([stub_file], optimize=optimize, + force=True, dry_run=self.dry_run) + if os.path.exists(stub_file) and not self.dry_run: + os.unlink(stub_file) + + +if use_stubs or os.name == 'nt': + # Build shared libraries + # + def link_shared_object( + self, objects, output_libname, output_dir=None, libraries=None, + library_dirs=None, runtime_library_dirs=None, export_symbols=None, + debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, + target_lang=None): + self.link( + self.SHARED_LIBRARY, objects, output_libname, + output_dir, libraries, library_dirs, runtime_library_dirs, + export_symbols, debug, extra_preargs, extra_postargs, + build_temp, target_lang + ) +else: + # Build static libraries everywhere else + libtype = 'static' + + def link_shared_object( + self, objects, output_libname, output_dir=None, libraries=None, + library_dirs=None, runtime_library_dirs=None, export_symbols=None, + debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, + target_lang=None): + # XXX we need to either disallow these attrs on Library instances, + # or warn/abort here if set, or something... + # libraries=None, library_dirs=None, runtime_library_dirs=None, + # export_symbols=None, extra_preargs=None, extra_postargs=None, + # build_temp=None + + assert output_dir is None # distutils build_ext doesn't pass this + output_dir, filename = os.path.split(output_libname) + basename, ext = os.path.splitext(filename) + if self.library_filename("x").startswith('lib'): + # strip 'lib' prefix; this is kludgy if some platform uses + # a different prefix + basename = basename[3:] + + self.create_static_lib( + objects, basename, output_dir, debug, target_lang + ) diff --git a/venv/lib/python3.7/site-packages/setuptools/command/build_py.py b/venv/lib/python3.7/site-packages/setuptools/command/build_py.py new file mode 100644 index 0000000..b0314fd --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/command/build_py.py @@ -0,0 +1,270 @@ +from glob import glob +from distutils.util import convert_path +import distutils.command.build_py as orig +import os +import fnmatch +import textwrap +import io +import distutils.errors +import itertools + +from setuptools.extern import six +from setuptools.extern.six.moves import map, filter, filterfalse + +try: + from setuptools.lib2to3_ex import Mixin2to3 +except ImportError: + + class Mixin2to3: + def run_2to3(self, files, doctests=True): + "do nothing" + + +class build_py(orig.build_py, Mixin2to3): + """Enhanced 'build_py' command that includes data files with packages + + The data files are specified via a 'package_data' argument to 'setup()'. + See 'setuptools.dist.Distribution' for more details. + + Also, this version of the 'build_py' command allows you to specify both + 'py_modules' and 'packages' in the same setup operation. + """ + + def finalize_options(self): + orig.build_py.finalize_options(self) + self.package_data = self.distribution.package_data + self.exclude_package_data = (self.distribution.exclude_package_data or + {}) + if 'data_files' in self.__dict__: + del self.__dict__['data_files'] + self.__updated_files = [] + self.__doctests_2to3 = [] + + def run(self): + """Build modules, packages, and copy data files to build directory""" + if not self.py_modules and not self.packages: + return + + if self.py_modules: + self.build_modules() + + if self.packages: + self.build_packages() + self.build_package_data() + + self.run_2to3(self.__updated_files, False) + self.run_2to3(self.__updated_files, True) + self.run_2to3(self.__doctests_2to3, True) + + # Only compile actual .py files, using our base class' idea of what our + # output files are. + self.byte_compile(orig.build_py.get_outputs(self, include_bytecode=0)) + + def __getattr__(self, attr): + "lazily compute data files" + if attr == 'data_files': + self.data_files = self._get_data_files() + return self.data_files + return orig.build_py.__getattr__(self, attr) + + def build_module(self, module, module_file, package): + if six.PY2 and isinstance(package, six.string_types): + # avoid errors on Python 2 when unicode is passed (#190) + package = package.split('.') + outfile, copied = orig.build_py.build_module(self, module, module_file, + package) + if copied: + self.__updated_files.append(outfile) + return outfile, copied + + def _get_data_files(self): + """Generate list of '(package,src_dir,build_dir,filenames)' tuples""" + self.analyze_manifest() + return list(map(self._get_pkg_data_files, self.packages or ())) + + def _get_pkg_data_files(self, package): + # Locate package source directory + src_dir = self.get_package_dir(package) + + # Compute package build directory + build_dir = os.path.join(*([self.build_lib] + package.split('.'))) + + # Strip directory from globbed filenames + filenames = [ + os.path.relpath(file, src_dir) + for file in self.find_data_files(package, src_dir) + ] + return package, src_dir, build_dir, filenames + + def find_data_files(self, package, src_dir): + """Return filenames for package's data files in 'src_dir'""" + patterns = self._get_platform_patterns( + self.package_data, + package, + src_dir, + ) + globs_expanded = map(glob, patterns) + # flatten the expanded globs into an iterable of matches + globs_matches = itertools.chain.from_iterable(globs_expanded) + glob_files = filter(os.path.isfile, globs_matches) + files = itertools.chain( + self.manifest_files.get(package, []), + glob_files, + ) + return self.exclude_data_files(package, src_dir, files) + + def build_package_data(self): + """Copy data files into build directory""" + for package, src_dir, build_dir, filenames in self.data_files: + for filename in filenames: + target = os.path.join(build_dir, filename) + self.mkpath(os.path.dirname(target)) + srcfile = os.path.join(src_dir, filename) + outf, copied = self.copy_file(srcfile, target) + srcfile = os.path.abspath(srcfile) + if (copied and + srcfile in self.distribution.convert_2to3_doctests): + self.__doctests_2to3.append(outf) + + def analyze_manifest(self): + self.manifest_files = mf = {} + if not self.distribution.include_package_data: + return + src_dirs = {} + for package in self.packages or (): + # Locate package source directory + src_dirs[assert_relative(self.get_package_dir(package))] = package + + self.run_command('egg_info') + ei_cmd = self.get_finalized_command('egg_info') + for path in ei_cmd.filelist.files: + d, f = os.path.split(assert_relative(path)) + prev = None + oldf = f + while d and d != prev and d not in src_dirs: + prev = d + d, df = os.path.split(d) + f = os.path.join(df, f) + if d in src_dirs: + if path.endswith('.py') and f == oldf: + continue # it's a module, not data + mf.setdefault(src_dirs[d], []).append(path) + + def get_data_files(self): + pass # Lazily compute data files in _get_data_files() function. + + def check_package(self, package, package_dir): + """Check namespace packages' __init__ for declare_namespace""" + try: + return self.packages_checked[package] + except KeyError: + pass + + init_py = orig.build_py.check_package(self, package, package_dir) + self.packages_checked[package] = init_py + + if not init_py or not self.distribution.namespace_packages: + return init_py + + for pkg in self.distribution.namespace_packages: + if pkg == package or pkg.startswith(package + '.'): + break + else: + return init_py + + with io.open(init_py, 'rb') as f: + contents = f.read() + if b'declare_namespace' not in contents: + raise distutils.errors.DistutilsError( + "Namespace package problem: %s is a namespace package, but " + "its\n__init__.py does not call declare_namespace()! Please " + 'fix it.\n(See the setuptools manual under ' + '"Namespace Packages" for details.)\n"' % (package,) + ) + return init_py + + def initialize_options(self): + self.packages_checked = {} + orig.build_py.initialize_options(self) + + def get_package_dir(self, package): + res = orig.build_py.get_package_dir(self, package) + if self.distribution.src_root is not None: + return os.path.join(self.distribution.src_root, res) + return res + + def exclude_data_files(self, package, src_dir, files): + """Filter filenames for package's data files in 'src_dir'""" + files = list(files) + patterns = self._get_platform_patterns( + self.exclude_package_data, + package, + src_dir, + ) + match_groups = ( + fnmatch.filter(files, pattern) + for pattern in patterns + ) + # flatten the groups of matches into an iterable of matches + matches = itertools.chain.from_iterable(match_groups) + bad = set(matches) + keepers = ( + fn + for fn in files + if fn not in bad + ) + # ditch dupes + return list(_unique_everseen(keepers)) + + @staticmethod + def _get_platform_patterns(spec, package, src_dir): + """ + yield platform-specific path patterns (suitable for glob + or fn_match) from a glob-based spec (such as + self.package_data or self.exclude_package_data) + matching package in src_dir. + """ + raw_patterns = itertools.chain( + spec.get('', []), + spec.get(package, []), + ) + return ( + # Each pattern has to be converted to a platform-specific path + os.path.join(src_dir, convert_path(pattern)) + for pattern in raw_patterns + ) + + +# from Python docs +def _unique_everseen(iterable, key=None): + "List unique elements, preserving order. Remember all elements ever seen." + # unique_everseen('AAAABBBCCDAABBB') --> A B C D + # unique_everseen('ABBCcAD', str.lower) --> A B C D + seen = set() + seen_add = seen.add + if key is None: + for element in filterfalse(seen.__contains__, iterable): + seen_add(element) + yield element + else: + for element in iterable: + k = key(element) + if k not in seen: + seen_add(k) + yield element + + +def assert_relative(path): + if not os.path.isabs(path): + return path + from distutils.errors import DistutilsSetupError + + msg = textwrap.dedent(""" + Error: setup script specifies an absolute path: + + %s + + setup() arguments must *always* be /-separated paths relative to the + setup.py directory, *never* absolute paths. + """).lstrip() % path + raise DistutilsSetupError(msg) diff --git a/venv/lib/python3.7/site-packages/setuptools/command/develop.py b/venv/lib/python3.7/site-packages/setuptools/command/develop.py new file mode 100644 index 0000000..fdc9fc4 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/command/develop.py @@ -0,0 +1,218 @@ +from distutils.util import convert_path +from distutils import log +from distutils.errors import DistutilsError, DistutilsOptionError +import os +import glob +import io + +from setuptools.extern import six + +from pkg_resources import Distribution, PathMetadata, normalize_path +from setuptools.command.easy_install import easy_install +from setuptools import namespaces +import setuptools + +__metaclass__ = type + + +class develop(namespaces.DevelopInstaller, easy_install): + """Set up package for development""" + + description = "install package in 'development mode'" + + user_options = easy_install.user_options + [ + ("uninstall", "u", "Uninstall this source package"), + ("egg-path=", None, "Set the path to be used in the .egg-link file"), + ] + + boolean_options = easy_install.boolean_options + ['uninstall'] + + command_consumes_arguments = False # override base + + def run(self): + if self.uninstall: + self.multi_version = True + self.uninstall_link() + self.uninstall_namespaces() + else: + self.install_for_development() + self.warn_deprecated_options() + + def initialize_options(self): + self.uninstall = None + self.egg_path = None + easy_install.initialize_options(self) + self.setup_path = None + self.always_copy_from = '.' # always copy eggs installed in curdir + + def finalize_options(self): + ei = self.get_finalized_command("egg_info") + if ei.broken_egg_info: + template = "Please rename %r to %r before using 'develop'" + args = ei.egg_info, ei.broken_egg_info + raise DistutilsError(template % args) + self.args = [ei.egg_name] + + easy_install.finalize_options(self) + self.expand_basedirs() + self.expand_dirs() + # pick up setup-dir .egg files only: no .egg-info + self.package_index.scan(glob.glob('*.egg')) + + egg_link_fn = ei.egg_name + '.egg-link' + self.egg_link = os.path.join(self.install_dir, egg_link_fn) + self.egg_base = ei.egg_base + if self.egg_path is None: + self.egg_path = os.path.abspath(ei.egg_base) + + target = normalize_path(self.egg_base) + egg_path = normalize_path(os.path.join(self.install_dir, + self.egg_path)) + if egg_path != target: + raise DistutilsOptionError( + "--egg-path must be a relative path from the install" + " directory to " + target + ) + + # Make a distribution for the package's source + self.dist = Distribution( + target, + PathMetadata(target, os.path.abspath(ei.egg_info)), + project_name=ei.egg_name + ) + + self.setup_path = self._resolve_setup_path( + self.egg_base, + self.install_dir, + self.egg_path, + ) + + @staticmethod + def _resolve_setup_path(egg_base, install_dir, egg_path): + """ + Generate a path from egg_base back to '.' where the + setup script resides and ensure that path points to the + setup path from $install_dir/$egg_path. + """ + path_to_setup = egg_base.replace(os.sep, '/').rstrip('/') + if path_to_setup != os.curdir: + path_to_setup = '../' * (path_to_setup.count('/') + 1) + resolved = normalize_path( + os.path.join(install_dir, egg_path, path_to_setup) + ) + if resolved != normalize_path(os.curdir): + raise DistutilsOptionError( + "Can't get a consistent path to setup script from" + " installation directory", resolved, normalize_path(os.curdir)) + return path_to_setup + + def install_for_development(self): + if six.PY3 and getattr(self.distribution, 'use_2to3', False): + # If we run 2to3 we can not do this inplace: + + # Ensure metadata is up-to-date + self.reinitialize_command('build_py', inplace=0) + self.run_command('build_py') + bpy_cmd = self.get_finalized_command("build_py") + build_path = normalize_path(bpy_cmd.build_lib) + + # Build extensions + self.reinitialize_command('egg_info', egg_base=build_path) + self.run_command('egg_info') + + self.reinitialize_command('build_ext', inplace=0) + self.run_command('build_ext') + + # Fixup egg-link and easy-install.pth + ei_cmd = self.get_finalized_command("egg_info") + self.egg_path = build_path + self.dist.location = build_path + # XXX + self.dist._provider = PathMetadata(build_path, ei_cmd.egg_info) + else: + # Without 2to3 inplace works fine: + self.run_command('egg_info') + + # Build extensions in-place + 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 + + self.install_namespaces() + + # create an .egg-link in the installation dir, pointing to our egg + log.info("Creating %s (link to %s)", self.egg_link, self.egg_base) + if not self.dry_run: + with open(self.egg_link, "w") as f: + f.write(self.egg_path + "\n" + self.setup_path) + # postprocess the installed distro, fixing up .pth, installing scripts, + # and handling requirements + self.process_distribution(None, self.dist, not self.no_deps) + + def uninstall_link(self): + if os.path.exists(self.egg_link): + log.info("Removing %s (link to %s)", self.egg_link, self.egg_base) + egg_link_file = open(self.egg_link) + contents = [line.rstrip() for line in egg_link_file] + egg_link_file.close() + if contents not in ([self.egg_path], + [self.egg_path, self.setup_path]): + log.warn("Link points to %s: uninstall aborted", contents) + return + if not self.dry_run: + os.unlink(self.egg_link) + if not self.dry_run: + self.update_pth(self.dist) # remove any .pth link to us + if self.distribution.scripts: + # XXX should also check for entry point scripts! + log.warn("Note: you must uninstall or replace scripts manually!") + + def install_egg_scripts(self, dist): + if dist is not self.dist: + # Installing a dependency, so fall back to normal behavior + return easy_install.install_egg_scripts(self, dist) + + # create wrapper scripts in the script dir, pointing to dist.scripts + + # new-style... + self.install_wrapper_scripts(dist) + + # ...and old-style + for script_name in self.distribution.scripts or []: + script_path = os.path.abspath(convert_path(script_name)) + script_name = os.path.basename(script_path) + with io.open(script_path) as strm: + script_text = strm.read() + self.install_script(dist, script_name, script_text, script_path) + + def install_wrapper_scripts(self, dist): + dist = VersionlessRequirement(dist) + return easy_install.install_wrapper_scripts(self, dist) + + +class VersionlessRequirement: + """ + Adapt a pkg_resources.Distribution to simply return the project + name as the 'requirement' so that scripts will work across + multiple versions. + + >>> dist = Distribution(project_name='foo', version='1.0') + >>> str(dist.as_requirement()) + 'foo==1.0' + >>> adapted_dist = VersionlessRequirement(dist) + >>> str(adapted_dist.as_requirement()) + 'foo' + """ + + def __init__(self, dist): + self.__dist = dist + + def __getattr__(self, name): + return getattr(self.__dist, name) + + def as_requirement(self): + return self.project_name diff --git a/venv/lib/python3.7/site-packages/setuptools/command/dist_info.py b/venv/lib/python3.7/site-packages/setuptools/command/dist_info.py new file mode 100644 index 0000000..c45258f --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/command/dist_info.py @@ -0,0 +1,36 @@ +""" +Create a dist_info directory +As defined in the wheel specification +""" + +import os + +from distutils.core import Command +from distutils import log + + +class dist_info(Command): + + description = 'create a .dist-info directory' + + user_options = [ + ('egg-base=', 'e', "directory containing .egg-info directories" + " (default: top of the source tree)"), + ] + + def initialize_options(self): + self.egg_base = None + + def finalize_options(self): + pass + + def run(self): + egg_info = self.get_finalized_command('egg_info') + egg_info.egg_base = self.egg_base + egg_info.finalize_options() + egg_info.run() + dist_info_dir = egg_info.egg_info[:-len('.egg-info')] + '.dist-info' + log.info("creating '{}'".format(os.path.abspath(dist_info_dir))) + + bdist_wheel = self.get_finalized_command('bdist_wheel') + bdist_wheel.egg2dist(egg_info.egg_info, dist_info_dir) diff --git a/venv/lib/python3.7/site-packages/setuptools/command/easy_install.py b/venv/lib/python3.7/site-packages/setuptools/command/easy_install.py new file mode 100644 index 0000000..06c9827 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/command/easy_install.py @@ -0,0 +1,2342 @@ +#!/usr/bin/env python +""" +Easy Install +------------ + +A tool for doing automatic download/extract/build of distutils-based Python +packages. For detailed documentation, see the accompanying EasyInstall.txt +file, or visit the `EasyInstall home page`__. + +__ https://setuptools.readthedocs.io/en/latest/easy_install.html + +""" + +from glob import glob +from distutils.util import get_platform +from distutils.util import convert_path, subst_vars +from distutils.errors import ( + DistutilsArgError, DistutilsOptionError, + DistutilsError, DistutilsPlatformError, +) +from distutils.command.install import INSTALL_SCHEMES, SCHEME_KEYS +from distutils import log, dir_util +from distutils.command.build_scripts import first_line_re +from distutils.spawn import find_executable +import sys +import os +import zipimport +import shutil +import tempfile +import zipfile +import re +import stat +import random +import textwrap +import warnings +import site +import struct +import contextlib +import subprocess +import shlex +import io + + +from sysconfig import get_config_vars, get_path + +from setuptools import SetuptoolsDeprecationWarning + +from setuptools.extern import six +from setuptools.extern.six.moves import configparser, map + +from setuptools import Command +from setuptools.sandbox import run_setup +from setuptools.py27compat import rmtree_safe +from setuptools.command import setopt +from setuptools.archive_util import unpack_archive +from setuptools.package_index import ( + PackageIndex, parse_requirement_arg, URL_SCHEME, +) +from setuptools.command import bdist_egg, egg_info +from setuptools.wheel import Wheel +from pkg_resources import ( + yield_lines, normalize_path, resource_string, ensure_directory, + get_distribution, find_distributions, Environment, Requirement, + Distribution, PathMetadata, EggMetadata, WorkingSet, DistributionNotFound, + VersionConflict, DEVELOP_DIST, +) +import pkg_resources.py31compat + +__metaclass__ = type + +# Turn on PEP440Warnings +warnings.filterwarnings("default", category=pkg_resources.PEP440Warning) + +__all__ = [ + 'samefile', 'easy_install', 'PthDistributions', 'extract_wininst_cfg', + 'main', 'get_exe_prefixes', +] + + +def is_64bit(): + return struct.calcsize("P") == 8 + + +def samefile(p1, p2): + """ + Determine if two paths reference the same file. + + Augments os.path.samefile to work on Windows and + suppresses errors if the path doesn't exist. + """ + both_exist = os.path.exists(p1) and os.path.exists(p2) + use_samefile = hasattr(os.path, 'samefile') and both_exist + if use_samefile: + return os.path.samefile(p1, p2) + norm_p1 = os.path.normpath(os.path.normcase(p1)) + norm_p2 = os.path.normpath(os.path.normcase(p2)) + return norm_p1 == norm_p2 + + +if six.PY2: + + def _to_bytes(s): + return s + + def isascii(s): + try: + six.text_type(s, 'ascii') + return True + except UnicodeError: + return False +else: + + def _to_bytes(s): + return s.encode('utf8') + + def isascii(s): + try: + s.encode('ascii') + return True + except UnicodeError: + return False + + +_one_liner = lambda text: textwrap.dedent(text).strip().replace('\n', '; ') + + +class easy_install(Command): + """Manage a download/build/install process""" + description = "Find/get/install Python packages" + command_consumes_arguments = True + + user_options = [ + ('prefix=', None, "installation prefix"), + ("zip-ok", "z", "install package as a zipfile"), + ("multi-version", "m", "make apps have to require() a version"), + ("upgrade", "U", "force upgrade (searches PyPI for latest versions)"), + ("install-dir=", "d", "install package to DIR"), + ("script-dir=", "s", "install scripts to DIR"), + ("exclude-scripts", "x", "Don't install scripts"), + ("always-copy", "a", "Copy all needed packages to install dir"), + ("index-url=", "i", "base URL of Python Package Index"), + ("find-links=", "f", "additional URL(s) to search for packages"), + ("build-directory=", "b", + "download/extract/build in DIR; keep the results"), + ('optimize=', 'O', + "also compile with optimization: -O1 for \"python -O\", " + "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"), + ('record=', None, + "filename in which to record list of installed files"), + ('always-unzip', 'Z', "don't install as a zipfile, no matter what"), + ('site-dirs=', 'S', "list of directories where .pth files work"), + ('editable', 'e', "Install specified packages in editable form"), + ('no-deps', 'N', "don't install dependencies"), + ('allow-hosts=', 'H', "pattern(s) that hostnames must match"), + ('local-snapshots-ok', 'l', + "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") + ] + boolean_options = [ + 'zip-ok', 'multi-version', 'exclude-scripts', 'upgrade', 'always-copy', + 'editable', + 'no-deps', 'local-snapshots-ok', 'version' + ] + + 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 + + def initialize_options(self): + # the --user option seems to be an opt-in one, + # so the default should be False. + self.user = 0 + self.zip_ok = self.local_snapshots_ok = None + self.install_dir = self.script_dir = self.exclude_scripts = None + self.index_url = None + self.find_links = None + self.build_directory = None + self.args = None + self.optimize = self.record = None + self.upgrade = self.always_copy = self.multi_version = None + self.editable = self.no_deps = self.allow_hosts = None + self.root = self.prefix = self.no_report = None + self.version = None + self.install_purelib = None # for pure module distributions + self.install_platlib = None # non-pure (dists w/ extensions) + self.install_headers = None # for C/C++ headers + self.install_lib = None # set to either purelib or platlib + self.install_scripts = None + self.install_data = None + self.install_base = None + self.install_platbase = None + if site.ENABLE_USER_SITE: + self.install_userbase = site.USER_BASE + self.install_usersite = site.USER_SITE + else: + self.install_userbase = None + self.install_usersite = None + self.no_find_links = None + + # Options not specifiable via command line + self.package_index = None + 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" + # section, even if this is a "develop" or "install" command, or some + # other embedding. + self._dry_run = None + self.verbose = self.distribution.verbose + self.distribution._set_command_options( + self, self.distribution.get_option_dict('easy_install') + ) + + def delete_blockers(self, blockers): + extant_blockers = ( + filename for filename in blockers + if os.path.exists(filename) or os.path.islink(filename) + ) + list(map(self._delete_path, extant_blockers)) + + def _delete_path(self, path): + log.info("Deleting %s", path) + if self.dry_run: + return + + is_tree = os.path.isdir(path) and not os.path.islink(path) + remover = rmtree if is_tree else os.unlink + remover(path) + + @staticmethod + def _render_version(): + """ + Render the Setuptools version and installation details, then exit. + """ + ver = sys.version[:3] + dist = get_distribution('setuptools') + tmpl = 'setuptools {dist.version} from {dist.location} (Python {ver})' + print(tmpl.format(**locals())) + raise SystemExit() + + def finalize_options(self): + self.version and self._render_version() + + py_version = sys.version.split()[0] + prefix, exec_prefix = get_config_vars('prefix', 'exec_prefix') + + self.config_vars = { + 'dist_name': self.distribution.get_name(), + 'dist_version': self.distribution.get_version(), + 'dist_fullname': self.distribution.get_fullname(), + 'py_version': py_version, + 'py_version_short': py_version[0:3], + 'py_version_nodot': py_version[0] + py_version[2], + 'sys_prefix': prefix, + 'prefix': prefix, + 'sys_exec_prefix': exec_prefix, + 'exec_prefix': exec_prefix, + # Only python 3.2+ has abiflags + 'abiflags': getattr(sys, 'abiflags', ''), + } + + if site.ENABLE_USER_SITE: + self.config_vars['userbase'] = self.install_userbase + self.config_vars['usersite'] = self.install_usersite + + self._fix_install_dir_for_user_site() + + self.expand_basedirs() + self.expand_dirs() + + self._expand( + 'install_dir', 'script_dir', 'build_directory', + 'site_dirs', + ) + # If a non-default installation directory was specified, default the + # script directory to match it. + if self.script_dir is None: + self.script_dir = self.install_dir + + if self.no_find_links is None: + self.no_find_links = False + + # Let install_dir get set by install_lib command, which in turn + # gets its info from the install command, and takes into account + # --prefix and --home and all that other crud. + self.set_undefined_options( + 'install_lib', ('install_dir', 'install_dir') + ) + # Likewise, set default script_dir from 'install_scripts.install_dir' + self.set_undefined_options( + 'install_scripts', ('install_dir', 'script_dir') + ) + + if self.user and self.install_purelib: + self.install_dir = self.install_purelib + self.script_dir = self.install_scripts + # default --record from the install command + self.set_undefined_options('install', ('record', 'record')) + # Should this be moved to the if statement below? It's not used + # elsewhere + normpath = map(normalize_path, sys.path) + self.all_site_dirs = get_site_dirs() + if self.site_dirs is not None: + site_dirs = [ + os.path.expanduser(s.strip()) for s in + self.site_dirs.split(',') + ] + for d in site_dirs: + if not os.path.isdir(d): + log.warn("%s (in --site-dirs) does not exist", d) + elif normalize_path(d) not in normpath: + raise DistutilsOptionError( + d + " (in --site-dirs) is not on sys.path" + ) + else: + self.all_site_dirs.append(normalize_path(d)) + if not self.editable: + self.check_site_dir() + self.index_url = self.index_url or "https://pypi.org/simple/" + self.shadow_path = self.all_site_dirs[:] + for path_item in self.install_dir, normalize_path(self.script_dir): + if path_item not in self.shadow_path: + self.shadow_path.insert(0, path_item) + + if self.allow_hosts is not None: + hosts = [s.strip() for s in self.allow_hosts.split(',')] + else: + hosts = ['*'] + if self.package_index is None: + self.package_index = self.create_index( + self.index_url, search_path=self.shadow_path, hosts=hosts, + ) + self.local_index = Environment(self.shadow_path + sys.path) + + if self.find_links is not None: + if isinstance(self.find_links, six.string_types): + self.find_links = self.find_links.split() + else: + self.find_links = [] + if self.local_snapshots_ok: + self.package_index.scan_egg_links(self.shadow_path + sys.path) + if not self.no_find_links: + self.package_index.add_find_links(self.find_links) + self.set_undefined_options('install_lib', ('optimize', 'optimize')) + if not isinstance(self.optimize, int): + try: + self.optimize = int(self.optimize) + if not (0 <= self.optimize <= 2): + raise ValueError + except ValueError: + raise DistutilsOptionError("--optimize must be 0, 1, or 2") + + if self.editable and not self.build_directory: + raise DistutilsArgError( + "Must specify a build directory (-b) when using --editable" + ) + if not self.args: + raise DistutilsArgError( + "No urls, filenames, or requirements specified (see --help)") + + self.outputs = [] + + def _fix_install_dir_for_user_site(self): + """ + Fix the install_dir if "--user" was used. + """ + if not self.user or not site.ENABLE_USER_SITE: + return + + self.create_home_path() + if self.install_userbase is None: + msg = "User base directory is not specified" + raise DistutilsPlatformError(msg) + self.install_base = self.install_platbase = self.install_userbase + scheme_name = os.name.replace('posix', 'unix') + '_user' + self.select_scheme(scheme_name) + + def _expand_attrs(self, attrs): + for attr in attrs: + val = getattr(self, attr) + if val is not None: + if os.name == 'posix' or os.name == 'nt': + val = os.path.expanduser(val) + val = subst_vars(val, self.config_vars) + setattr(self, attr, val) + + def expand_basedirs(self): + """Calls `os.path.expanduser` on install_base, install_platbase and + root.""" + self._expand_attrs(['install_base', 'install_platbase', 'root']) + + def expand_dirs(self): + """Calls `os.path.expanduser` on install dirs.""" + dirs = [ + 'install_purelib', + 'install_platlib', + 'install_lib', + 'install_headers', + 'install_scripts', + 'install_data', + ] + self._expand_attrs(dirs) + + def run(self): + if self.verbose != self.distribution.verbose: + log.set_verbosity(self.verbose) + try: + for spec in self.args: + self.easy_install(spec, not self.no_deps) + if self.record: + outputs = self.outputs + if self.root: # strip any package prefix + root_len = len(self.root) + for counter in range(len(outputs)): + outputs[counter] = outputs[counter][root_len:] + from distutils import file_util + + self.execute( + file_util.write_file, (self.record, outputs), + "writing list of installed files to '%s'" % + self.record + ) + self.warn_deprecated_options() + finally: + log.set_verbosity(self.distribution.verbose) + + def pseudo_tempname(self): + """Return a pseudo-tempname base in the install directory. + This code is intentionally naive; if a malicious party can write to + the target directory you're already in deep doodoo. + """ + try: + pid = os.getpid() + except Exception: + pid = random.randint(0, sys.maxsize) + return os.path.join(self.install_dir, "test-easy-install-%s" % pid) + + def warn_deprecated_options(self): + pass + + def check_site_dir(self): + """Verify that self.install_dir is .pth-capable dir, if needed""" + + instdir = normalize_path(self.install_dir) + pth_file = os.path.join(instdir, 'easy-install.pth') + + # Is it a configured, PYTHONPATH, implicit, or explicit site dir? + is_site_dir = instdir in self.all_site_dirs + + if not is_site_dir and not self.multi_version: + # No? Then directly test whether it does .pth file processing + is_site_dir = self.check_pth_processing() + else: + # make sure we can write to target dir + testfile = self.pseudo_tempname() + '.write-test' + test_exists = os.path.exists(testfile) + try: + if test_exists: + os.unlink(testfile) + open(testfile, 'w').close() + os.unlink(testfile) + except (OSError, IOError): + 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()) + + if is_site_dir: + if self.pth_file is None: + self.pth_file = PthDistributions(pth_file, self.all_site_dirs) + 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 + self.install_dir = instdir + + __cant_write_msg = textwrap.dedent(""" + can't create or remove files in install directory + + The following error occurred while trying to add or remove files in the + installation directory: + + %s + + The installation directory you specified (via --install-dir, --prefix, or + the distutils default setting) was: + + %s + """).lstrip() + + __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() + + __access_msg = textwrap.dedent(""" + Perhaps your account does not have write access to this directory? If the + installation directory is a system-owned directory, you may need to sign in + as the administrator or "root" account. If you do not have administrative + access to this machine, you may wish to choose a different installation + directory, preferably one that is listed in your PYTHONPATH environment + variable. + + For information on other options, you may wish to consult the + documentation at: + + https://setuptools.readthedocs.io/en/latest/easy_install.html + + Please make the appropriate changes for your system and try again. + """).lstrip() + + def cant_write_to_target(self): + msg = self.__cant_write_msg % (sys.exc_info()[1], self.install_dir,) + + if not os.path.exists(self.install_dir): + msg += '\n' + self.__not_exists_id + else: + msg += '\n' + self.__access_msg + raise DistutilsError(msg) + + def check_pth_processing(self): + """Empirically verify whether .pth files are supported in inst. dir""" + instdir = self.install_dir + log.info("Checking .pth file support in %s", instdir) + pth_file = self.pseudo_tempname() + ".pth" + ok_file = pth_file + '.ok' + ok_exists = os.path.exists(ok_file) + tmpl = _one_liner(""" + import os + f = open({ok_file!r}, 'w') + f.write('OK') + f.close() + """) + '\n' + try: + if ok_exists: + os.unlink(ok_file) + dirname = os.path.dirname(ok_file) + pkg_resources.py31compat.makedirs(dirname, exist_ok=True) + f = open(pth_file, 'w') + except (OSError, IOError): + self.cant_write_to_target() + else: + try: + f.write(tmpl.format(**locals())) + f.close() + f = None + executable = sys.executable + if os.name == 'nt': + dirname, basename = os.path.split(executable) + alt = os.path.join(dirname, 'pythonw.exe') + use_alt = ( + basename.lower() == 'python.exe' and + os.path.exists(alt) + ) + if use_alt: + # use pythonw.exe to avoid opening a console window + executable = alt + + from distutils.spawn import spawn + + spawn([executable, '-E', '-c', 'pass'], 0) + + if os.path.exists(ok_file): + log.info( + "TEST PASSED: %s appears to support .pth files", + instdir + ) + return True + finally: + if f: + f.close() + if os.path.exists(ok_file): + os.unlink(ok_file) + if os.path.exists(pth_file): + os.unlink(pth_file) + if not self.multi_version: + log.warn("TEST FAILED: %s does NOT support .pth files", instdir) + return False + + def install_egg_scripts(self, dist): + """Write all the scripts for `dist`, unless scripts are excluded""" + if not self.exclude_scripts and dist.metadata_isdir('scripts'): + for script_name in dist.metadata_listdir('scripts'): + if dist.metadata_isdir('scripts/' + script_name): + # The "script" is a directory, likely a Python 3 + # __pycache__ directory, so skip it. + continue + self.install_script( + dist, script_name, + dist.get_metadata('scripts/' + script_name) + ) + self.install_wrapper_scripts(dist) + + def add_output(self, path): + if os.path.isdir(path): + for base, dirs, files in os.walk(path): + for filename in files: + self.outputs.append(os.path.join(base, filename)) + else: + self.outputs.append(path) + + def not_editable(self, spec): + if self.editable: + raise DistutilsArgError( + "Invalid argument %r: you can't use filenames or URLs " + "with --editable (except via the --find-links option)." + % (spec,) + ) + + def check_editable(self, spec): + if not self.editable: + return + + if os.path.exists(os.path.join(self.build_directory, spec.key)): + raise DistutilsArgError( + "%r already exists in %s; can't do a checkout there" % + (spec.key, self.build_directory) + ) + + @contextlib.contextmanager + def _tmpdir(self): + tmpdir = tempfile.mkdtemp(prefix=u"easy_install-") + try: + # cast to str as workaround for #709 and #710 and #712 + yield str(tmpdir) + finally: + 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): + # It's a url, download it to tmpdir and process + self.not_editable(spec) + dl = self.package_index.download(spec, tmpdir) + return self.install_item(None, dl, tmpdir, deps, True) + + elif os.path.exists(spec): + # Existing file or directory, just process it directly + self.not_editable(spec) + return self.install_item(None, spec, tmpdir, deps, True) + else: + spec = parse_requirement_arg(spec) + + self.check_editable(spec) + dist = self.package_index.fetch_distribution( + spec, tmpdir, self.upgrade, self.editable, + not self.always_copy, self.local_index + ) + if dist is None: + msg = "Could not find suitable distribution for %r" % spec + if self.always_copy: + msg += " (--always-copy skips system and development eggs)" + raise DistutilsError(msg) + elif dist.precedence == DEVELOP_DIST: + # .egg-info dists don't need installing, just process deps + self.process_distribution(spec, dist, deps, "Using") + return dist + else: + return self.install_item(spec, dist.location, tmpdir, deps) + + def install_item(self, spec, download, tmpdir, deps, install_needed=False): + + # Installation is also needed if file in tmpdir or is not an egg + install_needed = install_needed or self.always_copy + install_needed = install_needed or os.path.dirname(download) == tmpdir + install_needed = install_needed or not download.endswith('.egg') + install_needed = install_needed or ( + self.always_copy_from is not None and + os.path.dirname(normalize_path(download)) == + normalize_path(self.always_copy_from) + ) + + if spec and not install_needed: + # at this point, we know it's a local .egg, we just don't know if + # it's already installed. + for dist in self.local_index[spec.project_name]: + if dist.location == download: + break + else: + install_needed = True # it's not in the local index + + log.info("Processing %s", os.path.basename(download)) + + if install_needed: + dists = self.install_eggs(spec, download, tmpdir) + for dist in dists: + self.process_distribution(spec, dist, deps) + else: + dists = [self.egg_distribution(download)] + self.process_distribution(spec, dists[0], deps, "Using") + + if spec is not None: + for dist in dists: + if dist in spec: + return dist + + def select_scheme(self, name): + """Sets the install directories by applying the install schemes.""" + # it's the caller's problem if they supply a bad name! + scheme = INSTALL_SCHEMES[name] + for key in SCHEME_KEYS: + attrname = 'install_' + key + if getattr(self, attrname) is None: + setattr(self, attrname, scheme[key]) + + def process_distribution(self, requirement, dist, deps=True, *info): + self.update_pth(dist) + self.package_index.add(dist) + if dist in self.local_index[dist.key]: + self.local_index.remove(dist) + self.local_index.add(dist) + self.install_egg_scripts(dist) + self.installed_projects[dist.key] = dist + log.info(self.installation_report(requirement, dist, *info)) + if (dist.has_metadata('dependency_links.txt') and + not self.no_find_links): + self.package_index.add_find_links( + dist.get_metadata_lines('dependency_links.txt') + ) + if not deps and not self.always_copy: + return + elif requirement is not None and dist.key != requirement.key: + log.warn("Skipping dependencies for %s", dist) + return # XXX this is not the distribution we were looking for + elif requirement is None or dist not in requirement: + # if we wound up with a different version, resolve what we've got + distreq = dist.as_requirement() + requirement = Requirement(str(distreq)) + log.info("Processing dependencies for %s", requirement) + try: + distros = WorkingSet([]).resolve( + [requirement], self.local_index, self.easy_install + ) + except DistributionNotFound as e: + raise DistutilsError(str(e)) + except VersionConflict as e: + raise DistutilsError(e.report()) + if self.always_copy or self.always_copy_from: + # Force all the relevant distros to be copied or activated + for dist in distros: + if dist.key not in self.installed_projects: + self.easy_install(dist.as_requirement()) + log.info("Finished processing dependencies for %s", requirement) + + def should_unzip(self, dist): + if self.zip_ok is not None: + return not self.zip_ok + if dist.has_metadata('not-zip-safe'): + return True + if not dist.has_metadata('zip-safe'): + return True + return False + + def maybe_move(self, spec, dist_filename, setup_base): + dst = os.path.join(self.build_directory, spec.key) + if os.path.exists(dst): + msg = ( + "%r already exists in %s; build directory %s will not be kept" + ) + log.warn(msg, spec.key, self.build_directory, setup_base) + return setup_base + if os.path.isdir(dist_filename): + setup_base = dist_filename + else: + if os.path.dirname(dist_filename) == setup_base: + os.unlink(dist_filename) # get it out of the tmp dir + contents = os.listdir(setup_base) + if len(contents) == 1: + dist_filename = os.path.join(setup_base, contents[0]) + if os.path.isdir(dist_filename): + # if the only thing there is a directory, move it instead + setup_base = dist_filename + ensure_directory(dst) + shutil.move(setup_base, dst) + return dst + + def install_wrapper_scripts(self, dist): + if self.exclude_scripts: + return + for args in ScriptWriter.best().get_args(dist): + self.write_script(*args) + + def install_script(self, dist, script_name, script_text, dev_path=None): + """Generate a legacy script wrapper and install it""" + spec = str(dist.as_requirement()) + is_script = is_python_script(script_text, script_name) + + if is_script: + body = self._load_template(dev_path) % locals() + script_text = ScriptWriter.get_header(script_text) + body + self.write_script(script_name, _to_bytes(script_text), 'b') + + @staticmethod + def _load_template(dev_path): + """ + There are a couple of template scripts in the package. This + function loads one of them and prepares it for use. + """ + # See https://github.com/pypa/setuptools/issues/134 for info + # on script file naming and downstream issues with SVR4 + name = 'script.tmpl' + if dev_path: + name = name.replace('.tmpl', ' (dev).tmpl') + + raw_bytes = resource_string('setuptools', name) + return raw_bytes.decode('utf-8') + + def write_script(self, script_name, contents, mode="t", blockers=()): + """Write an executable file to the scripts directory""" + self.delete_blockers( # clean up old .py/.pyw w/o a script + [os.path.join(self.script_dir, x) for x in blockers] + ) + log.info("Installing %s script to %s", script_name, self.script_dir) + target = os.path.join(self.script_dir, script_name) + self.add_output(target) + + if self.dry_run: + return + + mask = current_umask() + ensure_directory(target) + if os.path.exists(target): + os.unlink(target) + with open(target, "w" + mode) as f: + f.write(contents) + chmod(target, 0o777 - mask) + + def install_eggs(self, spec, dist_filename, tmpdir): + # .egg dirs or files are already built, so just return them + if dist_filename.lower().endswith('.egg'): + return [self.install_egg(dist_filename, tmpdir)] + elif dist_filename.lower().endswith('.exe'): + return [self.install_exe(dist_filename, tmpdir)] + elif dist_filename.lower().endswith('.whl'): + return [self.install_wheel(dist_filename, tmpdir)] + + # Anything else, try to extract and build + setup_base = tmpdir + if os.path.isfile(dist_filename) and not dist_filename.endswith('.py'): + unpack_archive(dist_filename, tmpdir, self.unpack_progress) + elif os.path.isdir(dist_filename): + setup_base = os.path.abspath(dist_filename) + + if (setup_base.startswith(tmpdir) # something we downloaded + and self.build_directory and spec is not None): + setup_base = self.maybe_move(spec, dist_filename, setup_base) + + # Find the setup.py file + setup_script = os.path.join(setup_base, 'setup.py') + + if not os.path.exists(setup_script): + setups = glob(os.path.join(setup_base, '*', 'setup.py')) + if not setups: + raise DistutilsError( + "Couldn't find a setup script in %s" % + os.path.abspath(dist_filename) + ) + if len(setups) > 1: + raise DistutilsError( + "Multiple setup scripts in %s" % + os.path.abspath(dist_filename) + ) + setup_script = setups[0] + + # Now run it, and return the result + if self.editable: + log.info(self.report_editable(spec, setup_script)) + return [] + else: + return self.build_and_install(setup_script, setup_base) + + def egg_distribution(self, egg_path): + if os.path.isdir(egg_path): + metadata = PathMetadata(egg_path, os.path.join(egg_path, + 'EGG-INFO')) + else: + metadata = EggMetadata(zipimport.zipimporter(egg_path)) + return Distribution.from_filename(egg_path, metadata=metadata) + + def install_egg(self, egg_path, tmpdir): + destination = os.path.join( + self.install_dir, + os.path.basename(egg_path), + ) + destination = os.path.abspath(destination) + if not self.dry_run: + ensure_directory(destination) + + dist = self.egg_distribution(egg_path) + if not samefile(egg_path, destination): + if os.path.isdir(destination) and not os.path.islink(destination): + dir_util.remove_tree(destination, dry_run=self.dry_run) + elif os.path.exists(destination): + self.execute( + os.unlink, + (destination,), + "Removing " + destination, + ) + try: + new_dist_is_zipped = False + if os.path.isdir(egg_path): + if egg_path.startswith(tmpdir): + f, m = shutil.move, "Moving" + else: + f, m = shutil.copytree, "Copying" + elif self.should_unzip(dist): + self.mkpath(destination) + f, m = self.unpack_and_compile, "Extracting" + else: + new_dist_is_zipped = True + if egg_path.startswith(tmpdir): + f, m = shutil.move, "Moving" + else: + f, m = shutil.copy2, "Copying" + self.execute( + f, + (egg_path, destination), + (m + " %s to %s") % ( + os.path.basename(egg_path), + os.path.dirname(destination) + ), + ) + update_dist_caches( + destination, + fix_zipimporter_caches=new_dist_is_zipped, + ) + except Exception: + update_dist_caches(destination, fix_zipimporter_caches=False) + raise + + self.add_output(destination) + return self.egg_distribution(destination) + + def install_exe(self, dist_filename, tmpdir): + # See if it's valid, get data + cfg = extract_wininst_cfg(dist_filename) + if cfg is None: + raise DistutilsError( + "%s is not a valid distutils Windows .exe" % dist_filename + ) + # Create a dummy distribution object until we build the real distro + dist = Distribution( + None, + project_name=cfg.get('metadata', 'name'), + version=cfg.get('metadata', 'version'), platform=get_platform(), + ) + + # Convert the .exe to an unpacked egg + egg_path = os.path.join(tmpdir, dist.egg_name() + '.egg') + dist.location = egg_path + egg_tmp = egg_path + '.tmp' + _egg_info = os.path.join(egg_tmp, 'EGG-INFO') + pkg_inf = os.path.join(_egg_info, 'PKG-INFO') + ensure_directory(pkg_inf) # make sure EGG-INFO dir exists + dist._provider = PathMetadata(egg_tmp, _egg_info) # XXX + self.exe_to_egg(dist_filename, egg_tmp) + + # Write EGG-INFO/PKG-INFO + if not os.path.exists(pkg_inf): + f = open(pkg_inf, 'w') + f.write('Metadata-Version: 1.0\n') + for k, v in cfg.items('metadata'): + if k != 'target_version': + f.write('%s: %s\n' % (k.replace('_', '-').title(), v)) + f.close() + script_dir = os.path.join(_egg_info, 'scripts') + # delete entry-point scripts to avoid duping + self.delete_blockers([ + os.path.join(script_dir, args[0]) + for args in ScriptWriter.get_args(dist) + ]) + # Build .egg file from tmpdir + bdist_egg.make_zipfile( + egg_path, egg_tmp, verbose=self.verbose, dry_run=self.dry_run, + ) + # install the .egg + return self.install_egg(egg_path, tmpdir) + + def exe_to_egg(self, dist_filename, egg_tmp): + """Extract a bdist_wininst to the directories an egg would use""" + # Check for .pth file and set up prefix translations + prefixes = get_exe_prefixes(dist_filename) + to_compile = [] + native_libs = [] + top_level = {} + + def process(src, dst): + s = src.lower() + for old, new in prefixes: + if s.startswith(old): + src = new + src[len(old):] + parts = src.split('/') + dst = os.path.join(egg_tmp, *parts) + dl = dst.lower() + if dl.endswith('.pyd') or dl.endswith('.dll'): + parts[-1] = bdist_egg.strip_module(parts[-1]) + top_level[os.path.splitext(parts[0])[0]] = 1 + native_libs.append(src) + elif dl.endswith('.py') and old != 'SCRIPTS/': + top_level[os.path.splitext(parts[0])[0]] = 1 + to_compile.append(dst) + return dst + if not src.endswith('.pth'): + log.warn("WARNING: can't process %s", src) + return None + + # extract, tracking .pyd/.dll->native_libs and .py -> to_compile + unpack_archive(dist_filename, egg_tmp, process) + stubs = [] + for res in native_libs: + if res.lower().endswith('.pyd'): # create stubs for .pyd's + parts = res.split('/') + resource = parts[-1] + parts[-1] = bdist_egg.strip_module(parts[-1]) + '.py' + pyfile = os.path.join(egg_tmp, *parts) + to_compile.append(pyfile) + stubs.append(pyfile) + bdist_egg.write_stub(resource, pyfile) + self.byte_compile(to_compile) # compile .py's + bdist_egg.write_safety_flag( + os.path.join(egg_tmp, 'EGG-INFO'), + bdist_egg.analyze_egg(egg_tmp, stubs)) # write zip-safety flag + + for name in 'top_level', 'native_libs': + if locals()[name]: + txt = os.path.join(egg_tmp, 'EGG-INFO', name + '.txt') + if not os.path.exists(txt): + f = open(txt, 'w') + f.write('\n'.join(locals()[name]) + '\n') + f.close() + + def install_wheel(self, wheel_path, tmpdir): + wheel = Wheel(wheel_path) + assert wheel.is_compatible() + destination = os.path.join(self.install_dir, wheel.egg_name()) + destination = os.path.abspath(destination) + if not self.dry_run: + ensure_directory(destination) + if os.path.isdir(destination) and not os.path.islink(destination): + dir_util.remove_tree(destination, dry_run=self.dry_run) + elif os.path.exists(destination): + self.execute( + os.unlink, + (destination,), + "Removing " + destination, + ) + try: + self.execute( + wheel.install_as_egg, + (destination,), + ("Installing %s to %s") % ( + os.path.basename(wheel_path), + os.path.dirname(destination) + ), + ) + finally: + update_dist_caches(destination, fix_zipimporter_caches=False) + self.add_output(destination) + return self.egg_distribution(destination) + + __mv_warning = textwrap.dedent(""" + Because this distribution was installed --multi-version, before you can + import modules from this package in an application, you will need to + 'import pkg_resources' and then use a 'require()' call similar to one of + these examples, in order to select the desired version: + + 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() + + __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.) + """) + + def installation_report(self, req, dist, what="Installed"): + """Helpful installation message for display to package users""" + msg = "\n%(what)s %(eggloc)s%(extras)s" + if self.multi_version and not self.no_report: + msg += '\n' + self.__mv_warning + if self.install_dir not in map(normalize_path, sys.path): + msg += '\n' + self.__id_warning + + eggloc = dist.location + name = dist.project_name + version = dist.version + extras = '' # TODO: self.report_extras(req, dist) + return msg % locals() + + __editable_msg = textwrap.dedent(""" + Extracted editable version of %(spec)s to %(dirname)s + + If it uses setuptools in its setup script, you can activate it in + "development" mode by going to that directory and running:: + + %(python)s setup.py develop + + See the setuptools documentation for the "develop" command for more info. + """).lstrip() + + def report_editable(self, spec, setup_script): + dirname = os.path.dirname(setup_script) + python = sys.executable + return '\n' + self.__editable_msg % locals() + + def run_setup(self, setup_script, setup_base, args): + sys.modules.setdefault('distutils.command.bdist_egg', bdist_egg) + sys.modules.setdefault('distutils.command.egg_info', egg_info) + + args = list(args) + if self.verbose > 2: + v = 'v' * (self.verbose - 1) + args.insert(0, '-' + v) + elif self.verbose < 2: + args.insert(0, '-q') + if self.dry_run: + args.insert(0, '-n') + log.info( + "Running %s %s", setup_script[len(setup_base) + 1:], ' '.join(args) + ) + try: + run_setup(setup_script, args) + except SystemExit as v: + raise DistutilsError("Setup script exited with %s" % (v.args[0],)) + + def build_and_install(self, setup_script, setup_base): + args = ['bdist_egg', '--dist-dir'] + + dist_dir = tempfile.mkdtemp( + prefix='egg-dist-tmp-', dir=os.path.dirname(setup_script) + ) + try: + self._set_fetcher_options(os.path.dirname(setup_script)) + args.append(dist_dir) + + self.run_setup(setup_script, setup_base, args) + all_eggs = Environment([dist_dir]) + eggs = [] + for key in all_eggs: + for dist in all_eggs[key]: + eggs.append(self.install_egg(dist.location, setup_base)) + if not eggs and not self.dry_run: + log.warn("No eggs found in %s (setup script problem?)", + dist_dir) + return eggs + finally: + rmtree(dist_dir) + log.set_verbosity(self.verbose) # restore our log verbosity + + def _set_fetcher_options(self, base): + """ + When easy_install is about to run bdist_egg on a source dist, that + source dist might have 'setup_requires' directives, requiring + additional fetching. Ensure the fetcher options given to easy_install + are available to that command as well. + """ + # find the fetch options from easy_install and write them out + # 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', + ) + fetch_options = {} + for key, val in ei_opts.items(): + if key not in fetch_directives: + continue + fetch_options[key.replace('_', '-')] = val[1] + # create a settings dictionary suitable for `edit_config` + settings = dict(easy_install=fetch_options) + cfg_filename = os.path.join(base, 'setup.cfg') + setopt.edit_config(cfg_filename, settings) + + def update_pth(self, dist): + if self.pth_file is None: + return + + for d in self.pth_file[dist.key]: # drop old entries + if self.multi_version or d.location != dist.location: + log.info("Removing %s from easy-install.pth file", d) + self.pth_file.remove(d) + if d.location in self.shadow_path: + self.shadow_path.remove(d.location) + + if not self.multi_version: + if dist.location in self.pth_file.paths: + log.info( + "%s is already the active version in easy-install.pth", + dist, + ) + else: + log.info("Adding %s to easy-install.pth file", dist) + self.pth_file.add(dist) # add new entry + if dist.location not in self.shadow_path: + self.shadow_path.append(dist.location) + + if not self.dry_run: + + self.pth_file.save() + + if dist.key == 'setuptools': + # Ensure that setuptools itself never becomes unavailable! + # XXX should this check for latest version? + filename = os.path.join(self.install_dir, 'setuptools.pth') + if os.path.islink(filename): + os.unlink(filename) + f = open(filename, 'wt') + f.write(self.pth_file.make_relative(dist.location) + '\n') + f.close() + + def unpack_progress(self, src, dst): + # Progress filter for unpacking + log.debug("Unpacking %s to %s", src, dst) + return dst # only unpack-and-compile skips files for dry run + + def unpack_and_compile(self, egg_path, destination): + to_compile = [] + to_chmod = [] + + def pf(src, dst): + if dst.endswith('.py') and not src.startswith('EGG-INFO/'): + to_compile.append(dst) + elif dst.endswith('.dll') or dst.endswith('.so'): + to_chmod.append(dst) + self.unpack_progress(src, dst) + return not self.dry_run and dst or None + + unpack_archive(egg_path, destination, pf) + self.byte_compile(to_compile) + if not self.dry_run: + for f in to_chmod: + mode = ((os.stat(f)[stat.ST_MODE]) | 0o555) & 0o7755 + chmod(f, mode) + + def byte_compile(self, to_compile): + if sys.dont_write_bytecode: + return + + from distutils.util import byte_compile + + try: + # try to make the byte compile messages quieter + log.set_verbosity(self.verbose - 1) + + byte_compile(to_compile, optimize=0, force=1, dry_run=self.dry_run) + if self.optimize: + byte_compile( + to_compile, optimize=self.optimize, force=1, + dry_run=self.dry_run, + ) + finally: + log.set_verbosity(self.verbose) # restore original verbosity + + __no_default_msg = textwrap.dedent(""" + bad install directory or PYTHONPATH + + You are attempting to install a package to a directory that is not + on PYTHONPATH and which Python does not read ".pth" files from. The + installation directory you specified (via --install-dir, --prefix, or + the distutils default setting) was: + + %s + + and your PYTHONPATH environment variable currently contains: + + %r + + Here are some of your options for correcting the problem: + + * You can choose a different installation directory, i.e., one that is + on PYTHONPATH or supports .pth files + + * You can add the installation directory to the PYTHONPATH environment + variable. (It must then also be on PYTHONPATH whenever you run + Python and want to use the package(s) you are installing.) + + * You can set up the installation directory to support ".pth" files by + using one of the approaches described here: + + 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 + + def create_home_path(self): + """Create directories under ~.""" + if not self.user: + return + home = convert_path(os.path.expanduser("~")) + for name, path in six.iteritems(self.config_vars): + if path.startswith(home) and not os.path.isdir(path): + self.debug_print("os.makedirs('%s', 0o700)" % path) + os.makedirs(path, 0o700) + + INSTALL_SCHEMES = dict( + posix=dict( + install_dir='$base/lib/python$py_version_short/site-packages', + script_dir='$base/bin', + ), + ) + + DEFAULT_SCHEME = dict( + install_dir='$base/Lib/site-packages', + script_dir='$base/Scripts', + ) + + def _expand(self, *attrs): + config_vars = self.get_finalized_command('install').config_vars + + if self.prefix: + # Set default install_dir/scripts from --prefix + config_vars = config_vars.copy() + config_vars['base'] = self.prefix + scheme = self.INSTALL_SCHEMES.get(os.name, self.DEFAULT_SCHEME) + for attr, val in scheme.items(): + if getattr(self, attr, None) is None: + setattr(self, attr, val) + + from distutils.util import subst_vars + + for attr in attrs: + val = getattr(self, attr) + if val is not None: + val = subst_vars(val, config_vars) + if os.name == 'posix': + val = os.path.expanduser(val) + setattr(self, attr, val) + + +def _pythonpath(): + items = os.environ.get('PYTHONPATH', '').split(os.pathsep) + return filter(None, items) + + +def get_site_dirs(): + """ + Return a list of 'site' dirs + """ + + sitedirs = [] + + # start with PYTHONPATH + sitedirs.extend(_pythonpath()) + + prefixes = [sys.prefix] + if sys.exec_prefix != sys.prefix: + prefixes.append(sys.exec_prefix) + for prefix in prefixes: + if prefix: + if sys.platform in ('os2emx', 'riscos'): + sitedirs.append(os.path.join(prefix, "Lib", "site-packages")) + elif os.sep == '/': + sitedirs.extend([ + os.path.join( + prefix, + "lib", + "python" + sys.version[:3], + "site-packages", + ), + os.path.join(prefix, "lib", "site-python"), + ]) + else: + sitedirs.extend([ + prefix, + os.path.join(prefix, "lib", "site-packages"), + ]) + if sys.platform == 'darwin': + # for framework builds *only* we add the standard Apple + # locations. Currently only per-user, but /Library and + # /Network/Library could be added too + if 'Python.framework' in prefix: + home = os.environ.get('HOME') + if home: + home_sp = os.path.join( + home, + 'Library', + 'Python', + sys.version[:3], + 'site-packages', + ) + sitedirs.append(home_sp) + lib_paths = get_path('purelib'), get_path('platlib') + for site_lib in lib_paths: + if site_lib not in sitedirs: + sitedirs.append(site_lib) + + if site.ENABLE_USER_SITE: + sitedirs.append(site.USER_SITE) + + try: + sitedirs.extend(site.getsitepackages()) + except AttributeError: + pass + + sitedirs = list(map(normalize_path, sitedirs)) + + return sitedirs + + +def expand_paths(inputs): + """Yield sys.path directories that might contain "old-style" packages""" + + seen = {} + + for dirname in inputs: + dirname = normalize_path(dirname) + if dirname in seen: + continue + + seen[dirname] = 1 + if not os.path.isdir(dirname): + continue + + files = os.listdir(dirname) + yield dirname, files + + for name in files: + if not name.endswith('.pth'): + # We only care about the .pth files + continue + if name in ('easy-install.pth', 'setuptools.pth'): + # Ignore .pth files that we control + continue + + # Read the .pth file + f = open(os.path.join(dirname, name)) + lines = list(yield_lines(f)) + f.close() + + # Yield existing non-dupe, non-import directory lines from it + for line in lines: + if not line.startswith("import"): + line = normalize_path(line.rstrip()) + if line not in seen: + seen[line] = 1 + if not os.path.isdir(line): + continue + yield line, os.listdir(line) + + +def extract_wininst_cfg(dist_filename): + """Extract configuration data from a bdist_wininst .exe + + Returns a configparser.RawConfigParser, or None + """ + f = open(dist_filename, 'rb') + try: + endrec = zipfile._EndRecData(f) + if endrec is None: + return None + + prepended = (endrec[9] - endrec[5]) - endrec[6] + if prepended < 12: # no wininst data here + return None + f.seek(prepended - 12) + + tag, cfglen, bmlen = struct.unpack("<iii", f.read(12)) + if tag not in (0x1234567A, 0x1234567B): + return None # not a valid tag + + f.seek(prepended - (12 + cfglen)) + init = {'version': '', 'target_version': ''} + cfg = configparser.RawConfigParser(init) + try: + part = f.read(cfglen) + # Read up to the first null byte. + config = part.split(b'\0', 1)[0] + # Now the config is in bytes, but for RawConfigParser, it should + # be text, so decode it. + config = config.decode(sys.getfilesystemencoding()) + cfg.readfp(six.StringIO(config)) + except configparser.Error: + return None + if not cfg.has_section('metadata') or not cfg.has_section('Setup'): + return None + return cfg + + finally: + f.close() + + +def get_exe_prefixes(exe_filename): + """Get exe->egg path translations for a given .exe file""" + + prefixes = [ + ('PURELIB/', ''), + ('PLATLIB/pywin32_system32', ''), + ('PLATLIB/', ''), + ('SCRIPTS/', 'EGG-INFO/scripts/'), + ('DATA/lib/site-packages', ''), + ] + z = zipfile.ZipFile(exe_filename) + try: + for info in z.infolist(): + name = info.filename + parts = name.split('/') + if len(parts) == 3 and parts[2] == 'PKG-INFO': + if parts[1].endswith('.egg-info'): + prefixes.insert(0, ('/'.join(parts[:2]), 'EGG-INFO/')) + break + if len(parts) != 2 or not name.endswith('.pth'): + continue + if name.endswith('-nspkg.pth'): + continue + if parts[0].upper() in ('PURELIB', 'PLATLIB'): + contents = z.read(name) + if six.PY3: + contents = contents.decode() + for pth in yield_lines(contents): + pth = pth.strip().replace('\\', '/') + if not pth.startswith('import'): + prefixes.append((('%s/%s/' % (parts[0], pth)), '')) + finally: + z.close() + prefixes = [(x.lower(), y) for x, y in prefixes] + prefixes.sort() + prefixes.reverse() + return prefixes + + +class PthDistributions(Environment): + """A .pth file with Distribution paths in it""" + + dirty = False + + def __init__(self, filename, sitedirs=()): + self.filename = filename + self.sitedirs = list(map(normalize_path, sitedirs)) + self.basedir = normalize_path(os.path.dirname(self.filename)) + self._load() + Environment.__init__(self, [], None, None) + for path in yield_lines(self.paths): + list(map(self.add, find_distributions(path, True))) + + def _load(self): + self.paths = [] + saw_import = False + seen = dict.fromkeys(self.sitedirs) + if os.path.isfile(self.filename): + f = open(self.filename, 'rt') + for line in f: + if line.startswith('import'): + saw_import = True + continue + path = line.rstrip() + self.paths.append(path) + if not path.strip() or path.strip().startswith('#'): + continue + # skip non-existent paths, in case somebody deleted a package + # manually, and duplicate paths as well + path = self.paths[-1] = normalize_path( + os.path.join(self.basedir, path) + ) + if not os.path.exists(path) or path in seen: + self.paths.pop() # skip it + self.dirty = True # we cleaned up, so we're dirty now :) + continue + seen[path] = 1 + f.close() + + if self.paths and not saw_import: + self.dirty = True # ensure anything we touch has import wrappers + while self.paths and not self.paths[-1].strip(): + self.paths.pop() + + def save(self): + """Write changed .pth file back to disk""" + if not self.dirty: + return + + rel_paths = list(map(self.make_relative, self.paths)) + if rel_paths: + log.debug("Saving %s", self.filename) + lines = self._wrap_lines(rel_paths) + data = '\n'.join(lines) + '\n' + + if os.path.islink(self.filename): + os.unlink(self.filename) + with open(self.filename, 'wt') as f: + f.write(data) + + elif os.path.exists(self.filename): + log.debug("Deleting empty %s", self.filename) + os.unlink(self.filename) + + self.dirty = False + + @staticmethod + def _wrap_lines(lines): + return lines + + def add(self, dist): + """Add `dist` to the distribution map""" + new_path = ( + dist.location not in self.paths and ( + dist.location not in self.sitedirs or + # account for '.' being in PYTHONPATH + dist.location == os.getcwd() + ) + ) + if new_path: + self.paths.append(dist.location) + self.dirty = True + Environment.add(self, dist) + + def remove(self, dist): + """Remove `dist` from the distribution map""" + while dist.location in self.paths: + self.paths.remove(dist.location) + self.dirty = True + Environment.remove(self, dist) + + def make_relative(self, path): + npath, last = os.path.split(normalize_path(path)) + baselen = len(self.basedir) + parts = [last] + sep = os.altsep == '/' and '/' or os.sep + while len(npath) >= baselen: + if npath == self.basedir: + parts.append(os.curdir) + parts.reverse() + return sep.join(parts) + npath, last = os.path.split(npath) + parts.append(last) + else: + return path + + +class RewritePthDistributions(PthDistributions): + @classmethod + def _wrap_lines(cls, lines): + yield cls.prelude + for line in lines: + yield line + yield cls.postlude + + prelude = _one_liner(""" + import sys + sys.__plen = len(sys.path) + """) + postlude = _one_liner(""" + import sys + new = sys.path[sys.__plen:] + del sys.path[sys.__plen:] + p = getattr(sys, '__egginsert', 0) + sys.path[p:p] = new + sys.__egginsert = p + len(new) + """) + + +if os.environ.get('SETUPTOOLS_SYS_PATH_TECHNIQUE', 'raw') == 'rewrite': + PthDistributions = RewritePthDistributions + + +def _first_line_re(): + """ + Return a regular expression based on first_line_re suitable for matching + strings. + """ + if isinstance(first_line_re.pattern, str): + return first_line_re + + # first_line_re in Python >=3.1.4 and >=3.2.1 is a bytes pattern. + return re.compile(first_line_re.pattern.decode()) + + +def auto_chmod(func, arg, exc): + if func in [os.unlink, os.remove] and os.name == 'nt': + chmod(arg, stat.S_IWRITE) + return func(arg) + et, ev, _ = sys.exc_info() + six.reraise(et, (ev[0], ev[1] + (" %s %s" % (func, arg)))) + + +def update_dist_caches(dist_path, fix_zipimporter_caches): + """ + Fix any globally cached `dist_path` related data + + `dist_path` should be a path of a newly installed egg distribution (zipped + or unzipped). + + sys.path_importer_cache contains finder objects that have been cached when + importing data from the original distribution. Any such finders need to be + cleared since the replacement distribution might be packaged differently, + e.g. a zipped egg distribution might get replaced with an unzipped egg + folder or vice versa. Having the old finders cached may then cause Python + to attempt loading modules from the replacement distribution using an + incorrect loader. + + zipimport.zipimporter objects are Python loaders charged with importing + data packaged inside zip archives. If stale loaders referencing the + original distribution, are left behind, they can fail to load modules from + the replacement distribution. E.g. if an old zipimport.zipimporter instance + is used to load data from a new zipped egg archive, it may cause the + operation to attempt to locate the requested data in the wrong location - + one indicated by the original distribution's zip archive directory + information. Such an operation may then fail outright, e.g. report having + read a 'bad local file header', or even worse, it may fail silently & + return invalid data. + + zipimport._zip_directory_cache contains cached zip archive directory + information for all existing zipimport.zipimporter instances and all such + instances connected to the same archive share the same cached directory + information. + + If asked, and the underlying Python implementation allows it, we can fix + all existing zipimport.zipimporter instances instead of having to track + them down and remove them one by one, by updating their shared cached zip + archive directory information. This, of course, assumes that the + replacement distribution is packaged as a zipped egg. + + If not asked to fix existing zipimport.zipimporter instances, we still do + our best to clear any remaining zipimport.zipimporter related cached data + that might somehow later get used when attempting to load data from the new + distribution and thus cause such load operations to fail. Note that when + tracking down such remaining stale data, we can not catch every conceivable + usage from here, and we clear only those that we know of and have found to + cause problems if left alive. Any remaining caches should be updated by + whomever is in charge of maintaining them, i.e. they should be ready to + handle us replacing their zip archives with new distributions at runtime. + + """ + # There are several other known sources of stale zipimport.zipimporter + # instances that we do not clear here, but might if ever given a reason to + # do so: + # * Global setuptools pkg_resources.working_set (a.k.a. 'master working + # set') may contain distributions which may in turn contain their + # zipimport.zipimporter loaders. + # * Several zipimport.zipimporter loaders held by local variables further + # up the function call stack when running the setuptools installation. + # * Already loaded modules may have their __loader__ attribute set to the + # exact loader instance used when importing them. Python 3.4 docs state + # that this information is intended mostly for introspection and so is + # not expected to cause us problems. + normalized_path = normalize_path(dist_path) + _uncache(normalized_path, sys.path_importer_cache) + if fix_zipimporter_caches: + _replace_zip_directory_cache_data(normalized_path) + else: + # Here, even though we do not want to fix existing and now stale + # zipimporter cache information, we still want to remove it. Related to + # Python's zip archive directory information cache, we clear each of + # its stale entries in two phases: + # 1. Clear the entry so attempting to access zip archive information + # via any existing stale zipimport.zipimporter instances fails. + # 2. Remove the entry from the cache so any newly constructed + # zipimport.zipimporter instances do not end up using old stale + # zip archive directory information. + # This whole stale data removal step does not seem strictly necessary, + # but has been left in because it was done before we started replacing + # the zip archive directory information cache content if possible, and + # there are no relevant unit tests that we can depend on to tell us if + # this is really needed. + _remove_and_clear_zip_directory_cache_data(normalized_path) + + +def _collect_zipimporter_cache_entries(normalized_path, cache): + """ + Return zipimporter cache entry keys related to a given normalized path. + + Alternative path spellings (e.g. those using different character case or + those using alternative path separators) related to the same path are + included. Any sub-path entries are included as well, i.e. those + corresponding to zip archives embedded in other zip archives. + + """ + result = [] + prefix_len = len(normalized_path) + for p in cache: + np = normalize_path(p) + if (np.startswith(normalized_path) and + np[prefix_len:prefix_len + 1] in (os.sep, '')): + result.append(p) + return result + + +def _update_zipimporter_cache(normalized_path, cache, updater=None): + """ + Update zipimporter cache data for a given normalized path. + + Any sub-path entries are processed as well, i.e. those corresponding to zip + archives embedded in other zip archives. + + Given updater is a callable taking a cache entry key and the original entry + (after already removing the entry from the cache), and expected to update + the entry and possibly return a new one to be inserted in its place. + Returning None indicates that the entry should not be replaced with a new + one. If no updater is given, the cache entries are simply removed without + any additional processing, the same as if the updater simply returned None. + + """ + for p in _collect_zipimporter_cache_entries(normalized_path, cache): + # N.B. pypy's custom zipimport._zip_directory_cache implementation does + # not support the complete dict interface: + # * Does not support item assignment, thus not allowing this function + # to be used only for removing existing cache entries. + # * Does not support the dict.pop() method, forcing us to use the + # get/del patterns instead. For more detailed information see the + # following links: + # https://github.com/pypa/setuptools/issues/202#issuecomment-202913420 + # http://bit.ly/2h9itJX + old_entry = cache[p] + del cache[p] + new_entry = updater and updater(p, old_entry) + if new_entry is not None: + cache[p] = new_entry + + +def _uncache(normalized_path, cache): + _update_zipimporter_cache(normalized_path, cache) + + +def _remove_and_clear_zip_directory_cache_data(normalized_path): + def clear_and_remove_cached_zip_archive_directory_data(path, old_entry): + old_entry.clear() + + _update_zipimporter_cache( + normalized_path, zipimport._zip_directory_cache, + updater=clear_and_remove_cached_zip_archive_directory_data) + + +# PyPy Python implementation does not allow directly writing to the +# zipimport._zip_directory_cache and so prevents us from attempting to correct +# its content. The best we can do there is clear the problematic cache content +# and have PyPy repopulate it as needed. The downside is that if there are any +# stale zipimport.zipimporter instances laying around, attempting to use them +# will fail due to not having its zip archive directory information available +# instead of being automatically corrected to use the new correct zip archive +# directory information. +if '__pypy__' in sys.builtin_module_names: + _replace_zip_directory_cache_data = \ + _remove_and_clear_zip_directory_cache_data +else: + + def _replace_zip_directory_cache_data(normalized_path): + def replace_cached_zip_archive_directory_data(path, old_entry): + # N.B. In theory, we could load the zip directory information just + # once for all updated path spellings, and then copy it locally and + # update its contained path strings to contain the correct + # spelling, but that seems like a way too invasive move (this cache + # structure is not officially documented anywhere and could in + # theory change with new Python releases) for no significant + # benefit. + old_entry.clear() + zipimport.zipimporter(path) + old_entry.update(zipimport._zip_directory_cache[path]) + return old_entry + + _update_zipimporter_cache( + normalized_path, zipimport._zip_directory_cache, + updater=replace_cached_zip_archive_directory_data) + + +def is_python(text, filename='<string>'): + "Is this string a valid Python script?" + try: + compile(text, filename, 'exec') + except (SyntaxError, TypeError): + return False + else: + return True + + +def is_sh(executable): + """Determine if the specified executable is a .sh (contains a #! line)""" + try: + with io.open(executable, encoding='latin-1') as fp: + magic = fp.read(2) + except (OSError, IOError): + return executable + return magic == '#!' + + +def nt_quote_arg(arg): + """Quote a command line argument according to Windows parsing rules""" + return subprocess.list2cmdline([arg]) + + +def is_python_script(script_text, filename): + """Is this text, as a whole, a Python script? (as opposed to shell/bat/etc. + """ + if filename.endswith('.py') or filename.endswith('.pyw'): + return True # extension says it's Python + if is_python(script_text, filename): + return True # it's syntactically valid Python + if script_text.startswith('#!'): + # It begins with a '#!' line, so check if 'python' is in it somewhere + return 'python' in script_text.splitlines()[0].lower() + + return False # Not any Python I can recognize + + +try: + from os import chmod as _chmod +except ImportError: + # Jython compatibility + def _chmod(*args): + pass + + +def chmod(path, mode): + log.debug("changing mode of %s to %o", path, mode) + try: + _chmod(path, mode) + except os.error as e: + log.debug("chmod failed: %s", e) + + +class CommandSpec(list): + """ + A command spec for a #! header, specified as a list of arguments akin to + those passed to Popen. + """ + + options = [] + split_args = dict() + + @classmethod + def best(cls): + """ + Choose the best CommandSpec class based on environmental conditions. + """ + return cls + + @classmethod + def _sys_executable(cls): + _default = os.path.normpath(sys.executable) + return os.environ.get('__PYVENV_LAUNCHER__', _default) + + @classmethod + def from_param(cls, param): + """ + Construct a CommandSpec from a parameter to build_scripts, which may + be None. + """ + if isinstance(param, cls): + return param + if isinstance(param, list): + return cls(param) + if param is None: + return cls.from_environment() + # otherwise, assume it's a string. + return cls.from_string(param) + + @classmethod + def from_environment(cls): + return cls([cls._sys_executable()]) + + @classmethod + def from_string(cls, string): + """ + Construct a command spec from a simple string representing a command + line parseable by shlex.split. + """ + items = shlex.split(string, **cls.split_args) + return cls(items) + + def install_options(self, script_text): + self.options = shlex.split(self._extract_options(script_text)) + cmdline = subprocess.list2cmdline(self) + if not isascii(cmdline): + self.options[:0] = ['-x'] + + @staticmethod + def _extract_options(orig_script): + """ + Extract any options from the first line of the script. + """ + first = (orig_script + '\n').splitlines()[0] + match = _first_line_re().match(first) + options = match.group(1) or '' if match else '' + return options.strip() + + def as_header(self): + return self._render(self + list(self.options)) + + @staticmethod + def _strip_quotes(item): + _QUOTES = '"\'' + for q in _QUOTES: + if item.startswith(q) and item.endswith(q): + return item[1:-1] + return item + + @staticmethod + def _render(items): + cmdline = subprocess.list2cmdline( + CommandSpec._strip_quotes(item.strip()) for item in items) + return '#!' + cmdline + '\n' + + +# For pbr compat; will be removed in a future version. +sys_executable = CommandSpec._sys_executable() + + +class WindowsCommandSpec(CommandSpec): + split_args = dict(posix=False) + + +class ScriptWriter: + """ + Encapsulates behavior around writing entry point scripts for console and + gui apps. + """ + + 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 + + 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() + + command_spec_class = CommandSpec + + @classmethod + def get_script_args(cls, dist, executable=None, wininst=False): + # for backward compatibility + warnings.warn("Use get_args", EasyInstallDeprecationWarning) + writer = (WindowsScriptWriter if wininst else ScriptWriter).best() + header = cls.get_script_header("", executable, wininst) + return writer.get_args(dist, header) + + @classmethod + def get_script_header(cls, script_text, executable=None, wininst=False): + # for backward compatibility + warnings.warn("Use get_header", EasyInstallDeprecationWarning, stacklevel=2) + if wininst: + executable = "python.exe" + return cls.get_header(script_text, executable) + + @classmethod + def get_args(cls, dist, header=None): + """ + Yield write_script() argument tuples for a distribution's + console_scripts and gui_scripts entry points. + """ + if header is None: + header = cls.get_header() + spec = str(dist.as_requirement()) + for type_ in 'console', 'gui': + group = type_ + '_scripts' + for name, ep in dist.get_entry_map(group).items(): + cls._ensure_safe_name(name) + script_text = cls.template % locals() + args = cls._get_script_args(type_, name, header, script_text) + for res in args: + yield res + + @staticmethod + def _ensure_safe_name(name): + """ + Prevent paths in *_scripts entry point names. + """ + has_path_sep = re.search(r'[\\/]', name) + if has_path_sep: + raise ValueError("Path separators not allowed in script names") + + @classmethod + def get_writer(cls, force_windows): + # for backward compatibility + warnings.warn("Use best", EasyInstallDeprecationWarning) + return WindowsScriptWriter.best() if force_windows else cls.best() + + @classmethod + def best(cls): + """ + Select the best ScriptWriter for this environment. + """ + if sys.platform == 'win32' or (os.name == 'java' and os._name == 'nt'): + return WindowsScriptWriter.best() + else: + return cls + + @classmethod + def _get_script_args(cls, type_, name, header, script_text): + # Simply write the stub with no extension. + yield (name, header + script_text) + + @classmethod + def get_header(cls, script_text="", executable=None): + """Create a #! line, getting options (if any) from script_text""" + cmd = cls.command_spec_class.best().from_param(executable) + cmd.install_options(script_text) + return cmd.as_header() + + +class WindowsScriptWriter(ScriptWriter): + command_spec_class = WindowsCommandSpec + + @classmethod + def get_writer(cls): + # for backward compatibility + warnings.warn("Use best", EasyInstallDeprecationWarning) + return cls.best() + + @classmethod + def best(cls): + """ + Select the best ScriptWriter suitable for Windows + """ + writer_lookup = dict( + executable=WindowsExecutableLauncherWriter, + natural=cls, + ) + # for compatibility, use the executable launcher by default + launcher = os.environ.get('SETUPTOOLS_LAUNCHER', 'executable') + return writer_lookup[launcher] + + @classmethod + def _get_script_args(cls, type_, name, header, script_text): + "For Windows, add a .py extension" + ext = dict(console='.pya', gui='.pyw')[type_] + if ext not in os.environ['PATHEXT'].lower().split(';'): + msg = ( + "{ext} not listed in PATHEXT; scripts will not be " + "recognized as executables." + ).format(**locals()) + warnings.warn(msg, UserWarning) + old = ['.pya', '.py', '-script.py', '.pyc', '.pyo', '.pyw', '.exe'] + old.remove(ext) + header = cls._adjust_header(type_, header) + blockers = [name + x for x in old] + yield name + ext, header + script_text, 't', blockers + + @classmethod + def _adjust_header(cls, type_, orig_header): + """ + Make sure 'pythonw' is used for gui and and 'python' is used for + console (regardless of what sys.executable is). + """ + pattern = 'pythonw.exe' + repl = 'python.exe' + if type_ == 'gui': + pattern, repl = repl, pattern + pattern_ob = re.compile(re.escape(pattern), re.IGNORECASE) + new_header = pattern_ob.sub(string=orig_header, repl=repl) + return new_header if cls._use_header(new_header) else orig_header + + @staticmethod + def _use_header(new_header): + """ + Should _adjust_header use the replaced header? + + On non-windows systems, always use. On + Windows systems, only use the replaced header if it resolves + to an executable on the system. + """ + clean_header = new_header[2:-1].strip('"') + return sys.platform != 'win32' or find_executable(clean_header) + + +class WindowsExecutableLauncherWriter(WindowsScriptWriter): + @classmethod + def _get_script_args(cls, type_, name, header, script_text): + """ + For Windows, add a .py extension and an .exe launcher + """ + if type_ == 'gui': + launcher_type = 'gui' + ext = '-script.pyw' + old = ['.pyw'] + else: + launcher_type = 'cli' + ext = '-script.py' + old = ['.py', '.pyc', '.pyo'] + hdr = cls._adjust_header(type_, header) + blockers = [name + x for x in old] + yield (name + ext, hdr + script_text, 't', blockers) + yield ( + name + '.exe', get_win_launcher(launcher_type), + 'b' # write in binary mode + ) + if not is_64bit(): + # install a manifest for the launcher to prevent Windows + # from detecting it as an installer (which it will for + # launchers like easy_install.exe). Consider only + # adding a manifest for launchers detected as installers. + # See Distribute #143 for details. + m_name = name + '.exe.manifest' + yield (m_name, load_launcher_manifest(name), 't') + + +# for backward-compatibility +get_script_args = ScriptWriter.get_script_args +get_script_header = ScriptWriter.get_script_header + + +def get_win_launcher(type): + """ + Load the Windows launcher (executable) suitable for launching a script. + + `type` should be either 'cli' or 'gui' + + Returns the executable as a byte string. + """ + launcher_fn = '%s.exe' % type + if is_64bit(): + launcher_fn = launcher_fn.replace(".", "-64.") + else: + launcher_fn = launcher_fn.replace(".", "-32.") + return resource_string('setuptools', launcher_fn) + + +def load_launcher_manifest(name): + manifest = pkg_resources.resource_string(__name__, 'launcher manifest.xml') + if six.PY2: + return manifest % vars() + else: + return manifest.decode('utf-8') % vars() + + +def rmtree(path, ignore_errors=False, onerror=auto_chmod): + return shutil.rmtree(path, ignore_errors, onerror) + + +def current_umask(): + tmp = os.umask(0o022) + os.umask(tmp) + return tmp + + +def bootstrap(): + # This function is called when setuptools*.egg is run using /bin/sh + import setuptools + + argv0 = os.path.dirname(setuptools.__path__[0]) + sys.argv[0] = argv0 + sys.argv.append(argv0) + main() + + +def main(argv=None, **kw): + from setuptools import setup + from setuptools.dist import Distribution + + class DistributionWithoutHelpCommands(Distribution): + common_usage = "" + + def _show_help(self, *args, **kw): + with _patch_usage(): + Distribution._show_help(self, *args, **kw) + + if argv is None: + argv = sys.argv[1:] + + with _patch_usage(): + setup( + script_args=['-q', 'easy_install', '-v'] + argv, + script_name=sys.argv[0] or 'easy_install', + distclass=DistributionWithoutHelpCommands, + **kw + ) + + +@contextlib.contextmanager +def _patch_usage(): + import distutils.core + USAGE = textwrap.dedent(""" + usage: %(script)s [options] requirement_or_url ... + or: %(script)s --help + """).lstrip() + + def gen_usage(script_name): + return USAGE % dict( + script=os.path.basename(script_name), + ) + + saved = distutils.core.gen_usage + distutils.core.gen_usage = gen_usage + try: + yield + finally: + distutils.core.gen_usage = saved + +class EasyInstallDeprecationWarning(SetuptoolsDeprecationWarning): + """Class for warning about deprecations in EasyInstall in SetupTools. Not ignored by default, unlike DeprecationWarning.""" + diff --git a/venv/lib/python3.7/site-packages/setuptools/command/egg_info.py b/venv/lib/python3.7/site-packages/setuptools/command/egg_info.py new file mode 100644 index 0000000..d9fe3da --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/command/egg_info.py @@ -0,0 +1,716 @@ +"""setuptools.command.egg_info + +Create a distribution's .egg-info directory and contents""" + +from distutils.filelist import FileList as _FileList +from distutils.errors import DistutilsInternalError +from distutils.util import convert_path +from distutils import log +import distutils.errors +import distutils.filelist +import os +import re +import sys +import io +import warnings +import time +import collections + +from setuptools.extern import six +from setuptools.extern.six.moves import map + +from setuptools import Command +from setuptools.command.sdist import sdist +from setuptools.command.sdist import walk_revctrl +from setuptools.command.setopt import edit_config +from setuptools.command import bdist_egg +from pkg_resources import ( + parse_requirements, safe_name, parse_version, + safe_version, yield_lines, EntryPoint, iter_entry_points, to_filename) +import setuptools.unicode_utils as unicode_utils +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. + This differs from fnmatch.translate which allows wildcards to match + directory separators. It also knows about '**/' which matches any number of + directories. + """ + pat = '' + + # This will split on '/' within [character classes]. This is deliberate. + chunks = glob.split(os.path.sep) + + sep = re.escape(os.sep) + valid_char = '[^%s]' % (sep,) + + for c, chunk in enumerate(chunks): + last_chunk = c == len(chunks) - 1 + + # Chunks that are a literal ** are globstars. They match anything. + if chunk == '**': + if last_chunk: + # Match anything if this is the last component + pat += '.*' + else: + # Match '(name/)*' + pat += '(?:%s+%s)*' % (valid_char, sep) + continue # Break here as the whole path component has been handled + + # Find any special characters in the remainder + i = 0 + chunk_len = len(chunk) + while i < chunk_len: + char = chunk[i] + if char == '*': + # Match any number of name characters + pat += valid_char + '*' + elif char == '?': + # Match a name character + pat += valid_char + elif char == '[': + # Character class + inner_i = i + 1 + # Skip initial !/] chars + if inner_i < chunk_len and chunk[inner_i] == '!': + inner_i = inner_i + 1 + if inner_i < chunk_len and chunk[inner_i] == ']': + inner_i = inner_i + 1 + + # Loop till the closing ] is found + while inner_i < chunk_len and chunk[inner_i] != ']': + inner_i = inner_i + 1 + + if inner_i >= chunk_len: + # Got to the end of the string without finding a closing ] + # Do not treat this as a matching group, but as a literal [ + pat += re.escape(char) + else: + # Grab the insides of the [brackets] + inner = chunk[i + 1:inner_i] + char_class = '' + + # Class negation + if inner[0] == '!': + char_class = '^' + inner = inner[1:] + + char_class += re.escape(inner) + pat += '[%s]' % (char_class,) + + # Skip to the end ] + i = inner_i + else: + pat += re.escape(char) + i += 1 + + # Join each chunk with the dir separator + if not last_chunk: + pat += sep + + pat += r'\Z' + return re.compile(pat, flags=re.MULTILINE|re.DOTALL) + + +class InfoCommon: + tag_build = None + tag_date = None + + @property + def name(self): + return safe_name(self.distribution.get_name()) + + def tagged_version(self): + version = self.distribution.get_version() + # egg_info may be called more than once for a distribution, + # in which case the version string already contains all tags. + if self.vtags and version.endswith(self.vtags): + return safe_version(version) + return safe_version(version + self.vtags) + + def tags(self): + version = '' + if self.tag_build: + version += self.tag_build + if self.tag_date: + version += time.strftime("-%Y%m%d") + return version + vtags = property(tags) + + +class egg_info(InfoCommon, Command): + description = "create a distribution's .egg-info directory" + + user_options = [ + ('egg-base=', 'e', "directory containing .egg-info directories" + " (default: top of the source tree)"), + ('tag-date', 'd', "Add date stamp (e.g. 20050528) to version number"), + ('tag-build=', 'b', "Specify explicit tag to add to version number"), + ('no-date', 'D', "Don't include date stamp [default]"), + ] + + boolean_options = ['tag-date'] + negative_opt = { + 'no-date': 'tag-date', + } + + def initialize_options(self): + self.egg_base = None + self.egg_name = None + self.egg_info = None + self.egg_version = None + self.broken_egg_info = False + + #################################### + # allow the 'tag_svn_revision' to be detected and + # set, supporting sdists built on older Setuptools. + @property + def tag_svn_revision(self): + pass + + @tag_svn_revision.setter + def tag_svn_revision(self, value): + pass + #################################### + + def save_version_info(self, filename): + """ + Materialize the value of date into the + build tag. Install build keys in a deterministic order + to avoid arbitrary reordering on subsequent builds. + """ + egg_info = collections.OrderedDict() + # follow the order these keys would have been added + # when PYTHONHASHSEED=0 + egg_info['tag_build'] = self.tags() + egg_info['tag_date'] = 0 + edit_config(filename, dict(egg_info=egg_info)) + + def finalize_options(self): + # Note: we need to capture the current value returned + # by `self.tagged_version()`, so we can later update + # `self.distribution.metadata.version` without + # repercussions. + self.egg_name = self.name + self.egg_version = self.tagged_version() + parsed_version = parse_version(self.egg_version) + + try: + is_version = isinstance(parsed_version, packaging.version.Version) + spec = ( + "%s==%s" if is_version else "%s===%s" + ) + list( + parse_requirements(spec % (self.egg_name, self.egg_version)) + ) + except ValueError: + raise distutils.errors.DistutilsOptionError( + "Invalid distribution name or version syntax: %s-%s" % + (self.egg_name, self.egg_version) + ) + + if self.egg_base is None: + dirs = self.distribution.package_dir + self.egg_base = (dirs or {}).get('', os.curdir) + + self.ensure_dirname('egg_base') + self.egg_info = to_filename(self.egg_name) + '.egg-info' + if self.egg_base != os.curdir: + self.egg_info = os.path.join(self.egg_base, self.egg_info) + if '-' in self.egg_name: + self.check_broken_egg_info() + + # Set package version for the benefit of dumber commands + # (e.g. sdist, bdist_wininst, etc.) + # + self.distribution.metadata.version = self.egg_version + + # If we bootstrapped around the lack of a PKG-INFO, as might be the + # case in a fresh checkout, make sure that any special tags get added + # to the version info + # + pd = self.distribution._patched_dist + if pd is not None and pd.key == self.egg_name.lower(): + pd._version = self.egg_version + pd._parsed_version = parse_version(self.egg_version) + self.distribution._patched_dist = None + + def write_or_delete_file(self, what, filename, data, force=False): + """Write `data` to `filename` or delete if empty + + If `data` is non-empty, this routine is the same as ``write_file()``. + If `data` is empty but not ``None``, this is the same as calling + ``delete_file(filename)`. If `data` is ``None``, then this is a no-op + unless `filename` exists, in which case a warning is issued about the + orphaned file (if `force` is false), or deleted (if `force` is true). + """ + if data: + self.write_file(what, filename, data) + elif os.path.exists(filename): + if data is None and not force: + log.warn( + "%s not set in setup(), but %s exists", what, filename + ) + return + else: + self.delete_file(filename) + + def write_file(self, what, filename, data): + """Write `data` to `filename` (if not a dry run) after announcing it + + `what` is used in a log message to identify what is being written + to the file. + """ + log.info("writing %s to %s", what, filename) + if six.PY3: + data = data.encode("utf-8") + if not self.dry_run: + f = open(filename, 'wb') + f.write(data) + f.close() + + def delete_file(self, filename): + """Delete `filename` (if not a dry run) after announcing it""" + log.info("deleting %s", filename) + if not self.dry_run: + os.unlink(filename) + + def run(self): + self.mkpath(self.egg_info) + os.utime(self.egg_info, None) + installer = self.distribution.fetch_build_egg + for ep in iter_entry_points('egg_info.writers'): + ep.require(installer=installer) + writer = ep.resolve() + writer(self, ep.name, os.path.join(self.egg_info, ep.name)) + + # Get rid of native_libs.txt if it was put there by older bdist_egg + nl = os.path.join(self.egg_info, "native_libs.txt") + if os.path.exists(nl): + self.delete_file(nl) + + self.find_sources() + + def find_sources(self): + """Generate SOURCES.txt manifest file""" + manifest_filename = os.path.join(self.egg_info, "SOURCES.txt") + mm = manifest_maker(self.distribution) + mm.manifest = manifest_filename + mm.run() + self.filelist = mm.filelist + + def check_broken_egg_info(self): + bei = self.egg_name + '.egg-info' + if self.egg_base != os.curdir: + bei = os.path.join(self.egg_base, bei) + if os.path.exists(bei): + log.warn( + "-" * 78 + '\n' + "Note: Your current .egg-info directory has a '-' in its name;" + '\nthis will not work correctly with "setup.py develop".\n\n' + 'Please rename %s to %s to correct this problem.\n' + '-' * 78, + bei, self.egg_info + ) + self.broken_egg_info = self.egg_info + self.egg_info = bei # make it work for now + + +class FileList(_FileList): + # Implementations of the various MANIFEST.in commands + + def process_template_line(self, line): + # Parse the line: split it up, make sure the right number of words + # is there, and return the relevant words. 'action' is always + # defined: it's the first word of the line. Which of the other + # three are defined depends on the action; it'll be either + # patterns, (dir and patterns), or (dir_pattern). + (action, patterns, dir, dir_pattern) = self._parse_template_line(line) + + # OK, now we know that the action is valid and we have the + # right number of words on the line for that action -- so we + # can proceed with minimal error-checking. + if action == 'include': + self.debug_print("include " + ' '.join(patterns)) + for pattern in patterns: + if not self.include(pattern): + log.warn("warning: no files found matching '%s'", pattern) + + elif action == 'exclude': + self.debug_print("exclude " + ' '.join(patterns)) + for pattern in patterns: + if not self.exclude(pattern): + log.warn(("warning: no previously-included files " + "found matching '%s'"), pattern) + + elif action == 'global-include': + self.debug_print("global-include " + ' '.join(patterns)) + for pattern in patterns: + if not self.global_include(pattern): + log.warn(("warning: no files found matching '%s' " + "anywhere in distribution"), pattern) + + elif action == 'global-exclude': + self.debug_print("global-exclude " + ' '.join(patterns)) + for pattern in patterns: + if not self.global_exclude(pattern): + log.warn(("warning: no previously-included files matching " + "'%s' found anywhere in distribution"), + pattern) + + elif action == 'recursive-include': + self.debug_print("recursive-include %s %s" % + (dir, ' '.join(patterns))) + for pattern in patterns: + if not self.recursive_include(dir, pattern): + log.warn(("warning: no files found matching '%s' " + "under directory '%s'"), + pattern, dir) + + elif action == 'recursive-exclude': + self.debug_print("recursive-exclude %s %s" % + (dir, ' '.join(patterns))) + for pattern in patterns: + if not self.recursive_exclude(dir, pattern): + log.warn(("warning: no previously-included files matching " + "'%s' found under directory '%s'"), + pattern, dir) + + elif action == 'graft': + self.debug_print("graft " + dir_pattern) + if not self.graft(dir_pattern): + log.warn("warning: no directories found matching '%s'", + dir_pattern) + + elif action == 'prune': + self.debug_print("prune " + dir_pattern) + if not self.prune(dir_pattern): + log.warn(("no previously-included directories found " + "matching '%s'"), dir_pattern) + + else: + raise DistutilsInternalError( + "this cannot happen: invalid action '%s'" % action) + + def _remove_files(self, predicate): + """ + Remove all files from the file list that match the predicate. + Return True if any matching files were removed + """ + found = False + for i in range(len(self.files) - 1, -1, -1): + if predicate(self.files[i]): + self.debug_print(" removing " + self.files[i]) + del self.files[i] + found = True + return found + + def include(self, pattern): + """Include files that match 'pattern'.""" + found = [f for f in glob(pattern) if not os.path.isdir(f)] + self.extend(found) + return bool(found) + + def exclude(self, pattern): + """Exclude files that match 'pattern'.""" + match = translate_pattern(pattern) + return self._remove_files(match.match) + + def recursive_include(self, dir, pattern): + """ + Include all files anywhere in 'dir/' that match the pattern. + """ + full_pattern = os.path.join(dir, '**', pattern) + found = [f for f in glob(full_pattern, recursive=True) + if not os.path.isdir(f)] + self.extend(found) + return bool(found) + + def recursive_exclude(self, dir, pattern): + """ + Exclude any file anywhere in 'dir/' that match the pattern. + """ + match = translate_pattern(os.path.join(dir, '**', pattern)) + return self._remove_files(match.match) + + def graft(self, dir): + """Include all files from 'dir/'.""" + found = [ + item + for match_dir in glob(dir) + for item in distutils.filelist.findall(match_dir) + ] + self.extend(found) + return bool(found) + + def prune(self, dir): + """Filter out files from 'dir/'.""" + match = translate_pattern(os.path.join(dir, '**')) + return self._remove_files(match.match) + + def global_include(self, pattern): + """ + Include all files anywhere in the current directory that match the + pattern. This is very inefficient on large file trees. + """ + if self.allfiles is None: + self.findall() + match = translate_pattern(os.path.join('**', pattern)) + found = [f for f in self.allfiles if match.match(f)] + self.extend(found) + return bool(found) + + def global_exclude(self, pattern): + """ + Exclude all files anywhere that match the pattern. + """ + match = translate_pattern(os.path.join('**', pattern)) + return self._remove_files(match.match) + + def append(self, item): + if item.endswith('\r'): # Fix older sdists built on Windows + item = item[:-1] + path = convert_path(item) + + if self._safe_path(path): + self.files.append(path) + + def extend(self, paths): + self.files.extend(filter(self._safe_path, paths)) + + def _repair(self): + """ + Replace self.files with only safe paths + + Because some owners of FileList manipulate the underlying + ``files`` attribute directly, this method must be called to + repair those paths. + """ + self.files = list(filter(self._safe_path, self.files)) + + def _safe_path(self, path): + enc_warn = "'%s' not %s encodable -- skipping" + + # To avoid accidental trans-codings errors, first to unicode + u_path = unicode_utils.filesys_decode(path) + if u_path is None: + log.warn("'%s' in unexpected encoding -- skipping" % path) + return False + + # Must ensure utf-8 encodability + utf8_path = unicode_utils.try_encode(u_path, "utf-8") + if utf8_path is None: + log.warn(enc_warn, path, 'utf-8') + return False + + try: + # accept is either way checks out + if os.path.exists(u_path) or os.path.exists(utf8_path): + return True + # this will catch any encode errors decoding u_path + except UnicodeEncodeError: + log.warn(enc_warn, path, sys.getfilesystemencoding()) + + +class manifest_maker(sdist): + template = "MANIFEST.in" + + def initialize_options(self): + self.use_defaults = 1 + self.prune = 1 + self.manifest_only = 1 + self.force_manifest = 1 + + def finalize_options(self): + pass + + def run(self): + self.filelist = FileList() + if not os.path.exists(self.manifest): + self.write_manifest() # it must exist so it'll get in the list + self.add_defaults() + if os.path.exists(self.template): + self.read_template() + self.prune_file_list() + self.filelist.sort() + self.filelist.remove_duplicates() + self.write_manifest() + + def _manifest_normalize(self, path): + path = unicode_utils.filesys_decode(path) + return path.replace(os.sep, '/') + + def write_manifest(self): + """ + Write the file list in 'self.filelist' to the manifest file + named by 'self.manifest'. + """ + self.filelist._repair() + + # Now _repairs should encodability, but not unicode + files = [self._manifest_normalize(f) for f in self.filelist.files] + msg = "writing manifest file '%s'" % self.manifest + self.execute(write_file, (self.manifest, files), msg) + + def warn(self, msg): + if not self._should_suppress_warning(msg): + sdist.warn(self, msg) + + @staticmethod + def _should_suppress_warning(msg): + """ + suppress missing-file warnings from sdist + """ + return re.match(r"standard file .*not found", msg) + + def add_defaults(self): + sdist.add_defaults(self) + self.filelist.append(self.template) + self.filelist.append(self.manifest) + rcfiles = list(walk_revctrl()) + if rcfiles: + self.filelist.extend(rcfiles) + elif os.path.exists(self.manifest): + self.read_manifest() + + if os.path.exists("setup.py"): + # setup.py should be included by default, even if it's not + # the script called to create the sdist + self.filelist.append("setup.py") + + ei_cmd = self.get_finalized_command('egg_info') + self.filelist.graft(ei_cmd.egg_info) + + def prune_file_list(self): + build = self.get_finalized_command('build') + base_dir = self.distribution.get_fullname() + self.filelist.prune(build.build_base) + self.filelist.prune(base_dir) + sep = re.escape(os.sep) + self.filelist.exclude_pattern(r'(^|' + sep + r')(RCS|CVS|\.svn)' + sep, + is_regex=1) + + +def write_file(filename, contents): + """Create a file with the specified name and write 'contents' (a + sequence of strings without line terminators) to it. + """ + contents = "\n".join(contents) + + # assuming the contents has been vetted for utf-8 encoding + contents = contents.encode("utf-8") + + with open(filename, "wb") as f: # always write POSIX-style manifest + f.write(contents) + + +def write_pkg_info(cmd, basename, filename): + log.info("writing %s", filename) + if not cmd.dry_run: + metadata = cmd.distribution.metadata + metadata.version, oldver = cmd.egg_version, metadata.version + metadata.name, oldname = cmd.egg_name, metadata.name + + try: + # write unescaped data to PKG-INFO, so older pkg_resources + # can still parse it + metadata.write_pkg_info(cmd.egg_info) + finally: + metadata.name, metadata.version = oldname, oldver + + safe = getattr(cmd.distribution, 'zip_safe', None) + + bdist_egg.write_safety_flag(cmd.egg_info, safe) + + +def warn_depends_obsolete(cmd, basename, filename): + if os.path.exists(filename): + log.warn( + "WARNING: 'depends.txt' is not used by setuptools 0.6!\n" + "Use the install_requires/extras_require setup() args instead." + ) + + +def _write_requirements(stream, reqs): + lines = yield_lines(reqs or ()) + append_cr = lambda line: line + '\n' + lines = map(append_cr, lines) + stream.writelines(lines) + + +def write_requirements(cmd, basename, filename): + dist = cmd.distribution + data = six.StringIO() + _write_requirements(data, dist.install_requires) + extras_require = dist.extras_require or {} + for extra in sorted(extras_require): + data.write('\n[{extra}]\n'.format(**vars())) + _write_requirements(data, extras_require[extra]) + cmd.write_or_delete_file("requirements", filename, data.getvalue()) + + +def write_setup_requirements(cmd, basename, filename): + data = io.StringIO() + _write_requirements(data, cmd.distribution.setup_requires) + cmd.write_or_delete_file("setup-requirements", filename, data.getvalue()) + + +def write_toplevel_names(cmd, basename, filename): + pkgs = dict.fromkeys( + [ + k.split('.', 1)[0] + for k in cmd.distribution.iter_distribution_names() + ] + ) + cmd.write_file("top-level names", filename, '\n'.join(sorted(pkgs)) + '\n') + + +def overwrite_arg(cmd, basename, filename): + write_arg(cmd, basename, filename, True) + + +def write_arg(cmd, basename, filename, force=False): + argname = os.path.splitext(basename)[0] + value = getattr(cmd.distribution, argname, None) + if value is not None: + value = '\n'.join(value) + '\n' + cmd.write_or_delete_file(argname, filename, value, force) + + +def write_entries(cmd, basename, filename): + ep = cmd.distribution.entry_points + + if isinstance(ep, six.string_types) or ep is None: + data = ep + elif ep is not None: + data = [] + for section, contents in sorted(ep.items()): + if not isinstance(contents, six.string_types): + contents = EntryPoint.parse_group(section, contents) + contents = '\n'.join(sorted(map(str, contents.values()))) + data.append('[%s]\n%s\n\n' % (section, contents)) + data = ''.join(data) + + cmd.write_or_delete_file('entry points', filename, data, True) + + +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) + if os.path.exists('PKG-INFO'): + with io.open('PKG-INFO') as f: + for line in f: + match = re.match(r"Version:.*-r(\d+)\s*$", line) + if match: + return int(match.group(1)) + return 0 + + +class EggInfoDeprecationWarning(SetuptoolsDeprecationWarning): + """Class for warning about deprecations in eggInfo in setupTools. Not ignored by default, unlike DeprecationWarning.""" diff --git a/venv/lib/python3.7/site-packages/setuptools/command/install.py b/venv/lib/python3.7/site-packages/setuptools/command/install.py new file mode 100644 index 0000000..31a5ddb --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/command/install.py @@ -0,0 +1,125 @@ +from distutils.errors import DistutilsArgError +import inspect +import glob +import warnings +import platform +import distutils.command.install as orig + +import setuptools + +# Prior to numpy 1.9, NumPy relies on the '_install' name, so provide it for +# now. See https://github.com/pypa/setuptools/issues/199/ +_install = orig.install + + +class install(orig.install): + """Use easy_install to install the package, w/dependencies""" + + user_options = orig.install.user_options + [ + ('old-and-unmanageable', None, "Try not to use this!"), + ('single-version-externally-managed', None, + "used by system package builders to create 'flat' eggs"), + ] + boolean_options = orig.install.boolean_options + [ + 'old-and-unmanageable', 'single-version-externally-managed', + ] + new_commands = [ + ('install_egg_info', lambda self: True), + ('install_scripts', lambda self: True), + ] + _nc = dict(new_commands) + + def initialize_options(self): + orig.install.initialize_options(self) + self.old_and_unmanageable = None + self.single_version_externally_managed = None + + def finalize_options(self): + orig.install.finalize_options(self) + if self.root: + self.single_version_externally_managed = True + elif self.single_version_externally_managed: + if not self.root and not self.record: + raise DistutilsArgError( + "You must specify --record or --root when building system" + " packages" + ) + + def handle_extra_path(self): + if self.root or self.single_version_externally_managed: + # explicit backward-compatibility mode, allow extra_path to work + return orig.install.handle_extra_path(self) + + # Ignore extra_path when installing an egg (or being run by another + # command without --root or --single-version-externally-managed + self.path_file = None + self.extra_dirs = '' + + def run(self): + # Explicit request for old-style install? Just do it + if self.old_and_unmanageable or self.single_version_externally_managed: + return orig.install.run(self) + + if not self._called_from_setup(inspect.currentframe()): + # Run in backward-compatibility mode to support bdist_* commands. + orig.install.run(self) + else: + self.do_egg_install() + + @staticmethod + def _called_from_setup(run_frame): + """ + Attempt to detect whether run() was called from setup() or by another + command. If called by setup(), the parent caller will be the + 'run_command' method in 'distutils.dist', and *its* caller will be + the 'run_commands' method. If called any other way, the + immediate caller *might* be 'run_command', but it won't have been + called by 'run_commands'. Return True in that case or if a call stack + is unavailable. Return False otherwise. + """ + if run_frame is None: + msg = "Call stack not available. bdist_* commands may fail." + warnings.warn(msg) + if platform.python_implementation() == 'IronPython': + msg = "For best results, pass -X:Frames to enable call stack." + warnings.warn(msg) + return True + res = inspect.getouterframes(run_frame)[2] + caller, = res[:1] + info = inspect.getframeinfo(caller) + caller_module = caller.f_globals.get('__name__', '') + return ( + caller_module == 'distutils.dist' + and info.function == 'run_commands' + ) + + def do_egg_install(self): + + easy_install = self.distribution.get_command_class('easy_install') + + cmd = easy_install( + self.distribution, args="x", root=self.root, record=self.record, + ) + cmd.ensure_finalized() # finalize before bdist_egg munges install cmd + cmd.always_copy_from = '.' # make sure local-dir eggs get installed + + # pick up setup-dir .egg files only: no .egg-info + cmd.package_index.scan(glob.glob('*.egg')) + + self.run_command('bdist_egg') + args = [self.distribution.get_command_obj('bdist_egg').egg_output] + + if setuptools.bootstrap_install_from: + # Bootstrap self-installation of setuptools + args.insert(0, setuptools.bootstrap_install_from) + + cmd.args = args + cmd.run() + setuptools.bootstrap_install_from = None + + +# XXX Python 3.1 doesn't see _nc if this is inside the class +install.sub_commands = ( + [cmd for cmd in orig.install.sub_commands if cmd[0] not in install._nc] + + install.new_commands +) diff --git a/venv/lib/python3.7/site-packages/setuptools/command/install_egg_info.py b/venv/lib/python3.7/site-packages/setuptools/command/install_egg_info.py new file mode 100644 index 0000000..edc4718 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/command/install_egg_info.py @@ -0,0 +1,62 @@ +from distutils import log, dir_util +import os + +from setuptools import Command +from setuptools import namespaces +from setuptools.archive_util import unpack_archive +import pkg_resources + + +class install_egg_info(namespaces.Installer, Command): + """Install an .egg-info directory for the package""" + + description = "Install an .egg-info directory for the package" + + user_options = [ + ('install-dir=', 'd', "directory to install to"), + ] + + def initialize_options(self): + self.install_dir = None + + def finalize_options(self): + self.set_undefined_options('install_lib', + ('install_dir', 'install_dir')) + ei_cmd = self.get_finalized_command("egg_info") + basename = pkg_resources.Distribution( + None, None, ei_cmd.egg_name, ei_cmd.egg_version + ).egg_name() + '.egg-info' + self.source = ei_cmd.egg_info + self.target = os.path.join(self.install_dir, basename) + self.outputs = [] + + def run(self): + self.run_command('egg_info') + if os.path.isdir(self.target) and not os.path.islink(self.target): + dir_util.remove_tree(self.target, dry_run=self.dry_run) + elif os.path.exists(self.target): + self.execute(os.unlink, (self.target,), "Removing " + self.target) + if not self.dry_run: + pkg_resources.ensure_directory(self.target) + self.execute( + self.copytree, (), "Copying %s to %s" % (self.source, self.target) + ) + self.install_namespaces() + + def get_outputs(self): + return self.outputs + + def copytree(self): + # Copy the .egg-info tree to site-packages + def skimmer(src, dst): + # filter out source-control directories; note that 'src' is always + # a '/'-separated path, regardless of platform. 'dst' is a + # platform-specific path. + for skip in '.svn/', 'CVS/': + if src.startswith(skip) or '/' + skip in src: + return None + self.outputs.append(dst) + log.debug("Copying %s to %s", src, dst) + return dst + + unpack_archive(self.source, self.target, skimmer) diff --git a/venv/lib/python3.7/site-packages/setuptools/command/install_lib.py b/venv/lib/python3.7/site-packages/setuptools/command/install_lib.py new file mode 100644 index 0000000..2b31c3e --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/command/install_lib.py @@ -0,0 +1,121 @@ +import os +import imp +from itertools import product, starmap +import distutils.command.install_lib as orig + + +class install_lib(orig.install_lib): + """Don't add compiled flags to filenames of non-Python files""" + + def run(self): + self.build() + outfiles = self.install() + if outfiles is not None: + # always compile, in case we have any extension stubs to deal with + self.byte_compile(outfiles) + + def get_exclusions(self): + """ + Return a collections.Sized collections.Container of paths to be + excluded for single_version_externally_managed installations. + """ + all_packages = ( + pkg + for ns_pkg in self._get_SVEM_NSPs() + for pkg in self._all_packages(ns_pkg) + ) + + excl_specs = product(all_packages, self._gen_exclusion_paths()) + return set(starmap(self._exclude_pkg_path, excl_specs)) + + def _exclude_pkg_path(self, pkg, exclusion_path): + """ + Given a package name and exclusion path within that package, + compute the full exclusion path. + """ + parts = pkg.split('.') + [exclusion_path] + return os.path.join(self.install_dir, *parts) + + @staticmethod + def _all_packages(pkg_name): + """ + >>> list(install_lib._all_packages('foo.bar.baz')) + ['foo.bar.baz', 'foo.bar', 'foo'] + """ + while pkg_name: + yield pkg_name + pkg_name, sep, child = pkg_name.rpartition('.') + + def _get_SVEM_NSPs(self): + """ + Get namespace packages (list) but only for + single_version_externally_managed installations and empty otherwise. + """ + # TODO: is it necessary to short-circuit here? i.e. what's the cost + # if get_finalized_command is called even when namespace_packages is + # False? + if not self.distribution.namespace_packages: + return [] + + install_cmd = self.get_finalized_command('install') + svem = install_cmd.single_version_externally_managed + + return self.distribution.namespace_packages if svem else [] + + @staticmethod + def _gen_exclusion_paths(): + """ + Generate file paths to be excluded for namespace packages (bytecode + cache files). + """ + # always exclude the package module itself + yield '__init__.py' + + yield '__init__.pyc' + yield '__init__.pyo' + + if not hasattr(imp, 'get_tag'): + return + + base = os.path.join('__pycache__', '__init__.' + imp.get_tag()) + yield base + '.pyc' + yield base + '.pyo' + yield base + '.opt-1.pyc' + yield base + '.opt-2.pyc' + + def copy_tree( + self, infile, outfile, + preserve_mode=1, preserve_times=1, preserve_symlinks=0, level=1 + ): + assert preserve_mode and preserve_times and not preserve_symlinks + exclude = self.get_exclusions() + + if not exclude: + return orig.install_lib.copy_tree(self, infile, outfile) + + # Exclude namespace package __init__.py* files from the output + + from setuptools.archive_util import unpack_directory + from distutils import log + + outfiles = [] + + def pf(src, dst): + if dst in exclude: + log.warn("Skipping installation of %s (namespace package)", + dst) + return False + + log.info("copying %s -> %s", src, os.path.dirname(dst)) + outfiles.append(dst) + return dst + + unpack_directory(infile, outfile, pf) + return outfiles + + def get_outputs(self): + outputs = orig.install_lib.get_outputs(self) + exclude = self.get_exclusions() + if exclude: + return [f for f in outputs if f not in exclude] + return outputs diff --git a/venv/lib/python3.7/site-packages/setuptools/command/install_scripts.py b/venv/lib/python3.7/site-packages/setuptools/command/install_scripts.py new file mode 100644 index 0000000..1623427 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/command/install_scripts.py @@ -0,0 +1,65 @@ +from distutils import log +import distutils.command.install_scripts as orig +import os +import sys + +from pkg_resources import Distribution, PathMetadata, ensure_directory + + +class install_scripts(orig.install_scripts): + """Do normal script install, plus any egg_info wrapper scripts""" + + def initialize_options(self): + orig.install_scripts.initialize_options(self) + self.no_ep = False + + def run(self): + import setuptools.command.easy_install as ei + + self.run_command("egg_info") + if self.distribution.scripts: + orig.install_scripts.run(self) # run first to set up self.outfiles + else: + self.outfiles = [] + if self.no_ep: + # don't install entry point scripts into .egg file! + return + + ei_cmd = self.get_finalized_command("egg_info") + dist = Distribution( + ei_cmd.egg_base, PathMetadata(ei_cmd.egg_base, ei_cmd.egg_info), + ei_cmd.egg_name, ei_cmd.egg_version, + ) + 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) + writer = ei.ScriptWriter + if is_wininst: + exec_param = "python.exe" + writer = ei.WindowsScriptWriter + if exec_param == sys.executable: + # In case the path to the Python executable contains a space, wrap + # it so it's not split up. + exec_param = [exec_param] + # resolve the writer to the environment + writer = writer.best() + cmd = writer.command_spec_class.best().from_param(exec_param) + for args in writer.get_args(dist, cmd.as_header()): + self.write_script(*args) + + def write_script(self, script_name, contents, mode="t", *ignored): + """Write an executable file to the scripts directory""" + from setuptools.command.easy_install import chmod, current_umask + + log.info("Installing %s script to %s", script_name, self.install_dir) + target = os.path.join(self.install_dir, script_name) + self.outfiles.append(target) + + mask = current_umask() + if not self.dry_run: + ensure_directory(target) + f = open(target, "w" + mode) + f.write(contents) + f.close() + chmod(target, 0o777 - mask) diff --git a/venv/lib/python3.7/site-packages/setuptools/command/launcher manifest.xml b/venv/lib/python3.7/site-packages/setuptools/command/launcher manifest.xml new file mode 100644 index 0000000..5972a96 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/command/launcher manifest.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> + <assemblyIdentity version="1.0.0.0" + processorArchitecture="X86" + name="%(name)s" + type="win32"/> + <!-- Identify the application security requirements. --> + <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> + <security> + <requestedPrivileges> + <requestedExecutionLevel level="asInvoker" uiAccess="false"/> + </requestedPrivileges> + </security> + </trustInfo> +</assembly> diff --git a/venv/lib/python3.7/site-packages/setuptools/command/py36compat.py b/venv/lib/python3.7/site-packages/setuptools/command/py36compat.py new file mode 100644 index 0000000..61063e7 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/command/py36compat.py @@ -0,0 +1,136 @@ +import os +from glob import glob +from distutils.util import convert_path +from distutils.command import sdist + +from setuptools.extern.six.moves import filter + + +class sdist_add_defaults: + """ + Mix-in providing forward-compatibility for functionality as found in + distutils on Python 3.7. + + Do not edit the code in this class except to update functionality + as implemented in distutils. Instead, override in the subclass. + """ + + def add_defaults(self): + """Add all the default files to self.filelist: + - README or README.txt + - setup.py + - test/test*.py + - all pure Python modules mentioned in setup script + - all files pointed by package_data (build_py) + - all files defined in data_files. + - all files defined as scripts. + - all C sources listed as part of extensions or C libraries + in the setup script (doesn't catch C headers!) + Warns if (README or README.txt) or setup.py are missing; everything + else is optional. + """ + self._add_defaults_standards() + self._add_defaults_optional() + self._add_defaults_python() + self._add_defaults_data_files() + self._add_defaults_ext() + self._add_defaults_c_libs() + self._add_defaults_scripts() + + @staticmethod + def _cs_path_exists(fspath): + """ + Case-sensitive path existence check + + >>> sdist_add_defaults._cs_path_exists(__file__) + True + >>> sdist_add_defaults._cs_path_exists(__file__.upper()) + False + """ + if not os.path.exists(fspath): + return False + # make absolute so we always have a directory + abspath = os.path.abspath(fspath) + directory, filename = os.path.split(abspath) + return filename in os.listdir(directory) + + def _add_defaults_standards(self): + standards = [self.READMES, self.distribution.script_name] + for fn in standards: + if isinstance(fn, tuple): + alts = fn + got_it = False + for fn in alts: + if self._cs_path_exists(fn): + got_it = True + self.filelist.append(fn) + break + + if not got_it: + self.warn("standard file not found: should have one of " + + ', '.join(alts)) + else: + if self._cs_path_exists(fn): + self.filelist.append(fn) + else: + self.warn("standard file '%s' not found" % fn) + + def _add_defaults_optional(self): + optional = ['test/test*.py', 'setup.cfg'] + for pattern in optional: + files = filter(os.path.isfile, glob(pattern)) + self.filelist.extend(files) + + def _add_defaults_python(self): + # build_py is used to get: + # - python modules + # - files defined in package_data + build_py = self.get_finalized_command('build_py') + + # getting python files + if self.distribution.has_pure_modules(): + self.filelist.extend(build_py.get_source_files()) + + # getting package_data files + # (computed in build_py.data_files by build_py.finalize_options) + for pkg, src_dir, build_dir, filenames in build_py.data_files: + for filename in filenames: + self.filelist.append(os.path.join(src_dir, filename)) + + def _add_defaults_data_files(self): + # getting distribution.data_files + if self.distribution.has_data_files(): + for item in self.distribution.data_files: + if isinstance(item, str): + # plain file + item = convert_path(item) + if os.path.isfile(item): + self.filelist.append(item) + else: + # a (dirname, filenames) tuple + dirname, filenames = item + for f in filenames: + f = convert_path(f) + if os.path.isfile(f): + self.filelist.append(f) + + def _add_defaults_ext(self): + if self.distribution.has_ext_modules(): + build_ext = self.get_finalized_command('build_ext') + self.filelist.extend(build_ext.get_source_files()) + + def _add_defaults_c_libs(self): + if self.distribution.has_c_libraries(): + build_clib = self.get_finalized_command('build_clib') + self.filelist.extend(build_clib.get_source_files()) + + def _add_defaults_scripts(self): + if self.distribution.has_scripts(): + build_scripts = self.get_finalized_command('build_scripts') + self.filelist.extend(build_scripts.get_source_files()) + + +if hasattr(sdist.sdist, '_add_defaults_standards'): + # disable the functionality already available upstream + class sdist_add_defaults: + pass diff --git a/venv/lib/python3.7/site-packages/setuptools/command/register.py b/venv/lib/python3.7/site-packages/setuptools/command/register.py new file mode 100644 index 0000000..98bc015 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/command/register.py @@ -0,0 +1,18 @@ +from distutils import log +import distutils.command.register as orig + + +class register(orig.register): + __doc__ = orig.register.__doc__ + + 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 + ) diff --git a/venv/lib/python3.7/site-packages/setuptools/command/rotate.py b/venv/lib/python3.7/site-packages/setuptools/command/rotate.py new file mode 100644 index 0000000..b89353f --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/command/rotate.py @@ -0,0 +1,66 @@ +from distutils.util import convert_path +from distutils import log +from distutils.errors import DistutilsOptionError +import os +import shutil + +from setuptools.extern import six + +from setuptools import Command + + +class rotate(Command): + """Delete older distributions""" + + description = "delete older distributions, keeping N newest files" + user_options = [ + ('match=', 'm', "patterns to match (required)"), + ('dist-dir=', 'd', "directory where the distributions are"), + ('keep=', 'k', "number of matching distributions to keep"), + ] + + boolean_options = [] + + def initialize_options(self): + self.match = None + self.dist_dir = None + self.keep = None + + def finalize_options(self): + if self.match is None: + raise DistutilsOptionError( + "Must specify one or more (comma-separated) match patterns " + "(e.g. '.zip' or '.egg')" + ) + if self.keep is None: + raise DistutilsOptionError("Must specify number of files to keep") + try: + self.keep = int(self.keep) + except ValueError: + raise DistutilsOptionError("--keep must be an integer") + if isinstance(self.match, six.string_types): + self.match = [ + convert_path(p.strip()) for p in self.match.split(',') + ] + self.set_undefined_options('bdist', ('dist_dir', 'dist_dir')) + + def run(self): + self.run_command("egg_info") + from glob import glob + + for pattern in self.match: + pattern = self.distribution.get_name() + '*' + pattern + files = glob(os.path.join(self.dist_dir, pattern)) + files = [(os.path.getmtime(f), f) for f in files] + files.sort() + files.reverse() + + log.info("%d file(s) matching %s", len(files), pattern) + files = files[self.keep:] + for (t, f) in files: + log.info("Deleting %s", f) + if not self.dry_run: + if os.path.isdir(f): + shutil.rmtree(f) + else: + os.unlink(f) diff --git a/venv/lib/python3.7/site-packages/setuptools/command/saveopts.py b/venv/lib/python3.7/site-packages/setuptools/command/saveopts.py new file mode 100644 index 0000000..611cec5 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/command/saveopts.py @@ -0,0 +1,22 @@ +from setuptools.command.setopt import edit_config, option_base + + +class saveopts(option_base): + """Save command-line options to a file""" + + description = "save supplied options to setup.cfg or other config file" + + def run(self): + dist = self.distribution + settings = {} + + for cmd in dist.command_options: + + if cmd == 'saveopts': + continue # don't save our own options! + + for opt, (src, val) in dist.get_option_dict(cmd).items(): + if src == "command line": + settings.setdefault(cmd, {})[opt] = val + + edit_config(self.filename, settings, self.dry_run) diff --git a/venv/lib/python3.7/site-packages/setuptools/command/sdist.py b/venv/lib/python3.7/site-packages/setuptools/command/sdist.py new file mode 100644 index 0000000..bcfae4d --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/command/sdist.py @@ -0,0 +1,200 @@ +from distutils import log +import distutils.command.sdist as orig +import os +import sys +import io +import contextlib + +from setuptools.extern import six + +from .py36compat import sdist_add_defaults + +import pkg_resources + +_default_revctrl = list + + +def walk_revctrl(dirname=''): + """Find all files under revision control""" + for ep in pkg_resources.iter_entry_points('setuptools.file_finders'): + for item in ep.load()(dirname): + yield item + + +class sdist(sdist_add_defaults, orig.sdist): + """Smart sdist that finds anything supported by revision control""" + + user_options = [ + ('formats=', None, + "formats for source distribution (comma-separated list)"), + ('keep-temp', 'k', + "keep the distribution tree around after creating " + + "archive file(s)"), + ('dist-dir=', 'd', + "directory to put the source distribution archive(s) in " + "[default: dist]"), + ] + + negative_opt = {} + + README_EXTENSIONS = ['', '.rst', '.txt', '.md'] + READMES = tuple('README{0}'.format(ext) for ext in README_EXTENSIONS) + + def run(self): + self.run_command('egg_info') + ei_cmd = self.get_finalized_command('egg_info') + self.filelist = ei_cmd.filelist + self.filelist.append(os.path.join(ei_cmd.egg_info, 'SOURCES.txt')) + self.check_readme() + + # Run sub commands + for cmd_name in self.get_sub_commands(): + self.run_command(cmd_name) + + self.make_distribution() + + dist_files = getattr(self.distribution, 'dist_files', []) + for file in self.archive_files: + data = ('sdist', '', file) + if data not in dist_files: + dist_files.append(data) + + def initialize_options(self): + orig.sdist.initialize_options(self) + + self._default_to_gztar() + + def _default_to_gztar(self): + # only needed on Python prior to 3.6. + if sys.version_info >= (3, 6, 0, 'beta', 1): + return + self.formats = ['gztar'] + + def make_distribution(self): + """ + Workaround for #516 + """ + with self._remove_os_link(): + orig.sdist.make_distribution(self) + + @staticmethod + @contextlib.contextmanager + def _remove_os_link(): + """ + In a context, remove and restore os.link if it exists + """ + + class NoValue: + pass + + orig_val = getattr(os, 'link', NoValue) + try: + del os.link + except Exception: + pass + try: + yield + finally: + if orig_val is not NoValue: + setattr(os, 'link', orig_val) + + def __read_template_hack(self): + # This grody hack closes the template file (MANIFEST.in) if an + # exception occurs during read_template. + # Doing so prevents an error when easy_install attempts to delete the + # file. + try: + orig.sdist.read_template(self) + except Exception: + _, _, tb = sys.exc_info() + tb.tb_next.tb_frame.f_locals['template'].close() + raise + + # Beginning with Python 2.7.2, 3.1.4, and 3.2.1, this leaky file handle + # has been fixed, so only override the method if we're using an earlier + # Python. + has_leaky_handle = ( + sys.version_info < (2, 7, 2) + or (3, 0) <= sys.version_info < (3, 1, 4) + or (3, 2) <= sys.version_info < (3, 2, 1) + ) + if has_leaky_handle: + read_template = __read_template_hack + + 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]) + + def _add_defaults_data_files(self): + try: + if six.PY2: + sdist_add_defaults._add_defaults_data_files(self) + else: + super()._add_defaults_data_files() + except TypeError: + log.warn("data_files contains unexpected objects") + + def check_readme(self): + for f in self.READMES: + if os.path.exists(f): + return + else: + self.warn( + "standard file not found: should have one of " + + ', '.join(self.READMES) + ) + + def make_release_tree(self, base_dir, files): + orig.sdist.make_release_tree(self, base_dir, files) + + # Save any egg_info command line options used to create this sdist + dest = os.path.join(base_dir, 'setup.cfg') + if hasattr(os, 'link') and os.path.exists(dest): + # unlink and re-copy, since it might be hard-linked, and + # we don't want to change the source version + os.unlink(dest) + self.copy_file('setup.cfg', dest) + + self.get_finalized_command('egg_info').save_version_info(dest) + + def _manifest_is_not_generated(self): + # check for special comment used in 2.7.1 and higher + if not os.path.isfile(self.manifest): + return False + + with io.open(self.manifest, 'rb') as fp: + first_line = fp.readline() + return (first_line != + '# file GENERATED by distutils, do NOT edit\n'.encode()) + + def read_manifest(self): + """Read the manifest file (named by 'self.manifest') and use it to + fill in 'self.filelist', the list of files to include in the source + distribution. + """ + log.info("reading manifest file '%s'", self.manifest) + manifest = open(self.manifest, 'rb') + for line in manifest: + # The manifest must contain UTF-8. See #303. + if six.PY3: + try: + line = line.decode('UTF-8') + except UnicodeDecodeError: + log.warn("%r not UTF-8 decodable -- skipping" % line) + continue + # ignore comments and blank lines + line = line.strip() + if line.startswith('#') or not line: + continue + self.filelist.append(line) + manifest.close() diff --git a/venv/lib/python3.7/site-packages/setuptools/command/setopt.py b/venv/lib/python3.7/site-packages/setuptools/command/setopt.py new file mode 100644 index 0000000..7e57cc0 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/command/setopt.py @@ -0,0 +1,149 @@ +from distutils.util import convert_path +from distutils import log +from distutils.errors import DistutilsOptionError +import distutils +import os + +from setuptools.extern.six.moves import configparser + +from setuptools import Command + +__all__ = ['config_file', 'edit_config', 'option_base', 'setopt'] + + +def config_file(kind="local"): + """Get the filename of the distutils, local, global, or per-user config + + `kind` must be one of "local", "global", or "user" + """ + if kind == 'local': + return 'setup.cfg' + if kind == 'global': + return os.path.join( + os.path.dirname(distutils.__file__), 'distutils.cfg' + ) + if kind == 'user': + dot = os.name == 'posix' and '.' or '' + return os.path.expanduser(convert_path("~/%spydistutils.cfg" % dot)) + raise ValueError( + "config_file() type must be 'local', 'global', or 'user'", kind + ) + + +def edit_config(filename, settings, dry_run=False): + """Edit a configuration file to include `settings` + + `settings` is a dictionary of dictionaries or ``None`` values, keyed by + command/section name. A ``None`` value means to delete the entire section, + while a dictionary lists settings to be changed or deleted in that section. + A setting of ``None`` means to delete that setting. + """ + log.debug("Reading configuration from %s", filename) + opts = configparser.RawConfigParser() + opts.read([filename]) + for section, options in settings.items(): + if options is None: + log.info("Deleting section [%s] from %s", section, filename) + opts.remove_section(section) + else: + if not opts.has_section(section): + log.debug("Adding new section [%s] to %s", section, filename) + opts.add_section(section) + for option, value in options.items(): + if value is None: + log.debug( + "Deleting %s.%s from %s", + section, option, filename + ) + opts.remove_option(section, option) + if not opts.options(section): + log.info("Deleting empty [%s] section from %s", + section, filename) + opts.remove_section(section) + else: + log.debug( + "Setting %s.%s to %r in %s", + section, option, value, filename + ) + opts.set(section, option, value) + + log.info("Writing %s", filename) + if not dry_run: + with open(filename, 'w') as f: + opts.write(f) + + +class option_base(Command): + """Abstract base class for commands that mess with config files""" + + user_options = [ + ('global-config', 'g', + "save options to the site-wide distutils.cfg file"), + ('user-config', 'u', + "save options to the current user's pydistutils.cfg file"), + ('filename=', 'f', + "configuration file to use (default=setup.cfg)"), + ] + + boolean_options = [ + 'global-config', 'user-config', + ] + + def initialize_options(self): + self.global_config = None + self.user_config = None + self.filename = None + + def finalize_options(self): + filenames = [] + if self.global_config: + filenames.append(config_file('global')) + if self.user_config: + filenames.append(config_file('user')) + if self.filename is not None: + filenames.append(self.filename) + if not filenames: + filenames.append(config_file('local')) + if len(filenames) > 1: + raise DistutilsOptionError( + "Must specify only one configuration file option", + filenames + ) + self.filename, = filenames + + +class setopt(option_base): + """Save command-line options to a file""" + + description = "set an option in setup.cfg or another config file" + + user_options = [ + ('command=', 'c', 'command to set an option for'), + ('option=', 'o', 'option to set'), + ('set-value=', 's', 'value of the option'), + ('remove', 'r', 'remove (unset) the value'), + ] + option_base.user_options + + boolean_options = option_base.boolean_options + ['remove'] + + def initialize_options(self): + option_base.initialize_options(self) + self.command = None + self.option = None + self.set_value = None + self.remove = None + + def finalize_options(self): + option_base.finalize_options(self) + if self.command is None or self.option is None: + raise DistutilsOptionError("Must specify --command *and* --option") + if self.set_value is None and not self.remove: + raise DistutilsOptionError("Must specify --set-value or --remove") + + def run(self): + edit_config( + self.filename, { + self.command: {self.option.replace('-', '_'): self.set_value} + }, + self.dry_run + ) diff --git a/venv/lib/python3.7/site-packages/setuptools/command/test.py b/venv/lib/python3.7/site-packages/setuptools/command/test.py new file mode 100644 index 0000000..dde0118 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/command/test.py @@ -0,0 +1,270 @@ +import os +import operator +import sys +import contextlib +import itertools +import unittest +from distutils.errors import DistutilsError, DistutilsOptionError +from distutils import log +from unittest import TestLoader + +from setuptools.extern import six +from setuptools.extern.six.moves import map, filter + +from pkg_resources import (resource_listdir, resource_exists, normalize_path, + working_set, _namespace_packages, evaluate_marker, + add_activation_listener, require, EntryPoint) +from setuptools import Command + +__metaclass__ = type + + +class ScanningLoader(TestLoader): + + def __init__(self): + TestLoader.__init__(self) + self._visited = set() + + def loadTestsFromModule(self, module, pattern=None): + """Return a suite of all tests cases contained in the given module + + If the module is a package, load tests from all the modules in it. + If the module has an ``additional_tests`` function, call it and add + the return value to the tests. + """ + if module in self._visited: + return None + self._visited.add(module) + + tests = [] + tests.append(TestLoader.loadTestsFromModule(self, module)) + + if hasattr(module, "additional_tests"): + tests.append(module.additional_tests()) + + if hasattr(module, '__path__'): + for file in resource_listdir(module.__name__, ''): + if file.endswith('.py') and file != '__init__.py': + submodule = module.__name__ + '.' + file[:-3] + else: + if resource_exists(module.__name__, file + '/__init__.py'): + submodule = module.__name__ + '.' + file + else: + continue + tests.append(self.loadTestsFromName(submodule)) + + if len(tests) != 1: + return self.suiteClass(tests) + else: + return tests[0] # don't create a nested suite for only one return + + +# adapted from jaraco.classes.properties:NonDataProperty +class NonDataProperty: + def __init__(self, fget): + self.fget = fget + + def __get__(self, obj, objtype=None): + if obj is None: + return self + return self.fget(obj) + + +class test(Command): + """Command to run unit tests after in-place build""" + + description = "run unit tests after in-place build" + + user_options = [ + ('test-module=', 'm', "Run 'test_suite' in specified module"), + ('test-suite=', 's', + "Run single test, case or suite (e.g. 'module.test_suite')"), + ('test-runner=', 'r', "Test runner to use"), + ] + + def initialize_options(self): + self.test_suite = None + self.test_module = None + self.test_loader = None + self.test_runner = None + + def finalize_options(self): + + if self.test_suite and self.test_module: + msg = "You may specify a module or a suite, but not both" + raise DistutilsOptionError(msg) + + if self.test_suite is None: + if self.test_module is None: + self.test_suite = self.distribution.test_suite + else: + self.test_suite = self.test_module + ".test_suite" + + if self.test_loader is None: + self.test_loader = getattr(self.distribution, 'test_loader', None) + if self.test_loader is None: + self.test_loader = "setuptools.command.test:ScanningLoader" + if self.test_runner is None: + self.test_runner = getattr(self.distribution, 'test_runner', None) + + @NonDataProperty + def test_args(self): + return list(self._test_args()) + + def _test_args(self): + if not self.test_suite and sys.version_info >= (2, 7): + yield 'discover' + if self.verbose: + yield '--verbose' + if self.test_suite: + yield self.test_suite + + def with_project_on_sys_path(self, func): + """ + Backward compatibility for project_on_sys_path context. + """ + with self.project_on_sys_path(): + func() + + @contextlib.contextmanager + def project_on_sys_path(self, include_dists=[]): + with_2to3 = six.PY3 and getattr(self.distribution, 'use_2to3', False) + + if with_2to3: + # If we run 2to3 we can not do this inplace: + + # Ensure metadata is up-to-date + self.reinitialize_command('build_py', inplace=0) + self.run_command('build_py') + bpy_cmd = self.get_finalized_command("build_py") + build_path = normalize_path(bpy_cmd.build_lib) + + # Build extensions + self.reinitialize_command('egg_info', egg_base=build_path) + self.run_command('egg_info') + + self.reinitialize_command('build_ext', inplace=0) + self.run_command('build_ext') + else: + # Without 2to3 inplace works fine: + self.run_command('egg_info') + + # Build extensions in-place + self.reinitialize_command('build_ext', inplace=1) + self.run_command('build_ext') + + ei_cmd = self.get_finalized_command("egg_info") + + old_path = sys.path[:] + old_modules = sys.modules.copy() + + try: + project_path = normalize_path(ei_cmd.egg_base) + sys.path.insert(0, project_path) + working_set.__init__() + add_activation_listener(lambda dist: dist.activate()) + require('%s==%s' % (ei_cmd.egg_name, ei_cmd.egg_version)) + with self.paths_on_pythonpath([project_path]): + yield + finally: + sys.path[:] = old_path + sys.modules.clear() + sys.modules.update(old_modules) + working_set.__init__() + + @staticmethod + @contextlib.contextmanager + def paths_on_pythonpath(paths): + """ + Add the indicated paths to the head of the PYTHONPATH environment + variable so that subprocesses will also see the packages at + these paths. + + Do this in a context that restores the value on exit. + """ + nothing = object() + orig_pythonpath = os.environ.get('PYTHONPATH', nothing) + current_pythonpath = os.environ.get('PYTHONPATH', '') + try: + prefix = os.pathsep.join(paths) + to_join = filter(None, [prefix, current_pythonpath]) + new_path = os.pathsep.join(to_join) + if new_path: + os.environ['PYTHONPATH'] = new_path + yield + finally: + if orig_pythonpath is nothing: + os.environ.pop('PYTHONPATH', None) + else: + os.environ['PYTHONPATH'] = orig_pythonpath + + @staticmethod + def install_dists(dist): + """ + Install the requirements indicated by self.distribution and + return an iterable of the dists that were built. + """ + ir_d = dist.fetch_build_eggs(dist.install_requires) + tr_d = dist.fetch_build_eggs(dist.tests_require or []) + er_d = dist.fetch_build_eggs( + v for k, v in dist.extras_require.items() + if k.startswith(':') and evaluate_marker(k[1:]) + ) + return itertools.chain(ir_d, tr_d, er_d) + + def run(self): + installed_dists = self.install_dists(self.distribution) + + cmd = ' '.join(self._argv) + if self.dry_run: + self.announce('skipping "%s" (dry run)' % cmd) + return + + self.announce('running "%s"' % cmd) + + paths = map(operator.attrgetter('location'), installed_dists) + with self.paths_on_pythonpath(paths): + with self.project_on_sys_path(): + self.run_tests() + + def run_tests(self): + # 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): + module = self.test_suite.split('.')[0] + if module in _namespace_packages: + del_modules = [] + if module in sys.modules: + del_modules.append(module) + module += '.' + for name in sys.modules: + if name.startswith(module): + del_modules.append(name) + list(map(sys.modules.__delitem__, del_modules)) + + test = unittest.main( + None, None, self._argv, + testLoader=self._resolve_as_ep(self.test_loader), + testRunner=self._resolve_as_ep(self.test_runner), + exit=False, + ) + if not test.result.wasSuccessful(): + msg = 'Test failed: %s' % test.result + self.announce(msg, log.ERROR) + raise DistutilsError(msg) + + @property + def _argv(self): + return ['unittest'] + self.test_args + + @staticmethod + def _resolve_as_ep(val): + """ + Load the indicated attribute value, called, as a as if it were + specified as an entry point. + """ + if val is None: + return + parsed = EntryPoint.parse("x=" + val) + return parsed.resolve()() diff --git a/venv/lib/python3.7/site-packages/setuptools/command/upload.py b/venv/lib/python3.7/site-packages/setuptools/command/upload.py new file mode 100644 index 0000000..dd17f7a --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/command/upload.py @@ -0,0 +1,196 @@ +import io +import os +import hashlib +import getpass +import platform + +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 + +class upload(orig.upload): + """ + Override default upload behavior to obtain password + in a variety of different ways. + """ + 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() + ) + + 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 diff --git a/venv/lib/python3.7/site-packages/setuptools/command/upload_docs.py b/venv/lib/python3.7/site-packages/setuptools/command/upload_docs.py new file mode 100644 index 0000000..07aa564 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/command/upload_docs.py @@ -0,0 +1,206 @@ +# -*- coding: utf-8 -*- +"""upload_docs + +Implements a Distutils 'upload_docs' subcommand (upload documentation to +PyPI's pythonhosted.org). +""" + +from base64 import standard_b64encode +from distutils import log +from distutils.errors import DistutilsOptionError +import os +import socket +import zipfile +import tempfile +import shutil +import itertools +import functools + +from setuptools.extern import six +from setuptools.extern.six.moves import http_client, urllib + +from pkg_resources import iter_entry_points +from .upload import upload + + +def _encode(s): + errors = 'surrogateescape' if six.PY3 else 'strict' + return s.encode('utf-8', errors) + + +class upload_docs(upload): + # override the default repository as upload_docs isn't + # supported by Warehouse (and won't be). + DEFAULT_REPOSITORY = 'https://pypi.python.org/pypi/' + + description = 'Upload documentation to PyPI' + + user_options = [ + ('repository=', 'r', + "url of repository [default: %s]" % upload.DEFAULT_REPOSITORY), + ('show-response', None, + 'display full response text from server'), + ('upload-dir=', None, 'directory to upload'), + ] + boolean_options = upload.boolean_options + + def has_sphinx(self): + if self.upload_dir is None: + for ep in iter_entry_points('distutils.commands', 'build_sphinx'): + return True + + sub_commands = [('build_sphinx', has_sphinx)] + + def initialize_options(self): + upload.initialize_options(self) + self.upload_dir = None + self.target_dir = None + + def finalize_options(self): + upload.finalize_options(self) + if self.upload_dir is None: + if self.has_sphinx(): + build_sphinx = self.get_finalized_command('build_sphinx') + self.target_dir = build_sphinx.builder_target_dir + else: + build = self.get_finalized_command('build') + self.target_dir = os.path.join(build.build_base, 'docs') + else: + self.ensure_dirname('upload_dir') + self.target_dir = self.upload_dir + if 'pypi.python.org' in self.repository: + log.warn("Upload_docs command is deprecated. Use RTD instead.") + self.announce('Using upload directory %s' % self.target_dir) + + def create_zipfile(self, filename): + zip_file = zipfile.ZipFile(filename, "w") + try: + self.mkpath(self.target_dir) # just in case + for root, dirs, files in os.walk(self.target_dir): + if root == self.target_dir and not files: + tmpl = "no files found in upload directory '%s'" + raise DistutilsOptionError(tmpl % self.target_dir) + for name in files: + full = os.path.join(root, name) + relative = root[len(self.target_dir):].lstrip(os.path.sep) + dest = os.path.join(relative, name) + zip_file.write(full, dest) + finally: + zip_file.close() + + def run(self): + # Run sub commands + for cmd_name in self.get_sub_commands(): + self.run_command(cmd_name) + + tmp_dir = tempfile.mkdtemp() + name = self.distribution.metadata.get_name() + zip_file = os.path.join(tmp_dir, "%s.zip" % name) + try: + self.create_zipfile(zip_file) + self.upload_file(zip_file) + finally: + shutil.rmtree(tmp_dir) + + @staticmethod + def _build_part(item, sep_boundary): + key, values = item + title = '\nContent-Disposition: form-data; name="%s"' % key + # handle multiple entries for the same name + if not isinstance(values, list): + values = [values] + for value in values: + if isinstance(value, tuple): + title += '; filename="%s"' % value[0] + value = value[1] + else: + value = _encode(value) + yield sep_boundary + yield _encode(title) + yield b"\n\n" + yield value + if value and value[-1:] == b'\r': + yield b'\n' # write an extra newline (lurve Macs) + + @classmethod + def _build_multipart(cls, data): + """ + Build up the MIME payload for the POST data + """ + boundary = b'--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' + sep_boundary = b'\n--' + boundary + end_boundary = sep_boundary + b'--' + end_items = end_boundary, b"\n", + builder = functools.partial( + cls._build_part, + sep_boundary=sep_boundary, + ) + 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') + return b''.join(body_items), content_type + + def upload_file(self, filename): + with open(filename, 'rb') as f: + content = f.read() + meta = self.distribution.metadata + data = { + ':action': 'doc_upload', + 'name': meta.get_name(), + 'content': (os.path.basename(filename), content), + } + # set up the authentication + credentials = _encode(self.username + ':' + self.password) + credentials = standard_b64encode(credentials) + if six.PY3: + credentials = credentials.decode('ascii') + auth = "Basic " + credentials + + body, ct = self._build_multipart(data) + + msg = "Submitting documentation to %s" % (self.repository) + self.announce(msg, log.INFO) + + # build the Request + # We can't use urllib2 since we need to send the Basic + # auth right with the first request + schema, netloc, url, params, query, fragments = \ + urllib.parse.urlparse(self.repository) + assert not params and not query and not fragments + if schema == 'http': + conn = http_client.HTTPConnection(netloc) + elif schema == 'https': + conn = http_client.HTTPSConnection(netloc) + else: + raise AssertionError("unsupported schema " + schema) + + data = '' + try: + conn.connect() + conn.putrequest("POST", url) + content_type = ct + conn.putheader('Content-type', content_type) + conn.putheader('Content-length', str(len(body))) + conn.putheader('Authorization', auth) + conn.endheaders() + conn.send(body) + except socket.error as e: + self.announce(str(e), log.ERROR) + return + + r = conn.getresponse() + if r.status == 200: + msg = 'Server response (%s): %s' % (r.status, r.reason) + self.announce(msg, log.INFO) + elif r.status == 301: + location = r.getheader('Location') + if location is None: + location = 'https://pythonhosted.org/%s/' % meta.get_name() + msg = 'Upload successful. Visit %s' % location + self.announce(msg, log.INFO) + else: + msg = 'Upload failed (%s): %s' % (r.status, r.reason) + self.announce(msg, log.ERROR) + if self.show_response: + print('-' * 75, r.read(), '-' * 75) diff --git a/venv/lib/python3.7/site-packages/setuptools/config.py b/venv/lib/python3.7/site-packages/setuptools/config.py new file mode 100644 index 0000000..d1ac673 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/config.py @@ -0,0 +1,635 @@ +from __future__ import absolute_import, unicode_literals +import io +import os +import sys + +import warnings +import functools +from collections import defaultdict +from functools import partial +from functools import wraps +from importlib import import_module + +from distutils.errors import DistutilsOptionError, DistutilsFileError +from setuptools.extern.packaging.version import LegacyVersion, parse +from setuptools.extern.six import string_types, PY3 + + +__metaclass__ = type + + +def read_configuration( + filepath, find_others=False, ignore_option_errors=False): + """Read given configuration file and returns options from it as a dict. + + :param str|unicode filepath: Path to configuration file + to get options from. + + :param bool find_others: Whether to search for other configuration files + which could be on in various places. + + :param bool ignore_option_errors: Whether to silently ignore + options, values of which could not be resolved (e.g. due to exceptions + in directives such as file:, attr:, etc.). + If False exceptions are propagated as expected. + + :rtype: dict + """ + from setuptools.dist import Distribution, _Distribution + + filepath = os.path.abspath(filepath) + + if not os.path.isfile(filepath): + raise DistutilsFileError( + 'Configuration file %s does not exist.' % filepath) + + current_directory = os.getcwd() + os.chdir(os.path.dirname(filepath)) + + try: + dist = Distribution() + + filenames = dist.find_config_files() if find_others else [] + if filepath not in filenames: + filenames.append(filepath) + + _Distribution.parse_config_files(dist, filenames=filenames) + + handlers = parse_configuration( + dist, dist.command_options, + ignore_option_errors=ignore_option_errors) + + finally: + os.chdir(current_directory) + + return configuration_to_dict(handlers) + + +def _get_option(target_obj, key): + """ + Given a target object and option key, get that option from + the target object, either through a get_{key} method or + from an attribute directly. + """ + getter_name = 'get_{key}'.format(**locals()) + by_attribute = functools.partial(getattr, target_obj, key) + getter = getattr(target_obj, getter_name, by_attribute) + return getter() + + +def configuration_to_dict(handlers): + """Returns configuration data gathered by given handlers as a dict. + + :param list[ConfigHandler] handlers: Handlers list, + usually from parse_configuration() + + :rtype: dict + """ + config_dict = defaultdict(dict) + + for handler in handlers: + for option in handler.set_options: + value = _get_option(handler.target_obj, option) + config_dict[handler.section_prefix][option] = value + + return config_dict + + +def parse_configuration( + distribution, command_options, ignore_option_errors=False): + """Performs additional parsing of configuration options + for a distribution. + + Returns a list of used option handlers. + + :param Distribution distribution: + :param dict command_options: + :param bool ignore_option_errors: Whether to silently ignore + options, values of which could not be resolved (e.g. due to exceptions + in directives such as file:, attr:, etc.). + If False exceptions are propagated as expected. + :rtype: list + """ + options = ConfigOptionsHandler( + distribution, command_options, ignore_option_errors) + options.parse() + + meta = ConfigMetadataHandler( + distribution.metadata, command_options, ignore_option_errors, + distribution.package_dir) + meta.parse() + + return meta, options + + +class ConfigHandler: + """Handles metadata supplied in configuration files.""" + + section_prefix = None + """Prefix for config sections handled by this handler. + Must be provided by class heirs. + + """ + + aliases = {} + """Options aliases. + For compatibility with various packages. E.g.: d2to1 and pbr. + Note: `-` in keys is replaced with `_` by config parser. + + """ + + def __init__(self, target_obj, options, ignore_option_errors=False): + sections = {} + + section_prefix = self.section_prefix + for section_name, section_options in options.items(): + if not section_name.startswith(section_prefix): + continue + + section_name = section_name.replace(section_prefix, '').strip('.') + sections[section_name] = section_options + + self.ignore_option_errors = ignore_option_errors + self.target_obj = target_obj + self.sections = sections + self.set_options = [] + + @property + def parsers(self): + """Metadata item name to parser function mapping.""" + raise NotImplementedError( + '%s must provide .parsers property' % self.__class__.__name__) + + def __setitem__(self, option_name, value): + unknown = tuple() + target_obj = self.target_obj + + # Translate alias into real name. + option_name = self.aliases.get(option_name, option_name) + + current_value = getattr(target_obj, option_name, unknown) + + if current_value is unknown: + raise KeyError(option_name) + + if current_value: + # Already inhabited. Skipping. + return + + skip_option = False + parser = self.parsers.get(option_name) + if parser: + try: + value = parser(value) + + except Exception: + skip_option = True + if not self.ignore_option_errors: + raise + + if skip_option: + return + + setter = getattr(target_obj, 'set_%s' % option_name, None) + if setter is None: + setattr(target_obj, option_name, value) + else: + setter(value) + + self.set_options.append(option_name) + + @classmethod + def _parse_list(cls, value, separator=','): + """Represents value as a list. + + Value is split either by separator (defaults to comma) or by lines. + + :param value: + :param separator: List items separator character. + :rtype: list + """ + if isinstance(value, list): # _get_parser_compound case + return value + + if '\n' in value: + value = value.splitlines() + else: + value = value.split(separator) + + return [chunk.strip() for chunk in value if chunk.strip()] + + @classmethod + def _parse_dict(cls, value): + """Represents value as a dict. + + :param value: + :rtype: dict + """ + separator = '=' + result = {} + for line in cls._parse_list(value): + key, sep, val = line.partition(separator) + if sep != separator: + raise DistutilsOptionError( + 'Unable to parse option value to dict: %s' % value) + result[key.strip()] = val.strip() + + return result + + @classmethod + def _parse_bool(cls, value): + """Represents value as boolean. + + :param value: + :rtype: bool + """ + value = value.lower() + return value in ('1', 'true', 'yes') + + @classmethod + def _parse_file(cls, value): + """Represents value as a string, allowing including text + from nearest files using `file:` directive. + + Directive is sandboxed and won't reach anything outside + directory with setup.py. + + Examples: + file: LICENSE + file: README.rst, CHANGELOG.md, src/file.txt + + :param str value: + :rtype: str + """ + include_directive = 'file:' + + if not isinstance(value, string_types): + return value + + if not value.startswith(include_directive): + return value + + spec = value[len(include_directive):] + filepaths = (os.path.abspath(path.strip()) for path in spec.split(',')) + return '\n'.join( + cls._read_file(path) + for path in filepaths + if (cls._assert_local(path) or True) + and os.path.isfile(path) + ) + + @staticmethod + def _assert_local(filepath): + if not filepath.startswith(os.getcwd()): + raise DistutilsOptionError( + '`file:` directive can not access %s' % filepath) + + @staticmethod + def _read_file(filepath): + with io.open(filepath, encoding='utf-8') as f: + return f.read() + + @classmethod + def _parse_attr(cls, value, package_dir=None): + """Represents value as a module attribute. + + Examples: + attr: package.attr + attr: package.module.attr + + :param str value: + :rtype: str + """ + attr_directive = 'attr:' + if not value.startswith(attr_directive): + return value + + attrs_path = value.replace(attr_directive, '').strip().split('.') + attr_name = attrs_path.pop() + + module_name = '.'.join(attrs_path) + module_name = module_name or '__init__' + + parent_path = os.getcwd() + if package_dir: + if attrs_path[0] in package_dir: + # A custom path was specified for the module we want to import + custom_path = package_dir[attrs_path[0]] + parts = custom_path.rsplit('/', 1) + if len(parts) > 1: + parent_path = os.path.join(os.getcwd(), parts[0]) + module_name = parts[1] + else: + module_name = custom_path + 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:] + + return value + + @classmethod + def _get_parser_compound(cls, *parse_methods): + """Returns parser function to represents value as a list. + + Parses a value applying given methods one after another. + + :param parse_methods: + :rtype: callable + """ + def parse(value): + parsed = value + + for method in parse_methods: + parsed = method(parsed) + + return parsed + + return parse + + @classmethod + def _parse_section_to_dict(cls, section_options, values_parser=None): + """Parses section options into a dictionary. + + Optionally applies a given parser to values. + + :param dict section_options: + :param callable values_parser: + :rtype: dict + """ + value = {} + values_parser = values_parser or (lambda val: val) + for key, (_, val) in section_options.items(): + value[key] = values_parser(val) + return value + + def parse_section(self, section_options): + """Parses configuration file section. + + :param dict section_options: + """ + for (name, (_, value)) in section_options.items(): + try: + self[name] = value + + except KeyError: + pass # Keep silent for a new option may appear anytime. + + def parse(self): + """Parses configuration file items from one + or more related sections. + + """ + for section_name, section_options in self.sections.items(): + + method_postfix = '' + if section_name: # [section.option] variant + method_postfix = '_%s' % section_name + + section_parser_method = getattr( + self, + # Dots in section names are tranlsated into dunderscores. + ('parse_section%s' % method_postfix).replace('.', '__'), + None) + + if section_parser_method is None: + raise DistutilsOptionError( + 'Unsupported distribution option section: [%s.%s]' % ( + self.section_prefix, section_name)) + + section_parser_method(section_options) + + def _deprecated_config_handler(self, func, msg, warning_class): + """ this function will wrap around parameters that are deprecated + + :param msg: deprecation message + :param warning_class: class of warning exception to be raised + :param func: function to be wrapped around + """ + @wraps(func) + def config_handler(*args, **kwargs): + warnings.warn(msg, warning_class) + return func(*args, **kwargs) + + return config_handler + + +class ConfigMetadataHandler(ConfigHandler): + + section_prefix = 'metadata' + + aliases = { + 'home_page': 'url', + 'summary': 'description', + 'classifier': 'classifiers', + 'platform': 'platforms', + } + + strict_mode = False + """We need to keep it loose, to be partially compatible with + `pbr` and `d2to1` packages which also uses `metadata` section. + + """ + + def __init__(self, target_obj, options, ignore_option_errors=False, + package_dir=None): + super(ConfigMetadataHandler, self).__init__(target_obj, options, + ignore_option_errors) + self.package_dir = package_dir + + @property + def parsers(self): + """Metadata item name to parser function mapping.""" + parse_list = self._parse_list + parse_file = self._parse_file + parse_dict = self._parse_dict + + return { + 'platforms': parse_list, + 'keywords': parse_list, + 'provides': parse_list, + 'requires': self._deprecated_config_handler(parse_list, + "The requires parameter is deprecated, please use " + + "install_requires for runtime dependencies.", + DeprecationWarning), + 'obsoletes': parse_list, + 'classifiers': self._get_parser_compound(parse_file, parse_list), + 'license': parse_file, + 'description': parse_file, + 'long_description': parse_file, + 'version': self._parse_version, + 'project_urls': parse_dict, + } + + def _parse_version(self, value): + """Parses `version` option value. + + :param value: + :rtype: str + + """ + version = self._parse_file(value) + + if version != value: + version = version.strip() + # Be strict about versions loaded from file because it's easy to + # accidentally include newlines and other unintended content + if isinstance(parse(version), LegacyVersion): + tmpl = ( + 'Version loaded from {value} does not ' + 'comply with PEP 440: {version}' + ) + raise DistutilsOptionError(tmpl.format(**locals())) + + return version + + version = self._parse_attr(value, self.package_dir) + + if callable(version): + version = version() + + if not isinstance(version, string_types): + if hasattr(version, '__iter__'): + version = '.'.join(map(str, version)) + else: + version = '%s' % version + + return version + + +class ConfigOptionsHandler(ConfigHandler): + + section_prefix = 'options' + + @property + def parsers(self): + """Metadata item name to parser function mapping.""" + parse_list = self._parse_list + parse_list_semicolon = partial(self._parse_list, separator=';') + parse_bool = self._parse_bool + parse_dict = self._parse_dict + + return { + 'zip_safe': parse_bool, + 'use_2to3': parse_bool, + 'include_package_data': parse_bool, + 'package_dir': parse_dict, + 'use_2to3_fixers': parse_list, + 'use_2to3_exclude_fixers': parse_list, + 'convert_2to3_doctests': parse_list, + 'scripts': parse_list, + 'eager_resources': parse_list, + 'dependency_links': parse_list, + 'namespace_packages': parse_list, + 'install_requires': parse_list_semicolon, + 'setup_requires': parse_list_semicolon, + 'tests_require': parse_list_semicolon, + 'packages': self._parse_packages, + 'entry_points': self._parse_file, + 'py_modules': parse_list, + } + + def _parse_packages(self, value): + """Parses `packages` option value. + + :param value: + :rtype: list + """ + find_directives = ['find:', 'find_namespace:'] + trimmed_value = value.strip() + + if trimmed_value not in find_directives: + return self._parse_list(value) + + findns = trimmed_value == find_directives[1] + if findns and not PY3: + raise DistutilsOptionError( + 'find_namespace: directive is unsupported on Python < 3.3') + + # Read function arguments from a dedicated section. + find_kwargs = self.parse_section_packages__find( + self.sections.get('packages.find', {})) + + if findns: + from setuptools import find_namespace_packages as find_packages + else: + from setuptools import find_packages + + return find_packages(**find_kwargs) + + def parse_section_packages__find(self, section_options): + """Parses `packages.find` configuration file section. + + To be used in conjunction with _parse_packages(). + + :param dict section_options: + """ + section_data = self._parse_section_to_dict( + section_options, self._parse_list) + + valid_keys = ['where', 'include', 'exclude'] + + find_kwargs = dict( + [(k, v) for k, v in section_data.items() if k in valid_keys and v]) + + where = find_kwargs.get('where') + if where is not None: + find_kwargs['where'] = where[0] # cast list to single val + + return find_kwargs + + def parse_section_entry_points(self, section_options): + """Parses `entry_points` configuration file section. + + :param dict section_options: + """ + parsed = self._parse_section_to_dict(section_options, self._parse_list) + self['entry_points'] = parsed + + def _parse_package_data(self, section_options): + parsed = self._parse_section_to_dict(section_options, self._parse_list) + + root = parsed.get('*') + if root: + parsed[''] = root + del parsed['*'] + + return parsed + + def parse_section_package_data(self, section_options): + """Parses `package_data` configuration file section. + + :param dict section_options: + """ + self['package_data'] = self._parse_package_data(section_options) + + def parse_section_exclude_package_data(self, section_options): + """Parses `exclude_package_data` configuration file section. + + :param dict section_options: + """ + self['exclude_package_data'] = self._parse_package_data( + section_options) + + def parse_section_extras_require(self, section_options): + """Parses `extras_require` configuration file section. + + :param dict section_options: + """ + parse_list = partial(self._parse_list, separator=';') + self['extras_require'] = self._parse_section_to_dict( + section_options, parse_list) + + def parse_section_data_files(self, section_options): + """Parses `data_files` configuration file section. + + :param dict section_options: + """ + parsed = self._parse_section_to_dict(section_options, self._parse_list) + self['data_files'] = [(k, v) for k, v in parsed.items()] diff --git a/venv/lib/python3.7/site-packages/setuptools/dep_util.py b/venv/lib/python3.7/site-packages/setuptools/dep_util.py new file mode 100644 index 0000000..2931c13 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/dep_util.py @@ -0,0 +1,23 @@ +from distutils.dep_util import newer_group + +# yes, this is was almost entirely copy-pasted from +# 'newer_pairwise()', this is just another convenience +# function. +def newer_pairwise_group(sources_groups, targets): + """Walk both arguments in parallel, testing if each source group is newer + than its corresponding target. Returns a pair of lists (sources_groups, + targets) where sources is newer than target, according to the semantics + of 'newer_group()'. + """ + if len(sources_groups) != len(targets): + 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 = [] + n_targets = [] + for i in range(len(sources_groups)): + if newer_group(sources_groups[i], targets[i]): + n_sources.append(sources_groups[i]) + n_targets.append(targets[i]) + + return n_sources, n_targets diff --git a/venv/lib/python3.7/site-packages/setuptools/depends.py b/venv/lib/python3.7/site-packages/setuptools/depends.py new file mode 100644 index 0000000..45e7052 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/depends.py @@ -0,0 +1,186 @@ +import sys +import imp +import marshal +from distutils.version import StrictVersion +from imp import PKG_DIRECTORY, PY_COMPILED, PY_SOURCE, PY_FROZEN + +from .py33compat import Bytecode + + +__all__ = [ + 'Require', 'find_module', 'get_module_constant', 'extract_constant' +] + + +class Require: + """A prerequisite to building or installing a distribution""" + + def __init__(self, name, requested_version, module, homepage='', + attribute=None, format=None): + + if format is None and requested_version is not None: + format = StrictVersion + + if format is not None: + requested_version = format(requested_version) + if attribute is None: + attribute = '__version__' + + self.__dict__.update(locals()) + del self.self + + def full_name(self): + """Return full package/distribution name, w/version""" + if self.requested_version is not None: + return '%s-%s' % (self.name, self.requested_version) + return self.name + + def version_ok(self, version): + """Is 'version' sufficiently up-to-date?""" + return self.attribute is None or self.format is None or \ + str(version) != "unknown" and version >= self.requested_version + + def get_version(self, paths=None, default="unknown"): + """Get version number of installed module, 'None', or 'default' + + Search 'paths' for module. If not found, return 'None'. If found, + return the extracted version attribute, or 'default' if no version + attribute was specified, or the value cannot be determined without + importing the module. The version is formatted according to the + requirement's version format (if any), unless it is 'None' or the + supplied 'default'. + """ + + if self.attribute is None: + try: + f, p, i = find_module(self.module, paths) + if f: + f.close() + return default + except ImportError: + return None + + v = get_module_constant(self.module, self.attribute, default, paths) + + if v is not None and v is not default and self.format is not None: + return self.format(v) + + return v + + def is_present(self, paths=None): + """Return true if dependency is present on 'paths'""" + return self.get_version(paths) is not None + + def is_current(self, paths=None): + """Return true if dependency is present and up-to-date on 'paths'""" + version = self.get_version(paths) + if version is None: + return False + return self.version_ok(version) + + +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 == PKG_DIRECTORY: + parts = parts or ['__init__'] + paths = [path] + + elif parts: + raise ImportError("Can't find %r in %s" % (parts, module)) + + return info + + +def get_module_constant(module, symbol, default=-1, paths=None): + """Find 'module' by searching 'paths', and extract 'symbol' + + Return 'None' if 'module' does not exist on 'paths', or it does not define + 'symbol'. If the module defines 'symbol' as a constant, return the + constant. Otherwise, return 'default'.""" + + try: + f, path, (suffix, mode, kind) = find_module(module, paths) + except ImportError: + # Module doesn't exist + return None + + try: + if kind == PY_COMPILED: + f.read(8) # skip magic & date + code = marshal.load(f) + elif kind == PY_FROZEN: + code = imp.get_frozen_object(module) + 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() + + return extract_constant(code, symbol, default) + + +def extract_constant(code, symbol, default=-1): + """Extract the constant value of 'symbol' from 'code' + + If the name 'symbol' is bound to a constant value by the Python code + object 'code', return that value. If 'symbol' is bound to an expression, + return 'default'. Otherwise, return 'None'. + + Return value is based on the first assignment to 'symbol'. 'symbol' must + be a global, or at least a non-"fast" local in the code block. That is, + only 'STORE_NAME' and 'STORE_GLOBAL' opcodes are checked, and 'symbol' + must be present in 'code.co_names'. + """ + if symbol not in code.co_names: + # name's not there, can't possibly be an assignment + return None + + name_idx = list(code.co_names).index(symbol) + + STORE_NAME = 90 + STORE_GLOBAL = 97 + LOAD_CONST = 100 + + const = default + + for byte_code in Bytecode(code): + op = byte_code.opcode + arg = byte_code.arg + + if op == LOAD_CONST: + const = code.co_consts[arg] + elif arg == name_idx and (op == STORE_NAME or op == STORE_GLOBAL): + return const + else: + const = default + + +def _update_globals(): + """ + Patch the globals to remove the objects not available on some platforms. + + XXX it'd be better to test assertions about bytecode instead. + """ + + if not sys.platform.startswith('java') and sys.platform != 'cli': + return + incompatible = 'extract_constant', 'get_module_constant' + for name in incompatible: + del globals()[name] + __all__.remove(name) + + +_update_globals() diff --git a/venv/lib/python3.7/site-packages/setuptools/dist.py b/venv/lib/python3.7/site-packages/setuptools/dist.py new file mode 100644 index 0000000..7062ae8 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/dist.py @@ -0,0 +1,1147 @@ +# -*- coding: utf-8 -*- +__all__ = ['Distribution'] + +import re +import os +import warnings +import numbers +import distutils.log +import distutils.core +import distutils.cmd +import distutils.dist +import itertools + + +from collections import defaultdict +from email import message_from_file + +from distutils.errors import ( + DistutilsOptionError, DistutilsPlatformError, 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.six.moves import map, filter, filterfalse + +from . import SetuptoolsDeprecationWarning + +from setuptools.depends import Require +from setuptools import windows_support +from setuptools.monkey import get_unpatched +from setuptools.config import parse_configuration +import pkg_resources +from .py36compat import Distribution_parse_config_files + +__import__('setuptools.extern.packaging.specifiers') +__import__('setuptools.extern.packaging.version') + + +def _get_unpatched(cls): + warnings.warn("Do not call this function", DistDeprecationWarning) + return get_unpatched(cls) + + +def get_metadata_version(self): + mv = getattr(self, 'metadata_version', None) + + if mv is None: + if self.long_description_content_type or self.provides_extras: + mv = StrictVersion('2.1') + elif (self.maintainer is not None or + self.maintainer_email is not None or + getattr(self, 'python_requires', None) is not None): + mv = StrictVersion('1.2') + elif (self.provides or self.requires or self.obsoletes or + self.classifiers or self.download_url): + mv = StrictVersion('1.1') + else: + mv = StrictVersion('1.0') + + self.metadata_version = mv + + return mv + + +def read_pkg_file(self, file): + """Reads the metadata values from a file object.""" + msg = message_from_file(file) + + def _read_field(name): + value = msg[name] + if value == 'UNKNOWN': + return None + return value + + def _read_list(name): + values = msg.get_all(name, None) + if values == []: + return None + return values + + self.metadata_version = StrictVersion(msg['metadata-version']) + self.name = _read_field('name') + self.version = _read_field('version') + self.description = _read_field('summary') + # we are filling author only. + self.author = _read_field('author') + self.maintainer = None + self.author_email = _read_field('author-email') + self.maintainer_email = None + self.url = _read_field('home-page') + self.license = _read_field('license') + + if 'download-url' in msg: + self.download_url = _read_field('download-url') + else: + self.download_url = None + + self.long_description = _read_field('description') + self.description = _read_field('summary') + + if 'keywords' in msg: + self.keywords = _read_field('keywords').split(',') + + self.platforms = _read_list('platform') + self.classifiers = _read_list('classifier') + + # PEP 314 - these fields only exist in 1.1 + if self.metadata_version == StrictVersion('1.1'): + self.requires = _read_list('requires') + self.provides = _read_list('provides') + self.obsoletes = _read_list('obsoletes') + else: + self.requires = None + self.provides = None + self.obsoletes = None + + +# Based on Python 3.5 version +def write_pkg_file(self, file): + """Write the PKG-INFO format data to a file object. + """ + version = self.get_metadata_version() + + if six.PY2: + def write_field(key, value): + file.write("%s: %s\n" % (key, self._encode_field(value))) + else: + def write_field(key, value): + file.write("%s: %s\n" % (key, value)) + + + write_field('Metadata-Version', str(version)) + write_field('Name', self.get_name()) + write_field('Version', self.get_version()) + write_field('Summary', self.get_description()) + write_field('Home-page', self.get_url()) + + if version < StrictVersion('1.2'): + write_field('Author', self.get_contact()) + write_field('Author-email', self.get_contact_email()) + else: + optional_fields = ( + ('Author', 'author'), + ('Author-email', 'author_email'), + ('Maintainer', 'maintainer'), + ('Maintainer-email', 'maintainer_email'), + ) + + for field, attr in optional_fields: + attr_val = getattr(self, attr) + + if attr_val is not None: + write_field(field, attr_val) + + write_field('License', self.get_license()) + 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) + + long_desc = rfc822_escape(self.get_long_description()) + write_field('Description', long_desc) + + keywords = ','.join(self.get_keywords()) + if keywords: + write_field('Keywords', keywords) + + if version >= StrictVersion('1.2'): + for platform in self.get_platforms(): + write_field('Platform', platform) + else: + self._write_list(file, 'Platform', self.get_platforms()) + + self._write_list(file, 'Classifier', self.get_classifiers()) + + # PEP 314 + self._write_list(file, 'Requires', self.get_requires()) + self._write_list(file, 'Provides', self.get_provides()) + self._write_list(file, 'Obsoletes', self.get_obsoletes()) + + # Setuptools specific for PEP 345 + if hasattr(self, 'python_requires'): + write_field('Requires-Python', self.python_requires) + + # PEP 566 + if self.long_description_content_type: + write_field( + 'Description-Content-Type', + self.long_description_content_type + ) + if self.provides_extras: + for extra in self.provides_extras: + write_field('Provides-Extra', extra) + + +sequence = tuple, list + + +def check_importable(dist, attr, value): + try: + ep = pkg_resources.EntryPoint.parse('x=' + value) + assert not ep.extras + except (TypeError, ValueError, AttributeError, AssertionError): + raise DistutilsSetupError( + "%r must be importable 'module:attrs' string (got %r)" + % (attr, value) + ) + + +def assert_string_list(dist, attr, value): + """Verify that value is a string list or None""" + try: + assert ''.join(value) != value + except (TypeError, ValueError, AttributeError, AssertionError): + raise DistutilsSetupError( + "%r must be a list of strings (got %r)" % (attr, value) + ) + + +def check_nsp(dist, attr, value): + """Verify that namespace packages are valid""" + ns_packages = value + assert_string_list(dist, attr, ns_packages) + for nsp in ns_packages: + if not dist.has_contents_for(nsp): + raise DistutilsSetupError( + "Distribution contains no modules or packages for " + + "namespace package %r" % nsp + ) + parent, sep, child = nsp.rpartition('.') + if parent and parent not in ns_packages: + distutils.log.warn( + "WARNING: %r is declared as a package namespace, but %r" + " is not: please correct this in setup.py", nsp, parent + ) + + +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): + raise DistutilsSetupError( + "'extras_require' must be a dictionary whose values are " + "strings or lists of strings containing valid project/version " + "requirement specifiers." + ) + + +def _check_extra(extra, reqs): + name, sep, marker = extra.partition(':') + if marker and pkg_resources.invalid_marker(marker): + raise DistutilsSetupError("Invalid environment marker: " + marker) + list(pkg_resources.parse_requirements(reqs)) + + +def assert_bool(dist, attr, value): + """Verify that value is True, False, 0, or 1""" + if bool(value) != value: + tmpl = "{attr!r} must be a boolean value (got {value!r})" + raise DistutilsSetupError(tmpl.format(attr=attr, value=value)) + + +def check_requirements(dist, attr, value): + """Verify that install_requires is a valid requirements list""" + try: + list(pkg_resources.parse_requirements(value)) + if isinstance(value, (dict, set)): + raise TypeError("Unordered types are not allowed") + except (TypeError, ValueError) as error: + tmpl = ( + "{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)) + + +def check_specifier(dist, attr, value): + """Verify that value is a valid version specifier""" + try: + packaging.specifiers.SpecifierSet(value) + except packaging.specifiers.InvalidSpecifier as error: + tmpl = ( + "{attr!r} must be a string " + "containing valid version specifiers; {error}" + ) + raise DistutilsSetupError(tmpl.format(attr=attr, error=error)) + + +def check_entry_points(dist, attr, value): + """Verify that entry_points map is parseable""" + try: + pkg_resources.EntryPoint.parse_map(value) + except ValueError as e: + raise DistutilsSetupError(e) + + +def check_test_suite(dist, attr, value): + if not isinstance(value, six.string_types): + raise DistutilsSetupError("test_suite must be a string") + + +def check_package_data(dist, attr, value): + """Verify that value is a dictionary of package names to glob lists""" + if isinstance(value, dict): + for k, v in value.items(): + if not isinstance(k, str): + break + try: + iter(v) + except TypeError: + break + else: + return + raise DistutilsSetupError( + attr + " must be a dictionary mapping package names to lists of " + "wildcard patterns" + ) + + +def check_packages(dist, attr, value): + for pkgname in value: + if not re.match(r'\w+(\.\w+)*', pkgname): + distutils.log.warn( + "WARNING: %r not a valid package name; please use only " + ".-separated package names in setup.py", pkgname + ) + + +_Distribution = get_unpatched(distutils.core.Distribution) + + +class Distribution(Distribution_parse_config_files, _Distribution): + """Distribution with support for features, tests, and package data + + This is an enhanced version of 'distutils.dist.Distribution' that + effectively adds the following new optional keyword arguments to 'setup()': + + 'install_requires' -- a string or sequence of strings specifying project + versions that the distribution requires when installed, in the format + used by 'pkg_resources.require()'. They will be installed + automatically when the package is installed. If you wish to use + packages that are not available in PyPI, or want to give your users an + alternate download location, you can add a 'find_links' option to the + '[easy_install]' section of your project's 'setup.cfg' file, and then + setuptools will scan the listed web pages for links that satisfy the + requirements. + + 'extras_require' -- a dictionary mapping names of optional "extras" to the + additional requirement(s) that using those extras incurs. For example, + this:: + + extras_require = dict(reST = ["docutils>=0.3", "reSTedit"]) + + indicates that the distribution can optionally provide an extra + capability called "reST", but it can only be used if docutils and + reSTedit are installed. If the user installs your package using + 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 + would be used on a 'unittest.py' command line. That is, it is the + dotted name of an object to import and call to generate a test suite. + + 'package_data' -- a dictionary mapping package names to lists of filenames + or globs to use to find data files contained in the named packages. + If the dictionary has filenames or globs listed under '""' (the empty + string), those names will be searched for in every package, in addition + to any names for the specific package. Data files found using these + names/globs will be installed along with the package, in the same + location as the package. Note that globs are allowed to reference + the contents of non-package subdirectories, as long as you use '/' as + a path separator. (Globs are automatically converted to + platform-specific paths at runtime.) + + In addition to these new keywords, this class also has several new methods + 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. + """ + + _DISTUTILS_UNSUPPORTED_METADATA = { + 'long_description_content_type': None, + 'project_urls': dict, + 'provides_extras': set, + } + + _patched_dist = None + + def patch_missing_pkg_info(self, attrs): + # Fake up a replacement for the data that would normally come from + # PKG-INFO, but which might not yet be built if this is a fresh + # checkout. + # + if not attrs or 'name' not in attrs or 'version' not in attrs: + return + key = pkg_resources.safe_name(str(attrs['name'])).lower() + dist = pkg_resources.working_set.by_key.get(key) + if dist is not None and not dist.has_metadata('PKG-INFO'): + dist._version = pkg_resources.safe_version(str(attrs['version'])) + self._patched_dist = dist + + def __init__(self, attrs=None): + have_package_data = hasattr(self, "package_data") + 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) + self.patch_missing_pkg_info(attrs) + self.dependency_links = attrs.pop('dependency_links', []) + self.setup_requires = attrs.pop('setup_requires', []) + for ep in pkg_resources.iter_entry_points('distutils.setup_keywords'): + vars(self).setdefault(ep.name, None) + _Distribution.__init__(self, { + k: v for k, v in attrs.items() + if k not in self._DISTUTILS_UNSUPPORTED_METADATA + }) + + # Fill-in missing metadata fields not supported by distutils. + # Note some fields may have been set by other tools (e.g. pbr) + # above; they are taken preferrentially to setup() arguments + for option, default in self._DISTUTILS_UNSUPPORTED_METADATA.items(): + for source in self.metadata.__dict__, attrs: + if option in source: + value = source[option] + break + else: + 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) + + if self.metadata.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 + 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 + ) + self._finalize_requires() + + def _finalize_requires(self): + """ + Set `metadata.python_requires` and fix environment markers + in `install_requires` and `extras_require`. + """ + if getattr(self, 'python_requires', None): + self.metadata.python_requires = self.python_requires + + if getattr(self, 'extras_require', None): + for extra in self.extras_require.keys(): + # Since this gets called multiple times at points where the + # keys have become 'converted' extras, ensure that we are only + # truly adding extras we haven't seen before here. + extra = extra.split(':')[0] + if extra: + self.metadata.provides_extras.add(extra) + + self._convert_extras_requirements() + self._move_install_requirements_markers() + + def _convert_extras_requirements(self): + """ + Convert requirements in `extras_require` of the form + `"extra": ["barbazquux; {marker}"]` to + `"extra:{marker}": ["barbazquux"]`. + """ + spec_ext_reqs = getattr(self, 'extras_require', None) or {} + self._tmp_extras_require = defaultdict(list) + for section, v in spec_ext_reqs.items(): + # Do not strip empty sections. + self._tmp_extras_require[section] + for r in pkg_resources.parse_requirements(v): + suffix = self._suffix_for(r) + self._tmp_extras_require[section + suffix].append(r) + + @staticmethod + def _suffix_for(req): + """ + For a requirement, return the 'extras_require' suffix for + that requirement. + """ + return ':' + str(req.marker) if req.marker else '' + + def _move_install_requirements_markers(self): + """ + Move requirements in `install_requires` that are using environment + markers `extras_require`. + """ + + # divide the install_requires into two sets, simple ones still + # handled by install_requires and more complex ones handled + # by extras_require. + + def is_simple_req(req): + return not req.marker + + spec_inst_reqs = getattr(self, 'install_requires', None) or () + inst_reqs = list(pkg_resources.parse_requirements(spec_inst_reqs)) + simple_reqs = filter(is_simple_req, inst_reqs) + complex_reqs = filterfalse(is_simple_req, inst_reqs) + self.install_requires = list(map(str, simple_reqs)) + + for r in complex_reqs: + self._tmp_extras_require[':' + str(r.marker)].append(r) + self.extras_require = dict( + (k, [str(r) for r in map(self._clean_req, v)]) + for k, v in self._tmp_extras_require.items() + ) + + def _clean_req(self, req): + """ + Given a Requirement, remove environment markers and return it. + """ + req.marker = None + return req + + def parse_config_files(self, filenames=None, ignore_option_errors=False): + """Parses configuration files from various levels + and loads configuration. + + """ + _Distribution.parse_config_files(self, filenames=filenames) + + parse_configuration(self, self.command_options, + 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( + pkg_resources.parse_requirements(requires), + installer=self.fetch_build_egg, + replace_conflicting=True, + ) + for dist in resolved_dists: + pkg_resources.working_set.add(dist, replace=True) + return resolved_dists + + def finalize_options(self): + _Distribution.finalize_options(self) + if self.features: + self._set_global_opts_from_features() + + 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) + 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 = [ + os.path.abspath(p) + for p in self.convert_2to3_doctests + ] + else: + self.convert_2to3_doctests = [] + + def get_egg_cache_dir(self): + egg_cache_dir = os.path.join(os.curdir, '.eggs') + if not os.path.exists(egg_cache_dir): + os.mkdir(egg_cache_dir) + windows_support.hide_file(egg_cache_dir) + readme_txt_filename = os.path.join(egg_cache_dir, 'README.txt') + with open(readme_txt_filename, 'w') as f: + f.write('This directory contains eggs that were downloaded ' + 'by setuptools to build, test, and run plug-ins.\n\n') + f.write('This directory caches those eggs to prevent ' + 'repeated downloads.\n\n') + f.write('However, it is safe to delete this directory.\n\n') + + return egg_cache_dir + + 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) + + def get_command_class(self, command): + """Pluggable version of get_command_class()""" + if command in self.cmdclass: + return self.cmdclass[command] + + eps = pkg_resources.iter_entry_points('distutils.commands', command) + for ep in eps: + ep.require(installer=self.fetch_build_egg) + self.cmdclass[command] = cmdclass = ep.load() + return cmdclass + else: + return _Distribution.get_command_class(self, command) + + def print_commands(self): + for ep in pkg_resources.iter_entry_points('distutils.commands'): + if ep.name not in self.cmdclass: + # don't require extras as the commands won't be invoked + cmdclass = ep.resolve() + self.cmdclass[ep.name] = cmdclass + return _Distribution.print_commands(self) + + def get_command_list(self): + for ep in pkg_resources.iter_entry_points('distutils.commands'): + if ep.name not in self.cmdclass: + # don't require extras as the commands won't be invoked + cmdclass = ep.resolve() + 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 + + For example, 'dist.exclude(py_modules=["x"])' would add 'x' to + the distribution's 'py_modules' attribute, if it was not already + there. + + Currently, this method only supports inclusion for attributes that are + lists or tuples. If you need to add support for adding to other + attributes in this or a subclass, you can add an '_include_X' method, + where 'X' is the name of the attribute. The method will be called with + the value passed to 'include()'. So, 'dist.include(foo={"bar":"baz"})' + will try to call 'dist._include_foo({"bar":"baz"})', which can then + handle whatever special inclusion logic is needed. + """ + for k, v in attrs.items(): + include = getattr(self, '_include_' + k, None) + if include: + include(v) + else: + self._include_misc(k, v) + + def exclude_package(self, package): + """Remove packages, modules, and extensions in named package""" + + pfx = package + '.' + if self.packages: + self.packages = [ + p for p in self.packages + if p != package and not p.startswith(pfx) + ] + + if self.py_modules: + self.py_modules = [ + p for p in self.py_modules + if p != package and not p.startswith(pfx) + ] + + if self.ext_modules: + self.ext_modules = [ + p for p in self.ext_modules + if p.name != package and not p.name.startswith(pfx) + ] + + def has_contents_for(self, package): + """Return true if 'exclude_package(package)' would do something""" + + pfx = package + '.' + + for p in self.iter_distribution_names(): + if p == package or p.startswith(pfx): + return True + + def _exclude_misc(self, name, value): + """Handle 'exclude()' for list/tuple attrs without a special handler""" + if not isinstance(value, sequence): + raise DistutilsSetupError( + "%s: setting must be a list or tuple (%r)" % (name, value) + ) + try: + old = getattr(self, name) + except AttributeError: + raise DistutilsSetupError( + "%s: No such distribution setting" % name + ) + if old is not None and not isinstance(old, sequence): + raise DistutilsSetupError( + name + ": this setting cannot be changed via include/exclude" + ) + elif old: + setattr(self, name, [item for item in old if item not in value]) + + def _include_misc(self, name, value): + """Handle 'include()' for list/tuple attrs without a special handler""" + + if not isinstance(value, sequence): + raise DistutilsSetupError( + "%s: setting must be a list (%r)" % (name, value) + ) + try: + old = getattr(self, name) + except AttributeError: + raise DistutilsSetupError( + "%s: No such distribution setting" % name + ) + if old is None: + setattr(self, name, value) + elif not isinstance(old, sequence): + raise DistutilsSetupError( + name + ": this setting cannot be changed via include/exclude" + ) + else: + new = [item for item in value if item not in old] + setattr(self, name, old + new) + + def exclude(self, **attrs): + """Remove items from distribution that are named in keyword arguments + + For example, 'dist.exclude(py_modules=["x"])' would remove 'x' from + the distribution's 'py_modules' attribute. Excluding packages uses + the 'exclude_package()' method, so all of the package's contained + packages, modules, and extensions are also excluded. + + Currently, this method only supports exclusion from attributes that are + lists or tuples. If you need to add support for excluding from other + attributes in this or a subclass, you can add an '_exclude_X' method, + where 'X' is the name of the attribute. The method will be called with + the value passed to 'exclude()'. So, 'dist.exclude(foo={"bar":"baz"})' + will try to call 'dist._exclude_foo({"bar":"baz"})', which can then + handle whatever special exclusion logic is needed. + """ + for k, v in attrs.items(): + exclude = getattr(self, '_exclude_' + k, None) + if exclude: + exclude(v) + else: + self._exclude_misc(k, v) + + def _exclude_packages(self, packages): + if not isinstance(packages, sequence): + raise DistutilsSetupError( + "packages: setting must be a list or tuple (%r)" % (packages,) + ) + list(map(self.exclude_package, packages)) + + def _parse_command_opts(self, parser, args): + # Remove --with-X/--without-X options when processing command args + self.global_options = self.__class__.global_options + self.negative_opt = self.__class__.negative_opt + + # First, expand any aliases + command = args[0] + aliases = self.get_option_dict('aliases') + while command in aliases: + src, alias = aliases[command] + del aliases[command] # ensure each alias can expand only once! + import shlex + args[:1] = shlex.split(alias, True) + command = args[0] + + nargs = _Distribution._parse_command_opts(self, parser, args) + + # Handle commands that want to consume all remaining arguments + cmd_class = self.get_command_class(command) + if getattr(cmd_class, 'command_consumes_arguments', None): + self.get_option_dict(command)['args'] = ("command line", nargs) + if nargs is not None: + return [] + + return nargs + + def get_cmdline_options(self): + """Return a '{cmd: {opt:val}}' map of all command-line options + + Option names are all long, but do not include the leading '--', and + contain dashes rather than underscores. If the option doesn't take + an argument (e.g. '--quiet'), the 'val' is 'None'. + + Note that options provided by config files are intentionally excluded. + """ + + d = {} + + for cmd, opts in self.command_options.items(): + + for opt, (src, val) in opts.items(): + + if src != "command line": + continue + + opt = opt.replace('_', '-') + + if val == 0: + cmdobj = self.get_command_obj(cmd) + neg_opt = self.negative_opt.copy() + neg_opt.update(getattr(cmdobj, 'negative_opt', {})) + for neg, pos in neg_opt.items(): + if pos == opt: + opt = neg + val = None + break + else: + raise AssertionError("Shouldn't be able to get here") + + elif val == 1: + val = None + + d.setdefault(cmd, {})[opt] = val + + return d + + def iter_distribution_names(self): + """Yield all packages, modules, and extension names in distribution""" + + for pkg in self.packages or (): + yield pkg + + for module in self.py_modules or (): + yield module + + for ext in self.ext_modules or (): + if isinstance(ext, tuple): + name, buildinfo = ext + else: + name = ext.name + if name.endswith('module'): + name = name[:-6] + yield name + + def handle_display_options(self, option_order): + """If there were any non-global "display-only" options + (--help-commands or the metadata display options) on the command + line, display the requested info and return true; else return + false. + """ + import sys + + if six.PY2 or self.help_commands: + return _Distribution.handle_display_options(self, option_order) + + # Stdout may be StringIO (e.g. in tests) + import io + if not isinstance(sys.stdout, io.TextIOWrapper): + return _Distribution.handle_display_options(self, option_order) + + # Don't wrap stdout if utf-8 is already the encoding. Provides + # workaround for #334. + if sys.stdout.encoding.lower() in ('utf-8', 'utf8'): + return _Distribution.handle_display_options(self, option_order) + + # Print metadata in UTF-8 no matter the platform + encoding = sys.stdout.encoding + errors = sys.stdout.errors + newline = sys.platform != 'win32' and '\n' or None + line_buffering = sys.stdout.line_buffering + + sys.stdout = io.TextIOWrapper( + sys.stdout.detach(), 'utf-8', errors, newline, line_buffering) + try: + return _Distribution.handle_display_options(self, option_order) + finally: + sys.stdout = io.TextIOWrapper( + 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.7/site-packages/setuptools/extension.py b/venv/lib/python3.7/site-packages/setuptools/extension.py new file mode 100644 index 0000000..2946889 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/extension.py @@ -0,0 +1,57 @@ +import re +import functools +import distutils.core +import distutils.errors +import distutils.extension + +from setuptools.extern.six.moves import map + +from .monkey import get_unpatched + + +def _have_cython(): + """ + Return True if Cython can be imported. + """ + cython_impl = 'Cython.Distutils.build_ext' + try: + # from (cython_impl) import build_ext + __import__(cython_impl, fromlist=['build_ext']).build_ext + return True + except Exception: + pass + return False + + +# for compatibility +have_pyrex = _have_cython + +_Extension = get_unpatched(distutils.core.Extension) + + +class Extension(_Extension): + """Extension that uses '.c' files in place of '.pyx' files""" + + def __init__(self, name, sources, *args, **kw): + # The *args is needed for compatibility as calls may use positional + # arguments. py_limited_api may be set only via keyword. + self.py_limited_api = kw.pop("py_limited_api", False) + _Extension.__init__(self, name, sources, *args, **kw) + + def _convert_pyx_sources_to_lang(self): + """ + Replace sources with .pyx extensions to sources with the target + language extension. This mechanism allows language authors to supply + pre-converted sources but to prefer the .pyx sources. + """ + if _have_cython(): + # the build has Cython, so allow it to compile the .pyx files + return + lang = self.language or '' + target_ext = '.cpp' if lang.lower() == 'c++' else '.c' + sub = functools.partial(re.sub, '.pyx$', target_ext) + self.sources = list(map(sub, self.sources)) + + +class Library(Extension): + """Just like a regular Extension, but built as a library instead""" diff --git a/venv/lib/python3.7/site-packages/setuptools/extern/__init__.py b/venv/lib/python3.7/site-packages/setuptools/extern/__init__.py new file mode 100644 index 0000000..cb2fa32 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/extern/__init__.py @@ -0,0 +1,73 @@ +import sys + + +class VendorImporter: + """ + A PEP 302 meta path importer for finding optionally-vendored + or otherwise naturally-installed packages from root_name. + """ + + def __init__(self, root_name, vendored_names=(), vendor_pkg=None): + self.root_name = root_name + self.vendored_names = set(vendored_names) + self.vendor_pkg = vendor_pkg or root_name.replace('extern', '_vendor') + + @property + def search_path(self): + """ + Search first the vendor package then as a natural package. + """ + yield self.vendor_pkg + '.' + yield '' + + def find_module(self, fullname, path=None): + """ + Return self when fullname starts with root_name and the + target module is one vendored through this importer. + """ + root, base, target = fullname.partition(self.root_name + '.') + if root: + return + if not any(map(target.startswith, self.vendored_names)): + return + return self + + def load_module(self, fullname): + """ + Iterate over the search path to locate and load fullname. + """ + root, base, target = fullname.partition(self.root_name + '.') + for prefix in self.search_path: + try: + extant = prefix + target + __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 + else: + raise ImportError( + "The '{target}' package is required; " + "normally this is bundled with this package so if you get " + "this warning, consult the packager of your " + "distribution.".format(**locals()) + ) + + def install(self): + """ + Install this importer into sys.meta_path if not already present. + """ + if self not in sys.meta_path: + sys.meta_path.append(self) + + +names = 'six', 'packaging', 'pyparsing', +VendorImporter(__name__, names, 'setuptools._vendor').install() diff --git a/venv/lib/python3.7/site-packages/setuptools/extern/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/setuptools/extern/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fdbe5c66986fb0678a7b2bf41a1151dd93b13794 GIT binary patch literal 2429 zcmZ`)TW=dh6rS0e?TwRG6-sD<Xe1ED617Xqtx!;*tq=l5RZ|tPidGxXINoHvyPX*) zv01<1h^LA--kV2$2mfMTdFo%_iF0OcCvDVO&Dq(V+nMuy=bLX=S3?5j*;_kL{%H{M zFMceF2aP*WRT~T^oTj8pz9Zb>?lIx+%;{3@bsa&4D;)06+~?j2p)hWnw1O8fhivuG zE{Y3{J5UuGL0~rNI-GW0zQ#T7AJeWUd>-)HF`3bBz%TGRZ@}Lg5BbV5>DGCZufn^* zUD)BGS$ixpp3CotMJ~0FljD#<`G!5X|A5`ReuE8#j#&}w0ZZmXSU;DnpJY7Ac3EEN zB+ueB9bY@J3khx)fFZda2zi(&!LnG7q#cuFN<%|%ShBYt?+V5GG9NOT=Q_&bp=jIL zf5V|Ma9Hq-^)6KPKA4i0BqExY&J0^l=@y$MeeQC~of8NCc$~n|+^udPj^Id{sYR7< zE#EYjI~i9AZPpfE+ufC^Nl~P6PnfXkh>HE)mS;RA(!TUzcUeONC=-cLSo7aOr;y1( ztVQP_mYsf{av@b`IOy~~DxzDHTYJ|JZ}#~_eR}gi-Z;{e;dLmxS?5uwNQ!Iopj`Xp zvz@{IXlJ(rj*SYP=czi|tPazOq9jXn6t#=7sV_c|e<}b&Xh1_c*?9aCs_n(N9>p<G z@a;fFZmD%JCD{YgZIH)EKF3-lh&TDsB7&sY7P0IN0D7r318`Xtq6L)rD`T-@@dEHg zPX#J2VQAZstroQbgctgK8b`STpJqkbeIg{?1$56c!Ee&Zl~+!6W?&D&z=A<o(&cmb z0BYdjC?4*FK5?h+)SLRHD>u2bO|+xk(%<u7gg*m9sgLn*X$ds>V|nz4fQZZ(vVa}p zG5e!5MZPlNv($<mCXgXZZm~Gy7>?z97_=)i8|HkJ3YI9AXN&MbF6e>GN4o=fL(d}3 zPJ<>_;TT)3z%&ZjE5U@bR5Wg!jg32u3lmmupcj^)t-yxX)E9ml55s9ZbkTS_u@WYz zoH`eNOzo)hbOSb4O)$h?rye|)pq_)_%!D3t3QHX-Cdpl>>KT}GFgOUrQ2~K>?vY;~ zP5to~rC)j*WEub@!HiO(y*<ASE|Y1ktl2ibjsF7f?EA7?^?pUl+BP7rYx|)rD6p53 zU&zzVpP~K)f4RF??-Sjakw58-{tjXbtoA2AETQ=xBmy#*<p)9{W&pCKxz#+Kvo!Bv zHzJzmF<&D83O+6R0x3B8>k%w*^|vav)2oXVK+L6hI!dJAU$QKhL)61L;)?BzGLEWf zX=G_I*GHyumh{;;A2B45?K+HQ2HN`}>*bjmrByD@$Aj$J(US2*X_@SdkS^`5Rwyrm zdzFM?R+$hq!76$bffSBG`YOzoX+k6v%mSh5=Vqn48tzM(OA~<h4`Xctj7q9n^(uqk zz@<?|Br-<6iR%Z26#eALig281;Azg!aSbCn=i0k4No|55-a2hkht}Z<X&8j?_UIZ7 z9ft<)Irg1d;w5!MG%WkBK%*oYBw)WL*YW)vZiy4%m%U`2$-`4FRM*qXiO7-+XaEsv z<6UTF2_eaH&Eiywn2#A8Rf$ZWQevy+%C})((^$?iL0lA|%CAwq+WZ!{1G6f{^FYVf zUs1gIpq67J2|^0M;w^wu1ULew6^PJoM$ywzY()ybYEi`VUKB~pW>YU@UI?kj5~(0B zqj?X_RWum6GX_OjVqT-HS~aM9o)h}bdf2SLV|!XIP$)S<fx=rI$O+9csFi}|<kIPV m)?VJkHavE+@zHxFKfrxn=YXl-u1@wf-dy&otGjFWJo-PC)P(#1 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/glibc.py b/venv/lib/python3.7/site-packages/setuptools/glibc.py new file mode 100644 index 0000000..a134591 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/glibc.py @@ -0,0 +1,86 @@ +# 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.7/site-packages/setuptools/glob.py b/venv/lib/python3.7/site-packages/setuptools/glob.py new file mode 100644 index 0000000..9d7cbc5 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/glob.py @@ -0,0 +1,174 @@ +""" +Filename globbing utility. Mostly a copy of `glob` from Python 3.5. + +Changes include: + * `yield from` and PEP3102 `*` removed. + * Hidden files are not ignored. +""" + +import os +import re +import fnmatch + +__all__ = ["glob", "iglob", "escape"] + + +def glob(pathname, recursive=False): + """Return a list of paths matching a pathname pattern. + + The pattern may contain simple shell-style wildcards a la + fnmatch. However, unlike fnmatch, filenames starting with a + dot are special cases that are not matched by '*' and '?' + patterns. + + If recursive is true, the pattern '**' will match any files and + zero or more directories and subdirectories. + """ + return list(iglob(pathname, recursive=recursive)) + + +def iglob(pathname, recursive=False): + """Return an iterator which yields the paths matching a pathname pattern. + + The pattern may contain simple shell-style wildcards a la + fnmatch. However, unlike fnmatch, filenames starting with a + dot are special cases that are not matched by '*' and '?' + patterns. + + If recursive is true, the pattern '**' will match any files and + zero or more directories and subdirectories. + """ + it = _iglob(pathname, recursive) + if recursive and _isrecursive(pathname): + s = next(it) # skip empty string + assert not s + return it + + +def _iglob(pathname, recursive): + dirname, basename = os.path.split(pathname) + if not has_magic(pathname): + if basename: + if os.path.lexists(pathname): + yield pathname + else: + # Patterns ending with a slash should match only directories + if os.path.isdir(dirname): + yield pathname + return + if not dirname: + if recursive and _isrecursive(basename): + for x in glob2(dirname, basename): + yield x + else: + for x in glob1(dirname, basename): + yield x + return + # `os.path.split()` returns the argument itself as a dirname if it is a + # drive or UNC path. Prevent an infinite recursion if a drive or UNC path + # contains magic characters (i.e. r'\\?\C:'). + if dirname != pathname and has_magic(dirname): + dirs = _iglob(dirname, recursive) + else: + dirs = [dirname] + if has_magic(basename): + if recursive and _isrecursive(basename): + glob_in_dir = glob2 + else: + glob_in_dir = glob1 + else: + glob_in_dir = glob0 + for dirname in dirs: + for name in glob_in_dir(dirname, basename): + yield os.path.join(dirname, name) + + +# These 2 helper functions non-recursively glob inside a literal directory. +# They return a list of basenames. `glob1` accepts a pattern while `glob0` +# takes a literal basename (so it only has to check for its existence). + + +def glob1(dirname, pattern): + if not dirname: + if isinstance(pattern, bytes): + dirname = os.curdir.encode('ASCII') + else: + dirname = os.curdir + try: + names = os.listdir(dirname) + except OSError: + return [] + return fnmatch.filter(names, pattern) + + +def glob0(dirname, basename): + if not basename: + # `os.path.split()` returns an empty basename for paths ending with a + # directory separator. 'q*x/' should match only directories. + if os.path.isdir(dirname): + return [basename] + else: + if os.path.lexists(os.path.join(dirname, basename)): + return [basename] + return [] + + +# This helper function recursively yields relative pathnames inside a literal +# directory. + + +def glob2(dirname, pattern): + assert _isrecursive(pattern) + yield pattern[:0] + for x in _rlistdir(dirname): + yield x + + +# Recursively yields relative pathnames inside a literal directory. +def _rlistdir(dirname): + if not dirname: + if isinstance(dirname, bytes): + dirname = os.curdir.encode('ASCII') + else: + dirname = os.curdir + try: + names = os.listdir(dirname) + except os.error: + return + for x in names: + yield x + path = os.path.join(dirname, x) if dirname else x + for y in _rlistdir(path): + yield os.path.join(x, y) + + +magic_check = re.compile('([*?[])') +magic_check_bytes = re.compile(b'([*?[])') + + +def has_magic(s): + if isinstance(s, bytes): + match = magic_check_bytes.search(s) + else: + match = magic_check.search(s) + return match is not None + + +def _isrecursive(pattern): + if isinstance(pattern, bytes): + return pattern == b'**' + else: + return pattern == '**' + + +def escape(pathname): + """Escape all special characters. + """ + # Escaping is done by wrapping any of "*?[" between square brackets. + # Metacharacters do not work in the drive part and shouldn't be escaped. + drive, pathname = os.path.splitdrive(pathname) + if isinstance(pathname, bytes): + pathname = magic_check_bytes.sub(br'[\1]', pathname) + else: + pathname = magic_check.sub(r'[\1]', pathname) + return drive + pathname diff --git a/venv/lib/python3.7/site-packages/setuptools/gui-32.exe b/venv/lib/python3.7/site-packages/setuptools/gui-32.exe new file mode 100644 index 0000000000000000000000000000000000000000..f8d3509653ba8f80ca7f3aa7f95616142ba83a94 GIT binary patch literal 65536 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/gui-64.exe b/venv/lib/python3.7/site-packages/setuptools/gui-64.exe new file mode 100644 index 0000000000000000000000000000000000000000..330c51a5dde15a0bb610a48cd0ca11770c914dae GIT binary patch literal 75264 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/gui.exe b/venv/lib/python3.7/site-packages/setuptools/gui.exe new file mode 100644 index 0000000000000000000000000000000000000000..f8d3509653ba8f80ca7f3aa7f95616142ba83a94 GIT binary patch literal 65536 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/setuptools/launch.py b/venv/lib/python3.7/site-packages/setuptools/launch.py new file mode 100644 index 0000000..308283e --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/launch.py @@ -0,0 +1,35 @@ +""" +Launch the Python script on the command line after +setuptools is bootstrapped via import. +""" + +# Note that setuptools gets imported implicitly by the +# invocation of this script using python -m setuptools.launch + +import tokenize +import sys + + +def run(): + """ + Run the script in sys.argv[1] as if it had + been invoked naturally. + """ + __builtins__ + script_name = sys.argv[1] + namespace = dict( + __file__=script_name, + __name__='__main__', + __doc__=None, + ) + sys.argv[:] = sys.argv[1:] + + open_ = getattr(tokenize, 'open', open) + script = open_(script_name).read() + norm_script = script.replace('\\r\\n', '\\n') + code = compile(norm_script, script_name, 'exec') + exec(code, namespace) + + +if __name__ == '__main__': + run() diff --git a/venv/lib/python3.7/site-packages/setuptools/lib2to3_ex.py b/venv/lib/python3.7/site-packages/setuptools/lib2to3_ex.py new file mode 100644 index 0000000..4b1a73f --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/lib2to3_ex.py @@ -0,0 +1,62 @@ +""" +Customized Mixin2to3 support: + + - adds support for converting doctests + + +This module raises an ImportError on Python 2. +""" + +from distutils.util import Mixin2to3 as _Mixin2to3 +from distutils import log +from lib2to3.refactor import RefactoringTool, get_fixers_from_package + +import setuptools + + +class DistutilsRefactoringTool(RefactoringTool): + def log_error(self, msg, *args, **kw): + log.error(msg, *args) + + def log_message(self, msg, *args): + log.info(msg, *args) + + def log_debug(self, msg, *args): + log.debug(msg, *args) + + +class Mixin2to3(_Mixin2to3): + def run_2to3(self, files, doctests=False): + # See of the distribution option has been set, otherwise check the + # setuptools default. + if self.distribution.use_2to3 is not True: + return + if not files: + return + log.info("Fixing " + " ".join(files)) + self.__build_fixer_names() + self.__exclude_fixers() + if doctests: + if setuptools.run_2to3_on_doctests: + r = DistutilsRefactoringTool(self.fixer_names) + r.refactor(files, write=True, doctests_only=True) + else: + _Mixin2to3.run_2to3(self, files) + + def __build_fixer_names(self): + if self.fixer_names: + return + self.fixer_names = [] + for p in setuptools.lib2to3_fixer_packages: + self.fixer_names.extend(get_fixers_from_package(p)) + if self.distribution.use_2to3_fixers is not None: + for p in self.distribution.use_2to3_fixers: + self.fixer_names.extend(get_fixers_from_package(p)) + + def __exclude_fixers(self): + excluded_fixers = getattr(self, 'exclude_fixers', []) + if self.distribution.use_2to3_exclude_fixers is not None: + excluded_fixers.extend(self.distribution.use_2to3_exclude_fixers) + for fixer_name in excluded_fixers: + if fixer_name in self.fixer_names: + self.fixer_names.remove(fixer_name) diff --git a/venv/lib/python3.7/site-packages/setuptools/monkey.py b/venv/lib/python3.7/site-packages/setuptools/monkey.py new file mode 100644 index 0000000..3c77f8c --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/monkey.py @@ -0,0 +1,179 @@ +""" +Monkey patching of distutils. +""" + +import sys +import distutils.filelist +import platform +import types +import functools +from importlib import import_module +import inspect + +from setuptools.extern import six + +import setuptools + +__all__ = [] +""" +Everything is private. Contact the project team +if you think you need this functionality. +""" + + +def _get_mro(cls): + """ + Returns the bases classes for cls sorted by the MRO. + + Works around an issue on Jython where inspect.getmro will not return all + base classes if multiple classes share the same name. Instead, this + function will return a tuple containing the class itself, and the contents + of cls.__bases__. See https://github.com/pypa/setuptools/issues/1024. + """ + if platform.python_implementation() == "Jython": + return (cls,) + cls.__bases__ + return inspect.getmro(cls) + + +def get_unpatched(item): + lookup = ( + get_unpatched_class if isinstance(item, six.class_types) else + get_unpatched_function if isinstance(item, types.FunctionType) else + lambda item: None + ) + return lookup(item) + + +def get_unpatched_class(cls): + """Protect against re-patching the distutils if reloaded + + Also ensures that no other distutils extension monkeypatched the distutils + first. + """ + external_bases = ( + cls + for cls in _get_mro(cls) + if not cls.__module__.startswith('setuptools') + ) + base = next(external_bases) + if not base.__module__.startswith('distutils'): + msg = "distutils has already been patched by %r" % cls + raise AssertionError(msg) + return base + + +def patch_all(): + # we can't patch distutils.cmd, alas + distutils.core.Command = setuptools.Command + + has_issue_12885 = sys.version_info <= (3, 5, 3) + + if has_issue_12885: + # fix findall bug in distutils (http://bugs.python.org/issue12885) + distutils.filelist.findall = setuptools.findall + + needs_warehouse = ( + sys.version_info < (2, 7, 13) + or + (3, 4) < sys.version_info < (3, 4, 6) + or + (3, 5) < sys.version_info <= (3, 5, 3) + ) + + if needs_warehouse: + warehouse = 'https://upload.pypi.org/legacy/' + distutils.config.PyPIRCCommand.DEFAULT_REPOSITORY = warehouse + + _patch_distribution_metadata() + + # Install Distribution throughout the distutils + for module in distutils.dist, distutils.core, distutils.cmd: + module.Distribution = setuptools.dist.Distribution + + # Install the patched Extension + distutils.core.Extension = setuptools.extension.Extension + distutils.extension.Extension = setuptools.extension.Extension + if 'distutils.command.build_ext' in sys.modules: + sys.modules['distutils.command.build_ext'].Extension = ( + setuptools.extension.Extension + ) + + patch_for_msvc_specialized_compiler() + + +def _patch_distribution_metadata(): + """Patch write_pkg_file and read_pkg_file for higher metadata standards""" + for attr in ('write_pkg_file', 'read_pkg_file', 'get_metadata_version'): + new_val = getattr(setuptools.dist, attr) + setattr(distutils.dist.DistributionMetadata, attr, new_val) + + +def patch_func(replacement, target_mod, func_name): + """ + Patch func_name in target_mod with replacement + + Important - original must be resolved by name to avoid + patching an already patched function. + """ + original = getattr(target_mod, func_name) + + # set the 'unpatched' attribute on the replacement to + # point to the original. + vars(replacement).setdefault('unpatched', original) + + # replace the function in the original module + setattr(target_mod, func_name, replacement) + + +def get_unpatched_function(candidate): + return getattr(candidate, 'unpatched') + + +def patch_for_msvc_specialized_compiler(): + """ + Patch functions in distutils to use standalone Microsoft Visual C++ + compilers. + """ + # import late to avoid circular imports on Python < 3.5 + msvc = import_module('setuptools.msvc') + + if platform.system() != 'Windows': + # Compilers only availables on Microsoft Windows + return + + def patch_params(mod_name, func_name): + """ + Prepare the parameters for patch_func to patch indicated function. + """ + repl_prefix = 'msvc9_' if 'msvc9' in mod_name else 'msvc14_' + repl_name = repl_prefix + func_name.lstrip('_') + repl = getattr(msvc, repl_name) + mod = import_module(mod_name) + if not hasattr(mod, func_name): + raise ImportError(func_name) + return repl, mod, func_name + + # Python 2.7 to 3.4 + msvc9 = functools.partial(patch_params, 'distutils.msvc9compiler') + + # Python 3.5+ + msvc14 = functools.partial(patch_params, 'distutils._msvccompiler') + + try: + # Patch distutils.msvc9compiler + patch_func(*msvc9('find_vcvarsall')) + patch_func(*msvc9('query_vcvarsall')) + except ImportError: + pass + + try: + # Patch distutils._msvccompiler._get_vc_env + patch_func(*msvc14('_get_vc_env')) + except ImportError: + pass + + try: + # Patch distutils._msvccompiler.gen_lib_options for Numpy + patch_func(*msvc14('gen_lib_options')) + except ImportError: + pass diff --git a/venv/lib/python3.7/site-packages/setuptools/msvc.py b/venv/lib/python3.7/site-packages/setuptools/msvc.py new file mode 100644 index 0000000..b9c472f --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/msvc.py @@ -0,0 +1,1301 @@ +""" +Improved support for Microsoft Visual C++ compilers. + +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) + +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) +""" + +import os +import sys +import platform +import itertools +import distutils.errors +from setuptools.extern.packaging.version import LegacyVersion + +from setuptools.extern.six.moves import filterfalse + +from .monkey import get_unpatched + +if platform.system() == 'Windows': + from setuptools.extern.six.moves import winreg + safe_env = os.environ +else: + """ + Mock winreg and environ so the module can be imported + on this platform. + """ + + class winreg: + HKEY_USERS = None + HKEY_CURRENT_USER = None + HKEY_LOCAL_MACHINE = None + HKEY_CLASSES_ROOT = None + + safe_env = dict() + +_msvc9_suppress_errors = ( + # msvc9compiler isn't available on some platforms + ImportError, + + # msvc9compiler raises DistutilsPlatformError in some + # environments. See #1118. + distutils.errors.DistutilsPlatformError, +) + +try: + from distutils.msvc9compiler import Reg +except _msvc9_suppress_errors: + pass + + +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. + + 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 + Required Microsoft Visual C++ version. + + Return + ------ + vcvarsall.bat path: str + """ + 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) + 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): + return vcvarsall + + return get_unpatched(msvc9_find_vcvarsall)(version) + + +def msvc9_query_vcvarsall(ver, arch='x86', *args, **kwargs): + """ + Patched "distutils.msvc9compiler.query_vcvarsall" for support extra + 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 + Required Microsoft Visual C++ version. + arch: str + Target architecture. + + Return + ------ + environment: dict + """ + # Try to get environement from vcvarsall.bat (Classical way) + try: + orig = get_unpatched(msvc9_query_vcvarsall) + return orig(ver, arch, *args, **kwargs) + except distutils.errors.DistutilsPlatformError: + # Pass error if Vcvarsall.bat is missing + pass + except ValueError: + # Pass error if environment not set after executing vcvarsall.bat + pass + + # If error, try to set environment directly + try: + return EnvironmentInfo(arch, ver).return_env() + except distutils.errors.DistutilsPlatformError as exc: + _augment_exception(exc, ver, arch) + raise + + +def msvc14_get_vc_env(plat_spec): + """ + Patched "distutils._msvccompiler._get_vc_env" for support extra + 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 + Target architecture. + + Return + ------ + environment: dict + """ + # 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 + try: + return EnvironmentInfo(plat_spec, vc_min_ver=14.0).return_env() + except distutils.errors.DistutilsPlatformError as exc: + _augment_exception(exc, 14.0) + raise + + +def msvc14_gen_lib_options(*args, **kwargs): + """ + Patched "distutils._msvccompiler.gen_lib_options" for fix + compatibility between "numpy.distutils" and "distutils._msvccompiler" + (for Numpy < 1.11.2) + """ + if "numpy.distutils" in sys.modules: + import numpy as np + if LegacyVersion(np.__version__) < LegacyVersion('1.11.2'): + return np.distutils.ccompiler.gen_lib_options(*args, **kwargs) + return get_unpatched(msvc14_gen_lib_options)(*args, **kwargs) + + +def _augment_exception(exc, version, arch=''): + """ + Add details to the exception message to help guide the user + as to what action will resolve it. + """ + # Error if MSVC++ directory not found or environment not set + message = exc.args[0] + + if "vcvarsall" in message.lower() or "visual c" in message.lower(): + # Special error message if MSVC++ not installed + tmpl = 'Microsoft Visual C++ {version:0.1f} is required.' + message = tmpl.format(**locals()) + msdownload = 'www.microsoft.com/download/details.aspx?id=%d' + 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 + else: + # For VC++ 9.0 redirect user to Vc++ for Python 2.7 : + # This redirection link is maintained by Microsoft. + # Contact vspython@microsoft.com if it needs updating. + message += ' Get it from http://aka.ms/vcpython27' + elif version == 10.0: + # For VC++ 10.0 Redirect user to Windows SDK 7.1 + 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": ' + r'https://visualstudio.microsoft.com/downloads/') + + exc.args = (message, ) + + +class PlatformInfo: + """ + Current and Target Architectures informations. + + Parameters + ---------- + arch: str + Target architecture. + """ + current_cpu = safe_env.get('processor_architecture', '').lower() + + def __init__(self, arch): + self.arch = arch.lower().replace('x64', 'amd64') + + @property + def target_cpu(self): + return self.arch[self.arch.find('_') + 1:] + + def target_is_x86(self): + return self.target_cpu == 'x86' + + def current_is_x86(self): + return self.current_cpu == 'x86' + + def current_dir(self, hidex86=False, x64=False): + """ + Current platform specific subfolder. + + Parameters + ---------- + hidex86: bool + return '' and not '\x86' if architecture is x86. + x64: bool + return '\x64' and not '\amd64' if architecture is amd64. + + Return + ------ + subfolder: str + '\target', or '' (see hidex86 parameter) + """ + return ( + '' if (self.current_cpu == 'x86' and hidex86) else + r'\x64' if (self.current_cpu == 'amd64' and x64) else + r'\%s' % self.current_cpu + ) + + def target_dir(self, hidex86=False, x64=False): + r""" + Target platform specific subfolder. + + Parameters + ---------- + hidex86: bool + return '' and not '\x86' if architecture is x86. + x64: bool + return '\x64' and not '\amd64' if architecture is amd64. + + Return + ------ + subfolder: str + '\current', or '' (see hidex86 parameter) + """ + return ( + '' if (self.target_cpu == 'x86' and hidex86) else + r'\x64' if (self.target_cpu == 'amd64' and x64) else + r'\%s' % self.target_cpu + ) + + def cross_dir(self, forcex86=False): + r""" + Cross platform specific subfolder. + + Parameters + ---------- + forcex86: bool + Use 'x86' as current architecture even if current acritecture is + not x86. + + Return + ------ + subfolder: str + '' if target architecture is current architecture, + '\current_target' if not. + """ + current = 'x86' if forcex86 else self.current_cpu + return ( + '' if self.target_cpu == current else + self.target_dir().replace('\\', '\\%s_' % current) + ) + + +class RegistryInfo: + """ + Microsoft Visual Studio related registry informations. + + Parameters + ---------- + platform_info: PlatformInfo + "PlatformInfo" instance. + """ + HKEYS = (winreg.HKEY_USERS, + winreg.HKEY_CURRENT_USER, + winreg.HKEY_LOCAL_MACHINE, + winreg.HKEY_CLASSES_ROOT) + + def __init__(self, platform_info): + self.pi = platform_info + + @property + def visualstudio(self): + """ + Microsoft Visual Studio root registry key. + """ + return 'VisualStudio' + + @property + def sxs(self): + """ + Microsoft Visual Studio SxS registry key. + """ + return os.path.join(self.visualstudio, 'SxS') + + @property + def vc(self): + """ + Microsoft Visual C++ VC7 registry key. + """ + return os.path.join(self.sxs, 'VC7') + + @property + def vs(self): + """ + Microsoft Visual Studio VS7 registry key. + """ + return os.path.join(self.sxs, 'VS7') + + @property + def vc_for_python(self): + """ + Microsoft Visual C++ for Python registry key. + """ + return r'DevDiv\VCForPython' + + @property + def microsoft_sdk(self): + """ + Microsoft SDK registry key. + """ + return 'Microsoft SDKs' + + @property + def windows_sdk(self): + """ + Microsoft Windows/Platform SDK registry key. + """ + return os.path.join(self.microsoft_sdk, 'Windows') + + @property + def netfx_sdk(self): + """ + Microsoft .NET Framework SDK registry key. + """ + return os.path.join(self.microsoft_sdk, 'NETFXSDK') + + @property + def windows_kits_roots(self): + """ + Microsoft Windows Kits Roots registry key. + """ + return r'Windows Kits\Installed Roots' + + def microsoft(self, key, x86=False): + """ + Return key in Microsoft software registry. + + Parameters + ---------- + key: str + Registry key path where look. + x86: str + Force x86 software registry. + + Return + ------ + str: value + """ + node64 = '' if self.pi.current_is_x86() or x86 else 'Wow6432Node' + return os.path.join('Software', node64, 'Microsoft', key) + + def lookup(self, key, name): + """ + Look for values in registry in Microsoft software registry. + + Parameters + ---------- + key: str + Registry key path where look. + name: str + Value name to find. + + Return + ------ + str: value + """ + KEY_READ = winreg.KEY_READ + openkey = winreg.OpenKey + ms = self.microsoft + for hkey in self.HKEYS: + try: + 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) + except (OSError, IOError): + continue + else: + continue + try: + return winreg.QueryValueEx(bkey, name)[0] + except (OSError, IOError): + pass + + +class SystemInfo: + """ + Microsoft Windows and Visual Studio related system inormations. + + Parameters + ---------- + registry_info: RegistryInfo + "RegistryInfo" instance. + vc_ver: float + Required Microsoft Visual C++ version. + """ + + # 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) + + 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) + + def find_available_vc_vers(self): + """ + Find all available Microsoft Visual C++ versions. + """ + ms = self.ri.microsoft + vckeys = (self.ri.vc, self.ri.vc_for_python, self.ri.vs) + vc_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) + + @property + def VSInstallDir(self): + """ + Microsoft Visual Studio directory. + """ + # Default path + name = 'Microsoft Visual Studio %0.1f' % self.vc_ver + default = os.path.join(self.ProgramFilesx86, name) + + # 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 + + @property + def VCInstallDir(self): + """ + Microsoft Visual C++ directory. + """ + self.VSInstallDir + + 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): + msg = 'Microsoft Visual C++ directory not found' + raise distutils.errors.DistutilsPlatformError(msg) + + return path + + def _guess_vc(self): + """ + Locate Visual C for 2017 + """ + if self.vc_ver <= 14.0: + return + + 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) + except (OSError, IOError, IndexError): + pass + + def _guess_vc_legacy(self): + """ + Locate Visual C for versions prior to 2017 + """ + default = r'Microsoft Visual Studio %0.1f\VC' % self.vc_ver + return os.path.join(self.ProgramFilesx86, default) + + @property + def WindowsSdkVersion(self): + """ + Microsoft Windows SDK versions for specified MSVC++ version. + """ + 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') + + @property + def WindowsSdkLastVersion(self): + """ + Microsoft Windows SDK last version + """ + return self._use_last_dir_name(os.path.join( + self.WindowsSdkDir, 'lib')) + + @property + def WindowsSdkDir(self): + """ + Microsoft Windows SDK directory. + """ + sdkdir = '' + for ver in self.WindowsSdkVersion: + # Try to get it from registry + loc = os.path.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): + # Try to get "VC++ for Python" version from registry + path = os.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): + # 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): + sdkdir = d + if not sdkdir or not os.path.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): + sdkdir = d + if not sdkdir: + # If fail, use Platform SDK + sdkdir = os.path.join(self.VCInstallDir, 'PlatformSDK') + return sdkdir + + @property + def WindowsSDKExecutablePath(self): + """ + Microsoft Windows SDK executable directory. + """ + # Find WinSDK NetFx Tools registry dir name + if self.vc_ver <= 11.0: + netfxver = 35 + arch = '' + else: + netfxver = 40 + hidex86 = True if self.vc_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 + regpaths = [] + if self.vc_ver >= 14.0: + for ver in self.NetFxSdkVersion: + regpaths += [os.path.join(self.ri.netfx_sdk, ver, fx)] + + for ver in self.WindowsSdkVersion: + regpaths += [os.path.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 + + @property + def FSharpInstallDir(self): + """ + Microsoft Visual F# directory. + """ + path = r'%0.1f\Setup\F#' % self.vc_ver + path = os.path.join(self.ri.visualstudio, path) + return self.ri.lookup(path, 'productdir') or '' + + @property + def UniversalCRTSdkDir(self): + """ + Microsoft Universal CRT SDK directory. + """ + # Set Kit Roots versions for specified MSVC++ version + if self.vc_ver >= 14.0: + vers = ('10', '81') + else: + vers = () + + # 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 '' + + @property + def UniversalCRTSdkLastVersion(self): + """ + Microsoft Universal C Runtime SDK last version + """ + return self._use_last_dir_name(os.path.join( + self.UniversalCRTSdkDir, 'lib')) + + @property + def NetFxSdkVersion(self): + """ + Microsoft .NET Framework SDK versions. + """ + # Set FxSdk versions for specified MSVC++ version + if self.vc_ver >= 14.0: + return ('4.6.1', '4.6') + else: + return () + + @property + def NetFxSdkDir(self): + """ + Microsoft .NET Framework SDK directory. + """ + for ver in self.NetFxSdkVersion: + loc = os.path.join(self.ri.netfx_sdk, ver) + sdkdir = self.ri.lookup(loc, 'kitsinstallationfolder') + if sdkdir: + break + return sdkdir or '' + + @property + def FrameworkDir32(self): + """ + Microsoft .NET Framework 32bit directory. + """ + # Default path + guess_fw = os.path.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 + + @property + def FrameworkDir64(self): + """ + Microsoft .NET Framework 64bit directory. + """ + # Default path + guess_fw = os.path.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 + + @property + def FrameworkVersion32(self): + """ + Microsoft .NET Framework 32bit versions. + """ + return self._find_dot_net_versions(32) + + @property + def FrameworkVersion64(self): + """ + Microsoft .NET Framework 64bit versions. + """ + return self._find_dot_net_versions(64) + + def _find_dot_net_versions(self, bits): + """ + Find Microsoft .NET Framework versions. + + Parameters + ---------- + bits: int + Platform number of bits: 32 or 64. + """ + # Find actual .NET version in registry + reg_ver = self.ri.lookup(self.ri.vc, 'frameworkver%d' % bits) + dot_net_dir = getattr(self, 'FrameworkDir%d' % bits) + 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 + + def _use_last_dir_name(self, path, prefix=''): + """ + Return name of the last dir in path or '' if no dir found. + + Parameters + ---------- + path: str + Use dirs in this path + prefix: str + Use only dirs startings by this prefix + """ + matching_dirs = ( + dir_name + for dir_name in reversed(os.listdir(path)) + if os.path.isdir(os.path.join(path, dir_name)) and + dir_name.startswith(prefix) + ) + return next(matching_dirs, None) or '' + + +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. + + Script created by analysing Microsoft environment configuration files like + "vcvars[...].bat", "SetEnv.Cmd", "vcbuildtools.bat", ... + + Parameters + ---------- + arch: str + Target architecture. + vc_ver: float + Required Microsoft Visual C++ version. If not set, autodetect the last + version. + vc_min_ver: float + Minimum Microsoft Visual C++ version. + """ + + # Variables and properties in this class use originals CamelCase variables + # names from Microsoft source files for more easy comparaison. + + def __init__(self, arch, vc_ver=None, vc_min_ver=0): + self.pi = PlatformInfo(arch) + self.ri = RegistryInfo(self.pi) + self.si = SystemInfo(self.ri, vc_ver) + + if self.vc_ver < vc_min_ver: + err = 'No suitable Microsoft Visual C++ version found' + raise distutils.errors.DistutilsPlatformError(err) + + @property + def vc_ver(self): + """ + Microsoft Visual C++ version. + """ + return self.si.vc_ver + + @property + def VSTools(self): + """ + Microsoft Visual Studio Tools + """ + paths = [r'Common7\IDE', r'Common7\Tools'] + + if self.vc_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] + + @property + def VCIncludes(self): + """ + Microsoft Visual C++ & Microsoft Foundation Class Includes + """ + return [os.path.join(self.si.VCInstallDir, 'Include'), + os.path.join(self.si.VCInstallDir, r'ATLMFC\Include')] + + @property + def VCLibraries(self): + """ + Microsoft Visual C++ & Microsoft Foundation Class Libraries + """ + if self.vc_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: + paths += [r'Lib\store%s' % arch_subdir] + + return [os.path.join(self.si.VCInstallDir, path) for path in paths] + + @property + def VCStoreRefs(self): + """ + Microsoft Visual C++ store references Libraries + """ + if self.vc_ver < 14.0: + return [] + return [os.path.join(self.si.VCInstallDir, r'Lib\store\references')] + + @property + def VCTools(self): + """ + Microsoft Visual C++ Tools + """ + si = self.si + tools = [os.path.join(si.VCInstallDir, 'VCPackages')] + + forcex86 = True if self.vc_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)] + + if self.vc_ver == 14.0: + path = 'Bin%s' % self.pi.current_dir(hidex86=True) + tools += [os.path.join(si.VCInstallDir, path)] + + elif self.vc_ver >= 15.0: + host_dir = (r'bin\HostX86%s' if self.pi.current_is_x86() else + r'bin\HostX64%s') + tools += [os.path.join( + si.VCInstallDir, host_dir % self.pi.target_dir(x64=True))] + + if self.pi.current_cpu != self.pi.target_cpu: + tools += [os.path.join( + si.VCInstallDir, host_dir % self.pi.current_dir(x64=True))] + + else: + tools += [os.path.join(si.VCInstallDir, 'Bin')] + + return tools + + @property + def OSLibraries(self): + """ + Microsoft Windows SDK Libraries + """ + if self.vc_ver <= 10.0: + arch_subdir = self.pi.target_dir(hidex86=True, x64=True) + return [os.path.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') + libver = self._sdk_subdir + return [os.path.join(lib, '%sum%s' % (libver , arch_subdir))] + + @property + def OSIncludes(self): + """ + Microsoft Windows SDK Include + """ + include = os.path.join(self.si.WindowsSdkDir, 'include') + + if self.vc_ver <= 10.0: + return [include, os.path.join(include, 'gl')] + + else: + if self.vc_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)] + + @property + def OSLibpath(self): + """ + Microsoft Windows SDK Libraries Paths + """ + ref = os.path.join(self.si.WindowsSdkDir, 'References') + libpath = [] + + if self.vc_ver <= 9.0: + libpath += self.OSLibraries + + if self.vc_ver >= 11.0: + libpath += [os.path.join(ref, r'CommonConfiguration\Neutral')] + + if self.vc_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', + ), + ] + return libpath + + @property + def SdkTools(self): + """ + Microsoft Windows SDK Tools + """ + return list(self._sdk_tools()) + + def _sdk_tools(self): + """ + Microsoft Windows SDK Tools paths generator + """ + 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 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) + + if self.vc_ver == 10.0 or self.vc_ver == 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) + + elif self.vc_ver >= 15.0: + path = os.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)) + + if self.si.WindowsSDKExecutablePath: + yield self.si.WindowsSDKExecutablePath + + @property + def _sdk_subdir(self): + """ + Microsoft Windows SDK version subdir + """ + ucrtver = self.si.WindowsSdkLastVersion + return ('%s\\' % ucrtver) if ucrtver else '' + + @property + def SdkSetup(self): + """ + Microsoft Windows SDK Setup + """ + if self.vc_ver > 9.0: + return [] + + return [os.path.join(self.si.WindowsSdkDir, 'Setup')] + + @property + def FxTools(self): + """ + Microsoft .NET Framework Tools + """ + pi = self.pi + si = self.si + + if self.vc_ver <= 10.0: + include32 = True + include64 = not pi.target_is_x86() and not pi.current_is_x86() + else: + include32 = pi.target_is_x86() or pi.current_is_x86() + include64 = pi.current_cpu == 'amd64' or pi.target_cpu == 'amd64' + + tools = [] + if include32: + tools += [os.path.join(si.FrameworkDir32, ver) + for ver in si.FrameworkVersion32] + if include64: + tools += [os.path.join(si.FrameworkDir64, ver) + for ver in si.FrameworkVersion64] + return tools + + @property + def NetFxSDKLibraries(self): + """ + Microsoft .Net Framework SDK Libraries + """ + if self.vc_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)] + + @property + def NetFxSDKIncludes(self): + """ + Microsoft .Net Framework SDK Includes + """ + if self.vc_ver < 14.0 or not self.si.NetFxSdkDir: + return [] + + return [os.path.join(self.si.NetFxSdkDir, r'include\um')] + + @property + def VsTDb(self): + """ + Microsoft Visual Studio Team System Database + """ + return [os.path.join(self.si.VSInstallDir, r'VSTSDB\Deploy')] + + @property + def MSBuild(self): + """ + Microsoft Build Engine + """ + if self.vc_ver < 12.0: + return [] + elif self.vc_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)] + + if self.vc_ver >= 15.0: + # Add Roslyn C# & Visual Basic Compiler + build += [os.path.join(base_path, path, 'Roslyn')] + + return build + + @property + def HTMLHelpWorkshop(self): + """ + Microsoft HTML Help Workshop + """ + if self.vc_ver < 11.0: + return [] + + return [os.path.join(self.si.ProgramFilesx86, 'HTML Help Workshop')] + + @property + def UCRTLibraries(self): + """ + Microsoft Universal C Runtime SDK Libraries + """ + if self.vc_ver < 14.0: + return [] + + arch_subdir = self.pi.target_dir(x64=True) + lib = os.path.join(self.si.UniversalCRTSdkDir, 'lib') + ucrtver = self._ucrt_subdir + return [os.path.join(lib, '%sucrt%s' % (ucrtver, arch_subdir))] + + @property + def UCRTIncludes(self): + """ + Microsoft Universal C Runtime SDK Include + """ + if self.vc_ver < 14.0: + return [] + + include = os.path.join(self.si.UniversalCRTSdkDir, 'include') + return [os.path.join(include, '%sucrt' % self._ucrt_subdir)] + + @property + def _ucrt_subdir(self): + """ + Microsoft Universal C Runtime SDK version subdir + """ + ucrtver = self.si.UniversalCRTSdkLastVersion + return ('%s\\' % ucrtver) if ucrtver else '' + + @property + def FSharp(self): + """ + Microsoft Visual F# + """ + if self.vc_ver < 11.0 and self.vc_ver > 12.0: + return [] + + return self.si.FSharpInstallDir + + @property + def VCRuntimeRedist(self): + """ + Microsoft Visual C++ runtime redistribuable dll + """ + 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' + + # Visual Studio 2017 is still Visual C++ 14.0 + dll_ver = 14.0 if self.vc_ver == 15 else self.vc_ver + + vcruntime = vcruntime % (arch_subdir, self.vc_ver, dll_ver) + return os.path.join(redist_path, vcruntime) + + def return_env(self, exists=True): + """ + Return environment dict. + + Parameters + ---------- + exists: bool + It True, only return existing paths. + """ + env = dict( + include=self._build_paths('include', + [self.VCIncludes, + self.OSIncludes, + self.UCRTIncludes, + self.NetFxSDKIncludes], + exists), + lib=self._build_paths('lib', + [self.VCLibraries, + self.OSLibraries, + self.FxTools, + self.UCRTLibraries, + self.NetFxSDKLibraries], + exists), + libpath=self._build_paths('libpath', + [self.VCLibraries, + self.FxTools, + self.VCStoreRefs, + self.OSLibpath], + exists), + path=self._build_paths('path', + [self.VCTools, + self.VSTools, + self.VsTDb, + self.SdkTools, + self.SdkSetup, + self.FxTools, + self.MSBuild, + self.HTMLHelpWorkshop, + self.FSharp], + exists), + ) + if self.vc_ver >= 14 and os.path.isfile(self.VCRuntimeRedist): + env['py_vcruntime_redist'] = self.VCRuntimeRedist + return env + + def _build_paths(self, name, spec_path_lists, exists): + """ + Given an environment variable name and specified paths, + return a pathsep-separated string of paths containing + unique, extant, directories from those paths and from + the environment variable. Raise an error if no paths + are resolved. + """ + # flatten spec_path_lists + spec_paths = itertools.chain.from_iterable(spec_path_lists) + env_paths = safe_env.get(name, '').split(os.pathsep) + paths = itertools.chain(spec_paths, env_paths) + extant_paths = list(filter(os.path.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) + + # from Python docs + def _unique_everseen(self, iterable, key=None): + """ + List unique elements, preserving order. + Remember all elements ever seen. + + _unique_everseen('AAAABBBCCDAABBB') --> A B C D + + _unique_everseen('ABBCcAD', str.lower) --> A B C D + """ + seen = set() + seen_add = seen.add + if key is None: + for element in filterfalse(seen.__contains__, iterable): + seen_add(element) + yield element + else: + for element in iterable: + k = key(element) + if k not in seen: + seen_add(k) + yield element diff --git a/venv/lib/python3.7/site-packages/setuptools/namespaces.py b/venv/lib/python3.7/site-packages/setuptools/namespaces.py new file mode 100644 index 0000000..dc16106 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/namespaces.py @@ -0,0 +1,107 @@ +import os +from distutils import log +import itertools + +from setuptools.extern.six.moves import map + + +flatten = itertools.chain.from_iterable + + +class Installer: + + nspkg_ext = '-nspkg.pth' + + def install_namespaces(self): + nsp = self._get_all_ns_packages() + if not nsp: + return + filename, ext = os.path.splitext(self._get_target()) + filename += self.nspkg_ext + self.outputs.append(filename) + log.info("Installing %s", filename) + lines = map(self._gen_nspkg_line, nsp) + + if self.dry_run: + # always generate the lines, even in dry run + list(lines) + return + + with open(filename, 'wt') as f: + f.writelines(lines) + + def uninstall_namespaces(self): + filename, ext = os.path.splitext(self._get_target()) + filename += self.nspkg_ext + if not os.path.exists(filename): + return + log.info("Removing %s", filename) + os.remove(filename) + + def _get_target(self): + return self.target + + _nspkg_tmpl = ( + "import sys, types, os", + "has_mfs = sys.version_info > (3, 5)", + "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 " + "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))", + "mp = (m or []) and m.__dict__.setdefault('__path__',[])", + "(p not in mp) and mp.append(p)", + ) + "lines for the namespace installer" + + _nspkg_tmpl_multi = ( + 'm and setattr(sys.modules[%(parent)r], %(child)r, m)', + ) + "additional line(s) when a parent package is indicated" + + def _get_root(self): + return "sys._getframe(1).f_locals['sitedir']" + + def _gen_nspkg_line(self, pkg): + # ensure pkg is not a unicode string under Python 2.7 + pkg = str(pkg) + pth = tuple(pkg.split('.')) + root = self._get_root() + tmpl_lines = self._nspkg_tmpl + parent, sep, child = pkg.rpartition('.') + if parent: + tmpl_lines += self._nspkg_tmpl_multi + return ';'.join(tmpl_lines) % locals() + '\n' + + def _get_all_ns_packages(self): + """Return sorted list of all package namespaces""" + pkgs = self.distribution.namespace_packages or [] + return sorted(flatten(map(self._pkg_names, pkgs))) + + @staticmethod + def _pkg_names(pkg): + """ + Given a namespace package, yield the components of that + package. + + >>> names = Installer._pkg_names('a.b.c') + >>> set(names) == set(['a', 'a.b', 'a.b.c']) + True + """ + parts = pkg.split('.') + while parts: + yield '.'.join(parts) + parts.pop() + + +class DevelopInstaller(Installer): + def _get_root(self): + return repr(str(self.egg_path)) + + def _get_target(self): + return self.egg_link diff --git a/venv/lib/python3.7/site-packages/setuptools/package_index.py b/venv/lib/python3.7/site-packages/setuptools/package_index.py new file mode 100644 index 0000000..1608b91 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/package_index.py @@ -0,0 +1,1128 @@ +"""PyPI and direct package downloading""" +import sys +import os +import re +import shutil +import socket +import base64 +import hashlib +import itertools +import warnings +from functools import wraps + +from setuptools.extern import six +from setuptools.extern.six.moves import urllib, http_client, configparser, map + +import setuptools +from pkg_resources import ( + CHECKOUT_DIST, Distribution, BINARY_DIST, normalize_path, SOURCE_DIST, + Environment, find_distributions, safe_name, safe_version, + to_filename, Requirement, DEVELOP_DIST, EGG_DIST, +) +from setuptools import ssl_support +from distutils import log +from distutils.errors import DistutilsError +from fnmatch import translate +from setuptools.py27compat import get_all_headers +from setuptools.py33compat import unescape +from setuptools.wheel import Wheel + +__metaclass__ = type + +EGG_FRAGMENT = re.compile(r'^egg=([-A-Za-z0-9_.+!]+)$') +HREF = re.compile(r"""href\s*=\s*['"]?([^'"> ]+)""", re.I) +PYPI_MD5 = re.compile( + r'<a href="([^"#]+)">([^<]+)</a>\n\s+\(<a (?:title="MD5 hash"\n\s+)' + r'href="[^?]+\?:action=show_md5&digest=([0-9a-f]{32})">md5</a>\)' +) +URL_SCHEME = re.compile('([-+.a-z0-9]{2,}):', re.I).match +EXTENSIONS = ".tar.gz .tar.bz2 .tar .zip .tgz".split() + +__all__ = [ + 'PackageIndex', 'distros_for_url', 'parse_bdist_wininst', + 'interpret_distro_name', +] + +_SOCKET_TIMEOUT = 15 + +_tmpl = "setuptools/{setuptools.__version__} Python-urllib/{py_major}" +user_agent = _tmpl.format(py_major=sys.version[:3], setuptools=setuptools) + + +def parse_requirement_arg(spec): + try: + return Requirement.parse(spec) + except ValueError: + raise DistutilsError( + "Not a URL, existing file, or requirement spec: %r" % (spec,) + ) + + +def parse_bdist_wininst(name): + """Return (base,pyversion) or (None,None) for possible .exe name""" + + lower = name.lower() + base, py_ver, plat = None, None, None + + if lower.endswith('.exe'): + if lower.endswith('.win32.exe'): + base = name[:-10] + plat = 'win32' + elif lower.startswith('.win32-py', -16): + py_ver = name[-7:-4] + base = name[:-16] + plat = 'win32' + elif lower.endswith('.win-amd64.exe'): + base = name[:-14] + plat = 'win-amd64' + elif lower.startswith('.win-amd64-py', -20): + py_ver = name[-7:-4] + base = name[:-20] + plat = 'win-amd64' + return base, py_ver, plat + + +def egg_info_for_url(url): + parts = urllib.parse.urlparse(url) + scheme, server, path, parameters, query, fragment = parts + base = urllib.parse.unquote(path.split('/')[-1]) + if server == 'sourceforge.net' and base == 'download': # XXX Yuck + base = urllib.parse.unquote(path.split('/')[-2]) + if '#' in base: + base, fragment = base.split('#', 1) + return base, fragment + + +def distros_for_url(url, metadata=None): + """Yield egg or source distribution objects that might be found at a URL""" + base, fragment = egg_info_for_url(url) + for dist in distros_for_location(url, base, metadata): + yield dist + if fragment: + match = EGG_FRAGMENT.match(fragment) + if match: + for dist in interpret_distro_name( + url, match.group(1), metadata, precedence=CHECKOUT_DIST + ): + yield dist + + +def distros_for_location(location, basename, metadata=None): + """Yield egg or source distribution objects based on basename""" + if basename.endswith('.egg.zip'): + basename = basename[:-4] # strip the .zip + if basename.endswith('.egg') and '-' in basename: + # only one, unambiguous interpretation + return [Distribution.from_location(location, basename, metadata)] + if basename.endswith('.whl') and '-' in basename: + wheel = Wheel(basename) + if not wheel.is_compatible(): + return [] + return [Distribution( + location=location, + project_name=wheel.project_name, + version=wheel.version, + # Increase priority over eggs. + precedence=EGG_DIST + 1, + )] + if basename.endswith('.exe'): + win_base, py_ver, platform = parse_bdist_wininst(basename) + if win_base is not None: + return interpret_distro_name( + location, win_base, metadata, py_ver, BINARY_DIST, platform + ) + # Try source distro extensions (.zip, .tgz, etc.) + # + for ext in EXTENSIONS: + if basename.endswith(ext): + basename = basename[:-len(ext)] + return interpret_distro_name(location, basename, metadata) + return [] # no extension matched + + +def distros_for_filename(filename, metadata=None): + """Yield possible egg or source distribution objects based on a filename""" + return distros_for_location( + normalize_path(filename), os.path.basename(filename), metadata + ) + + +def interpret_distro_name( + location, basename, metadata, py_version=None, precedence=SOURCE_DIST, + platform=None +): + """Generate alternative interpretations of a source distro name + + Note: if `location` is a filesystem filename, you should call + ``pkg_resources.normalize_path()`` on it before passing it to this + routine! + """ + # Generate alternative interpretations of a source distro name + # Because some packages are ambiguous as to name/versions split + # e.g. "adns-python-1.1.0", "egenix-mx-commercial", etc. + # So, we generate each possible interepretation (e.g. "adns, python-1.1.0" + # "adns-python, 1.1.0", and "adns-python-1.1.0, no version"). In practice, + # the spurious interpretations should be ignored, because in the event + # there's also an "adns" package, the spurious "python-1.1.0" version will + # compare lower than any numeric version number, and is therefore unlikely + # to match a request for it. It's still a potential problem, though, and + # in the long run PyPI and the distutils should go for "safe" names and + # versions in distribution archive names (sdist and bdist). + + parts = basename.split('-') + if not py_version and any(re.match(r'py\d\.\d$', p) for p in parts[2:]): + # it is a bdist_dumb, not an sdist -- bail out + return + + for p in range(1, len(parts) + 1): + yield Distribution( + location, metadata, '-'.join(parts[:p]), '-'.join(parts[p:]), + py_version=py_version, precedence=precedence, + platform=platform + ) + + +# From Python 2.7 docs +def unique_everseen(iterable, key=None): + "List unique elements, preserving order. Remember all elements ever seen." + # unique_everseen('AAAABBBCCDAABBB') --> A B C D + # unique_everseen('ABBCcAD', str.lower) --> A B C D + seen = set() + seen_add = seen.add + if key is None: + for element in six.moves.filterfalse(seen.__contains__, iterable): + seen_add(element) + yield element + else: + for element in iterable: + k = key(element) + if k not in seen: + seen_add(k) + yield element + + +def unique_values(func): + """ + Wrap a function returning an iterable such that the resulting iterable + only ever yields unique items. + """ + + @wraps(func) + def wrapper(*args, **kwargs): + return unique_everseen(func(*args, **kwargs)) + + return wrapper + + +REL = re.compile(r"""<([^>]*\srel\s*=\s*['"]?([^'">]+)[^>]*)>""", re.I) +# this line is here to fix emacs' cruddy broken syntax highlighting + + +@unique_values +def find_external_links(url, page): + """Find rel="homepage" and rel="download" links in `page`, yielding URLs""" + + for match in REL.finditer(page): + tag, rel = match.groups() + rels = set(map(str.strip, rel.lower().split(','))) + if 'homepage' in rels or 'download' in rels: + for match in HREF.finditer(tag): + yield urllib.parse.urljoin(url, htmldecode(match.group(1))) + + for tag in ("<th>Home Page", "<th>Download URL"): + pos = page.find(tag) + if pos != -1: + match = HREF.search(page, pos) + if match: + yield urllib.parse.urljoin(url, htmldecode(match.group(1))) + + +class ContentChecker: + """ + A null content checker that defines the interface for checking content + """ + + def feed(self, block): + """ + Feed a block of data to the hash. + """ + return + + def is_valid(self): + """ + Check the hash. Return False if validation fails. + """ + return True + + def report(self, reporter, template): + """ + Call reporter with information about the checker (hash name) + substituted into the template. + """ + return + + +class HashChecker(ContentChecker): + pattern = re.compile( + r'(?P<hash_name>sha1|sha224|sha384|sha256|sha512|md5)=' + r'(?P<expected>[a-f0-9]+)' + ) + + def __init__(self, hash_name, expected): + self.hash_name = hash_name + self.hash = hashlib.new(hash_name) + self.expected = expected + + @classmethod + def from_url(cls, url): + "Construct a (possibly null) ContentChecker from a URL" + fragment = urllib.parse.urlparse(url)[-1] + if not fragment: + return ContentChecker() + match = cls.pattern.search(fragment) + if not match: + return ContentChecker() + return cls(**match.groupdict()) + + def feed(self, block): + self.hash.update(block) + + def is_valid(self): + return self.hash.hexdigest() == self.expected + + def report(self, reporter, template): + msg = template % self.hash_name + return reporter(msg) + + +class PackageIndex(Environment): + """A distribution index that scans web pages for download URLs""" + + def __init__( + self, index_url="https://pypi.org/simple/", hosts=('*',), + ca_bundle=None, verify_ssl=True, *args, **kw + ): + Environment.__init__(self, *args, **kw) + self.index_url = index_url + "/" [:not index_url.endswith('/')] + self.scanned_urls = {} + self.fetched_urls = {} + self.package_pages = {} + self.allows = re.compile('|'.join(map(translate, hosts))).match + self.to_scan = [] + use_ssl = ( + verify_ssl + and ssl_support.is_available + and (ca_bundle or ssl_support.find_ca_bundle()) + ) + if use_ssl: + self.opener = ssl_support.opener_for(ca_bundle) + else: + self.opener = urllib.request.urlopen + + def process_url(self, url, retrieve=False): + """Evaluate a URL as a possible download, and maybe retrieve it""" + if url in self.scanned_urls and not retrieve: + return + self.scanned_urls[url] = True + if not URL_SCHEME(url): + self.process_filename(url) + return + else: + dists = list(distros_for_url(url)) + if dists: + if not self.url_ok(url): + return + self.debug("Found link: %s", url) + + if dists or not retrieve or url in self.fetched_urls: + list(map(self.add, dists)) + return # don't need the actual page + + if not self.url_ok(url): + self.fetched_urls[url] = True + return + + self.info("Reading %s", url) + self.fetched_urls[url] = True # prevent multiple fetch attempts + tmpl = "Download error on %s: %%s -- Some packages may not be found!" + f = self.open_url(url, tmpl % url) + if f is None: + return + 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 + return + + base = f.url # handle redirects + page = f.read() + if not isinstance(page, str): + # In Python 3 and got bytes but want str. + if isinstance(f, urllib.error.HTTPError): + # Errors have no charset, assume latin1: + charset = 'latin-1' + else: + charset = f.headers.get_param('charset') or 'latin-1' + page = page.decode(charset, "ignore") + f.close() + for match in HREF.finditer(page): + link = urllib.parse.urljoin(base, htmldecode(match.group(1))) + self.process_url(link) + if url.startswith(self.index_url) and getattr(f, 'code', None) != 404: + page = self.process_index(url, page) + + def process_filename(self, fn, nested=False): + # process filenames or directories + if not os.path.exists(fn): + self.warn("Not found: %s", fn) + return + + if os.path.isdir(fn) and not nested: + path = os.path.realpath(fn) + for item in os.listdir(path): + self.process_filename(os.path.join(path, item), True) + + dists = distros_for_filename(fn) + if dists: + self.debug("Found: %s", fn) + list(map(self.add, dists)) + + def url_ok(self, url, fatal=False): + s = URL_SCHEME(url) + is_file = s and s.group(1).lower() == 'file' + if is_file or self.allows(urllib.parse.urlparse(url)[1]): + return True + msg = ( + "\nNote: Bypassing %s (disallowed host; see " + "http://bit.ly/2hrImnY for details).\n") + if fatal: + raise DistutilsError(msg % url) + else: + self.warn(msg, url) + + def scan_egg_links(self, search_path): + dirs = filter(os.path.isdir, search_path) + egg_links = ( + (path, entry) + for path in dirs + for entry in os.listdir(path) + if entry.endswith('.egg-link') + ) + list(itertools.starmap(self.scan_egg_link, egg_links)) + + def scan_egg_link(self, path, entry): + with open(os.path.join(path, entry)) as raw_lines: + # filter non-empty lines + lines = list(filter(None, map(str.strip, raw_lines))) + + if len(lines) != 2: + # format is not recognized; punt + return + + egg_path, setup_path = lines + + for dist in find_distributions(os.path.join(path, egg_path)): + dist.location = os.path.join(path, *lines) + dist.precedence = SOURCE_DIST + self.add(dist) + + def process_index(self, url, page): + """Process the contents of a PyPI page""" + + def scan(link): + # Process a URL to see if it's for a package page + if link.startswith(self.index_url): + parts = list(map( + urllib.parse.unquote, link[len(self.index_url):].split('/') + )) + if len(parts) == 2 and '#' not in parts[1]: + # it's a package page, sanitize and index it + pkg = safe_name(parts[0]) + ver = safe_version(parts[1]) + self.package_pages.setdefault(pkg.lower(), {})[link] = True + return to_filename(pkg), to_filename(ver) + return None, None + + # process an index page into the package-page index + for match in HREF.finditer(page): + try: + scan(urllib.parse.urljoin(url, htmldecode(match.group(1)))) + except ValueError: + pass + + pkg, ver = scan(url) # ensure this page is in the page index + if pkg: + # process individual package page + for new_url in find_external_links(url, page): + # Process the found URL + base, frag = egg_info_for_url(new_url) + if base.endswith('.py') and not frag: + if ver: + new_url += '#egg=%s-%s' % (pkg, ver) + else: + self.need_version_info(url) + self.scan_url(new_url) + + return PYPI_MD5.sub( + lambda m: '<a href="%s#md5=%s">%s</a>' % m.group(1, 3, 2), page + ) + else: + return "" # no sense double-scanning non-package pages + + def need_version_info(self, url): + self.scan_all( + "Page at %s links to .py file(s) without version info; an index " + "scan is required.", url + ) + + def scan_all(self, msg=None, *args): + if self.index_url not in self.fetched_urls: + if msg: + self.warn(msg, *args) + self.info( + "Scanning index of all packages (this may take a while)" + ) + self.scan_url(self.index_url) + + def find_packages(self, requirement): + self.scan_url(self.index_url + requirement.unsafe_name + '/') + + if not self.package_pages.get(requirement.key): + # Fall back to safe version of the name + self.scan_url(self.index_url + requirement.project_name + '/') + + if not self.package_pages.get(requirement.key): + # We couldn't find the target package, so search the index page too + self.not_found_in_index(requirement) + + for url in list(self.package_pages.get(requirement.key, ())): + # scan each page that might be related to the desired package + self.scan_url(url) + + def obtain(self, requirement, installer=None): + self.prescan() + self.find_packages(requirement) + for dist in self[requirement.key]: + if dist in requirement: + return dist + self.debug("%s does not match %s", requirement, dist) + return super(PackageIndex, self).obtain(requirement, installer) + + def check_hash(self, checker, filename, tfp): + """ + checker is a ContentChecker + """ + checker.report( + self.debug, + "Validating %%s checksum for %s" % filename) + if not checker.is_valid(): + tfp.close() + os.unlink(filename) + raise DistutilsError( + "%s validation failed for %s; " + "possible download problem?" + % (checker.hash.name, os.path.basename(filename)) + ) + + def add_find_links(self, urls): + """Add `urls` to the list that will be prescanned for searches""" + for url in urls: + if ( + self.to_scan is None # if we have already "gone online" + or not URL_SCHEME(url) # or it's a local file/directory + or url.startswith('file:') + or list(distros_for_url(url)) # or a direct package link + ): + # then go ahead and process it now + self.scan_url(url) + else: + # otherwise, defer retrieval till later + self.to_scan.append(url) + + def prescan(self): + """Scan urls scheduled for prescanning (e.g. --find-links)""" + if self.to_scan: + list(map(self.scan_url, self.to_scan)) + self.to_scan = None # from now on, go ahead and process immediately + + def not_found_in_index(self, requirement): + if self[requirement.key]: # we've seen at least one distro + meth, msg = self.info, "Couldn't retrieve index page for %r" + else: # no distros seen for this name, might be misspelled + meth, msg = ( + self.warn, + "Couldn't find index page for %r (maybe misspelled?)") + meth(msg, requirement.unsafe_name) + self.scan_all() + + def download(self, spec, tmpdir): + """Locate and/or download `spec` to `tmpdir`, returning a local path + + `spec` may be a ``Requirement`` object, or a string containing a URL, + an existing local filename, or a project/version requirement spec + (i.e. the string form of a ``Requirement`` object). If it is the URL + of a .py file with an unambiguous ``#egg=name-version`` tag (i.e., one + that escapes ``-`` as ``_`` throughout), a trivial ``setup.py`` is + automatically created alongside the downloaded file. + + If `spec` is a ``Requirement`` object or a string containing a + project/version requirement spec, this method returns the location of + a matching distribution (possibly after downloading it to `tmpdir`). + If `spec` is a locally existing file or directory name, it is simply + returned unchanged. If `spec` is a URL, it is downloaded to a subpath + of `tmpdir`, and the local filename is returned. Various errors may be + raised if a problem occurs during downloading. + """ + if not isinstance(spec, Requirement): + scheme = URL_SCHEME(spec) + if scheme: + # It's a url, download it to tmpdir + found = self._download_url(scheme.group(1), spec, tmpdir) + base, fragment = egg_info_for_url(spec) + if base.endswith('.py'): + found = self.gen_setup(found, fragment, tmpdir) + return found + elif os.path.exists(spec): + # Existing file or directory, just return it + return spec + else: + spec = parse_requirement_arg(spec) + return getattr(self.fetch_distribution(spec, tmpdir), 'location', None) + + def fetch_distribution( + self, requirement, tmpdir, force_scan=False, source=False, + develop_ok=False, local_index=None): + """Obtain a distribution suitable for fulfilling `requirement` + + `requirement` must be a ``pkg_resources.Requirement`` instance. + If necessary, or if the `force_scan` flag is set, the requirement is + searched for in the (online) package index as well as the locally + installed packages. If a distribution matching `requirement` is found, + the returned distribution's ``location`` is the value you would have + gotten from calling the ``download()`` method with the matching + distribution's URL or filename. If no matching distribution is found, + ``None`` is returned. + + If the `source` flag is set, only source distributions and source + checkout links will be considered. Unless the `develop_ok` flag is + set, development and system eggs (i.e., those using the ``.egg-info`` + format) will be ignored. + """ + # process a Requirement + self.info("Searching for %s", requirement) + skipped = {} + dist = None + + def find(req, env=None): + if env is None: + env = self + # Find a matching distribution; may be called more than once + + for dist in env[req.key]: + + if dist.precedence == DEVELOP_DIST and not develop_ok: + if dist not in skipped: + self.warn( + "Skipping development or system egg: %s", dist, + ) + skipped[dist] = 1 + continue + + test = ( + dist in req + and (dist.precedence <= SOURCE_DIST or not source) + ) + if test: + loc = self.download(dist.location, tmpdir) + dist.download_location = loc + if os.path.exists(dist.download_location): + return dist + + if force_scan: + self.prescan() + self.find_packages(requirement) + dist = find(requirement) + + if not dist and local_index is not None: + dist = find(requirement, local_index) + + if dist is None: + if self.to_scan is not None: + self.prescan() + dist = find(requirement) + + if dist is None and not force_scan: + self.find_packages(requirement) + dist = find(requirement) + + if dist is None: + self.warn( + "No local packages or working download links found for %s%s", + (source and "a source distribution of " or ""), + requirement, + ) + else: + self.info("Best match: %s", dist) + return dist.clone(location=dist.download_location) + + def fetch(self, requirement, tmpdir, force_scan=False, source=False): + """Obtain a file suitable for fulfilling `requirement` + + DEPRECATED; use the ``fetch_distribution()`` method now instead. For + backward compatibility, this routine is identical but returns the + ``location`` of the downloaded distribution instead of a distribution + object. + """ + dist = self.fetch_distribution(requirement, tmpdir, force_scan, source) + if dist is not None: + return dist.location + return None + + def gen_setup(self, filename, fragment, tmpdir): + match = EGG_FRAGMENT.match(fragment) + dists = match and [ + d for d in + interpret_distro_name(filename, match.group(1), None) if d.version + ] or [] + + if len(dists) == 1: # unambiguous ``#egg`` fragment + basename = os.path.basename(filename) + + # Make sure the file has been downloaded to the temp dir. + if os.path.dirname(filename) != tmpdir: + dst = os.path.join(tmpdir, basename) + from setuptools.command.easy_install import samefile + if not samefile(filename, dst): + shutil.copy2(filename, dst) + filename = dst + + with open(os.path.join(tmpdir, 'setup.py'), 'w') as file: + file.write( + "from setuptools import setup\n" + "setup(name=%r, version=%r, py_modules=[%r])\n" + % ( + dists[0].project_name, dists[0].version, + os.path.splitext(basename)[0] + ) + ) + return filename + + elif match: + raise DistutilsError( + "Can't unambiguously interpret project/version identifier %r; " + "any dashes in the name or version should be escaped using " + "underscores. %r" % (fragment, dists) + ) + else: + raise DistutilsError( + "Can't process plain .py files without an '#egg=name-version'" + " suffix to enable automatic setup script generation." + ) + + dl_blocksize = 8192 + + def _download_to(self, url, filename): + self.info("Downloading %s", url) + # Download the file + fp = None + try: + checker = HashChecker.from_url(url) + fp = self.open_url(url) + if isinstance(fp, urllib.error.HTTPError): + raise DistutilsError( + "Can't download %s: %s %s" % (url, fp.code, fp.msg) + ) + headers = fp.info() + blocknum = 0 + bs = self.dl_blocksize + size = -1 + if "content-length" in headers: + # Some servers return multiple Content-Length headers :( + sizes = get_all_headers(headers, 'Content-Length') + size = max(map(int, sizes)) + self.reporthook(url, filename, blocknum, bs, size) + with open(filename, 'wb') as tfp: + while True: + block = fp.read(bs) + if block: + checker.feed(block) + tfp.write(block) + blocknum += 1 + self.reporthook(url, filename, blocknum, bs, size) + else: + break + self.check_hash(checker, filename, tfp) + return headers + finally: + if fp: + fp.close() + + def reporthook(self, url, filename, blocknum, blksize, size): + pass # no-op + + def open_url(self, url, warning=None): + if url.startswith('file:'): + return local_open(url) + try: + return open_with_auth(url, self.opener) + except (ValueError, http_client.InvalidURL) as v: + msg = ' '.join([str(arg) for arg in v.args]) + if warning: + self.warn(warning, msg) + else: + raise DistutilsError('%s %s' % (url, msg)) + except urllib.error.HTTPError as v: + return v + except urllib.error.URLError as v: + if warning: + self.warn(warning, v.reason) + else: + raise DistutilsError("Download error for %s: %s" + % (url, v.reason)) + except http_client.BadStatusLine as v: + if warning: + self.warn(warning, v.line) + else: + raise DistutilsError( + '%s returned a bad status line. The server might be ' + 'down, %s' % + (url, v.line) + ) + except (http_client.HTTPException, socket.error) as v: + if warning: + self.warn(warning, v) + else: + raise DistutilsError("Download error for %s: %s" + % (url, v)) + + def _download_url(self, scheme, url, tmpdir): + # Determine download filename + # + name, fragment = egg_info_for_url(url) + if name: + while '..' in name: + name = name.replace('..', '.').replace('\\', '_') + else: + name = "__downloaded__" # default if URL has no path contents + + if name.endswith('.egg.zip'): + name = name[:-4] # strip the extra .zip before download + + filename = os.path.join(tmpdir, name) + + # Download the file + # + if scheme == 'svn' or scheme.startswith('svn+'): + return self._download_svn(url, filename) + elif scheme == 'git' or scheme.startswith('git+'): + return self._download_git(url, filename) + elif scheme.startswith('hg+'): + return self._download_hg(url, filename) + elif scheme == 'file': + return urllib.request.url2pathname(urllib.parse.urlparse(url)[2]) + else: + self.url_ok(url, True) # raises error if not allowed + return self._attempt_download(url, filename) + + def scan_url(self, url): + self.process_url(url, True) + + def _attempt_download(self, url, filename): + headers = self._download_to(url, filename) + if 'html' in headers.get('content-type', '').lower(): + return self._download_html(url, headers, filename) + else: + return filename + + def _download_html(self, url, headers, filename): + file = open(filename) + for line in file: + if line.strip(): + # Check for a subversion index page + if re.search(r'<title>([^- ]+ - )?Revision \d+:', line): + # it's a subversion index page: + file.close() + os.unlink(filename) + return self._download_svn(url, filename) + break # not an index page + file.close() + os.unlink(filename) + raise DistutilsError("Unexpected HTML page found at " + url) + + def _download_svn(self, url, filename): + warnings.warn("SVN download support is deprecated", UserWarning) + url = url.split('#', 1)[0] # remove any fragment for svn's sake + creds = '' + if url.lower().startswith('svn:') and '@' in url: + scheme, netloc, path, p, q, f = urllib.parse.urlparse(url) + if not netloc and path.startswith('//') and '/' in path[2:]: + netloc, path = path[2:].split('/', 1) + auth, host = urllib.parse.splituser(netloc) + if auth: + if ':' in auth: + user, pw = auth.split(':', 1) + creds = " --username=%s --password=%s" % (user, pw) + else: + creds = " --username=" + auth + netloc = host + parts = scheme, netloc, url, p, q, f + url = urllib.parse.urlunparse(parts) + self.info("Doing subversion checkout from %s to %s", url, filename) + os.system("svn checkout%s -q %s %s" % (creds, url, filename)) + return filename + + @staticmethod + def _vcs_split_rev_from_url(url, pop_prefix=False): + scheme, netloc, path, query, frag = urllib.parse.urlsplit(url) + + scheme = scheme.split('+', 1)[-1] + + # Some fragment identification fails + path = path.split('#', 1)[0] + + rev = None + if '@' in path: + path, rev = path.rsplit('@', 1) + + # Also, discard fragment + url = urllib.parse.urlunsplit((scheme, netloc, path, query, '')) + + return url, rev + + def _download_git(self, url, filename): + filename = filename.split('#', 1)[0] + url, rev = self._vcs_split_rev_from_url(url, pop_prefix=True) + + self.info("Doing git clone from %s to %s", url, filename) + os.system("git clone --quiet %s %s" % (url, filename)) + + if rev is not None: + self.info("Checking out %s", rev) + os.system("(cd %s && git checkout --quiet %s)" % ( + filename, + rev, + )) + + return filename + + def _download_hg(self, url, filename): + filename = filename.split('#', 1)[0] + url, rev = self._vcs_split_rev_from_url(url, pop_prefix=True) + + self.info("Doing hg clone from %s to %s", url, filename) + os.system("hg clone --quiet %s %s" % (url, filename)) + + if rev is not None: + self.info("Updating to %s", rev) + os.system("(cd %s && hg up -C -r %s -q)" % ( + filename, + rev, + )) + + return filename + + def debug(self, msg, *args): + log.debug(msg, *args) + + def info(self, msg, *args): + log.info(msg, *args) + + def warn(self, msg, *args): + log.warn(msg, *args) + + +# This pattern matches a character entity reference (a decimal numeric +# references, a hexadecimal numeric reference, or a named reference). +entity_sub = re.compile(r'&(#(\d+|x[\da-fA-F]+)|[\w.:-]+);?').sub + + +def decode_entity(match): + what = match.group(0) + return unescape(what) + + +def htmldecode(text): + """ + Decode HTML entities in the given text. + + >>> htmldecode( + ... 'https://../package_name-0.1.2.tar.gz' + ... '?tokena=A&tokenb=B">package_name-0.1.2.tar.gz') + 'https://../package_name-0.1.2.tar.gz?tokena=A&tokenb=B">package_name-0.1.2.tar.gz' + """ + return entity_sub(decode_entity, text) + + +def socket_timeout(timeout=15): + def _socket_timeout(func): + def _socket_timeout(*args, **kwargs): + old_timeout = socket.getdefaulttimeout() + socket.setdefaulttimeout(timeout) + try: + return func(*args, **kwargs) + finally: + socket.setdefaulttimeout(old_timeout) + + return _socket_timeout + + return _socket_timeout + + +def _encode_auth(auth): + """ + A function compatible with Python 2.3-3.3 that will encode + auth from a URL suitable for an HTTP header. + >>> str(_encode_auth('username%3Apassword')) + 'dXNlcm5hbWU6cGFzc3dvcmQ=' + + Long auth strings should not cause a newline to be inserted. + >>> long_auth = 'username:' + 'password'*10 + >>> chr(10) in str(_encode_auth(long_auth)) + False + """ + auth_s = urllib.parse.unquote(auth) + # convert to bytes + auth_bytes = auth_s.encode() + encoded_bytes = base64.b64encode(auth_bytes) + # convert back to a string + encoded = encoded_bytes.decode() + # strip the trailing carriage return + return encoded.replace('\n', '') + + +class Credential: + """ + A username/password pair. Use like a namedtuple. + """ + + def __init__(self, username, password): + self.username = username + self.password = password + + def __iter__(self): + yield self.username + yield self.password + + def __str__(self): + return '%(username)s:%(password)s' % vars(self) + + +class PyPIConfig(configparser.RawConfigParser): + def __init__(self): + """ + Load from ~/.pypirc + """ + defaults = dict.fromkeys(['username', 'password', 'repository'], '') + configparser.RawConfigParser.__init__(self, defaults) + + rc = os.path.join(os.path.expanduser('~'), '.pypirc') + if os.path.exists(rc): + self.read(rc) + + @property + def creds_by_repository(self): + sections_with_repositories = [ + section for section in self.sections() + if self.get(section, 'repository').strip() + ] + + return dict(map(self._get_repo_cred, sections_with_repositories)) + + def _get_repo_cred(self, section): + repo = self.get(section, 'repository').strip() + return repo, Credential( + self.get(section, 'username').strip(), + self.get(section, 'password').strip(), + ) + + def find_credential(self, url): + """ + If the URL indicated appears to be a repository defined in this + config, return the credential for that repository. + """ + for repository, cred in self.creds_by_repository.items(): + if url.startswith(repository): + return cred + + +def open_with_auth(url, opener=urllib.request.urlopen): + """Open a urllib2 request, handling HTTP authentication""" + + scheme, netloc, path, params, query, frag = urllib.parse.urlparse(url) + + # Double scheme does not raise on Mac OS X as revealed by a + # failing test. We would expect "nonnumeric port". Refs #20. + if netloc.endswith(':'): + raise http_client.InvalidURL("nonnumeric port: ''") + + if scheme in ('http', 'https'): + auth, host = urllib.parse.splituser(netloc) + else: + auth = None + + if not auth: + cred = PyPIConfig().find_credential(url) + if cred: + auth = str(cred) + info = cred.username, url + log.info('Authenticating as %s for %s (from .pypirc)', *info) + + if auth: + auth = "Basic " + _encode_auth(auth) + parts = scheme, host, path, params, query, frag + new_url = urllib.parse.urlunparse(parts) + request = urllib.request.Request(new_url) + request.add_header("Authorization", auth) + else: + request = urllib.request.Request(url) + + request.add_header('User-Agent', user_agent) + fp = opener(request) + + if auth: + # Put authentication info back into request URL if same host, + # so that links found on the page will work + s2, h2, path2, param2, query2, frag2 = urllib.parse.urlparse(fp.url) + if s2 == scheme and h2 == host: + parts = s2, netloc, path2, param2, query2, frag2 + fp.url = urllib.parse.urlunparse(parts) + + return fp + + +# adding a timeout to avoid freezing package_index +open_with_auth = socket_timeout(_SOCKET_TIMEOUT)(open_with_auth) + + +def fix_sf_url(url): + return url # backward compatibility + + +def local_open(url): + """Read a local path, with special support for directories""" + scheme, server, path, param, query, frag = urllib.parse.urlparse(url) + filename = urllib.request.url2pathname(path) + if os.path.isfile(filename): + return urllib.request.urlopen(url) + elif path.endswith('/') and os.path.isdir(filename): + files = [] + for f in os.listdir(filename): + filepath = os.path.join(filename, f) + if f == 'index.html': + with open(filepath, 'r') as fp: + body = fp.read() + break + elif os.path.isdir(filepath): + f += '/' + files.append('<a href="{name}">{name}</a>'.format(name=f)) + else: + tmpl = ( + "<html><head><title>{url}" + "{files}") + body = tmpl.format(url=url, files='\n'.join(files)) + status, message = 200, "OK" + else: + status, message, body = 404, "Path not found", "Not found" + + headers = {'content-type': 'text/html'} + body_stream = six.StringIO(body) + return urllib.error.HTTPError(url, status, message, headers, body_stream) diff --git a/venv/lib/python3.7/site-packages/setuptools/pep425tags.py b/venv/lib/python3.7/site-packages/setuptools/pep425tags.py new file mode 100644 index 0000000..8bf4277 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/pep425tags.py @@ -0,0 +1,319 @@ +# 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 an 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.7/site-packages/setuptools/py27compat.py b/venv/lib/python3.7/site-packages/setuptools/py27compat.py new file mode 100644 index 0000000..2985011 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/py27compat.py @@ -0,0 +1,28 @@ +""" +Compatibility Support for Python 2.7 and earlier +""" + +import platform + +from setuptools.extern import six + + +def get_all_headers(message, key): + """ + Given an HTTPMessage, return all headers matching a given key. + """ + return message.get_all(key) + + +if six.PY2: + def get_all_headers(message, key): + return message.getheaders(key) + + +linux_py2_ascii = ( + platform.system() == 'Linux' and + six.PY2 +) + +rmtree_safe = str if linux_py2_ascii else lambda x: x +"""Workaround for http://bugs.python.org/issue24672""" diff --git a/venv/lib/python3.7/site-packages/setuptools/py31compat.py b/venv/lib/python3.7/site-packages/setuptools/py31compat.py new file mode 100644 index 0000000..1a0705e --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/py31compat.py @@ -0,0 +1,32 @@ +__all__ = [] + +__metaclass__ = type + + +try: + # Python >=3.2 + from tempfile import TemporaryDirectory +except ImportError: + import shutil + import tempfile + + class TemporaryDirectory: + """ + Very simple temporary directory context manager. + Will try to delete afterward, but will also ignore OS and similar + errors on deletion. + """ + + def __init__(self): + self.name = None # Handle mkdtemp raising an exception + self.name = tempfile.mkdtemp() + + def __enter__(self): + return self.name + + def __exit__(self, exctype, excvalue, exctrace): + try: + shutil.rmtree(self.name, True) + except OSError: # removal errors are not the only possible + pass + self.name = None diff --git a/venv/lib/python3.7/site-packages/setuptools/py33compat.py b/venv/lib/python3.7/site-packages/setuptools/py33compat.py new file mode 100644 index 0000000..87cf539 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/py33compat.py @@ -0,0 +1,55 @@ +import dis +import array +import collections + +try: + import html +except ImportError: + html = None + +from setuptools.extern import six +from setuptools.extern.six.moves import html_parser + +__metaclass__ = type + +OpArg = collections.namedtuple('OpArg', 'opcode arg') + + +class Bytecode_compat: + def __init__(self, code): + self.code = code + + def __iter__(self): + """Yield '(op,arg)' pair for each operation in code object 'code'""" + + bytes = array.array('b', self.code.co_code) + eof = len(self.code.co_code) + + ptr = 0 + extended_arg = 0 + + while ptr < eof: + + op = bytes[ptr] + + if op >= dis.HAVE_ARGUMENT: + + arg = bytes[ptr + 1] + bytes[ptr + 2] * 256 + extended_arg + ptr += 3 + + if op == dis.EXTENDED_ARG: + long_type = six.integer_types[-1] + extended_arg = arg * long_type(65536) + continue + + else: + arg = None + ptr += 1 + + yield OpArg(op, arg) + + +Bytecode = getattr(dis, 'Bytecode', Bytecode_compat) + + +unescape = getattr(html, 'unescape', html_parser.HTMLParser().unescape) diff --git a/venv/lib/python3.7/site-packages/setuptools/py36compat.py b/venv/lib/python3.7/site-packages/setuptools/py36compat.py new file mode 100644 index 0000000..f527969 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/py36compat.py @@ -0,0 +1,82 @@ +import sys +from distutils.errors import DistutilsOptionError +from distutils.util import strtobool +from distutils.debug import DEBUG + + +class Distribution_parse_config_files: + """ + Mix-in providing forward-compatibility for functionality to be + included by default on Python 3.7. + + Do not edit the code in this class except to update functionality + as implemented in distutils. + """ + def parse_config_files(self, filenames=None): + from configparser import ConfigParser + + # Ignore install directory options if we have a venv + if sys.prefix != sys.base_prefix: + ignore_options = [ + 'install-base', 'install-platbase', 'install-lib', + 'install-platlib', 'install-purelib', 'install-headers', + 'install-scripts', 'install-data', 'prefix', 'exec-prefix', + 'home', 'user', 'root'] + else: + ignore_options = [] + + ignore_options = frozenset(ignore_options) + + if filenames is None: + filenames = self.find_config_files() + + if DEBUG: + self.announce("Distribution.parse_config_files():") + + parser = ConfigParser(interpolation=None) + for filename in filenames: + if DEBUG: + self.announce(" reading %s" % filename) + parser.read(filename) + for section in parser.sections(): + options = parser.options(section) + opt_dict = self.get_option_dict(section) + + for opt in options: + if opt != '__name__' and opt not in ignore_options: + val = parser.get(section,opt) + opt = opt.replace('-', '_') + opt_dict[opt] = (filename, val) + + # Make the ConfigParser forget everything (so we retain + # the original filenames that options come from) + parser.__init__() + + # If there was a "global" section in the config file, use it + # to set Distribution options. + + if 'global' in self.command_options: + for (opt, (src, val)) in self.command_options['global'].items(): + alias = self.negative_opt.get(opt) + try: + if alias: + setattr(self, alias, not strtobool(val)) + elif opt in ('verbose', 'dry_run'): # ugh! + setattr(self, opt, strtobool(val)) + else: + setattr(self, opt, val) + except ValueError as msg: + raise DistutilsOptionError(msg) + + +if sys.version_info < (3,): + # Python 2 behavior is sufficient + class Distribution_parse_config_files: + pass + + +if False: + # When updated behavior is available upstream, + # disable override here. + class Distribution_parse_config_files: + pass diff --git a/venv/lib/python3.7/site-packages/setuptools/sandbox.py b/venv/lib/python3.7/site-packages/setuptools/sandbox.py new file mode 100644 index 0000000..685f3f7 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/sandbox.py @@ -0,0 +1,491 @@ +import os +import sys +import tempfile +import operator +import functools +import itertools +import re +import contextlib +import pickle +import textwrap + +from setuptools.extern import six +from setuptools.extern.six.moves import builtins, map + +import pkg_resources.py31compat + +if sys.platform.startswith('java'): + import org.python.modules.posix.PosixModule as _os +else: + _os = sys.modules[os.name] +try: + _file = file +except NameError: + _file = None +_open = open +from distutils.errors import DistutilsError +from pkg_resources import working_set + + +__all__ = [ + "AbstractSandbox", "DirectorySandbox", "SandboxViolation", "run_setup", +] + + +def _execfile(filename, globals, locals=None): + """ + Python 3 implementation of execfile. + """ + mode = 'rb' + with open(filename, mode) as stream: + script = stream.read() + if locals is None: + locals = globals + code = compile(script, filename, 'exec') + exec(code, globals, locals) + + +@contextlib.contextmanager +def save_argv(repl=None): + saved = sys.argv[:] + if repl is not None: + sys.argv[:] = repl + try: + yield saved + finally: + sys.argv[:] = saved + + +@contextlib.contextmanager +def save_path(): + saved = sys.path[:] + try: + yield saved + finally: + sys.path[:] = saved + + +@contextlib.contextmanager +def override_temp(replacement): + """ + Monkey-patch tempfile.tempdir with replacement, ensuring it exists + """ + pkg_resources.py31compat.makedirs(replacement, exist_ok=True) + + saved = tempfile.tempdir + + tempfile.tempdir = replacement + + try: + yield + finally: + tempfile.tempdir = saved + + +@contextlib.contextmanager +def pushd(target): + saved = os.getcwd() + os.chdir(target) + try: + yield saved + finally: + os.chdir(saved) + + +class UnpickleableException(Exception): + """ + An exception representing another Exception that could not be pickled. + """ + + @staticmethod + def dump(type, exc): + """ + Always return a dumped (pickled) type and exc. If exc can't be pickled, + wrap it in UnpickleableException first. + """ + try: + return pickle.dumps(type), pickle.dumps(exc) + except Exception: + # get UnpickleableException inside the sandbox + from setuptools.sandbox import UnpickleableException as cls + return cls.dump(cls, cls(repr(exc))) + + +class ExceptionSaver: + """ + A Context Manager that will save an exception, serialized, and restore it + later. + """ + + def __enter__(self): + return self + + def __exit__(self, type, exc, tb): + if not exc: + return + + # dump the exception + self._saved = UnpickleableException.dump(type, exc) + self._tb = tb + + # suppress the exception + return True + + def resume(self): + "restore and re-raise any exception" + + if '_saved' not in vars(self): + return + + type, exc = map(pickle.loads, self._saved) + six.reraise(type, exc, self._tb) + + +@contextlib.contextmanager +def save_modules(): + """ + Context in which imported modules are saved. + + Translates exceptions internal to the context into the equivalent exception + outside the context. + """ + saved = sys.modules.copy() + with ExceptionSaver() as saved_exc: + yield saved + + sys.modules.update(saved) + # remove any modules imported since + del_modules = ( + mod_name for mod_name in sys.modules + if mod_name not in saved + # exclude any encodings modules. See #285 + and not mod_name.startswith('encodings.') + ) + _clear_modules(del_modules) + + saved_exc.resume() + + +def _clear_modules(module_names): + for mod_name in list(module_names): + del sys.modules[mod_name] + + +@contextlib.contextmanager +def save_pkg_resources_state(): + saved = pkg_resources.__getstate__() + try: + yield saved + finally: + pkg_resources.__setstate__(saved) + + +@contextlib.contextmanager +def setup_context(setup_dir): + temp_dir = os.path.join(setup_dir, 'temp') + with save_pkg_resources_state(): + with save_modules(): + hide_setuptools() + with save_path(): + with save_argv(): + with override_temp(temp_dir): + with pushd(setup_dir): + # ensure setuptools commands are available + __import__('setuptools') + yield + + +def _needs_hiding(mod_name): + """ + >>> _needs_hiding('setuptools') + True + >>> _needs_hiding('pkg_resources') + True + >>> _needs_hiding('setuptools_plugin') + False + >>> _needs_hiding('setuptools.__init__') + True + >>> _needs_hiding('distutils') + True + >>> _needs_hiding('os') + False + >>> _needs_hiding('Cython') + True + """ + pattern = re.compile(r'(setuptools|pkg_resources|distutils|Cython)(\.|$)') + return bool(pattern.match(mod_name)) + + +def hide_setuptools(): + """ + Remove references to setuptools' modules from sys.modules to allow the + invocation to import the most appropriate setuptools. This technique is + necessary to avoid issues such as #315 where setuptools upgrading itself + would fail to find a function declared in the metadata. + """ + modules = filter(_needs_hiding, sys.modules) + _clear_modules(modules) + + +def run_setup(setup_script, args): + """Run a distutils setup script, sandboxed in its directory""" + setup_dir = os.path.abspath(os.path.dirname(setup_script)) + with setup_context(setup_dir): + try: + sys.argv[:] = [setup_script] + list(args) + sys.path.insert(0, setup_dir) + # reset to include setup dir, w/clean callback list + working_set.__init__() + working_set.callbacks.append(lambda dist: dist.activate()) + + # __file__ should be a byte string on Python 2 (#712) + dunder_file = ( + setup_script + if isinstance(setup_script, str) else + setup_script.encode(sys.getfilesystemencoding()) + ) + + with DirectorySandbox(setup_dir): + ns = dict(__file__=dunder_file, __name__='__main__') + _execfile(setup_script, ns) + except SystemExit as v: + if v.args and v.args[0]: + raise + # Normal exit, just return + + +class AbstractSandbox: + """Wrap 'os' module and 'open()' builtin for virtualizing setup scripts""" + + _active = False + + def __init__(self): + self._attrs = [ + name for name in dir(_os) + if not name.startswith('_') and hasattr(self, name) + ] + + def _copy(self, source): + for name in self._attrs: + setattr(os, name, getattr(source, name)) + + def __enter__(self): + self._copy(self) + if _file: + builtins.file = self._file + builtins.open = self._open + self._active = True + + def __exit__(self, exc_type, exc_value, traceback): + self._active = False + if _file: + builtins.file = _file + builtins.open = _open + self._copy(_os) + + def run(self, func): + """Run 'func' under os sandboxing""" + with self: + return func() + + def _mk_dual_path_wrapper(name): + original = getattr(_os, name) + + def wrap(self, src, dst, *args, **kw): + if self._active: + src, dst = self._remap_pair(name, src, dst, *args, **kw) + return original(src, dst, *args, **kw) + + return wrap + + for name in ["rename", "link", "symlink"]: + if hasattr(_os, name): + locals()[name] = _mk_dual_path_wrapper(name) + + def _mk_single_path_wrapper(name, original=None): + original = original or getattr(_os, name) + + def wrap(self, path, *args, **kw): + if self._active: + path = self._remap_input(name, path, *args, **kw) + return original(path, *args, **kw) + + return wrap + + if _file: + _file = _mk_single_path_wrapper('file', _file) + _open = _mk_single_path_wrapper('open', _open) + for name in [ + "stat", "listdir", "chdir", "open", "chmod", "chown", "mkdir", + "remove", "unlink", "rmdir", "utime", "lchown", "chroot", "lstat", + "startfile", "mkfifo", "mknod", "pathconf", "access" + ]: + if hasattr(_os, name): + locals()[name] = _mk_single_path_wrapper(name) + + def _mk_single_with_return(name): + original = getattr(_os, name) + + def wrap(self, path, *args, **kw): + if self._active: + path = self._remap_input(name, path, *args, **kw) + return self._remap_output(name, original(path, *args, **kw)) + return original(path, *args, **kw) + + return wrap + + for name in ['readlink', 'tempnam']: + if hasattr(_os, name): + locals()[name] = _mk_single_with_return(name) + + def _mk_query(name): + original = getattr(_os, name) + + def wrap(self, *args, **kw): + retval = original(*args, **kw) + if self._active: + return self._remap_output(name, retval) + return retval + + return wrap + + for name in ['getcwd', 'tmpnam']: + if hasattr(_os, name): + locals()[name] = _mk_query(name) + + def _validate_path(self, path): + """Called to remap or validate any path, whether input or output""" + return path + + def _remap_input(self, operation, path, *args, **kw): + """Called for path inputs""" + return self._validate_path(path) + + def _remap_output(self, operation, path): + """Called for path outputs""" + return self._validate_path(path) + + def _remap_pair(self, operation, src, dst, *args, **kw): + """Called for path pairs like rename, link, and symlink operations""" + return ( + self._remap_input(operation + '-from', src, *args, **kw), + self._remap_input(operation + '-to', dst, *args, **kw) + ) + + +if hasattr(os, 'devnull'): + _EXCEPTIONS = [os.devnull,] +else: + _EXCEPTIONS = [] + + +class DirectorySandbox(AbstractSandbox): + """Restrict operations to a single subdirectory - pseudo-chroot""" + + write_ops = dict.fromkeys([ + "open", "chmod", "chown", "mkdir", "remove", "unlink", "rmdir", + "utime", "lchown", "chroot", "mkfifo", "mknod", "tempnam", + ]) + + _exception_patterns = [ + # Allow lib2to3 to attempt to save a pickled grammar object (#121) + r'.*lib2to3.*\.pickle$', + ] + "exempt writing to paths that match the pattern" + + def __init__(self, sandbox, exceptions=_EXCEPTIONS): + self._sandbox = os.path.normcase(os.path.realpath(sandbox)) + self._prefix = os.path.join(self._sandbox, '') + self._exceptions = [ + os.path.normcase(os.path.realpath(path)) + for path in exceptions + ] + AbstractSandbox.__init__(self) + + def _violation(self, operation, *args, **kw): + from setuptools.sandbox import SandboxViolation + raise SandboxViolation(operation, args, kw) + + if _file: + + def _file(self, path, mode='r', *args, **kw): + if mode not in ('r', 'rt', 'rb', 'rU', 'U') and not self._ok(path): + self._violation("file", path, mode, *args, **kw) + return _file(path, mode, *args, **kw) + + def _open(self, path, mode='r', *args, **kw): + if mode not in ('r', 'rt', 'rb', 'rU', 'U') and not self._ok(path): + self._violation("open", path, mode, *args, **kw) + return _open(path, mode, *args, **kw) + + def tmpnam(self): + self._violation("tmpnam") + + def _ok(self, path): + active = self._active + try: + self._active = False + realpath = os.path.normcase(os.path.realpath(path)) + return ( + self._exempted(realpath) + or realpath == self._sandbox + or realpath.startswith(self._prefix) + ) + finally: + self._active = active + + def _exempted(self, filepath): + start_matches = ( + filepath.startswith(exception) + for exception in self._exceptions + ) + pattern_matches = ( + re.match(pattern, filepath) + for pattern in self._exception_patterns + ) + candidates = itertools.chain(start_matches, pattern_matches) + return any(candidates) + + def _remap_input(self, operation, path, *args, **kw): + """Called for path inputs""" + if operation in self.write_ops and not self._ok(path): + self._violation(operation, os.path.realpath(path), *args, **kw) + return path + + def _remap_pair(self, operation, src, dst, *args, **kw): + """Called for path pairs like rename, link, and symlink operations""" + if not self._ok(src) or not self._ok(dst): + self._violation(operation, src, dst, *args, **kw) + return (src, dst) + + def open(self, file, flags, mode=0o777, *args, **kw): + """Called for low-level os.open()""" + if flags & WRITE_FLAGS and not self._ok(file): + self._violation("os.open", file, flags, mode, *args, **kw) + return _os.open(file, flags, mode, *args, **kw) + + +WRITE_FLAGS = functools.reduce( + operator.or_, [getattr(_os, a, 0) for a in + "O_WRONLY O_RDWR O_APPEND O_CREAT O_TRUNC O_TEMPORARY".split()] +) + + +class SandboxViolation(DistutilsError): + """A setup script attempted to modify the filesystem outside the sandbox""" + + tmpl = textwrap.dedent(""" + SandboxViolation: {cmd}{args!r} {kwargs} + + The package setup script has attempted to modify files on your system + that are not within the EasyInstall build area, and has been aborted. + + This package cannot be safely installed by EasyInstall, and may not + support alternate installation locations even if you run its setup + script by hand. Please inform the package's author and the EasyInstall + maintainers to find out if a fix or workaround is available. + """).lstrip() + + def __str__(self): + cmd, args, kwargs = self.args + return self.tmpl.format(**locals()) diff --git a/venv/lib/python3.7/site-packages/setuptools/script (dev).tmpl b/venv/lib/python3.7/site-packages/setuptools/script (dev).tmpl new file mode 100644 index 0000000..39a24b0 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/script (dev).tmpl @@ -0,0 +1,6 @@ +# EASY-INSTALL-DEV-SCRIPT: %(spec)r,%(script_name)r +__requires__ = %(spec)r +__import__('pkg_resources').require(%(spec)r) +__file__ = %(dev_path)r +with open(__file__) as f: + exec(compile(f.read(), __file__, 'exec')) diff --git a/venv/lib/python3.7/site-packages/setuptools/script.tmpl b/venv/lib/python3.7/site-packages/setuptools/script.tmpl new file mode 100644 index 0000000..ff5efbc --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/script.tmpl @@ -0,0 +1,3 @@ +# EASY-INSTALL-SCRIPT: %(spec)r,%(script_name)r +__requires__ = %(spec)r +__import__('pkg_resources').run_script(%(spec)r, %(script_name)r) diff --git a/venv/lib/python3.7/site-packages/setuptools/site-patch.py b/venv/lib/python3.7/site-packages/setuptools/site-patch.py new file mode 100644 index 0000000..40b00de --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/site-patch.py @@ -0,0 +1,74 @@ +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.7/site-packages/setuptools/ssl_support.py b/venv/lib/python3.7/site-packages/setuptools/ssl_support.py new file mode 100644 index 0000000..6362f1f --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/ssl_support.py @@ -0,0 +1,260 @@ +import os +import socket +import atexit +import re +import functools + +from setuptools.extern.six.moves import urllib, http_client, map, filter + +from pkg_resources import ResolutionError, ExtractionError + +try: + import ssl +except ImportError: + ssl = None + +__all__ = [ + 'VerifyingHTTPSHandler', 'find_ca_bundle', 'is_available', 'cert_paths', + 'opener_for' +] + +cert_paths = """ +/etc/pki/tls/certs/ca-bundle.crt +/etc/ssl/certs/ca-certificates.crt +/usr/share/ssl/certs/ca-bundle.crt +/usr/local/share/certs/ca-root.crt +/etc/ssl/cert.pem +/System/Library/OpenSSL/certs/cert.pem +/usr/local/share/certs/ca-root-nss.crt +/etc/ssl/ca-bundle.pem +""".strip().split() + +try: + HTTPSHandler = urllib.request.HTTPSHandler + HTTPSConnection = http_client.HTTPSConnection +except AttributeError: + HTTPSHandler = HTTPSConnection = object + +is_available = ssl is not None and object not in (HTTPSHandler, HTTPSConnection) + + +try: + from ssl import CertificateError, match_hostname +except ImportError: + try: + from backports.ssl_match_hostname import CertificateError + from backports.ssl_match_hostname import match_hostname + except ImportError: + CertificateError = None + match_hostname = None + +if not CertificateError: + + class CertificateError(ValueError): + pass + + +if not match_hostname: + + def _dnsname_match(dn, hostname, max_wildcards=1): + """Matching according to RFC 6125, section 6.4.3 + + http://tools.ietf.org/html/rfc6125#section-6.4.3 + """ + pats = [] + if not dn: + return False + + # Ported from python3-syntax: + # leftmost, *remainder = dn.split(r'.') + parts = dn.split(r'.') + leftmost = parts[0] + remainder = parts[1:] + + 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)) + + # speed up common case w/o wildcards + if not wildcards: + 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. + 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--'): + # 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 + # U-label of an internationalized domain name. + pats.append(re.escape(leftmost)) + else: + # Otherwise, '*' matches any dotless string, e.g. www* + 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) + return pat.match(hostname) + + def match_hostname(cert, hostname): + """Verify that *cert* (in decoded format as returned by + SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125 + rules are followed, but IP addresses are not accepted for *hostname*. + + CertificateError is raised on failure. On success, the function + returns nothing. + """ + if not cert: + raise ValueError("empty or no certificate") + dnsnames = [] + san = cert.get('subjectAltName', ()) + for key, value in san: + if key == 'DNS': + if _dnsname_match(value, hostname): + 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 key, value in sub: + # XXX according to RFC 2818, the most specific Common Name + # must be used. + 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)))) + elif len(dnsnames) == 1: + raise CertificateError("hostname %r " + "doesn't match %r" + % (hostname, dnsnames[0])) + else: + raise CertificateError("no appropriate commonName or " + "subjectAltName fields were found") + + +class VerifyingHTTPSHandler(HTTPSHandler): + """Simple verifying handler: no auth, subclasses, timeouts, etc.""" + + def __init__(self, ca_bundle): + self.ca_bundle = ca_bundle + HTTPSHandler.__init__(self) + + def https_open(self, req): + return self.do_open( + lambda host, **kw: VerifyingHTTPSConn(host, self.ca_bundle, **kw), req + ) + + +class VerifyingHTTPSConn(HTTPSConnection): + """Simple verifying connection: no auth, subclasses, timeouts, etc.""" + + def __init__(self, host, ca_bundle, **kw): + HTTPSConnection.__init__(self, host, **kw) + self.ca_bundle = ca_bundle + + def connect(self): + sock = socket.create_connection( + (self.host, self.port), getattr(self, 'source_address', None) + ) + + # Handle the socket if a (proxy) tunnel is present + if hasattr(self, '_tunnel') and getattr(self, '_tunnel_host', None): + self.sock = sock + self._tunnel() + # http://bugs.python.org/issue7776: Python>=3.4.1 and >=2.7.7 + # change self.host to mean the proxy server host when tunneling is + # being used. Adapt, since we are interested in the destination + # host for the match_hostname() comparison. + actual_host = self._tunnel_host + else: + actual_host = self.host + + if hasattr(ssl, 'create_default_context'): + ctx = ssl.create_default_context(cafile=self.ca_bundle) + self.sock = ctx.wrap_socket(sock, server_hostname=actual_host) + else: + # This is for python < 2.7.9 and < 3.4? + self.sock = ssl.wrap_socket( + sock, cert_reqs=ssl.CERT_REQUIRED, ca_certs=self.ca_bundle + ) + try: + match_hostname(self.sock.getpeercert(), actual_host) + except CertificateError: + self.sock.shutdown(socket.SHUT_RDWR) + self.sock.close() + raise + + +def opener_for(ca_bundle=None): + """Get a urlopen() replacement that uses ca_bundle for verification""" + return urllib.request.build_opener( + VerifyingHTTPSHandler(ca_bundle or find_ca_bundle()) + ).open + + +# from jaraco.functools +def once(func): + @functools.wraps(func) + def wrapper(*args, **kwargs): + if not hasattr(func, 'always_returns'): + func.always_returns = func(*args, **kwargs) + return func.always_returns + return wrapper + + +@once +def get_win_certfile(): + try: + import wincertstore + except ImportError: + return None + + class CertFile(wincertstore.CertFile): + def __init__(self): + super(CertFile, self).__init__() + atexit.register(self.close) + + def close(self): + try: + super(CertFile, self).close() + except OSError: + pass + + _wincerts = CertFile() + _wincerts.addstore('CA') + _wincerts.addstore('ROOT') + return _wincerts.name + + +def find_ca_bundle(): + """Return an existing CA bundle path, or None""" + extant_cert_paths = filter(os.path.isfile, cert_paths) + return ( + get_win_certfile() + or next(extant_cert_paths, None) + or _certifi_where() + ) + + +def _certifi_where(): + try: + return __import__('certifi').where() + except (ImportError, ResolutionError, ExtractionError): + pass diff --git a/venv/lib/python3.7/site-packages/setuptools/unicode_utils.py b/venv/lib/python3.7/site-packages/setuptools/unicode_utils.py new file mode 100644 index 0000000..7c63efd --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/unicode_utils.py @@ -0,0 +1,44 @@ +import unicodedata +import sys + +from setuptools.extern import six + + +# HFS Plus uses decomposed UTF-8 +def decompose(path): + if isinstance(path, six.text_type): + return unicodedata.normalize('NFD', path) + try: + path = path.decode('utf-8') + path = unicodedata.normalize('NFD', path) + path = path.encode('utf-8') + except UnicodeError: + pass # Not UTF-8 + return path + + +def filesys_decode(path): + """ + Ensure that the given path is decoded, + NONE when no expected encoding works + """ + + if isinstance(path, six.text_type): + return path + + fs_enc = sys.getfilesystemencoding() or 'utf-8' + candidates = fs_enc, 'utf-8' + + for enc in candidates: + try: + return path.decode(enc) + except UnicodeDecodeError: + continue + + +def try_encode(string, enc): + "turn unicode encoding into a functional routine" + try: + return string.encode(enc) + except UnicodeEncodeError: + return None diff --git a/venv/lib/python3.7/site-packages/setuptools/version.py b/venv/lib/python3.7/site-packages/setuptools/version.py new file mode 100644 index 0000000..95e1869 --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/version.py @@ -0,0 +1,6 @@ +import pkg_resources + +try: + __version__ = pkg_resources.get_distribution('setuptools').version +except Exception: + __version__ = 'unknown' diff --git a/venv/lib/python3.7/site-packages/setuptools/wheel.py b/venv/lib/python3.7/site-packages/setuptools/wheel.py new file mode 100644 index 0000000..95a794a --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/wheel.py @@ -0,0 +1,210 @@ +"""Wheels support.""" + +from distutils.util import get_platform +import email +import itertools +import os +import posixpath +import re +import zipfile + +from pkg_resources import Distribution, PathMetadata, parse_version +from setuptools.extern.packaging.utils import canonicalize_name +from setuptools.extern.six import PY3 +from setuptools import Distribution as SetuptoolsDistribution +from setuptools import pep425tags +from setuptools.command.egg_info import write_requirements + + +__metaclass__ = type + + +WHEEL_NAME = re.compile( + r"""^(?P.+?)-(?P\d.*?) + ((-(?P\d.*?))?-(?P.+?)-(?P.+?)-(?P.+?) + )\.whl$""", + re.VERBOSE).match + +NAMESPACE_PACKAGE_INIT = '''\ +try: + __import__('pkg_resources').declare_namespace(__name__) +except ImportError: + __path__ = __import__('pkgutil').extend_path(__path__, __name__) +''' + + +def unpack(src_dir, dst_dir): + '''Move everything under `src_dir` to `dst_dir`, and delete the former.''' + for dirpath, dirnames, filenames in os.walk(src_dir): + subdir = os.path.relpath(dirpath, src_dir) + for f in filenames: + src = os.path.join(dirpath, f) + dst = os.path.join(dst_dir, subdir, f) + os.renames(src, dst) + for n, d in reversed(list(enumerate(dirnames))): + src = os.path.join(dirpath, d) + dst = os.path.join(dst_dir, subdir, d) + if not os.path.exists(dst): + # Directory does not exist in destination, + # rename it and prune it from os.walk list. + os.renames(src, dst) + del dirnames[n] + # Cleanup. + for dirpath, dirnames, filenames in os.walk(src_dir, topdown=True): + assert not filenames + os.rmdir(dirpath) + + +class Wheel: + + def __init__(self, filename): + match = WHEEL_NAME(os.path.basename(filename)) + if match is None: + raise ValueError('invalid wheel name: %r' % filename) + self.filename = filename + for k, v in match.groupdict().items(): + setattr(self, k, v) + + def tags(self): + '''List tags (py_version, abi, platform) supported by this wheel.''' + return itertools.product( + self.py_version.split('.'), + self.abi.split('.'), + self.platform.split('.'), + ) + + def is_compatible(self): + '''Is the wheel is compatible with the current platform?''' + supported_tags = pep425tags.get_supported() + return next((True for t in self.tags() if t in supported_tags), False) + + def egg_name(self): + return Distribution( + project_name=self.project_name, version=self.version, + platform=(None if self.platform == 'any' else get_platform()), + ).egg_name() + '.egg' + + def get_dist_info(self, zf): + # find the correct name of the .dist-info dir in the wheel file + for member in zf.namelist(): + dirname = posixpath.dirname(member) + if (dirname.endswith('.dist-info') and + canonicalize_name(dirname).startswith( + canonicalize_name(self.project_name))): + return dirname + raise ValueError("unsupported wheel format. .dist-info not found") + + def install_as_egg(self, destination_eggdir): + '''Install wheel as an egg directory.''' + with zipfile.ZipFile(self.filename) as zf: + self._install_as_egg(destination_eggdir, zf) + + def _install_as_egg(self, destination_eggdir, zf): + dist_basename = '%s-%s' % (self.project_name, self.version) + dist_info = self.get_dist_info(zf) + dist_data = '%s.data' % dist_basename + egg_info = os.path.join(destination_eggdir, 'EGG-INFO') + + self._convert_metadata(zf, destination_eggdir, dist_info, egg_info) + self._move_data_entries(destination_eggdir, dist_data) + self._fix_namespace_packages(egg_info, destination_eggdir) + + @staticmethod + def _convert_metadata(zf, destination_eggdir, dist_info, egg_info): + def get_metadata(name): + with zf.open(posixpath.join(dist_info, name)) as fp: + value = fp.read().decode('utf-8') if PY3 else fp.read() + return email.parser.Parser().parsestr(value) + + wheel_metadata = get_metadata('WHEEL') + # Check wheel format version is supported. + wheel_version = parse_version(wheel_metadata.get('Wheel-Version')) + wheel_v1 = ( + parse_version('1.0') <= wheel_version < parse_version('2.0dev0') + ) + if not wheel_v1: + raise ValueError( + 'unsupported wheel format version: %s' % wheel_version) + # Extract to target directory. + os.mkdir(destination_eggdir) + zf.extractall(destination_eggdir) + # Convert metadata. + dist_info = os.path.join(destination_eggdir, dist_info) + dist = Distribution.from_location( + destination_eggdir, dist_info, + metadata=PathMetadata(destination_eggdir, dist_info), + ) + + # Note: Evaluate and strip markers now, + # as it's difficult to convert back from the syntax: + # foobar; "linux" in sys_platform and extra == 'test' + def raw_req(req): + req.marker = None + return str(req) + install_requires = list(sorted(map(raw_req, dist.requires()))) + extras_require = { + extra: sorted( + req + for req in map(raw_req, dist.requires((extra,))) + if req not in install_requires + ) + for extra in dist.extras + } + os.rename(dist_info, egg_info) + os.rename( + os.path.join(egg_info, 'METADATA'), + os.path.join(egg_info, 'PKG-INFO'), + ) + setup_dist = SetuptoolsDistribution( + attrs=dict( + install_requires=install_requires, + extras_require=extras_require, + ), + ) + write_requirements( + setup_dist.get_command_obj('egg_info'), + None, + os.path.join(egg_info, 'requires.txt'), + ) + + @staticmethod + def _move_data_entries(destination_eggdir, dist_data): + """Move data entries to their correct location.""" + dist_data = os.path.join(destination_eggdir, dist_data) + dist_data_scripts = os.path.join(dist_data, 'scripts') + if os.path.exists(dist_data_scripts): + egg_info_scripts = os.path.join( + destination_eggdir, 'EGG-INFO', 'scripts') + os.mkdir(egg_info_scripts) + for entry in os.listdir(dist_data_scripts): + # Remove bytecode, as it's not properly handled + # during easy_install scripts install phase. + if entry.endswith('.pyc'): + os.unlink(os.path.join(dist_data_scripts, entry)) + else: + os.rename( + os.path.join(dist_data_scripts, entry), + os.path.join(egg_info_scripts, entry), + ) + os.rmdir(dist_data_scripts) + for subdir in filter(os.path.exists, ( + os.path.join(dist_data, d) + for d in ('data', 'headers', 'purelib', 'platlib') + )): + unpack(subdir, destination_eggdir) + if os.path.exists(dist_data): + os.rmdir(dist_data) + + @staticmethod + def _fix_namespace_packages(egg_info, destination_eggdir): + namespace_packages = os.path.join( + egg_info, 'namespace_packages.txt') + if os.path.exists(namespace_packages): + with open(namespace_packages) as fp: + namespace_packages = fp.read().split() + 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): + with open(mod_init, 'w') as fp: + fp.write(NAMESPACE_PACKAGE_INIT) diff --git a/venv/lib/python3.7/site-packages/setuptools/windows_support.py b/venv/lib/python3.7/site-packages/setuptools/windows_support.py new file mode 100644 index 0000000..cb977cf --- /dev/null +++ b/venv/lib/python3.7/site-packages/setuptools/windows_support.py @@ -0,0 +1,29 @@ +import platform +import ctypes + + +def windows_only(func): + if platform.system() != 'Windows': + return lambda *args, **kwargs: None + return func + + +@windows_only +def hide_file(path): + """ + Set the hidden attribute on a file or directory. + + From http://stackoverflow.com/questions/19622133/ + + `path` must be text. + """ + __import__('ctypes.wintypes') + SetFileAttributes = ctypes.windll.kernel32.SetFileAttributesW + SetFileAttributes.argtypes = ctypes.wintypes.LPWSTR, ctypes.wintypes.DWORD + SetFileAttributes.restype = ctypes.wintypes.BOOL + + FILE_ATTRIBUTE_HIDDEN = 0x02 + + ret = SetFileAttributes(path, FILE_ATTRIBUTE_HIDDEN) + if not ret: + raise ctypes.WinError() diff --git a/venv/pyvenv.cfg b/venv/pyvenv.cfg new file mode 100644 index 0000000..de15ebd --- /dev/null +++ b/venv/pyvenv.cfg @@ -0,0 +1,3 @@ +home = /usr/local/bin +include-system-site-packages = false +version = 3.7.2