From e352bcf4cb2d598957487b42d4d84407ce9cc109 Mon Sep 17 00:00:00 2001 From: Marco Costa Date: Fri, 18 Sep 2026 21:32:35 -0300 Subject: [PATCH] fdfgdfgfd --- .../__pycache__/uninstall.cpython-311.pyc | Bin 5101 -> 0 bytes .../__pycache__/wheel.cpython-311.pyc | Bin 9046 -> 0 bytes .../pip/_internal/commands/cache.py | 256 - .../pip/_internal/commands/check.py | 66 - .../pip/_internal/commands/completion.py | 136 - .../pip/_internal/commands/configuration.py | 289 - .../pip/_internal/commands/debug.py | 195 - .../pip/_internal/commands/download.py | 150 - .../pip/_internal/commands/freeze.py | 107 - .../pip/_internal/commands/hash.py | 58 - .../pip/_internal/commands/help.py | 40 - .../pip/_internal/commands/index.py | 173 - .../pip/_internal/commands/inspect.py | 92 - .../pip/_internal/commands/install.py | 904 - .../pip/_internal/commands/list.py | 408 - .../pip/_internal/commands/lock.py | 173 - .../pip/_internal/commands/search.py | 178 - .../pip/_internal/commands/show.py | 237 - .../pip/_internal/commands/uninstall.py | 113 - .../pip/_internal/commands/wheel.py | 177 - .../pip/_internal/configuration.py | 395 - .../pip/_internal/distributions/__init__.py | 21 - .../__pycache__/__init__.cpython-311.pyc | Bin 1037 -> 0 bytes .../__pycache__/base.cpython-311.pyc | Bin 3293 -> 0 bytes .../__pycache__/installed.cpython-311.pyc | Bin 1994 -> 0 bytes .../__pycache__/sdist.cpython-311.pyc | Bin 10751 -> 0 bytes .../__pycache__/wheel.cpython-311.pyc | Bin 2587 -> 0 bytes .../pip/_internal/distributions/base.py | 57 - .../pip/_internal/distributions/installed.py | 34 - .../pip/_internal/distributions/sdist.py | 193 - .../pip/_internal/distributions/wheel.py | 45 - .../site-packages/pip/_internal/exceptions.py | 1145 -- .../pip/_internal/index/__init__.py | 1 - .../__pycache__/__init__.cpython-311.pyc | Bin 232 -> 0 bytes .../__pycache__/collector.cpython-311.pyc | Bin 24632 -> 0 bytes .../package_finder.cpython-311.pyc | Bin 47829 -> 0 bytes .../index/__pycache__/sources.cpython-311.pyc | Bin 13589 -> 0 bytes .../pip/_internal/index/collector.py | 510 - .../pip/_internal/index/package_finder.py | 1152 -- .../pip/_internal/index/sources.py | 286 - .../pip/_internal/locations/__init__.py | 438 - .../__pycache__/__init__.cpython-311.pyc | Bin 16305 -> 0 bytes .../__pycache__/_distutils.cpython-311.pyc | Bin 7254 -> 0 bytes .../__pycache__/_sysconfig.cpython-311.pyc | Bin 8931 -> 0 bytes .../__pycache__/base.cpython-311.pyc | Bin 3956 -> 0 bytes .../pip/_internal/locations/_distutils.py | 173 - .../pip/_internal/locations/_sysconfig.py | 218 - .../pip/_internal/locations/base.py | 82 - .../site-packages/pip/_internal/main.py | 12 - .../pip/_internal/metadata/__init__.py | 169 - .../__pycache__/__init__.cpython-311.pyc | Bin 7442 -> 0 bytes .../__pycache__/_json.cpython-311.pyc | Bin 3618 -> 0 bytes .../metadata/__pycache__/base.cpython-311.pyc | Bin 37393 -> 0 bytes .../__pycache__/pkg_resources.cpython-311.pyc | Bin 18054 -> 0 bytes .../pip/_internal/metadata/_json.py | 87 - .../pip/_internal/metadata/base.py | 690 - .../_internal/metadata/importlib/__init__.py | 6 - .../__pycache__/__init__.cpython-311.pyc | Bin 392 -> 0 bytes .../__pycache__/_compat.cpython-311.pyc | Bin 4734 -> 0 bytes .../__pycache__/_dists.cpython-311.pyc | Bin 14535 -> 0 bytes .../__pycache__/_envs.cpython-311.pyc | Bin 9279 -> 0 bytes .../_internal/metadata/importlib/_compat.py | 87 - .../_internal/metadata/importlib/_dists.py | 235 - .../pip/_internal/metadata/importlib/_envs.py | 148 - .../pip/_internal/metadata/pkg_resources.py | 298 - .../pip/_internal/models/__init__.py | 1 - .../__pycache__/__init__.cpython-311.pyc | Bin 266 -> 0 bytes .../__pycache__/candidate.cpython-311.pyc | Bin 1983 -> 0 bytes .../__pycache__/direct_url.cpython-311.pyc | Bin 2308 -> 0 bytes .../format_control.cpython-311.pyc | Bin 4501 -> 0 bytes .../models/__pycache__/index.cpython-311.pyc | Bin 1900 -> 0 bytes .../installation_report.cpython-311.pyc | Bin 2636 -> 0 bytes .../models/__pycache__/link.cpython-311.pyc | Bin 31074 -> 0 bytes .../release_control.cpython-311.pyc | Bin 4639 -> 0 bytes .../models/__pycache__/scheme.cpython-311.pyc | Bin 1134 -> 0 bytes .../__pycache__/search_scope.cpython-311.pyc | Bin 5691 -> 0 bytes .../selection_prefs.cpython-311.pyc | Bin 1961 -> 0 bytes .../__pycache__/target_python.cpython-311.pyc | Bin 5122 -> 0 bytes .../models/__pycache__/wheel.cpython-311.pyc | Bin 5121 -> 0 bytes .../pip/_internal/models/candidate.py | 27 - .../pip/_internal/models/direct_url.py | 42 - .../pip/_internal/models/format_control.py | 78 - .../pip/_internal/models/index.py | 28 - .../_internal/models/installation_report.py | 57 - .../pip/_internal/models/link.py | 657 - .../pip/_internal/models/release_control.py | 91 - .../pip/_internal/models/scheme.py | 23 - .../pip/_internal/models/search_scope.py | 124 - .../pip/_internal/models/selection_prefs.py | 36 - .../pip/_internal/models/target_python.py | 122 - .../pip/_internal/models/wheel.py | 80 - .../pip/_internal/network/__init__.py | 1 - .../__pycache__/__init__.cpython-311.pyc | Bin 254 -> 0 bytes .../network/__pycache__/auth.cpython-311.pyc | Bin 24046 -> 0 bytes .../network/__pycache__/cache.cpython-311.pyc | Bin 9671 -> 0 bytes .../__pycache__/download.cpython-311.pyc | Bin 18655 -> 0 bytes .../__pycache__/lazy_wheel.cpython-311.pyc | Bin 12877 -> 0 bytes .../__pycache__/session.cpython-311.pyc | Bin 22512 -> 0 bytes .../network/__pycache__/utils.cpython-311.pyc | Bin 7104 -> 0 bytes .../__pycache__/xmlrpc.cpython-311.pyc | Bin 3223 -> 0 bytes .../pip/_internal/network/auth.py | 587 - .../pip/_internal/network/cache.py | 128 - .../pip/_internal/network/download.py | 387 - .../pip/_internal/network/lazy_wheel.py | 215 - .../pip/_internal/network/session.py | 532 - .../pip/_internal/network/utils.py | 206 - .../pip/_internal/network/xmlrpc.py | 61 - .../pip/_internal/operations/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 201 -> 0 bytes .../__pycache__/check.cpython-311.pyc | Bin 8080 -> 0 bytes .../__pycache__/freeze.cpython-311.pyc | Bin 11687 -> 0 bytes .../__pycache__/prepare.cpython-311.pyc | Bin 34239 -> 0 bytes .../_internal/operations/build/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 207 -> 0 bytes .../__pycache__/build_tracker.cpython-311.pyc | Bin 8703 -> 0 bytes .../__pycache__/metadata.cpython-311.pyc | Bin 2271 -> 0 bytes .../metadata_editable.cpython-311.pyc | Bin 2327 -> 0 bytes .../build/__pycache__/wheel.cpython-311.pyc | Bin 1953 -> 0 bytes .../wheel_editable.cpython-311.pyc | Bin 2397 -> 0 bytes .../operations/build/build_tracker.py | 140 - .../_internal/operations/build/metadata.py | 38 - .../operations/build/metadata_editable.py | 41 - .../pip/_internal/operations/build/wheel.py | 38 - .../operations/build/wheel_editable.py | 47 - .../pip/_internal/operations/check.py | 174 - .../pip/_internal/operations/freeze.py | 259 - .../_internal/operations/install/__init__.py | 1 - .../__pycache__/__init__.cpython-311.pyc | Bin 266 -> 0 bytes .../install/__pycache__/wheel.cpython-311.pyc | Bin 40533 -> 0 bytes .../pip/_internal/operations/install/wheel.py | 764 - .../pip/_internal/operations/prepare.py | 896 - .../site-packages/pip/_internal/pyproject.py | 123 - .../pip/_internal/req/__init__.py | 105 - .../req/__pycache__/__init__.cpython-311.pyc | Bin 4674 -> 0 bytes .../__pycache__/constructors.cpython-311.pyc | Bin 26726 -> 0 bytes .../req/__pycache__/pep723.cpython-311.pyc | Bin 3187 -> 0 bytes .../req_dependency_group.cpython-311.pyc | Bin 5511 -> 0 bytes .../req/__pycache__/req_file.cpython-311.pyc | Bin 26021 -> 0 bytes .../__pycache__/req_install.cpython-311.pyc | Bin 36670 -> 0 bytes .../req/__pycache__/req_set.cpython-311.pyc | Bin 5931 -> 0 bytes .../__pycache__/req_uninstall.cpython-311.pyc | Bin 36139 -> 0 bytes .../pip/_internal/req/constructors.py | 662 - .../site-packages/pip/_internal/req/pep723.py | 41 - .../pip/_internal/req/req_dependency_group.py | 86 - .../pip/_internal/req/req_file.py | 622 - .../pip/_internal/req/req_install.py | 842 - .../pip/_internal/req/req_set.py | 81 - .../pip/_internal/req/req_uninstall.py | 644 - .../pip/_internal/resolution/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 201 -> 0 bytes .../__pycache__/base.cpython-311.pyc | Bin 1330 -> 0 bytes .../pip/_internal/resolution/base.py | 20 - .../_internal/resolution/legacy/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 208 -> 0 bytes .../__pycache__/resolver.cpython-311.pyc | Bin 23519 -> 0 bytes .../_internal/resolution/legacy/resolver.py | 598 - .../resolution/resolvelib/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 212 -> 0 bytes .../__pycache__/base.cpython-311.pyc | Bin 11571 -> 0 bytes .../__pycache__/candidates.cpython-311.pyc | Bin 30420 -> 0 bytes .../__pycache__/factory.cpython-311.pyc | Bin 39787 -> 0 bytes .../found_candidates.cpython-311.pyc | Bin 7152 -> 0 bytes .../__pycache__/provider.cpython-311.pyc | Bin 13613 -> 0 bytes .../__pycache__/reporter.cpython-311.pyc | Bin 6436 -> 0 bytes .../__pycache__/requirements.cpython-311.pyc | Bin 15867 -> 0 bytes .../__pycache__/resolver.cpython-311.pyc | Bin 13905 -> 0 bytes .../_internal/resolution/resolvelib/base.py | 164 - .../resolution/resolvelib/candidates.py | 598 - .../resolution/resolvelib/factory.py | 901 - .../resolution/resolvelib/found_candidates.py | 166 - .../resolution/resolvelib/provider.py | 309 - .../resolution/resolvelib/reporter.py | 98 - .../resolution/resolvelib/requirements.py | 251 - .../resolution/resolvelib/resolver.py | 341 - .../pip/_internal/self_outdated_check.py | 246 - .../pip/_internal/utils/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 196 -> 0 bytes .../__pycache__/_jaraco_text.cpython-311.pyc | Bin 4759 -> 0 bytes .../utils/__pycache__/_log.cpython-311.pyc | Bin 2017 -> 0 bytes .../utils/__pycache__/appdirs.cpython-311.pyc | Bin 2586 -> 0 bytes .../utils/__pycache__/compat.cpython-311.pyc | Bin 3644 -> 0 bytes .../compatibility_tags.cpython-311.pyc | Bin 8060 -> 0 bytes .../__pycache__/datetime.cpython-311.pyc | Bin 1600 -> 0 bytes .../__pycache__/deprecation.cpython-311.pyc | Bin 5485 -> 0 bytes .../direct_url_helpers.cpython-311.pyc | Bin 3835 -> 0 bytes .../__pycache__/egg_link.cpython-311.pyc | Bin 3490 -> 0 bytes .../__pycache__/entrypoints.cpython-311.pyc | Bin 4307 -> 0 bytes .../__pycache__/filesystem.cpython-311.pyc | Bin 11148 -> 0 bytes .../__pycache__/filetypes.cpython-311.pyc | Bin 1258 -> 0 bytes .../utils/__pycache__/glibc.cpython-311.pyc | Bin 2622 -> 0 bytes .../utils/__pycache__/hashes.cpython-311.pyc | Bin 8942 -> 0 bytes .../utils/__pycache__/logging.cpython-311.pyc | Bin 17479 -> 0 bytes .../utils/__pycache__/misc.cpython-311.pyc | Bin 37717 -> 0 bytes .../__pycache__/packaging.cpython-311.pyc | Bin 2030 -> 0 bytes .../utils/__pycache__/pylock.cpython-311.pyc | Bin 12074 -> 0 bytes .../utils/__pycache__/retry.cpython-311.pyc | Bin 2305 -> 0 bytes .../__pycache__/subprocess.cpython-311.pyc | Bin 9462 -> 0 bytes .../__pycache__/temp_dir.cpython-311.pyc | Bin 13282 -> 0 bytes .../__pycache__/unpacking.cpython-311.pyc | Bin 18318 -> 0 bytes .../utils/__pycache__/urls.cpython-311.pyc | Bin 2288 -> 0 bytes .../__pycache__/virtualenv.cpython-311.pyc | Bin 3293 -> 0 bytes .../utils/__pycache__/wheel.cpython-311.pyc | Bin 6933 -> 0 bytes .../pip/_internal/utils/_jaraco_text.py | 109 - .../site-packages/pip/_internal/utils/_log.py | 38 - .../pip/_internal/utils/appdirs.py | 52 - .../pip/_internal/utils/compat.py | 91 - .../pip/_internal/utils/compatibility_tags.py | 201 - .../pip/_internal/utils/datetime.py | 28 - .../pip/_internal/utils/deprecation.py | 144 - .../pip/_internal/utils/direct_url_helpers.py | 92 - .../pip/_internal/utils/egg_link.py | 81 - .../pip/_internal/utils/entrypoints.py | 88 - .../pip/_internal/utils/filesystem.py | 201 - .../pip/_internal/utils/filetypes.py | 24 - .../pip/_internal/utils/glibc.py | 102 - .../pip/_internal/utils/hashes.py | 150 - .../pip/_internal/utils/logging.py | 404 - .../site-packages/pip/_internal/utils/misc.py | 815 - .../pip/_internal/utils/packaging.py | 44 - .../pip/_internal/utils/pylock.py | 299 - .../pip/_internal/utils/retry.py | 46 - .../pip/_internal/utils/subprocess.py | 249 - .../pip/_internal/utils/temp_dir.py | 293 - .../pip/_internal/utils/unpacking.py | 407 - .../site-packages/pip/_internal/utils/urls.py | 58 - .../pip/_internal/utils/virtualenv.py | 71 - .../pip/_internal/utils/wheel.py | 132 - .../pip/_internal/vcs/__init__.py | 15 - .../vcs/__pycache__/__init__.cpython-311.pyc | Bin 631 -> 0 bytes .../vcs/__pycache__/bazaar.cpython-311.pyc | Bin 5874 -> 0 bytes .../vcs/__pycache__/git.cpython-311.pyc | Bin 22548 -> 0 bytes .../vcs/__pycache__/mercurial.cpython-311.pyc | Bin 8777 -> 0 bytes .../__pycache__/subversion.cpython-311.pyc | Bin 14254 -> 0 bytes .../versioncontrol.cpython-311.pyc | Bin 31271 -> 0 bytes .../site-packages/pip/_internal/vcs/bazaar.py | 130 - .../site-packages/pip/_internal/vcs/git.py | 574 - .../pip/_internal/vcs/mercurial.py | 186 - .../pip/_internal/vcs/subversion.py | 335 - .../pip/_internal/vcs/versioncontrol.py | 694 - .../pip/_internal/wheel_builder.py | 265 - .../site-packages/pip/_vendor/README.rst | 178 - .../site-packages/pip/_vendor/__init__.py | 117 - .../__pycache__/__init__.cpython-311.pyc | Bin 5481 -> 0 bytes .../site-packages/pip/_vendor/bom.cdx.json | 231 - .../pip/_vendor/cachecontrol/LICENSE.txt | 13 - .../pip/_vendor/cachecontrol/__init__.py | 32 - .../__pycache__/__init__.cpython-311.pyc | Bin 1004 -> 0 bytes .../__pycache__/_cmd.cpython-311.pyc | Bin 3026 -> 0 bytes .../__pycache__/adapter.cpython-311.pyc | Bin 7106 -> 0 bytes .../__pycache__/cache.cpython-311.pyc | Bin 4499 -> 0 bytes .../__pycache__/controller.cpython-311.pyc | Bin 18577 -> 0 bytes .../__pycache__/filewrapper.cpython-311.pyc | Bin 4818 -> 0 bytes .../__pycache__/heuristics.cpython-311.pyc | Bin 7566 -> 0 bytes .../__pycache__/serialize.cpython-311.pyc | Bin 5936 -> 0 bytes .../__pycache__/wrapper.cpython-311.pyc | Bin 1867 -> 0 bytes .../pip/_vendor/cachecontrol/_cmd.py | 70 - .../pip/_vendor/cachecontrol/adapter.py | 167 - .../pip/_vendor/cachecontrol/cache.py | 75 - .../_vendor/cachecontrol/caches/__init__.py | 8 - .../__pycache__/__init__.cpython-311.pyc | Bin 476 -> 0 bytes .../__pycache__/file_cache.cpython-311.pyc | Bin 8201 -> 0 bytes .../__pycache__/redis_cache.cpython-311.pyc | Bin 3083 -> 0 bytes .../_vendor/cachecontrol/caches/file_cache.py | 145 - .../cachecontrol/caches/redis_cache.py | 48 - .../pip/_vendor/cachecontrol/controller.py | 511 - .../pip/_vendor/cachecontrol/filewrapper.py | 121 - .../pip/_vendor/cachecontrol/heuristics.py | 157 - .../pip/_vendor/cachecontrol/py.typed | 0 .../pip/_vendor/cachecontrol/serialize.py | 146 - .../pip/_vendor/cachecontrol/wrapper.py | 43 - .../site-packages/pip/_vendor/certifi/LICENSE | 20 - .../pip/_vendor/certifi/__init__.py | 4 - .../pip/_vendor/certifi/__main__.py | 12 - .../__pycache__/__init__.cpython-311.pyc | Bin 338 -> 0 bytes .../__pycache__/__main__.cpython-311.pyc | Bin 739 -> 0 bytes .../certifi/__pycache__/core.cpython-311.pyc | Bin 2414 -> 0 bytes .../pip/_vendor/certifi/cacert.pem | 3863 ---- .../site-packages/pip/_vendor/certifi/core.py | 83 - .../pip/_vendor/certifi/py.typed | 0 .../pip/_vendor/distlib/LICENSE.txt | 284 - .../pip/_vendor/distlib/__init__.py | 33 - .../__pycache__/__init__.cpython-311.pyc | Bin 1465 -> 0 bytes .../__pycache__/compat.cpython-311.pyc | Bin 52137 -> 0 bytes .../__pycache__/resources.cpython-311.pyc | Bin 19634 -> 0 bytes .../__pycache__/scripts.cpython-311.pyc | Bin 21865 -> 0 bytes .../distlib/__pycache__/util.cpython-311.pyc | Bin 99687 -> 0 bytes .../pip/_vendor/distlib/compat.py | 1107 - .../pip/_vendor/distlib/resources.py | 372 - .../pip/_vendor/distlib/scripts.py | 451 - .../site-packages/pip/_vendor/distlib/t32.exe | Bin 97792 -> 0 bytes .../pip/_vendor/distlib/t64-arm.exe | Bin 182784 -> 0 bytes .../site-packages/pip/_vendor/distlib/t64.exe | Bin 108032 -> 0 bytes .../site-packages/pip/_vendor/distlib/util.py | 2021 -- .../site-packages/pip/_vendor/distlib/w32.exe | Bin 91648 -> 0 bytes .../pip/_vendor/distlib/w64-arm.exe | Bin 168448 -> 0 bytes .../site-packages/pip/_vendor/distlib/w64.exe | Bin 101888 -> 0 bytes .../site-packages/pip/_vendor/distro/LICENSE | 202 - .../pip/_vendor/distro/__init__.py | 54 - .../pip/_vendor/distro/__main__.py | 4 - .../__pycache__/__init__.cpython-311.pyc | Bin 1194 -> 0 bytes .../__pycache__/__main__.cpython-311.pyc | Bin 328 -> 0 bytes .../distro/__pycache__/distro.cpython-311.pyc | Bin 57818 -> 0 bytes .../pip/_vendor/distro/distro.py | 1403 -- .../site-packages/pip/_vendor/distro/py.typed | 0 .../site-packages/pip/_vendor/idna/LICENSE.md | 31 - .../pip/_vendor/idna/__init__.py | 45 - .../pip/_vendor/idna/__main__.py | 6 - .../idna/__pycache__/__init__.cpython-311.pyc | Bin 1100 -> 0 bytes .../idna/__pycache__/__main__.cpython-311.pyc | Bin 399 -> 0 bytes .../idna/__pycache__/cli.cpython-311.pyc | Bin 6622 -> 0 bytes .../idna/__pycache__/codec.cpython-311.pyc | Bin 7083 -> 0 bytes .../idna/__pycache__/compat.cpython-311.pyc | Bin 2040 -> 0 bytes .../idna/__pycache__/core.cpython-311.pyc | Bin 31548 -> 0 bytes .../idna/__pycache__/idnadata.cpython-311.pyc | Bin 22052 -> 0 bytes .../__pycache__/intranges.cpython-311.pyc | Bin 2917 -> 0 bytes .../__pycache__/package_data.cpython-311.pyc | Bin 216 -> 0 bytes .../__pycache__/uts46data.cpython-311.pyc | Bin 96348 -> 0 bytes .../site-packages/pip/_vendor/idna/cli.py | 128 - .../site-packages/pip/_vendor/idna/codec.py | 159 - .../site-packages/pip/_vendor/idna/compat.py | 41 - .../site-packages/pip/_vendor/idna/core.py | 648 - .../pip/_vendor/idna/idnadata.py | 1897 -- .../pip/_vendor/idna/intranges.py | 55 - .../pip/_vendor/idna/package_data.py | 1 - .../site-packages/pip/_vendor/idna/py.typed | 0 .../pip/_vendor/idna/uts46data.py | 16896 ---------------- .../site-packages/pip/_vendor/msgpack/COPYING | 14 - .../pip/_vendor/msgpack/__init__.py | 55 - .../__pycache__/__init__.cpython-311.pyc | Bin 1978 -> 0 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 2375 -> 0 bytes .../msgpack/__pycache__/ext.cpython-311.pyc | Bin 8727 -> 0 bytes .../__pycache__/fallback.cpython-311.pyc | Bin 44768 -> 0 bytes .../pip/_vendor/msgpack/exceptions.py | 48 - .../site-packages/pip/_vendor/msgpack/ext.py | 170 - .../pip/_vendor/msgpack/fallback.py | 929 - .../pip/_vendor/packaging/LICENSE | 3 - .../pip/_vendor/packaging/LICENSE.APACHE | 177 - .../pip/_vendor/packaging/LICENSE.BSD | 23 - .../pip/_vendor/packaging/__init__.py | 15 - .../__pycache__/__init__.cpython-311.pyc | Bin 558 -> 0 bytes .../__pycache__/_elffile.cpython-311.pyc | Bin 5423 -> 0 bytes .../__pycache__/_manylinux.cpython-311.pyc | Bin 11142 -> 0 bytes .../__pycache__/_musllinux.cpython-311.pyc | Bin 5321 -> 0 bytes .../__pycache__/_parser.cpython-311.pyc | Bin 18092 -> 0 bytes .../__pycache__/_structures.cpython-311.pyc | Bin 1818 -> 0 bytes .../__pycache__/_tokenizer.cpython-311.pyc | Bin 8894 -> 0 bytes .../dependency_groups.cpython-311.pyc | Bin 12593 -> 0 bytes .../__pycache__/direct_url.cpython-311.pyc | Bin 16476 -> 0 bytes .../__pycache__/errors.cpython-311.pyc | Bin 4781 -> 0 bytes .../__pycache__/markers.cpython-311.pyc | Bin 19944 -> 0 bytes .../__pycache__/metadata.cpython-311.pyc | Bin 35859 -> 0 bytes .../__pycache__/pylock.cpython-311.pyc | Bin 41845 -> 0 bytes .../__pycache__/requirements.cpython-311.pyc | Bin 6540 -> 0 bytes .../__pycache__/specifiers.cpython-311.pyc | Bin 81011 -> 0 bytes .../__pycache__/tags.cpython-311.pyc | Bin 41179 -> 0 bytes .../__pycache__/utils.cpython-311.pyc | Bin 12046 -> 0 bytes .../__pycache__/version.cpython-311.pyc | Bin 43901 -> 0 bytes .../pip/_vendor/packaging/_elffile.py | 108 - .../pip/_vendor/packaging/_manylinux.py | 262 - .../pip/_vendor/packaging/_musllinux.py | 85 - .../pip/_vendor/packaging/_parser.py | 393 - .../pip/_vendor/packaging/_structures.py | 33 - .../pip/_vendor/packaging/_tokenizer.py | 193 - .../_vendor/packaging/dependency_groups.py | 302 - .../pip/_vendor/packaging/direct_url.py | 325 - .../pip/_vendor/packaging/errors.py | 94 - .../_vendor/packaging/licenses/__init__.py | 186 - .../__pycache__/__init__.cpython-311.pyc | Bin 6397 -> 0 bytes .../__pycache__/_spdx.cpython-311.pyc | Bin 52906 -> 0 bytes .../pip/_vendor/packaging/licenses/_spdx.py | 799 - .../pip/_vendor/packaging/markers.py | 492 - .../pip/_vendor/packaging/metadata.py | 964 - .../pip/_vendor/packaging/py.typed | 0 .../pip/_vendor/packaging/pylock.py | 905 - .../pip/_vendor/packaging/requirements.py | 129 - .../pip/_vendor/packaging/specifiers.py | 1943 -- .../pip/_vendor/packaging/tags.py | 932 - .../pip/_vendor/packaging/utils.py | 296 - .../pip/_vendor/packaging/version.py | 1231 -- .../pip/_vendor/pkg_resources/LICENSE | 17 - 380 files changed, 72436 deletions(-) delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/commands/cache.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/commands/check.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/commands/completion.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/commands/configuration.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/commands/debug.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/commands/download.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/commands/freeze.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/commands/hash.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/commands/help.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/commands/index.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/commands/inspect.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/commands/install.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/commands/list.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/commands/lock.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/commands/search.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/commands/show.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/commands/uninstall.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/commands/wheel.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/configuration.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/distributions/__init__.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/distributions/__pycache__/base.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/distributions/__pycache__/installed.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/distributions/base.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/distributions/installed.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/distributions/sdist.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/distributions/wheel.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/exceptions.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/index/__init__.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/index/__pycache__/__init__.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/index/__pycache__/collector.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/index/__pycache__/package_finder.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/index/__pycache__/sources.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/index/collector.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/index/package_finder.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/index/sources.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/locations/__init__.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/locations/__pycache__/__init__.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/locations/__pycache__/_distutils.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/locations/__pycache__/_sysconfig.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/locations/__pycache__/base.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/locations/_distutils.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/locations/_sysconfig.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/locations/base.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/main.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/metadata/__init__.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/metadata/__pycache__/__init__.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/metadata/__pycache__/_json.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/metadata/__pycache__/base.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/metadata/__pycache__/pkg_resources.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/metadata/_json.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/metadata/base.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/__init__.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/__pycache__/__init__.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/__pycache__/_compat.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/__pycache__/_dists.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/__pycache__/_envs.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/_compat.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/_dists.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/_envs.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/metadata/pkg_resources.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/models/__init__.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/__init__.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/candidate.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/format_control.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/index.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/installation_report.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/link.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/release_control.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/scheme.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/target_python.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/wheel.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/models/candidate.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/models/direct_url.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/models/format_control.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/models/index.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/models/installation_report.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/models/link.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/models/release_control.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/models/scheme.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/models/search_scope.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/models/selection_prefs.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/models/target_python.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/models/wheel.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/network/__init__.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/network/__pycache__/__init__.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/network/__pycache__/auth.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/network/__pycache__/cache.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/network/__pycache__/download.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/network/__pycache__/lazy_wheel.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/network/__pycache__/session.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/network/__pycache__/utils.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/network/__pycache__/xmlrpc.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/network/auth.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/network/cache.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/network/download.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/network/lazy_wheel.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/network/session.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/network/utils.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/network/xmlrpc.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/operations/__init__.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/operations/__pycache__/check.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/operations/build/__init__.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/operations/build/__pycache__/build_tracker.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/operations/build/__pycache__/metadata.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/operations/build/__pycache__/metadata_editable.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/operations/build/__pycache__/wheel.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/operations/build/__pycache__/wheel_editable.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/operations/build/build_tracker.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/operations/build/metadata.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/operations/build/metadata_editable.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/operations/build/wheel.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/operations/build/wheel_editable.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/operations/check.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/operations/freeze.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/operations/install/__init__.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/operations/install/__pycache__/wheel.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/operations/install/wheel.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/operations/prepare.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/pyproject.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/req/__init__.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/req/__pycache__/__init__.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/req/__pycache__/constructors.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/req/__pycache__/pep723.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/req/__pycache__/req_dependency_group.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/req/__pycache__/req_file.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/req/__pycache__/req_install.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/req/__pycache__/req_set.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/req/constructors.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/req/pep723.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/req/req_dependency_group.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/req/req_file.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/req/req_install.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/req/req_set.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/req/req_uninstall.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/resolution/__init__.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/resolution/__pycache__/base.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/resolution/base.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/resolution/legacy/__init__.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/resolution/legacy/__pycache__/__init__.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/resolution/legacy/__pycache__/resolver.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/resolution/legacy/resolver.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__init__.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/base.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/base.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/candidates.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/factory.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/provider.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/reporter.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/requirements.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/resolver.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/self_outdated_check.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/__init__.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/_jaraco_text.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/_log.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/compat.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/compatibility_tags.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/datetime.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/egg_link.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/entrypoints.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/filetypes.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/logging.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/misc.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/pylock.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/retry.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/unpacking.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/urls.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/wheel.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/_jaraco_text.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/_log.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/appdirs.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/compat.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/compatibility_tags.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/datetime.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/deprecation.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/direct_url_helpers.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/egg_link.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/entrypoints.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/filesystem.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/filetypes.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/glibc.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/hashes.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/logging.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/misc.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/packaging.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/pylock.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/retry.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/subprocess.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/temp_dir.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/unpacking.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/urls.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/virtualenv.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/utils/wheel.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/vcs/__init__.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/vcs/__pycache__/git.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/vcs/bazaar.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/vcs/git.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/vcs/mercurial.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/vcs/subversion.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/vcs/versioncontrol.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_internal/wheel_builder.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/README.rst delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/__init__.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/__pycache__/__init__.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/bom.cdx.json delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/LICENSE.txt delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__init__.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/_cmd.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/adapter.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/cache.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/caches/__init__.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/controller.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/filewrapper.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/heuristics.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/py.typed delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/serialize.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/wrapper.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/certifi/LICENSE delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/certifi/__init__.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/certifi/__main__.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/certifi/__pycache__/__main__.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/certifi/cacert.pem delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/certifi/core.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/certifi/py.typed delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/distlib/LICENSE.txt delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/distlib/__init__.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/distlib/__pycache__/scripts.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/distlib/compat.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/distlib/resources.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/distlib/scripts.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/distlib/t32.exe delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/distlib/t64-arm.exe delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/distlib/t64.exe delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/distlib/util.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/distlib/w32.exe delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/distlib/w64-arm.exe delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/distlib/w64.exe delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/distro/LICENSE delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/distro/__init__.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/distro/__main__.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/distro/__pycache__/__init__.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/distro/__pycache__/__main__.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/distro/__pycache__/distro.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/distro/distro.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/distro/py.typed delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/idna/LICENSE.md delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/idna/__init__.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/idna/__main__.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/__main__.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/cli.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/codec.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/compat.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/core.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/uts46data.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/idna/cli.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/idna/codec.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/idna/compat.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/idna/core.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/idna/idnadata.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/idna/intranges.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/idna/package_data.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/idna/py.typed delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/idna/uts46data.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/msgpack/COPYING delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/msgpack/__init__.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/msgpack/__pycache__/ext.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/msgpack/exceptions.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/msgpack/ext.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/msgpack/fallback.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/LICENSE delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/LICENSE.APACHE delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/LICENSE.BSD delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__init__.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/_elffile.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/_manylinux.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/_musllinux.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/_parser.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/_structures.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/_tokenizer.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/dependency_groups.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/direct_url.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/errors.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/metadata.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/pylock.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/tags.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/_elffile.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/_manylinux.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/_musllinux.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/_parser.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/_structures.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/_tokenizer.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/dependency_groups.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/direct_url.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/errors.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/licenses/__init__.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/licenses/__pycache__/__init__.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/licenses/__pycache__/_spdx.cpython-311.pyc delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/licenses/_spdx.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/markers.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/metadata.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/py.typed delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/pylock.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/requirements.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/specifiers.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/tags.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/utils.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/packaging/version.py delete mode 100755 venv/lib/python3.11/site-packages/pip/_vendor/pkg_resources/LICENSE diff --git a/venv/lib/python3.11/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-311.pyc deleted file mode 100755 index 5dcf719f55e15282b3c0eb25bd560584f022ef2c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5101 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 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-311.pyc deleted file mode 100755 index 47ff21e14b82e1fb8f553a681446d3e8f0db4fa2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9046 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 M80p&|U|=@?Kj8adLjV8( diff --git a/venv/lib/python3.11/site-packages/pip/_internal/commands/cache.py b/venv/lib/python3.11/site-packages/pip/_internal/commands/cache.py deleted file mode 100755 index 232ace8..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/commands/cache.py +++ /dev/null @@ -1,256 +0,0 @@ -import os -import textwrap -from collections.abc import Callable -from optparse import Values - -from pip._internal.cli.base_command import Command -from pip._internal.cli.status_codes import ERROR, SUCCESS -from pip._internal.exceptions import CommandError, PipError -from pip._internal.utils import filesystem -from pip._internal.utils.logging import getLogger -from pip._internal.utils.misc import format_size - -logger = getLogger(__name__) - - -class CacheCommand(Command): - """ - Inspect and manage pip's wheel cache. - - Subcommands: - - - dir: Show the cache directory. - - info: Show information about the cache. - - list: List filenames of packages stored in the cache. - - remove: Remove one or more package from the cache. - - purge: Remove all items from the cache. - - ```` can be a glob expression or a package name. - """ - - ignore_require_venv = True - usage = """ - %prog dir - %prog info - %prog list [] [--format=[human, abspath]] - %prog remove - %prog purge - """ - - def add_options(self) -> None: - self.cmd_opts.add_option( - "--format", - action="store", - dest="list_format", - default="human", - choices=("human", "abspath"), - help="Select the output format among: human (default) or abspath", - ) - - self.parser.insert_option_group(0, self.cmd_opts) - - def handler_map(self) -> dict[str, Callable[[Values, list[str]], None]]: - return { - "dir": self.get_cache_dir, - "info": self.get_cache_info, - "list": self.list_cache_items, - "remove": self.remove_cache_items, - "purge": self.purge_cache, - } - - def run(self, options: Values, args: list[str]) -> int: - handler_map = self.handler_map() - - if not options.cache_dir: - logger.error("pip cache commands can not function since cache is disabled.") - return ERROR - - # Determine action - if not args or args[0] not in handler_map: - logger.error( - "Need an action (%s) to perform.", - ", ".join(sorted(handler_map)), - ) - return ERROR - - action = args[0] - - # Error handling happens here, not in the action-handlers. - try: - handler_map[action](options, args[1:]) - except PipError as e: - logger.error(e.args[0]) - return ERROR - - return SUCCESS - - def get_cache_dir(self, options: Values, args: list[str]) -> None: - if args: - raise CommandError("Too many arguments") - - logger.info(options.cache_dir) - - def get_cache_info(self, options: Values, args: list[str]) -> None: - if args: - raise CommandError("Too many arguments") - - num_http_files = len(self._find_http_files(options)) - num_packages = len(self._find_wheels(options, "*")) - - http_cache_location = self._cache_dir(options, "http-v2") - old_http_cache_location = self._cache_dir(options, "http") - wheels_cache_location = self._cache_dir(options, "wheels") - http_cache_size = filesystem.format_size( - filesystem.directory_size(http_cache_location) - + filesystem.directory_size(old_http_cache_location) - ) - wheels_cache_size = filesystem.format_directory_size(wheels_cache_location) - - message = ( - textwrap.dedent(""" - Package index page cache location (pip v23.3+): {http_cache_location} - Package index page cache location (older pips): {old_http_cache_location} - Package index page cache size: {http_cache_size} - Number of HTTP files: {num_http_files} - Locally built wheels location: {wheels_cache_location} - Locally built wheels size: {wheels_cache_size} - Number of locally built wheels: {package_count} - """) # noqa: E501 - .format( - http_cache_location=http_cache_location, - old_http_cache_location=old_http_cache_location, - http_cache_size=http_cache_size, - num_http_files=num_http_files, - wheels_cache_location=wheels_cache_location, - package_count=num_packages, - wheels_cache_size=wheels_cache_size, - ) - .strip() - ) - - logger.info(message) - - def list_cache_items(self, options: Values, args: list[str]) -> None: - if len(args) > 1: - raise CommandError("Too many arguments") - - if args: - pattern = args[0] - else: - pattern = "*" - - files = self._find_wheels(options, pattern) - if options.list_format == "human": - self.format_for_human(files) - else: - self.format_for_abspath(files) - - def format_for_human(self, files: list[str]) -> None: - if not files: - logger.info("No locally built wheels cached.") - return - - results = [] - for filename in files: - wheel = os.path.basename(filename) - size = filesystem.format_file_size(filename) - results.append(f" - {wheel} ({size})") - logger.info("Cache contents:\n") - logger.info("\n".join(sorted(results))) - - def format_for_abspath(self, files: list[str]) -> None: - if files: - logger.info("\n".join(sorted(files))) - - def remove_cache_items(self, options: Values, args: list[str]) -> None: - if len(args) > 1: - raise CommandError("Too many arguments") - - if not args: - raise CommandError("Please provide a pattern") - - files = self._find_wheels(options, args[0]) - - no_matching_msg = "No matching packages" - if args[0] == "*": - # Only fetch http files if no specific pattern given - files += self._find_http_files(options) - else: - # Add the pattern to the log message - no_matching_msg += f' for pattern "{args[0]}"' - - if not files: - logger.warning(no_matching_msg) - - bytes_removed = 0 - for filename in files: - bytes_removed += os.stat(filename).st_size - os.unlink(filename) - logger.verbose("Removed %s", filename) - - http_dirs = filesystem.subdirs_without_files(self._cache_dir(options, "http")) - http_v2_dirs = filesystem.subdirs_without_files( - self._cache_dir(options, "http-v2") - ) - wheel_dirs = filesystem.subdirs_without_wheels( - self._cache_dir(options, "wheels") - ) - dirs = [*http_dirs, *http_v2_dirs, *wheel_dirs] - - for subdir in dirs: - try: - for file in subdir.iterdir(): - file.unlink(missing_ok=True) - subdir.rmdir() - except FileNotFoundError: - # If the directory is already gone, that's fine. - pass - logger.verbose("Removed %s", subdir) - - # selfcheck.json is no longer used by pip. - selfcheck_json = self._cache_dir(options, "selfcheck.json") - if os.path.isfile(selfcheck_json): - os.remove(selfcheck_json) - logger.verbose("Removed legacy selfcheck.json file") - - logger.info("Files removed: %s (%s)", len(files), format_size(bytes_removed)) - logger.info("Directories removed: %s", len(dirs)) - - def purge_cache(self, options: Values, args: list[str]) -> None: - if args: - raise CommandError("Too many arguments") - - return self.remove_cache_items(options, ["*"]) - - def _cache_dir(self, options: Values, subdir: str) -> str: - return os.path.join(options.cache_dir, subdir) - - def _find_http_files(self, options: Values) -> list[str]: - old_http_dir = self._cache_dir(options, "http") - new_http_dir = self._cache_dir(options, "http-v2") - return filesystem.find_files(old_http_dir, "*") + filesystem.find_files( - new_http_dir, "*" - ) - - def _find_wheels(self, options: Values, pattern: str) -> list[str]: - wheel_dir = self._cache_dir(options, "wheels") - - # The wheel filename format, as specified in PEP 427, is: - # {distribution}-{version}(-{build})?-{python}-{abi}-{platform}.whl - # - # Additionally, non-alphanumeric values in the distribution are - # normalized to underscores (_), meaning hyphens can never occur - # before `-{version}`. - # - # Given that information: - # - If the pattern we're given contains a hyphen (-), the user is - # providing at least the version. Thus, we can just append `*.whl` - # to match the rest of it. - # - If the pattern we're given doesn't contain a hyphen (-), the - # user is only providing the name. Thus, we append `-*.whl` to - # match the hyphen before the version, followed by anything else. - # - # PEP 427: https://www.python.org/dev/peps/pep-0427/ - pattern = pattern + ("*.whl" if "-" in pattern else "-*.whl") - - return filesystem.find_files(wheel_dir, pattern) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/commands/check.py b/venv/lib/python3.11/site-packages/pip/_internal/commands/check.py deleted file mode 100755 index 516757e..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/commands/check.py +++ /dev/null @@ -1,66 +0,0 @@ -import logging -from optparse import Values - -from pip._internal.cli.base_command import Command -from pip._internal.cli.status_codes import ERROR, SUCCESS -from pip._internal.metadata import get_default_environment -from pip._internal.operations.check import ( - check_package_set, - check_unsupported, - create_package_set_from_installed, -) -from pip._internal.utils.compatibility_tags import get_supported -from pip._internal.utils.misc import write_output - -logger = logging.getLogger(__name__) - - -class CheckCommand(Command): - """Verify installed packages have compatible dependencies.""" - - ignore_require_venv = True - usage = """ - %prog [options]""" - - def run(self, options: Values, args: list[str]) -> int: - package_set, parsing_probs = create_package_set_from_installed() - missing, conflicting = check_package_set(package_set) - unsupported = list( - check_unsupported( - get_default_environment().iter_installed_distributions(), - get_supported(), - ) - ) - - for project_name in missing: - version = package_set[project_name].version - for dependency in missing[project_name]: - write_output( - "%s %s requires %s, which is not installed.", - project_name, - version, - dependency[0], - ) - - for project_name in conflicting: - version = package_set[project_name].version - for dep_name, dep_version, req in conflicting[project_name]: - write_output( - "%s %s has requirement %s, but you have %s %s.", - project_name, - version, - req, - dep_name, - dep_version, - ) - for package in unsupported: - write_output( - "%s %s is not supported on this platform", - package.raw_name, - package.version, - ) - if missing or conflicting or parsing_probs or unsupported: - return ERROR - else: - write_output("No broken requirements found.") - return SUCCESS diff --git a/venv/lib/python3.11/site-packages/pip/_internal/commands/completion.py b/venv/lib/python3.11/site-packages/pip/_internal/commands/completion.py deleted file mode 100755 index 7ba205d..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/commands/completion.py +++ /dev/null @@ -1,136 +0,0 @@ -import sys -import textwrap -from optparse import Values - -from pip._internal.cli.base_command import Command -from pip._internal.cli.status_codes import SUCCESS -from pip._internal.utils.misc import get_prog - -BASE_COMPLETION = """ -# pip {shell} completion start{script}# pip {shell} completion end -""" - -COMPLETION_SCRIPTS = { - "bash": """ - _pip_completion() - {{ - local IFS=$' \\t\\n' - COMPREPLY=( $( COMP_WORDS="${{COMP_WORDS[*]}}" \\ - COMP_CWORD=$COMP_CWORD \\ - PIP_AUTO_COMPLETE=1 "$1" 2>/dev/null ) ) - }} - complete -o default -F _pip_completion {prog} - """, - "zsh": """ - #compdef -P pip[0-9.]# - __pip() {{ - compadd $( COMP_WORDS="$words[*]" \\ - COMP_CWORD=$((CURRENT-1)) \\ - PIP_AUTO_COMPLETE=1 $words[1] 2>/dev/null ) - }} - if [[ $zsh_eval_context[-1] == loadautofunc ]]; then - # autoload from fpath, call function directly - __pip "$@" - else - # eval/source/. command, register function for later - compdef __pip -P 'pip[0-9.]#' - fi - """, - "fish": """ - function __fish_complete_pip - set -lx COMP_WORDS \\ - (commandline --current-process --tokenize --cut-at-cursor) \\ - (commandline --current-token --cut-at-cursor) - set -lx COMP_CWORD (math (count $COMP_WORDS) - 1) - set -lx PIP_AUTO_COMPLETE 1 - set -l completions - if string match -q '2.*' $version - set completions (eval $COMP_WORDS[1]) - else - set completions ($COMP_WORDS[1]) - end - string split \\ -- $completions - end - complete -fa "(__fish_complete_pip)" -c {prog} - """, - "powershell": """ - if ((Test-Path Function:\\TabExpansion) -and -not ` - (Test-Path Function:\\_pip_completeBackup)) {{ - Rename-Item Function:\\TabExpansion _pip_completeBackup - }} - function TabExpansion($line, $lastWord) {{ - $lastBlock = [regex]::Split($line, '[|;]')[-1].TrimStart() - if ($lastBlock.StartsWith("{prog} ")) {{ - $Env:COMP_WORDS=$lastBlock - $Env:COMP_CWORD=$lastBlock.Split().Length - 1 - $Env:PIP_AUTO_COMPLETE=1 - (& {prog}).Split() - Remove-Item Env:COMP_WORDS - Remove-Item Env:COMP_CWORD - Remove-Item Env:PIP_AUTO_COMPLETE - }} - elseif (Test-Path Function:\\_pip_completeBackup) {{ - # Fall back on existing tab expansion - _pip_completeBackup $line $lastWord - }} - }} - """, -} - - -class CompletionCommand(Command): - """A helper command to be used for command completion.""" - - ignore_require_venv = True - - def add_options(self) -> None: - self.cmd_opts.add_option( - "--bash", - "-b", - action="store_const", - const="bash", - dest="shell", - help="Emit completion code for bash", - ) - self.cmd_opts.add_option( - "--zsh", - "-z", - action="store_const", - const="zsh", - dest="shell", - help="Emit completion code for zsh", - ) - self.cmd_opts.add_option( - "--fish", - "-f", - action="store_const", - const="fish", - dest="shell", - help="Emit completion code for fish", - ) - self.cmd_opts.add_option( - "--powershell", - "-p", - action="store_const", - const="powershell", - dest="shell", - help="Emit completion code for powershell", - ) - - self.parser.insert_option_group(0, self.cmd_opts) - - def run(self, options: Values, args: list[str]) -> int: - """Prints the completion code of the given shell""" - shells = COMPLETION_SCRIPTS.keys() - shell_options = ["--" + shell for shell in sorted(shells)] - if options.shell in shells: - script = textwrap.dedent( - COMPLETION_SCRIPTS.get(options.shell, "").format(prog=get_prog()) - ) - print(BASE_COMPLETION.format(script=script, shell=options.shell)) - return SUCCESS - else: - sys.stderr.write( - "ERROR: You must pass {}\n".format(" or ".join(shell_options)) - ) - return SUCCESS diff --git a/venv/lib/python3.11/site-packages/pip/_internal/commands/configuration.py b/venv/lib/python3.11/site-packages/pip/_internal/commands/configuration.py deleted file mode 100755 index 4fa860f..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/commands/configuration.py +++ /dev/null @@ -1,289 +0,0 @@ -from __future__ import annotations - -import logging -import os -import subprocess -from collections.abc import Callable -from optparse import Values -from typing import Any - -from pip._internal.cli.base_command import Command -from pip._internal.cli.status_codes import ERROR, SUCCESS -from pip._internal.configuration import ( - Configuration, - Kind, - get_configuration_files, - kinds, -) -from pip._internal.exceptions import PipError -from pip._internal.utils.logging import indent_log -from pip._internal.utils.misc import get_prog, write_output - -logger = logging.getLogger(__name__) - - -class ConfigurationCommand(Command): - """ - Manage local and global configuration. - - Subcommands: - - - list: List the active configuration (or from the file specified) - - edit: Edit the configuration file in an editor - - get: Get the value associated with command.option - - set: Set the command.option=value - - unset: Unset the value associated with command.option - - debug: List the configuration files and values defined under them - - Configuration keys should be dot separated command and option name, - with the special prefix "global" affecting any command. For example, - "pip config set global.index-url https://example.org/" would configure - the index url for all commands, but "pip config set download.timeout 10" - would configure a 10 second timeout only for "pip download" commands. - - If none of --user, --global and --site are passed, a virtual - environment configuration file is used if one is active and the file - exists. Otherwise, all modifications happen to the user file by - default. - """ - - ignore_require_venv = True - usage = """ - %prog [] list - %prog [] [--editor ] edit - - %prog [] get command.option - %prog [] set command.option value - %prog [] unset command.option - %prog [] debug - """ - - def add_options(self) -> 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( - "--site", - dest="site_file", - action="store_true", - default=False, - help="Use the current environment configuration file only", - ) - - self.parser.insert_option_group(0, self.cmd_opts) - - def handler_map(self) -> dict[str, Callable[[Values, list[str]], None]]: - return { - "list": self.list_values, - "edit": self.open_in_editor, - "get": self.get_name, - "set": self.set_name_value, - "unset": self.unset_name, - "debug": self.list_config_values, - } - - def run(self, options: Values, args: list[str]) -> int: - handler_map = self.handler_map() - - # Determine action - if not args or args[0] not in handler_map: - logger.error( - "Need an action (%s) to perform.", - ", ".join(sorted(handler_map)), - ) - 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: - handler_map[action](options, args[1:]) - except PipError as e: - logger.error(e.args[0]) - return ERROR - - return SUCCESS - - def _determine_file(self, options: Values, need_value: bool) -> Kind | None: - file_options = [ - key - for key, value in ( - (kinds.USER, options.user_file), - (kinds.GLOBAL, options.global_file), - (kinds.SITE, options.site_file), - ) - if value - ] - - if not file_options: - if not need_value: - return None - # Default to user, unless there's a site file. - elif any( - os.path.exists(site_config_file) - for site_config_file in get_configuration_files()[kinds.SITE] - ): - return kinds.SITE - else: - return kinds.USER - elif len(file_options) == 1: - return file_options[0] - - raise PipError( - "Need exactly one file to operate upon " - "(--user, --site, --global) to perform." - ) - - def list_values(self, options: Values, args: list[str]) -> None: - self._get_n_args(args, "list", n=0) - - for key, value in sorted(self.configuration.items()): - for key, value in sorted(value.items()): - write_output("%s=%r", key, value) - - def get_name(self, options: Values, args: list[str]) -> None: - key = self._get_n_args(args, "get [name]", n=1) - value = self.configuration.get_value(key) - - write_output("%s", value) - - def set_name_value(self, options: Values, args: list[str]) -> None: - key, value = self._get_n_args(args, "set [name] [value]", n=2) - self.configuration.set_value(key, value) - - self._save_configuration() - - def unset_name(self, options: Values, args: list[str]) -> None: - key = self._get_n_args(args, "unset [name]", n=1) - self.configuration.unset_value(key) - - self._save_configuration() - - def list_config_values(self, options: Values, args: list[str]) -> None: - """List config key-value pairs across different config files""" - self._get_n_args(args, "debug", n=0) - - self.print_env_var_values() - # Iterate over config files and print if they exist, and the - # key-value pairs present in them if they do - for variant, files in sorted(self.configuration.iter_config_files()): - write_output("%s:", variant) - for fname in files: - with indent_log(): - file_exists = os.path.exists(fname) - write_output("%s, exists: %r", fname, file_exists) - if file_exists: - self.print_config_file_values(variant, fname) - - def print_config_file_values(self, variant: Kind, fname: str) -> None: - """Get key-value pairs from the file of a variant""" - for name, value in self.configuration.get_values_in_config(variant).items(): - with indent_log(): - if name == fname: - for confname, confvalue in value.items(): - write_output("%s: %s", confname, confvalue) - - def print_env_var_values(self) -> None: - """Get key-values pairs present as environment variables""" - write_output("%s:", "env_var") - with indent_log(): - for key, value in sorted(self.configuration.get_environ_vars()): - env_var = f"PIP_{key.upper()}" - write_output("%s=%r", env_var, value) - - def open_in_editor(self, options: Values, args: list[str]) -> None: - editor = self._determine_editor(options) - - fname = self.configuration.get_file_to_edit() - if fname is None: - raise PipError("Could not determine appropriate file.") - elif '"' in fname: - # This shouldn't happen, unless we see a username like that. - # If that happens, we'd appreciate a pull request fixing this. - raise PipError( - f'Can not open an editor for a file name containing "\n{fname}' - ) - - try: - subprocess.check_call(f'{editor} "{fname}"', shell=True) - except FileNotFoundError as e: - if not e.filename: - e.filename = editor - raise - except subprocess.CalledProcessError as e: - raise PipError(f"Editor Subprocess exited with exit code {e.returncode}") - - def _get_n_args(self, args: list[str], example: str, n: int) -> Any: - """Helper to make sure the command got the right number of arguments""" - if len(args) != n: - msg = ( - f"Got unexpected number of arguments, expected {n}. " - f'(example: "{get_prog()} config {example}")' - ) - raise PipError(msg) - - if n == 1: - return args[0] - else: - return args - - def _save_configuration(self) -> None: - # We successfully ran a modifying command. Need to save the - # configuration. - try: - self.configuration.save() - except Exception: - logger.exception( - "Unable to save configuration. Please report this as a bug." - ) - raise PipError("Internal Error.") - - def _determine_editor(self, options: Values) -> str: - 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.11/site-packages/pip/_internal/commands/debug.py b/venv/lib/python3.11/site-packages/pip/_internal/commands/debug.py deleted file mode 100755 index 4e8178d..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/commands/debug.py +++ /dev/null @@ -1,195 +0,0 @@ -from __future__ import annotations - -import logging -import os -import sys -from optparse import Values -from types import ModuleType -from typing import Any - -import pip._vendor -from pip._vendor.certifi import where -from pip._vendor.packaging.version import parse as parse_version - -from pip._internal.cli import cmdoptions -from pip._internal.cli.base_command import Command -from pip._internal.cli.cmdoptions import make_target_python -from pip._internal.cli.status_codes import SUCCESS -from pip._internal.configuration import Configuration -from pip._internal.metadata import get_environment -from pip._internal.utils.compat import get_locale_encoding, open_text_resource -from pip._internal.utils.logging import indent_log -from pip._internal.utils.misc import get_pip_version - -logger = logging.getLogger(__name__) - - -def show_value(name: str, value: Any) -> None: - logger.info("%s: %s", name, value) - - -def show_sys_implementation() -> None: - logger.info("sys.implementation:") - implementation_name = sys.implementation.name - with indent_log(): - show_value("name", implementation_name) - - -def create_vendor_txt_map() -> dict[str, str]: - with open_text_resource("pip._vendor", "vendor.txt") as f: - # Purge non version specifying lines. - # Also, remove any space prefix or suffixes (including comments). - lines = [ - line.strip().split(" ", 1)[0] for line in f.readlines() if "==" in line - ] - - # Transform into "module" -> version dict. - return dict(line.split("==", 1) for line in lines) - - -def get_module_from_module_name(module_name: str) -> ModuleType | None: - # Module name can be uppercase in vendor.txt for some reason... - module_name = module_name.lower().replace("-", "_") - # PATCH: setuptools is actually only pkg_resources. - if module_name == "setuptools": - module_name = "pkg_resources" - - __import__(f"pip._vendor.{module_name}", globals(), locals(), level=0) - return getattr(pip._vendor, module_name) - - -def get_vendor_version_from_module(module_name: str) -> str | None: - module = get_module_from_module_name(module_name) - version = getattr(module, "__version__", None) - - if module and not version: - # Try to find version in debundled module info. - assert module.__file__ is not None - env = get_environment([os.path.dirname(module.__file__)]) - dist = env.get_distribution(module_name) - if dist: - version = str(dist.version) - - return version - - -def show_actual_vendor_versions(vendor_txt_versions: dict[str, str]) -> None: - """Log the actual version and print extra info if there is - a conflict or if the actual version could not be imported. - """ - for module_name, expected_version in vendor_txt_versions.items(): - extra_message = "" - actual_version = get_vendor_version_from_module(module_name) - if not actual_version: - extra_message = ( - " (Unable to locate actual module version, using" - " vendor.txt specified version)" - ) - actual_version = expected_version - elif parse_version(actual_version) != parse_version(expected_version): - extra_message = ( - " (CONFLICT: vendor.txt suggests version should" - f" be {expected_version})" - ) - logger.info("%s==%s%s", module_name, actual_version, extra_message) - - -def show_vendor_versions() -> None: - logger.info("vendored library versions:") - - vendor_txt_versions = create_vendor_txt_map() - with indent_log(): - show_actual_vendor_versions(vendor_txt_versions) - - -def show_tags(options: Values) -> None: - tag_limit = 10 - - target_python = make_target_python(options) - tags = target_python.get_sorted_tags() - - # Display the target options that were explicitly provided. - formatted_target = target_python.format_given() - suffix = "" - if formatted_target: - suffix = f" (target: {formatted_target})" - - msg = f"Compatible tags: {len(tags)}{suffix}" - logger.info(msg) - - if options.verbose < 1 and len(tags) > tag_limit: - tags_limited = True - tags = tags[:tag_limit] - else: - tags_limited = False - - with indent_log(): - for tag in tags: - logger.info(str(tag)) - - if tags_limited: - msg = f"...\n[First {tag_limit} tags shown. Pass --verbose to show all.]" - logger.info(msg) - - -def ca_bundle_info(config: Configuration) -> str: - levels = {key.split(".", 1)[0] for _, options in config.items() for key in options} - if not levels: - return "Not specified" - - levels_that_override_global = ["install", "wheel", "download"] - global_overriding_level = [ - level for level in levels if level in levels_that_override_global - ] - if not global_overriding_level: - return "global" - - if "global" in levels: - levels.remove("global") - return ", ".join(levels) - - -class DebugCommand(Command): - """ - Display debug information. - """ - - usage = """ - %prog """ - ignore_require_venv = True - - def add_options(self) -> None: - cmdoptions.add_target_python_options(self.cmd_opts) - self.parser.insert_option_group(0, self.cmd_opts) - self.parser.config.load() - - def run(self, options: Values, args: list[str]) -> int: - logger.warning( - "This command is only meant for debugging. " - "Do not use this with automation for parsing and getting these " - "details, since the output and options of this command may " - "change without notice." - ) - show_value("pip version", get_pip_version()) - show_value("sys.version", sys.version) - show_value("sys.executable", sys.executable) - show_value("sys.getdefaultencoding", sys.getdefaultencoding()) - show_value("sys.getfilesystemencoding", sys.getfilesystemencoding()) - show_value( - "locale.getencoding", - get_locale_encoding(), - ) - show_value("sys.platform", sys.platform) - show_sys_implementation() - - show_value("'cert' config value", ca_bundle_info(self.parser.config)) - show_value("REQUESTS_CA_BUNDLE", os.environ.get("REQUESTS_CA_BUNDLE")) - show_value("CURL_CA_BUNDLE", os.environ.get("CURL_CA_BUNDLE")) - show_value("pip._vendor.certifi.where()", where()) - show_value("pip._vendor.DEBUNDLED", pip._vendor.DEBUNDLED) - - show_vendor_versions() - - show_tags(options) - - return SUCCESS diff --git a/venv/lib/python3.11/site-packages/pip/_internal/commands/download.py b/venv/lib/python3.11/site-packages/pip/_internal/commands/download.py deleted file mode 100755 index 8b34982..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/commands/download.py +++ /dev/null @@ -1,150 +0,0 @@ -import logging -import os -from optparse import Values - -from pip._internal.cli import cmdoptions -from pip._internal.cli.cmdoptions import make_target_python -from pip._internal.cli.req_command import RequirementCommand, with_cleanup -from pip._internal.cli.status_codes import SUCCESS -from pip._internal.operations.build.build_tracker import get_build_tracker -from pip._internal.utils.misc import ensure_dir, normalize_path, write_output -from pip._internal.utils.temp_dir import TempDirectory - -logger = logging.getLogger(__name__) - - -class DownloadCommand(RequirementCommand): - """ - Download packages from: - - - PyPI (and other indexes) using requirement specifiers. - - VCS project urls. - - Local project directories. - - Local or remote source archives. - - pip also supports downloading from "requirements files", which provide - an easy way to specify a whole environment to be downloaded. - """ - - usage = """ - %prog [options] [package-index-options] ... - %prog [options] -r [package-index-options] ... - %prog [options] ... - %prog [options] ... - %prog [options] ...""" - - def add_options(self) -> None: - self.cmd_opts.add_option(cmdoptions.constraints()) - self.cmd_opts.add_option(cmdoptions.build_constraints()) - self.cmd_opts.add_option(cmdoptions.requirements()) - self.cmd_opts.add_option(cmdoptions.requirements_from_scripts()) - self.cmd_opts.add_option(cmdoptions.no_deps()) - self.cmd_opts.add_option(cmdoptions.only_deps()) - self.cmd_opts.add_option(cmdoptions.src()) - self.cmd_opts.add_option(cmdoptions.require_hashes()) - self.cmd_opts.add_option(cmdoptions.no_require_hashes()) - self.cmd_opts.add_option(cmdoptions.progress_bar()) - self.cmd_opts.add_option(cmdoptions.no_build_isolation()) - self.cmd_opts.add_option(cmdoptions.use_pep517()) - self.cmd_opts.add_option(cmdoptions.check_build_deps()) - self.cmd_opts.add_option(cmdoptions.ignore_requires_python()) - - self.cmd_opts.add_option( - "-d", - "--dest", - "--destination-dir", - "--destination-directory", - dest="download_dir", - metavar="dir", - default=os.curdir, - help="Download packages into .", - ) - - cmdoptions.add_target_python_options(self.cmd_opts) - - index_opts = cmdoptions.make_option_group( - cmdoptions.index_group, - self.parser, - ) - - selection_opts = cmdoptions.make_option_group( - cmdoptions.package_selection_group, - self.parser, - ) - - self.parser.insert_option_group(0, index_opts) - self.parser.insert_option_group(0, selection_opts) - self.parser.insert_option_group(0, self.cmd_opts) - - @with_cleanup - def run(self, options: Values, args: list[str]) -> int: - options.ignore_installed = True - # editable doesn't really make sense for `pip download`, but the bowels - # of the RequirementSet code require that property. - options.editables = [] - - cmdoptions.check_dist_restriction(options) - cmdoptions.check_build_constraints(options) - cmdoptions.check_release_control_exclusive(options) - cmdoptions.check_only_deps_option_does_not_conflict(options) - - options.download_dir = normalize_path(options.download_dir) - ensure_dir(options.download_dir) - - session = self.get_default_session(options) - - target_python = make_target_python(options) - finder = self._build_package_finder( - options=options, - session=session, - target_python=target_python, - ignore_requires_python=options.ignore_requires_python, - ) - - build_tracker = self.enter_context(get_build_tracker()) - - directory = TempDirectory( - delete=not options.no_clean, - kind="download", - globally_managed=True, - ) - - reqs = self.get_requirements(args, options, finder, session) - - preparer = self.make_requirement_preparer( - temp_build_dir=directory, - options=options, - build_tracker=build_tracker, - session=session, - finder=finder, - download_dir=options.download_dir, - use_user_site=False, - verbosity=self.verbosity, - allow_editables=False, - ) - - resolver = self.make_resolver( - preparer=preparer, - finder=finder, - options=options, - ignore_requires_python=options.ignore_requires_python, - py_version_info=options.python_version, - ) - - self.trace_basic_info(finder) - - requirement_set = resolver.resolve(reqs, check_supported_wheels=True) - - preparer.prepare_linked_requirements_more(requirement_set.requirements.values()) - - downloaded: list[str] = [] - for req in requirement_set.requirements.values(): - if req.satisfied_by is None: - assert req.name is not None - preparer.save_linked_requirement(req) - downloaded.append(req.name) - - if downloaded: - write_output("Successfully downloaded %s", " ".join(downloaded)) - - return SUCCESS diff --git a/venv/lib/python3.11/site-packages/pip/_internal/commands/freeze.py b/venv/lib/python3.11/site-packages/pip/_internal/commands/freeze.py deleted file mode 100755 index ab501db..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/commands/freeze.py +++ /dev/null @@ -1,107 +0,0 @@ -import sys -from optparse import Values - -from pip._internal.cli import cmdoptions -from pip._internal.cli.base_command import Command -from pip._internal.cli.status_codes import SUCCESS -from pip._internal.metadata.base import stdlib_pkgs -from pip._internal.operations.freeze import freeze - - -def _should_suppress_build_backends() -> bool: - return sys.version_info < (3, 12) - - -def _dev_pkgs() -> set[str]: - pkgs = {"pip"} - - if _should_suppress_build_backends(): - pkgs |= {"setuptools", "distribute", "wheel"} - - return pkgs - - -class FreezeCommand(Command): - """ - Output installed packages in requirements format. - - packages are listed in a case-insensitive sorted order. - """ - - ignore_require_venv = True - usage = """ - %prog [options]""" - - def add_options(self) -> None: - 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( - "-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(cmdoptions.list_path()) - self.cmd_opts.add_option( - "--all", - dest="freeze_all", - action="store_true", - help=( - "Do not skip these packages in the output:" - " {}".format(", ".join(_dev_pkgs())) - ), - ) - self.cmd_opts.add_option( - "--exclude-editable", - dest="exclude_editable", - action="store_true", - help="Exclude editable package from output.", - ) - self.cmd_opts.add_option(cmdoptions.list_exclude()) - - self.parser.insert_option_group(0, self.cmd_opts) - - def run(self, options: Values, args: list[str]) -> int: - skip = set(stdlib_pkgs) - if not options.freeze_all: - skip.update(_dev_pkgs()) - - if options.excludes: - skip.update(options.excludes) - - cmdoptions.check_list_path_option(options) - - for line in freeze( - requirement=options.requirements, - local_only=options.local, - user_only=options.user, - paths=options.path, - isolated=options.isolated_mode, - skip=skip, - exclude_editable=options.exclude_editable, - ): - sys.stdout.write(line + "\n") - return SUCCESS diff --git a/venv/lib/python3.11/site-packages/pip/_internal/commands/hash.py b/venv/lib/python3.11/site-packages/pip/_internal/commands/hash.py deleted file mode 100755 index 271a4c9..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/commands/hash.py +++ /dev/null @@ -1,58 +0,0 @@ -import hashlib -import logging -import sys -from optparse import Values - -from pip._internal.cli.base_command import Command -from pip._internal.cli.status_codes import ERROR, SUCCESS -from pip._internal.utils.hashes import FAVORITE_HASH, STRONG_HASHES -from pip._internal.utils.misc import read_chunks, write_output - -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. - """ - - usage = "%prog [options] ..." - ignore_require_venv = True - - def add_options(self) -> None: - self.cmd_opts.add_option( - "-a", - "--algorithm", - dest="algorithm", - choices=STRONG_HASHES, - action="store", - default=FAVORITE_HASH, - help="The hash algorithm to use: one of {}".format( - ", ".join(STRONG_HASHES) - ), - ) - self.parser.insert_option_group(0, self.cmd_opts) - - def run(self, options: Values, args: list[str]) -> int: - if not args: - self.parser.print_usage(sys.stderr) - return ERROR - - algorithm = options.algorithm - for path in args: - write_output( - "%s:\n--hash=%s:%s", path, algorithm, _hash_of_file(path, algorithm) - ) - return SUCCESS - - -def _hash_of_file(path: str, algorithm: str) -> str: - """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.11/site-packages/pip/_internal/commands/help.py b/venv/lib/python3.11/site-packages/pip/_internal/commands/help.py deleted file mode 100755 index 2ae658f..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/commands/help.py +++ /dev/null @@ -1,40 +0,0 @@ -from optparse import Values - -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""" - - usage = """ - %prog """ - ignore_require_venv = True - - def run(self, options: Values, args: list[str]) -> int: - from pip._internal.commands import ( - commands_dict, - create_command, - get_similar_commands, - ) - - try: - # 'pip help' with no args is handled by pip.__init__.parseopt() - 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 = [f'unknown command "{cmd_name}"'] - if guess: - msg.append(f'maybe you meant "{guess}"') - - raise CommandError(" - ".join(msg)) - - command = create_command(cmd_name) - command.parser.print_help() - - return SUCCESS diff --git a/venv/lib/python3.11/site-packages/pip/_internal/commands/index.py b/venv/lib/python3.11/site-packages/pip/_internal/commands/index.py deleted file mode 100755 index e444b9a..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/commands/index.py +++ /dev/null @@ -1,173 +0,0 @@ -from __future__ import annotations - -import json -import logging -from collections.abc import Callable, Iterable -from optparse import Values -from typing import Any - -from pip._vendor.packaging.utils import canonicalize_name -from pip._vendor.packaging.version import Version - -from pip._internal.cli import cmdoptions -from pip._internal.cli.req_command import IndexGroupCommand -from pip._internal.cli.status_codes import ERROR, SUCCESS -from pip._internal.commands.search import ( - get_installed_distribution, - print_dist_installation_info, -) -from pip._internal.exceptions import ( - CommandError, - DiagnosticPipError, - DistributionNotFound, - PipError, -) -from pip._internal.index.collector import LinkCollector -from pip._internal.index.package_finder import PackageFinder -from pip._internal.models.selection_prefs import SelectionPreferences -from pip._internal.models.target_python import TargetPython -from pip._internal.network.session import PipSession -from pip._internal.utils.misc import write_output - -logger = logging.getLogger(__name__) - - -class IndexCommand(IndexGroupCommand): - """ - Inspect information available from package indexes. - """ - - ignore_require_venv = True - usage = """ - %prog versions - """ - - def add_options(self) -> None: - cmdoptions.add_target_python_options(self.cmd_opts) - - self.cmd_opts.add_option(cmdoptions.ignore_requires_python()) - self.cmd_opts.add_option(cmdoptions.json()) - - index_opts = cmdoptions.make_option_group( - cmdoptions.index_group, - self.parser, - ) - - selection_opts = cmdoptions.make_option_group( - cmdoptions.package_selection_group, - self.parser, - ) - - self.parser.insert_option_group(0, index_opts) - self.parser.insert_option_group(0, selection_opts) - self.parser.insert_option_group(0, self.cmd_opts) - - def handler_map(self) -> dict[str, Callable[[Values, list[str]], None]]: - return { - "versions": self.get_available_package_versions, - } - - def run(self, options: Values, args: list[str]) -> int: - cmdoptions.check_release_control_exclusive(options) - - handler_map = self.handler_map() - - # Determine action - if not args or args[0] not in handler_map: - logger.error( - "Need an action (%s) to perform.", - ", ".join(sorted(handler_map)), - ) - return ERROR - - action = args[0] - - # Error handling happens here, not in the action-handlers. - try: - handler_map[action](options, args[1:]) - except DiagnosticPipError: - raise - except PipError as e: - logger.error(e.args[0]) - return ERROR - - return SUCCESS - - def _build_package_finder( - self, - options: Values, - session: PipSession, - target_python: TargetPython | None = None, - ignore_requires_python: bool = False, - ) -> PackageFinder: - """ - Create a package finder appropriate to the index command. - """ - link_collector = LinkCollector.create(session, options=options) - - # Pass allow_yanked=False to ignore yanked versions. - selection_prefs = SelectionPreferences( - allow_yanked=False, - release_control=options.release_control, - format_control=options.format_control, - ignore_requires_python=ignore_requires_python, - ) - - return PackageFinder.create( - link_collector=link_collector, - selection_prefs=selection_prefs, - target_python=target_python, - uploaded_prior_to=options.uploaded_prior_to, - ) - - def get_available_package_versions(self, options: Values, args: list[Any]) -> None: - if len(args) != 1: - raise CommandError("You need to specify exactly one argument") - - target_python = cmdoptions.make_target_python(options) - query = args[0] - - with self._build_session(options) as session: - finder = self._build_package_finder( - options=options, - session=session, - target_python=target_python, - ignore_requires_python=options.ignore_requires_python, - ) - - versions: Iterable[Version] = ( - candidate.version for candidate in finder.find_all_candidates(query) - ) - - if self.should_exclude_prerelease(options, canonicalize_name(query)): - versions = ( - version for version in versions if not version.is_prerelease - ) - versions = set(versions) - - if not versions: - raise DistributionNotFound( - f"No matching distribution found for {query}" - ) - - formatted_versions = [str(ver) for ver in sorted(versions, reverse=True)] - latest = formatted_versions[0] - - dist = get_installed_distribution(query) - - if options.json: - structured_output = { - "name": query, - "versions": formatted_versions, - "latest": latest, - } - - if dist is not None: - structured_output["installed_version"] = str(dist.version) - - write_output(json.dumps(structured_output)) - - else: - write_output(f"{query} ({latest})") - write_output("Available versions: {}".format(", ".join(formatted_versions))) - print_dist_installation_info(latest, dist) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/commands/inspect.py b/venv/lib/python3.11/site-packages/pip/_internal/commands/inspect.py deleted file mode 100755 index 53b4f00..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/commands/inspect.py +++ /dev/null @@ -1,92 +0,0 @@ -import logging -from optparse import Values -from typing import Any - -from pip._vendor.packaging.markers import default_environment -from pip._vendor.rich import print_json - -from pip import __version__ -from pip._internal.cli import cmdoptions -from pip._internal.cli.base_command import Command -from pip._internal.cli.status_codes import SUCCESS -from pip._internal.metadata import BaseDistribution, get_environment -from pip._internal.metadata.base import stdlib_pkgs -from pip._internal.utils.urls import path_to_url - -logger = logging.getLogger(__name__) - - -class InspectCommand(Command): - """ - Inspect the content of a Python environment and produce a report in JSON format. - """ - - ignore_require_venv = True - usage = """ - %prog [options]""" - - def add_options(self) -> None: - self.cmd_opts.add_option( - "--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.", - ) - self.cmd_opts.add_option(cmdoptions.list_path()) - self.parser.insert_option_group(0, self.cmd_opts) - - def run(self, options: Values, args: list[str]) -> int: - cmdoptions.check_list_path_option(options) - dists = get_environment(options.path).iter_installed_distributions( - local_only=options.local, - user_only=options.user, - skip=set(stdlib_pkgs), - ) - output = { - "version": "1", - "pip_version": __version__, - "installed": [self._dist_to_dict(dist) for dist in dists], - "environment": default_environment(), - # TODO tags? scheme? - } - print_json(data=output) - return SUCCESS - - def _dist_to_dict(self, dist: BaseDistribution) -> dict[str, Any]: - res: dict[str, Any] = { - "metadata": dist.metadata_dict, - "metadata_location": dist.info_location, - } - # direct_url. Note that we don't have download_info (as in the installation - # report) since it is not recorded in installed metadata. - direct_url = dist.direct_url - if direct_url is not None: - res["direct_url"] = direct_url.to_dict_compat() - else: - # Emulate direct_url for legacy editable installs. - editable_project_location = dist.editable_project_location - if editable_project_location is not None: - res["direct_url"] = { - "url": path_to_url(editable_project_location), - "dir_info": { - "editable": True, - }, - } - # installer - installer = dist.installer - if dist.installer: - res["installer"] = installer - # requested - if dist.installed_with_dist_info: - res["requested"] = dist.requested - return res diff --git a/venv/lib/python3.11/site-packages/pip/_internal/commands/install.py b/venv/lib/python3.11/site-packages/pip/_internal/commands/install.py deleted file mode 100755 index e1482b9..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/commands/install.py +++ /dev/null @@ -1,904 +0,0 @@ -from __future__ import annotations - -import contextlib -import errno -import json -import operator -import os -import shutil -import site -import sys -from collections.abc import Iterator -from optparse import SUPPRESS_HELP, Values -from pathlib import Path -from typing import Any - -from pip._vendor.packaging.requirements import InvalidRequirement, Requirement -from pip._vendor.packaging.utils import canonicalize_name -from pip._vendor.requests.exceptions import InvalidProxyURL -from pip._vendor.rich import print_json - -# Eagerly import self_outdated_check to avoid crashes. Otherwise, -# this module would be imported *after* pip was replaced, resulting -# in crashes if the new self_outdated_check module was incompatible -# with the rest of pip that's already imported, or allowing a -# wheel to execute arbitrary code on install by replacing -# self_outdated_check. -import pip._internal.self_outdated_check # noqa: F401 -from pip._internal.cache import WheelCache -from pip._internal.cli import cmdoptions -from pip._internal.cli.cmdoptions import make_target_python -from pip._internal.cli.req_command import ( - RequirementCommand, - with_cleanup, -) -from pip._internal.cli.status_codes import ERROR, SUCCESS -from pip._internal.exceptions import ( - CommandError, - InstallationError, - InstallWheelBuildError, -) -from pip._internal.locations import get_scheme -from pip._internal.metadata import BaseEnvironment, get_environment -from pip._internal.models.installation_report import InstallationReport -from pip._internal.operations.build.build_tracker import get_build_tracker -from pip._internal.operations.check import ConflictDetails, check_install_conflicts -from pip._internal.req import InstallationResult, install_given_reqs -from pip._internal.req.req_install import ( - InstallRequirement, -) -from pip._internal.utils.compat import WINDOWS -from pip._internal.utils.deprecation import deprecated -from pip._internal.utils.filesystem import test_writable_dir -from pip._internal.utils.logging import getLogger -from pip._internal.utils.misc import ( - check_externally_managed, - ensure_dir, - get_pip_version, - protect_pip_from_modification_on_windows, - warn_if_run_as_root, - write_output, -) -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.utils.virtualenv import ( - running_under_virtualenv, - virtualenv_no_global, -) -from pip._internal.wheel_builder import build - -logger = getLogger(__name__) - - -_IMPORT_AUDIT_HOOK_INSTALLED = False -_MISSING_MODULES: set[str] = set() - -# Non-stdlib modules pip (or its vendored dependencies) may import lazily -# after installation has started. Importing them eagerly keeps the audit -# hook from misattributing them to a freshly installed distribution. -_EAGER_IMPORTS: tuple[str, ...] = ( - "pip._internal.operations.install.wheel", - # Used by rich when emitting output to a legacy Windows console. - "pip._vendor.rich._windows_renderer", -) - - -# Imports of standard library modules are always safe: they cannot be -# shadowed by a distribution pip has just installed. -_STDLIB_MODULE_NAMES: frozenset[str] = frozenset(sys.stdlib_module_names) | frozenset( - sys.builtin_module_names -) - - -def _prevent_import_hook(name: str, args: tuple[Any, ...]) -> None: - if name != "import": - return - module = args[0] - if module in _MISSING_MODULES: - raise ImportError(f"No module named {module!r}") - if module.partition(".")[0] in _STDLIB_MODULE_NAMES: - return - deprecated( - reason=f"Unexpected import of {module!r} after pip install started.", - replacement=None, - gone_in="26.3", - issue=13842, - include_source=True, - stacklevel=3, - ) - - -def _eagerly_import_modules() -> None: - """Import modules pip uses lazily so the audit hook ignores them later.""" - for module in _EAGER_IMPORTS: - try: - __import__(module) - except ImportError: - # Record the module as missing so the hook can raise ImportError - # instead of trying to import it again. - _MISSING_MODULES.add(module) - - -def _prevent_further_imports() -> None: - """Install an audit hook that warns on unexpected imports after pip install starts. - - Eagerly pre-imports the known lazy imports first so the hook only fires - on genuinely unexpected modules. - """ - global _IMPORT_AUDIT_HOOK_INSTALLED - if _IMPORT_AUDIT_HOOK_INSTALLED: - return - - _IMPORT_AUDIT_HOOK_INSTALLED = True - sys.addaudithook(_prevent_import_hook) - - -def _arg_refers_to_pip(arg: str) -> bool: - try: - req = Requirement(arg) - except InvalidRequirement: - return False - return canonicalize_name(req.name) == "pip" - - -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. - """ - - usage = """ - %prog [options] [package-index-options] ... - %prog [options] -r [package-index-options] ... - %prog [options] [-e] ... - %prog [options] [-e] ... - %prog [options] ...""" - - def add_options(self) -> None: - self.cmd_opts.add_option(cmdoptions.requirements()) - self.cmd_opts.add_option(cmdoptions.constraints()) - self.cmd_opts.add_option(cmdoptions.build_constraints()) - self.cmd_opts.add_option(cmdoptions.requirements_from_scripts()) - self.cmd_opts.add_option(cmdoptions.no_deps()) - self.cmd_opts.add_option(cmdoptions.only_deps()) - - self.cmd_opts.add_option(cmdoptions.editable()) - self.cmd_opts.add_option( - "--dry-run", - action="store_true", - dest="dry_run", - default=False, - help=( - "Don't actually install anything, just print what would be. " - "Can be used in combination with --ignore-installed " - "to 'resolve' the requirements." - ), - ) - self.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." - ), - ) - cmdoptions.add_target_python_options(self.cmd_opts) - - self.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.)" - ), - ) - self.cmd_opts.add_option( - "--no-user", - dest="use_user_site", - action="store_false", - help=SUPPRESS_HELP, - ) - self.cmd_opts.add_option( - "--root", - dest="root_path", - metavar="dir", - default=None, - help="Install everything relative to this alternate root directory.", - ) - self.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. Note that the resulting installation may " - "contain scripts and other resources which reference the " - "Python interpreter of pip, and not that of ``--prefix``. " - "See also the ``--python`` option if the intention is to " - "install packages into another (possibly pip-free) " - "environment." - ), - ) - - self.cmd_opts.add_option(cmdoptions.src()) - - self.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." - ), - ) - - self.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)." - ), - ) - - self.cmd_opts.add_option( - "--force-reinstall", - dest="force_reinstall", - action="store_true", - help="Reinstall all packages even if they are already up-to-date.", - ) - - self.cmd_opts.add_option( - "-I", - "--ignore-installed", - dest="ignore_installed", - action="store_true", - help=( - "Ignore the installed packages, overwriting them. " - "This can break your system if the existing package " - "is of a different version or was installed " - "with a different package manager!" - ), - ) - - self.cmd_opts.add_option(cmdoptions.ignore_requires_python()) - self.cmd_opts.add_option(cmdoptions.no_build_isolation()) - self.cmd_opts.add_option(cmdoptions.use_pep517()) - self.cmd_opts.add_option(cmdoptions.check_build_deps()) - self.cmd_opts.add_option(cmdoptions.override_externally_managed()) - - self.cmd_opts.add_option(cmdoptions.config_settings()) - - self.cmd_opts.add_option( - "--compile", - action="store_true", - dest="compile", - default=True, - help="Compile Python source files to bytecode", - ) - - self.cmd_opts.add_option( - "--no-compile", - action="store_false", - dest="compile", - help="Do not compile Python source files to bytecode", - ) - - self.cmd_opts.add_option( - "--no-warn-script-location", - action="store_false", - dest="warn_script_location", - default=True, - help="Do not warn when installing scripts outside PATH", - ) - self.cmd_opts.add_option( - "--no-warn-conflicts", - action="store_false", - dest="warn_about_conflicts", - default=True, - help="Do not warn about broken dependencies", - ) - self.cmd_opts.add_option(cmdoptions.require_hashes()) - self.cmd_opts.add_option(cmdoptions.no_require_hashes()) - self.cmd_opts.add_option(cmdoptions.progress_bar()) - self.cmd_opts.add_option(cmdoptions.root_user_action()) - - index_opts = cmdoptions.make_option_group( - cmdoptions.index_group, - self.parser, - ) - - selection_opts = cmdoptions.make_option_group( - cmdoptions.package_selection_group, - self.parser, - ) - - self.parser.insert_option_group(0, index_opts) - self.parser.insert_option_group(0, selection_opts) - self.parser.insert_option_group(0, self.cmd_opts) - - self.cmd_opts.add_option( - "--report", - dest="json_report_file", - metavar="file", - default=None, - help=( - "Generate a JSON file describing what pip did to install " - "the provided requirements. " - "Can be used in combination with --dry-run and --ignore-installed " - "to 'resolve' the requirements. " - "When - is used as file name it writes to stdout. " - "When writing to stdout, please combine with the --quiet option " - "to avoid mixing pip logging output with JSON output." - ), - ) - - @contextlib.contextmanager - def pip_version_check(self, options: Values, args: list[str]) -> Iterator[None]: - # Skip the self-version check when pip itself is a requirement. The - # running pip may be replaced mid-command, and the upgrade prompt - # is redundant. - if any(_arg_refers_to_pip(arg) for arg in args): - yield - return - with super().pip_version_check(options, args): - yield - - @with_cleanup - def run(self, options: Values, args: list[str]) -> int: - if options.use_user_site and options.target_dir is not None: - raise CommandError("Can not combine '--user' and '--target'") - - # Check whether the environment we're installing into is externally - # managed, as specified in PEP 668. Specifying --root, --target, or - # --prefix disables the check, since there's no reliable way to locate - # the EXTERNALLY-MANAGED file for those cases. An exception is also - # made specifically for "--dry-run --report" for convenience. - installing_into_current_environment = ( - not (options.dry_run and options.json_report_file) - and options.root_path is None - and options.target_dir is None - and options.prefix_path is None - ) - if ( - installing_into_current_environment - and not options.override_externally_managed - ): - check_externally_managed() - - upgrade_strategy = "to-satisfy-only" - if options.upgrade: - upgrade_strategy = options.upgrade_strategy - - cmdoptions.check_only_deps_option_does_not_conflict(options) - cmdoptions.check_build_constraints(options) - cmdoptions.check_dist_restriction(options, check_target=True) - cmdoptions.check_release_control_exclusive(options) - - logger.verbose("Using %s", get_pip_version()) - options.use_user_site = decide_user_install( - options.use_user_site, - prefix_path=options.prefix_path, - target_dir=options.target_dir, - root_path=options.root_path, - isolated_mode=options.isolated_mode, - ) - - target_temp_dir: TempDirectory | None = None - target_temp_dir_path: str | None = None - if options.target_dir: - options.ignore_installed = True - options.target_dir = os.path.abspath(options.target_dir) - if ( - # fmt: off - os.path.exists(options.target_dir) and - not os.path.isdir(options.target_dir) - # fmt: on - ): - 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 = TempDirectory(kind="target") - target_temp_dir_path = target_temp_dir.path - self.enter_context(target_temp_dir) - - session = self.get_default_session(options) - - target_python = make_target_python(options) - finder = self._build_package_finder( - options=options, - session=session, - target_python=target_python, - ignore_requires_python=options.ignore_requires_python, - ) - build_tracker = self.enter_context(get_build_tracker()) - - directory = TempDirectory( - delete=not options.no_clean, - kind="install", - globally_managed=True, - ) - - try: - reqs = self.get_requirements(args, options, finder, session) - - wheel_cache = WheelCache(options.cache_dir) - - preparer = self.make_requirement_preparer( - temp_build_dir=directory, - options=options, - build_tracker=build_tracker, - session=session, - finder=finder, - use_user_site=options.use_user_site, - verbosity=self.verbosity, - allow_editables=True, - ) - resolver = self.make_resolver( - preparer=preparer, - finder=finder, - options=options, - wheel_cache=wheel_cache, - use_user_site=options.use_user_site, - ignore_installed=options.ignore_installed, - ignore_requires_python=options.ignore_requires_python, - force_reinstall=options.force_reinstall, - upgrade_strategy=upgrade_strategy, - py_version_info=options.python_version, - ) - - self.trace_basic_info(finder) - - requirement_set = resolver.resolve( - reqs, check_supported_wheels=not options.target_dir - ) - - if options.json_report_file: - report = InstallationReport(requirement_set.requirements_to_install) - if options.json_report_file == "-": - print_json(data=report.to_dict()) - else: - with open(options.json_report_file, "w", encoding="utf-8") as f: - json.dump(report.to_dict(), f, indent=2, ensure_ascii=False) - - if options.dry_run: - would_install_items = sorted( - (r.metadata["name"], r.metadata["version"]) - for r in requirement_set.requirements_to_install - ) - if would_install_items: - write_output( - "Would install %s", - " ".join("-".join(item) for item in would_install_items), - ) - return SUCCESS - - # If there is any more preparation to do for the actual installation, do - # so now. This includes actually downloading the files in the case that - # we have been using PEP-658 metadata so far. - preparer.prepare_linked_requirements_more( - requirement_set.requirements.values() - ) - - try: - pip_req = requirement_set.get_requirement("pip") - except KeyError: - modifying_pip = False - else: - # If we're not replacing an already installed pip, - # we're not modifying it. - modifying_pip = pip_req.satisfied_by is None - protect_pip_from_modification_on_windows(modifying_pip=modifying_pip) - - reqs_to_build = [ - r for r in requirement_set.requirements_to_install if not r.is_wheel - ] - - _, build_failures = build( - reqs_to_build, - wheel_cache=wheel_cache, - verify=True, - allow_editables=True, - ) - - if build_failures: - raise InstallWheelBuildError(build_failures) - - to_install = resolver.get_installation_order(requirement_set) - - # Check for conflicts in the package set we're installing. - conflicts: ConflictDetails | None = None - should_warn_about_conflicts = ( - not options.ignore_dependencies and options.warn_about_conflicts - ) - if should_warn_about_conflicts: - conflicts = self._determine_conflicts(to_install) - - # Don't warn about script install locations if - # --target or --prefix has been specified - warn_script_location = options.warn_script_location - if options.target_dir or options.prefix_path: - warn_script_location = False - - # Warn on late imports so we don't silently pick up a module - # from a distribution pip is about to install. - try: - _eagerly_import_modules() - finally: - _prevent_further_imports() - - installed = install_given_reqs( - to_install, - root=options.root_path, - home=target_temp_dir_path, - prefix=options.prefix_path, - warn_script_location=warn_script_location, - use_user_site=options.use_user_site, - pycompile=options.compile, - progress_bar=options.progress_bar, - ) - - 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, - ) - env = get_environment(lib_locations) - - if conflicts is not None: - self._warn_about_conflicts( - conflicts, - resolver_variant=self.determine_resolver_variant(options), - ) - if summary := installed_packages_summary(installed, env): - write_output(summary) - except OSError as error: - show_traceback = self.verbosity >= 1 - - message = create_os_error_message( - error, - show_traceback, - options.use_user_site, - ) - logger.error(message, exc_info=show_traceback) - - return ERROR - - if options.target_dir: - assert target_temp_dir - self._handle_target_dir( - options.target_dir, target_temp_dir, options.upgrade - ) - if options.root_user_action == "warn": - warn_if_run_as_root() - return SUCCESS - - def _handle_target_dir( - self, target_dir: str, target_temp_dir: TempDirectory, upgrade: bool - ) -> None: - ensure_dir(target_dir) - - # Checking both purelib and platlib directories for installed - # packages to be moved to target directory - lib_dir_list = [] - - # Checking both purelib and platlib directories for installed - # packages to be moved to target directory - scheme = get_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 _determine_conflicts( - self, to_install: list[InstallRequirement] - ) -> ConflictDetails | None: - try: - return check_install_conflicts(to_install) - except Exception: - logger.exception( - "Error while checking for conflicts. Please file an issue on " - "pip's issue tracker: https://github.com/pypa/pip/issues/new" - ) - return None - - def _warn_about_conflicts( - self, conflict_details: ConflictDetails, resolver_variant: str - ) -> None: - package_set, (missing, conflicting) = conflict_details - if not missing and not conflicting: - return - - parts: list[str] = [] - if resolver_variant == "legacy": - parts.append( - "pip's legacy dependency resolver does not consider dependency " - "conflicts when selecting packages. This behaviour is the " - "source of the following dependency conflicts." - ) - else: - assert resolver_variant == "resolvelib" - parts.append( - "pip's dependency resolver does not currently take into account " - "all the packages that are installed. This behaviour is the " - "source of the following dependency conflicts." - ) - - # NOTE: There is some duplication here, with commands/check.py - for project_name in missing: - version = package_set[project_name][0] - for dependency in missing[project_name]: - message = ( - f"{project_name} {version} requires {dependency[1]}, " - "which is not installed." - ) - parts.append(message) - - for project_name in conflicting: - version = package_set[project_name][0] - for dep_name, dep_version, req in conflicting[project_name]: - message = ( - "{name} {version} requires {requirement}, but {you} have " - "{dep_name} {dep_version} which is incompatible." - ).format( - name=project_name, - version=version, - requirement=req, - dep_name=dep_name, - dep_version=dep_version, - you=("you" if resolver_variant == "resolvelib" else "you'll"), - ) - parts.append(message) - - logger.critical("\n".join(parts)) - - -def installed_packages_summary( - installed: list[InstallationResult], env: BaseEnvironment -) -> str: - # Format a summary of installed packages, with extra care to - # display a package name as it was requested by the user. - installed.sort(key=operator.attrgetter("name")) - summary = [] - installed_versions = {} - for distribution in env.iter_all_distributions(): - installed_versions[distribution.canonical_name] = distribution.version - for package in installed: - display_name = package.name - version = installed_versions.get(canonicalize_name(display_name), None) - if version: - text = f"{display_name}-{version}" - else: - text = display_name - summary.append(text) - - if not summary: - return "" - return f"Successfully installed {' '.join(summary)}" - - -def get_lib_location_guesses( - user: bool = False, - home: str | None = None, - root: str | None = None, - isolated: bool = False, - prefix: str | None = None, -) -> list[str]: - scheme = get_scheme( - "", - user=user, - home=home, - root=root, - isolated=isolated, - prefix=prefix, - ) - return [scheme.purelib, scheme.platlib] - - -def site_packages_writable(root: str | None, isolated: bool) -> bool: - return all( - test_writable_dir(d) - for d in set(get_lib_location_guesses(root=root, isolated=isolated)) - ) - - -def decide_user_install( - use_user_site: bool | None, - prefix_path: str | None = None, - target_dir: str | None = None, - root_path: str | None = None, - isolated_mode: bool = False, -) -> bool: - """Determine whether to do a user install based on the input options. - - If use_user_site is False, no additional checks are done. - If use_user_site is True, it is checked for compatibility with other - options. - If use_user_site is None, the default behaviour depends on the environment, - which is provided by the other arguments. - """ - # In some cases (config from tox), use_user_site can be set to an integer - # rather than a bool, which 'use_user_site is False' wouldn't catch. - if (use_user_site is not None) and (not use_user_site): - logger.debug("Non-user install by explicit request") - return False - - # If we have been asked for a user install explicitly, check compatibility. - if use_user_site: - if prefix_path: - raise CommandError( - "Can not combine '--user' and '--prefix' as they imply " - "different installation locations" - ) - if virtualenv_no_global(): - raise InstallationError( - "Can not perform a '--user' install. User site-packages " - "are not visible in this virtualenv." - ) - # Catch all remaining cases which honour the site.ENABLE_USER_SITE - # value, such as a plain Python installation (e.g. no virtualenv). - if not site.ENABLE_USER_SITE: - raise InstallationError( - "Can not perform a '--user' install. User site-packages " - "are disabled for this Python." - ) - logger.debug("User install by explicit request") - return True - - # If we are here, user installs have not been explicitly requested/avoided - assert use_user_site is None - - # user install incompatible with --prefix/--target - if prefix_path or target_dir: - logger.debug("Non-user install due to --prefix or --target option") - return False - - # If user installs are not enabled, choose a non-user install - if not site.ENABLE_USER_SITE: - logger.debug("Non-user install because user site-packages disabled") - return False - - # If we have permission for a non-user install, do that, - # otherwise do a user install. - if site_packages_writable(root=root_path, isolated=isolated_mode): - logger.debug("Non-user install because site-packages writeable") - return False - - logger.info( - "Defaulting to user installation because normal site-packages " - "is not writeable" - ) - return True - - -def create_os_error_message( - error: OSError, show_traceback: bool, using_user_site: bool -) -> str: - """Format an error message for an OSError - - 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 OSError") - 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 running_under_virtualenv() and not using_user_site: - parts.extend( - [ - user_option_part, - " or ", - permissions_part.lower(), - ] - ) - else: - parts.append(permissions_part) - parts.append(".\n") - - # Suggest to check "pip config debug" in case of invalid proxy - if type(error) is InvalidProxyURL: - parts.append( - 'Consider checking your local proxy configuration with "pip config debug"' - ) - parts.append(".\n") - - # On Windows, errors like EINVAL or ENOENT may occur - # if a file or folder name exceeds 255 characters, - # or if the full path exceeds 260 characters and long path support isn't enabled. - # This condition checks for such cases and adds a hint to the error output. - - if WINDOWS and error.errno in (errno.EINVAL, errno.ENOENT) and error.filename: - if any(len(part) > 255 for part in Path(error.filename).parts): - parts.append( - "HINT: This error might be caused by a file or folder name exceeding " - "255 characters, which is a Windows limitation even if long paths " - "are enabled.\n " - ) - if len(error.filename) > 260: - parts.append( - "HINT: This error might have occurred since " - "this system does not have Windows Long Path " - "support enabled. You can find information on " - "how to enable this at " - "https://pip.pypa.io/warnings/enable-long-paths\n" - ) - return "".join(parts).strip() + "\n" diff --git a/venv/lib/python3.11/site-packages/pip/_internal/commands/list.py b/venv/lib/python3.11/site-packages/pip/_internal/commands/list.py deleted file mode 100755 index 3d82d07..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/commands/list.py +++ /dev/null @@ -1,408 +0,0 @@ -from __future__ import annotations - -import contextlib -import json -import logging -from collections.abc import Generator, Iterator, Sequence -from email.parser import Parser -from optparse import Values -from typing import TYPE_CHECKING, cast - -from pip._vendor.packaging.utils import canonicalize_name -from pip._vendor.packaging.version import InvalidVersion, Version - -from pip._internal.cli import cmdoptions -from pip._internal.cli.index_command import IndexGroupCommand -from pip._internal.cli.status_codes import SUCCESS -from pip._internal.exceptions import CommandError -from pip._internal.metadata import BaseDistribution, get_environment -from pip._internal.metadata.base import stdlib_pkgs -from pip._internal.models.selection_prefs import SelectionPreferences -from pip._internal.utils.misc import tabulate, write_output - -if TYPE_CHECKING: - from pip._internal.index.package_finder import PackageFinder - from pip._internal.network.session import PipSession - - class _DistWithLatestInfo(BaseDistribution): - """Give the distribution object a couple of extra fields. - - These will be populated during ``get_outdated()``. This is dirty but - makes the rest of the code much cleaner. - """ - - latest_version: Version - latest_filetype: str - - _ProcessedDists = Sequence[_DistWithLatestInfo] - - -logger = logging.getLogger(__name__) - - -class ListCommand(IndexGroupCommand): - """ - List installed packages, including editables. - - Packages are listed in a case-insensitive sorted order. - """ - - ignore_require_venv = True - usage = """ - %prog [options]""" - - def add_options(self) -> None: - self.cmd_opts.add_option( - "-o", - "--outdated", - action="store_true", - default=False, - help="List outdated packages", - ) - self.cmd_opts.add_option( - "-u", - "--uptodate", - action="store_true", - default=False, - help="List uptodate packages", - ) - self.cmd_opts.add_option( - "-e", - "--editable", - action="store_true", - default=False, - help="List editable projects.", - ) - self.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.", - ) - self.cmd_opts.add_option(cmdoptions.list_path()) - - self.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. " - "The 'freeze' format cannot be used with the --outdated option." - ), - ) - - self.cmd_opts.add_option( - "--not-required", - action="store_true", - dest="not_required", - help="List packages that are not dependencies of installed packages.", - ) - - self.cmd_opts.add_option( - "--exclude-editable", - action="store_false", - dest="include_editable", - help="Exclude editable package from output.", - ) - self.cmd_opts.add_option( - "--include-editable", - action="store_true", - dest="include_editable", - help="Include editable package in output.", - default=True, - ) - self.cmd_opts.add_option(cmdoptions.list_exclude()) - index_opts = cmdoptions.make_option_group(cmdoptions.index_group, self.parser) - - selection_opts = cmdoptions.make_option_group( - cmdoptions.package_selection_group, - self.parser, - ) - - self.parser.insert_option_group(0, index_opts) - self.parser.insert_option_group(0, selection_opts) - self.parser.insert_option_group(0, self.cmd_opts) - - @contextlib.contextmanager - def pip_version_check(self, options: Values, args: list[str]) -> Iterator[None]: - if not (options.outdated or options.uptodate): - yield - return - with super().pip_version_check(options, args): - yield - - def _build_package_finder( - self, options: Values, session: PipSession - ) -> PackageFinder: - """ - Create a package finder appropriate to this list command. - """ - # Lazy import the heavy index modules as most list invocations won't need 'em. - from pip._internal.index.collector import LinkCollector - from pip._internal.index.package_finder import PackageFinder - - link_collector = LinkCollector.create(session, options=options) - - # Pass allow_yanked=False to ignore yanked versions. - selection_prefs = SelectionPreferences( - allow_yanked=False, - release_control=options.release_control, - format_control=options.format_control, - prefer_binary=options.prefer_binary, - ) - - return PackageFinder.create( - link_collector=link_collector, - selection_prefs=selection_prefs, - uploaded_prior_to=options.uploaded_prior_to, - ) - - def run(self, options: Values, args: list[str]) -> int: - cmdoptions.check_release_control_exclusive(options) - - if options.outdated and options.uptodate: - raise CommandError("Options --outdated and --uptodate cannot be combined.") - - if options.outdated and options.list_format == "freeze": - raise CommandError( - "List format 'freeze' cannot be used with the --outdated option." - ) - - cmdoptions.check_list_path_option(options) - - packages: _ProcessedDists = [ - cast("_DistWithLatestInfo", d) - for d in get_environment(options.path).iter_installed_distributions( - local_only=options.local, - user_only=options.user, - editables_only=options.editable, - include_editables=options.include_editable, - skip=set(stdlib_pkgs), - ) - ] - - # get_not_required must be called firstly in order to find and - # filter out all dependencies correctly. Otherwise a package - # can't be identified as requirement because some parent packages - # could be filtered out before. - if options.not_required: - packages = self.get_not_required(packages, options) - - if options.excludes: - excluded_names = {canonicalize_name(n) for n in options.excludes} - packages = [ - dist for dist in packages if dist.canonical_name not in excluded_names - ] - - if options.outdated: - packages = self.get_outdated(packages, options) - elif options.uptodate: - packages = self.get_uptodate(packages, options) - - self.output_package_listing(packages, options) - return SUCCESS - - def get_outdated( - self, packages: _ProcessedDists, options: Values - ) -> _ProcessedDists: - return [ - dist - for dist in self.iter_packages_latest_infos(packages, options) - if dist.latest_version > dist.version - ] - - def get_uptodate( - self, packages: _ProcessedDists, options: Values - ) -> _ProcessedDists: - return [ - dist - for dist in self.iter_packages_latest_infos(packages, options) - if dist.latest_version == dist.version - ] - - def get_not_required( - self, packages: _ProcessedDists, options: Values - ) -> _ProcessedDists: - dep_keys = { - canonicalize_name(dep.name) - for dist in packages - for dep in (dist.iter_dependencies() or ()) - } - - # Create a set to remove duplicate packages, and cast it to a list - # to keep the return type consistent with get_outdated and - # get_uptodate - return list({pkg for pkg in packages if pkg.canonical_name not in dep_keys}) - - def iter_packages_latest_infos( - self, packages: _ProcessedDists, options: Values - ) -> Generator[_DistWithLatestInfo, None, None]: - with self._build_session(options) as session: - finder = self._build_package_finder(options, session) - - def latest_info( - dist: _DistWithLatestInfo, - ) -> _DistWithLatestInfo | None: - all_candidates = finder.find_all_candidates(dist.canonical_name) - if self.should_exclude_prerelease(options, dist.canonical_name): - all_candidates = [ - candidate - for candidate in all_candidates - if not candidate.version.is_prerelease - ] - - evaluator = finder.make_candidate_evaluator( - project_name=dist.canonical_name, - ) - best_candidate = evaluator.sort_best_candidate(all_candidates) - if best_candidate is None: - return None - - remote_version = best_candidate.version - if best_candidate.link.is_wheel: - typ = "wheel" - else: - typ = "sdist" - dist.latest_version = remote_version - dist.latest_filetype = typ - return dist - - for dist in map(latest_info, packages): - if dist is not None: - yield dist - - def output_package_listing( - self, packages: _ProcessedDists, options: Values - ) -> None: - packages = sorted( - packages, - key=lambda dist: dist.canonical_name, - ) - 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: - try: - req_string = f"{dist.raw_name}=={dist.version}" - except InvalidVersion: - req_string = f"{dist.raw_name}==={dist.raw_version}" - if options.verbose >= 1: - write_output("%s (%s)", req_string, dist.location) - else: - write_output(req_string) - elif options.list_format == "json": - write_output(format_for_json(packages, options)) - - def output_package_listing_columns( - self, data: list[list[str]], header: list[str] - ) -> None: - # 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("-" * x for x in sizes)) - - for val in pkg_strings: - write_output(val) - - -def format_for_columns( - pkgs: _ProcessedDists, options: Values -) -> tuple[list[list[str]], list[str]]: - """ - Convert the package data into something usable - by output_package_listing_columns. - """ - header = ["Package", "Version"] - - running_outdated = options.outdated - if running_outdated: - header.extend(["Latest", "Type"]) - - def wheel_build_tag(dist: BaseDistribution) -> str | None: - try: - wheel_file = dist.read_text("WHEEL") - except FileNotFoundError: - return None - return Parser().parsestr(wheel_file).get("Build") - - build_tags = [wheel_build_tag(p) for p in pkgs] - has_build_tags = any(build_tags) - if has_build_tags: - header.append("Build") - - has_editables = any(x.editable for x in pkgs) - if has_editables: - header.append("Editable project location") - - if options.verbose >= 1: - header.append("Location") - if options.verbose >= 1: - header.append("Installer") - - data = [] - for i, proj in enumerate(pkgs): - # if we're working on the 'outdated' list, separate out the - # latest_version and type - row = [proj.raw_name, proj.raw_version] - - if running_outdated: - row.append(str(proj.latest_version)) - row.append(proj.latest_filetype) - - if has_build_tags: - row.append(build_tags[i] or "") - - if has_editables: - row.append(proj.editable_project_location or "") - - if options.verbose >= 1: - row.append(proj.location or "") - if options.verbose >= 1: - row.append(proj.installer) - - data.append(row) - - return data, header - - -def format_for_json(packages: _ProcessedDists, options: Values) -> str: - data = [] - for dist in packages: - try: - version = str(dist.version) - except InvalidVersion: - version = dist.raw_version - info = { - "name": dist.raw_name, - "version": version, - } - if options.verbose >= 1: - info["location"] = dist.location or "" - info["installer"] = dist.installer - if options.outdated: - info["latest_version"] = str(dist.latest_version) - info["latest_filetype"] = dist.latest_filetype - editable_project_location = dist.editable_project_location - if editable_project_location: - info["editable_project_location"] = editable_project_location - data.append(info) - return json.dumps(data) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/commands/lock.py b/venv/lib/python3.11/site-packages/pip/_internal/commands/lock.py deleted file mode 100755 index 73df864..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/commands/lock.py +++ /dev/null @@ -1,173 +0,0 @@ -import sys -from optparse import Values -from pathlib import Path - -from pip._vendor import tomli_w -from pip._vendor.packaging.pylock import is_valid_pylock_path - -from pip._internal.cache import WheelCache -from pip._internal.cli import cmdoptions -from pip._internal.cli.req_command import ( - RequirementCommand, - with_cleanup, -) -from pip._internal.cli.status_codes import SUCCESS -from pip._internal.operations.build.build_tracker import get_build_tracker -from pip._internal.utils.logging import getLogger -from pip._internal.utils.misc import ( - get_pip_version, -) -from pip._internal.utils.pylock import pylock_from_install_requirements -from pip._internal.utils.temp_dir import TempDirectory - -logger = getLogger(__name__) - - -class LockCommand(RequirementCommand): - """ - EXPERIMENTAL - Lock packages and their dependencies from: - - - PyPI (and other indexes) using requirement specifiers. - - VCS project urls. - - Local project directories. - - Local or remote source archives. - - pip also supports locking from "requirements files", which provide an easy - way to specify a whole environment to be installed. - - The generated lock file is only guaranteed to be valid for the current - python version and platform. - """ - - usage = """ - %prog [options] [-e] ... - %prog [options] [package-index-options] ... - %prog [options] -r [package-index-options] ... - %prog [options] ...""" - - def add_options(self) -> None: - self.cmd_opts.add_option( - cmdoptions.PipOption( - "--output", - "-o", - dest="output_file", - metavar="path", - type="path", - default="pylock.toml", - help="Lock file name (default=pylock.toml). Use - for stdout.", - ) - ) - self.cmd_opts.add_option(cmdoptions.requirements()) - self.cmd_opts.add_option(cmdoptions.requirements_from_scripts()) - self.cmd_opts.add_option(cmdoptions.constraints()) - self.cmd_opts.add_option(cmdoptions.build_constraints()) - self.cmd_opts.add_option(cmdoptions.no_deps()) - self.cmd_opts.add_option(cmdoptions.only_deps()) - - self.cmd_opts.add_option(cmdoptions.editable()) - - self.cmd_opts.add_option(cmdoptions.src()) - - self.cmd_opts.add_option(cmdoptions.ignore_requires_python()) - self.cmd_opts.add_option(cmdoptions.no_build_isolation()) - self.cmd_opts.add_option(cmdoptions.use_pep517()) - self.cmd_opts.add_option(cmdoptions.check_build_deps()) - - self.cmd_opts.add_option(cmdoptions.config_settings()) - - self.cmd_opts.add_option(cmdoptions.require_hashes()) - self.cmd_opts.add_option(cmdoptions.no_require_hashes()) - self.cmd_opts.add_option(cmdoptions.progress_bar()) - - index_opts = cmdoptions.make_option_group( - cmdoptions.index_group, - self.parser, - ) - - selection_opts = cmdoptions.make_option_group( - cmdoptions.package_selection_group, - self.parser, - ) - - self.parser.insert_option_group(0, index_opts) - self.parser.insert_option_group(0, selection_opts) - self.parser.insert_option_group(0, self.cmd_opts) - - @with_cleanup - def run(self, options: Values, args: list[str]) -> int: - logger.verbose("Using %s", get_pip_version()) - - logger.warning( - "pip lock is currently an experimental command. " - "It may be removed/changed in a future release " - "without prior warning." - ) - - cmdoptions.check_build_constraints(options) - cmdoptions.check_release_control_exclusive(options) - cmdoptions.check_only_deps_option_does_not_conflict(options) - - session = self.get_default_session(options) - - finder = self._build_package_finder( - options=options, - session=session, - ignore_requires_python=options.ignore_requires_python, - ) - build_tracker = self.enter_context(get_build_tracker()) - - directory = TempDirectory( - delete=not options.no_clean, - kind="install", - globally_managed=True, - ) - - reqs = self.get_requirements(args, options, finder, session) - - wheel_cache = WheelCache(options.cache_dir) - - preparer = self.make_requirement_preparer( - temp_build_dir=directory, - options=options, - build_tracker=build_tracker, - session=session, - finder=finder, - use_user_site=False, - verbosity=self.verbosity, - allow_editables=True, - ) - resolver = self.make_resolver( - preparer=preparer, - finder=finder, - options=options, - wheel_cache=wheel_cache, - use_user_site=False, - ignore_installed=True, - ignore_requires_python=options.ignore_requires_python, - upgrade_strategy="to-satisfy-only", - ) - - self.trace_basic_info(finder) - - requirement_set = resolver.resolve(reqs, check_supported_wheels=True) - - if options.output_file == "-": - base_dir = Path.cwd() - else: - output_file_path = Path(options.output_file) - if not is_valid_pylock_path(output_file_path): - logger.warning( - "%s is not a valid lock file name.", - output_file_path, - ) - base_dir = output_file_path.parent - pylock = pylock_from_install_requirements( - requirement_set.requirements.values(), base_dir=base_dir - ) - pylock_toml = tomli_w.dumps(pylock.to_dict()) - if options.output_file == "-": - sys.stdout.write(pylock_toml) - else: - output_file_path.write_text(pylock_toml, encoding="utf-8") - - return SUCCESS diff --git a/venv/lib/python3.11/site-packages/pip/_internal/commands/search.py b/venv/lib/python3.11/site-packages/pip/_internal/commands/search.py deleted file mode 100755 index b8dbc27..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/commands/search.py +++ /dev/null @@ -1,178 +0,0 @@ -from __future__ import annotations - -import logging -import shutil -import sys -import textwrap -import xmlrpc.client -from collections import OrderedDict -from optparse import Values -from typing import TypedDict - -from pip._vendor.packaging.version import parse as parse_version - -from pip._internal.cli.base_command import Command -from pip._internal.cli.req_command import SessionCommandMixin -from pip._internal.cli.status_codes import NO_MATCHES_FOUND, SUCCESS -from pip._internal.exceptions import CommandError -from pip._internal.metadata import get_default_environment -from pip._internal.metadata.base import BaseDistribution -from pip._internal.models.index import PyPI -from pip._internal.network.xmlrpc import PipXmlrpcTransport -from pip._internal.utils.logging import indent_log -from pip._internal.utils.misc import write_output - - -class TransformedHit(TypedDict): - name: str - summary: str - versions: list[str] - - -logger = logging.getLogger(__name__) - - -class SearchCommand(Command, SessionCommandMixin): - """Search for PyPI packages whose name or summary contains .""" - - usage = """ - %prog [options] """ - ignore_require_venv = True - - def add_options(self) -> None: - 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: Values, args: list[str]) -> int: - 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 = shutil.get_terminal_size()[0] - - print_results(hits, terminal_width=terminal_width) - if pypi_hits: - return SUCCESS - return NO_MATCHES_FOUND - - def search(self, query: list[str], options: Values) -> list[dict[str, str]]: - index_url = options.index - - session = self.get_default_session(options) - - transport = PipXmlrpcTransport(index_url, session) - pypi = xmlrpc.client.ServerProxy(index_url, transport) - try: - hits = pypi.search({"name": query, "summary": query}, "or") - except xmlrpc.client.Fault as fault: - message = ( - f"XMLRPC request failed [code: {fault.faultCode}]\n{fault.faultString}" - ) - raise CommandError(message) - assert isinstance(hits, list) - return hits - - -def transform_hits(hits: list[dict[str, str]]) -> list[TransformedHit]: - """ - The list from pypi is really a list of versions. We want a list of - packages with the list of versions stored inline. This converts the - list from pypi into one we can use. - """ - packages: dict[str, TransformedHit] = 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_dist_installation_info(latest: str, dist: BaseDistribution | None) -> None: - if dist is not None: - with indent_log(): - if dist.version == latest: - write_output("INSTALLED: %s (latest)", dist.version) - else: - write_output("INSTALLED: %s", dist.version) - if parse_version(latest).pre: - write_output( - "LATEST: %s (pre-release; install" - " with `pip install --pre`)", - latest, - ) - else: - write_output("LATEST: %s", latest) - - -def get_installed_distribution(name: str) -> BaseDistribution | None: - env = get_default_environment() - return env.get_distribution(name) - - -def print_results( - hits: list[TransformedHit], - name_column_width: int | None = None, - terminal_width: int | None = None, -) -> 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 - ) - - 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_lines = textwrap.wrap(summary, target_width) - summary = ("\n" + " " * (name_column_width + 3)).join(summary_lines) - - name_latest = f"{name} ({latest})" - line = f"{name_latest:{name_column_width}} - {summary}" - try: - write_output(line) - dist = get_installed_distribution(name) - print_dist_installation_info(latest, dist) - except UnicodeEncodeError: - pass - - -def highest_version(versions: list[str]) -> str: - return max(versions, key=parse_version) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/commands/show.py b/venv/lib/python3.11/site-packages/pip/_internal/commands/show.py deleted file mode 100755 index 40601a2..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/commands/show.py +++ /dev/null @@ -1,237 +0,0 @@ -from __future__ import annotations - -import logging -import string -from collections.abc import Generator, Iterable, Iterator -from optparse import Values -from typing import NamedTuple - -from pip._vendor.packaging.requirements import InvalidRequirement -from pip._vendor.packaging.utils import canonicalize_name - -from pip._internal.cli.base_command import Command -from pip._internal.cli.status_codes import ERROR, SUCCESS -from pip._internal.metadata import BaseDistribution, get_default_environment -from pip._internal.utils.misc import write_output - -logger = logging.getLogger(__name__) - - -def normalize_project_url_label(label: str) -> str: - # This logic is from PEP 753 (Well-known Project URLs in Metadata). - chars_to_remove = string.punctuation + string.whitespace - removal_map = str.maketrans("", "", chars_to_remove) - return label.translate(removal_map).lower() - - -class ShowCommand(Command): - """ - Show information about one or more installed packages. - - The output is in RFC-compliant mail header format. - """ - - usage = """ - %prog [options] ...""" - ignore_require_venv = True - - def add_options(self) -> None: - 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: Values, args: list[str]) -> int: - if not args: - logger.warning("ERROR: Please provide a package name or names.") - return ERROR - query = args - - results = search_packages_info(query, include_files=options.files) - if not print_results( - results, list_files=options.files, verbose=options.verbose - ): - return ERROR - return SUCCESS - - -class _PackageInfo(NamedTuple): - name: str - version: str - location: str - editable_project_location: str | None - requires: list[str] - required_by: list[str] - installer: str - metadata_version: str - classifiers: list[str] - summary: str - homepage: str - project_urls: list[str] - author: str - author_email: str - license: str - license_expression: str - entry_points: list[str] - files: list[str] | None - - -def search_packages_info( - query: list[str], - include_files: bool, -) -> Generator[_PackageInfo, None, None]: - """ - 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. - """ - env = get_default_environment() - - installed = {dist.canonical_name: dist for dist in env.iter_all_distributions()} - query_names = [canonicalize_name(name) for name in query] - missing = sorted( - [name for name, pkg in zip(query, query_names) if pkg not in installed] - ) - if missing: - logger.warning("Package(s) not found: %s", ", ".join(missing)) - - def _get_requiring_packages(current_dist: BaseDistribution) -> Iterator[str]: - return ( - dist.metadata["Name"] or "UNKNOWN" - for dist in installed.values() - if current_dist.canonical_name - in {canonicalize_name(d.name) for d in dist.iter_dependencies()} - ) - - for query_name in query_names: - try: - dist = installed[query_name] - except KeyError: - continue - - try: - requires = sorted( - # Avoid duplicates in requirements (e.g. due to environment markers). - {req.name for req in dist.iter_dependencies()}, - key=str.lower, - ) - except InvalidRequirement: - requires = sorted(dist.iter_raw_dependencies(), key=str.lower) - - try: - required_by = sorted(_get_requiring_packages(dist), key=str.lower) - except InvalidRequirement: - required_by = ["#N/A"] - - try: - entry_points_text = dist.read_text("entry_points.txt") - entry_points = entry_points_text.splitlines(keepends=False) - except FileNotFoundError: - entry_points = [] - - files: list[str] | None = None - if include_files: - files_iter = dist.iter_declared_entries() - if files_iter is not None: - files = sorted(files_iter) - - metadata = dist.metadata - - project_urls = metadata.get_all("Project-URL", []) - homepage = metadata.get("Home-page", "") - if not homepage: - # It's common that there is a "homepage" Project-URL, but Home-page - # remains unset (especially as PEP 621 doesn't surface the field). - for url in project_urls: - url_label, url = url.split(",", maxsplit=1) - normalized_label = normalize_project_url_label(url_label) - if normalized_label == "homepage": - homepage = url.strip() - break - - yield _PackageInfo( - name=dist.raw_name, - version=dist.raw_version, - location=dist.location or "", - editable_project_location=dist.editable_project_location, - requires=requires, - required_by=required_by, - installer=dist.installer, - metadata_version=dist.metadata_version or "", - classifiers=metadata.get_all("Classifier", []), - summary=metadata.get("Summary", ""), - homepage=homepage, - project_urls=project_urls, - author=metadata.get("Author", ""), - author_email=metadata.get("Author-email", ""), - license=metadata.get("License", ""), - license_expression=metadata.get("License-Expression", ""), - entry_points=entry_points, - files=files, - ) - - -def print_results( - distributions: Iterable[_PackageInfo], - list_files: bool, - verbose: bool, -) -> bool: - """ - Print the information from installed distributions found. - """ - results_printed = False - for i, dist in enumerate(distributions): - results_printed = True - if i > 0: - write_output("---") - - metadata_version = dist.metadata_version - metadata_version_tuple = ( - tuple(map(int, metadata_version.split("."))) if metadata_version else () - ) - - write_output("Name: %s", dist.name) - write_output("Version: %s", dist.version) - write_output("Summary: %s", dist.summary) - write_output("Home-page: %s", dist.homepage) - write_output("Author: %s", dist.author) - write_output("Author-email: %s", dist.author_email) - if metadata_version_tuple >= (2, 4) and dist.license_expression: - write_output("License-Expression: %s", dist.license_expression) - else: - write_output("License: %s", dist.license) - write_output("Location: %s", dist.location) - if dist.editable_project_location is not None: - write_output( - "Editable project location: %s", dist.editable_project_location - ) - write_output("Requires: %s", ", ".join(dist.requires)) - write_output("Required-by: %s", ", ".join(dist.required_by)) - - if verbose: - write_output("Metadata-Version: %s", dist.metadata_version) - write_output("Installer: %s", dist.installer) - write_output("Classifiers:") - for classifier in dist.classifiers: - write_output(" %s", classifier) - write_output("Entry-points:") - for entry in dist.entry_points: - write_output(" %s", entry.strip()) - write_output("Project-URLs:") - for project_url in dist.project_urls: - write_output(" %s", project_url) - if list_files: - write_output("Files:") - if dist.files is None: - write_output("Cannot locate RECORD or installed-files.txt") - else: - for line in dist.files: - write_output(" %s", line.strip()) - return results_printed diff --git a/venv/lib/python3.11/site-packages/pip/_internal/commands/uninstall.py b/venv/lib/python3.11/site-packages/pip/_internal/commands/uninstall.py deleted file mode 100755 index 9c4f031..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/commands/uninstall.py +++ /dev/null @@ -1,113 +0,0 @@ -import logging -from optparse import Values - -from pip._vendor.packaging.utils import canonicalize_name - -from pip._internal.cli import cmdoptions -from pip._internal.cli.base_command import Command -from pip._internal.cli.index_command import SessionCommandMixin -from pip._internal.cli.status_codes import SUCCESS -from pip._internal.exceptions import InstallationError -from pip._internal.req import parse_requirements -from pip._internal.req.constructors import ( - install_req_from_line, - install_req_from_parsed_requirement, -) -from pip._internal.utils.misc import ( - check_externally_managed, - protect_pip_from_modification_on_windows, - warn_if_run_as_root, -) - -logger = logging.getLogger(__name__) - - -class UninstallCommand(Command, SessionCommandMixin): - """ - 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``. - """ - - usage = """ - %prog [options] ... - %prog [options] -r ...""" - - def add_options(self) -> None: - 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.cmd_opts.add_option(cmdoptions.root_user_action()) - self.cmd_opts.add_option(cmdoptions.override_externally_managed()) - self.parser.insert_option_group(0, self.cmd_opts) - - def run(self, options: Values, args: list[str]) -> int: - session = self.get_default_session(options) - - reqs_to_uninstall = {} - for name in args: - req = install_req_from_line( - name, - isolated=options.isolated_mode, - ) - if req.name: - reqs_to_uninstall[canonicalize_name(req.name)] = req - else: - logger.warning( - "Invalid requirement: %r ignored -" - " the uninstall command expects named" - " requirements.", - name, - ) - for filename in options.requirements: - for parsed_req in parse_requirements( - filename, options=options, session=session - ): - req = install_req_from_parsed_requirement( - parsed_req, isolated=options.isolated_mode - ) - if req.name: - reqs_to_uninstall[canonicalize_name(req.name)] = req - if not reqs_to_uninstall: - raise InstallationError( - f"You must give at least one requirement to {self.name} (see " - f'"pip help {self.name}")' - ) - - if not options.override_externally_managed: - check_externally_managed() - - 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() - if options.root_user_action == "warn": - warn_if_run_as_root() - return SUCCESS diff --git a/venv/lib/python3.11/site-packages/pip/_internal/commands/wheel.py b/venv/lib/python3.11/site-packages/pip/_internal/commands/wheel.py deleted file mode 100755 index ee25b82..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/commands/wheel.py +++ /dev/null @@ -1,177 +0,0 @@ -import logging -import os -import shutil -from optparse import Values - -from pip._internal.cache import WheelCache -from pip._internal.cli import cmdoptions -from pip._internal.cli.req_command import RequirementCommand, with_cleanup -from pip._internal.cli.status_codes import SUCCESS -from pip._internal.exceptions import CommandError -from pip._internal.operations.build.build_tracker import get_build_tracker -from pip._internal.req.req_install import ( - InstallRequirement, -) -from pip._internal.utils.misc import ensure_dir, normalize_path -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.wheel_builder import build - -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/ - - 'pip wheel' uses the build system interface as described here: - https://pip.pypa.io/en/stable/reference/build-system/ - - """ - - usage = """ - %prog [options] ... - %prog [options] -r ... - %prog [options] [-e] ... - %prog [options] [-e] ... - %prog [options] ...""" - - def add_options(self) -> None: - self.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." - ), - ) - self.cmd_opts.add_option(cmdoptions.no_build_isolation()) - self.cmd_opts.add_option(cmdoptions.use_pep517()) - self.cmd_opts.add_option(cmdoptions.check_build_deps()) - self.cmd_opts.add_option(cmdoptions.constraints()) - self.cmd_opts.add_option(cmdoptions.build_constraints()) - self.cmd_opts.add_option(cmdoptions.editable()) - self.cmd_opts.add_option(cmdoptions.requirements()) - self.cmd_opts.add_option(cmdoptions.requirements_from_scripts()) - self.cmd_opts.add_option(cmdoptions.src()) - self.cmd_opts.add_option(cmdoptions.ignore_requires_python()) - self.cmd_opts.add_option(cmdoptions.no_deps()) - self.cmd_opts.add_option(cmdoptions.only_deps()) - self.cmd_opts.add_option(cmdoptions.progress_bar()) - - self.cmd_opts.add_option( - "--no-verify", - dest="no_verify", - action="store_true", - default=False, - help="Don't verify if built wheel is valid.", - ) - - self.cmd_opts.add_option(cmdoptions.config_settings()) - - self.cmd_opts.add_option(cmdoptions.require_hashes()) - self.cmd_opts.add_option(cmdoptions.no_require_hashes()) - - index_opts = cmdoptions.make_option_group( - cmdoptions.index_group, - self.parser, - ) - - selection_opts = cmdoptions.make_option_group( - cmdoptions.package_selection_group, - self.parser, - ) - - self.parser.insert_option_group(0, index_opts) - self.parser.insert_option_group(0, selection_opts) - self.parser.insert_option_group(0, self.cmd_opts) - - @with_cleanup - def run(self, options: Values, args: list[str]) -> int: - cmdoptions.check_build_constraints(options) - cmdoptions.check_release_control_exclusive(options) - cmdoptions.check_only_deps_option_does_not_conflict(options) - - session = self.get_default_session(options) - - finder = self._build_package_finder(options, session) - - options.wheel_dir = normalize_path(options.wheel_dir) - ensure_dir(options.wheel_dir) - - build_tracker = self.enter_context(get_build_tracker()) - - directory = TempDirectory( - delete=not options.no_clean, - kind="wheel", - globally_managed=True, - ) - - reqs = self.get_requirements(args, options, finder, session) - - wheel_cache = WheelCache(options.cache_dir) - - preparer = self.make_requirement_preparer( - temp_build_dir=directory, - options=options, - build_tracker=build_tracker, - session=session, - finder=finder, - download_dir=options.wheel_dir, - use_user_site=False, - verbosity=self.verbosity, - allow_editables=False, - ) - - resolver = self.make_resolver( - preparer=preparer, - finder=finder, - options=options, - wheel_cache=wheel_cache, - ignore_requires_python=options.ignore_requires_python, - ) - - self.trace_basic_info(finder) - - requirement_set = resolver.resolve(reqs, check_supported_wheels=True) - - preparer.prepare_linked_requirements_more(requirement_set.requirements.values()) - - reqs_to_build: list[InstallRequirement] = [] - for req in requirement_set.requirements.values(): - if req.is_wheel: - preparer.save_linked_requirement(req) - else: - reqs_to_build.append(req) - - # build wheels - build_successes, build_failures = build( - reqs_to_build, - wheel_cache=wheel_cache, - verify=(not options.no_verify), - allow_editables=False, - ) - for req in build_successes: - assert req.link and req.link.is_wheel - assert req.local_file_path - # copy from cache to target directory - try: - shutil.copy(req.local_file_path, options.wheel_dir) - except OSError as e: - logger.warning( - "Failed to copy built wheel %s to %s: %s", - req.name, - options.wheel_dir, - e, - ) - build_failures.append(req) - if len(build_failures) != 0: - raise CommandError("Failed to build one or more wheels") - - return SUCCESS diff --git a/venv/lib/python3.11/site-packages/pip/_internal/configuration.py b/venv/lib/python3.11/site-packages/pip/_internal/configuration.py deleted file mode 100755 index 661d25e..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/configuration.py +++ /dev/null @@ -1,395 +0,0 @@ -"""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 -""" - -from __future__ import annotations - -import configparser -import os -import sys -from collections.abc import Iterable -from typing import Any, NewType - -from pip._internal.exceptions import ( - ConfigurationError, - ConfigurationFileCouldNotBeLoaded, -) -from pip._internal.utils import appdirs -from pip._internal.utils.compat import WINDOWS, get_locale_encoding -from pip._internal.utils.logging import getLogger -from pip._internal.utils.misc import ensure_dir, enum - -RawConfigParser = configparser.RawConfigParser # Shorthand -Kind = NewType("Kind", str) - -CONFIG_BASENAME = "pip.ini" if WINDOWS else "pip.conf" -ENV_NAMES_IGNORED = "version", "help" - -# The kinds of configurations there are. -kinds = enum( - USER="user", # User Specific - GLOBAL="global", # System Wide - SITE="site", # [Virtual] Environment Specific - ENV="env", # from PIP_CONFIG_FILE - ENV_VAR="env-var", # from Environment Variables -) -OVERRIDE_ORDER = kinds.GLOBAL, kinds.USER, kinds.SITE, kinds.ENV, kinds.ENV_VAR -VALID_LOAD_ONLY = kinds.USER, kinds.GLOBAL, kinds.SITE - -logger = getLogger(__name__) - - -# NOTE: Maybe use the optionx attribute to normalize keynames. -def _normalize_name(name: str) -> str: - """Make a name consistent regardless of source (environment or file)""" - name = name.lower().replace("_", "-") - name = name.removeprefix("--") # only prefer long opts - return name - - -def _disassemble_key(name: str) -> list[str]: - if "." not in name: - error_message = ( - "Key does not contain dot separated section and key. " - f"Perhaps you wanted to use 'global.{name}' instead?" - ) - raise ConfigurationError(error_message) - return name.split(".", 1) - - -def get_configuration_files() -> dict[Kind, list[str]]: - global_config_files = [ - os.path.join(path, CONFIG_BASENAME) for path in appdirs.site_config_dirs("pip") - ] - - site_config_file = os.path.join(sys.prefix, CONFIG_BASENAME) - legacy_config_file = os.path.join( - os.path.expanduser("~"), - "pip" if WINDOWS else ".pip", - CONFIG_BASENAME, - ) - new_config_file = os.path.join(appdirs.user_config_dir("pip"), CONFIG_BASENAME) - return { - kinds.GLOBAL: global_config_files, - kinds.SITE: [site_config_file], - kinds.USER: [legacy_config_file, new_config_file], - } - - -class Configuration: - """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: bool, load_only: Kind | None = None) -> None: - super().__init__() - - if load_only is not None and 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)) - ) - ) - self.isolated = isolated - self.load_only = load_only - - # Because we keep track of where we got the data from - self._parsers: dict[Kind, list[tuple[str, RawConfigParser]]] = { - variant: [] for variant in OVERRIDE_ORDER - } - self._config: dict[Kind, dict[str, dict[str, Any]]] = { - variant: {} for variant in OVERRIDE_ORDER - } - self._modified_parsers: list[tuple[str, RawConfigParser]] = [] - - def load(self) -> 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) -> str | None: - """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) -> Iterable[tuple[str, Any]]: - """Returns key-value pairs like dict.items() representing the loaded - configuration - """ - return self._dictionary.items() - - def get_value(self, key: str) -> Any: - """Get a value from the configuration.""" - orig_key = key - key = _normalize_name(key) - try: - clean_config: dict[str, Any] = {} - for file_values in self._dictionary.values(): - clean_config.update(file_values) - return clean_config[key] - except KeyError: - # disassembling triggers a more useful error message than simply - # "No such key" in the case that the key isn't in the form command.option - _disassemble_key(key) - raise ConfigurationError(f"No such key - {orig_key}") - - def set_value(self, key: str, value: Any) -> None: - """Modify a value in the configuration.""" - key = _normalize_name(key) - self._ensure_have_load_only() - - assert self.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].setdefault(fname, {}) - self._config[self.load_only][fname][key] = value - self._mark_as_modified(fname, parser) - - def unset_value(self, key: str) -> None: - """Unset a value in the configuration.""" - orig_key = key - key = _normalize_name(key) - self._ensure_have_load_only() - - assert self.load_only - fname, parser = self._get_parser_to_modify() - - if ( - key not in self._config[self.load_only][fname] - and key not in self._config[self.load_only] - ): - raise ConfigurationError(f"No such key - {orig_key}") - - if parser is not None: - section, name = _disassemble_key(key) - if not ( - parser.has_section(section) and parser.remove_option(section, name) - ): - # The option was not removed. - raise ConfigurationError( - "Fatal Internal error [id=1]. Please report as a bug." - ) - - # The section may be empty after the option was removed. - if not parser.items(section): - parser.remove_section(section) - self._mark_as_modified(fname, parser) - try: - del self._config[self.load_only][fname][key] - except KeyError: - del self._config[self.load_only][key] - - def save(self) -> None: - """Save the current in-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)) - - # Ensure directory's permission(need to be writeable) - try: - with open(fname, "w") as f: - parser.write(f) - except OSError as error: - raise ConfigurationError( - f"An error occurred while writing to the configuration file " - f"{fname}: {error}" - ) - - # - # Private routines - # - - def _ensure_have_load_only(self) -> 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) -> dict[str, 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 OVERRIDE_ORDER: - retval.update(self._config[variant]) - - return retval - - def _load_config_files(self) -> 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: Kind, fname: str) -> RawConfigParser: - logger.verbose("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].setdefault(fname, {}) - self._config[variant][fname].update(self._normalized_keys(section, items)) - - return parser - - def _construct_parser(self, fname: 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): - locale_encoding = get_locale_encoding() - try: - parser.read(fname, encoding=locale_encoding) - except UnicodeDecodeError: - # See https://github.com/pypa/pip/issues/4963 - raise ConfigurationFileCouldNotBeLoaded( - reason=f"contains invalid {locale_encoding} characters", - 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) -> None: - """Loads configuration from environment variables""" - self._config[kinds.ENV_VAR].setdefault(":env:", {}) - self._config[kinds.ENV_VAR][":env:"].update( - self._normalized_keys(":env:", self.get_environ_vars()) - ) - - def _normalized_keys( - self, section: str, items: 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) -> Iterable[tuple[str, str]]: - """Returns a generator with all environmental vars with prefix PIP_""" - for key, val in os.environ.items(): - if key.startswith("PIP_"): - name = key[4:].lower() - if name not in ENV_NAMES_IGNORED: - yield name, val - - # XXX: This is patched in the tests. - def iter_config_files(self) -> Iterable[tuple[Kind, list[str]]]: - """Yields variant and configuration files associated with it. - - This should be treated like items of a dictionary. The order - here doesn't affect what gets overridden. That is controlled - by OVERRIDE_ORDER. However this does control the order they are - displayed to the user. It's probably most ergonomic to display - things in the same order as OVERRIDE_ORDER - """ - # SMELL: Move the conditions out of this function - - env_config_file = os.environ.get("PIP_CONFIG_FILE", None) - config_files = get_configuration_files() - - yield kinds.GLOBAL, config_files[kinds.GLOBAL] - - # per-user config is not loaded when env_config_file exists - should_load_user_config = not self.isolated and not ( - env_config_file and os.path.exists(env_config_file) - ) - if should_load_user_config: - # The legacy config file is overridden by the new config file - yield kinds.USER, config_files[kinds.USER] - - # virtualenv config - yield kinds.SITE, config_files[kinds.SITE] - - if env_config_file is not None: - yield kinds.ENV, [env_config_file] - else: - yield kinds.ENV, [] - - def get_values_in_config(self, variant: Kind) -> dict[str, Any]: - """Get values present in a config file""" - return self._config[variant] - - def _get_parser_to_modify(self) -> tuple[str, RawConfigParser]: - # Determine which parser to modify - assert self.load_only - parsers = self._parsers[self.load_only] - if not parsers: - # This should not happen if everything works correctly. - 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: str, parser: RawConfigParser) -> None: - file_parser_tuple = (fname, parser) - if file_parser_tuple not in self._modified_parsers: - self._modified_parsers.append(file_parser_tuple) - - def __repr__(self) -> str: - return f"{self.__class__.__name__}({self._dictionary!r})" diff --git a/venv/lib/python3.11/site-packages/pip/_internal/distributions/__init__.py b/venv/lib/python3.11/site-packages/pip/_internal/distributions/__init__.py deleted file mode 100755 index 9a89a83..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/distributions/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -from pip._internal.distributions.base import AbstractDistribution -from pip._internal.distributions.sdist import SourceDistribution -from pip._internal.distributions.wheel import WheelDistribution -from pip._internal.req.req_install import InstallRequirement - - -def make_distribution_for_install_requirement( - install_req: InstallRequirement, -) -> AbstractDistribution: - """Returns a Distribution for the given InstallRequirement""" - # Editable requirements will always be source distributions. They use the - # legacy logic until we create a modern standard for them. - if install_req.editable: - return SourceDistribution(install_req) - - # If it's a wheel, it's a WheelDistribution - if install_req.is_wheel: - return WheelDistribution(install_req) - - # Otherwise, a SourceDistribution - return SourceDistribution(install_req) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-311.pyc deleted file mode 100755 index b0b92bc2b4c1cff1ebcb834ddf6e1cbb45b31ebe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1037 zcmaJ;&1=*^6rbtltM((b_98_|@sur_q4dy8Q41pK!9#lxatYbZba&c(buwG6_Ta%k zL8y4@NfG~Z49%vNrDuMo9agD&( zLH6`7+0@3x(pEDQ+;54;3_NRg1xsRxFYY8=-lEr{3okpAhS!3N&*Dt@VYp2Xx{T9^ z#-f;Ee`6k}2ZhF|=<>LQFN8=3BCBus8o&uUMtd?^Ep7^#y;#TSGu-=jd3Q(FPK~lq ztB){(%=OxvJK6Zn#&*RmvwUk@mbII3OLVB!W`{Jk{#9rzg+T)*{ANhGoKRt~%zGuD zhpTY3F_*+L$=f>jNGFLXiG1El$n&I~tP?*?3A8>WA#0NKNOY2T-C0{B856XT`mKGx zO*4|Rlz1!_l*fKZg0UH8#DfGAp68@Tg&q0()Em!xpa2T0$;c^;M#JZTQAO=3fOn{z zMaJ#EzFZ=#k~4GVbhT$XebdPer_`=e&Y5YQF89nv-)!VY1UM7*%m7|m1Whf>QQg3yL#>7?qomE>%ceC&o%gGCHyPm z^AgX(c5ZA&Nze`H1HJ@DIjQU|Y-J5&JV0Cdqz%xce9{K!VLoXCw3$y@smBDDYj diff --git a/venv/lib/python3.11/site-packages/pip/_internal/distributions/__pycache__/base.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/distributions/__pycache__/base.cpython-311.pyc deleted file mode 100755 index 3a72894b85d7716d41716b410dfcfd78f08e42cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3293 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 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-311.pyc deleted file mode 100755 index 619712f891add113a4908ff9c4d30359c1251b4e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10751 zcmeG?TWlLwb~BtIIh2MXB~cH`mNj}sq)U;Zi>>|)^h{rf+;wy=$1{sUj^%WDzi!a!<(WfXzCHcp?2u?9MKjt`Su2wD>6H;Y9y1@PUYa4n_t8Q zLVfS~qN-)`)`X`CDG{g)pU9|6TgNSAu~<|{`eshMnpVp>`chC-HM4-97Hyxifmb2f z2BGMqK{oa&f!7Zhg-Nk816$9gIE9zTWd1Jy09rn2j!AiCN%r04Q$BfI4#CqePsm|- z3i71f3(tT&CHKR#3!V{pcFWu40eFh?v^)aOpu9sKg=dev4Yp~g*>|zDNV2Z4TYC48 zlrm9NAgn57B$alMWCx+*U0o7fm#!)jbS!5G-5*KSl(KZCL?rDhjFyUuBCAqC(K2#I z%h(N4Ig`B(L{cTKB+V-n(Sib`%xH=nr>~}uDB2<^KJS9Pk(Q-osi9_jfH z5?4zFB~i$bY$-8US}5&LWXk2l4Pe_uJ~y8z-`1{{iu>a;GYK`PDSK=pCCa&SBAo*f zA;nBS;oJl@q2g=2eA^7qqoAabp|1l^=H#WxjoTV;?)NufJn7WS%NABIax1tMM zt-BWL$9E$%qYE=np%X)b09@OEM5Nnr01EDHSZi(rG&L_bFC*!bF%KDlc2ihTv^4#^ zVR*HuMnjx7@-MWm>^qmvVMz5 zuq{AzstFWALf8_rT5`5FB7Uq5XRj*R>uIY^R?4c$&zDMhGXy%MbTh5UISrK^R8uBy zsC^j8Fj%J4+XZy|zf+F|wqI+qF~!&b%bsQS0knM5Y=yp{Q?A2ou#IP794$G=V0qc& zR`WPROR(1X_WtD zyPxy9%(st`8IT!1X>z42S7I!gg5J-ELD@?4DELJ%4N4gvN->*L)R<^VR)4;fk<;bd zWm3APWVN(bD&)<+w57O}2I~UDn}cn24W#CP&BbXoQ_N|%)0F4Uep^BsC_o{qW?yTb zh89)LKvSm7K1*C23RX44X_CpQN*Wx2EBRbjQvtJ8Q^=`muDFn0Y>NS`@X5l$PzXfMv@ z66{?UcT~k44?`94h#?-)#Uu4DsJ(Y?UEEa_cU8pQhPYc7cRv=x>*7>ZoT`N<*V3Pr z>Kqf?{)F)ad!8Yvw}9Ajc=wh%6A0|9jc@;G*cd;mi`#1b+x7k#>#j}i_~?i+d2oI5 zTy^qXEj;mr^GqS;sh)}`t-f-92(1U8V1uu*wQyuTyuBLUu1_ET>|2#^(g-K@aIzK} z#P)r(d1p1e^Wjh>JY$4s^zaN&11U6K6~@;R6=9zt?9=U=D&?$GTVWag*{8pU0%%PZ z^cvN3WJGh=oOWFX`l8vIZtBJ27>xHc#z(cLp4g}hJCAqPcGi#19xbQiT2n`MlyEL- z`oXtF*VW|FMTq$bY85KaB!MMVN@g!Icy3{lfD~H_!0fdgiL`P{$u3gU6XPr~p%Nm& zFcnE?Ge6k{FH74yuy~s?fK^{bJgx0diRbm#*gSPeXlb9sxkiR>ZyC@ z3~?K>P;l#-uNs`zgVSG(AJh+>uZ+(b<8zG;kF8Cgs0tHn2Pk_PlV>Z!IYT(7+qbp( z&CP;|QBBg#zYn!;liAwd70KJPPx%Kt7<2fyE*iN(l;~bBn9}Y^W`^9~$Dm7{2W>RV%c`&v73(O<5wy$s5OUhcLHP@PhZmn9` z=lu3|9A9I+Ul!KH7QR+V+u|srv)8z^F}noc-{uOq=XcY=-G;kzk^aX5N%9h)H2tL; z3dv_~FZEFa=rYb9drba%t|*&+h?mg7ElpfFeL*@nb2xEu=7^*&mdhmq0g*EnQI`(9 zYFR|dLg+N3Qm!a9ZEqZHJPo+EtMR2DT5%e+{*qjR$O|HJNi8c`jCe8)WDO0nTgreR z0a1sPrIEXI1w2{mUtqkZLR?nXz`<1|416Krk#Ght9TW>&3W^%vt{j+daG;A>#nM>F zO#}tfj5IuJ{A@eUQpsLy8gN#Dr((GpWCq)O`O?CILQMb73@M^X=dYD=MUyLJ$|es{ zC^3C1r5R{T>KIUsM;GI7BpC<>D&!yl6@?F!AY9Z5Am4)brPx>N!3LSqh~wvAQtmL1 zN5?;W(-=LX3nR7AxE|VL-Cy*N-j_eTYHZv4Z~M+v`p+8uXLX@*Ki+xx*N3V*XZ4-4 z?@hhG)99Ph`=jTF*dV4cB(pdsoNouKJdpZ^jR0jtKzsmaprg374ecGUed)&weCK2GJ3uc z`+l7Kvt%uN27H0{g(qGPmk*$h;12>5?8o-HhwYtZABTrN5dT8_*~MQ*etF~J!Y|(a z=-tZbVPo`gC49sPA9>>EaWH^-8|a3a=yYlyY}DtG*ogr5D8Qcx`X7Z^fX{<=8tVIy zVz}&zYEdy#BeM&(cQYe{YTapGWY(=5R@{k)rom|$r)AG39zz=@YCt?|4pRo}Yg}$~ zlf{%_2g9&g{Y9p;!3a<+8x0I9xXvSJT;fSCO`cUW4MfwWwP>CP^Apm|tBR5b>BNBF zQVKm#GJDEO85Cd3hfx>jAy~;mGA(Uo+03mN)i-p5nnsmr#S|3d$Cif!StFW~GyM%2 zbvZg_G>tf{VNFbQe8)7xroC5S$?D5g@@wFWzi9-=K=J~|DEMMvuRim7W#A2C;EmNY zwZW11uNs4UR?pV@NA&(_>#p?`X!M?<15ZOrn`j+PjRkC&XwxY+PU@(k6Lns*bDiW8 z&^_CXM&PAsF#qKR29r!Kb7b7<+qc4Dnl@{iNWj><+y-uiFGe82=A3)ep01gi#&eUH zt1Zz+BOLFF4^?to*@hgnEFG+U7Laji?S1gf2CchME7*p=5?+ZrwK;4h8UChX~_2|ph=*yMp zQ6qYEb#8U;addP&dbk=rT#3G9L|%Y5|L z*DKASxkrX>Q$o+PZKRM$6?I;Tn4oVv7T}}Yb}dAqB@EmNOIAjbSYM45R7 zUGv>=s7NkfcBKF@6-FKOzkvdrowJx{S%dP%3nT;f)VeU$*ZIIi=I$~tO8%W{lT^2> z5BV8bP3r`Fh1VQM2JK1wAF(lSaw&BYP6Hc(w=-u?WA=9(LGX%X(~Sn)(mVF6O~#d% zrFUdS&5~RhkFZzb&po>(mz#v@azAEFG1d19#4Q-pT<)Ptj)i!H{VDkS%buSyKjU6! zK44kqUPxx)oWZj+D8XT9u9z(q%5cC7$5_@Hk{>g00P2bFH3Rk;nQZ!QX5f%gb{YKV zfune`d#g;2EgkA4hi!@f_|beRo5`!k;>~e?3u{)-0r)TYgS;cdO(4rp^!$5d`+Mi_ z-vIuOjOyW|aR2og>sjaQKCRxZ5=|BQ~sy6_@ zhlBtAUHI6*U|nFM)9b^#tHZl#7N9n|2cAC<{3Ou&$p4Hb^u5O`u~{QFTlWGvK*lFf z#%U>vrD#vx&qVits}O}q9>8kw4`C)GtpzJRaib@$3vo&+nk{)QpirVDW;>>1AHf=_ zAVTVO4ayrYryy=7hE5T5CT5)pRyf%Nfo}a2#chJ!ZJ%=P))h{}Bkabt%(;7mVDibO z*{?5{8KOvyLnV;GMrkEZ=3xRj)y~0#5-;W_*Rf2aUdl*k@fDfc!BV`%QWzPLJc0rM z6=k=@IQ!tOvq9TmAMp;L6lUSNU zKudJ|c6fzwV;pN~PYFwObgP|rw6|&-D|iJl2pwnbJQo$;Kf!5GhRF{Rw6OAY^GMNM z8#0A-x|k^_>9pCEP8Uk@Vjjz4I{h{r*ECxE>9kzRLbU*SjIu(s+XR!(1T)R#5CYW2 zH0Nl!LDV5af5mcx_F+jzfO%>wL5Y4NL4dhU^?v}|Y5vtcyjOr67yyy+_0&C_7qSXA zc)~&5-8Ze;F4j8X4wEE z!#Lgz4urgkI^zZteyrOBSad;Z#J1o*Tv>$Q3&B1Ru*8sf$4oKm;ZU}e&%>EF{`f4O zna>g)o4Xp>VEEmQm5}ynx8Vm|3&e-5Ly-H9H-B-{_|XiUepy^ev)E|f>4BVyiE>A0 z=K-=BpNC(K5j^BDhuz(jTUmu#Yn7T4bI{#vA8^wj+?dk=F-S=ar=MMd=F;lwx z-q^XuNV@y3^Ip~iX`gQdM20=V>ddV3t}%yn_g!Q5>+ZY8oYCF)V=fGA57=t_tnR)a n2S!$hjKIkKBbC6E5tzE;tNX5cSm3_SP)EIpP0u#zKuP_-md?*{ diff --git a/venv/lib/python3.11/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-311.pyc deleted file mode 100755 index 225745ba5959c446ff519aa6fc71a14273fdc437..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2587 zcmb7F-ER{|5Z|-U_Qk=mLsAN&z!vpGZi!vQOQD|{yGai2!|bjD zwm?Ev9(drf6;hv2Ri#4t2l~Jt;YewVPC|;*r@k4bPds&IFLr$dDs{b{o1NX+otgd3 z>@THKkwE+X`ya3VkR#+z91I(bu^HPvp!W$Q%Vk}XZRn+l@z#z%`m^JmvHd;_?-NdJgAqH!3_HtB zHqFdca}8$JM>=+n?Pd8@)6TOQR)%kZRUj&}@wB#b+=brtFL+yU2?j~(Qf)dNH@#LY zQfOC}JxN)_C53p>kaI@euuDO;?Fwx+b!DP1DFl@^Icy_%OZi>e3EOV#8fP`VRh$=G zbwv2A2+^gtXd?=F%NQ9C@BtotHn#J?Ac`)NheqQe-lr+KzbJ75efDjAISP0^a78Ps zUyPQb6Lq)UuCMTLrS5ypdb_KZqwqxS`0={*6rV#I+$ApSZLeK-yijowx_*7!Sy|Ts zsI|LsrHS|DAP%l^;drcfbXV|d&#&1JhRFhuJ7lXob60HxO9Tp14x(S$!5EnPD zQebcemdI*G%)lqk=?F*+8Kq(tMF+5e3`3QwA-#8Z|P$ZSvdp9@B zZ}+VQ?A3)0YhhFKkIOUnZr;1yx8|`Qp5L(MH#PsHa^!*ev$aX*H!3GLD<|*fo|NBw zz<--N^{aYx^U>{%xl5aKmp00c&2pn}HN-x&eI`i<$Un%go#H0&v53pbj5jQC0+AJ0 zTFbn3%}M4MZ_C(hMv)(vp)5u>9L_xDHle=8rY;dXj|*tNutbPykc+)QsyQ8AaR>#6 zksLwtIuMDQ;H~e3`%qHAcq-DP`1k6&L;jx%Z{ZPm%@Fn}GEur~>c}+U!lytg%0PxZ zCTF#n7>PkjEXBYi=2GO)W}!K)e-wsQE4Cc{R5?yubete!9RQmX?{S>#9oI*^!KmOk zENTH`wMEqCLUqL}xEUftynzHmrOngG6D1rXLAk_=bZ7J%WU@JHK#&wkerk|0aYi=6DI`xZIfPxnE_G%^G7 nf5;wUPQ%R^UmB0ih5n2BAb-$+o7zqK`;R?E@!v0)(--&;dylsM diff --git a/venv/lib/python3.11/site-packages/pip/_internal/distributions/base.py b/venv/lib/python3.11/site-packages/pip/_internal/distributions/base.py deleted file mode 100755 index 66cc542..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/distributions/base.py +++ /dev/null @@ -1,57 +0,0 @@ -from __future__ import annotations - -import abc -from typing import TYPE_CHECKING - -from pip._internal.metadata.base import BaseDistribution -from pip._internal.req import InstallRequirement - -if TYPE_CHECKING: - from pip._internal.build_env import BuildEnvironmentInstaller, BuildIsolationMode - - -class AbstractDistribution(metaclass=abc.ABCMeta): - """A base class for handling installable artifacts. - - 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). - - - 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. - - - if we need to do work in the build tracker, we must be able to generate a unique - string to identify the requirement in the build tracker. - """ - - def __init__(self, req: InstallRequirement) -> None: - super().__init__() - self.req = req - - @property - @abc.abstractmethod - def build_tracker_id(self) -> str | None: - """A string that uniquely identifies this requirement to the build tracker. - - If None, then this dist has no work to do in the build tracker, and - ``.prepare_distribution_metadata()`` will not be called.""" - raise NotImplementedError() - - @abc.abstractmethod - def get_metadata_distribution(self) -> BaseDistribution: - raise NotImplementedError() - - @abc.abstractmethod - def prepare_distribution_metadata( - self, - build_env_installer: BuildEnvironmentInstaller, - build_isolation: BuildIsolationMode, - check_build_deps: bool, - allow_editables: bool, - ) -> None: - raise NotImplementedError() diff --git a/venv/lib/python3.11/site-packages/pip/_internal/distributions/installed.py b/venv/lib/python3.11/site-packages/pip/_internal/distributions/installed.py deleted file mode 100755 index 06cff25..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/distributions/installed.py +++ /dev/null @@ -1,34 +0,0 @@ -from __future__ import annotations - -from typing import TYPE_CHECKING - -from pip._internal.distributions.base import AbstractDistribution -from pip._internal.metadata import BaseDistribution - -if TYPE_CHECKING: - from pip._internal.build_env import BuildEnvironmentInstaller, BuildIsolationMode - - -class InstalledDistribution(AbstractDistribution): - """Represents an installed package. - - This does not need any preparation as the required information has already - been computed. - """ - - @property - def build_tracker_id(self) -> str | None: - return None - - def get_metadata_distribution(self) -> BaseDistribution: - assert self.req.satisfied_by is not None, "not actually installed" - return self.req.satisfied_by - - def prepare_distribution_metadata( - self, - build_env_installer: BuildEnvironmentInstaller, - build_isolation: BuildIsolationMode, - check_build_deps: bool, - allow_editables: bool, - ) -> None: - pass diff --git a/venv/lib/python3.11/site-packages/pip/_internal/distributions/sdist.py b/venv/lib/python3.11/site-packages/pip/_internal/distributions/sdist.py deleted file mode 100755 index fad25db..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/distributions/sdist.py +++ /dev/null @@ -1,193 +0,0 @@ -from __future__ import annotations - -import logging -from collections.abc import Iterable -from contextlib import nullcontext -from typing import TYPE_CHECKING - -from pip._internal.build_env import ( - BuildIsolationMode, - NoOpBuildEnvironment, - VenvBuildEnvironment, - VirtualBuildEnvironment, -) -from pip._internal.distributions.base import AbstractDistribution -from pip._internal.exceptions import InstallationError -from pip._internal.metadata import BaseDistribution -from pip._internal.utils.subprocess import runner_with_spinner_message - -if TYPE_CHECKING: - from pip._internal.build_env import BuildEnvironmentInstaller - -logger = logging.getLogger(__name__) - - -class SourceDistribution(AbstractDistribution): - """Represents a source distribution. - - The preparation step for these needs metadata for the packages to be - generated. - """ - - @property - def build_tracker_id(self) -> str | None: - """Identify this requirement uniquely by its link.""" - assert self.req.link - return self.req.link.url_without_fragment - - def get_metadata_distribution(self) -> BaseDistribution: - return self.req.get_dist() - - def prepare_distribution_metadata( - self, - build_env_installer: BuildEnvironmentInstaller, - build_isolation: BuildIsolationMode, - check_build_deps: bool, - allow_editables: bool, - ) -> None: - # Load pyproject.toml and set up backend environment - self.req.load_pyproject_toml() - self._prepare_build_env(build_isolation, build_env_installer) - - # Set up the build isolation, if this requirement should be isolated - if build_isolation != "off": - # Setup an isolated environment and install the build backend static - # requirements in it. - self._prepare_build_backend(build_isolation) - # Check that the build backend supports PEP 660. This cannot be done - # earlier because we need to setup the build backend to verify it - # supports build_editable, nor can it be done later, because we want - # to avoid installing build requirements needlessly. - self.req.editable_sanity_check() - # Install the dynamic build requirements. - self._install_build_reqs( - build_env_installer, build_isolation, allow_editables=allow_editables - ) - else: - # When not using build isolation, we still need to check that - # the build backend supports PEP 660. - self.req.editable_sanity_check() - # Check if the current environment provides build dependencies - if check_build_deps: - pyproject_requires = self.req.pyproject_requires - assert pyproject_requires is not None - conflicting, missing = self.req.build_env.check_requirements( - pyproject_requires - ) - if conflicting: - self._raise_conflicts("the backend dependencies", conflicting) - if missing: - self._raise_missing_reqs(missing) - self.req.prepare_metadata(allow_editables) - - def _prepare_build_env( - self, - build_isolation: BuildIsolationMode, - build_env_installer: BuildEnvironmentInstaller, - ) -> None: - if build_isolation == "virtual": - self.req.build_env = VirtualBuildEnvironment(build_env_installer) - elif build_isolation == "venv": - self.req.build_env = VenvBuildEnvironment(build_env_installer) - - self.req.configure_backend(self.req.build_env.python_executable) - - def _prepare_build_backend(self, build_isolation: BuildIsolationMode) -> None: - # Install the pyproject.toml declared build-time requirements. - pyproject_requires = self.req.pyproject_requires - assert pyproject_requires is not None - assert not isinstance(self.req.build_env, NoOpBuildEnvironment) - - context = self.req.build_env if build_isolation == "venv" else nullcontext() - with context: - self.req.build_env.install_requirements( - pyproject_requires, - "overlay", - kind="build dependencies", - for_req=self.req, - ) - conflicting, missing = self.req.build_env.check_requirements( - self.req.requirements_to_check - ) - if conflicting: - self._raise_conflicts("PEP 517/518 supported requirements", conflicting) - if missing: - logger.warning( - "Missing build requirements in pyproject.toml for %s.", - self.req, - ) - logger.warning( - "The project does not specify a build backend, and " - "pip cannot fall back to setuptools without %s.", - " and ".join(map(repr, sorted(missing))), - ) - - def _get_build_requires_wheel(self) -> Iterable[str]: - with self.req.build_env: - runner = runner_with_spinner_message("Getting requirements to build wheel") - backend = self.req.pep517_backend - assert backend is not None - with backend.subprocess_runner(runner): - return backend.get_requires_for_build_wheel() - - def _get_build_requires_editable(self) -> Iterable[str]: - with self.req.build_env: - runner = runner_with_spinner_message( - "Getting requirements to build editable" - ) - backend = self.req.pep517_backend - assert backend is not None - with backend.subprocess_runner(runner): - return backend.get_requires_for_build_editable() - - def _install_build_reqs( - self, - build_env_installer: BuildEnvironmentInstaller, - build_isolation: BuildIsolationMode, - allow_editables: bool, - ) -> None: - # Install any extra build dependencies that the backend requests. - # This must be done in a second pass, as the pyproject.toml - # dependencies must be installed before we can call the backend. - if ( - self.req.editable - and allow_editables - and self.req.supports_pyproject_editable - ): - build_reqs = self._get_build_requires_editable() - else: - build_reqs = self._get_build_requires_wheel() - conflicting, missing = self.req.build_env.check_requirements(build_reqs) - if conflicting: - self._raise_conflicts("the backend dependencies", conflicting) - context = self.req.build_env if build_isolation == "venv" else nullcontext() - with context: - self.req.build_env.install_requirements( - missing, "normal", kind="backend dependencies", for_req=self.req - ) - - def _raise_conflicts( - self, conflicting_with: str, conflicting_reqs: set[tuple[str, str]] - ) -> None: - format_string = ( - "Some build dependencies for {requirement} " - "conflict with {conflicting_with}: {description}." - ) - error_message = format_string.format( - requirement=self.req, - conflicting_with=conflicting_with, - description=", ".join( - f"{installed} is incompatible with {wanted}" - for installed, wanted in sorted(conflicting_reqs) - ), - ) - raise InstallationError(error_message) - - def _raise_missing_reqs(self, missing: set[str]) -> None: - format_string = ( - "Some build dependencies for {requirement} are missing: {missing}." - ) - error_message = format_string.format( - requirement=self.req, missing=", ".join(map(repr, sorted(missing))) - ) - raise InstallationError(error_message) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/distributions/wheel.py b/venv/lib/python3.11/site-packages/pip/_internal/distributions/wheel.py deleted file mode 100755 index 8f2a217..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/distributions/wheel.py +++ /dev/null @@ -1,45 +0,0 @@ -from __future__ import annotations - -from typing import TYPE_CHECKING - -from pip._vendor.packaging.utils import canonicalize_name - -from pip._internal.distributions.base import AbstractDistribution -from pip._internal.metadata import ( - BaseDistribution, - FilesystemWheel, - get_wheel_distribution, -) - -if TYPE_CHECKING: - from pip._internal.build_env import BuildEnvironmentInstaller, BuildIsolationMode - - -class WheelDistribution(AbstractDistribution): - """Represents a wheel distribution. - - This does not need any preparation as wheels can be directly unpacked. - """ - - @property - def build_tracker_id(self) -> str | None: - return None - - def get_metadata_distribution(self) -> BaseDistribution: - """Loads the metadata from the wheel file into memory and returns a - Distribution that uses it, not relying on the wheel file or - requirement. - """ - assert self.req.local_file_path, "Set as part of preparation during download" - assert self.req.name, "Wheels are never unnamed" - wheel = FilesystemWheel(self.req.local_file_path) - return get_wheel_distribution(wheel, canonicalize_name(self.req.name)) - - def prepare_distribution_metadata( - self, - build_env_installer: BuildEnvironmentInstaller, - build_isolation: BuildIsolationMode, - check_build_deps: bool, - allow_editables: bool, - ) -> None: - pass diff --git a/venv/lib/python3.11/site-packages/pip/_internal/exceptions.py b/venv/lib/python3.11/site-packages/pip/_internal/exceptions.py deleted file mode 100755 index b2d1e1d..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/exceptions.py +++ /dev/null @@ -1,1145 +0,0 @@ -"""Exceptions used throughout package. - -This module MUST NOT try to import from anything within `pip._internal` to -operate. This is expected to be importable from any/all files within the -subpackage and, thus, should not depend on them. -""" - -from __future__ import annotations - -import configparser -import contextlib -import locale -import logging -import os -import pathlib -import re -import sys -import traceback -from collections.abc import Iterable, Iterator -from itertools import chain, groupby, repeat -from typing import TYPE_CHECKING, Literal - -from pip._vendor.packaging.requirements import InvalidRequirement -from pip._vendor.packaging.version import InvalidVersion -from pip._vendor.rich.console import Console, ConsoleOptions, RenderResult -from pip._vendor.rich.markup import escape -from pip._vendor.rich.text import Text - -if TYPE_CHECKING: - from hashlib import _Hash - - from pip._vendor import urllib3 - from pip._vendor.requests.models import PreparedRequest, Request, Response - - from pip._internal.metadata import BaseDistribution - from pip._internal.models.link import Link - from pip._internal.network.download import _FileDownload - from pip._internal.req.req_install import InstallRequirement - -logger = logging.getLogger(__name__) - - -# -# Scaffolding -# -def _is_kebab_case(s: str) -> bool: - return re.match(r"^[a-z]+(-[a-z]+)*$", s) is not None - - -def _prefix_with_indent( - s: Text | str, - console: Console, - *, - prefix: str, - indent: str, -) -> Text: - if isinstance(s, Text): - text = s - else: - text = console.render_str(s) - - return console.render_str(prefix, overflow="ignore") + console.render_str( - f"\n{indent}", overflow="ignore" - ).join(text.split(allow_blank=True)) - - -class PipError(Exception): - """The base pip error.""" - - -class DiagnosticPipError(PipError): - """An error, that presents diagnostic information to the user. - - This contains a bunch of logic, to enable pretty presentation of our error - messages. Each error gets a unique reference. Each error can also include - additional context, a hint and/or a note -- which are presented with the - main error message in a consistent style. - - This is adapted from the error output styling in `sphinx-theme-builder`. - """ - - reference: str - - def __init__( - self, - *, - kind: Literal["error", "warning"] = "error", - reference: str | None = None, - message: str | Text, - context: str | Text | None, - hint_stmt: str | Text | None, - note_stmt: str | Text | None = None, - link: str | None = None, - ) -> None: - # Ensure a proper reference is provided. - if reference is None: - assert hasattr(self, "reference"), "error reference not provided!" - reference = self.reference - assert _is_kebab_case(reference), "error reference must be kebab-case!" - - self.kind = kind - self.reference = reference - - self.message = message - self.context = context - - self.note_stmt = note_stmt - self.hint_stmt = hint_stmt - - self.link = link - - super().__init__(f"<{self.__class__.__name__}: {self.reference}>") - - def __repr__(self) -> str: - return ( - f"<{self.__class__.__name__}(" - f"reference={self.reference!r}, " - f"message={self.message!r}, " - f"context={self.context!r}, " - f"note_stmt={self.note_stmt!r}, " - f"hint_stmt={self.hint_stmt!r}" - ")>" - ) - - def __rich_console__( - self, - console: Console, - options: ConsoleOptions, - ) -> RenderResult: - colour = "red" if self.kind == "error" else "yellow" - - yield f"[{colour} bold]{self.kind}[/]: [bold]{self.reference}[/]" - yield "" - - if not options.ascii_only: - # Present the main message, with relevant context indented. - if self.context is not None: - yield _prefix_with_indent( - self.message, - console, - prefix=f"[{colour}]×[/] ", - indent=f"[{colour}]│[/] ", - ) - yield _prefix_with_indent( - self.context, - console, - prefix=f"[{colour}]╰─>[/] ", - indent=f"[{colour}] [/] ", - ) - else: - yield _prefix_with_indent( - self.message, - console, - prefix="[red]×[/] ", - indent=" ", - ) - else: - yield self.message - if self.context is not None: - yield "" - yield self.context - - if self.note_stmt is not None or self.hint_stmt is not None: - yield "" - - if self.note_stmt is not None: - yield _prefix_with_indent( - self.note_stmt, - console, - prefix="[magenta bold]note[/]: ", - indent=" ", - ) - if self.hint_stmt is not None: - yield _prefix_with_indent( - self.hint_stmt, - console, - prefix="[cyan bold]hint[/]: ", - indent=" ", - ) - - if self.link is not None: - yield "" - yield f"Link: {self.link}" - - -# -# Actual Errors -# -class ConfigurationError(PipError): - """General exception in configuration""" - - -class InstallationError(PipError): - """General exception during installation""" - - -class FailedToPrepareCandidate(InstallationError): - """Raised when we fail to prepare a candidate (i.e. fetch and generate metadata). - - This is intentionally not a diagnostic error, since the output will be presented - above this error, when this occurs. This should instead present information to the - user. - """ - - def __init__( - self, *, package_name: str, requirement_chain: str, failed_step: str - ) -> None: - super().__init__(f"Failed to build '{package_name}' when {failed_step.lower()}") - self.package_name = package_name - self.requirement_chain = requirement_chain - self.failed_step = failed_step - - -class MissingPyProjectBuildRequires(DiagnosticPipError): - """Raised when pyproject.toml has `build-system`, but no `build-system.requires`.""" - - reference = "missing-pyproject-build-system-requires" - - def __init__(self, *, package: str) -> None: - super().__init__( - message=f"Can not process {escape(package)}", - context=Text( - "This package has an invalid pyproject.toml file.\n" - "The [build-system] table is missing the mandatory `requires` key." - ), - note_stmt="This is an issue with the package mentioned above, not pip.", - hint_stmt=Text("See PEP 518 for the detailed specification."), - ) - - -class InvalidPyProjectBuildRequires(DiagnosticPipError): - """Raised when pyproject.toml an invalid `build-system.requires`.""" - - reference = "invalid-pyproject-build-system-requires" - - def __init__(self, *, package: str, reason: str) -> None: - super().__init__( - message=f"Can not process {escape(package)}", - context=Text( - "This package has an invalid `build-system.requires` key in " - f"pyproject.toml.\n{reason}" - ), - note_stmt="This is an issue with the package mentioned above, not pip.", - hint_stmt=Text("See PEP 518 for the detailed specification."), - ) - - -class NoneMetadataError(PipError): - """Raised when accessing a Distribution's "METADATA" or "PKG-INFO". - - This signifies an inconsistency, when the Distribution claims to have - the metadata file (if not, raise ``FileNotFoundError`` instead), but is - not actually able to produce its content. This may be due to permission - errors. - """ - - def __init__( - self, - dist: BaseDistribution, - metadata_name: str, - ) -> None: - """ - :param dist: A Distribution object. - :param metadata_name: The name of the metadata being accessed - (can be "METADATA" or "PKG-INFO"). - """ - self.dist = dist - self.metadata_name = metadata_name - - def __str__(self) -> str: - # Use `dist` in the error message because its stringification - # includes more information, like the version and location. - return f"None {self.metadata_name} metadata found for distribution: {self.dist}" - - -class UserInstallationInvalid(InstallationError): - """A --user install is requested on an environment without user site.""" - - def __str__(self) -> str: - return "User base directory is not specified" - - -class InvalidSchemeCombination(InstallationError): - def __str__(self) -> str: - before = ", ".join(str(a) for a in self.args[:-1]) - return f"Cannot set {before} and {self.args[-1]} together" - - -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 NetworkConnectionError(PipError): - """HTTP connection error""" - - def __init__( - self, - error_msg: str, - response: Response | None = None, - request: Request | PreparedRequest | None = None, - ) -> None: - """ - Initialize NetworkConnectionError with `request` and `response` - objects. - """ - self.response = response - self.request = request - self.error_msg = error_msg - if ( - self.response is not None - and not self.request - and hasattr(response, "request") - ): - self.request = self.response.request - super().__init__(error_msg, response, request) - - def __str__(self) -> str: - return str(self.error_msg) - - -class ConnectionFailedError(DiagnosticPipError): - reference = "connection-failed" - - def __init__(self, url: str, host: str, error: Exception) -> None: - from http.client import RemoteDisconnected - - from pip._vendor.urllib3.exceptions import ( - NameResolutionError, - NewConnectionError, - ProtocolError, - ) - - details = str(error) - if isinstance(error, NameResolutionError): - parts = details.split("Failed to resolve ", maxsplit=1) - if len(parts) == 2: - details = "Failed to resolve IP address for " + parts[1] - elif isinstance(error, NewConnectionError): - parts = details.split("Failed to establish a new connection: ", maxsplit=1) - if len(parts) == 2: - _, details = parts - elif isinstance(error, ProtocolError): - try: - reason = error.args[1] - except IndexError: - pass - else: - if isinstance(reason, (RemoteDisconnected, ConnectionResetError)): - details = ( - "the connection was closed without a reply from the server." - ) - - super().__init__( - message=( - f"Failed to connect to [magenta]{escape(host)}[/] while fetching " - f"{escape(url)}" - ), - context=Text(details), - hint_stmt=( - "Are you connected to the Internet? If so, check whether your system " - f"can connect to [magenta]{escape(host)}[/] before trying again. " - "There may be a firewall or proxy that's preventing the connection." - ), - ) - - -class ConnectionTimeoutError(DiagnosticPipError): - reference = "connection-timeout" - - def __init__( - self, - url: str, - host: str, - *, - kind: Literal["connect", "read"], - timeout: float, - ) -> None: - context = Text.assemble( - (host, "magenta"), f" didn't respond within {timeout} seconds" - ) - if kind == "connect": - context.append(" (while establishing a connection)") - super().__init__( - message=f"Unable to fetch {escape(url)}", - context=context, - hint_stmt=( - "This is probably a temporary issue with the remote server or the " - "network connection. If this error persists, check the network " - "configuration. There may be a firewall or proxy that's preventing " - "the connection." - ), - ) - - -class SSLMissingError(DiagnosticPipError): - reference = "ssl-missing" - - def __init__(self, url: str) -> None: - super().__init__( - message=f"Failed to establish a secure connection for {escape(url)}", - context="The 'ssl' module is unavailable but required for HTTPS URLs", - hint_stmt=None, - ) - - -class SSLVerificationError(DiagnosticPipError): - reference = "ssl-verification-failed" - - def __init__(self, url: str, host: str, error: urllib3.exceptions.SSLError) -> None: - message = ( - "Failed to establish a secure connection to " - f"[magenta]{escape(host)}[/] while fetching {escape(url)}" - ) - hint = "You may need to use --cert or check your proxy/firewall configuration" - super().__init__(message=message, context=Text(str(error)), hint_stmt=hint) - - -class ProxyConnectionError(DiagnosticPipError): - reference = "proxy-connection-failed" - - def __init__( - self, url: str, proxy: str, error: urllib3.exceptions.ProxyError - ) -> None: - super().__init__( - message=( - "Failed to connect to proxy " - f"[magenta]{escape(proxy)}[/] while fetching {escape(url)}" - ), - context=Text(str(error)), - hint_stmt="This is likely a proxy configuration issue.", - ) - - -class InvalidWheelFilename(InstallationError): - """Invalid wheel filename.""" - - -class UnsupportedWheel(InstallationError): - """Unsupported wheel.""" - - -class InvalidWheel(InstallationError): - """Invalid (e.g. corrupt) wheel.""" - - def __init__(self, location: str, name: str): - self.location = location - self.name = name - - def __str__(self) -> str: - return f"Wheel '{self.name}' located at {self.location} is invalid." - - -class MetadataInconsistent(InstallationError): - """Built metadata contains inconsistent information. - - This is raised when the metadata contains values (e.g. name and version) - that do not match the information previously obtained from sdist filename, - user-supplied ``#egg=`` value, or an install requirement name. - """ - - def __init__( - self, ireq: InstallRequirement, field: str, f_val: str, m_val: str - ) -> None: - self.ireq = ireq - self.field = field - self.f_val = f_val - self.m_val = m_val - - def __str__(self) -> str: - return ( - f"Requested {self.ireq} has inconsistent {self.field}: " - f"expected {self.f_val!r}, but metadata has {self.m_val!r}" - ) - - -class SidecarMetadataInconsistent(MetadataInconsistent): - """The wheel's METADATA disagrees with its PEP 658 ``.metadata`` file. - - Raised after the wheel has been downloaded and hash-verified, when a - resolver-affecting field in the wheel's embedded ``METADATA`` does not - match the value taken from the remote ``.metadata`` sidecar that drove - resolution. ``f_val`` is the sidecar value, ``m_val`` is the wheel value. - """ - - def __str__(self) -> str: - return ( - f"Requested {self.ireq} has inconsistent {self.field} between " - f"its PEP 658 .metadata file and the wheel's METADATA: " - f"sidecar has {self.f_val!r}, wheel has {self.m_val!r}" - ) - - -class MetadataInvalid(InstallationError): - """Metadata is invalid.""" - - def __init__(self, ireq: InstallRequirement, error: str) -> None: - self.ireq = ireq - self.error = error - - def __str__(self) -> str: - return f"Requested {self.ireq} has invalid metadata: {self.error}" - - -class InstallationSubprocessError(DiagnosticPipError, InstallationError): - """A subprocess call failed.""" - - reference = "subprocess-exited-with-error" - - def __init__( - self, - *, - command_description: str, - exit_code: int, - output_lines: list[str] | None, - ) -> None: - if output_lines is None: - output_prompt = Text("No available output.") - else: - output_prompt = ( - Text.from_markup(f"[red][{len(output_lines)} lines of output][/]\n") - + Text("".join(output_lines)) - + Text.from_markup(R"[red]\[end of output][/]") - ) - - super().__init__( - message=( - f"[green]{escape(command_description)}[/] did not run successfully.\n" - f"exit code: {exit_code}" - ), - context=output_prompt, - hint_stmt=None, - note_stmt=( - "This error originates from a subprocess, and is likely not a " - "problem with pip." - ), - ) - - self.command_description = command_description - self.exit_code = exit_code - - def __str__(self) -> str: - return f"{self.command_description} exited with {self.exit_code}" - - -class MetadataGenerationFailed(DiagnosticPipError, InstallationError): - reference = "metadata-generation-failed" - - def __init__( - self, - *, - package_details: str, - ) -> None: - super().__init__( - message="Encountered error while generating package metadata.", - context=escape(package_details), - hint_stmt="See above for details.", - note_stmt="This is an issue with the package mentioned above, not pip.", - ) - - def __str__(self) -> str: - return "metadata generation failed" - - -class HashErrors(InstallationError): - """Multiple HashError instances rolled into one for reporting""" - - def __init__(self) -> None: - self.errors: list[HashError] = [] - - def append(self, error: HashError) -> None: - self.errors.append(error) - - def __str__(self) -> str: - 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) - return "" - - def __bool__(self) -> bool: - return bool(self.errors) - - -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: InstallRequirement | None = None - head = "" - order: int = -1 - - def body(self) -> str: - """Return a summary of me for display under the heading. - - This default implementation simply prints a description of the - triggering requirement. - - :param req: The InstallRequirement that provoked this error, with - its link already populated by the resolver's _populate_link(). - - """ - return f" {self._requirement_name()}" - - def __str__(self) -> str: - return f"{self.head}\n{self.body()}" - - def _requirement_name(self) -> str: - """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: str) -> None: - """ - :param gotten_hash: The hash of the (possibly malicious) archive we - just downloaded - """ - self.gotten_hash = gotten_hash - - def body(self) -> str: - # 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.is_direct - # In case someone feeds something downright stupid - # to InstallRequirement's constructor. - else getattr(self.req, "req", None) - ) - return " {} --hash={}:{}".format( - 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: dict[str, list[str]], gots: dict[str, _Hash]) -> None: - """ - :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) -> str: - return f" {self._requirement_name()}:\n{self._hash_comparison()}" - - def _hash_comparison(self) -> str: - """ - Return a comparison of actual and expected hash values. - - Example:: - - Expected sha256 abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde - or 123451234512345123451234512345123451234512345 - Got bcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdef - - """ - - def hash_then_or(hash_name: str) -> chain[str]: - # For now, all the decent hashes have 6-char names, so we can get - # away with hard-coding space literals. - return chain([hash_name], repeat(" or")) - - lines: list[str] = [] - for hash_name, expecteds in self.allowed.items(): - prefix = hash_then_or(hash_name) - lines.extend((f" Expected {next(prefix)} {e}") for e in expecteds) - lines.append( - f" Got {self.gots[hash_name].hexdigest()}\n" - ) - 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: str = "could not be loaded", - fname: str | None = None, - error: configparser.Error | None = None, - ) -> None: - super().__init__(error) - self.reason = reason - self.fname = fname - self.error = error - - def __str__(self) -> str: - if self.fname is not None: - message_part = f" in {self.fname}." - else: - assert self.error is not None - message_part = f".\n{self.error}\n" - return f"Configuration file {self.reason}{message_part}" - - -_DEFAULT_EXTERNALLY_MANAGED_ERROR = f"""\ -The Python environment under {sys.prefix} is managed externally, and may not be -manipulated by the user. Please use specific tooling from the distributor of -the Python installation to interact with this environment instead. -""" - - -class ExternallyManagedEnvironment(DiagnosticPipError): - """The current environment is externally managed. - - This is raised when the current environment is externally managed, as - defined by `PEP 668`_. The ``EXTERNALLY-MANAGED`` configuration is checked - and displayed when the error is bubbled up to the user. - - :param error: The error message read from ``EXTERNALLY-MANAGED``. - """ - - reference = "externally-managed-environment" - - def __init__(self, error: str | None) -> None: - if error is None: - context = Text(_DEFAULT_EXTERNALLY_MANAGED_ERROR) - else: - context = Text(error) - super().__init__( - message="This environment is externally managed", - context=context, - note_stmt=( - "If you believe this is a mistake, please contact your " - "Python installation or OS distribution provider. " - "You can override this, at the risk of breaking your Python " - "installation or OS, by passing --break-system-packages." - ), - hint_stmt=Text("See PEP 668 for the detailed specification."), - ) - - @staticmethod - def _iter_externally_managed_error_keys() -> Iterator[str]: - # LC_MESSAGES is in POSIX, but not the C standard. The most common - # platform that does not implement this category is Windows, where - # using other categories for console message localization is equally - # unreliable, so we fall back to the locale-less vendor message. This - # can always be re-evaluated when a vendor proposes a new alternative. - try: - category = locale.LC_MESSAGES - except AttributeError: - lang: str | None = None - else: - lang, _ = locale.getlocale(category) - if lang is not None: - yield f"Error-{lang}" - for sep in ("-", "_"): - before, found, _ = lang.partition(sep) - if not found: - continue - yield f"Error-{before}" - yield "Error" - - @classmethod - def from_config( - cls, - config: pathlib.Path | str, - ) -> ExternallyManagedEnvironment: - parser = configparser.ConfigParser(interpolation=None) - try: - parser.read(config, encoding="utf-8") - section = parser["externally-managed"] - for key in cls._iter_externally_managed_error_keys(): - with contextlib.suppress(KeyError): - return cls(section[key]) - except KeyError: - pass - except (OSError, UnicodeDecodeError, configparser.ParsingError): - from pip._internal.utils._log import VERBOSE - - exc_info = logger.isEnabledFor(VERBOSE) - logger.warning("Failed to read %s", config, exc_info=exc_info) - return cls(None) - - -class UninstallMissingRecord(DiagnosticPipError): - reference = "uninstall-no-record-file" - - def __init__(self, *, distribution: BaseDistribution) -> None: - installer = distribution.installer - if not installer or installer == "pip": - dep = f"{distribution.raw_name}=={distribution.version}" - hint = Text.assemble( - "You might be able to recover from this via: ", - (f"pip install --ignore-installed --no-deps {dep}", "green"), - ) - else: - hint = Text( - f"The package was installed by {installer}. " - "You should check if it can uninstall the package." - ) - - super().__init__( - message=Text(f"Cannot uninstall {distribution}"), - context=( - "The package's contents are unknown: " - f"no RECORD file was found for {distribution.raw_name}." - ), - hint_stmt=hint, - ) - - -class LegacyDistutilsInstall(DiagnosticPipError): - reference = "uninstall-distutils-installed-package" - - def __init__(self, *, distribution: BaseDistribution) -> None: - super().__init__( - message=Text(f"Cannot uninstall {distribution}"), - context=( - "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." - ), - hint_stmt=None, - ) - - -class InvalidInstalledPackage(DiagnosticPipError): - reference = "invalid-installed-package" - - def __init__( - self, - *, - dist: BaseDistribution, - invalid_exc: InvalidRequirement | InvalidVersion, - ) -> None: - installed_location = dist.installed_location - - if isinstance(invalid_exc, InvalidRequirement): - invalid_type = "requirement" - else: - invalid_type = "version" - - super().__init__( - message=Text( - f"Cannot process installed package {dist} " - + (f"in {installed_location!r} " if installed_location else "") - + f"because it has an invalid {invalid_type}:\n{invalid_exc.args[0]}" - ), - context=( - "Starting with pip 24.1, packages with invalid " - f"{invalid_type}s can not be processed." - ), - hint_stmt="To proceed this package must be uninstalled.", - ) - - -class IncompleteDownloadError(DiagnosticPipError): - """Raised when the downloader receives fewer bytes than advertised - in the Content-Length header.""" - - reference = "incomplete-download" - - def __init__(self, download: _FileDownload) -> None: - # Dodge circular import. - from pip._internal.utils.misc import format_size - - assert download.size is not None - download_status = ( - f"{format_size(download.bytes_received)}/{format_size(download.size)}" - ) - if download.reattempts: - retry_status = f"after {download.reattempts + 1} attempts " - hint = "Use --resume-retries to configure resume attempt limit." - else: - # Download retrying is not enabled. - retry_status = "" - hint = "Consider using --resume-retries to enable download resumption." - message = Text( - f"Download failed {retry_status}because not enough bytes " - f"were received ({download_status})" - ) - - super().__init__( - message=message, - context=f"URL: {download.link.redacted_url}", - hint_stmt=hint, - note_stmt="This is an issue with network connectivity, not pip.", - ) - - -class ResolutionTooDeepError(DiagnosticPipError): - """Raised when the dependency resolver exceeds the maximum recursion depth.""" - - reference = "resolution-too-deep" - - def __init__(self) -> None: - super().__init__( - message="Dependency resolution exceeded maximum depth", - context=( - "Pip cannot resolve the current dependencies as the dependency graph " - "is too complex for pip to solve efficiently." - ), - hint_stmt=( - "Try adding lower bounds to constrain your dependencies, " - "for example: 'package>=2.0.0' instead of just 'package'. " - ), - link="https://pip.pypa.io/en/stable/topics/dependency-resolution/#handling-resolution-too-deep-errors", - ) - - -class InstallWheelBuildError(DiagnosticPipError): - reference = "failed-wheel-build-for-install" - - def __init__(self, failed: list[InstallRequirement]) -> None: - super().__init__( - message=( - "Failed to build installable wheels for some " - "pyproject.toml based projects" - ), - context=", ".join(r.name for r in failed), # type: ignore - hint_stmt=None, - ) - - -class InvalidEggFragment(DiagnosticPipError): - reference = "invalid-egg-fragment" - - def __init__(self, link: Link, fragment: str) -> None: - hint = "" - if ">" in fragment or "=" in fragment or "<" in fragment: - hint = ( - "Version specifiers are silently ignored for URL references. " - "Remove them. " - ) - if "[" in fragment and "]" in fragment: - hint += "Try using the Direct URL requirement syntax: 'name[extra] @ URL'" - - if not hint: - hint = "Egg fragments can only be a valid project name." - - super().__init__( - message=f"The '{escape(fragment)}' egg fragment is invalid", - context=f"from '{escape(str(link))}'", - hint_stmt=escape(hint), - ) - - -class BuildDependencyInstallError(DiagnosticPipError): - """Raised when build dependencies cannot be installed.""" - - reference = "failed-build-dependency-install" - - def __init__( - self, - req: InstallRequirement | None, - build_reqs: Iterable[str], - *, - cause: Exception, - log_lines: list[str] | None, - ) -> None: - if isinstance(cause, PipError): - note = "This is likely not a problem with pip." - else: - note = ( - "pip crashed unexpectedly. Please file an issue on pip's issue " - "tracker: https://github.com/pypa/pip/issues/new" - ) - - if log_lines is None: - # No logs are available, they must have been printed earlier. - context = Text("See above for more details.") - else: - if isinstance(cause, PipError): - log_lines.append(f"ERROR: {cause}") - else: - # Split rendered error into real lines without trailing newlines. - log_lines.extend( - "".join(traceback.format_exception(cause)).splitlines() - ) - - context = Text.assemble( - f"Installing {' '.join(build_reqs)}\n", - (f"[{len(log_lines)} lines of output]\n", "red"), - "\n".join(log_lines), - ("\n[end of output]", "red"), - ) - - message = Text("Cannot install build dependencies", "green") - if req: - message += Text(f" for {req}") - super().__init__( - message=message, context=context, hint_stmt=None, note_stmt=note - ) - - -class VenvImportError(DiagnosticPipError): - """Raised when 'venv' can't be imported.""" - - reference = "venv-import-error" - - def __init__(self) -> None: - if sys.platform != "linux": - hint_stmt = None - else: - hint_stmt = ( - "If this is an OS-provided Python, it's likely that your OS " - "package maintainers have split Python's standard library across " - "multiple OS packages." - ) - super().__init__( - message="Cannot import the 'venv' module of the Python standard library", - context=( - "This is a symptom of a broken/modified Python, which cannot be used " - "with pip." - ), - note_stmt="This is an issue with the Python installation itself, not pip.", - hint_stmt=hint_stmt, - ) - - -class VenvCreationError(DiagnosticPipError): - """Raised when a virtual environment can't be created.""" - - reference = "venv-creation-error" - - def __init__(self, context: str) -> None: - if os.name == "nt": - hint = "This may be caused by running antivirus software." - else: - hint = None - super().__init__( - message="Cannot create a virtual environment", - context=Text(context), - hint_stmt=hint, - ) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/index/__init__.py b/venv/lib/python3.11/site-packages/pip/_internal/index/__init__.py deleted file mode 100755 index 197dd75..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/index/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Index interaction code""" diff --git a/venv/lib/python3.11/site-packages/pip/_internal/index/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/index/__pycache__/__init__.cpython-311.pyc deleted file mode 100755 index 4901a07d14f6d6a3c7c3e2a6cbdb5da9deed2ea4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 232 zcmZ3^%ge<81lOj_%8~`rk3k$5V1zP0gOp5XNMVR#NMQ_S&}6C-^UO<0tx(9!D@iR% zOfJdH&r?XwPf7LDWW2>5AD@z+93Q`u;WJ44uW?m%-GapA?8NlcV*P^50{wWf4S9(<`k5dL_2Yp8 unI-Y@dIgogIBatBQ%ZAE?TXld_JG`4EC?h%Ff%eT-e8cq07FGAKv4kor$Jx< diff --git a/venv/lib/python3.11/site-packages/pip/_internal/index/__pycache__/collector.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/index/__pycache__/collector.cpython-311.pyc deleted file mode 100755 index 15461ccf1564631664402c1572ca13f72b4ffccd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24632 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 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/index/__pycache__/package_finder.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/index/__pycache__/package_finder.cpython-311.pyc deleted file mode 100755 index 26751d5dc2903d833cdaaf726dd259dbf480e508..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47829 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 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/index/__pycache__/sources.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/index/__pycache__/sources.cpython-311.pyc deleted file mode 100755 index 3b6233357f57d372e91955513aae1439eacfa870..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13589 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 HDqsE=RXpJT diff --git a/venv/lib/python3.11/site-packages/pip/_internal/index/collector.py b/venv/lib/python3.11/site-packages/pip/_internal/index/collector.py deleted file mode 100755 index a77c398..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/index/collector.py +++ /dev/null @@ -1,510 +0,0 @@ -""" -The main purpose of this module is to expose LinkCollector.collect_sources(). -""" - -from __future__ import annotations - -import collections -import email.message -import functools -import itertools -import json -import logging -import os -import urllib.parse -from collections.abc import Callable, Iterable, MutableMapping, Sequence -from dataclasses import dataclass -from html.parser import HTMLParser -from optparse import Values -from typing import ( - NamedTuple, - Protocol, -) - -from pip._vendor.packaging.utils import canonicalize_name -from pip._vendor.requests import Response -from pip._vendor.requests.exceptions import RetryError - -from pip._internal.exceptions import ( - ConnectionFailedError, - ConnectionTimeoutError, - NetworkConnectionError, - ProxyConnectionError, - SSLMissingError, - SSLVerificationError, -) -from pip._internal.models.link import Link -from pip._internal.models.search_scope import SearchScope -from pip._internal.network.session import PipSession -from pip._internal.network.utils import raise_for_status -from pip._internal.utils.filetypes import is_archive_file -from pip._internal.utils.misc import redact_auth_from_url -from pip._internal.utils.urls import url_to_path -from pip._internal.vcs import vcs - -from .sources import CandidatesFromPage, LinkSource, build_source - -logger = logging.getLogger(__name__) - -ResponseHeaders = MutableMapping[str, str] - - -def _match_vcs_scheme(url: str) -> str | None: - """Look for VCS schemes in the URL. - - Returns the matched VCS scheme, or None if there's no match. - """ - for scheme in vcs.schemes: - if url.lower().startswith(scheme) and url[len(scheme)] in "+:": - return scheme - return None - - -class _NotAPIContent(Exception): - def __init__(self, content_type: str, request_desc: str) -> None: - super().__init__(content_type, request_desc) - self.content_type = content_type - self.request_desc = request_desc - - -def _ensure_api_header(response: Response) -> None: - """ - Check the Content-Type header to ensure the response contains a Simple - API Response. - - Raises `_NotAPIContent` if the content type is not a valid content-type. - """ - content_type = response.headers.get("Content-Type", "Unknown") - - content_type_l = content_type.lower() - if content_type_l.startswith( - ( - "text/html", - "application/vnd.pypi.simple.v1+html", - "application/vnd.pypi.simple.v1+json", - ) - ): - return - - raise _NotAPIContent(content_type, response.request.method) # type: ignore[arg-type] - - -class _NotHTTP(Exception): - pass - - -def _ensure_api_response(url: str, session: PipSession) -> None: - """ - Send a HEAD request to the URL, and ensure the response contains a simple - API Response. - - Raises `_NotHTTP` if the URL is not available for a HEAD request, or - `_NotAPIContent` if the content type is not a valid content type. - """ - scheme, netloc, path, query, fragment = urllib.parse.urlsplit(url) - if scheme not in {"http", "https"}: - raise _NotHTTP() - - resp = session.head(url, allow_redirects=True) - raise_for_status(resp) - - _ensure_api_header(resp) - - -def _get_simple_response( - url: str, - session: PipSession, - force_revalidate: bool = False, -) -> Response: - """Access an Simple API response with GET, and return the response. - - This consists of three parts: - - 1. If the URL looks suspiciously like an archive, send a HEAD first to - check the Content-Type is HTML or Simple API, to avoid downloading a - large file. Raise `_NotHTTP` if the content type cannot be determined, or - `_NotAPIContent` if it is not HTML or a Simple API. - 2. Actually perform the request. Raise HTTP exceptions on network failures. - 3. Check the Content-Type header to make sure we got a Simple API response, - and raise `_NotAPIContent` otherwise. - """ - if is_archive_file(Link(url).filename): - _ensure_api_response(url, session=session) - - logger.debug("Getting page %s", redact_auth_from_url(url)) - - headers = { - "Accept": ", ".join( - [ - "application/vnd.pypi.simple.v1+json", - "application/vnd.pypi.simple.v1+html; q=0.1", - "text/html; q=0.01", - ] - ), - } - - if force_revalidate: - # Using max-age=0 rather than no-cache still supports conditional - # requests, minimizing traffic when the page hasn't changed. - # See pypa/pip#5670. - logger.debug("Refreshing package index response.") - headers["Cache-Control"] = "max-age=0" - - resp = session.get(url, headers=headers) - raise_for_status(resp) - - # 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 a - # Simple API response or not. However we can check after we've - # downloaded it. - _ensure_api_header(resp) - - logger.debug( - "Fetched page %s as %s", - redact_auth_from_url(url), - resp.headers.get("Content-Type", "Unknown"), - ) - - return resp - - -def _get_encoding_from_headers(headers: ResponseHeaders) -> str | None: - """Determine if we have any encoding information in our headers.""" - if headers and "Content-Type" in headers: - m = email.message.Message() - m["content-type"] = headers["Content-Type"] - charset = m.get_param("charset") - if charset: - return str(charset) - return None - - -class CacheablePageContent: - def __init__(self, page: IndexContent) -> None: - assert page.cache_link_parsing - self.page = page - - def __eq__(self, other: object) -> bool: - return isinstance(other, type(self)) and self.page.url == other.page.url - - def __hash__(self) -> int: - return hash(self.page.url) - - -class ParseLinks(Protocol): - def __call__(self, page: IndexContent) -> Iterable[Link]: ... - - -def with_cached_index_content(fn: ParseLinks) -> ParseLinks: - """ - Given a function that parses an Iterable[Link] from an IndexContent, cache the - function's result (keyed by CacheablePageContent), unless the IndexContent - `page` has `page.cache_link_parsing == False`. - """ - - @functools.cache - def wrapper(cacheable_page: CacheablePageContent) -> list[Link]: - return list(fn(cacheable_page.page)) - - @functools.wraps(fn) - def wrapper_wrapper(page: IndexContent) -> list[Link]: - if page.cache_link_parsing: - return wrapper(CacheablePageContent(page)) - return list(fn(page)) - - return wrapper_wrapper - - -@with_cached_index_content -def parse_links(page: IndexContent) -> Iterable[Link]: - """ - Parse a Simple API's Index Content, and yield its anchor elements as Link objects. - """ - - content_type_l = page.content_type.lower() - if content_type_l.startswith("application/vnd.pypi.simple.v1+json"): - data = json.loads(page.content) - for file in data.get("files", []): - link = Link.from_json(file, page.url) - if link is None: - continue - yield link - return - - parser = HTMLLinkParser(page.url) - encoding = page.encoding or "utf-8" - parser.feed(page.content.decode(encoding)) - - url = page.url - base_url = parser.base_url or url - for anchor in parser.anchors: - link = Link.from_element(anchor, page_url=url, base_url=base_url) - if link is None: - continue - yield link - - -@dataclass(frozen=True) -class IndexContent: - """Represents one response (or page), along with its URL. - - :param encoding: the encoding to decode the given content. - :param url: the URL from which the HTML was downloaded. - :param cache_link_parsing: whether links parsed from this page's url - should be cached. PyPI index urls should - have this set to False, for example. - """ - - content: bytes - content_type: str - encoding: str | None - url: str - cache_link_parsing: bool = True - - def __str__(self) -> str: - return redact_auth_from_url(self.url) - - -class HTMLLinkParser(HTMLParser): - """ - HTMLParser that keeps the first base HREF and a list of all anchor - elements' attributes. - """ - - def __init__(self, url: str) -> None: - super().__init__(convert_charrefs=True) - - self.url: str = url - self.base_url: str | None = None - self.anchors: list[dict[str, str | None]] = [] - - def handle_starttag(self, tag: str, attrs: list[tuple[str, str | None]]) -> None: - if tag == "base" and self.base_url is None: - href = self.get_href(attrs) - if href is not None: - self.base_url = href - elif tag == "a": - self.anchors.append(dict(attrs)) - - def get_href(self, attrs: list[tuple[str, str | None]]) -> str | None: - for name, value in attrs: - if name == "href": - return value - return None - - -def _handle_get_simple_fail( - link: Link, - reason: str | Exception, - meth: Callable[..., None] | None = None, -) -> None: - if meth is None: - meth = logger.debug - meth("Could not fetch URL %s: %s - skipping", link, reason) - - -def _make_index_content( - response: Response, cache_link_parsing: bool = True -) -> IndexContent: - encoding = _get_encoding_from_headers(response.headers) - return IndexContent( - response.content, - response.headers["Content-Type"], - encoding=encoding, - url=response.url, - cache_link_parsing=cache_link_parsing, - ) - - -def _get_index_content( - link: Link, - *, - session: PipSession, - force_revalidate: bool = False, -) -> IndexContent | None: - url = link.url.split("#", 1)[0] - - # Check for VCS schemes that do not support lookup as web pages. - vcs_scheme = _match_vcs_scheme(url) - if vcs_scheme: - logger.warning( - "Cannot look at %s URL %s because it does not support lookup as web pages.", - vcs_scheme, - link, - ) - return None - - # Tack index.html onto file:// URLs that point to directories - if url.startswith("file:") and os.path.isdir(url_to_path(url)): - # add trailing slash if not present so urljoin doesn't trim - # final segment - if not url.endswith("/"): - url += "/" - # TODO: In the future, it would be nice if pip supported PEP 691 - # style responses in the file:// URLs, however there's no - # standard file extension for application/vnd.pypi.simple.v1+json - # so we'll need to come up with something on our own. - url = urllib.parse.urljoin(url, "index.html") - logger.debug(" file: URL is directory, getting %s", url) - - try: - resp = _get_simple_response( - url, session=session, force_revalidate=force_revalidate - ) - except _NotHTTP: - logger.warning( - "Skipping page %s because it looks like an archive, and cannot " - "be checked by a HTTP HEAD request.", - link, - ) - except _NotAPIContent as exc: - logger.warning( - "Skipping page %s because the %s request got Content-Type: %s. " - "The only supported Content-Types are application/vnd.pypi.simple.v1+json, " - "application/vnd.pypi.simple.v1+html, and text/html", - link, - exc.request_desc, - exc.content_type, - ) - except (RetryError, NetworkConnectionError) as exc: - _handle_get_simple_fail(link, exc) - except (SSLVerificationError, SSLMissingError) as exc: - reason = f"There was a problem confirming the ssl certificate: {exc.context}" - _handle_get_simple_fail(link, reason, meth=logger.info) - except ConnectionFailedError as exc: - _handle_get_simple_fail(link, f"connection error: {exc.context}") - except ProxyConnectionError as exc: - _handle_get_simple_fail(link, f"proxy connection error: {exc.context}") - except ConnectionTimeoutError as exc: - _handle_get_simple_fail(link, str(exc.context)) - else: - return _make_index_content(resp, cache_link_parsing=link.cache_link_parsing) - return None - - -class CollectedSources(NamedTuple): - find_links: Sequence[LinkSource | None] - index_urls: Sequence[LinkSource | None] - - -class LinkCollector: - """ - Responsible for collecting Link objects from all configured locations, - making network requests as needed. - - The class's main method is its collect_sources() method. - """ - - def __init__( - self, - session: PipSession, - search_scope: SearchScope, - ) -> None: - self.search_scope = search_scope - self.session = session - - @classmethod - def create( - cls, - session: PipSession, - options: Values, - suppress_no_index: bool = False, - ) -> LinkCollector: - """ - :param session: The Session to use to make requests. - :param suppress_no_index: Whether to ignore the --no-index option - when constructing the SearchScope object. - """ - index_urls = [options.index_url] + options.extra_index_urls - if options.no_index and not suppress_no_index: - logger.debug( - "Ignoring indexes: %s", - ",".join(redact_auth_from_url(url) for url in index_urls), - ) - index_urls = [] - - # Make sure find_links is a list before passing to create(). - find_links = options.find_links or [] - - search_scope = SearchScope.create( - find_links=find_links, - index_urls=index_urls, - no_index=options.no_index, - ) - link_collector = LinkCollector( - session=session, - search_scope=search_scope, - ) - return link_collector - - @property - def find_links(self) -> list[str]: - return self.search_scope.find_links - - def fetch_response( - self, location: Link, package_name: str | None = None - ) -> IndexContent | None: - """ - Fetch an HTML page containing package links. - """ - # By default we may return cached /simple/ responses. Users can force - # revalidation to ensure newly uploaded distributions become visible - # immediately after publication. See pypa/pip#5670. - force_revalidate = self.session.refresh_package - should_force_revalidate = ":all:" in force_revalidate or ( - package_name is not None - and canonicalize_name(package_name) in force_revalidate - ) - return _get_index_content( - location, - session=self.session, - force_revalidate=should_force_revalidate, - ) - - def collect_sources( - self, - project_name: str, - candidates_from_page: CandidatesFromPage, - ) -> CollectedSources: - # The OrderedDict calls deduplicate sources by URL. - index_url_sources = collections.OrderedDict( - build_source( - loc, - candidates_from_page=candidates_from_page, - page_validator=self.session.is_secure_origin, - expand_dir=False, - cache_link_parsing=False, - project_name=project_name, - ) - for loc in self.search_scope.get_index_urls_locations(project_name) - ).values() - find_links_sources = collections.OrderedDict( - build_source( - loc, - candidates_from_page=candidates_from_page, - page_validator=self.session.is_secure_origin, - expand_dir=True, - cache_link_parsing=True, - project_name=project_name, - ) - for loc in self.find_links - ).values() - - if logger.isEnabledFor(logging.DEBUG): - lines = [ - f"* {s.link}" - for s in itertools.chain(find_links_sources, index_url_sources) - if s is not None and s.link is not None - ] - lines = [ - f"{len(lines)} location(s) to search " - f"for versions of {project_name}:" - ] + lines - logger.debug("\n".join(lines)) - - return CollectedSources( - find_links=list(find_links_sources), - index_urls=list(index_url_sources), - ) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/index/package_finder.py b/venv/lib/python3.11/site-packages/pip/_internal/index/package_finder.py deleted file mode 100755 index cf4a2ee..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/index/package_finder.py +++ /dev/null @@ -1,1152 +0,0 @@ -"""Routines related to PyPI, indexes""" - -from __future__ import annotations - -import datetime -import enum -import functools -import itertools -import logging -import re -from collections.abc import Iterable -from dataclasses import dataclass -from typing import ( - TYPE_CHECKING, -) - -from pip._vendor.packaging import specifiers -from pip._vendor.packaging.tags import Tag -from pip._vendor.packaging.utils import NormalizedName, canonicalize_name -from pip._vendor.packaging.version import InvalidVersion, _BaseVersion -from pip._vendor.packaging.version import parse as parse_version - -from pip._internal.exceptions import ( - BestVersionAlreadyInstalled, - DistributionNotFound, - InstallationError, - InvalidWheelFilename, - UnsupportedWheel, -) -from pip._internal.index.collector import LinkCollector, parse_links -from pip._internal.metadata import select_backend -from pip._internal.models.candidate import InstallationCandidate -from pip._internal.models.format_control import FormatControl -from pip._internal.models.link import Link -from pip._internal.models.release_control import ReleaseControl -from pip._internal.models.search_scope import SearchScope -from pip._internal.models.selection_prefs import SelectionPreferences -from pip._internal.models.target_python import TargetPython -from pip._internal.models.wheel import Wheel -from pip._internal.req import InstallRequirement -from pip._internal.utils._log import getLogger -from pip._internal.utils.filetypes import WHEEL_EXTENSION -from pip._internal.utils.hashes import Hashes -from pip._internal.utils.logging import indent_log -from pip._internal.utils.misc import build_netloc -from pip._internal.utils.packaging import check_requires_python -from pip._internal.utils.unpacking import SUPPORTED_EXTENSIONS - -if TYPE_CHECKING: - from typing import TypeGuard - -__all__ = ["FormatControl", "BestCandidateResult", "PackageFinder"] - - -logger = getLogger(__name__) - -BuildTag = tuple[()] | tuple[int, str] -CandidateSortingKey = tuple[int, int, int, _BaseVersion, int | None, BuildTag] - - -def _check_link_requires_python( - link: Link, - version_info: tuple[int, int, int], - ignore_requires_python: bool = False, -) -> bool: - """ - Return whether the given Python version is compatible with a link's - "Requires-Python" value. - - :param version_info: A 3-tuple of ints representing the Python - major-minor-micro version to check. - :param ignore_requires_python: Whether to ignore the "Requires-Python" - value if the given Python version isn't compatible. - """ - try: - is_compatible = check_requires_python( - link.requires_python, - version_info=version_info, - ) - except specifiers.InvalidSpecifier: - logger.debug( - "Ignoring invalid Requires-Python (%r) for link: %s", - link.requires_python, - link, - ) - else: - if not is_compatible: - version = ".".join(map(str, version_info)) - if not ignore_requires_python: - logger.verbose( - "Link requires a different Python (%s not in: %r): %s", - version, - link.requires_python, - link, - ) - return False - - logger.debug( - "Ignoring failed Requires-Python check (%s not in: %r) for link: %s", - version, - link.requires_python, - link, - ) - - return True - - -class LinkType(enum.Enum): - candidate = enum.auto() - different_project = enum.auto() - yanked = enum.auto() - format_unsupported = enum.auto() - format_invalid = enum.auto() - platform_mismatch = enum.auto() - requires_python_mismatch = enum.auto() - upload_too_late = enum.auto() - upload_time_missing = enum.auto() - - -class LinkEvaluator: - """ - Responsible for evaluating links for a particular project. - """ - - _py_version_re = re.compile(r"-py([123]\.?[0-9]?)$") - - # Don't include an allow_yanked default value to make sure each call - # site considers whether yanked releases are allowed. This also causes - # that decision to be made explicit in the calling code, which helps - # people when reading the code. - def __init__( - self, - project_name: str, - canonical_name: NormalizedName, - formats: frozenset[str], - target_python: TargetPython, - allow_yanked: bool, - ignore_requires_python: bool = False, - uploaded_prior_to: datetime.datetime | None = None, - ) -> None: - """ - :param project_name: The user supplied package name. - :param canonical_name: The canonical package name. - :param formats: The formats allowed for this package. Should be a set - with 'binary' or 'source' or both in it. - :param target_python: The target Python interpreter to use when - evaluating link compatibility. This is used, for example, to - check wheel compatibility, as well as when checking the Python - version, e.g. the Python version embedded in a link filename - (or egg fragment) and against an HTML link's optional PEP 503 - "data-requires-python" attribute. - :param allow_yanked: Whether files marked as yanked (in the sense - of PEP 592) are permitted to be candidates for install. - :param ignore_requires_python: Whether to ignore incompatible - PEP 503 "data-requires-python" values in HTML links. Defaults - to False. - :param uploaded_prior_to: If set, only allow links uploaded prior to - the given datetime. - """ - - self._allow_yanked = allow_yanked - self._canonical_name = canonical_name - self._ignore_requires_python = ignore_requires_python - self._formats = formats - self._target_python = target_python - self._uploaded_prior_to = uploaded_prior_to - - self.project_name = project_name - - def evaluate_link(self, link: Link) -> tuple[LinkType, str]: - """ - Determine whether a link is a candidate for installation. - - :return: A tuple (result, detail), where *result* is an enum - representing whether the evaluation found a candidate, or the reason - why one is not found. If a candidate is found, *detail* will be the - candidate's version string; if one is not found, it contains the - reason the link fails to qualify. - """ - version = None - if link.is_yanked and not self._allow_yanked: - reason = link.yanked_reason or "" - return (LinkType.yanked, f"yanked for reason: {reason}") - - if link.egg_fragment: - egg_info = link.egg_fragment - ext = link.ext - else: - egg_info, ext = link.splitext() - if not ext: - return (LinkType.format_unsupported, "not a file") - if ext not in SUPPORTED_EXTENSIONS: - return ( - LinkType.format_unsupported, - f"unsupported archive format: {ext}", - ) - if "binary" not in self._formats and ext == WHEEL_EXTENSION: - reason = f"No binaries permitted for {self.project_name}" - return (LinkType.format_unsupported, reason) - if "macosx10" in link.path and ext == ".zip": - return (LinkType.format_unsupported, "macosx10 one") - if ext == WHEEL_EXTENSION: - try: - wheel = Wheel(link.filename) - except InvalidWheelFilename: - return ( - LinkType.format_invalid, - "invalid wheel filename", - ) - if wheel.name != self._canonical_name: - reason = f"wrong project name (not {self.project_name})" - return (LinkType.different_project, reason) - - supported_tags = self._target_python.get_unsorted_tags() - if not wheel.supported(supported_tags): - # Include the wheel's tags in the reason string to - # simplify troubleshooting compatibility issues. - file_tags = ", ".join(wheel.get_formatted_file_tags()) - reason = ( - f"none of the wheel's tags ({file_tags}) are compatible " - f"(run pip debug --verbose to show compatible tags)" - ) - return (LinkType.platform_mismatch, reason) - - version = wheel.version - - # Check upload-time filter after verifying the link is a package file. - # Skip this check for local files, as --uploaded-prior-to only applies - # to packages from indexes. - if self._uploaded_prior_to is not None and not link.is_file: - if link.upload_time is None: - if link.comes_from: - index_info = f"Index {link.comes_from}" - else: - index_info = "Index" - - return ( - LinkType.upload_time_missing, - f"{index_info} does not provide upload-time metadata.", - ) - elif link.upload_time >= self._uploaded_prior_to: - return ( - LinkType.upload_too_late, - f"Upload time {link.upload_time} not " - f"prior to {self._uploaded_prior_to}", - ) - - # This should be up by the self.ok_binary check, but see issue 2700. - if "source" not in self._formats and ext != WHEEL_EXTENSION: - reason = f"No sources permitted for {self.project_name}" - return (LinkType.format_unsupported, reason) - - if not version: - version = _extract_version_from_fragment( - egg_info, - self._canonical_name, - ) - if not version: - reason = f"Missing project version for {self.project_name}" - return (LinkType.format_invalid, reason) - - match = self._py_version_re.search(version) - if match: - version = version[: match.start()] - py_version = match.group(1) - if py_version != self._target_python.py_version: - return ( - LinkType.platform_mismatch, - "Python version is incorrect", - ) - - supports_python = _check_link_requires_python( - link, - version_info=self._target_python.py_version_info, - ignore_requires_python=self._ignore_requires_python, - ) - if not supports_python: - requires_python = link.requires_python - if requires_python: - - def get_version_sort_key(v: str) -> tuple[int, ...]: - return tuple(int(s) for s in v.split(".") if s.isdigit()) - - requires_python = ",".join( - sorted( - (str(s) for s in specifiers.SpecifierSet(requires_python)), - key=get_version_sort_key, - ) - ) - reason = f"{version} Requires-Python {requires_python}" - return (LinkType.requires_python_mismatch, reason) - - logger.debug("Found link %s, version: %s", link, version) - - return (LinkType.candidate, version) - - -def filter_unallowed_hashes( - candidates: list[InstallationCandidate], - hashes: Hashes | None, - project_name: str, -) -> list[InstallationCandidate]: - """ - Filter out candidates whose hashes aren't allowed, and return a new - list of candidates. - - If at least one candidate has an allowed hash, then all candidates with - either an allowed hash or no hash specified are returned. Otherwise, - the given candidates are returned. - - Including the candidates with no hash specified when there is a match - allows a warning to be logged if there is a more preferred candidate - with no hash specified. Returning all candidates in the case of no - matches lets pip report the hash of the candidate that would otherwise - have been installed (e.g. permitting the user to more easily update - their requirements file with the desired hash). - """ - if not hashes: - logger.debug( - "Given no hashes to check %s links for project %r: " - "discarding no candidates", - len(candidates), - project_name, - ) - # Make sure we're not returning back the given value. - return list(candidates) - - matches_or_no_digest = [] - # Collect the non-matches for logging purposes. - non_matches = [] - match_count = 0 - for candidate in candidates: - link = candidate.link - if not link.has_hash: - pass - elif link.is_hash_allowed(hashes=hashes): - match_count += 1 - else: - non_matches.append(candidate) - continue - - matches_or_no_digest.append(candidate) - - if match_count: - filtered = matches_or_no_digest - else: - # Make sure we're not returning back the given value. - filtered = list(candidates) - - if len(filtered) == len(candidates): - discard_message = "discarding no candidates" - else: - discard_message = "discarding {} non-matches:\n {}".format( - len(non_matches), - "\n ".join(str(candidate.link) for candidate in non_matches), - ) - - logger.debug( - "Checked %s links for project %r against %s hashes " - "(%s matches, %s no digest): %s", - len(candidates), - project_name, - hashes.digest_count, - match_count, - len(matches_or_no_digest) - match_count, - discard_message, - ) - - return filtered - - -@dataclass -class CandidatePreferences: - """ - Encapsulates some of the preferences for filtering and sorting - InstallationCandidate objects. - """ - - prefer_binary: bool = False - release_control: ReleaseControl | None = None - - -@dataclass(frozen=True) -class BestCandidateResult: - """A collection of candidates, returned by `PackageFinder.find_best_candidate`. - - This class is only intended to be instantiated by CandidateEvaluator's - `compute_best_candidate()` method. - - :param all_candidates: A sequence of all available candidates found. - :param applicable_candidates: The applicable candidates. - :param best_candidate: The most preferred candidate found, or None - if no applicable candidates were found. - """ - - all_candidates: list[InstallationCandidate] - applicable_candidates: list[InstallationCandidate] - best_candidate: InstallationCandidate | None - - def __post_init__(self) -> None: - assert set(self.applicable_candidates) <= set(self.all_candidates) - - if self.best_candidate is None: - assert not self.applicable_candidates - else: - assert self.best_candidate in self.applicable_candidates - - -class CandidateEvaluator: - """ - Responsible for filtering and sorting candidates for installation based - on what tags are valid. - """ - - @classmethod - def create( - cls, - project_name: str, - target_python: TargetPython | None = None, - prefer_binary: bool = False, - release_control: ReleaseControl | None = None, - specifier: specifiers.BaseSpecifier | None = None, - hashes: Hashes | None = None, - ) -> CandidateEvaluator: - """Create a CandidateEvaluator object. - - :param target_python: The target Python interpreter to use when - checking compatibility. If None (the default), a TargetPython - object will be constructed from the running Python. - :param specifier: An optional object implementing `filter` - (e.g. `packaging.specifiers.SpecifierSet`) to filter applicable - versions. - :param hashes: An optional collection of allowed hashes. - """ - if target_python is None: - target_python = TargetPython() - if specifier is None: - specifier = specifiers.SpecifierSet() - - supported_tags = target_python.get_sorted_tags() - - return cls( - project_name=project_name, - supported_tags=supported_tags, - specifier=specifier, - prefer_binary=prefer_binary, - release_control=release_control, - hashes=hashes, - ) - - def __init__( - self, - project_name: str, - supported_tags: list[Tag], - specifier: specifiers.BaseSpecifier, - prefer_binary: bool = False, - release_control: ReleaseControl | None = None, - hashes: Hashes | None = None, - ) -> None: - """ - :param supported_tags: The PEP 425 tags supported by the target - Python in order of preference (most preferred first). - """ - self._release_control = release_control - self._hashes = hashes - self._prefer_binary = prefer_binary - self._project_name = project_name - self._specifier = specifier - self._supported_tags = supported_tags - # Since the index of the tag in the _supported_tags list is used - # as a priority, precompute a map from tag to index/priority to be - # used in wheel.find_most_preferred_tag. - self._wheel_tag_preferences = { - tag: idx for idx, tag in enumerate(supported_tags) - } - - def get_applicable_candidates( - self, - candidates: list[InstallationCandidate], - ) -> list[InstallationCandidate]: - """ - Return the applicable candidates from a list of candidates. - """ - # Using None infers from the specifier instead. - if self._release_control is not None: - allow_prereleases = self._release_control.allows_prereleases( - canonicalize_name(self._project_name) - ) - else: - allow_prereleases = None - specifier = self._specifier - # When using the pkg_resources backend 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(). - applicable_candidates = specifier.filter( - candidates, - prereleases=allow_prereleases, - key=lambda c: ( - str(c.version) - if select_backend().NAME == "pkg_resources" - else c.version - ), - ) - filtered_applicable_candidates = filter_unallowed_hashes( - candidates=list(applicable_candidates), - hashes=self._hashes, - project_name=self._project_name, - ) - - return sorted(filtered_applicable_candidates, key=self._sort_key) - - def _sort_key(self, candidate: InstallationCandidate) -> CandidateSortingKey: - """ - Function to pass as the `key` argument to a call to sorted() to sort - InstallationCandidates by preference. - - Returns a tuple such that tuples sorting as greater using Python's - default comparison operator are more preferred. - - The preference is as follows: - - First and foremost, candidates with allowed (matching) hashes are - always preferred over candidates without matching hashes. This is - because e.g. if the only candidate with an allowed hash is yanked, - we still want to use that candidate. - - Second, excepting hash considerations, candidates that have been - yanked (in the sense of PEP 592) are always less preferred than - candidates that haven't been yanked. Then: - - If not finding wheels, they are sorted by version only. - If finding wheels, then the sort order is by version, then: - 1. existing installs - 2. wheels ordered via Wheel.support_index_min(self._supported_tags) - 3. source archives - If prefer_binary was set, then all wheels are sorted above sources. - - Note: it was considered to embed this logic into the Link - comparison operators, but then different sdist links - with the same version, would have to be considered equal - """ - valid_tags = self._supported_tags - support_num = len(valid_tags) - build_tag: BuildTag = () - binary_preference = 0 - link = candidate.link - if link.is_wheel: - # can raise InvalidWheelFilename - wheel = Wheel(link.filename) - try: - pri = -( - wheel.find_most_preferred_tag( - valid_tags, self._wheel_tag_preferences - ) - ) - except ValueError: - raise UnsupportedWheel( - f"{wheel.filename} is not a supported wheel for this platform. It " - "can't be sorted." - ) - if self._prefer_binary: - binary_preference = 1 - build_tag = wheel.build_tag - else: # sdist - pri = -(support_num) - has_allowed_hash = int(link.is_hash_allowed(self._hashes)) - yank_value = -1 * int(link.is_yanked) # -1 for yanked. - return ( - has_allowed_hash, - yank_value, - binary_preference, - candidate.version, - pri, - build_tag, - ) - - def sort_best_candidate( - self, - candidates: list[InstallationCandidate], - ) -> InstallationCandidate | None: - """ - Return the best candidate per the instance's sort order, or None if - no candidate is acceptable. - """ - if not candidates: - return None - best_candidate = max(candidates, key=self._sort_key) - return best_candidate - - def compute_best_candidate( - self, - candidates: list[InstallationCandidate], - ) -> BestCandidateResult: - """ - Compute and return a `BestCandidateResult` instance. - """ - applicable_candidates = self.get_applicable_candidates(candidates) - - best_candidate = self.sort_best_candidate(applicable_candidates) - - return BestCandidateResult( - candidates, - applicable_candidates=applicable_candidates, - best_candidate=best_candidate, - ) - - -class PackageFinder: - """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, - link_collector: LinkCollector, - target_python: TargetPython, - allow_yanked: bool, - format_control: FormatControl | None = None, - candidate_prefs: CandidatePreferences | None = None, - ignore_requires_python: bool = False, - uploaded_prior_to: datetime.datetime | None = None, - ) -> None: - """ - This constructor is primarily meant to be used by the create() class - method and from tests. - - :param format_control: A FormatControl object, used to control - the selection of source packages / binary packages when consulting - the index and links. - :param candidate_prefs: Options to use when creating a - CandidateEvaluator object. - """ - if candidate_prefs is None: - candidate_prefs = CandidatePreferences() - - format_control = format_control or FormatControl(set(), set()) - - self._allow_yanked = allow_yanked - self._candidate_prefs = candidate_prefs - self._ignore_requires_python = ignore_requires_python - self._link_collector = link_collector - self._target_python = target_python - self._uploaded_prior_to = uploaded_prior_to - - self.format_control = format_control - - # Collects the detail strings for links skipped due to Requires-Python - # incompatibility. Used by requires_python_skipped_reasons() to build - # the error message when resolution fails. - self._requires_python_skipped: set[str] = set() - - # Cache of the result of finding candidates - self._all_candidates: dict[str, list[InstallationCandidate]] = {} - self._best_candidates: dict[ - tuple[str, specifiers.BaseSpecifier | None, Hashes | None], - BestCandidateResult, - ] = {} - - # projects for which a link is locked from a pylock - self._locked_links: dict[NormalizedName, Link] = {} - - # Don't include an allow_yanked default value to make sure each call - # site considers whether yanked releases are allowed. This also causes - # that decision to be made explicit in the calling code, which helps - # people when reading the code. - @classmethod - def create( - cls, - link_collector: LinkCollector, - selection_prefs: SelectionPreferences, - target_python: TargetPython | None = None, - uploaded_prior_to: datetime.datetime | None = None, - ) -> PackageFinder: - """Create a PackageFinder. - - :param selection_prefs: The candidate selection preferences, as a - SelectionPreferences object. - :param target_python: The target Python interpreter to use when - checking compatibility. If None (the default), a TargetPython - object will be constructed from the running Python. - :param uploaded_prior_to: If set, only find links uploaded prior - to the given datetime. - """ - if target_python is None: - target_python = TargetPython() - - candidate_prefs = CandidatePreferences( - prefer_binary=selection_prefs.prefer_binary, - release_control=selection_prefs.release_control, - ) - - return cls( - candidate_prefs=candidate_prefs, - link_collector=link_collector, - target_python=target_python, - allow_yanked=selection_prefs.allow_yanked, - format_control=selection_prefs.format_control, - ignore_requires_python=selection_prefs.ignore_requires_python, - uploaded_prior_to=uploaded_prior_to, - ) - - @property - def target_python(self) -> TargetPython: - return self._target_python - - @property - def search_scope(self) -> SearchScope: - return self._link_collector.search_scope - - @search_scope.setter - def search_scope(self, search_scope: SearchScope) -> None: - self._link_collector.search_scope = search_scope - - @property - def find_links(self) -> list[str]: - return self._link_collector.find_links - - @property - def index_urls(self) -> list[str]: - return self.search_scope.index_urls - - @property - def refresh_package(self) -> set[str]: - return self._link_collector.session.refresh_package - - @property - def proxy(self) -> str | None: - return self._link_collector.session.pip_proxy - - @property - def no_proxy_env(self) -> bool: - return self._link_collector.session.pip_no_proxy_env - - @property - def trusted_hosts(self) -> Iterable[str]: - for host_port in self._link_collector.session.pip_trusted_origins: - yield build_netloc(*host_port) - - @property - def custom_cert(self) -> str | None: - # session.verify is either a boolean (use default bundle/no SSL - # verification) or a string path to a custom CA bundle to use. We only - # care about the latter. - verify = self._link_collector.session.verify - return verify if isinstance(verify, str) else None - - @property - def client_cert(self) -> str | None: - cert = self._link_collector.session.cert - assert not isinstance(cert, tuple), "pip only supports PEM client certs" - return cert - - @property - def release_control(self) -> ReleaseControl | None: - return self._candidate_prefs.release_control - - def set_release_control(self, release_control: ReleaseControl) -> None: - self._candidate_prefs.release_control = release_control - - @property - def prefer_binary(self) -> bool: - return self._candidate_prefs.prefer_binary - - def set_prefer_binary(self) -> None: - self._candidate_prefs.prefer_binary = True - - @property - def uploaded_prior_to(self) -> datetime.datetime | None: - return self._uploaded_prior_to - - def requires_python_skipped_reasons(self) -> list[str]: - return sorted(self._requires_python_skipped) - - def make_link_evaluator(self, project_name: str) -> LinkEvaluator: - canonical_name = canonicalize_name(project_name) - formats = self.format_control.get_allowed_formats(canonical_name) - - return LinkEvaluator( - project_name=project_name, - canonical_name=canonical_name, - formats=formats, - target_python=self._target_python, - allow_yanked=self._allow_yanked, - ignore_requires_python=self._ignore_requires_python, - uploaded_prior_to=self._uploaded_prior_to, - ) - - def _sort_links(self, links: Iterable[Link]) -> list[Link]: - """ - Returns elements of links in order, non-egg links first, egg links - second, while eliminating duplicates - """ - eggs, no_eggs = [], [] - seen: set[Link] = 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 _log_skipped_link(self, link: Link, result: LinkType, detail: str) -> None: - # Put the link at the end so the reason is more visible and because - # the link string is usually very long. - logger.debug("Skipping link: %s: %s", detail, link) - if result == LinkType.requires_python_mismatch: - self._requires_python_skipped.add(detail) - - def get_install_candidate( - self, link_evaluator: LinkEvaluator, link: Link - ) -> InstallationCandidate | None: - """ - If the link is a candidate for install, convert it to an - InstallationCandidate and return it. Otherwise, return None. - """ - result, detail = link_evaluator.evaluate_link(link) - if result == LinkType.upload_time_missing: - # Fail immediately if the index doesn't provide upload-time - # when --uploaded-prior-to is specified - raise InstallationError(detail) - if result != LinkType.candidate: - self._log_skipped_link(link, result, detail) - return None - - try: - return InstallationCandidate( - name=link_evaluator.project_name, - link=link, - version=detail, - ) - except InvalidVersion: - return None - - def evaluate_links( - self, link_evaluator: LinkEvaluator, links: Iterable[Link] - ) -> list[InstallationCandidate]: - """ - Convert links that are candidates to InstallationCandidate objects. - """ - candidates = [] - for link in self._sort_links(links): - candidate = self.get_install_candidate(link_evaluator, link) - if candidate is not None: - candidates.append(candidate) - - return candidates - - def process_project_url( - self, project_url: Link, link_evaluator: LinkEvaluator - ) -> list[InstallationCandidate]: - logger.debug( - "Fetching project page and analyzing links: %s", - project_url, - ) - index_response = self._link_collector.fetch_response( - project_url, package_name=link_evaluator.project_name - ) - if index_response is None: - return [] - - page_links = list(parse_links(index_response)) - - with indent_log(): - package_links = self.evaluate_links( - link_evaluator, - links=page_links, - ) - - return package_links - - def find_all_candidates(self, project_name: str) -> list[InstallationCandidate]: - """Find all available InstallationCandidate for project_name - - This checks index_urls and find_links, unless a locked link is known - for that project. - All versions found are returned as an InstallationCandidate list. - - See LinkEvaluator.evaluate_link() for details on which files - are accepted. - """ - if project_name in self._all_candidates: - return self._all_candidates[project_name] - - link_evaluator = self.make_link_evaluator(project_name) - - if locked_link := self._locked_links.get(canonicalize_name(project_name)): - # If a locked link is known for that project, do not check - # index_urls nor find_links. We don't use get_install_candidate here, - # because if a locked link is unsupported (due to format control, - # release control or otherwise), we want to error out immediately - # instead of ignoring it. - result, detail = link_evaluator.evaluate_link(locked_link) - if result != LinkType.candidate: - raise InstallationError( - f"Could not install locked package {project_name!r} " - f"from {locked_link.comes_from!r}: {detail}" - ) - self._all_candidates[project_name] = [ - InstallationCandidate(project_name, detail, locked_link, locked=True) - ] - return self._all_candidates[project_name] - - collected_sources = self._link_collector.collect_sources( - project_name=project_name, - candidates_from_page=functools.partial( - self.process_project_url, - link_evaluator=link_evaluator, - ), - ) - - page_candidates_it = itertools.chain.from_iterable( - source.page_candidates() - for sources in collected_sources - for source in sources - if source is not None - ) - page_candidates = list(page_candidates_it) - - file_links_it = itertools.chain.from_iterable( - source.file_links() - for sources in collected_sources - for source in sources - if source is not None - ) - file_candidates = self.evaluate_links( - link_evaluator, - sorted(file_links_it, reverse=True), - ) - - if logger.isEnabledFor(logging.DEBUG) and file_candidates: - paths = [] - for candidate in file_candidates: - assert candidate.link.url # we need to have a URL - try: - paths.append(candidate.link.file_path) - except Exception: - paths.append(candidate.link.url) # it's not a local file - - logger.debug("Local files found: %s", ", ".join(paths)) - - # This is an intentional priority ordering - self._all_candidates[project_name] = file_candidates + page_candidates - - return self._all_candidates[project_name] - - def make_candidate_evaluator( - self, - project_name: str, - specifier: specifiers.BaseSpecifier | None = None, - hashes: Hashes | None = None, - ) -> CandidateEvaluator: - """Create a CandidateEvaluator object to use.""" - candidate_prefs = self._candidate_prefs - return CandidateEvaluator.create( - project_name=project_name, - target_python=self._target_python, - prefer_binary=candidate_prefs.prefer_binary, - release_control=candidate_prefs.release_control, - specifier=specifier, - hashes=hashes, - ) - - def find_best_candidate( - self, - project_name: str, - specifier: specifiers.BaseSpecifier | None = None, - hashes: Hashes | None = None, - ) -> BestCandidateResult: - """Find matches for the given project and specifier. - - :param specifier: An optional object implementing `filter` - (e.g. `packaging.specifiers.SpecifierSet`) to filter applicable - versions. - - :return: A `BestCandidateResult` instance. - """ - if (project_name, specifier, hashes) in self._best_candidates: - return self._best_candidates[project_name, specifier, hashes] - - candidates = self.find_all_candidates(project_name) - candidate_evaluator = self.make_candidate_evaluator( - project_name=project_name, - specifier=specifier, - hashes=hashes, - ) - self._best_candidates[project_name, specifier, hashes] = ( - candidate_evaluator.compute_best_candidate(candidates) - ) - - return self._best_candidates[project_name, specifier, hashes] - - def find_requirement( - self, req: InstallRequirement, upgrade: bool - ) -> InstallationCandidate | None: - """Try to find a Link matching req - - Expects req, an InstallRequirement and upgrade, a boolean - Returns a InstallationCandidate if found, - Raises DistributionNotFound or BestVersionAlreadyInstalled otherwise - """ - name = req.name - assert name is not None, "find_requirement() called with no name" - - hashes = req.hashes(trust_internet=False) - best_candidate_result = self.find_best_candidate( - name, - specifier=req.specifier, - hashes=hashes, - ) - best_candidate = best_candidate_result.best_candidate - - installed_version: _BaseVersion | None = None - if req.satisfied_by is not None: - installed_version = req.satisfied_by.version - - def _format_versions(cand_iter: Iterable[InstallationCandidate]) -> str: - # This repeated parse_version and str() conversion is needed to - # handle different vendoring sources from pip and pkg_resources. - # If we stop using the pkg_resources provided specifier and start - # using our own, we can drop the cast to str(). - return ( - ", ".join( - sorted( - {str(c.version) for c in cand_iter}, - key=parse_version, - ) - ) - or "none" - ) - - if installed_version is None and best_candidate is None: - # Check if only final releases are allowed for this package - version_type = "version" - if self.release_control is not None: - allows_pre = self.release_control.allows_prereleases( - canonicalize_name(name) - ) - if allows_pre is False: - version_type = "final version" - - logger.critical( - "Could not find a %s that satisfies the requirement %s " - "(from versions: %s)", - version_type, - req, - _format_versions(best_candidate_result.all_candidates), - ) - - raise DistributionNotFound(f"No matching distribution found for {req}") - - def _should_install_candidate( - candidate: InstallationCandidate | None, - ) -> TypeGuard[InstallationCandidate]: - if installed_version is None: - return True - if best_candidate is None: - return False - return best_candidate.version > installed_version - - if not upgrade and installed_version is not None: - if _should_install_candidate(best_candidate): - logger.debug( - "Existing installed version (%s) satisfies requirement " - "(most up-to-date version is %s)", - installed_version, - best_candidate.version, - ) - else: - logger.debug( - "Existing installed version (%s) is most up-to-date and " - "satisfies requirement", - installed_version, - ) - return None - - if _should_install_candidate(best_candidate): - logger.debug( - "Using version %s (newest of versions: %s)", - best_candidate.version, - _format_versions(best_candidate_result.applicable_candidates), - ) - return best_candidate - - # We have an existing version, and its the best version - logger.debug( - "Installed version (%s) is most up-to-date (past versions: %s)", - installed_version, - _format_versions(best_candidate_result.applicable_candidates), - ) - raise BestVersionAlreadyInstalled - - def add_locked_link(self, project_name: NormalizedName, locked_link: Link) -> None: - assert not self._all_candidates - if project_name in self._locked_links: - raise InstallationError( - f"Multiple locked links provided for {project_name}: " - f"{self._locked_links[project_name]} and {locked_link}" - ) - - self._locked_links[project_name] = locked_link - - -def _find_name_version_sep(fragment: str, canonical_name: str) -> int: - """Find the separator's index based on the package's canonical name. - - :param fragment: A + filename "fragment" (stem) or - egg fragment. - :param canonical_name: The package's canonical name. - - This function is needed since the canonicalized name does not necessarily - have the same length as the egg info's name part. An example:: - - >>> fragment = 'foo__bar-1.0' - >>> canonical_name = 'foo-bar' - >>> _find_name_version_sep(fragment, canonical_name) - 8 - """ - # Project name and version must be separated by one single dash. Find all - # occurrences of dashes; if the string in front of it matches the canonical - # name, this is the one separating the name and version parts. - for i, c in enumerate(fragment): - if c != "-": - continue - if canonicalize_name(fragment[:i]) == canonical_name: - return i - raise ValueError(f"{fragment} does not match {canonical_name}") - - -def _extract_version_from_fragment(fragment: str, canonical_name: str) -> str | None: - """Parse the version string from a + filename - "fragment" (stem) or egg fragment. - - :param fragment: The string to parse. E.g. foo-2.1 - :param canonical_name: The canonicalized name of the package this - belongs to. - """ - try: - version_start = _find_name_version_sep(fragment, canonical_name) + 1 - except ValueError: - return None - version = fragment[version_start:] - if not version: - return None - return version diff --git a/venv/lib/python3.11/site-packages/pip/_internal/index/sources.py b/venv/lib/python3.11/site-packages/pip/_internal/index/sources.py deleted file mode 100755 index 6e7c007..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/index/sources.py +++ /dev/null @@ -1,286 +0,0 @@ -from __future__ import annotations - -import logging -import mimetypes -import os -from collections import defaultdict -from collections.abc import Callable, Iterable - -from pip._vendor.packaging.utils import ( - InvalidSdistFilename, - InvalidWheelFilename, - canonicalize_name, - parse_sdist_filename, - parse_wheel_filename, -) - -from pip._internal.models.candidate import InstallationCandidate -from pip._internal.models.link import Link -from pip._internal.utils.urls import path_to_url, url_to_path -from pip._internal.vcs import is_url - -logger = logging.getLogger(__name__) - -FoundCandidates = Iterable[InstallationCandidate] -FoundLinks = Iterable[Link] -CandidatesFromPage = Callable[[Link], Iterable[InstallationCandidate]] -PageValidator = Callable[[Link], bool] - - -class LinkSource: - @property - def link(self) -> Link | None: - """Returns the underlying link, if there's one.""" - raise NotImplementedError() - - def page_candidates(self) -> FoundCandidates: - """Candidates found by parsing an archive listing HTML file.""" - raise NotImplementedError() - - def file_links(self) -> FoundLinks: - """Links found by specifying archives directly.""" - raise NotImplementedError() - - -def _is_html_file(file_url: str) -> bool: - return mimetypes.guess_type(file_url, strict=False)[0] == "text/html" - - -class _FlatDirectoryToUrls: - """Scans directory and caches results""" - - def __init__(self, path: str) -> None: - self._path = path - self._page_candidates: list[str] = [] - self._project_name_to_urls: dict[str, list[str]] = defaultdict(list) - self._scanned_directory = False - - def _scan_directory(self) -> None: - """Scans directory once and populates both page_candidates - and project_name_to_urls at the same time - """ - for entry in os.scandir(self._path): - url = path_to_url(entry.path) - if _is_html_file(url): - self._page_candidates.append(url) - continue - - # File must have a valid wheel or sdist name, - # otherwise not worth considering as a package - try: - project_filename = parse_wheel_filename(entry.name)[0] - except InvalidWheelFilename: - try: - project_filename = parse_sdist_filename(entry.name)[0] - except InvalidSdistFilename: - continue - - self._project_name_to_urls[project_filename].append(url) - self._scanned_directory = True - - @property - def page_candidates(self) -> list[str]: - if not self._scanned_directory: - self._scan_directory() - - return self._page_candidates - - @property - def project_name_to_urls(self) -> dict[str, list[str]]: - if not self._scanned_directory: - self._scan_directory() - - return self._project_name_to_urls - - -class _FlatDirectorySource(LinkSource): - """Link source specified by ``--find-links=``. - - This looks the content of the directory, and returns: - - * ``page_candidates``: Links listed on each HTML file in the directory. - * ``file_candidates``: Archives in the directory. - """ - - _paths_to_urls: dict[str, _FlatDirectoryToUrls] = {} - - def __init__( - self, - candidates_from_page: CandidatesFromPage, - path: str, - project_name: str, - ) -> None: - self._candidates_from_page = candidates_from_page - self._project_name = canonicalize_name(project_name) - - # Get existing instance of _FlatDirectoryToUrls if it exists - if path in self._paths_to_urls: - self._path_to_urls = self._paths_to_urls[path] - else: - self._path_to_urls = _FlatDirectoryToUrls(path=path) - self._paths_to_urls[path] = self._path_to_urls - - @property - def link(self) -> Link | None: - return None - - def page_candidates(self) -> FoundCandidates: - for url in self._path_to_urls.page_candidates: - yield from self._candidates_from_page(Link(url)) - - def file_links(self) -> FoundLinks: - for url in self._path_to_urls.project_name_to_urls[self._project_name]: - yield Link(url) - - -class _LocalFileSource(LinkSource): - """``--find-links=`` or ``--[extra-]index-url=``. - - If a URL is supplied, it must be a ``file:`` URL. If a path is supplied to - the option, it is converted to a URL first. This returns: - - * ``page_candidates``: Links listed on an HTML file. - * ``file_candidates``: The non-HTML file. - """ - - def __init__( - self, - candidates_from_page: CandidatesFromPage, - link: Link, - ) -> None: - self._candidates_from_page = candidates_from_page - self._link = link - - @property - def link(self) -> Link | None: - return self._link - - def page_candidates(self) -> FoundCandidates: - if not _is_html_file(self._link.url): - return - yield from self._candidates_from_page(self._link) - - def file_links(self) -> FoundLinks: - if _is_html_file(self._link.url): - return - yield self._link - - -class _RemoteFileSource(LinkSource): - """``--find-links=`` or ``--[extra-]index-url=``. - - This returns: - - * ``page_candidates``: Links listed on an HTML file. - * ``file_candidates``: The non-HTML file. - """ - - def __init__( - self, - candidates_from_page: CandidatesFromPage, - page_validator: PageValidator, - link: Link, - ) -> None: - self._candidates_from_page = candidates_from_page - self._page_validator = page_validator - self._link = link - - @property - def link(self) -> Link | None: - return self._link - - def page_candidates(self) -> FoundCandidates: - if not self._page_validator(self._link): - return - yield from self._candidates_from_page(self._link) - - def file_links(self) -> FoundLinks: - yield self._link - - -class _IndexDirectorySource(LinkSource): - """``--[extra-]index-url=``. - - This is treated like a remote URL; ``candidates_from_page`` contains logic - for this by appending ``index.html`` to the link. - """ - - def __init__( - self, - candidates_from_page: CandidatesFromPage, - link: Link, - ) -> None: - self._candidates_from_page = candidates_from_page - self._link = link - - @property - def link(self) -> Link | None: - return self._link - - def page_candidates(self) -> FoundCandidates: - yield from self._candidates_from_page(self._link) - - def file_links(self) -> FoundLinks: - return () - - -def build_source( - location: str, - *, - candidates_from_page: CandidatesFromPage, - page_validator: PageValidator, - expand_dir: bool, - cache_link_parsing: bool, - project_name: str, -) -> tuple[str | None, LinkSource | None]: - path: str | None = None - url: str | None = None - if os.path.exists(location): # Is a local path. - url = path_to_url(location) - path = location - elif location.startswith("file:"): # A file: URL. - url = location - path = url_to_path(location) - elif is_url(location): - url = location - - if url is None: - msg = ( - "Location '%s' is ignored: " - "it is either a non-existing path or lacks a specific scheme." - ) - logger.warning(msg, location) - return (None, None) - - if path is None: - source: LinkSource = _RemoteFileSource( - candidates_from_page=candidates_from_page, - page_validator=page_validator, - link=Link(url, cache_link_parsing=cache_link_parsing), - ) - return (url, source) - - if os.path.isdir(path): - if expand_dir: - source = _FlatDirectorySource( - candidates_from_page=candidates_from_page, - path=path, - project_name=project_name, - ) - else: - source = _IndexDirectorySource( - candidates_from_page=candidates_from_page, - link=Link(url, cache_link_parsing=cache_link_parsing), - ) - return (url, source) - elif os.path.isfile(path): - source = _LocalFileSource( - candidates_from_page=candidates_from_page, - link=Link(url, cache_link_parsing=cache_link_parsing), - ) - return (url, source) - logger.warning( - "Location '%s' is ignored: it is neither a file nor a directory.", - location, - ) - return (url, None) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/locations/__init__.py b/venv/lib/python3.11/site-packages/pip/_internal/locations/__init__.py deleted file mode 100755 index ec15d1d..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/locations/__init__.py +++ /dev/null @@ -1,438 +0,0 @@ -from __future__ import annotations - -import functools -import logging -import os -import pathlib -import sys -import sysconfig - -from pip._internal.models.scheme import SCHEME_KEYS, Scheme -from pip._internal.utils.compat import WINDOWS -from pip._internal.utils.deprecation import deprecated -from pip._internal.utils.virtualenv import running_under_virtualenv - -from . import _sysconfig -from .base import ( - USER_CACHE_DIR, - get_major_minor_version, - get_src_prefix, - is_osx_framework, - site_packages, - user_site, -) - -__all__ = [ - "USER_CACHE_DIR", - "get_bin_prefix", - "get_bin_user", - "get_major_minor_version", - "get_platlib", - "get_purelib", - "get_scheme", - "get_src_prefix", - "site_packages", - "user_site", -] - - -logger = logging.getLogger(__name__) - - -_PLATLIBDIR: str = getattr(sys, "platlibdir", "lib") - - -def _should_use_sysconfig() -> bool: - """This function determines the value of _USE_SYSCONFIG. - - By default, pip uses sysconfig. - But Python distributors can override this decision by setting: - sysconfig._PIP_USE_SYSCONFIG = True / False - Rationale in https://github.com/pypa/pip/issues/10647 - - This is a function for testability, but should be constant during any one - run. - """ - return bool(getattr(sysconfig, "_PIP_USE_SYSCONFIG", True)) - - -_USE_SYSCONFIG = _should_use_sysconfig() - -if not _USE_SYSCONFIG: - # Import distutils lazily to avoid deprecation warnings, - # but import it soon enough that it is in memory and available during - # a pip reinstall. - from . import _distutils - -# Be noisy about incompatibilities if this platforms "should" be using -# sysconfig, but is explicitly opting out and using distutils instead. -if _USE_SYSCONFIG: - _MISMATCH_LEVEL = logging.DEBUG -else: - _MISMATCH_LEVEL = logging.WARNING - - -def _looks_like_bpo_44860() -> bool: - """The resolution to bpo-44860 will change this incorrect platlib. - - See . - """ - from distutils.command.install import INSTALL_SCHEMES - - try: - unix_user_platlib = INSTALL_SCHEMES["unix_user"]["platlib"] - except KeyError: - return False - return unix_user_platlib == "$usersite" - - -def _looks_like_red_hat_patched_platlib_purelib(scheme: dict[str, str]) -> bool: - platlib = scheme["platlib"] - if "/$platlibdir/" in platlib: - platlib = platlib.replace("/$platlibdir/", f"/{_PLATLIBDIR}/") - if "/lib64/" not in platlib: - return False - unpatched = platlib.replace("/lib64/", "/lib/") - return unpatched.replace("$platbase/", "$base/") == scheme["purelib"] - - -@functools.cache -def _looks_like_red_hat_lib() -> bool: - """Red Hat patches platlib in unix_prefix and unix_home, but not purelib. - - This is the only way I can see to tell a Red Hat-patched Python. - """ - from distutils.command.install import INSTALL_SCHEMES - - return all( - k in INSTALL_SCHEMES - and _looks_like_red_hat_patched_platlib_purelib(INSTALL_SCHEMES[k]) - for k in ("unix_prefix", "unix_home") - ) - - -@functools.cache -def _looks_like_debian_scheme() -> bool: - """Debian adds two additional schemes.""" - from distutils.command.install import INSTALL_SCHEMES - - return "deb_system" in INSTALL_SCHEMES and "unix_local" in INSTALL_SCHEMES - - -@functools.cache -def _looks_like_red_hat_scheme() -> bool: - """Red Hat patches ``sys.prefix`` and ``sys.exec_prefix``. - - Red Hat's ``00251-change-user-install-location.patch`` changes the install - command's ``prefix`` and ``exec_prefix`` to append ``"/local"``. This is - (fortunately?) done quite unconditionally, so we create a default command - object without any configuration to detect this. - """ - from distutils.command.install import install - from distutils.dist import Distribution - - cmd = install(Distribution()) - cmd.finalize_options() - return ( - cmd.exec_prefix == f"{os.path.normpath(sys.exec_prefix)}/local" - and cmd.prefix == f"{os.path.normpath(sys.prefix)}/local" - ) - - -@functools.cache -def _looks_like_slackware_scheme() -> bool: - """Slackware patches sysconfig but fails to patch distutils and site. - - Slackware changes sysconfig's user scheme to use ``"lib64"`` for the lib - path, but does not do the same to the site module. - """ - if user_site is None: # User-site not available. - return False - try: - paths = sysconfig.get_paths(scheme="posix_user", expand=False) - except KeyError: # User-site not available. - return False - return "/lib64/" in paths["purelib"] and "/lib64/" not in user_site - - -@functools.cache -def _looks_like_msys2_mingw_scheme() -> bool: - """MSYS2 patches distutils and sysconfig to use a UNIX-like scheme. - - However, MSYS2 incorrectly patches sysconfig ``nt`` scheme. The fix is - likely going to be included in their 3.10 release, so we ignore the warning. - See msys2/MINGW-packages#9319. - - MSYS2 MINGW's patch uses lowercase ``"lib"`` instead of the usual uppercase, - and is missing the final ``"site-packages"``. - """ - paths = sysconfig.get_paths("nt", expand=False) - return all( - "Lib" not in p and "lib" in p and not p.endswith("site-packages") - for p in (paths[key] for key in ("platlib", "purelib")) - ) - - -@functools.cache -def _warn_mismatched(old: pathlib.Path, new: pathlib.Path, *, key: str) -> None: - issue_url = "https://github.com/pypa/pip/issues/10151" - message = ( - "Value for %s does not match. Please report this to <%s>" - "\ndistutils: %s" - "\nsysconfig: %s" - ) - logger.log(_MISMATCH_LEVEL, message, key, issue_url, old, new) - - -def _warn_if_mismatch(old: pathlib.Path, new: pathlib.Path, *, key: str) -> bool: - if old == new: - return False - _warn_mismatched(old, new, key=key) - return True - - -@functools.cache -def _log_context( - *, - user: bool = False, - home: str | None = None, - root: str | None = None, - prefix: str | None = None, -) -> None: - parts = [ - "Additional context:", - "user = %r", - "home = %r", - "root = %r", - "prefix = %r", - ] - - logger.log(_MISMATCH_LEVEL, "\n".join(parts), user, home, root, prefix) - - -def get_scheme( - dist_name: str, - user: bool = False, - home: str | None = None, - root: str | None = None, - isolated: bool = False, - prefix: str | None = None, -) -> Scheme: - new = _sysconfig.get_scheme( - dist_name, - user=user, - home=home, - root=root, - isolated=isolated, - prefix=prefix, - ) - if _USE_SYSCONFIG: - return new - - old = _distutils.get_scheme( - dist_name, - user=user, - home=home, - root=root, - isolated=isolated, - prefix=prefix, - ) - - warning_contexts = [] - for k in SCHEME_KEYS: - old_v = pathlib.Path(getattr(old, k)) - new_v = pathlib.Path(getattr(new, k)) - - if old_v == new_v: - continue - - # distutils incorrectly put PyPy packages under ``site-packages/python`` - # in the ``posix_home`` scheme, but PyPy devs said they expect the - # directory name to be ``pypy`` instead. So we treat this as a bug fix - # and not warn about it. See bpo-43307 and python/cpython#24628. - skip_pypy_special_case = ( - sys.implementation.name == "pypy" - and home is not None - and k in ("platlib", "purelib") - and old_v.parent == new_v.parent - and old_v.name.startswith("python") - and new_v.name.startswith("pypy") - ) - if skip_pypy_special_case: - continue - - # sysconfig's ``osx_framework_user`` does not include ``pythonX.Y`` in - # the ``include`` value, but distutils's ``headers`` does. We'll let - # CPython decide whether this is a bug or feature. See bpo-43948. - skip_osx_framework_user_special_case = ( - user - and is_osx_framework() - and k == "headers" - and old_v.parent.parent == new_v.parent - and old_v.parent.name.startswith("python") - ) - if skip_osx_framework_user_special_case: - continue - - # On Red Hat and derived Linux distributions, distutils is patched to - # use "lib64" instead of "lib" for platlib. - if k == "platlib" and _looks_like_red_hat_lib(): - continue - - # sysconfig's posix_user scheme sets platlib against - # sys.platlibdir, but distutils's unix_user incorrectly continues - # using the same $usersite for both platlib and purelib. This creates a - # mismatch when sys.platlibdir is not "lib". - skip_bpo_44860 = ( - user - and k == "platlib" - and not WINDOWS - and _PLATLIBDIR != "lib" - and _looks_like_bpo_44860() - ) - if skip_bpo_44860: - continue - - # Slackware incorrectly patches posix_user to use lib64 instead of lib, - # but not usersite to match the location. - skip_slackware_user_scheme = ( - user - and k in ("platlib", "purelib") - and not WINDOWS - and _looks_like_slackware_scheme() - ) - if skip_slackware_user_scheme: - continue - - # Both Debian and Red Hat patch Python to place the system site under - # /usr/local instead of /usr. Debian also places lib in dist-packages - # instead of site-packages, but the /usr/local check should cover it. - skip_linux_system_special_case = ( - not (user or home or prefix or running_under_virtualenv()) - and old_v.parts[1:3] == ("usr", "local") - and len(new_v.parts) > 1 - and new_v.parts[1] == "usr" - and (len(new_v.parts) < 3 or new_v.parts[2] != "local") - and (_looks_like_red_hat_scheme() or _looks_like_debian_scheme()) - ) - if skip_linux_system_special_case: - continue - - # MSYS2 MINGW's sysconfig patch does not include the "site-packages" - # part of the path. This is incorrect and will be fixed in MSYS. - skip_msys2_mingw_bug = ( - WINDOWS and k in ("platlib", "purelib") and _looks_like_msys2_mingw_scheme() - ) - if skip_msys2_mingw_bug: - continue - - # CPython's POSIX install script invokes pip (via ensurepip) against the - # interpreter located in the source tree, not the install site. This - # triggers special logic in sysconfig that's not present in distutils. - # https://github.com/python/cpython/blob/8c21941ddaf/Lib/sysconfig.py#L178-L194 - skip_cpython_build = ( - sysconfig.is_python_build(check_home=True) - and not WINDOWS - and k in ("headers", "include", "platinclude") - ) - if skip_cpython_build: - continue - - warning_contexts.append((old_v, new_v, f"scheme.{k}")) - - if not warning_contexts: - return old - - # Check if this path mismatch is caused by distutils config files. Those - # files will no longer work once we switch to sysconfig, so this raises a - # deprecation message for them. - default_old = _distutils.distutils_scheme( - dist_name, - user, - home, - root, - isolated, - prefix, - ignore_config_files=True, - ) - if any(default_old[k] != getattr(old, k) for k in SCHEME_KEYS): - deprecated( - reason=( - "Configuring installation scheme with distutils config files " - "is deprecated and will no longer work in the near future. If you " - "are using a Homebrew or Linuxbrew Python, please see discussion " - "at https://github.com/Homebrew/homebrew-core/issues/76621" - ), - replacement=None, - gone_in=None, - ) - return old - - # Post warnings about this mismatch so user can report them back. - for old_v, new_v, key in warning_contexts: - _warn_mismatched(old_v, new_v, key=key) - _log_context(user=user, home=home, root=root, prefix=prefix) - - return old - - -def get_bin_prefix() -> str: - new = _sysconfig.get_bin_prefix() - if _USE_SYSCONFIG: - return new - - old = _distutils.get_bin_prefix() - if _warn_if_mismatch(pathlib.Path(old), pathlib.Path(new), key="bin_prefix"): - _log_context() - return old - - -def get_bin_user() -> str: - return _sysconfig.get_scheme("", user=True).scripts - - -def _looks_like_deb_system_dist_packages(value: str) -> bool: - """Check if the value is Debian's APT-controlled dist-packages. - - Debian's ``distutils.sysconfig.get_python_lib()`` implementation returns the - default package path controlled by APT, but does not patch ``sysconfig`` to - do the same. This is similar to the bug worked around in ``get_scheme()``, - but here the default is ``deb_system`` instead of ``unix_local``. Ultimately - we can't do anything about this Debian bug, and this detection allows us to - skip the warning when needed. - """ - if not _looks_like_debian_scheme(): - return False - if value == "/usr/lib/python3/dist-packages": - return True - return False - - -def get_purelib() -> str: - """Return the default pure-Python lib location.""" - new = _sysconfig.get_purelib() - if _USE_SYSCONFIG: - return new - - old = _distutils.get_purelib() - if _looks_like_deb_system_dist_packages(old): - return old - if _warn_if_mismatch(pathlib.Path(old), pathlib.Path(new), key="purelib"): - _log_context() - return old - - -def get_platlib() -> str: - """Return the default platform-shared lib location.""" - new = _sysconfig.get_platlib() - if _USE_SYSCONFIG: - return new - - from . import _distutils - - old = _distutils.get_platlib() - if _looks_like_deb_system_dist_packages(old): - return old - if _warn_if_mismatch(pathlib.Path(old), pathlib.Path(new), key="platlib"): - _log_context() - return old diff --git a/venv/lib/python3.11/site-packages/pip/_internal/locations/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/locations/__pycache__/__init__.cpython-311.pyc deleted file mode 100755 index cb02f8f8ca849be3b454cdcdf4df8845e719d4d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16305 zcmcJ0Yit`=mSz=Md{a_U4_mTjxh&hUWlN+SDYoM{cKnbW*^c6l>?Bq?pea>JqRfZ7 zs%S?Fh1Skyx0Q@%SKV;Kn(1UAG#Y7T?8XEO3}9ffn8y4V%#Zy+3e1K}z<_{71Jl6% zU?a&QFc#ST&aDR@l9TN0Y_WLiR@J%ZzRo@OJZ}BAp~27L_^YW5$FbKHNY8|!cz z3I3~l4vu@k-QZ+S<`Z0!ALn^WI}(m@2fI4Qo$M-%3+(C|cd@H`+|90@aSyJ}gg5CM z_a*(~ewJTI1d_q=AWORv4avswMwWIbnv&wUh_pxcCPK;P@n)9xC0dfLf#h$&IIRE59IzJ`l$D0e9c0xPNHkaNKye(yh5suV&P1|M-5MQ@T|zN<3hp zj2}#SaQ|H89@JVu?T~z2-hu03#WCAsy~Vqo9|(129I3----21ZY; zD{AykT-7tNgp#`RM`9U5k81PUWI8n!pYCy&8gGmZy%D`|4uwQ7j=WLYIj!i?WNbFA zMw9Ur;2lNPP?u68z0lOjD9W0OzgH6DS~RV_7oAdLN#$-@yqvBmkm*k9!T1&Ciyp&EE z6#=Ik9Z_oDTJ!5YPL+ga$pglT>0k(--O$gtuV^%%z7v^ACzVJtrcS0Km($bffk@P!pDw9h>!a$-e#?f##0#2R4frmq%rwuzDA;W7}ulG@Z5ZM=dcoICyfAwP|9x%S7#cYw|A&#Bi)SV>(;9k;`Z%0crwx8#1kV`bs#5W2f78h5*!6Q) zuSN}7I0o60ioeIiM#*CqFudS9Kyri$9A~M+?lI!YWGp3zkDR^;E-ncLjg#9e^dS?B`ska>9$% zXIXH%+KQb=*RK>hPd@G_bY94LJ8*vcB+ydkcvo8m6q{O?Gs~H>6HmYW_S?-s=UQMR za5N_z)kr!nH}2#f_zyaN!yj~(+!~XGPaEapEPx8HI*50kNlB31b@?1w z$J*8+@q|>QT3poISE;wnlm1cl2=EsgA_po9K;$VOdFr9rdwei5yx?NvI(I!Tli|OcTSwlyH8%%aMTFnlsB1dOpShoyJ zi+`eK0qP0lyotXy53s})8(UXy78>_1T`GEZtRBjF_TelxcRYyvBC;0A4GjJ5`vAt7 zZyqi*4=;O)9&y!^^X$dRn4~D~e9-iZrZwOCiM%*a5C@htHYGwyDaDb%eWh8#dUqPd3j=Z~P5whUc+uNX3N=QA3jo&yeXp7tYvZ&B^wRx$a9Kx0*F>`Im0TywbWLB0P(&%P#rRFG0Z zYP!q4m9a@WVY>2Pbs8bCJ=UFuJwX0tm2HpT?NfwHnhm;Yd0c!KDuHIR5;1P2@$A z&O~p^QJahBvW{6>Q0TNsna3>Y)$CaFTB+)*-dwq>P^g_%SZ{<+9EQA4527Sy*i*iL zc1bpcXO~1g5&JQ^uwIVcx`j~>8`A66EhfK=N6LGOWftAKWeP4c^C3;Tb*sPs`4^7$ z8R}6V=_q}sD$-|Zj$tOYK-54o3D;Cc!^qXupr&+^h)`h_$kto8x|wF0=tiX^ zQ;;%ZhoN)pnG_7h#QfPFNrpZx{Uieg7xEbTw#EDjDC1gMx(g*-Re%gBYnmj`%9%>V zsHG=nNzc0r10W66ofLG#y3D9dE2b)u=>r_HMXE$Hj8Tu-NF;+7EgJ??Z^3QUy(eJI zs!JI35>y>i3l39CC5x>jPQ@`%;|oeOJ;#*rQlP3wN{+Nv641LdB`>VmBuhCljwQFz zjgV?Y+o0u~OxCUQyQ(LyYOeF<%zXp-7Vy`81Av*^%(qCm=9^||Q}EgxFx zUFrRK_kZIcY31ln`KO@PiNq zmZr&+Ov{-BDgmWY8Xbn0BCVN53)Tu!F-vYJ08oQeXd#?B2+$)ikA_ONVadmQAt+B% zdvOmt$VH`VY{@kjmd^< zxB+jabg-2nLP#tt61-_rTw`oP#F1?}O|A~`5*#2Pm&nLasi8iDwc@G-e?&hl@q_|% z#*)zSX-GG+y%lK4D*68mz9V}(33h)z^4iGgrMGMk#{L%vj=gBs->5cwkNIFsCQJiO zN}yrtBuX)71kDGM*Gfz#zZDgh(coN^GFWjKVlQh2Y4&jPB;o&I?O<&rZ3+{s#*acP z6U$L@r1W8E%{MUmlQtLNh6EJT(Mj0a8hSUZPG~T9_;iO1T^%B%?U|ORqjv0roT;nt zm!04Pq2#<8pHO##`U3M`+C2m%zU0L^s?oxR3HuUIO8i{4Q$T&0vK_0Qf~>E}b2@$3 zoP^tG@qdkM+FJmY67M7>9$+)rP@#+4r}H|D$}t1qmbTRnxudhBmz|9bZE-h6nZ z5FW`L87VuhEG%CgFjT|pZp4%`x{-VzRi;jG5r$5+Sz~ri0~s>vDIlv702WEseCKUt zUVR%6YHXQ*ZZ|w4LWclMV0FG{t@G@8nR}6=3s`oAuXLuP^xc&hWZKt z>Qp8kO^c-KyT?W)+4LVM&$|FHOyG@c*ii`XT@%)C7Ni-lwNaP0`mz#$G#j{lcr!t3z)NUF~tHGFqih5nvtVV~*u$ zMopAFNk!8r+&~KpEwtvkC`L&PVj^m+Zi=j?fbco~+6w?n+@^SHX{0PTe7i8?T)}VP zxC{L3@}FJ)i=VD})?3!&k6Rv3=7sYG;e5_IjcHXqKK5!xGlhHyS>CW#;0=QkQ@ys) zyR73;UEBa;z@*UV@Mk=0+jR&*swrk%ZKG@5Pa&gu@hQ87>Q9jCKjE((0f3Xq<6oZq zvxTJvw%9)rT35za_pc4)ghP4ZP(e6^L^05`Jjfa~{FzV^ND(RtWa*a#HJ#SgYapa* z1c>3D`k`@4S&5ib&CpYNPZNk80-(*VS=>CJ_$B{q{{NO;Wycyxt1U-Xs1@W!hi0A6 zU~1U)E$1qBJS-Ajc~3vJz@k!!Y8+G-eAHGmNewoV0nEw0ow~8>FDAx>nDOK}ezLs96Q|eGvJ3{Iv@JFdIa714M)cmWI9&E37E|*7s}Q z`oX-^Uy%AgKk!(1EdPEuFI*`IS8~?LMzG|g85T`J2Q7KyaMDvWP$mAHv?n}neE2hg zat%*^*7CE~XDMJ-??QOE9@PnsMR&D$Q5{(~Slt84=221OzKhC7t<&71M<<>!kBi)j zY@Lg^mNyoC-%lg!{vI0stS{>~r!#+VR2Qw%Q7h_4 zc2ryvvgN3_lEn^!44=M~^~z4DCKs~4S-VA9eV~TDz)hX4kw@?`_)9Ro%w#tyx`b7K7O! zYWBZTvKeqvMSYK5r8R93LLETF~SHXwTMV>zM2y*FmU9#>dpm3W>lyrl>zw)%U z-HQ#`21fZjD0i46*H%ZhK|lD+{EgX0mVYA4&xNv%xu&dZu0bd5#yo1vLmijUXRX#- z*(>}0jiX`}%O>ZglloB$hvU%mc8*$(m%X=10(0pb)i|=ZiekVV)r&unqVF~@F)MH$G~r?Vog@x(xKb6QziExW!O5#3-G~de*9Dg+&Q{4k;j`PQT(laZEXD zsq&Cm_uk2RG{=XnbuzHiqEIaZQLpAtAt@i)((y)+q<})_7~>Vr`$+ z)>X-Fg@V8LiAVKiW~B4?TRY z3JWR>R7uyPou7i+9x{%jw+8*5_R+1&;v!x%O#xoG`MG&@0{8H}v7m3sGXql+AzMSG zCnHQH$@)i{t_VapGn!g*G4Hziujx7IUg`$`P?Ji2MCB%LN6pa0zrs`UCNg8W6rg~h zd9&a#jcw#k(s*h3S(u zythW@G52nji_PdjxGvCvWb0S9ATj3&+YgXR!-Iew0jfmXgG~R0lu}|Uc7I?ujuMte zrlk3FMj{_yhWQF&(yLI)CRF9F1RLXOJe7Hm-5A?kuocEIF(~#2g=aDY4+HihAlSH# z31d-Wn>>h0ANC|D)~=Kj$B#dMjBF41wl(Z;3YanAq>|FHX9QX<_Hw9mG)@$r>Di~! zf~&Rxlp1R{$*8m}s5EQ{DjT+4Ng(5njkfwa%Mwqb?nIn*Ye`_Lnj88el?UCL6i0G3 zsEtI7CY?&m$U@R=n}JH+JeBk%m7HfVmXwrAZV@AdG)XDuH*CVrEMtO2Co=JbTyh%` zfs$xjVWw}QYoJZ5%SNi@AomR747%ZQ{ouQ6mQ(L*g6M$y`;A;X)7l7*BK^s6?icQVS{y+Fze^@>Q8`=>k zXnoSqUWUiab@opTF7r>so%e&4DW4bn3S!@~>lu$X1LDfiM`xDL6oaks4mXH}U{@iy zf9=jju&>Oy8p1`fb@gISl*&%rY>J^=+tHkOwCutiB9);X_k(M$-vl?r-m-@tdFhe= zOYz`_cyMhdFGdPtr0k)OCo8`i9y_We+c0(LMbQn)r(ZPba?@O^4^;v&AFCH(5$IAiE*H>=j zg8gqMdJ#PXT{hQiSStnkA{vp5ue_z$hSR{~V<;cw93&ehC@ zcz{Yg{0&NcE-xM`h=-_FHXLhKlygy$rS zp2>O7Ah8+P4Rmvgp>8dE3e9~qIlV#a6pP-*Vy9GY^0r`p0(?zi>B=|FoHtOnV*c%I zJjnac7XUry3!d|3F5qf;;%&xGuh3N<)$7<(Y;7-xd_Mo5IDoGSlo@E{#Fk}0n%@lJ`am-Ut#np9tcLywERjN-lVU~$LqE!jHtYAELI!t z(2byHV#$2HuS{*Mb^+AZ1N#stXy_a*`78U2+2Y;fHP-DA3RnL<0k&9^ zw@h6j@N)w11HiL9MQJAYNs}{ui7LxV;C<4w==Bo!gaq~ey#HXqe{ku-6A#ffjr|XLji53TLS-< znol+onveA@Agwj8AIJqF`9P#V=ZTzfg5@i@*xu$E#hN;lF(p39sH=SKP-@I|iWsr! zPk}2HE>d!*_6V_WP=yPm_DgXi{$y;Th5~Br;X(ZB+_me_^HRE+P9zXDBbCRF>6ig8 z8~4^NTO$hFKIt$EyD|d>yFDik_fXWUMtOsWn>LfPT^cNWWo?Tv_Xkr9ZH6{MSe3x8 zYgDT)Yz(By8HB{_f>Dm1Ht1C%%J$9;NsA}r3Fyvdh#3kD)2q?On3~3Be^Rh--KrQ0 zRBcnbv=Q|B1PV<_L3gPDrahy(%l&)1xrCe z+|vjU4li^?U=3F9%8t|wEwS_vSPPejxM(D9%vivI>L5_1#cWTt{kekrJ7oBXIGlVL z(BWFS;K6+0xk7*zWo+Q3t+_={FemnJc=~gm{$f+hvR({`%P)L~1jg4tb>TmI)CR)of68IGj^E?tu98CRZHW3Oo@Wd97jvH1@}AcUp4WbmaCf6ROg`enu>S{^A@QGZ zCIxe&AOB2tb5t`$w$4`!w!w~_Y9^>&dS`8)eSN-XVAZpY6FY~{*2xhxf<+jbjs8YyU0)Cu2%NqPc0TO&+Lvlya!hf)~=EOpIJv3fA-uHn(q z;nAK(!wbQR{%#`7Gr@|eBj*BjtKmck4X34{syVEZC-Her)Nn{eqbm3kJFnO`Tli8; zD|sk1jpa=xhoB*1$e&|)T6W_rr?CAUP#7D&l!O*GJZ8)v#3FE|UA1UzlNx=M0u6xq zcuIS>L$F+GSTUK4rqs0^R^|IX!!^X%nOGd3y201NKD=X}))^noG3QbfH9#aBPc({+ z+|el8Yj)KL!h54EjEKI76COD%nG*_u`DoR*iFm)CUfDWz$#rq){EbUSkks?mxi?0! z|xwy_o{aCMT2NY`#hKb{~Om zfT!Nm#%8-S>fhlO^N`clFp~I?hUbf1cW%qM$%#4ZEOL!Y>{sM`OYB$m#J|LTMGG0Z zHo2E_+nq%&oU1*H-0@uPS>!I{YR^rsJy&~{9Uk6M=KkeCb07eE7FhC>J30UE<(&oJ zuGN!y-+_Yfz>*s#Da`E?s{?DnbtT_2SZEns3goy!*vT~?%E1#7 zI$Q`HUTWMVTS(ydz#-$>Qzz;0OlZb-82-89jy?C2ORq1zzKKM7>2;#sOT?=|r-#3c z61Tus&Jp-vZ`l#x5jeNNpPZZ{WIgRPF$Df~5U4;Ki9KpGu|%R{0UL!LJZEAA`By=w z0&OJrsLRA^BsvzbQRqRpiQ(Zdum)MsMq)2o1zx1uRs*w+_zGfYap!J2JNA?VO+5Sz z-1g9>$zC6>WNh0-c^f7jd=q?z+rz6aFTJe=J9z#il$aXeZRA7L*lN%npuDx9vw@yH J1F#wVe*oI=Jv0CS diff --git a/venv/lib/python3.11/site-packages/pip/_internal/locations/__pycache__/_distutils.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/locations/__pycache__/_distutils.cpython-311.pyc deleted file mode 100755 index 50832713415364e8b473b0fc62dd2ae7e9a2272c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7254 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 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/locations/_distutils.py b/venv/lib/python3.11/site-packages/pip/_internal/locations/_distutils.py deleted file mode 100755 index 28c066b..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/locations/_distutils.py +++ /dev/null @@ -1,173 +0,0 @@ -"""Locations where we look for configs, install stuff, etc""" - -# The following comment should be removed at some point in the future. -# mypy: strict-optional=False - -# If pip's going to use distutils, it should not be using the copy that setuptools -# might have injected into the environment. This is done by removing the injected -# shim, if it's injected. -# -# See https://github.com/pypa/pip/issues/8761 for the original discussion and -# rationale for why this is done within pip. -from __future__ import annotations - -try: - __import__("_distutils_hack").remove_shim() -except (ImportError, AttributeError): - pass - -import logging -import os -import sys -from distutils.cmd import Command as DistutilsCommand -from distutils.command.install import SCHEME_KEYS -from distutils.command.install import install as distutils_install_command -from distutils.sysconfig import get_python_lib - -from pip._internal.models.scheme import Scheme -from pip._internal.utils.compat import WINDOWS -from pip._internal.utils.virtualenv import running_under_virtualenv - -from .base import get_major_minor_version - -logger = logging.getLogger(__name__) - - -def distutils_scheme( - dist_name: str, - user: bool = False, - home: str | None = None, - root: str | None = None, - isolated: bool = False, - prefix: str | None = None, - *, - ignore_config_files: bool = False, -) -> dict[str, str]: - """ - Return a distutils install scheme - """ - from distutils.dist import Distribution - - dist_args: dict[str, str | list[str]] = {"name": dist_name} - if isolated: - dist_args["script_args"] = ["--no-user-cfg"] - - d = Distribution(dist_args) - if not ignore_config_files: - try: - d.parse_config_files() - except UnicodeDecodeError: - paths = d.find_config_files() - logger.warning( - "Ignore distutils configs in %s due to encoding errors.", - ", ".join(os.path.basename(p) for p in paths), - ) - obj: DistutilsCommand | None = None - obj = d.get_command_obj("install", create=True) - assert obj is not None - i: distutils_install_command = obj - # NOTE: setting user or home has the side-effect of creating the home dir - # or user base for installations during finalize_options() - # ideally, we'd prefer a scheme class that has no side-effects. - assert not (user and prefix), f"user={user} prefix={prefix}" - assert not (home and prefix), f"home={home} prefix={prefix}" - i.user = user or i.user - if user or home: - i.prefix = "" - i.prefix = prefix or i.prefix - i.home = home or i.home - i.root = root or i.root - i.finalize_options() - - scheme: dict[str, str] = {} - 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({"purelib": i.install_lib, "platlib": i.install_lib}) - - if running_under_virtualenv(): - if home: - prefix = home - elif user: - prefix = i.install_userbase - else: - prefix = i.prefix - scheme["headers"] = os.path.join( - prefix, - "include", - "site", - f"python{get_major_minor_version()}", - 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 - - -def get_scheme( - dist_name: str, - user: bool = False, - home: str | None = None, - root: str | None = None, - isolated: bool = False, - prefix: str | None = None, -) -> Scheme: - """ - Get the "scheme" corresponding to the input parameters. The distutils - documentation provides the context for the available schemes: - https://docs.python.org/3/install/index.html#alternate-installation - - :param dist_name: the name of the package to retrieve the scheme for, used - in the headers scheme path - :param user: indicates to use the "user" scheme - :param home: indicates to use the "home" scheme and provides the base - directory for the same - :param root: root under which other directories are re-based - :param isolated: equivalent to --no-user-cfg, i.e. do not consider - ~/.pydistutils.cfg (posix) or ~/pydistutils.cfg (non-posix) for - scheme paths - :param prefix: indicates to use the "prefix" scheme and provides the - base directory for the same - """ - scheme = distutils_scheme(dist_name, user, home, root, isolated, prefix) - return Scheme( - platlib=scheme["platlib"], - purelib=scheme["purelib"], - headers=scheme["headers"], - scripts=scheme["scripts"], - data=scheme["data"], - ) - - -def get_bin_prefix() -> str: - # XXX: In old virtualenv versions, sys.prefix can contain '..' components, - # so we need to call normpath to eliminate them. - prefix = os.path.normpath(sys.prefix) - if WINDOWS: - bin_py = os.path.join(prefix, "Scripts") - # buildout uses 'bin' on Windows too? - if not os.path.exists(bin_py): - bin_py = os.path.join(prefix, "bin") - return bin_py - # 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 prefix[:16] == "/System/Library/": - return "/usr/local/bin" - return os.path.join(prefix, "bin") - - -def get_purelib() -> str: - return get_python_lib(plat_specific=False) - - -def get_platlib() -> str: - return get_python_lib(plat_specific=True) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/locations/_sysconfig.py b/venv/lib/python3.11/site-packages/pip/_internal/locations/_sysconfig.py deleted file mode 100755 index 129dd11..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/locations/_sysconfig.py +++ /dev/null @@ -1,218 +0,0 @@ -from __future__ import annotations - -import logging -import os -import sys -import sysconfig -from collections.abc import Callable - -from pip._internal.exceptions import InvalidSchemeCombination, UserInstallationInvalid -from pip._internal.models.scheme import SCHEME_KEYS, Scheme -from pip._internal.utils.virtualenv import running_under_virtualenv - -from .base import change_root, get_major_minor_version, is_osx_framework - -logger = logging.getLogger(__name__) - - -# Notes on _infer_* functions. -# Unfortunately ``get_default_scheme()`` didn't exist before 3.10, so there's no -# way to ask things like "what is the '_prefix' scheme on this platform". These -# functions try to answer that with some heuristics while accounting for ad-hoc -# platforms not covered by CPython's default sysconfig implementation. If the -# ad-hoc implementation does not fully implement sysconfig, we'll fall back to -# a POSIX scheme. - -_AVAILABLE_SCHEMES = set(sysconfig.get_scheme_names()) - -_PREFERRED_SCHEME_API: Callable[[str], str] | None = getattr( - sysconfig, "get_preferred_scheme", None -) - - -def _should_use_osx_framework_prefix() -> bool: - """Check for Apple's ``osx_framework_library`` scheme. - - Python distributed by Apple's Command Line Tools has this special scheme - that's used when: - - * This is a framework build. - * We are installing into the system prefix. - - This does not account for ``pip install --prefix`` (also means we're not - installing to the system prefix), which should use ``posix_prefix``, but - logic here means ``_infer_prefix()`` outputs ``osx_framework_library``. But - since ``prefix`` is not available for ``sysconfig.get_default_scheme()``, - which is the stdlib replacement for ``_infer_prefix()``, presumably Apple - wouldn't be able to magically switch between ``osx_framework_library`` and - ``posix_prefix``. ``_infer_prefix()`` returning ``osx_framework_library`` - means its behavior is consistent whether we use the stdlib implementation - or our own, and we deal with this special case in ``get_scheme()`` instead. - """ - return ( - "osx_framework_library" in _AVAILABLE_SCHEMES - and not running_under_virtualenv() - and is_osx_framework() - ) - - -def _infer_prefix() -> str: - """Try to find a prefix scheme for the current platform. - - This tries: - - * A special ``osx_framework_library`` for Python distributed by Apple's - Command Line Tools, when not running in a virtual environment. - * Implementation + OS, used by PyPy on Windows (``pypy_nt``). - * Implementation without OS, used by PyPy on POSIX (``pypy``). - * OS + "prefix", used by CPython on POSIX (``posix_prefix``). - * Just the OS name, used by CPython on Windows (``nt``). - - If none of the above works, fall back to ``posix_prefix``. - """ - if _PREFERRED_SCHEME_API: - return _PREFERRED_SCHEME_API("prefix") - if _should_use_osx_framework_prefix(): - return "osx_framework_library" - implementation_suffixed = f"{sys.implementation.name}_{os.name}" - if implementation_suffixed in _AVAILABLE_SCHEMES: - return implementation_suffixed - if sys.implementation.name in _AVAILABLE_SCHEMES: - return sys.implementation.name - suffixed = f"{os.name}_prefix" - if suffixed in _AVAILABLE_SCHEMES: - return suffixed - if os.name in _AVAILABLE_SCHEMES: # On Windows, prefx is just called "nt". - return os.name - return "posix_prefix" - - -def _infer_user() -> str: - """Try to find a user scheme for the current platform.""" - if _PREFERRED_SCHEME_API: - return _PREFERRED_SCHEME_API("user") - if is_osx_framework() and not running_under_virtualenv(): - suffixed = "osx_framework_user" - else: - suffixed = f"{os.name}_user" - if suffixed in _AVAILABLE_SCHEMES: - return suffixed - if "posix_user" not in _AVAILABLE_SCHEMES: # User scheme unavailable. - raise UserInstallationInvalid() - return "posix_user" - - -def _infer_home() -> str: - """Try to find a home for the current platform.""" - if _PREFERRED_SCHEME_API: - return _PREFERRED_SCHEME_API("home") - suffixed = f"{os.name}_home" - if suffixed in _AVAILABLE_SCHEMES: - return suffixed - return "posix_home" - - -# Update these keys if the user sets a custom home. -_HOME_KEYS = [ - "installed_base", - "base", - "installed_platbase", - "platbase", - "prefix", - "exec_prefix", -] -if sysconfig.get_config_var("userbase") is not None: - _HOME_KEYS.append("userbase") - - -def get_scheme( - dist_name: str, - user: bool = False, - home: str | None = None, - root: str | None = None, - isolated: bool = False, - prefix: str | None = None, -) -> Scheme: - """ - Get the "scheme" corresponding to the input parameters. - - :param dist_name: the name of the package to retrieve the scheme for, used - in the headers scheme path - :param user: indicates to use the "user" scheme - :param home: indicates to use the "home" scheme - :param root: root under which other directories are re-based - :param isolated: ignored, but kept for distutils compatibility (where - this controls whether the user-site pydistutils.cfg is honored) - :param prefix: indicates to use the "prefix" scheme and provides the - base directory for the same - """ - if user and prefix: - raise InvalidSchemeCombination("--user", "--prefix") - if home and prefix: - raise InvalidSchemeCombination("--home", "--prefix") - - if home is not None: - scheme_name = _infer_home() - elif user: - scheme_name = _infer_user() - else: - scheme_name = _infer_prefix() - - # Special case: When installing into a custom prefix, use posix_prefix - # instead of osx_framework_library. See _should_use_osx_framework_prefix() - # docstring for details. - if prefix is not None and scheme_name == "osx_framework_library": - scheme_name = "posix_prefix" - - if home is not None: - variables = {k: home for k in _HOME_KEYS} - elif prefix is not None: - variables = {k: prefix for k in _HOME_KEYS} - else: - variables = {} - - paths = sysconfig.get_paths(scheme=scheme_name, vars=variables) - - # Logic here is very arbitrary, we're doing it for compatibility, don't ask. - # 1. Pip historically uses a special header path in virtual environments. - # 2. If the distribution name is not known, distutils uses 'UNKNOWN'. We - # only do the same when not running in a virtual environment because - # pip's historical header path logic (see point 1) did not do this. - if running_under_virtualenv(): - if user: - base = variables.get("userbase", sys.prefix) - else: - base = variables.get("base", sys.prefix) - python_xy = f"python{get_major_minor_version()}" - paths["include"] = os.path.join(base, "include", "site", python_xy) - elif not dist_name: - dist_name = "UNKNOWN" - - scheme = Scheme( - platlib=paths["platlib"], - purelib=paths["purelib"], - headers=os.path.join(paths["include"], dist_name), - scripts=paths["scripts"], - data=paths["data"], - ) - if root is not None: - converted_keys = {} - for key in SCHEME_KEYS: - converted_keys[key] = change_root(root, getattr(scheme, key)) - scheme = Scheme(**converted_keys) - return scheme - - -def get_bin_prefix() -> str: - # Forcing to use /usr/local/bin for standard macOS framework installs. - if sys.platform[:6] == "darwin" and sys.prefix[:16] == "/System/Library/": - return "/usr/local/bin" - return sysconfig.get_paths()["scripts"] - - -def get_purelib() -> str: - return sysconfig.get_paths()["purelib"] - - -def get_platlib() -> str: - return sysconfig.get_paths()["platlib"] diff --git a/venv/lib/python3.11/site-packages/pip/_internal/locations/base.py b/venv/lib/python3.11/site-packages/pip/_internal/locations/base.py deleted file mode 100755 index f8d13cd..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/locations/base.py +++ /dev/null @@ -1,82 +0,0 @@ -from __future__ import annotations - -import functools -import os -import site -import sys -import sysconfig - -from pip._internal.exceptions import InstallationError -from pip._internal.utils import appdirs -from pip._internal.utils.virtualenv import running_under_virtualenv - -# Application Directories -USER_CACHE_DIR = appdirs.user_cache_dir("pip") - -# FIXME doesn't account for venv linked to global site-packages -site_packages: str = sysconfig.get_path("purelib") - - -def get_major_minor_version() -> str: - """ - Return the major-minor version of the current Python as a string, e.g. - "3.7" or "3.10". - """ - return "{}.{}".format(*sys.version_info) - - -def change_root(new_root: str, pathname: str) -> str: - """Return 'pathname' with 'new_root' prepended. - - If 'pathname' is relative, this is equivalent to os.path.join(new_root, pathname). - Otherwise, it requires making 'pathname' relative and then joining the - two, which is tricky on DOS/Windows and Mac OS. - - This is borrowed from Python's standard library's distutils module. - """ - if os.name == "posix": - if not os.path.isabs(pathname): - return os.path.join(new_root, pathname) - else: - return os.path.join(new_root, pathname[1:]) - - elif os.name == "nt": - drive, path = os.path.splitdrive(pathname) - if path[0] == "\\": - path = path[1:] - return os.path.join(new_root, path) - - else: - raise InstallationError( - f"Unknown platform: {os.name}\n" - "Can not change root path prefix on unknown platform." - ) - - -def get_src_prefix() -> str: - 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/.. - return os.path.abspath(src_prefix) - - -try: - # Use getusersitepackages if this is present, as it ensures that the - # value is initialised properly. - user_site: str | None = site.getusersitepackages() -except AttributeError: - user_site = site.USER_SITE - - -@functools.cache -def is_osx_framework() -> bool: - return bool(sysconfig.get_config_var("PYTHONFRAMEWORK")) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/main.py b/venv/lib/python3.11/site-packages/pip/_internal/main.py deleted file mode 100755 index ec52c4e..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/main.py +++ /dev/null @@ -1,12 +0,0 @@ -from __future__ import annotations - - -def main(args: list[str] | None = None) -> int: - """This is preserved for old console scripts that may still be referencing - it. - - For additional details, see https://github.com/pypa/pip/issues/7498. - """ - from pip._internal.utils.entrypoints import _wrapper - - return _wrapper(args) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/metadata/__init__.py b/venv/lib/python3.11/site-packages/pip/_internal/metadata/__init__.py deleted file mode 100755 index 1c24efc..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/metadata/__init__.py +++ /dev/null @@ -1,169 +0,0 @@ -from __future__ import annotations - -import contextlib -import functools -import os -import sys -from typing import TYPE_CHECKING, Literal, Protocol, cast - -from pip._internal.utils.deprecation import deprecated -from pip._internal.utils.misc import strtobool - -from .base import BaseDistribution, BaseEnvironment, FilesystemWheel, MemoryWheel, Wheel - -if TYPE_CHECKING: - from pip._vendor.packaging.utils import NormalizedName - -__all__ = [ - "BaseDistribution", - "BaseEnvironment", - "FilesystemWheel", - "MemoryWheel", - "Wheel", - "get_default_environment", - "get_environment", - "get_wheel_distribution", - "select_backend", -] - - -def _should_use_importlib_metadata() -> bool: - """Whether to use the ``importlib.metadata`` or ``pkg_resources`` backend. - - By default, pip uses ``importlib.metadata`` on Python 3.11+, and - ``pkg_resources`` otherwise. Up to Python 3.13, This can be - overridden by a couple of ways: - - * If environment variable ``_PIP_USE_IMPORTLIB_METADATA`` is set, it - dictates whether ``importlib.metadata`` is used, for Python <3.14. - * On Python 3.11, 3.12 and 3.13, Python distributors can patch - ``importlib.metadata`` to add a global constant - ``_PIP_USE_IMPORTLIB_METADATA = False``. This makes pip use - ``pkg_resources`` (unless the user set the aforementioned environment - variable to *True*). - - On Python 3.14+, the ``pkg_resources`` backend cannot be used. - """ - if sys.version_info >= (3, 14): - # On Python >=3.14 we only support importlib.metadata. - return True - with contextlib.suppress(KeyError, ValueError): - # On Python <3.14, if the environment variable is set, we obey what it says. - return bool(strtobool(os.environ["_PIP_USE_IMPORTLIB_METADATA"])) - if sys.version_info < (3, 11): - # On Python <3.11, we always use pkg_resources, unless the environment - # variable was set. - return False - # On Python 3.11, 3.12 and 3.13, we check if the global constant is set. - import importlib.metadata - - return bool(getattr(importlib.metadata, "_PIP_USE_IMPORTLIB_METADATA", True)) - - -def _emit_pkg_resources_deprecation_if_needed() -> None: - if sys.version_info < (3, 11): - # All pip versions supporting Python<=3.11 will support pkg_resources, - # and pkg_resources is the default for these, so let's not bother users. - return - - import importlib.metadata - - if hasattr(importlib.metadata, "_PIP_USE_IMPORTLIB_METADATA"): - # The Python distributor has set the global constant, so we don't - # warn, since it is not a user decision. - return - - # The user has decided to use pkg_resources, so we warn. - deprecated( - reason="Using the pkg_resources metadata backend is deprecated.", - replacement=( - "to use the default importlib.metadata backend, " - "by unsetting the _PIP_USE_IMPORTLIB_METADATA environment variable" - ), - gone_in="26.3", - issue=13317, - ) - - -class Backend(Protocol): - NAME: Literal["importlib", "pkg_resources"] - Distribution: type[BaseDistribution] - Environment: type[BaseEnvironment] - - -@functools.cache -def select_backend() -> Backend: - if _should_use_importlib_metadata(): - from . import importlib - - return cast(Backend, importlib) - - _emit_pkg_resources_deprecation_if_needed() - - from . import pkg_resources - - return cast(Backend, pkg_resources) - - -def get_default_environment() -> BaseEnvironment: - """Get the default representation for the current environment. - - This returns an Environment instance from the chosen backend. The default - Environment instance should be built from ``sys.path`` and may use caching - to share instance state across calls. - """ - return select_backend().Environment.default() - - -def get_environment(paths: list[str] | None) -> BaseEnvironment: - """Get a representation of the environment specified by ``paths``. - - This returns an Environment instance from the chosen backend based on the - given import paths. The backend must build a fresh instance representing - the state of installed distributions when this function is called. - """ - return select_backend().Environment.from_paths(paths) - - -def get_directory_distribution(directory: str) -> BaseDistribution: - """Get the distribution metadata representation in the specified directory. - - This returns a Distribution instance from the chosen backend based on - the given on-disk ``.dist-info`` directory. - """ - return select_backend().Distribution.from_directory(directory) - - -def get_wheel_distribution( - wheel: Wheel, canonical_name: NormalizedName -) -> BaseDistribution: - """Get the representation of the specified wheel's distribution metadata. - - This returns a Distribution instance from the chosen backend based on - the given wheel's ``.dist-info`` directory. - - :param canonical_name: Normalized project name of the given wheel. - """ - return select_backend().Distribution.from_wheel(wheel, canonical_name) - - -def get_metadata_distribution( - metadata_contents: bytes, - filename: str, - canonical_name: str, -) -> BaseDistribution: - """Get the dist representation of the specified METADATA file contents. - - This returns a Distribution instance from the chosen backend sourced from the data - in `metadata_contents`. - - :param metadata_contents: Contents of a METADATA file within a dist, or one served - via PEP 658. - :param filename: Filename for the dist this metadata represents. - :param canonical_name: Normalized project name of the given dist. - """ - return select_backend().Distribution.from_metadata_file_contents( - metadata_contents, - filename, - canonical_name, - ) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/metadata/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/metadata/__pycache__/__init__.cpython-311.pyc deleted file mode 100755 index 9eb060e03beb128ad27e0bae2de58e8aeb11d6d5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7442 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 U2vY9`i<{o3(4SU`VqD<=0leWkTL1t6 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/metadata/__pycache__/pkg_resources.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/metadata/__pycache__/pkg_resources.cpython-311.pyc deleted file mode 100755 index 4dcb688fbfa1a0bf2b6fd09f5f355d53c1445b66..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18054 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

70UAc+ z2#1nN|G`0q;~c25P0-6YJHV^jF$B`61|HiW?v1Z&u|CGxxyf}pz__OaOz(W-n_BEn zn%;rwIxx~PB23f$n63jO9V2$r`dJ4Y!sx)LA0wPJopCsK_@H~J?W&m-f>a>c%yR-+JXa;_} z1GgSc&>O_zvVwh1$6lPmCg5Wod$5X@K%*WsQO&@gaRFDui+%DffF>8yfZ<{q6kEBN z+Qlx>-Qa;|X8E-oc@?y{iy($5 zzc>hZ7E2&dxW<5kw3*fqTMTb%_!7;QxP=xj6slw$fZ2wpxlIO5A9)#Glm81*k?Wwf zstdd(`6B$ZG3$e9iw1yW27m06eGs_M;0bshLi$y=7FpF3-P*&|Jo;~Golb!81%8x+ z>}E?`nOJB_Fa2NmI9nLkK-yVXZ^Q?#j~Wyvfwt&-dh#SP-zoq#~I zZ3%2b0q`@$8LnN89j{qXf_0+fhzhtGPyRZDEZqzws91-cim`>03p>pHZGqs#jw1=z zOd7$^y|b{eUBeU`Xly5+YC(bMdq#_Pr+hb;Xj^9!9Fu--R@?R`I#HQ z8t6uNdKx!>)6=*a#f`C4|6H^7Z65CT==XWD1Rp`((7)o_181IlECqw(!%f(K;^($4 zO4|n??im|u+5}qPRq00ZW(q!+%3TXjPg_|SZnVv_44dug`UZOn6lgR%sNIwtpg9&~ znW_Z3WtYwy)e$a2mYQ3Mu3iU$UtrfP`3qqSMYX_iBS~F=;$TbbW%~B6PE>mLE4}-R z9pFB)9voW>j#Yx=N)Y58=jx}RcnTC}&?igTHDRJGOuzDHhx+A5u6 zJIJr03v`*QZM7|t#>6e>aJs=>-z?F2q*DkZ!T@DzCQe@?slcasCPHpZ?Z%n=HWWY| z6xM~^Yxsp$MHp3tQ83nf1Y`;!IAbY(Witq;@t~)`LHyZuZ~vMX4go9PsN#*5=?(S> zborne>HxB?Osq^G_XvSS0VdX3Ntqv|A4UGS?=bV{!X$hb$Fl%&OMw!WR1p|rTUXmr zY61rGee$0T3>sTg%Kt{gpraHuF#apXx?5@84{wFDaD#snPUbARa0;^x#DMa%})#DZyHac#D5d`wsxe$=?DB zazz=n3s|ZwTV-~rcmi4>J1j_ndWjdDWugbWV>CY7Ne3|(>Zupdh<$$uE0(geq zS!RaKca=F>w%%3dT)EXTkl8A%jKuvRpwOLdRLjra;v+_e5Ks#-n2Wh zYyYpn$9N8u-Q#dCw>@(86?+s{--Bl>t|7%WwCsG;*1c@sblO;8*Uez1?=i-HT2JzZ zS@=@089c_gPwNS1*y|h%8@|@C92k5|lRh;gTypGZf%`Orm9fVd`)P|L%9#ESh|@Ln diff --git a/venv/lib/python3.11/site-packages/pip/_internal/metadata/_json.py b/venv/lib/python3.11/site-packages/pip/_internal/metadata/_json.py deleted file mode 100755 index b39ac05..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/metadata/_json.py +++ /dev/null @@ -1,87 +0,0 @@ -# Extracted from https://github.com/pfmoore/pkg_metadata -from __future__ import annotations - -from email.header import Header, decode_header, make_header -from email.message import Message -from typing import Any, cast - -METADATA_FIELDS = [ - # Name, Multiple-Use - ("Metadata-Version", False), - ("Name", False), - ("Version", False), - ("Dynamic", True), - ("Platform", True), - ("Supported-Platform", True), - ("Summary", False), - ("Description", False), - ("Description-Content-Type", False), - ("Keywords", False), - ("Home-page", False), - ("Download-URL", False), - ("Author", False), - ("Author-email", False), - ("Maintainer", False), - ("Maintainer-email", False), - ("License", False), - ("License-Expression", False), - ("License-File", True), - ("Classifier", True), - ("Requires-Dist", True), - ("Requires-Python", False), - ("Requires-External", True), - ("Project-URL", True), - ("Provides-Extra", True), - ("Provides-Dist", True), - ("Obsoletes-Dist", True), -] - - -def json_name(field: str) -> str: - return field.lower().replace("-", "_") - - -def msg_to_json(msg: Message) -> dict[str, Any]: - """Convert a Message object into a JSON-compatible dictionary.""" - - def sanitise_header(h: Header | str) -> str: - if isinstance(h, Header): - chunks = [] - for bytes, encoding in decode_header(h): - if encoding == "unknown-8bit": - try: - # See if UTF-8 works - bytes.decode("utf-8") - encoding = "utf-8" - except UnicodeDecodeError: - # If not, latin1 at least won't fail - encoding = "latin1" - chunks.append((bytes, encoding)) - return str(make_header(chunks)) - return str(h) - - result = {} - for field, multi in METADATA_FIELDS: - if field not in msg: - continue - key = json_name(field) - if multi: - value: str | list[str] = [ - sanitise_header(v) for v in msg.get_all(field) # type: ignore - ] - else: - value = sanitise_header(msg.get(field)) # type: ignore - if key == "keywords": - # Accept both comma-separated and space-separated - # forms, for better compatibility with old data. - if "," in value: - value = [v.strip() for v in value.split(",")] - else: - value = value.split() - result[key] = value - - payload = cast(str, msg.get_payload()) - if payload: - result["description"] = payload - - return result diff --git a/venv/lib/python3.11/site-packages/pip/_internal/metadata/base.py b/venv/lib/python3.11/site-packages/pip/_internal/metadata/base.py deleted file mode 100755 index 76fb963..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/metadata/base.py +++ /dev/null @@ -1,690 +0,0 @@ -from __future__ import annotations - -import csv -import email.message -import functools -import json -import logging -import pathlib -import re -import zipfile -from collections.abc import Collection, Container, Iterable, Iterator -from typing import ( - IO, - Any, - NamedTuple, - Protocol, -) - -from pip._vendor.packaging.requirements import Requirement -from pip._vendor.packaging.specifiers import InvalidSpecifier, SpecifierSet -from pip._vendor.packaging.utils import NormalizedName, canonicalize_name -from pip._vendor.packaging.version import Version - -from pip._internal.exceptions import NoneMetadataError -from pip._internal.locations import site_packages, user_site -from pip._internal.models.direct_url import ( - DIRECT_URL_METADATA_NAME, - DirectUrl, - DirectUrlValidationError, -) -from pip._internal.utils.egg_link import egg_link_path_from_sys_path -from pip._internal.utils.misc import is_local, normalize_path -from pip._internal.utils.urls import url_to_path - -from ._json import msg_to_json - -# 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"} - - -InfoPath = str | pathlib.PurePath - -logger = logging.getLogger(__name__) - - -class BaseEntryPoint(Protocol): - @property - def name(self) -> str: - raise NotImplementedError() - - @property - def value(self) -> str: - raise NotImplementedError() - - @property - def group(self) -> str: - raise NotImplementedError() - - -def _convert_installed_files_path( - entry: tuple[str, ...], - info: tuple[str, ...], -) -> str: - """Convert a legacy installed-files.txt path into modern RECORD path. - - The legacy format stores paths relative to the info directory, while the - modern format stores paths relative to the package root, e.g. the - site-packages directory. - - :param entry: Path parts of the installed-files.txt entry. - :param info: Path parts of the egg-info directory relative to package root. - :returns: The converted entry. - - For best compatibility with symlinks, this does not use ``abspath()`` or - ``Path.resolve()``, but tries to work with path parts: - - 1. While ``entry`` starts with ``..``, remove the equal amounts of parts - from ``info``; if ``info`` is empty, start appending ``..`` instead. - 2. Join the two directly. - """ - while entry and entry[0] == "..": - if not info or info[-1] == "..": - info += ("..",) - else: - info = info[:-1] - entry = entry[1:] - return str(pathlib.Path(*info, *entry)) - - -class RequiresEntry(NamedTuple): - requirement: str - extra: str - marker: str - - -class BaseDistribution(Protocol): - @classmethod - def from_directory(cls, directory: str) -> BaseDistribution: - """Load the distribution from a metadata directory. - - :param directory: Path to a metadata directory, e.g. ``.dist-info``. - """ - raise NotImplementedError() - - @classmethod - def from_metadata_file_contents( - cls, - metadata_contents: bytes, - filename: str, - project_name: str, - ) -> BaseDistribution: - """Load the distribution from the contents of a METADATA file. - - This is used to implement PEP 658 by generating a "shallow" dist object that can - be used for resolution without downloading or building the actual dist yet. - - :param metadata_contents: The contents of a METADATA file. - :param filename: File name for the dist with this metadata. - :param project_name: Name of the project this dist represents. - """ - raise NotImplementedError() - - @classmethod - def from_wheel(cls, wheel: Wheel, name: str) -> BaseDistribution: - """Load the distribution from a given wheel. - - :param wheel: A concrete wheel definition. - :param name: File name of the wheel. - - :raises InvalidWheel: Whenever loading of the wheel causes a - :py:exc:`zipfile.BadZipFile` exception to be thrown. - :raises UnsupportedWheel: If the wheel is a valid zip, but malformed - internally. - """ - raise NotImplementedError() - - def __repr__(self) -> str: - return f"{self.raw_name} {self.raw_version} ({self.location})" - - def __str__(self) -> str: - return f"{self.raw_name} {self.raw_version}" - - @property - def location(self) -> str | None: - """Where the distribution is loaded from. - - A string value is not necessarily a filesystem path, since distributions - can be loaded from other sources, e.g. arbitrary zip archives. ``None`` - means the distribution is created in-memory. - - Do not canonicalize this value with e.g. ``pathlib.Path.resolve()``. If - this is a symbolic link, we want to preserve the relative path between - it and files in the distribution. - """ - raise NotImplementedError() - - @functools.cached_property - def editable_project_location(self) -> str | None: - """The project location for editable distributions. - - This is the directory where pyproject.toml or setup.py is located. - None if the distribution is not installed in editable mode. - """ - direct_url = self.direct_url - if direct_url: - if direct_url.is_local_editable(): - return url_to_path(direct_url.url) - else: - # Search for an .egg-link file by walking sys.path, as it was - # done before by dist_is_editable(). - egg_link_path = egg_link_path_from_sys_path(self.raw_name) - if egg_link_path: - # TODO: get project location from second line of egg_link file - # (https://github.com/pypa/pip/issues/10243) - return self.location - return None - - @property - def installed_location(self) -> str | None: - """The distribution's "installed" location. - - This should generally be a ``site-packages`` directory. This is - usually ``dist.location``, except for legacy develop-installed packages, - where ``dist.location`` is the source code location, and this is where - the ``.egg-link`` file is. - - The returned location is normalized (in particular, with symlinks removed). - """ - raise NotImplementedError() - - @property - def info_location(self) -> str | None: - """Location of the .[egg|dist]-info directory or file. - - Similarly to ``location``, a string value is not necessarily a - filesystem path. ``None`` means the distribution is created in-memory. - - For a modern .dist-info installation on disk, this should be something - like ``{location}/{raw_name}-{version}.dist-info``. - - Do not canonicalize this value with e.g. ``pathlib.Path.resolve()``. If - this is a symbolic link, we want to preserve the relative path between - it and other files in the distribution. - """ - raise NotImplementedError() - - @property - def installed_by_distutils(self) -> bool: - """Whether this distribution is installed with legacy distutils format. - - A distribution installed with "raw" distutils not patched by setuptools - uses one single file at ``info_location`` to store metadata. We need to - treat this specially on uninstallation. - """ - info_location = self.info_location - if not info_location: - return False - return pathlib.Path(info_location).is_file() - - @property - def installed_as_egg(self) -> bool: - """Whether this distribution is installed as an egg. - - This usually indicates the distribution was installed by (older versions - of) easy_install. - """ - location = self.location - if not location: - return False - # XXX if the distribution is a zipped egg, location has a trailing / - # so we resort to pathlib.Path to check the suffix in a reliable way. - return pathlib.Path(location).suffix == ".egg" - - @property - def installed_with_setuptools_egg_info(self) -> bool: - """Whether this distribution is installed with the ``.egg-info`` format. - - This usually indicates the distribution was installed with setuptools - with an old pip version or with ``single-version-externally-managed``. - - Note that this ensure the metadata store is a directory. distutils can - also installs an ``.egg-info``, but as a file, not a directory. This - property is *False* for that case. Also see ``installed_by_distutils``. - """ - info_location = self.info_location - if not info_location: - return False - if not info_location.endswith(".egg-info"): - return False - return pathlib.Path(info_location).is_dir() - - @property - def installed_with_dist_info(self) -> bool: - """Whether this distribution is installed with the "modern format". - - This indicates a "modern" installation, e.g. storing metadata in the - ``.dist-info`` directory. This applies to installations made by - setuptools (but through pip, not directly), or anything using the - standardized build backend interface (PEP 517). - """ - info_location = self.info_location - if not info_location: - return False - if not info_location.endswith(".dist-info"): - return False - return pathlib.Path(info_location).is_dir() - - @property - def canonical_name(self) -> NormalizedName: - raise NotImplementedError() - - @property - def version(self) -> Version: - raise NotImplementedError() - - @property - def raw_version(self) -> str: - raise NotImplementedError() - - @property - def setuptools_filename(self) -> str: - """Convert a project name to its setuptools-compatible filename. - - This is a copy of ``pkg_resources.to_filename()`` for compatibility. - """ - return self.raw_name.replace("-", "_") - - @property - def direct_url(self) -> DirectUrl | None: - """Obtain a DirectUrl from this distribution. - - Returns None if the distribution has no `direct_url.json` metadata, - or if `direct_url.json` is invalid. - """ - try: - content = self.read_text(DIRECT_URL_METADATA_NAME) - except FileNotFoundError: - return None - try: - return DirectUrl.from_json(content) - except ( - UnicodeDecodeError, - json.JSONDecodeError, - DirectUrlValidationError, - ) as e: - logger.warning( - "Error parsing %s for %s: %s", - DIRECT_URL_METADATA_NAME, - self.canonical_name, - e, - ) - return None - - @property - def installer(self) -> str: - try: - installer_text = self.read_text("INSTALLER") - except (OSError, ValueError, NoneMetadataError): - return "" # Fail silently if the installer file cannot be read. - for line in installer_text.splitlines(): - cleaned_line = line.strip() - if cleaned_line: - return cleaned_line - return "" - - @property - def requested(self) -> bool: - return self.is_file("REQUESTED") - - @property - def editable(self) -> bool: - return bool(self.editable_project_location) - - @property - def local(self) -> bool: - """If distribution is installed in the current virtual environment. - - Always True if we're not in a virtualenv. - """ - if self.installed_location is None: - return False - return is_local(self.installed_location) - - @property - def in_usersite(self) -> bool: - if self.installed_location is None or user_site is None: - return False - return self.installed_location.startswith(normalize_path(user_site)) - - @property - def in_site_packages(self) -> bool: - if self.installed_location is None or site_packages is None: - return False - return self.installed_location.startswith(normalize_path(site_packages)) - - def is_file(self, path: InfoPath) -> bool: - """Check whether an entry in the info directory is a file.""" - raise NotImplementedError() - - def iter_distutils_script_names(self) -> Iterator[str]: - """Find distutils 'scripts' entries metadata. - - If 'scripts' is supplied in ``setup.py``, distutils records those in the - installed distribution's ``scripts`` directory, a file for each script. - """ - raise NotImplementedError() - - def read_text(self, path: InfoPath) -> str: - """Read a file in the info directory. - - :raise FileNotFoundError: If ``path`` does not exist in the directory. - :raise NoneMetadataError: If ``path`` exists in the info directory, but - cannot be read. - """ - raise NotImplementedError() - - def iter_entry_points(self) -> Iterable[BaseEntryPoint]: - raise NotImplementedError() - - def _metadata_impl(self) -> email.message.Message: - raise NotImplementedError() - - @functools.cached_property - def metadata(self) -> email.message.Message: - """Metadata of distribution parsed from e.g. METADATA or PKG-INFO. - - This should return an empty message if the metadata file is unavailable. - - :raises NoneMetadataError: If the metadata file is available, but does - not contain valid metadata. - """ - metadata = self._metadata_impl() - self._add_egg_info_requires(metadata) - return metadata - - @property - def metadata_dict(self) -> dict[str, Any]: - """PEP 566 compliant JSON-serializable representation of METADATA or PKG-INFO. - - This should return an empty dict if the metadata file is unavailable. - - :raises NoneMetadataError: If the metadata file is available, but does - not contain valid metadata. - """ - return msg_to_json(self.metadata) - - @property - def metadata_version(self) -> str | None: - """Value of "Metadata-Version:" in distribution metadata, if available.""" - return self.metadata.get("Metadata-Version") - - @property - def raw_name(self) -> str: - """Value of "Name:" in distribution metadata.""" - # The metadata should NEVER be missing the Name: key, but if it somehow - # does, fall back to the known canonical name. - return self.metadata.get("Name", self.canonical_name) - - @property - def requires_python(self) -> SpecifierSet: - """Value of "Requires-Python:" in distribution metadata. - - If the key does not exist or contains an invalid value, an empty - SpecifierSet should be returned. - """ - value = self.metadata.get("Requires-Python") - if value is None: - return SpecifierSet() - try: - # Convert to str to satisfy the type checker; this can be a Header object. - spec = SpecifierSet(str(value)) - except InvalidSpecifier as e: - message = "Package %r has an invalid Requires-Python: %s" - logger.warning(message, self.raw_name, e) - return SpecifierSet() - return spec - - def iter_dependencies(self, extras: Collection[str] = ()) -> Iterable[Requirement]: - """Dependencies of this distribution. - - For modern .dist-info distributions, this is the collection of - "Requires-Dist:" entries in distribution metadata. - """ - raise NotImplementedError() - - def iter_raw_dependencies(self) -> Iterable[str]: - """Raw Requires-Dist metadata.""" - return self.metadata.get_all("Requires-Dist", []) - - def iter_provided_extras(self) -> Iterable[NormalizedName]: - """Extras provided by this distribution. - - For modern .dist-info distributions, this is the collection of - "Provides-Extra:" entries in distribution metadata. - - The return value of this function is expected to be normalised names, - per PEP 685, with the returned value being handled appropriately by - `iter_dependencies`. - """ - raise NotImplementedError() - - def _iter_declared_entries_from_record(self) -> Iterator[str] | None: - try: - text = self.read_text("RECORD") - except FileNotFoundError: - return None - # This extra Path-str cast normalizes entries. - return (str(pathlib.Path(row[0])) for row in csv.reader(text.splitlines())) - - def _iter_declared_entries_from_legacy(self) -> Iterator[str] | None: - try: - text = self.read_text("installed-files.txt") - except FileNotFoundError: - return None - paths = (p for p in text.splitlines(keepends=False) if p) - root = self.location - info = self.info_location - if root is None or info is None: - return paths - try: - info_rel = pathlib.Path(info).relative_to(root) - except ValueError: # info is not relative to root. - return paths - if not info_rel.parts: # info *is* root. - return paths - return ( - _convert_installed_files_path(pathlib.Path(p).parts, info_rel.parts) - for p in paths - ) - - def iter_declared_entries(self) -> Iterator[str] | None: - """Iterate through file entries declared in this distribution. - - For modern .dist-info distributions, this is the files listed in the - ``RECORD`` metadata file. For legacy setuptools distributions, this - comes from ``installed-files.txt``, with entries normalized to be - compatible with the format used by ``RECORD``. - - :return: An iterator for listed entries, or None if the distribution - contains neither ``RECORD`` nor ``installed-files.txt``. - """ - return ( - self._iter_declared_entries_from_record() - or self._iter_declared_entries_from_legacy() - ) - - def _iter_requires_txt_entries(self) -> Iterator[RequiresEntry]: - """Parse a ``requires.txt`` in an egg-info directory. - - This is an INI-ish format where an egg-info stores dependencies. A - section name describes extra other environment markers, while each entry - is an arbitrary string (not a key-value pair) representing a dependency - as a requirement string (no markers). - - There is a construct in ``importlib.metadata`` called ``Sectioned`` that - does mostly the same, but the format is currently considered private. - """ - try: - content = self.read_text("requires.txt") - except FileNotFoundError: - return - extra = marker = "" # Section-less entries don't have markers. - for line in content.splitlines(): - line = line.strip() - if not line or line.startswith("#"): # Comment; ignored. - continue - if line.startswith("[") and line.endswith("]"): # A section header. - extra, _, marker = line.strip("[]").partition(":") - continue - yield RequiresEntry(requirement=line, extra=extra, marker=marker) - - def _iter_egg_info_extras(self) -> Iterable[str]: - """Get extras from the egg-info directory.""" - known_extras = {""} - for entry in self._iter_requires_txt_entries(): - extra = canonicalize_name(entry.extra) - if extra in known_extras: - continue - known_extras.add(extra) - yield extra - - def _iter_egg_info_dependencies(self) -> Iterable[str]: - """Get distribution dependencies from the egg-info directory. - - To ease parsing, this converts a legacy dependency entry into a PEP 508 - requirement string. Like ``_iter_requires_txt_entries()``, there is code - in ``importlib.metadata`` that does mostly the same, but not do exactly - what we need. - - Namely, ``importlib.metadata`` does not normalize the extra name before - putting it into the requirement string, which causes marker comparison - to fail because the dist-info format do normalize. This is consistent in - all currently available PEP 517 backends, although not standardized. - """ - for entry in self._iter_requires_txt_entries(): - extra = canonicalize_name(entry.extra) - if extra and entry.marker: - marker = f'({entry.marker}) and extra == "{extra}"' - elif extra: - marker = f'extra == "{extra}"' - elif entry.marker: - marker = entry.marker - else: - marker = "" - if marker: - yield f"{entry.requirement} ; {marker}" - else: - yield entry.requirement - - def _add_egg_info_requires(self, metadata: email.message.Message) -> None: - """Add egg-info requires.txt information to the metadata.""" - if not metadata.get_all("Requires-Dist"): - for dep in self._iter_egg_info_dependencies(): - metadata["Requires-Dist"] = dep - if not metadata.get_all("Provides-Extra"): - for extra in self._iter_egg_info_extras(): - metadata["Provides-Extra"] = extra - - -class BaseEnvironment: - """An environment containing distributions to introspect.""" - - @classmethod - def default(cls) -> BaseEnvironment: - raise NotImplementedError() - - @classmethod - def from_paths(cls, paths: list[str] | None) -> BaseEnvironment: - raise NotImplementedError() - - def get_distribution(self, name: str) -> BaseDistribution | None: - """Given a requirement name, return the installed distributions. - - The name may not be normalized. The implementation must canonicalize - it for lookup. - """ - raise NotImplementedError() - - def _iter_distributions(self) -> Iterator[BaseDistribution]: - """Iterate through installed distributions. - - This function should be implemented by subclass, but never called - directly. Use the public ``iter_distribution()`` instead, which - implements additional logic to make sure the distributions are valid. - """ - raise NotImplementedError() - - def iter_all_distributions(self) -> Iterator[BaseDistribution]: - """Iterate through all installed distributions without any filtering.""" - for dist in self._iter_distributions(): - # Make sure the distribution actually comes from a valid Python - # packaging distribution. Pip's AdjacentTempDirectory leaves folders - # e.g. ``~atplotlib.dist-info`` if cleanup was interrupted. The - # valid project name pattern is taken from PEP 508. - project_name_valid = re.match( - r"^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$", - dist.canonical_name, - flags=re.IGNORECASE, - ) - if not project_name_valid: - logger.warning( - "Ignoring invalid distribution %s (%s)", - dist.canonical_name, - dist.location, - ) - continue - yield dist - - def iter_installed_distributions( - self, - local_only: bool = True, - skip: Container[str] = stdlib_pkgs, - include_editables: bool = True, - editables_only: bool = False, - user_only: bool = False, - ) -> Iterator[BaseDistribution]: - """Return a list of installed distributions. - - This is based on ``iter_all_distributions()`` with additional filtering - options. Note that ``iter_installed_distributions()`` without arguments - is *not* equal to ``iter_all_distributions()``, since some of the - configurations exclude packages by default. - - :param local_only: If True (default), only return installations - local to the current virtualenv, if in a virtualenv. - :param skip: An iterable of canonicalized project names to ignore; - defaults to ``stdlib_pkgs``. - :param include_editables: If False, don't report editables. - :param editables_only: If True, only report editables. - :param user_only: If True, only report installations in the user - site directory. - """ - it = self.iter_all_distributions() - if local_only: - it = (d for d in it if d.local) - if not include_editables: - it = (d for d in it if not d.editable) - if editables_only: - it = (d for d in it if d.editable) - if user_only: - it = (d for d in it if d.in_usersite) - return (d for d in it if d.canonical_name not in skip) - - -class Wheel(Protocol): - location: str - - def as_zipfile(self) -> zipfile.ZipFile: - raise NotImplementedError() - - -class FilesystemWheel(Wheel): - def __init__(self, location: str) -> None: - self.location = location - - def as_zipfile(self) -> zipfile.ZipFile: - return zipfile.ZipFile(self.location, allowZip64=True) - - -class MemoryWheel(Wheel): - def __init__(self, location: str, stream: IO[bytes]) -> None: - self.location = location - self.stream = stream - - def as_zipfile(self) -> zipfile.ZipFile: - return zipfile.ZipFile(self.stream, allowZip64=True) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/__init__.py b/venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/__init__.py deleted file mode 100755 index a779138..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -from ._dists import Distribution -from ._envs import Environment - -__all__ = ["NAME", "Distribution", "Environment"] - -NAME = "importlib" diff --git a/venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/__pycache__/__init__.cpython-311.pyc deleted file mode 100755 index 1b5a8ab6b1e24d2333b5fa4fefae3cd3c3b0f321..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 392 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 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/__pycache__/_envs.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/__pycache__/_envs.cpython-311.pyc deleted file mode 100755 index 24aad1af48fd0247abb24c7d75d4e4eec49a735b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9279 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 G>hr%Cy6MUQ diff --git a/venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/_compat.py b/venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/_compat.py deleted file mode 100755 index 7de614d..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/_compat.py +++ /dev/null @@ -1,87 +0,0 @@ -from __future__ import annotations - -import importlib.metadata -import os -from typing import Any, Protocol, cast - -from pip._vendor.packaging.utils import NormalizedName, canonicalize_name - - -class BadMetadata(ValueError): - def __init__(self, dist: importlib.metadata.Distribution, *, reason: str) -> None: - self.dist = dist - self.reason = reason - - def __str__(self) -> str: - return f"Bad metadata in {self.dist} ({self.reason})" - - -class BasePath(Protocol): - """A protocol that various path objects conform. - - This exists because importlib.metadata uses both ``pathlib.Path`` and - ``zipfile.Path``, and we need a common base for type hints (Union does not - work well since ``zipfile.Path`` is too new for our linter setup). - - This does not mean to be exhaustive, but only contains things that present - in both classes *that we need*. - """ - - @property - def name(self) -> str: - raise NotImplementedError() - - @property - def parent(self) -> BasePath: - raise NotImplementedError() - - -def get_info_location(d: importlib.metadata.Distribution) -> BasePath | None: - """Find the path to the distribution's metadata directory. - - HACK: This relies on importlib.metadata's private ``_path`` attribute. Not - all distributions exist on disk, so importlib.metadata is correct to not - expose the attribute as public. But pip's code base is old and not as clean, - so we do this to avoid having to rewrite too many things. Hopefully we can - eliminate this some day. - """ - return getattr(d, "_path", None) - - -def parse_name_and_version_from_info_directory( - dist: importlib.metadata.Distribution, -) -> tuple[str | None, str | None]: - """Get a name and version from the metadata directory name. - - This is much faster than reading distribution metadata. - """ - info_location = get_info_location(dist) - if info_location is None: - return None, None - - stem, suffix = os.path.splitext(info_location.name) - if suffix == ".dist-info": - name, sep, version = stem.partition("-") - if sep: - return name, version - - if suffix == ".egg-info": - name = stem.split("-", 1)[0] - return name, None - - return None, None - - -def get_dist_canonical_name(dist: importlib.metadata.Distribution) -> NormalizedName: - """Get the distribution's normalized name. - - The ``name`` attribute is only available in Python 3.10 or later. We are - targeting exactly that, but Mypy does not know this. - """ - if name := parse_name_and_version_from_info_directory(dist)[0]: - return canonicalize_name(name) - - name = cast(Any, dist).name - if not isinstance(name, str): - raise BadMetadata(dist, reason="invalid metadata entry 'name'") - return canonicalize_name(name) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/_dists.py b/venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/_dists.py deleted file mode 100755 index 98a3cd3..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/_dists.py +++ /dev/null @@ -1,235 +0,0 @@ -from __future__ import annotations - -import email.message -import importlib.metadata -import pathlib -import zipfile -from collections.abc import Collection, Iterable, Iterator, Mapping, Sequence -from os import PathLike -from typing import ( - cast, -) - -from pip._vendor.packaging.requirements import Requirement -from pip._vendor.packaging.utils import NormalizedName, canonicalize_name -from pip._vendor.packaging.version import Version -from pip._vendor.packaging.version import parse as parse_version - -from pip._internal.exceptions import InvalidWheel, UnsupportedWheel -from pip._internal.metadata.base import ( - BaseDistribution, - BaseEntryPoint, - InfoPath, - Wheel, -) -from pip._internal.utils.misc import normalize_path -from pip._internal.utils.packaging import get_requirement -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.utils.wheel import parse_wheel, read_wheel_metadata_file - -from ._compat import ( - BadMetadata, - BasePath, - get_dist_canonical_name, - parse_name_and_version_from_info_directory, -) - - -class WheelDistribution(importlib.metadata.Distribution): - """An ``importlib.metadata.Distribution`` read from a wheel. - - Although ``importlib.metadata.PathDistribution`` accepts ``zipfile.Path``, - its implementation is too "lazy" for pip's needs (we can't keep the ZipFile - handle open for the entire lifetime of the distribution object). - - This implementation eagerly reads the entire metadata directory into the - memory instead, and operates from that. - """ - - def __init__( - self, - files: Mapping[pathlib.PurePosixPath, bytes], - info_location: pathlib.PurePosixPath, - ) -> None: - self._files = files - self.info_location = info_location - - @classmethod - def from_zipfile( - cls, - zf: zipfile.ZipFile, - name: str, - location: str, - ) -> WheelDistribution: - info_dir, _ = parse_wheel(zf, name) - paths = ( - (name, pathlib.PurePosixPath(name.split("/", 1)[-1])) - for name in zf.namelist() - if name.startswith(f"{info_dir}/") - ) - files = { - relpath: read_wheel_metadata_file(zf, fullpath) - for fullpath, relpath in paths - } - info_location = pathlib.PurePosixPath(location, info_dir) - return cls(files, info_location) - - def iterdir(self, path: InfoPath) -> Iterator[pathlib.PurePosixPath]: - # Only allow iterating through the metadata directory. - if pathlib.PurePosixPath(str(path)) in self._files: - return iter(self._files) - raise FileNotFoundError(path) - - def read_text(self, filename: str) -> str | None: - try: - data = self._files[pathlib.PurePosixPath(filename)] - except KeyError: - return None - try: - text = data.decode("utf-8") - except UnicodeDecodeError as e: - wheel = self.info_location.parent - error = f"Error decoding metadata for {wheel}: {e} in {filename} file" - raise UnsupportedWheel(error) - return text - - def locate_file(self, path: str | PathLike[str]) -> pathlib.Path: - # This method doesn't make sense for our in-memory wheel, but the API - # requires us to define it. - raise NotImplementedError - - -class Distribution(BaseDistribution): - def __init__( - self, - dist: importlib.metadata.Distribution, - info_location: BasePath | None, - installed_location: BasePath | None, - ) -> None: - self._dist = dist - self._info_location = info_location - self._installed_location = installed_location - - @classmethod - def from_directory(cls, directory: str) -> BaseDistribution: - info_location = pathlib.Path(directory) - dist = importlib.metadata.Distribution.at(info_location) - return cls(dist, info_location, info_location.parent) - - @classmethod - def from_metadata_file_contents( - cls, - metadata_contents: bytes, - filename: str, - project_name: str, - ) -> BaseDistribution: - # Generate temp dir to contain the metadata file, and write the file contents. - temp_dir = pathlib.Path( - TempDirectory(kind="metadata", globally_managed=True).path - ) - metadata_path = temp_dir / "METADATA" - metadata_path.write_bytes(metadata_contents) - # Construct dist pointing to the newly created directory. - dist = importlib.metadata.Distribution.at(metadata_path.parent) - return cls(dist, metadata_path.parent, None) - - @classmethod - def from_wheel(cls, wheel: Wheel, name: str) -> BaseDistribution: - try: - with wheel.as_zipfile() as zf: - dist = WheelDistribution.from_zipfile(zf, name, wheel.location) - except zipfile.BadZipFile as e: - raise InvalidWheel(wheel.location, name) from e - return cls(dist, dist.info_location, pathlib.PurePosixPath(wheel.location)) - - @property - def location(self) -> str | None: - if self._info_location is None: - return None - return str(self._info_location.parent) - - @property - def info_location(self) -> str | None: - if self._info_location is None: - return None - return str(self._info_location) - - @property - def installed_location(self) -> str | None: - if self._installed_location is None: - return None - return normalize_path(str(self._installed_location)) - - @property - def canonical_name(self) -> NormalizedName: - return get_dist_canonical_name(self._dist) - - @property - def version(self) -> Version: - try: - version = ( - parse_name_and_version_from_info_directory(self._dist)[1] - or self._dist.version - ) - return parse_version(version) - except TypeError: - raise BadMetadata(self._dist, reason="invalid metadata entry `version`") - - @property - def raw_version(self) -> str: - return self.metadata["Version"] - - def is_file(self, path: InfoPath) -> bool: - return self._dist.read_text(str(path)) is not None - - def iter_distutils_script_names(self) -> Iterator[str]: - # A distutils installation is always "flat" (not in e.g. egg form), so - # if this distribution's info location is NOT a pathlib.Path (but e.g. - # zipfile.Path), it can never contain any distutils scripts. - if not isinstance(self._info_location, pathlib.Path): - return - for child in self._info_location.joinpath("scripts").iterdir(): - yield child.name - - def read_text(self, path: InfoPath) -> str: - content = self._dist.read_text(str(path)) - if content is None: - raise FileNotFoundError(path) - return content - - def iter_entry_points(self) -> Iterable[BaseEntryPoint]: - # importlib.metadata's EntryPoint structure satisfies BaseEntryPoint. - return self._dist.entry_points - - def _metadata_impl(self) -> email.message.Message: - # From Python 3.10+, importlib.metadata declares PackageMetadata as the - # return type. This protocol is unfortunately a disaster now and misses - # a ton of fields that we need, including get() and get_payload(). We - # rely on the implementation that the object is actually a Message now, - # until upstream can improve the protocol. (python/cpython#94952) - metadata = self._dist.metadata - # From Python 3.15+, importlib.metadata may return None when no - # metadata file (METADATA or PKG-INFO) exists in the distribution - # directory. (python/cpython#132947) - if metadata is None: - return email.message.Message() - return cast(email.message.Message, metadata) - - def iter_provided_extras(self) -> Iterable[NormalizedName]: - return [ - canonicalize_name(extra) - for extra in self.metadata.get_all("Provides-Extra", []) - ] - - def iter_dependencies(self, extras: Collection[str] = ()) -> Iterable[Requirement]: - contexts: Sequence[dict[str, str]] = [{"extra": e} for e in extras] - for req_string in self.metadata.get_all("Requires-Dist", []): - # strip() because email.message.Message.get_all() may return a leading \n - # in case a long header was wrapped. - req = get_requirement(req_string.strip()) - if not req.marker: - yield req - elif not extras and req.marker.evaluate({"extra": ""}): - yield req - elif any(req.marker.evaluate(context) for context in contexts): - yield req diff --git a/venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/_envs.py b/venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/_envs.py deleted file mode 100755 index be732a9..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/_envs.py +++ /dev/null @@ -1,148 +0,0 @@ -from __future__ import annotations - -import importlib.metadata -import logging -import os -import pathlib -import sys -import zipfile -from collections.abc import Iterator, Sequence - -from pip._vendor.packaging.utils import ( - InvalidWheelFilename, - NormalizedName, - canonicalize_name, - parse_wheel_filename, -) - -from pip._internal.metadata.base import BaseDistribution, BaseEnvironment -from pip._internal.utils.filetypes import WHEEL_EXTENSION - -from ._compat import BadMetadata, BasePath, get_dist_canonical_name, get_info_location -from ._dists import Distribution - -logger = logging.getLogger(__name__) - -# Used to avoid emitting duplicate invalid distribution metadata warnings for -# the same dist-info directory. -_warned_bad_metadata: set[BasePath | None] = set() - - -def _looks_like_wheel(location: str) -> bool: - if not location.endswith(WHEEL_EXTENSION): - return False - if not os.path.isfile(location): - return False - try: - parse_wheel_filename(os.path.basename(location)) - except InvalidWheelFilename: - return False - return zipfile.is_zipfile(location) - - -class _DistributionFinder: - """Finder to locate distributions. - - The main purpose of this class is to memoize found distributions' names, so - only one distribution is returned for each package name. At lot of pip code - assumes this (because it is setuptools's behavior), and not doing the same - can potentially cause a distribution in lower precedence path to override a - higher precedence one if the caller is not careful. - - Eventually we probably want to make it possible to see lower precedence - installations as well. It's useful feature, after all. - """ - - FoundResult = tuple[importlib.metadata.Distribution, BasePath | None] - - def __init__(self) -> None: - self._found_names: set[NormalizedName] = set() - - def _find_impl(self, location: str) -> Iterator[FoundResult]: - """Find distributions in a location.""" - # Skip looking inside a wheel. Since a package inside a wheel is not - # always valid (due to .data directories etc.), its .dist-info entry - # should not be considered an installed distribution. - if _looks_like_wheel(location): - return - # To know exactly where we find a distribution, we have to feed in the - # paths one by one, instead of dumping the list to importlib.metadata. - for dist in importlib.metadata.distributions(path=[location]): - info_location = get_info_location(dist) - try: - name = get_dist_canonical_name(dist) - except BadMetadata as e: - if info_location not in _warned_bad_metadata: - logger.warning("Skipping %s due to %s", info_location, e.reason) - _warned_bad_metadata.add(info_location) - continue - if name in self._found_names: - continue - self._found_names.add(name) - yield dist, info_location - - def find(self, location: str) -> Iterator[BaseDistribution]: - """Find distributions in a location. - - The path can be either a directory, or a ZIP archive. - """ - for dist, info_location in self._find_impl(location): - if info_location is None: - installed_location: BasePath | None = None - else: - installed_location = info_location.parent - yield Distribution(dist, info_location, installed_location) - - def find_legacy_editables(self, location: str) -> Iterator[BaseDistribution]: - """Read location in egg-link files and return distributions in there. - - The path should be a directory; otherwise this returns nothing. This - follows how setuptools does this for compatibility. The first non-empty - line in the egg-link is read as a path (resolved against the egg-link's - containing directory if relative). Distributions found at that linked - location are returned. - """ - path = pathlib.Path(location) - if not path.is_dir(): - return - for child in path.iterdir(): - if child.suffix != ".egg-link": - continue - with child.open() as f: - lines = (line.strip() for line in f) - target_rel = next((line for line in lines if line), "") - if not target_rel: - continue - target_location = str(path.joinpath(target_rel)) - for dist, info_location in self._find_impl(target_location): - yield Distribution(dist, info_location, path) - - -class Environment(BaseEnvironment): - def __init__(self, paths: Sequence[str]) -> None: - self._paths = paths - - @classmethod - def default(cls) -> BaseEnvironment: - return cls(sys.path) - - @classmethod - def from_paths(cls, paths: list[str] | None) -> BaseEnvironment: - if paths is None: - return cls(sys.path) - return cls(paths) - - def _iter_distributions(self) -> Iterator[BaseDistribution]: - finder = _DistributionFinder() - for location in self._paths: - yield from finder.find(location) - yield from finder.find_legacy_editables(location) - - def get_distribution(self, name: str) -> BaseDistribution | None: - canonical_name = canonicalize_name(name) - matches = ( - distribution - for distribution in self.iter_all_distributions() - if distribution.canonical_name == canonical_name - ) - return next(matches, None) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/metadata/pkg_resources.py b/venv/lib/python3.11/site-packages/pip/_internal/metadata/pkg_resources.py deleted file mode 100755 index 89fce8b..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/metadata/pkg_resources.py +++ /dev/null @@ -1,298 +0,0 @@ -from __future__ import annotations - -import email.message -import email.parser -import logging -import os -import zipfile -from collections.abc import Collection, Iterable, Iterator, Mapping -from typing import ( - NamedTuple, -) - -from pip._vendor import pkg_resources -from pip._vendor.packaging.requirements import Requirement -from pip._vendor.packaging.utils import NormalizedName, canonicalize_name -from pip._vendor.packaging.version import Version -from pip._vendor.packaging.version import parse as parse_version - -from pip._internal.exceptions import InvalidWheel, NoneMetadataError, UnsupportedWheel -from pip._internal.utils.egg_link import egg_link_path_from_location -from pip._internal.utils.misc import display_path, normalize_path -from pip._internal.utils.wheel import parse_wheel, read_wheel_metadata_file - -from .base import ( - BaseDistribution, - BaseEntryPoint, - BaseEnvironment, - InfoPath, - Wheel, -) - -__all__ = ["NAME", "Distribution", "Environment"] - -logger = logging.getLogger(__name__) - -NAME = "pkg_resources" - - -class EntryPoint(NamedTuple): - name: str - value: str - group: str - - -class InMemoryMetadata: - """IMetadataProvider that reads metadata files from a dictionary. - - This also maps metadata decoding exceptions to our internal exception type. - """ - - def __init__(self, metadata: Mapping[str, bytes], wheel_name: str) -> None: - self._metadata = metadata - self._wheel_name = wheel_name - - def has_metadata(self, name: str) -> bool: - return name in self._metadata - - def get_metadata(self, name: str) -> str: - try: - return self._metadata[name].decode() - except UnicodeDecodeError as e: - # Augment the default error with the origin of the file. - raise UnsupportedWheel( - f"Error decoding metadata for {self._wheel_name}: {e} in {name} file" - ) - - def get_metadata_lines(self, name: str) -> Iterable[str]: - return pkg_resources.yield_lines(self.get_metadata(name)) - - def metadata_isdir(self, name: str) -> bool: - return False - - def metadata_listdir(self, name: str) -> list[str]: - return [] - - def run_script(self, script_name: str, namespace: str) -> None: - pass - - -class Distribution(BaseDistribution): - def __init__(self, dist: pkg_resources.Distribution) -> None: - self._dist = dist - # This is populated lazily, to avoid loading metadata for all possible - # distributions eagerly. - self.__extra_mapping: Mapping[NormalizedName, str] | None = None - - @property - def _extra_mapping(self) -> Mapping[NormalizedName, str]: - if self.__extra_mapping is None: - self.__extra_mapping = { - canonicalize_name(extra): extra for extra in self._dist.extras - } - - return self.__extra_mapping - - @classmethod - def from_directory(cls, directory: str) -> BaseDistribution: - dist_dir = directory.rstrip(os.sep) - - # Build a PathMetadata object, from path to metadata. :wink: - base_dir, dist_dir_name = os.path.split(dist_dir) - metadata = pkg_resources.PathMetadata(base_dir, dist_dir) - - # Determine the correct Distribution object type. - if dist_dir.endswith(".egg-info"): - dist_cls = pkg_resources.Distribution - dist_name = os.path.splitext(dist_dir_name)[0] - else: - assert dist_dir.endswith(".dist-info") - dist_cls = pkg_resources.DistInfoDistribution - dist_name = os.path.splitext(dist_dir_name)[0].split("-")[0] - - dist = dist_cls(base_dir, project_name=dist_name, metadata=metadata) - return cls(dist) - - @classmethod - def from_metadata_file_contents( - cls, - metadata_contents: bytes, - filename: str, - project_name: str, - ) -> BaseDistribution: - metadata_dict = { - "METADATA": metadata_contents, - } - dist = pkg_resources.DistInfoDistribution( - location=filename, - metadata=InMemoryMetadata(metadata_dict, filename), - project_name=project_name, - ) - return cls(dist) - - @classmethod - def from_wheel(cls, wheel: Wheel, name: str) -> BaseDistribution: - try: - with wheel.as_zipfile() as zf: - info_dir, _ = parse_wheel(zf, name) - metadata_dict = { - path.split("/", 1)[-1]: read_wheel_metadata_file(zf, path) - for path in zf.namelist() - if path.startswith(f"{info_dir}/") - } - except zipfile.BadZipFile as e: - raise InvalidWheel(wheel.location, name) from e - except UnsupportedWheel as e: - raise UnsupportedWheel(f"{name} has an invalid wheel, {e}") - dist = pkg_resources.DistInfoDistribution( - location=wheel.location, - metadata=InMemoryMetadata(metadata_dict, wheel.location), - project_name=name, - ) - return cls(dist) - - @property - def location(self) -> str | None: - return self._dist.location - - @property - def installed_location(self) -> str | None: - egg_link = egg_link_path_from_location(self.raw_name) - if egg_link: - location = egg_link - elif self.location: - location = self.location - else: - return None - return normalize_path(location) - - @property - def info_location(self) -> str | None: - return self._dist.egg_info - - @property - def installed_by_distutils(self) -> bool: - # A distutils-installed distribution is provided by FileMetadata. This - # provider has a "path" attribute not present anywhere else. Not the - # best introspection logic, but pip has been doing this for a long time. - try: - return bool(self._dist._provider.path) - except AttributeError: - return False - - @property - def canonical_name(self) -> NormalizedName: - return canonicalize_name(self._dist.project_name) - - @property - def version(self) -> Version: - return parse_version(self._dist.version) - - @property - def raw_version(self) -> str: - return self._dist.version - - def is_file(self, path: InfoPath) -> bool: - return self._dist.has_metadata(str(path)) - - def iter_distutils_script_names(self) -> Iterator[str]: - yield from self._dist.metadata_listdir("scripts") - - def read_text(self, path: InfoPath) -> str: - name = str(path) - if not self._dist.has_metadata(name): - raise FileNotFoundError(name) - content = self._dist.get_metadata(name) - if content is None: - raise NoneMetadataError(self, name) - return content - - def iter_entry_points(self) -> Iterable[BaseEntryPoint]: - for group, entries in self._dist.get_entry_map().items(): - for name, entry_point in entries.items(): - name, _, value = str(entry_point).partition("=") - yield EntryPoint(name=name.strip(), value=value.strip(), group=group) - - def _metadata_impl(self) -> email.message.Message: - """ - :raises NoneMetadataError: if the distribution reports `has_metadata()` - True but `get_metadata()` returns None. - """ - if isinstance(self._dist, pkg_resources.DistInfoDistribution): - metadata_name = "METADATA" - else: - metadata_name = "PKG-INFO" - try: - metadata = self.read_text(metadata_name) - except FileNotFoundError: - if self.location: - displaying_path = display_path(self.location) - else: - displaying_path = repr(self.location) - logger.warning("No metadata found in %s", displaying_path) - metadata = "" - feed_parser = email.parser.FeedParser() - feed_parser.feed(metadata) - return feed_parser.close() - - def iter_dependencies(self, extras: Collection[str] = ()) -> Iterable[Requirement]: - if extras: - relevant_extras = set(self._extra_mapping) & set( - map(canonicalize_name, extras) - ) - extras = [self._extra_mapping[extra] for extra in relevant_extras] - return self._dist.requires(extras) - - def iter_provided_extras(self) -> Iterable[NormalizedName]: - return self._extra_mapping.keys() - - -class Environment(BaseEnvironment): - def __init__(self, ws: pkg_resources.WorkingSet) -> None: - self._ws = ws - - @classmethod - def default(cls) -> BaseEnvironment: - return cls(pkg_resources.working_set) - - @classmethod - def from_paths(cls, paths: list[str] | None) -> BaseEnvironment: - return cls(pkg_resources.WorkingSet(paths)) - - def _iter_distributions(self) -> Iterator[BaseDistribution]: - for dist in self._ws: - yield Distribution(dist) - - def _search_distribution(self, name: str) -> BaseDistribution | None: - """Find a distribution matching the ``name`` in the environment. - - This searches from *all* distributions available in the environment, to - match the behavior of ``pkg_resources.get_distribution()``. - """ - canonical_name = canonicalize_name(name) - for dist in self.iter_all_distributions(): - if dist.canonical_name == canonical_name: - return dist - return None - - def get_distribution(self, name: str) -> BaseDistribution | None: - # Search the distribution by looking through the working set. - dist = self._search_distribution(name) - if dist: - return dist - - # If distribution could not be found, call working_set.require to - # update the working set, and try to find the distribution again. - # This might happen for e.g. when you install a package twice, once - # using setup.py develop and again using setup.py install. Now when - # running pip uninstall twice, the package gets removed from the - # working set in the first uninstall, so we have to populate the - # working set again so that pip knows about it and the packages gets - # picked up and is successfully uninstalled the second time too. - try: - # We didn't pass in any version specifiers, so this can never - # raise pkg_resources.VersionConflict. - self._ws.require(name) - except pkg_resources.DistributionNotFound: - return None - return self._search_distribution(name) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/models/__init__.py b/venv/lib/python3.11/site-packages/pip/_internal/models/__init__.py deleted file mode 100755 index 7b1fc29..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/models/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""A package that contains models that represent entities.""" diff --git a/venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/__init__.cpython-311.pyc deleted file mode 100755 index 68bd7ce0eea309a86781c7dd88257ff0da62740c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 266 zcmZ3^%ge<81lOj_%CZB}k3k$5V1zP0gOp5XNMVR#NMQ_S&}6DIcT^}yOwLYBPgN+% zNGwrE&d)1J%*-oR$jwhl%_)Wm7Nr&xr52~=l_&slW=Uphv7VnM<1P01_>}zQ`1q9! zpF!sTiqOx<&rQ|OO)N^z*Z0a#&o|ajEGW<~OU*0O&&f>EFQ_cZ$j>v@Gc?pM&MZmQ zg<4#!Uyxa#AD@|5l3J9Pn4=G|Sw9{ql35ZTuUAm{i^B#eSelb+SHuRi2;`e$K_Kyg SnURt427~Pd7%E}`iUI(=u1>uG diff --git a/venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/candidate.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/candidate.cpython-311.pyc deleted file mode 100755 index 34e1f74959c68be4c86b2841e62b2c140a81fe73..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1983 zcmbVM&1>976ra)e?t1Ms**LW!MYYqWDv5++6ACqMi6O0xYegeri<6sdru6ls8Dj&g_;h(IL*7DS>dk*P*hqAll1Zd)$rh)Shpf#kQP za-L}5!$5Lz&JQEU^PC6{J?r?y1#f75>MpG@8d5(Bbw{rS5g^y`^s!2B%9y?!Fx@?2 zZ6=cMRB57aW+6x<5ByFPFQ}|jaywBNjW(FSSm|YtyR5(XP;{F@pO zkp|uan|*GV68?X7LUdy1hOh_g@Avn3r4_}7_)2zCLweDUAjpTj$ao>J0nUn?4FWU7 zLsQ}$M>z(ph~T(!zzI_AFKqE zmQ$-)o7CU5Ja@^eJ&0BVf6|x}-aievA!6d?76cW+m7p zF_8wy9%s{+UJKK8u8E_Xg^H-IGv%N@BMN=L!4`O*d>^2 z;M+!lCy3urD4o1*Lk2fIjt6Y}iw(!?j=(8MPyw|FyCp-m?f8BG6$j5lXxmJJ#TXA+ zA}s}h$A-DgkMtc%H%eV${N+wr4nX)6So6epD9yyu%wfLRoNLZ)&9#fASmLcEmD>5i z=6rL0YrZ{juDQ@$*jnf)Xcm8rJE9^_b`Y?3=~61R$KJ~N>l0c3{s(D)m@9VV-sIFG zW9P7Z7w=x^Am0Bs&phEyEE>6_(0|`)$atkBm*Fm$aPNE)Ff+R#uD@b-v!2C>-#B)G z&mKu<_im1v-5is@jcFjWV2$zVJX2`^kG1J6Ju~cW(D5P(zX8?}F~)85W_-FGqKWu) zYoib2)9nzw8=r0vS)tGz`SQvxiSc*~k00Rij_?}h(K(wxPxXJL{JDsPD`#4yZu|qO CAKMK8 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-311.pyc deleted file mode 100755 index 1cfb5cf606ffa1b9bec998f9c139abfdadeda129..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2308 zcmbVN-ESL35a0Ek&*#|Aku;Q&7KlozbhPnN6~RlA#?Yt~(KKq)K3o;8F1MG&>3x{J zb3~$6%0nb7gw%ps1yGSHgi@mLz+?Xm8(C1Dgs8+5Z?3`v>Jzhj$;EE@kXYN}*_qkh zncvLL-Y=DU5R9L0f3^67gwSt%vOBT~gSVG}Sw|F^h+>*?v6nG3nDde=nG*cVuIy#a ztdM10#mkvFPc>C9Z|1!ovq#7kkQdA%M)Qc~zQJaRs%CEnok29ehG>sd+<^19;Fk=u zK&6XFFRbLICZ>koI`PKuT(0A|VEKL!Sy46c!%3J+6@OWm<3fem3)Lm(tUnjT2ToU+ zV@H>md)acUR2WY%7O*%68ex*VY=@kI9rCHQt}q@n%W;zDL;(WZoxL#e?lie{;RAAR zV!Cp=GF>5)m2(qJ1@($X#c8C@-11@=_%;aBu@ey9eh)++1B?zbF+iE2JvY!CK)6;k zB}b+Os;tQyV6&AjHM6uxb8E7x&=P)O40f7^Edlr~GcpXI@+9<^vq3*-)WjgjqS&F~UY{2@hbdT;CxF$_b1EvG> zj_)ula)|59TlO+pu)+mhie>I;oDJ(W2a*v5gwOR%EQgLe7v~AFT`LR;3Hk9ut4~a0 zA@Cf-vzQ$i?+5e2NyDnuj3vikGTiE{QCp4{0{>+B#0ev;M$T}}vaee6PH5DsHG@?B z$YH+a8eTvhH#9mDRa=gGcaA4^;MJ^XWv^<=-I`axm+(~}f3Bimw0(CbK09;!%=-Dy z&p#Nrb-p<;)*2XVYNuM-sfK!Ln`0H@FqR-4b|;8wBBsD%9bH5Bxal*aGbM}Z`fIow z=?I%-xx$cC4ixYpBQA3t-SyaWV)*#a#fVyWSSlx`FW1 z;J_>$-Bl>+4eYj3+qA;+VZb7C)maX8iM<5t<1DRvwUF%xeiO5O@E7vqc4FnlCL- z{SGkQL0?0AVF!iI*1dG{g zoV*SsF70#$+i_h&bj$`oDqWo&oh3D z;vr~bWdhxf2CSU)Hqe!!9^iT74^Hx4DSWkfwD^ORybb+Rq7{O9S_b@Ri(|<6qrZs~ zw|FObqK+il8Dnq5lwX_hS0HT(WBd@6R!fi2;YRoO5h|>T&qK7o(fw`9S)6I3|3``$ pzV@Gpnk#^Im#pU6{piqe10859MGRSZmNcF_{FsaX_#2%7;4h^q8;Jk_ diff --git a/venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/format_control.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/format_control.cpython-311.pyc deleted file mode 100755 index 1caac786bf70a0ed2ba3e2a61c39df57c73db637..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4501 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 D|3LqN diff --git a/venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/index.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/index.cpython-311.pyc deleted file mode 100755 index a62d596fb7007e51fb4792b9273e7cefd6f5ab4d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1900 zcmaJ>QEMAV5Z*hTq_b?Jq_!2InsDIKA}8@Rc5tAir8I@c#keMIOc90Udb_euJ>6Y) z&n6an(1S}|@MB6!pF}CHi~G>W{tU^8S{wuded?Qn^HB2C*_BU`W8A&FnVp%Po!Oah z@7MA141)33$IQa_L6GRYETvSq2^a&#B4kC$t6`@1;`lF<(h^j;* z$=_42SrXEcCi*#xMwHJ{apWJd#fp8plVqt=;p84nzJvG_ViQzSiBd|eLk2%9C5%$@1AfJ1l-Oi$l=5ik`gWAz zPBm~T7CJrH4jeg~C_A9zq0b;TCVtg&JeGu`u@N9qiqUYBc`J6}^w@%lx%f`5DhU0c zJV7Dwc3XvdaY+@x!^$Q`eb<0D2 z8^PFiEzU9KqJoBDG+sV1H~cC!s}{3;^HYD_Uofp8Ft@0;WkO^#*bX;*Z(;7{O_Mtz zy%F>Q$<4qCOvp8)%(Gmx>J#d6(-AnG3$|Gn_ODG1qjxSonJ5eof&AM*PxbNd(|hS- zJ%6O<+j^m+7g~CuJCWPf_VlN@>BsJI?%GlA+QHp+?%j@fZ-ZsDTex~$xPDZ)e(+_x zu-GXqf->99Pao%JkMgqzi|zb;CqEC$@m>bK1uh-kXvy~k;vy(I)XN@V3sj;W61~eX z0qg>eM`eJc=CDU>Ms-vf+yg)!taG6s~=})j`8%JXpKist3Q%f4dHMcRE?u(*C+UoY|Qlx(Y&SLf(>L(|9{!+iw@68A7 zZ4gCW`9mPRgrX>2G|`IRUg{0yRu7#g&xP*AE5j_(CmZ$F7fK6rTODz5a_02|rHi$ORhe0$w7Z0+dEXpcYV-15~Iot+vbVIB~MxHM48l zM5cXxDqKw7!DayC0dMfh)3@sJv@)}$UPpRhwy8cVoaAVqkQxq+RSsVbQxc-VN=6^ zg)wsmKD|0FsWrn>cE~a;i^R(x3ApZwL&(wZEM}=zycHt@LTT#v54wi9Vvj?MMq$n z8wdAyDcf1f^R8%PqeN(qZE7l)d!fmbRt3uym1vfH(VDQ1$!fJK-+=JSM){gtopB~D z^H^bcShmX!K2lY+X>|hIa)a3ME+5R&7tp(*w*oV_mf#G~@8$w9U6B=%*xZ`(&j~U)orjT-uUF?*=uWqk z;3`u-H<2zZhi(QekU_8~`3A@yr`N{_xUeyD54?HU^{CG4;s_|#dEiHAe0JBkmD8{1v{#)I;xxQb}INY zhp2WwMkq(!9>)S3nxkk|rK&n)7wr^{vN=t5Q<$vTm?(CwS~bel;ska;-*()jZ<|eb z!)>!}*al8vJukR|X4qs0wIL8}+cX`yT#oe6p1#coK z&H?0?1yllV&P%t@RCm@n6y%}PA<(n1(|xA|7!1L^fTOIWIrfElKH|>mSd8Hb|=SkEXOZmBL?t<(rR?JuuWz= zSuczjmZlo^C;(qyrpAtg_-_tDZ1?tTh}Q9w--u7s`6uc8g9EE+xtW$dA)vvcofq9m z=fQE~a25Kmj~nUm$&GJ*paeosK1onP;|dNkhiLRaX;U`hv$X%!z8nH|`+X3w@3lSs ze+~?Jd|+?PkJiYU=ExPc>u1!t=T!W=6TK#{4jgR`9Q88EG*GQAqHXq!=M(gnHq{DN z6gQ?QaG}=>iW7=*y`~!N5kg5t=nX|uAl$fSsJ0C!b<)yZk)Cr`upL6^9mrBh3KSir zf|8WEN}?1|!5*To0nBy(Je~`ke(+)A?eone7d!-wmqi$bcX)h%sJHPZjKTMj^Z4xV zy^qiT_Bm^Ah-U(*&R=E9-pQU&Y^iTaTRFBg35OFw^Od5#SGvRTeB4cGmSMmp2oJSg zP_Jn$2yWP!sg}(N=Bk?o3KW0?rf!i!`-z0H0=%lz@Lvf_xhsGUqd`a8e>)3sb<&@I zWwpc0Vib(q3u&aCl~Flzwp1ZxY8G=kL& S%N&Git9VBHo^Lb2!uLOB=#Y;9 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/link.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/link.cpython-311.pyc deleted file mode 100755 index 26dded6e6473a03ac8bd2a05f8af4663bcdafa97..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31074 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 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/scheme.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/scheme.cpython-311.pyc deleted file mode 100755 index 5692b6955051bb80ed8306bb85ed8069b77cde7e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1134 zcmZ`%O=}ZD7@pniCTY^diVAugO)ml6rSv96P-!(c=DD~Pd)k0=7UOccHU>7`P^sU=lxizln}Jv z!KB$^a`X(yE~2P~s6oxh=$b9lKpjMLABaKk>tsF~;vqWRZ|7XF>z zgXR6nCe*TMv5D$4+h0m6Twt}8Fo}tj+z*Lj6mNtoz+o&Ei6Wvx9%JbTtjnZR$_^0R zVKEaV!o1H!KV%!2w=wCHFe2*_o9xCUrdS0m6xipnVw>tJmW-7Gr4o7Fbt(6ylWeJg z#|{@AchMbx6W)|uUkZD2sB21J_Eq&lo-Awas!M9nQ+A`uw`qS(H$&Cj`D?oM;LoEZGFdu^#tsJwM zP0b}($yjd6tSPgnEUy_YK(>o%zL{llTiwJXh65f^i4&p%i8q4K4=@o7_at~gq)r`P zCz4?r3g#;=La?dLMF~SALWOPOtJB62{4mQY-0Qy}9p+^Fg#|){E-#VSP|#2WSgYsL zqUXh=%RDbFd0v;(UZnY~=e_KaXuMMJJTMHVb5e=)jOUR!<|-=>>3N^f5!{82pSS_< zGPg^F&)s{x!xvqWByOL@eHZ+2M|Lkd3k$9c!PK!v=_X;~dLdK^m>s#Gfko0Cl^xWG znALJMR3KynU~u9YTBcnbA`L}UJv&$(tnRG-sLcJBlq!S9ps@onXo&NZyVvTrn1exD zo)#68LKj0?Zr;AT{9xI;zx=d05_3+U%8p(Dc3fN<5ECkU4*P HYo_imEI~df diff --git a/venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-311.pyc deleted file mode 100755 index aa90313c051e98fdb58fdaae9f053c74cb2be121..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5691 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 L=z*s_NDSov_77XO diff --git a/venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-311.pyc deleted file mode 100755 index 08691fd017e2dae19d21e5f97707a72716a90e6c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1961 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 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/wheel.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/wheel.cpython-311.pyc deleted file mode 100755 index 2a9239a18ee9bc00d973405d220c91abe5dc6fba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5121 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 None: - object.__setattr__(self, "name", name) - object.__setattr__(self, "version", parse_version(version)) - object.__setattr__(self, "link", link) - object.__setattr__(self, "locked", locked) - - def __str__(self) -> str: - return f"{self.name!r} candidate (version {self.version} at {self.link})" diff --git a/venv/lib/python3.11/site-packages/pip/_internal/models/direct_url.py b/venv/lib/python3.11/site-packages/pip/_internal/models/direct_url.py deleted file mode 100755 index a2dfb34..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/models/direct_url.py +++ /dev/null @@ -1,42 +0,0 @@ -"""PEP 610""" - -from __future__ import annotations - -import json -from typing import Any - -from pip._vendor.packaging.direct_url import ( - ArchiveInfo, - DirectUrlValidationError, - DirInfo, - VcsInfo, -) -from pip._vendor.packaging.direct_url import ( - DirectUrl as PackagingDirectUrl, -) - -__all__ = [ - "ArchiveInfo", - "DirInfo", - "DirectUrl", - "DirectUrlValidationError", - "DIRECT_URL_METADATA_NAME", - "VcsInfo", -] - -DIRECT_URL_METADATA_NAME = "direct_url.json" - - -class DirectUrl(PackagingDirectUrl): - def to_dict_compat(self) -> dict[str, Any]: - return dict(super().to_dict(generate_legacy_hash=True)) - - @classmethod - def from_json(cls, s: str) -> DirectUrl: - return cls.from_dict(json.loads(s)) - - def to_json(self) -> str: - return json.dumps(self.to_dict_compat(), sort_keys=True) - - def is_local_editable(self) -> bool: - return bool(self.dir_info and self.dir_info.editable) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/models/format_control.py b/venv/lib/python3.11/site-packages/pip/_internal/models/format_control.py deleted file mode 100755 index 9f07e3f..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/models/format_control.py +++ /dev/null @@ -1,78 +0,0 @@ -from __future__ import annotations - -from pip._vendor.packaging.utils import canonicalize_name - -from pip._internal.exceptions import CommandError - - -class FormatControl: - """Helper for managing formats from which a package can be installed.""" - - __slots__ = ["no_binary", "only_binary"] - - def __init__( - self, - no_binary: set[str] | None = None, - only_binary: set[str] | None = None, - ) -> None: - if no_binary is None: - no_binary = set() - if only_binary is None: - only_binary = set() - - self.no_binary = no_binary - self.only_binary = only_binary - - def __eq__(self, other: object) -> bool: - if not isinstance(other, self.__class__): - return NotImplemented - - if self.__slots__ != other.__slots__: - return False - - return all(getattr(self, k) == getattr(other, k) for k in self.__slots__) - - def __repr__(self) -> str: - return f"{self.__class__.__name__}({self.no_binary}, {self.only_binary})" - - @staticmethod - def handle_mutual_excludes(value: str, target: set[str], other: set[str]) -> None: - if value.startswith("-"): - raise CommandError( - "--no-binary / --only-binary option requires 1 argument." - ) - new = value.split(",") - while ":all:" in new: - other.clear() - 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: str) -> frozenset[str]: - 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) -> None: - self.handle_mutual_excludes( - ":all:", - self.no_binary, - self.only_binary, - ) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/models/index.py b/venv/lib/python3.11/site-packages/pip/_internal/models/index.py deleted file mode 100755 index b94c325..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/models/index.py +++ /dev/null @@ -1,28 +0,0 @@ -import urllib.parse - - -class PackageIndex: - """Represents a Package Index and provides easier access to endpoints""" - - __slots__ = ["url", "netloc", "simple_url", "pypi_url", "file_storage_domain"] - - def __init__(self, url: str, file_storage_domain: str) -> None: - super().__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: str) -> str: - 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.11/site-packages/pip/_internal/models/installation_report.py b/venv/lib/python3.11/site-packages/pip/_internal/models/installation_report.py deleted file mode 100755 index 145e2cf..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/models/installation_report.py +++ /dev/null @@ -1,57 +0,0 @@ -from collections.abc import Sequence -from typing import Any - -from pip._vendor.packaging.markers import default_environment - -from pip import __version__ -from pip._internal.req.req_install import InstallRequirement - - -class InstallationReport: - def __init__(self, install_requirements: Sequence[InstallRequirement]): - self._install_requirements = install_requirements - - @classmethod - def _install_req_to_dict(cls, ireq: InstallRequirement) -> dict[str, Any]: - assert ireq.download_info, f"No download_info for {ireq}" - res = { - # PEP 610 json for the download URL. download_info.archive_info.hashes may - # be absent when the requirement was installed from the wheel cache - # and the cache entry was populated by an older pip version that did not - # record origin.json. - "download_info": ireq.download_info.to_dict_compat(), - # is_direct is true if the requirement was a direct URL reference (which - # includes editable requirements), and false if the requirement was - # downloaded from a PEP 503 index or --find-links. - "is_direct": ireq.is_direct, - # is_yanked is true if the requirement was yanked from the index, but - # was still selected by pip to conform to PEP 592. - "is_yanked": ireq.link.is_yanked if ireq.link else False, - # requested is true if the requirement was specified by the user (aka - # top level requirement), and false if it was installed as a dependency of a - # requirement. https://peps.python.org/pep-0376/#requested - "requested": ireq.user_supplied, - # PEP 566 json encoding for metadata - # https://www.python.org/dev/peps/pep-0566/#json-compatible-metadata - "metadata": ireq.get_dist().metadata_dict, - } - if ireq.user_supplied and ireq.extras: - # For top level requirements, the list of requested extras, if any. - res["requested_extras"] = sorted(ireq.extras) - return res - - def to_dict(self) -> dict[str, Any]: - return { - "version": "1", - "pip_version": __version__, - "install": [ - self._install_req_to_dict(ireq) for ireq in self._install_requirements - ], - # https://peps.python.org/pep-0508/#environment-markers - # TODO: currently, the resolver uses the default environment to evaluate - # environment markers, so that is what we report here. In the future, it - # should also take into account options such as --python-version or - # --platform, perhaps under the form of an environment_override field? - # https://github.com/pypa/pip/issues/11198 - "environment": default_environment(), - } diff --git a/venv/lib/python3.11/site-packages/pip/_internal/models/link.py b/venv/lib/python3.11/site-packages/pip/_internal/models/link.py deleted file mode 100755 index cbbe945..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/models/link.py +++ /dev/null @@ -1,657 +0,0 @@ -from __future__ import annotations - -import datetime -import functools -import itertools -import logging -import os -import posixpath -import re -import urllib.parse -from collections.abc import Mapping -from dataclasses import dataclass -from typing import ( - Any, - NamedTuple, - NewType, -) - -from pip._internal.exceptions import InvalidEggFragment -from pip._internal.utils.datetime import parse_iso_datetime -from pip._internal.utils.filetypes import WHEEL_EXTENSION -from pip._internal.utils.hashes import Hashes -from pip._internal.utils.misc import ( - pairwise, - redact_auth_from_url, - split_auth_from_netloc, - splitext, -) -from pip._internal.utils.urls import path_to_url, url_to_path - -logger = logging.getLogger(__name__) - - -# A single path component: percent-decoded once and reduced to a basename, so it -# contains no path separator and is not a ``.`` or ``..`` reference. The empty -# string means "no component". -PathComponent = NewType("PathComponent", str) - - -def _to_path_component(name: str) -> PathComponent: - """Reduce ``name`` to a single path component, or ``""`` if it has none. - - ``os.path.basename`` drops any directory part, drive letter, or separator; - a ``.``, ``..``, or empty result is not a component and becomes ``""``. - """ - name = os.path.basename(name) - if name in ("", os.curdir, os.pardir): - return PathComponent("") - - return PathComponent(name) - - -def as_path_component(name: str) -> PathComponent: - """Like ``_to_path_component`` but reject the empty result. - - Use where a file is about to be written, so a missing name is an error - rather than a silent fallback to the directory itself. - """ - component = _to_path_component(name) - if not component: - raise ValueError(f"Unexpected file name derived from URL: {name!r}") - - return component - - -def join_within_directory(directory: str, component: PathComponent) -> str: - """Join a single path ``component`` onto ``directory``. - - ``component`` is a :data:`PathComponent`, so by type it has no separator and - is not a ``.`` or ``..`` reference; the result can never escape ``directory``. - Requiring ``PathComponent`` rather than ``str`` lets the type checker enforce - at the call site that the name was reduced to a safe component beforehand. - """ - return os.path.join(directory, component) - - -# Order matters, earlier hashes have a precedence over later hashes for what -# we will pick to use. -_SUPPORTED_HASHES = ("sha512", "sha384", "sha256", "sha224", "sha1", "md5") - - -@dataclass(frozen=True) -class LinkHash: - """Links to content may have embedded hash values. This class parses those. - - `name` must be any member of `_SUPPORTED_HASHES`. - - This class can be converted to and from `ArchiveInfo`. While ArchiveInfo intends to - be JSON-serializable to conform to PEP 610, this class contains the logic for - parsing a hash name and value for correctness, and then checking whether that hash - conforms to a schema with `.is_hash_allowed()`.""" - - name: str - value: str - - _hash_url_fragment_re = re.compile( - # NB: we do not validate that the second group (.*) is a valid hex - # digest. Instead, we simply keep that string in this class, and then check it - # against Hashes when hash-checking is needed. This is easier to debug than - # proactively discarding an invalid hex digest, as we handle incorrect hashes - # and malformed hashes in the same place. - r"[#&]({choices})=([^&]*)".format( - choices="|".join(re.escape(hash_name) for hash_name in _SUPPORTED_HASHES) - ), - ) - - def __post_init__(self) -> None: - assert self.name in _SUPPORTED_HASHES - - @classmethod - @functools.cache - def find_hash_url_fragment(cls, url: str) -> LinkHash | None: - """Search a string for a checksum algorithm name and encoded output value.""" - match = cls._hash_url_fragment_re.search(url) - if match is None: - return None - name, value = match.groups() - return cls(name=name, value=value) - - def as_dict(self) -> dict[str, str]: - return {self.name: self.value} - - def as_hashes(self) -> Hashes: - """Return a Hashes instance which checks only for the current hash.""" - return Hashes({self.name: [self.value]}) - - def is_hash_allowed(self, hashes: Hashes | None) -> bool: - """ - Return True if the current hash is allowed by `hashes`. - """ - if hashes is None: - return False - return hashes.is_hash_allowed(self.name, hex_digest=self.value) - - -@dataclass(frozen=True) -class MetadataFile: - """Information about a core metadata file associated with a distribution.""" - - hashes: dict[str, str] | None - - def __post_init__(self) -> None: - if self.hashes is not None: - assert all(name in _SUPPORTED_HASHES for name in self.hashes) - - -def supported_hashes(hashes: dict[str, str] | None) -> dict[str, str] | None: - # Remove any unsupported hash types from the mapping. If this leaves no - # supported hashes, return None - if hashes is None: - return None - hashes = {n: v for n, v in hashes.items() if n in _SUPPORTED_HASHES} - if not hashes: - return None - return hashes - - -def _clean_url_path_part(part: str) -> str: - """ - Clean a "part" of a URL path (i.e. after splitting on "@" characters). - """ - # We unquote prior to quoting to make sure nothing is double quoted. - return urllib.parse.quote(urllib.parse.unquote(part)) - - -def _clean_file_url_path(part: str) -> str: - """ - Clean the first part of a URL path that corresponds to a local - filesystem path (i.e. the first part after splitting on "@" characters). - """ - import urllib.request - - # We unquote prior to quoting to make sure nothing is double quoted. - # Also, on Windows the path part might contain a drive letter which - # should not be quoted. On Linux where drive letters do not - # exist, the colon should be quoted. We rely on urllib.request - # to do the right thing here. - ret = urllib.request.pathname2url(urllib.request.url2pathname(part)) - if ret.startswith("///"): - # Remove any URL authority section, leaving only the URL path. - ret = ret.removeprefix("//") - return ret - - -# percent-encoded: / -_reserved_chars_re = re.compile("(@|%2F)", re.IGNORECASE) - - -def _clean_url_path(path: str, is_local_path: bool) -> str: - """ - Clean the path portion of a URL. - """ - if is_local_path: - clean_func = _clean_file_url_path - else: - clean_func = _clean_url_path_part - - # Split on the reserved characters prior to cleaning so that - # revision strings in VCS URLs are properly preserved. - parts = _reserved_chars_re.split(path) - - cleaned_parts = [] - for to_clean, reserved in pairwise(itertools.chain(parts, [""])): - cleaned_parts.append(clean_func(to_clean)) - # Normalize %xx escapes (e.g. %2f -> %2F) - cleaned_parts.append(reserved.upper()) - - return "".join(cleaned_parts) - - -def _ensure_quoted_url(url: str) -> str: - """ - Make sure a link is fully quoted. - For example, if ' ' occurs in the URL, it will be replaced with "%20", - and without double-quoting other characters. - """ - # Split the URL into parts according to the general structure - # `scheme://netloc/path?query#fragment`. - result = urllib.parse.urlsplit(url) - # If the netloc is empty, then the URL refers to a local filesystem path. - is_local_path = not result.netloc - path = _clean_url_path(result.path, is_local_path=is_local_path) - # Temporarily replace scheme with file to ensure the URL generated by - # urlunsplit() contains an empty netloc (file://) as per RFC 1738. - ret = urllib.parse.urlunsplit(result._replace(scheme="file", path=path)) - ret = result.scheme + ret[4:] # Restore original scheme. - return ret - - -def _absolute_link_url(base_url: str, url: str) -> str: - """ - A faster implementation of urllib.parse.urljoin with a shortcut - for absolute http/https URLs. - """ - if url.startswith(("https://", "http://")): - return url - else: - return urllib.parse.urljoin(base_url, url) - - -@functools.total_ordering -class Link: - """Represents a parsed link from a Package Index's simple URL""" - - __slots__ = [ - "_parsed_url", - "_url", - "_path", - "_hashes", - "comes_from", - "requires_python", - "yanked_reason", - "metadata_file_data", - "upload_time", - "cache_link_parsing", - "egg_fragment", - ] - - def __init__( - self, - url: str, - comes_from: str | None = None, - requires_python: str | None = None, - yanked_reason: str | None = None, - metadata_file_data: MetadataFile | None = None, - upload_time: datetime.datetime | None = None, - cache_link_parsing: bool = True, - hashes: Mapping[str, str] | None = None, - ) -> None: - """ - :param url: url of the resource pointed to (href of the link) - :param comes_from: URL or string indicating where the link was found. - :param 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. - :param yanked_reason: the reason the file has been yanked, if the - file has been yanked, or None if the file hasn't been yanked. - This is the value of the "data-yanked" attribute, if present, in - a simple repository HTML link. If the file has been yanked but - no reason was provided, this should be the empty string. See - PEP 592 for more information and the specification. - :param metadata_file_data: the metadata attached to the file, or None if - no such metadata is provided. This argument, if not None, indicates - that a separate metadata file exists, and also optionally supplies - hashes for that file. - :param upload_time: upload time of the file, or None if the information - is not available from the server. - :param cache_link_parsing: A flag that is used elsewhere to determine - whether resources retrieved from this link should be cached. PyPI - URLs should generally have this set to False, for example. - :param hashes: A mapping of hash names to digests to allow us to - determine the validity of a download. - """ - - # The comes_from, requires_python, and metadata_file_data arguments are - # only used by classmethods of this class, and are not used in client - # code directly. - - # url can be a UNC windows share - if url.startswith("\\\\"): - url = path_to_url(url) - - self._parsed_url = urllib.parse.urlsplit(url) - # Store the url as a private attribute to prevent accidentally - # trying to set a new value. - self._url = url - # The .path property is hot, so calculate its value ahead of time. - self._path = urllib.parse.unquote(self._parsed_url.path) - - link_hash = LinkHash.find_hash_url_fragment(url) - hashes_from_link = {} if link_hash is None else link_hash.as_dict() - if hashes is None: - self._hashes = hashes_from_link - else: - self._hashes = {**hashes, **hashes_from_link} - - self.comes_from = comes_from - self.requires_python = requires_python if requires_python else None - self.yanked_reason = yanked_reason - self.metadata_file_data = metadata_file_data - self.upload_time = upload_time - - self.cache_link_parsing = cache_link_parsing - self.egg_fragment = self._egg_fragment() - - @classmethod - def from_json( - cls, - file_data: dict[str, Any], - page_url: str, - ) -> Link | None: - """ - Convert an pypi json document from a simple repository page into a Link. - """ - file_url = file_data.get("url") - if file_url is None: - return None - - url = _ensure_quoted_url(_absolute_link_url(page_url, file_url)) - pyrequire = file_data.get("requires-python") - yanked_reason = file_data.get("yanked") - hashes = file_data.get("hashes", {}) - - # PEP 714: Indexes must use the name core-metadata, but - # clients should support the old name as a fallback for compatibility. - metadata_info = file_data.get("core-metadata") - if metadata_info is None: - metadata_info = file_data.get("dist-info-metadata") - - if upload_time_data := file_data.get("upload-time"): - upload_time = parse_iso_datetime(upload_time_data) - else: - upload_time = None - - # The metadata info value may be a boolean, or a dict of hashes. - if isinstance(metadata_info, dict): - # The file exists, and hashes have been supplied - metadata_file_data = MetadataFile(supported_hashes(metadata_info)) - elif metadata_info: - # The file exists, but there are no hashes - metadata_file_data = MetadataFile(None) - else: - # False or not present: the file does not exist - metadata_file_data = None - - # The Link.yanked_reason expects an empty string instead of a boolean. - if yanked_reason and not isinstance(yanked_reason, str): - yanked_reason = "" - # The Link.yanked_reason expects None instead of False. - elif not yanked_reason: - yanked_reason = None - - return cls( - url, - comes_from=page_url, - requires_python=pyrequire, - yanked_reason=yanked_reason, - hashes=hashes, - metadata_file_data=metadata_file_data, - upload_time=upload_time, - ) - - @classmethod - def from_element( - cls, - anchor_attribs: dict[str, str | None], - page_url: str, - base_url: str, - ) -> Link | None: - """ - Convert an anchor element's attributes in a simple repository page to a Link. - """ - href = anchor_attribs.get("href") - if not href: - return None - - url = _ensure_quoted_url(_absolute_link_url(base_url, href)) - pyrequire = anchor_attribs.get("data-requires-python") - yanked_reason = anchor_attribs.get("data-yanked") - - # PEP 714: Indexes must use the name data-core-metadata, but - # clients should support the old name as a fallback for compatibility. - metadata_info = anchor_attribs.get("data-core-metadata") - if metadata_info is None: - metadata_info = anchor_attribs.get("data-dist-info-metadata") - # The metadata info value may be the string "true", or a string of - # the form "hashname=hashval" - if metadata_info == "true": - # The file exists, but there are no hashes - metadata_file_data = MetadataFile(None) - elif metadata_info is None: - # The file does not exist - metadata_file_data = None - else: - # The file exists, and hashes have been supplied - hashname, sep, hashval = metadata_info.partition("=") - if sep == "=": - metadata_file_data = MetadataFile(supported_hashes({hashname: hashval})) - else: - # Error - data is wrong. Treat as no hashes supplied. - logger.debug( - "Index returned invalid data-dist-info-metadata value: %s", - metadata_info, - ) - metadata_file_data = MetadataFile(None) - - return cls( - url, - comes_from=page_url, - requires_python=pyrequire, - yanked_reason=yanked_reason, - metadata_file_data=metadata_file_data, - ) - - def __str__(self) -> str: - if self.requires_python: - rp = f" (requires-python:{self.requires_python})" - else: - rp = "" - if self.comes_from: - return f"{self.redacted_url} (from {self.comes_from}){rp}" - else: - return self.redacted_url - - def __repr__(self) -> str: - return f"" - - def __hash__(self) -> int: - return hash(self.url) - - def __eq__(self, other: Any) -> bool: - if not isinstance(other, Link): - return NotImplemented - return self.url == other.url - - def __lt__(self, other: Any) -> bool: - if not isinstance(other, Link): - return NotImplemented - return self.url < other.url - - @property - def url(self) -> str: - return self._url - - @property - def redacted_url(self) -> str: - return redact_auth_from_url(self.url) - - @property - def filename(self) -> PathComponent: - name = _to_path_component(posixpath.basename(self.path.rstrip("/"))) - if name: - return name - - # No component in the path; fall back to the netloc, dropping any auth. - return _to_path_component(split_auth_from_netloc(self.netloc)[0]) - - @property - def file_path(self) -> str: - return url_to_path(self.url) - - @property - def scheme(self) -> str: - return self._parsed_url.scheme - - @property - def netloc(self) -> str: - """ - This can contain auth information. - """ - return self._parsed_url.netloc - - @property - def path(self) -> str: - return self._path - - def splitext(self) -> tuple[str, str]: - return splitext(posixpath.basename(self.path.rstrip("/"))) - - @property - def ext(self) -> str: - return self.splitext()[1] - - @property - def url_without_fragment(self) -> str: - scheme, netloc, path, query, fragment = self._parsed_url - return urllib.parse.urlunsplit((scheme, netloc, path, query, "")) - - _egg_fragment_re = re.compile(r"[#&]egg=([^&]*)") - - # Per PEP 508. - _project_name_re = re.compile( - r"^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$", re.IGNORECASE - ) - - def _egg_fragment(self) -> str | None: - match = self._egg_fragment_re.search(self._url) - if not match: - return None - - # An egg fragment looks like a PEP 508 project name, along with - # an optional extras specifier. Anything else is invalid. - project_name = match.group(1) - if not self._project_name_re.match(project_name): - raise InvalidEggFragment(self, project_name) - - return project_name - - _subdirectory_fragment_re = re.compile(r"[#&]subdirectory=([^&]*)") - - @property - def subdirectory_fragment(self) -> str | None: - match = self._subdirectory_fragment_re.search(self._url) - if not match: - return None - return match.group(1) - - def metadata_link(self) -> Link | None: - """Return a link to the associated core metadata file (if any).""" - if self.metadata_file_data is None: - return None - metadata_url = f"{self.url_without_fragment}.metadata" - if self.metadata_file_data.hashes is None: - return Link(metadata_url) - return Link(metadata_url, hashes=self.metadata_file_data.hashes) - - def as_hashes(self) -> Hashes: - return Hashes({k: [v] for k, v in self._hashes.items()}) - - @property - def hash(self) -> str | None: - return next(iter(self._hashes.values()), None) - - @property - def hash_name(self) -> str | None: - return next(iter(self._hashes), None) - - @property - def show_url(self) -> str: - return posixpath.basename(self._url.split("#", 1)[0].split("?", 1)[0]) - - @property - def is_file(self) -> bool: - return self.scheme == "file" - - def is_existing_dir(self) -> bool: - return self.is_file and os.path.isdir(self.file_path) - - @property - def is_wheel(self) -> bool: - return self.ext == WHEEL_EXTENSION - - @property - def is_vcs(self) -> bool: - from pip._internal.vcs import vcs - - return self.scheme in vcs.all_schemes - - @property - def is_yanked(self) -> bool: - return self.yanked_reason is not None - - @property - def has_hash(self) -> bool: - return bool(self._hashes) - - def is_hash_allowed(self, hashes: Hashes | None) -> bool: - """ - Return True if the link has a hash and it is allowed by `hashes`. - """ - if hashes is None: - return False - return any(hashes.is_hash_allowed(k, v) for k, v in self._hashes.items()) - - -class _CleanResult(NamedTuple): - """Convert link for equivalency check. - - This is used in the resolver to check whether two URL-specified requirements - likely point to the same distribution and can be considered equivalent. This - equivalency logic avoids comparing URLs literally, which can be too strict - (e.g. "a=1&b=2" vs "b=2&a=1") and produce conflicts unexpecting to users. - - Currently this does three things: - - 1. Drop the basic auth part. This is technically wrong since a server can - serve different content based on auth, but if it does that, it is even - impossible to guarantee two URLs without auth are equivalent, since - the user can input different auth information when prompted. So the - practical solution is to assume the auth doesn't affect the response. - 2. Parse the query to avoid the ordering issue. Note that ordering under the - same key in the query are NOT cleaned; i.e. "a=1&a=2" and "a=2&a=1" are - still considered different. - 3. Explicitly drop most of the fragment part, except ``subdirectory=`` and - hash values, since it should have no impact the downloaded content. Note - that this drops the "egg=" part historically used to denote the requested - project (and extras), which is wrong in the strictest sense, but too many - people are supplying it inconsistently to cause superfluous resolution - conflicts, so we choose to also ignore them. - """ - - parsed: urllib.parse.SplitResult - query: dict[str, list[str]] - subdirectory: str - hashes: dict[str, str] - - -def _clean_link(link: Link) -> _CleanResult: - parsed = link._parsed_url - netloc = parsed.netloc.rsplit("@", 1)[-1] - # According to RFC 8089, an empty host in file: means localhost. - if parsed.scheme == "file" and not netloc: - netloc = "localhost" - fragment = urllib.parse.parse_qs(parsed.fragment) - if "egg" in fragment: - logger.debug("Ignoring egg= fragment in %s", link) - try: - # If there are multiple subdirectory values, use the first one. - # This matches the behavior of Link.subdirectory_fragment. - subdirectory = fragment["subdirectory"][0] - except (IndexError, KeyError): - subdirectory = "" - # If there are multiple hash values under the same algorithm, use the - # first one. This matches the behavior of Link.hash_value. - hashes = {k: fragment[k][0] for k in _SUPPORTED_HASHES if k in fragment} - return _CleanResult( - parsed=parsed._replace(netloc=netloc, query="", fragment=""), - query=urllib.parse.parse_qs(parsed.query), - subdirectory=subdirectory, - hashes=hashes, - ) - - -@functools.cache -def links_equivalent(link1: Link, link2: Link) -> bool: - return _clean_link(link1) == _clean_link(link2) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/models/release_control.py b/venv/lib/python3.11/site-packages/pip/_internal/models/release_control.py deleted file mode 100755 index d432fa3..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/models/release_control.py +++ /dev/null @@ -1,91 +0,0 @@ -from __future__ import annotations - -from dataclasses import dataclass, field - -from pip._vendor.packaging.utils import NormalizedName, canonicalize_name - -from pip._internal.exceptions import CommandError - - -@dataclass(slots=True) -class ReleaseControl: - """Helper for managing which release types can be installed.""" - - all_releases: set[str] = field(default_factory=set) - only_final: set[str] = field(default_factory=set) - _order: list[tuple[str, str]] = field( - init=False, default_factory=list, compare=False, repr=False - ) - - def handle_mutual_excludes( - self, value: str, target: set[str], other: set[str], attr_name: str - ) -> None: - """Parse and apply release control option value. - - Processes comma-separated package names or special values `:all:` and `:none:`. - - When adding packages to target, they're removed from other to maintain mutual - exclusivity between all_releases and only_final. All operations are tracked in - order so that the original command-line argument sequence can be reconstructed - when passing options to build subprocesses. - """ - if value.startswith("-"): - raise CommandError( - "--all-releases / --only-final option requires 1 argument." - ) - new = value.split(",") - while ":all:" in new: - other.clear() - target.clear() - target.add(":all:") - # Track :all: in order - self._order.append((attr_name, ":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() - # Track :none: in order - self._order.append((attr_name, ":none:")) - continue - name = canonicalize_name(name) - other.discard(name) - target.add(name) - # Track package-specific setting in order - self._order.append((attr_name, name)) - - def get_ordered_args(self) -> list[tuple[str, str]]: - """ - Get ordered list of (flag_name, value) tuples for reconstructing CLI args. - - Returns: - List of tuples where each tuple is (attribute_name, value). - The attribute_name is either 'all_releases' or 'only_final'. - - Example: - [("all_releases", ":all:"), ("only_final", "simple")] - would be reconstructed as: - ["--all-releases", ":all:", "--only-final", "simple"] - """ - return self._order[:] - - def allows_prereleases(self, canonical_name: NormalizedName) -> bool | None: - """ - Determine if pre-releases are allowed for a package. - - Returns: - True: Pre-releases are allowed (package in all_releases) - False: Only final releases allowed (package in only_final) - None: No specific setting, use default behavior - """ - if canonical_name in self.all_releases: - return True - elif canonical_name in self.only_final: - return False - elif ":all:" in self.all_releases: - return True - elif ":all:" in self.only_final: - return False - return None diff --git a/venv/lib/python3.11/site-packages/pip/_internal/models/scheme.py b/venv/lib/python3.11/site-packages/pip/_internal/models/scheme.py deleted file mode 100755 index 5ed7057..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/models/scheme.py +++ /dev/null @@ -1,23 +0,0 @@ -""" -For types associated with installation schemes. - -For a general overview of available schemes and their context, see -https://docs.python.org/3/install/index.html#alternate-installation. -""" - -from dataclasses import dataclass - -SCHEME_KEYS = ["platlib", "purelib", "headers", "scripts", "data"] - - -@dataclass(frozen=True, slots=True) -class Scheme: - """A Scheme holds paths which are used as the base directories for - artifacts associated with a Python package. - """ - - platlib: str - purelib: str - headers: str - scripts: str - data: str diff --git a/venv/lib/python3.11/site-packages/pip/_internal/models/search_scope.py b/venv/lib/python3.11/site-packages/pip/_internal/models/search_scope.py deleted file mode 100755 index b3aaa18..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/models/search_scope.py +++ /dev/null @@ -1,124 +0,0 @@ -import itertools -import logging -import os -import posixpath -import urllib.parse -from dataclasses import dataclass - -from pip._vendor.packaging.utils import canonicalize_name - -from pip._internal.models.index import PyPI -from pip._internal.utils.compat import has_tls -from pip._internal.utils.misc import normalize_path, redact_auth_from_url - -logger = logging.getLogger(__name__) - - -@dataclass(frozen=True, slots=True) -class SearchScope: - """ - Encapsulates the locations that pip is configured to search. - """ - - find_links: list[str] - index_urls: list[str] - no_index: bool - - @classmethod - def create( - cls, - find_links: list[str], - index_urls: list[str], - no_index: bool, - ) -> "SearchScope": - """ - Create a SearchScope object after normalizing the `find_links`. - """ - # 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 ~... - built_find_links: list[str] = [] - for link in find_links: - if link.startswith("~"): - new_link = normalize_path(link) - if os.path.exists(new_link): - link = new_link - built_find_links.append(link) - - # 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(index_urls, built_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 - - return cls( - find_links=built_find_links, - index_urls=index_urls, - no_index=no_index, - ) - - def get_formatted_locations(self) -> str: - lines = [] - redacted_index_urls = [] - if self.index_urls and self.index_urls != [PyPI.simple_url]: - for url in self.index_urls: - redacted_index_url = redact_auth_from_url(url) - - # Parse the URL - purl = urllib.parse.urlsplit(redacted_index_url) - - # URL is generally invalid if scheme and netloc is missing - # there are issues with Python and URL parsing, so this test - # is a bit crude. See bpo-20271, bpo-23505. Python doesn't - # always parse invalid URLs correctly - it should raise - # exceptions for malformed URLs - if not purl.scheme and not purl.netloc: - logger.warning( - 'The index url "%s" seems invalid, please provide a scheme.', - redacted_index_url, - ) - - redacted_index_urls.append(redacted_index_url) - - lines.append( - "Looking in indexes: {}".format(", ".join(redacted_index_urls)) - ) - - if self.find_links: - lines.append( - "Looking in links: {}".format( - ", ".join(redact_auth_from_url(url) for url in self.find_links) - ) - ) - return "\n".join(lines) - - def get_index_urls_locations(self, project_name: str) -> list[str]: - """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: str) -> str: - 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] diff --git a/venv/lib/python3.11/site-packages/pip/_internal/models/selection_prefs.py b/venv/lib/python3.11/site-packages/pip/_internal/models/selection_prefs.py deleted file mode 100755 index 3473031..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/models/selection_prefs.py +++ /dev/null @@ -1,36 +0,0 @@ -from __future__ import annotations - -from dataclasses import dataclass - -from pip._internal.models.format_control import FormatControl -from pip._internal.models.release_control import ReleaseControl - - -@dataclass(slots=True) -class SelectionPreferences: - """ - Encapsulates the candidate selection preferences for downloading - and installing files. - - :param allow_yanked: Whether files marked as yanked (in the sense - of PEP 592) are permitted to be candidates for install. - :param release_control: A ReleaseControl object or None. Used to control - whether pre-releases are allowed for specific packages. - :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 prefer_binary: Whether to prefer an old, but valid, binary - dist over a new source dist. - :param ignore_requires_python: Whether to ignore incompatible - "Requires-Python" values in links. Defaults to False. - """ - - # Don't include an allow_yanked default value to make sure each call - # site considers whether yanked releases are allowed. This also causes - # that decision to be made explicit in the calling code, which helps - # people when reading the code. - allow_yanked: bool - release_control: ReleaseControl | None = None - format_control: FormatControl | None = None - prefer_binary: bool = False - ignore_requires_python: bool = False diff --git a/venv/lib/python3.11/site-packages/pip/_internal/models/target_python.py b/venv/lib/python3.11/site-packages/pip/_internal/models/target_python.py deleted file mode 100755 index 8c38392..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/models/target_python.py +++ /dev/null @@ -1,122 +0,0 @@ -from __future__ import annotations - -import sys - -from pip._vendor.packaging.tags import Tag - -from pip._internal.utils.compatibility_tags import get_supported, version_info_to_nodot -from pip._internal.utils.misc import normalize_version_info - - -class TargetPython: - """ - Encapsulates the properties of a Python interpreter one is targeting - for a package install, download, etc. - """ - - __slots__ = [ - "_given_py_version_info", - "abis", - "implementation", - "platforms", - "py_version", - "py_version_info", - "_valid_tags", - "_valid_tags_set", - ] - - def __init__( - self, - platforms: list[str] | None = None, - py_version_info: tuple[int, ...] | None = None, - abis: list[str] | None = None, - implementation: str | None = None, - ) -> None: - """ - :param platforms: A list of strings or None. If None, searches for - packages that are supported by the current system. Otherwise, will - find packages that can be built on the platforms passed in. These - packages will only be downloaded for distribution: they will - not be built locally. - :param py_version_info: An optional tuple of ints representing the - Python version information to use (e.g. `sys.version_info[:3]`). - This can have length 1, 2, or 3 when provided. - :param abis: A list of strings or None. This is passed to - compatibility_tags.py's get_supported() function as is. - :param implementation: A string or None. This is passed to - compatibility_tags.py's get_supported() function as is. - """ - # Store the given py_version_info for when we call get_supported(). - self._given_py_version_info = py_version_info - - if py_version_info is None: - py_version_info = sys.version_info[:3] - else: - py_version_info = normalize_version_info(py_version_info) - - py_version = ".".join(map(str, py_version_info[:2])) - - self.abis = abis - self.implementation = implementation - self.platforms = platforms - self.py_version = py_version - self.py_version_info = py_version_info - - # This is used to cache the return value of get_(un)sorted_tags. - self._valid_tags: list[Tag] | None = None - self._valid_tags_set: set[Tag] | None = None - - def format_given(self) -> str: - """ - Format the given, non-None attributes for display. - """ - display_version = None - if self._given_py_version_info is not None: - display_version = ".".join( - str(part) for part in self._given_py_version_info - ) - - key_values = [ - ("platforms", self.platforms), - ("version_info", display_version), - ("abis", self.abis), - ("implementation", self.implementation), - ] - return " ".join( - f"{key}={value!r}" for key, value in key_values if value is not None - ) - - def get_sorted_tags(self) -> list[Tag]: - """ - Return the supported PEP 425 tags to check wheel candidates against. - - The tags are returned in order of preference (most preferred first). - """ - if self._valid_tags is None: - # Pass versions=None if no py_version_info was given since - # versions=None uses special default logic. - py_version_info = self._given_py_version_info - if py_version_info is None: - version = None - else: - version = version_info_to_nodot(py_version_info) - - tags = get_supported( - version=version, - platforms=self.platforms, - abis=self.abis, - impl=self.implementation, - ) - self._valid_tags = tags - - return self._valid_tags - - def get_unsorted_tags(self) -> set[Tag]: - """Exactly the same as get_sorted_tags, but returns a set. - - This is important for performance. - """ - if self._valid_tags_set is None: - self._valid_tags_set = set(self.get_sorted_tags()) - - return self._valid_tags_set diff --git a/venv/lib/python3.11/site-packages/pip/_internal/models/wheel.py b/venv/lib/python3.11/site-packages/pip/_internal/models/wheel.py deleted file mode 100755 index fbd4902..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/models/wheel.py +++ /dev/null @@ -1,80 +0,0 @@ -"""Represents a wheel file and provides access to the various parts of the -name that have meaning. -""" - -from __future__ import annotations - -from collections.abc import Iterable - -from pip._vendor.packaging.tags import Tag -from pip._vendor.packaging.utils import ( - InvalidWheelFilename as _PackagingInvalidWheelFilename, -) -from pip._vendor.packaging.utils import parse_wheel_filename - -from pip._internal.exceptions import InvalidWheelFilename - - -class Wheel: - """A wheel file""" - - def __init__(self, filename: str) -> None: - self.filename = filename - - try: - wheel_info = parse_wheel_filename(filename) - except _PackagingInvalidWheelFilename as e: - raise InvalidWheelFilename(e.args[0]) from None - - self.name, _version, self.build_tag, self.file_tags = wheel_info - self.version = str(_version) - - def get_formatted_file_tags(self) -> list[str]: - """Return the wheel's tags as a sorted list of strings.""" - return sorted(str(tag) for tag in self.file_tags) - - def support_index_min(self, tags: list[Tag]) -> int: - """Return the lowest index that one of the wheel's file_tag combinations - achieves in the given list of supported tags. - - For example, if there are 8 supported tags and one of the file tags - is first in the list, then return 0. - - :param tags: the PEP 425 tags to check the wheel against, in order - with most preferred first. - - :raises ValueError: If none of the wheel's file tags match one of - the supported tags. - """ - try: - return next(i for i, t in enumerate(tags) if t in self.file_tags) - except StopIteration: - raise ValueError() - - def find_most_preferred_tag( - self, tags: list[Tag], tag_to_priority: dict[Tag, int] - ) -> int: - """Return the priority of the most preferred tag that one of the wheel's file - tag combinations achieves in the given list of supported tags using the given - tag_to_priority mapping, where lower priorities are more-preferred. - - This is used in place of support_index_min in some cases in order to avoid - an expensive linear scan of a large list of tags. - - :param tags: the PEP 425 tags to check the wheel against. - :param tag_to_priority: a mapping from tag to priority of that tag, where - lower is more preferred. - - :raises ValueError: If none of the wheel's file tags match one of - the supported tags. - """ - return min( - tag_to_priority[tag] for tag in self.file_tags if tag in tag_to_priority - ) - - def supported(self, tags: Iterable[Tag]) -> bool: - """Return whether the wheel is compatible with one of the given tags. - - :param tags: the PEP 425 tags to check the wheel against. - """ - return not self.file_tags.isdisjoint(tags) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/network/__init__.py b/venv/lib/python3.11/site-packages/pip/_internal/network/__init__.py deleted file mode 100755 index 0ae1f56..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/network/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Contains purely network-related utilities.""" diff --git a/venv/lib/python3.11/site-packages/pip/_internal/network/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/network/__pycache__/__init__.cpython-311.pyc deleted file mode 100755 index 07e2175b29ff7872f11130f90b68bf8cdf4dc389..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 254 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 O@|1;qx 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 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/network/__pycache__/download.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/network/__pycache__/download.cpython-311.pyc deleted file mode 100755 index a200bae32f8dad06df1814fb38f3b2f35d8be0ef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18655 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 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/network/__pycache__/lazy_wheel.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/network/__pycache__/lazy_wheel.cpython-311.pyc deleted file mode 100755 index aee0523e85533ac251210747fe06e92b712b47ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12877 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 Vvp&3CuT^e*#1cP#1_~2x{x8PoH!lDH diff --git a/venv/lib/python3.11/site-packages/pip/_internal/network/__pycache__/utils.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/network/__pycache__/utils.cpython-311.pyc deleted file mode 100755 index 792e550cb5829e05989b4f6b4c384efa6773fdaf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7104 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 J2!!M&5gz{eBLdMyJk}*+B-bNC1=qZM0G9 zAEfUCK9FDER(9sVI!(T}%sYgX+6I@H5Yx4@SVr)=FBGQUHb>u~jX$o_*I_W!#CS{o zkm>I+{in(-v<^J}G7oPMjW19ZNKHh6jF8kQ(|9K-Keq0H|$oY5)KL diff --git a/venv/lib/python3.11/site-packages/pip/_internal/network/__pycache__/xmlrpc.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/network/__pycache__/xmlrpc.cpython-311.pyc deleted file mode 100755 index a79a89a1565f9fcdff843030d3e5aebd2081ac11..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3223 zcmaJ@O>7&-6`tjC|M)M`CiQ2Vb|l7ZY|^e(H$a27iQ-sJQ^lwSB;jSf;*O+cmRx3b zsULzWjKDzI!ay%7A_P6~(5eX>6h%+H);;t}2}HG6z<_|BdZXb4Fai|ln_Vs?Izne> z-@G^P&CkAh-<$nYG#Wxs{%$brX z2Q91fRiPv>)F!BlRjDMoJg0}M;ZoS;c|B5%mZA*80*Qg0pa-k5Qmh&;#a+FqC#qwm zF$M(?W-3X4BRI9kAoLhsuawRN&~2nj50M(eT;;6aUrGDi9t-yHdZm<61NTrq+`P0| z)k(dqYs-ZtqSVZ~L9DD+t?RgoYnEbZM(saz$YP#xqDvp$y(P~t+?xN{oyFVGkzT~s zhCx1_H)=Iprna{TF$icvceVOGY?{yoQi3R&iRBf8$R^C$F!KRNk{1lqTH2~(Co2D3 zA?BK*>&mi@!9ILXYhv}S#>xsN<-v~KCNdD7tHAsUP5>kDJSqiLro>7}9aC8xRD+mP zIn1lPDy)cYw8E(3!)Qrx^^zJ=!(bCpqiT%WU{Q@v4A)o*sfmYNNou1_rW67XC7mRE z%7?C#h7M}};w~}PH5F%-?EO<5c>g62X4f@^njSmlekcpYSgwHE3NHVSBWX1iZ^{j# zJA&!?&WSX@Z>nNpORHjsC)jF`+G064+%Q7)OzHdl&p>|1e1@!HR3NkmeUIVwO6P>e z??b4?j>Zy$tP}HB=-h7UoapuYU^Fv2dOO$(R(zbG7Ls}2wiN&g5aksWfp?k3yy$Rd zqmGFq%Cc6|ELnDVZ~+9Q!_^@yup@%#alBbxgSd1AdBBMBz)^YL37S}6Av8irl#&<_ zC+ztYhFd0toLtrw)0AbCZi=2j_QAIw6xWO@E>;y%Hj3{WtHzC@Qm+@+ac#W_yC~MT ztTm%{qj3Ft(bOz_wXT#uR#vfDtZVfmY}vx3rs&0*2Zf>+4u$#_p6^Xu&34$% zT6T8&iLUh#8Hj7GniKJ1Bd=KOV|v;9c}7(?XSDPm5^6g+5vw=3*kI)8_=NFq1NXizZ@T)Y% zHbo0>S~ND7@~jhtgrY!jU`55mba)6CtW=xl7nYXpW--m+*;zBYv8L%byNWGKtF1yu ze#{AJrdERtUMpjVg;68}yCNw{&H!;jfYe6K#VVmraDsIji}b9>MJmT!olG#?Gc|xV zOOy>l562OQeY|e0uF`x^CYq&{72OGYmxf$6RGbeH3LA2sk_(h%DRF0~`2t|h!Y;@R z?Y#oTVew|!q{ryu-6e#2-w_6&XilDj(SeT6YyKAqAT)*≤s2WcTAUz4%O598`Pk z?9TMA)%oBH^)GM#ZKj*}Nt=5bJM&0CjLjazW;=L4cBL1)(q{XCq?EKXvz=x){r&cB zJ2SPjeVEA~Wb$?*WuLtWNQSPLt{chOQ>qh2YJdMxxksu|HiJeOCywQzZ@aoe@^0)8*=6ySH z4Hn&r^b(h$eI^8>upE%SOF}4`d;z5&hnb)?smuS)y*c()20h7y=F{wxi`VAI*nf<1 zz~`BF@?o03Yf2SE`VPr*)leHcG8bOv-qb$qhRhW-Z*gL^x!_eJS>2Ov9 zemlqw+8rIF>N3`KSf>0Z!~AN)tqACC!aGn0EnI7`ajj9LtSYdFndZ#pXx=q8< zbkl=3&BE?Q0=FzIj?Fc!dKZlZDdasD(qxVrU8Q^C2OE}#|5WZ_eu=!#r}+FDimlfb?00VQh4{i!L9b*aP>mQL5`#8=dL;)kfLwXgxwd>W)?$&2>ksjb87L z)+092M=X=GgEzaU)uZ5SceEZ!lkH4Tn%sSTUz&mAf57+oJOgL{U9y}0{kh)6wP#fI K^(lJSCI18TMK8So diff --git a/venv/lib/python3.11/site-packages/pip/_internal/network/auth.py b/venv/lib/python3.11/site-packages/pip/_internal/network/auth.py deleted file mode 100755 index 99b929a..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/network/auth.py +++ /dev/null @@ -1,587 +0,0 @@ -"""Network Authentication Helpers - -Contains interface (MultiDomainBasicAuth) and associated glue code for -providing credentials in the context of network requests. -""" - -from __future__ import annotations - -import json -import logging -import os -import shutil -import subprocess -import sysconfig -import typing -import urllib.parse -from abc import ABC, abstractmethod -from functools import cache -from os.path import commonpath -from pathlib import Path -from typing import Any, NamedTuple - -from pip._vendor.requests.auth import AuthBase, HTTPBasicAuth -from pip._vendor.requests.utils import get_netrc_auth - -from pip._internal.utils.logging import getLogger -from pip._internal.utils.misc import ( - ask, - ask_input, - ask_password, - remove_auth_from_url, - split_auth_netloc_from_url, -) -from pip._internal.vcs.versioncontrol import AuthInfo - -if typing.TYPE_CHECKING: - from pip._vendor.requests import PreparedRequest - from pip._vendor.requests.models import Response - -logger = getLogger(__name__) - -KEYRING_DISABLED = False - - -class Credentials(NamedTuple): - url: str - username: str - password: str - - -class KeyRingBaseProvider(ABC): - """Keyring base provider interface""" - - has_keyring: bool - - @abstractmethod - def get_auth_info(self, url: str, username: str | None) -> AuthInfo | None: ... - - @abstractmethod - def save_auth_info(self, url: str, username: str, password: str) -> None: ... - - -class KeyRingNullProvider(KeyRingBaseProvider): - """Keyring null provider""" - - has_keyring = False - - def get_auth_info(self, url: str, username: str | None) -> AuthInfo | None: - return None - - def save_auth_info(self, url: str, username: str, password: str) -> None: - return None - - -class KeyRingPythonProvider(KeyRingBaseProvider): - """Keyring interface which uses locally imported `keyring`""" - - has_keyring = True - - def __init__(self) -> None: - import keyring - - self.keyring = keyring - - def get_auth_info(self, url: str, username: str | None) -> AuthInfo | None: - # Support keyring's get_credential interface which supports getting - # credentials without a username. This is only available for - # keyring>=15.2.0. - if hasattr(self.keyring, "get_credential"): - logger.debug("Getting credentials from keyring for %s", url) - cred = self.keyring.get_credential(url, username) - if cred is not None: - return cred.username, cred.password - return None - - if username is not None: - logger.debug("Getting password from keyring for %s", url) - password = self.keyring.get_password(url, username) - if password: - return username, password - return None - - def save_auth_info(self, url: str, username: str, password: str) -> None: - self.keyring.set_password(url, username, password) - - -class KeyRingCliProvider(KeyRingBaseProvider): - """Provider which uses `keyring` cli - - Instead of calling the keyring package installed alongside pip - we call keyring on the command line which will enable pip to - use which ever installation of keyring is available first in - PATH. - """ - - has_keyring = True - - def __init__(self, cmd: str) -> None: - self.keyring = cmd - - def get_auth_info(self, url: str, username: str | None) -> AuthInfo | None: - return self._get_creds(url, username) - - def save_auth_info(self, url: str, username: str, password: str) -> None: - return self._set_password(url, username, password) - - def _get_creds(self, service_name: str, username: str | None) -> AuthInfo | None: - """Mirror the implementation of keyring.get_credential using cli""" - if self.keyring is None: - return None - - cmd = [self.keyring, "--mode=creds", "--output=json", "get", service_name] - if username is not None: - cmd.append(username) - - env = os.environ.copy() - env["PYTHONIOENCODING"] = "utf-8" - res = subprocess.run( # noqa: UP022 - cmd, - stdin=subprocess.DEVNULL, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - env=env, - ) - - # Detect if the user is running an outdated version of keyring without support - # for querying credentials without username - errs = res.stderr.decode("utf-8") - if ( - res.returncode == 2 - and "unrecognized arguments" in errs - and "--mode=creds" in errs - ): - raise RuntimeError( - "Keyring util is outdated; must be at least version 25.2.1, " - "please upgrade it" - ) - - if res.returncode: - return None - - data = json.loads(res.stdout.decode("utf-8")) - return (data["username"], data["password"]) - - def _set_password(self, service_name: str, username: str, password: str) -> None: - """Mirror the implementation of keyring.set_password using cli""" - if self.keyring is None: - return None - env = os.environ.copy() - env["PYTHONIOENCODING"] = "utf-8" - subprocess.run( - [self.keyring, "set", service_name, username], - input=f"{password}{os.linesep}".encode(), - env=env, - check=True, - ) - return None - - -@cache -def get_keyring_provider(provider: str) -> KeyRingBaseProvider: - logger.verbose("Keyring provider requested: %s", provider) - - # keyring has previously failed and been disabled - if KEYRING_DISABLED: - provider = "disabled" - if provider in ["import", "auto"]: - try: - impl = KeyRingPythonProvider() - logger.verbose("Keyring provider set: import") - return impl - except ImportError: - pass - except Exception as exc: - # In the event of an unexpected exception - # we should warn the user - msg = "Installed copy of keyring fails with exception %s" - if provider == "auto": - msg = msg + ", trying to find a keyring executable as a fallback" - logger.warning(msg, exc, exc_info=logger.isEnabledFor(logging.DEBUG)) - if provider in ["subprocess", "auto"]: - cli = shutil.which("keyring") - if cli and cli.startswith(sysconfig.get_path("scripts")): - # all code within this function is stolen from shutil.which implementation - @typing.no_type_check - def PATH_as_shutil_which_determines_it() -> str: - path = os.environ.get("PATH", None) - if path is None: - try: - path = os.confstr("CS_PATH") - except (AttributeError, ValueError): - # os.confstr() or CS_PATH is not available - path = os.defpath - # bpo-35755: Don't use os.defpath if the PATH environment variable is - # set to an empty string - - return path - - scripts = Path(sysconfig.get_path("scripts")) - - paths = [] - for path in PATH_as_shutil_which_determines_it().split(os.pathsep): - p = Path(path) - try: - if not p.samefile(scripts): - paths.append(path) - except FileNotFoundError: - pass - - path = os.pathsep.join(paths) - - cli = shutil.which("keyring", path=path) - - if cli: - logger.verbose("Keyring provider set: subprocess with executable %s", cli) - return KeyRingCliProvider(cli) - - logger.verbose("Keyring provider set: disabled") - return KeyRingNullProvider() - - -class MultiDomainBasicAuth(AuthBase): - def __init__( - self, - prompting: bool = True, - index_urls: list[str] | None = None, - keyring_provider: str = "auto", - ) -> None: - self.prompting = prompting - self.index_urls = index_urls - self.keyring_provider = keyring_provider - self.passwords: dict[str, AuthInfo] = {} - # When the user is prompted to enter credentials and keyring is - # available, we will offer to save them. If the user accepts, - # this value is set to the credentials they entered. After the - # request authenticates, the caller should call - # ``save_credentials`` to save these. - self._credentials_to_save: Credentials | None = None - - @property - def keyring_provider(self) -> KeyRingBaseProvider: - return get_keyring_provider(self._keyring_provider) - - @keyring_provider.setter - def keyring_provider(self, provider: str) -> None: - # The free function get_keyring_provider has been decorated with - # functools.cache. If an exception occurs in get_keyring_auth that - # cache will be cleared and keyring disabled, take that into account - # if you want to remove this indirection. - self._keyring_provider = provider - - @property - def use_keyring(self) -> bool: - # We won't use keyring when --no-input is passed unless - # a specific provider is requested because it might require - # user interaction - return self.prompting or self._keyring_provider not in ["auto", "disabled"] - - def _get_keyring_auth( - self, - url: str | None, - username: str | None, - ) -> AuthInfo | None: - """Return the tuple auth for a given url from keyring.""" - # Do nothing if no url was provided - if not url: - return None - - try: - return self.keyring_provider.get_auth_info(url, username) - except Exception as exc: - # Log the full exception (with stacktrace) at debug, so it'll only - # show up when running in verbose mode. - logger.debug("Keyring is skipped due to an exception", exc_info=True) - # Always log a shortened version of the exception. - logger.warning( - "Keyring is skipped due to an exception: %s", - str(exc), - ) - global KEYRING_DISABLED - KEYRING_DISABLED = True - get_keyring_provider.cache_clear() - return None - - def _get_index_url(self, url: str) -> str | None: - """Return the original index URL matching the requested URL. - - Cached or dynamically generated credentials may work against - the original index URL rather than just the netloc. - - The provided url should have had its username and password - removed already. If the original index url had credentials then - they will be included in the return value. - - Returns None if no matching index was found, or if --no-index - was specified by the user. - """ - if not url or not self.index_urls: - return None - - url = remove_auth_from_url(url).rstrip("/") + "/" - parsed_url = urllib.parse.urlsplit(url) - - candidates = [] - - for index in self.index_urls: - index = index.rstrip("/") + "/" - parsed_index = urllib.parse.urlsplit(remove_auth_from_url(index)) - if parsed_url == parsed_index: - return index - - if parsed_url.netloc != parsed_index.netloc: - continue - - candidate = urllib.parse.urlsplit(index) - candidates.append(candidate) - - if not candidates: - return None - - candidates.sort( - reverse=True, - key=lambda candidate: len( - commonpath( - [ - parsed_url.path, - candidate.path, - ] - ) - ), - ) - - return urllib.parse.urlunsplit(candidates[0]) - - def _get_new_credentials( - self, - original_url: str, - *, - allow_netrc: bool = True, - allow_keyring: bool = False, - ) -> AuthInfo: - """Find and return credentials for the specified URL.""" - # Split the credentials and netloc from the url. - url, netloc, url_user_password = split_auth_netloc_from_url( - original_url, - ) - - # Start with the credentials embedded in the url - username, password = url_user_password - if username is not None and password is not None: - logger.debug("Found credentials in url for %s", netloc) - return url_user_password - - # Find a matching index url for this request - index_url = self._get_index_url(url) - if index_url: - # Split the credentials from the url. - index_info = split_auth_netloc_from_url(index_url) - if index_info: - index_url, _, index_url_user_password = index_info - logger.debug("Found index url %s", index_url) - - # If an index URL was found, try its embedded credentials - if index_url and index_url_user_password[0] is not None: - username, password = index_url_user_password - if username is not None and password is not None: - logger.debug("Found credentials in index url for %s", netloc) - return index_url_user_password - - # Get creds from netrc if we still don't have them - if allow_netrc: - netrc_auth = get_netrc_auth(original_url) - if netrc_auth: - logger.debug("Found credentials in netrc for %s", netloc) - return netrc_auth - - # If we don't have a password and keyring is available, use it. - if allow_keyring: - # The index url is more specific than the netloc, so try it first - # fmt: off - kr_auth = ( - self._get_keyring_auth(index_url, username) or - self._get_keyring_auth(netloc, username) - ) - # fmt: on - if kr_auth: - logger.debug("Found credentials in keyring for %s", netloc) - return kr_auth - - return username, password - - def _get_url_and_credentials( - self, original_url: str - ) -> tuple[str, str | None, str | None]: - """Return the credentials to use for the provided URL. - - If allowed, netrc and keyring may be used to obtain the - correct credentials. - - Returns (url_without_credentials, username, password). Note - that even if the original URL contains credentials, this - function may return a different username and password. - """ - url, netloc, _ = split_auth_netloc_from_url(original_url) - - # Try to get credentials from original url - username, password = self._get_new_credentials(original_url) - - # If credentials not found, use any stored credentials for this netloc. - # Do this if either the username or the password is missing. - # This accounts for the situation in which the user has specified - # the username in the index url, but the password comes from keyring. - if (username is None or password is None) and netloc in self.passwords: - un, pw = self.passwords[netloc] - # It is possible that the cached credentials are for a different username, - # in which case the cache should be ignored. - if username is None or username == un: - username, password = un, pw - - if username is not None or password is not None: - # Convert the username and password if they're None, so that - # this netloc will show up as "cached" in the conditional above. - # Further, HTTPBasicAuth doesn't accept None, so it makes sense to - # cache the value that is going to be used. - username = username or "" - password = password or "" - - # Store any acquired credentials. - self.passwords[netloc] = (username, password) - - assert ( - # Credentials were found - (username is not None and password is not None) - # Credentials were not found - or (username is None and password is None) - ), f"Could not load credentials from url: {original_url}" - - return url, username, password - - def __call__(self, req: PreparedRequest) -> PreparedRequest: - # Get credentials for this request - assert req.url is not None - url, username, password = self._get_url_and_credentials(req.url) - - # Set the url of the request to the url without any credentials - req.url = url - - if username is not None and password is not None: - # Send the basic auth with this request - req = HTTPBasicAuth(username, password)(req) - - # Attach a hook to handle 401 responses - req.register_hook("response", self.handle_401) - - return req - - # Factored out to allow for easy patching in tests - def _prompt_for_password(self, netloc: str) -> tuple[str | None, str | None, bool]: - username = ask_input(f"User for {netloc}: ") if self.prompting else None - if not username: - return None, None, False - if self.use_keyring: - auth = self._get_keyring_auth(netloc, username) - if auth and auth[0] is not None and auth[1] is not None: - return auth[0], auth[1], False - password = ask_password("Password: ") - return username, password, True - - # Factored out to allow for easy patching in tests - def _should_save_password_to_keyring(self) -> bool: - if ( - not self.prompting - or not self.use_keyring - or not self.keyring_provider.has_keyring - ): - return False - return ask("Save credentials to keyring [y/N]: ", ["y", "n"]) == "y" - - def handle_401(self, resp: Response, **kwargs: Any) -> Response: - # We only care about 401 responses, anything else we want to just - # pass through the actual response - if resp.status_code != 401: - return resp - - # Look for credentials for the (possibly redirected) URL. Credentials - # embedded in the URL -- e.g. carried in the ``Location`` of a - # cross-origin redirect, whose ``Authorization`` header requests strips - # -- are always honoured, since recovering them needs no user - # interaction. Keyring is only consulted when it is enabled, because it - # may require interaction and is therefore disabled under --no-input. - username, password = self._get_new_credentials( - resp.url, - allow_netrc=False, - allow_keyring=self.use_keyring, - ) - - # We are not able to prompt the user so simply return the response - if not self.prompting and not username and not password: - return resp - - parsed = urllib.parse.urlparse(resp.url) - - # Prompt the user for a new username and password - save = False - if not username and not password: - username, password, save = self._prompt_for_password(parsed.netloc) - - # Store the new username and password to use for future requests - self._credentials_to_save = None - if username is not None and password is not None: - self.passwords[parsed.netloc] = (username, password) - - # Prompt to save the password to keyring - if save and self._should_save_password_to_keyring(): - self._credentials_to_save = Credentials( - url=parsed.netloc, - username=username, - password=password, - ) - - # Consume content and release the original connection to allow our new - # request to reuse the same one. - # The result of the assignment isn't used, it's just needed to consume - # the content. - _ = resp.content - resp.raw.release_conn() - - # Add our new username and password to the request - req = HTTPBasicAuth(username or "", password or "")(resp.request) - req.register_hook("response", self.warn_on_401) - - # On successful request, save the credentials that were used to - # keyring. (Note that if the user responded "no" above, this member - # is not set and nothing will be saved.) - if self._credentials_to_save: - req.register_hook("response", self.save_credentials) - - # Send our new request - new_resp = resp.connection.send(req, **kwargs) - new_resp.history.append(resp) - - return new_resp - - def warn_on_401(self, resp: Response, **kwargs: Any) -> None: - """Response callback to warn about incorrect credentials.""" - if resp.status_code == 401: - logger.warning( - "401 Error, Credentials not correct for %s", - resp.request.url, - ) - - def save_credentials(self, resp: Response, **kwargs: Any) -> None: - """Response callback to save credentials on success.""" - assert ( - self.keyring_provider.has_keyring - ), "should never reach here without keyring" - - creds = self._credentials_to_save - self._credentials_to_save = None - if creds and resp.status_code < 400: - try: - logger.info("Saving credentials to keyring") - self.keyring_provider.save_auth_info( - creds.url, creds.username, creds.password - ) - except Exception: - logger.exception("Failed to save credentials") diff --git a/venv/lib/python3.11/site-packages/pip/_internal/network/cache.py b/venv/lib/python3.11/site-packages/pip/_internal/network/cache.py deleted file mode 100755 index bff9707..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/network/cache.py +++ /dev/null @@ -1,128 +0,0 @@ -"""HTTP cache implementation.""" - -from __future__ import annotations - -import os -import shutil -from collections.abc import Callable, Generator -from contextlib import contextmanager -from datetime import datetime -from typing import Any, BinaryIO - -from pip._vendor.cachecontrol.cache import SeparateBodyBaseCache -from pip._vendor.cachecontrol.caches import SeparateBodyFileCache -from pip._vendor.requests.models import Response - -from pip._internal.utils.filesystem import ( - adjacent_tmp_file, - copy_directory_permissions, - replace, -) -from pip._internal.utils.misc import ensure_dir - - -def is_from_cache(response: Response) -> bool: - return getattr(response, "from_cache", False) - - -@contextmanager -def suppressed_cache_errors() -> Generator[None, None, None]: - """If we can't access the cache then we can just skip caching and process - requests as if caching wasn't enabled. - """ - try: - yield - except OSError: - pass - - -class SafeFileCache(SeparateBodyBaseCache): - """ - A file based cache which is safe to use even when the target directory may - not be accessible or writable. - - There is a race condition when two processes try to write and/or read the - same entry at the same time, since each entry consists of two separate - files (https://github.com/psf/cachecontrol/issues/324). We therefore have - additional logic that makes sure that both files to be present before - returning an entry; this fixes the read side of the race condition. - - For the write side, we assume that the server will only ever return the - same data for the same URL, which ought to be the case for files pip is - downloading. PyPI does not have a mechanism to swap out a wheel for - another wheel, for example. If this assumption is not true, the - CacheControl issue will need to be fixed. - """ - - def __init__(self, directory: str) -> None: - assert directory is not None, "Cache directory must not be None." - super().__init__() - self.directory = directory - - def _get_cache_path(self, name: str) -> str: - # From cachecontrol.caches.file_cache.FileCache._fn, brought into our - # class for backwards-compatibility and to avoid using a non-public - # method. - hashed = SeparateBodyFileCache.encode(name) - parts = list(hashed[:5]) + [hashed] - return os.path.join(self.directory, *parts) - - def get(self, key: str) -> bytes | None: - # The cache entry is only valid if both metadata and body exist. - metadata_path = self._get_cache_path(key) - body_path = metadata_path + ".body" - if not (os.path.exists(metadata_path) and os.path.exists(body_path)): - return None - with suppressed_cache_errors(): - with open(metadata_path, "rb") as f: - return f.read() - - def _write_to_file(self, path: str, writer_func: Callable[[BinaryIO], Any]) -> None: - """Common file writing logic with proper permissions and atomic replacement.""" - with suppressed_cache_errors(): - ensure_dir(os.path.dirname(path)) - - with adjacent_tmp_file(path) as f: - writer_func(f) - # Inherit the read/write permissions of the cache directory - # to enable multi-user cache use-cases. - copy_directory_permissions(self.directory, f) - - replace(f.name, path) - - def _write(self, path: str, data: bytes) -> None: - self._write_to_file(path, lambda f: f.write(data)) - - def _write_from_io(self, path: str, source_file: BinaryIO) -> None: - self._write_to_file(path, lambda f: shutil.copyfileobj(source_file, f)) - - def set( - self, key: str, value: bytes, expires: int | datetime | None = None - ) -> None: - path = self._get_cache_path(key) - self._write(path, value) - - def delete(self, key: str) -> None: - path = self._get_cache_path(key) - with suppressed_cache_errors(): - os.remove(path) - with suppressed_cache_errors(): - os.remove(path + ".body") - - def get_body(self, key: str) -> BinaryIO | None: - # The cache entry is only valid if both metadata and body exist. - metadata_path = self._get_cache_path(key) - body_path = metadata_path + ".body" - if not (os.path.exists(metadata_path) and os.path.exists(body_path)): - return None - with suppressed_cache_errors(): - return open(body_path, "rb") - - def set_body(self, key: str, body: bytes) -> None: - path = self._get_cache_path(key) + ".body" - self._write(path, body) - - def set_body_from_io(self, key: str, body_file: BinaryIO) -> None: - """Set the body of the cache entry from a file object.""" - path = self._get_cache_path(key) + ".body" - self._write_from_io(path, body_file) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/network/download.py b/venv/lib/python3.11/site-packages/pip/_internal/network/download.py deleted file mode 100755 index 521abb7..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/network/download.py +++ /dev/null @@ -1,387 +0,0 @@ -"""Download files with progress indicators.""" - -from __future__ import annotations - -import email.message -import logging -import mimetypes -import os -from collections.abc import Iterable, Mapping -from dataclasses import dataclass -from http import HTTPStatus -from typing import BinaryIO - -from pip._vendor.requests import PreparedRequest -from pip._vendor.requests.models import Response -from pip._vendor.urllib3 import HTTPResponse as URLlib3Response -from pip._vendor.urllib3._collections import HTTPHeaderDict -from pip._vendor.urllib3.exceptions import ProtocolError, ReadTimeoutError - -from pip._internal.cli.progress_bars import BarType, get_download_progress_renderer -from pip._internal.exceptions import ( - ConnectionFailedError, - ConnectionTimeoutError, - IncompleteDownloadError, - NetworkConnectionError, - ProxyConnectionError, - SSLVerificationError, -) -from pip._internal.models.link import ( - Link, - PathComponent, - as_path_component, - join_within_directory, -) -from pip._internal.network.cache import SafeFileCache, is_from_cache -from pip._internal.network.session import CacheControlAdapter, PipSession -from pip._internal.network.utils import HEADERS, raise_for_status, response_chunks -from pip._internal.utils.misc import format_size, redact_auth_from_url, splitext - -logger = logging.getLogger(__name__) - - -def _get_http_response_size(resp: Response) -> int | None: - try: - size = int(resp.headers["content-length"]) - except (ValueError, KeyError, TypeError): - return None - # A negative length would make _FileDownload.is_incomplete() report a - # truncated download as complete, so treat it as unknown instead. - if size < 0: - return None - return size - - -def _get_http_response_etag_or_last_modified(resp: Response) -> str | None: - """ - Return either the ETag or Last-Modified header (or None if neither exists). - The return value can be used in an If-Range header. - """ - return resp.headers.get("etag", resp.headers.get("last-modified")) - - -def _log_download( - resp: Response, - link: Link, - progress_bar: BarType, - total_length: int | None, - range_start: int | None = 0, -) -> Iterable[bytes]: - if logger.getEffectiveLevel() > logging.INFO: - url = link.url_without_fragment - else: - url = link.show_url - - logged_url = redact_auth_from_url(url) - - if total_length: - if range_start: - logged_url = ( - f"{logged_url} ({format_size(range_start)}/{format_size(total_length)})" - ) - else: - logged_url = f"{logged_url} ({format_size(total_length)})" - - if is_from_cache(resp): - logger.info("Using cached %s", logged_url) - elif range_start: - logger.info("Resuming download %s", logged_url) - else: - logger.info("Downloading %s", logged_url) - - if logger.getEffectiveLevel() > logging.INFO: - show_progress = False - elif is_from_cache(resp): - show_progress = False - elif not total_length: - show_progress = True - elif total_length > (512 * 1024): - show_progress = True - else: - show_progress = False - - chunks = response_chunks(resp) - - if not show_progress: - return chunks - - renderer = get_download_progress_renderer( - bar_type=progress_bar, size=total_length, initial_progress=range_start - ) - return renderer(chunks) - - -def sanitize_content_filename(filename: str) -> str: - """ - Sanitize the "filename" value from a Content-Disposition header. - """ - return os.path.basename(filename) - - -def parse_content_disposition(content_disposition: str, default_filename: str) -> str: - """ - Parse the "filename" value from a Content-Disposition header, and - return the default filename if the result is empty. - """ - m = email.message.Message() - m["content-type"] = content_disposition - filename = m.get_param("filename") - if filename: - # We need to sanitize the filename to prevent directory traversal - # in case the filename contains ".." path parts. - filename = sanitize_content_filename(str(filename)) - return filename or default_filename - - -def _get_http_response_filename(resp: Response, link: Link) -> PathComponent: - """Get an ideal filename from the given HTTP response, falling back to - the link filename if not provided. - - The result is validated as a single path component, so it can be joined onto - a download directory without escaping it. - """ - filename: str = link.filename # fallback - # Have a look at the Content-Disposition header for a better guess - content_disposition = resp.headers.get("content-disposition") - if content_disposition: - filename = parse_content_disposition(content_disposition, filename) - ext: str | None = splitext(filename)[1] - if not ext: - ext = mimetypes.guess_extension(resp.headers.get("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 - return as_path_component(filename) - - -@dataclass -class _FileDownload: - """Stores the state of a single link download.""" - - link: Link - output_file: BinaryIO - size: int | None - bytes_received: int = 0 - reattempts: int = 0 - - def is_incomplete(self) -> bool: - return bool(self.size is not None and self.bytes_received < self.size) - - def write_chunk(self, data: bytes) -> None: - self.bytes_received += len(data) - self.output_file.write(data) - - def reset_file(self) -> None: - """Delete any saved data and reset progress to zero.""" - self.output_file.seek(0) - self.output_file.truncate() - self.bytes_received = 0 - - -class Downloader: - def __init__( - self, - session: PipSession, - progress_bar: BarType, - ) -> None: - self._session = session - self._progress_bar = progress_bar - self._resume_retries = session.resume_retries - assert ( - self._resume_retries >= 0 - ), "Number of max resume retries must be bigger or equal to zero" - - def batch( - self, links: Iterable[Link], location: str - ) -> Iterable[tuple[Link, tuple[str, str]]]: - """Convenience method to download multiple links.""" - for link in links: - filepath, content_type = self(link, location) - yield link, (filepath, content_type) - - def __call__(self, link: Link, location: str) -> tuple[str, str]: - """Download a link and save it under location.""" - resp = self._http_get(link) - download_size = _get_http_response_size(resp) - - filepath = join_within_directory( - location, _get_http_response_filename(resp, link) - ) - with open(filepath, "wb") as content_file: - download = _FileDownload(link, content_file, download_size) - self._process_response(download, resp) - if download.is_incomplete(): - self._attempt_resumes_or_redownloads(download, resp) - - content_type = resp.headers.get("Content-Type", "") - return filepath, content_type - - def _process_response(self, download: _FileDownload, resp: Response) -> None: - """Download and save chunks from a response.""" - chunks = _log_download( - resp, - download.link, - self._progress_bar, - download.size, - range_start=download.bytes_received, - ) - try: - for chunk in chunks: - download.write_chunk(chunk) - except (ReadTimeoutError, ProtocolError) as e: - # If the download size is not known, then give up downloading the file. - if download.size is None: - raise e - - logger.warning("Connection interrupted while downloading.") - - def _attempt_resumes_or_redownloads( - self, download: _FileDownload, first_resp: Response - ) -> None: - """Attempt to resume/restart the download if connection was dropped.""" - - while download.reattempts < self._resume_retries and download.is_incomplete(): - assert download.size is not None - download.reattempts += 1 - logger.warning( - "Attempting to resume incomplete download (%s/%s, attempt %d)", - format_size(download.bytes_received), - format_size(download.size), - download.reattempts, - ) - - try: - resume_resp = self._http_get_resume(download, should_match=first_resp) - # Fallback: if the server responded with 200 (i.e., the file has - # since been modified or range requests are unsupported) or any - # other unexpected status, restart the download from the beginning. - must_restart = resume_resp.status_code != HTTPStatus.PARTIAL_CONTENT - if must_restart: - download.reset_file() - download.size = _get_http_response_size(resume_resp) - first_resp = resume_resp - else: - # If the resume request starts at the wrong location, fail - # outright since the server is misbehaving. - content_range = resume_resp.headers.get("Content-Range", "") - resumed_at = content_range.lower().partition("bytes ")[2] - resumed_at = resumed_at.partition("-")[0] - if resumed_at and resumed_at != str(download.bytes_received): - raise IncompleteDownloadError(download) - - self._process_response(download, resume_resp) - except ( - ConnectionFailedError, - ConnectionTimeoutError, - ProxyConnectionError, - SSLVerificationError, - ReadTimeoutError, - ProtocolError, - OSError, - ): - # The error handling here is tricky, a few notes: - # - # - The diagnostic connection errors are raised by our custom - # requests.request() connection exception handler. - # - ProtocolError is raised by urllib3 when the returned data length - # doesn't match the response Content-Length. - # - ReadTimeoutError / ProtocolError come straight from urllib3 (via - # process_response) and aren't caught by our connection exception - # handler since they occur while *streaming* a response. - continue - - # No more resume attempts. Raise an error if the download is still incomplete. - if download.is_incomplete(): - os.remove(download.output_file.name) - raise IncompleteDownloadError(download) - - # If we successfully completed the download via resume, manually cache it - # as a complete response to enable future caching - if download.reattempts > 0: - self._cache_resumed_download(download, first_resp) - - def _cache_resumed_download( - self, download: _FileDownload, original_response: Response - ) -> None: - """ - Manually cache a file that was successfully downloaded via resume retries. - - cachecontrol doesn't cache 206 (Partial Content) responses, since they - are not complete files. This method manually adds the final file to the - cache as though it was downloaded in a single request, so that future - requests can use the cache. - """ - url = download.link.url_without_fragment - adapter = self._session.get_adapter(url) - - # Check if the adapter is the CacheControlAdapter (i.e. caching is enabled) - if not isinstance(adapter, CacheControlAdapter): - logger.debug( - "Skipping resume download caching: no cache controller for %s", url - ) - return - - # Check SafeFileCache is being used - assert isinstance( - adapter.cache, SafeFileCache - ), "separate body cache not in use!" - - synthetic_request = PreparedRequest() - synthetic_request.prepare(method="GET", url=url, headers={}) - - synthetic_response_headers = HTTPHeaderDict() - for key, value in original_response.headers.items(): - if key.lower() not in ["content-range", "content-length"]: - synthetic_response_headers[key] = value - synthetic_response_headers["content-length"] = str(download.size) - - synthetic_response = URLlib3Response( - body="", - headers=synthetic_response_headers, - status=200, - preload_content=False, - ) - - # Save metadata and then stream the file contents to cache. - cache_url = adapter.controller.cache_url(url) - metadata_blob = adapter.controller.serializer.dumps( - synthetic_request, synthetic_response, b"" - ) - adapter.cache.set(cache_url, metadata_blob) - download.output_file.flush() - with open(download.output_file.name, "rb") as f: - adapter.cache.set_body_from_io(cache_url, f) - - logger.debug( - "Cached resumed download as complete response for future use: %s", url - ) - - def _http_get_resume( - self, download: _FileDownload, should_match: Response - ) -> Response: - """Issue a HTTP range request to resume the download.""" - # To better understand the download resumption logic, see the mdn web docs: - # https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Range_requests - headers = HEADERS.copy() - headers["Range"] = f"bytes={download.bytes_received}-" - # If possible, use a conditional range request to avoid corrupted - # downloads caused by the remote file changing in-between. - if identifier := _get_http_response_etag_or_last_modified(should_match): - headers["If-Range"] = identifier - return self._http_get(download.link, headers) - - def _http_get(self, link: Link, headers: Mapping[str, str] = HEADERS) -> Response: - target_url = link.url_without_fragment - try: - resp = self._session.get(target_url, headers=headers, stream=True) - raise_for_status(resp) - except NetworkConnectionError as e: - assert e.response is not None - logger.critical( - "HTTP error %s while getting %s", e.response.status_code, link - ) - raise - return resp diff --git a/venv/lib/python3.11/site-packages/pip/_internal/network/lazy_wheel.py b/venv/lib/python3.11/site-packages/pip/_internal/network/lazy_wheel.py deleted file mode 100755 index 0039833..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/network/lazy_wheel.py +++ /dev/null @@ -1,215 +0,0 @@ -"""Lazy ZIP over HTTP""" - -from __future__ import annotations - -__all__ = ["HTTPRangeRequestUnsupported", "dist_from_wheel_url"] - -from bisect import bisect_left, bisect_right -from collections.abc import Generator -from contextlib import contextmanager -from tempfile import NamedTemporaryFile -from typing import Any -from zipfile import BadZipFile, ZipFile - -from pip._vendor.packaging.utils import NormalizedName -from pip._vendor.requests.models import CONTENT_CHUNK_SIZE, Response - -from pip._internal.metadata import BaseDistribution, MemoryWheel, get_wheel_distribution -from pip._internal.network.session import PipSession -from pip._internal.network.utils import HEADERS, raise_for_status, response_chunks - - -class HTTPRangeRequestUnsupported(Exception): - pass - - -def dist_from_wheel_url( - name: NormalizedName, url: str, session: PipSession -) -> BaseDistribution: - """Return a distribution object from the given wheel URL. - - This uses HTTP range requests to only fetch the portion of the wheel - containing metadata, just enough for the object to be constructed. - If such requests are not supported, HTTPRangeRequestUnsupported - is raised. - """ - with LazyZipOverHTTP(url, session) as zf: - # For read-only ZIP files, ZipFile only needs methods read, - # seek, seekable and tell, not the whole IO protocol. - wheel = MemoryWheel(zf.name, zf) # type: ignore - # After context manager exit, wheel.name - # is an invalid file by intention. - return get_wheel_distribution(wheel, name) - - -class LazyZipOverHTTP: - """File-like object mapped to a ZIP file over HTTP. - - This uses HTTP range requests to lazily fetch the file's content, - which is supposed to be fed to ZipFile. If such requests are not - supported by the server, raise HTTPRangeRequestUnsupported - during initialization. - """ - - def __init__( - self, url: str, session: PipSession, chunk_size: int = CONTENT_CHUNK_SIZE - ) -> None: - head = session.head(url, headers=HEADERS) - raise_for_status(head) - assert head.status_code == 200 - self._session, self._url, self._chunk_size = session, url, chunk_size - self._length = int(head.headers["Content-Length"]) - self._file = NamedTemporaryFile() - self.truncate(self._length) - self._left: list[int] = [] - self._right: list[int] = [] - if "bytes" not in head.headers.get("Accept-Ranges", "none"): - raise HTTPRangeRequestUnsupported("range request is not supported") - self._check_zip() - - @property - def mode(self) -> str: - """Opening mode, which is always rb.""" - return "rb" - - @property - def name(self) -> str: - """Path to the underlying file.""" - return self._file.name - - def seekable(self) -> bool: - """Return whether random access is supported, which is True.""" - return True - - def close(self) -> None: - """Close the file.""" - self._file.close() - - @property - def closed(self) -> bool: - """Whether the file is closed.""" - return self._file.closed - - def read(self, size: int = -1) -> bytes: - """Read up to size bytes from the object and return them. - - As a convenience, if size is unspecified or -1, - all bytes until EOF are returned. Fewer than - size bytes may be returned if EOF is reached. - """ - download_size = max(size, self._chunk_size) - start, length = self.tell(), self._length - stop = length if size < 0 else min(start + download_size, length) - start = max(0, stop - download_size) - self._download(start, stop - 1) - return self._file.read(size) - - def readable(self) -> bool: - """Return whether the file is readable, which is True.""" - return True - - def seek(self, offset: int, whence: int = 0) -> int: - """Change stream position and return the new absolute position. - - Seek to offset relative position indicated by whence: - * 0: Start of stream (the default). pos should be >= 0; - * 1: Current position - pos may be negative; - * 2: End of stream - pos usually negative. - """ - return self._file.seek(offset, whence) - - def tell(self) -> int: - """Return the current position.""" - return self._file.tell() - - def truncate(self, size: int | None = None) -> int: - """Resize the stream to the given size in bytes. - - If size is unspecified resize to the current position. - The current stream position isn't changed. - - Return the new file size. - """ - return self._file.truncate(size) - - def writable(self) -> bool: - """Return False.""" - return False - - def __enter__(self) -> LazyZipOverHTTP: - self._file.__enter__() - return self - - def __exit__(self, *exc: Any) -> None: - self._file.__exit__(*exc) - - @contextmanager - def _stay(self) -> Generator[None, None, None]: - """Return a context manager keeping the position. - - At the end of the block, seek back to original position. - """ - pos = self.tell() - try: - yield - finally: - self.seek(pos) - - def _check_zip(self) -> None: - """Check and download until the file is a valid ZIP.""" - end = self._length - 1 - for start in reversed(range(0, end, self._chunk_size)): - self._download(start, end) - with self._stay(): - try: - # For read-only ZIP files, ZipFile only needs - # methods read, seek, seekable and tell. - ZipFile(self) - except BadZipFile: - pass - else: - break - - def _stream_response( - self, start: int, end: int, base_headers: dict[str, str] = HEADERS - ) -> Response: - """Return HTTP response to a range request from start to end.""" - headers = base_headers.copy() - headers["Range"] = f"bytes={start}-{end}" - # TODO: Get range requests to be correctly cached - headers["Cache-Control"] = "no-cache" - return self._session.get(self._url, headers=headers, stream=True) - - def _merge( - self, start: int, end: int, left: int, right: int - ) -> Generator[tuple[int, int], None, None]: - """Return a generator of intervals to be fetched. - - Args: - start (int): Start of needed interval - end (int): End of needed interval - left (int): Index of first overlapping downloaded data - right (int): Index after last overlapping downloaded data - """ - lslice, rslice = self._left[left:right], self._right[left:right] - i = start = min([start] + lslice[:1]) - end = max([end] + rslice[-1:]) - for j, k in zip(lslice, rslice): - if j > i: - yield i, j - 1 - i = k + 1 - if i <= end: - yield i, end - self._left[left:right], self._right[left:right] = [start], [end] - - def _download(self, start: int, end: int) -> None: - """Download bytes from start to end inclusively.""" - with self._stay(): - left = bisect_left(self._right, start) - right = bisect_right(self._left, end) - for start, end in self._merge(start, end, left, right): - response = self._stream_response(start, end) - response.raise_for_status() - self.seek(start) - for chunk in response_chunks(response, self._chunk_size): - self._file.write(chunk) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/network/session.py b/venv/lib/python3.11/site-packages/pip/_internal/network/session.py deleted file mode 100755 index 5ddbb2a..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/network/session.py +++ /dev/null @@ -1,532 +0,0 @@ -"""PipSession and supporting code, containing all pip-specific -network request configuration and behavior. -""" - -from __future__ import annotations - -import email.utils -import functools -import io -import ipaddress -import json -import logging -import mimetypes -import os -import platform -import shutil -import subprocess -import sys -import urllib.parse -import warnings -from collections.abc import Generator, Mapping, Sequence -from typing import ( - TYPE_CHECKING, - Any, -) - -from pip._vendor import requests, urllib3 -from pip._vendor.cachecontrol import CacheControlAdapter as _BaseCacheControlAdapter -from pip._vendor.requests.adapters import DEFAULT_POOLBLOCK, BaseAdapter -from pip._vendor.requests.adapters import HTTPAdapter as _BaseHTTPAdapter -from pip._vendor.requests.models import PreparedRequest, Response -from pip._vendor.requests.structures import CaseInsensitiveDict -from pip._vendor.urllib3.connectionpool import ConnectionPool -from pip._vendor.urllib3.exceptions import InsecureRequestWarning - -from pip import __version__ -from pip._internal.exceptions import SSLMissingError -from pip._internal.metadata import get_default_environment -from pip._internal.models.link import Link -from pip._internal.network.auth import MultiDomainBasicAuth -from pip._internal.network.cache import SafeFileCache -from pip._internal.network.utils import raise_connection_error - -# Import ssl from compat so the initial import occurs in only one place. -from pip._internal.utils.compat import has_tls -from pip._internal.utils.glibc import libc_ver -from pip._internal.utils.misc import ( - build_url_from_netloc, - looks_like_ci, - parse_netloc, - redact_auth_from_url, -) -from pip._internal.utils.urls import url_to_path - -if TYPE_CHECKING: - from ssl import SSLContext - - from pip._vendor.urllib3 import ProxyManager - - -logger = logging.getLogger(__name__) - -SecureOrigin = tuple[str, str, int | str | None] - - -# Ignore warning raised when using --trusted-host. -warnings.filterwarnings("ignore", category=InsecureRequestWarning) - - -SECURE_ORIGINS: list[SecureOrigin] = [ - # 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", "*", "*"), -] - - -@functools.lru_cache(maxsize=1) -def user_agent() -> str: - """ - Return a string representing the user agent. - """ - data: dict[str, Any] = { - "installer": {"name": "pip", "version": __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": - pypy_version_info = sys.pypy_version_info # type: ignore - if pypy_version_info.releaselevel == "final": - pypy_version_info = pypy_version_info[:3] - 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 - - linux_distribution = distro.name(), distro.version(), distro.codename() - distro_infos: dict[str, Any] = dict( - filter( - lambda x: x[1], - zip(["name", "version", "id"], 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(): - import _ssl as ssl - - data["openssl_version"] = ssl.OPENSSL_VERSION - - setuptools_dist = get_default_environment().get_distribution("setuptools") - if setuptools_dist is not None: - data["setuptools_version"] = str(setuptools_dist.version) - - if shutil.which("rustc") is not None: - # If for any reason `rustc --version` fails, silently ignore it - try: - rustc_output = subprocess.check_output( - ["rustc", "--version"], stderr=subprocess.STDOUT, timeout=0.5 - ) - except Exception: - pass - else: - if rustc_output.startswith(b"rustc "): - # The format of `rustc --version` is: - # `b'rustc 1.52.1 (9bc8c42bb 2021-05-09)\n'` - # We extract just the middle (1.52.1) part - data["rustc_version"] = rustc_output.split(b" ")[1].decode() - - # Use None rather than False so as not to give the impression that - # pip knows it is not being run under CI. Rather, it is a null or - # inconclusive result. Also, we include some value rather than no - # value to make it easier to know that the check has been run. - data["ci"] = True if looks_like_ci() else None - - user_data = os.environ.get("PIP_USER_AGENT_USER_DATA") - if user_data is not None: - data["user_data"] = user_data - - return "{data[installer][name]}/{data[installer][version]} {json}".format( - data=data, - json=json.dumps(data, separators=(",", ":"), sort_keys=True), - ) - - -class LocalFSAdapter(BaseAdapter): - def send( - self, - request: PreparedRequest, - stream: bool = False, - timeout: float | tuple[float | None, float | None] | None = None, - verify: bool | str = True, - cert: bytes | str | tuple[bytes | str, bytes | str] | None = None, - proxies: Mapping[str, str] | None = None, - ) -> Response: - assert request.url is not 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: - # format the exception raised as a io.BytesIO object, - # to return a better error message: - resp.status_code = 404 - resp.reason = type(exc).__name__ - resp.raw = io.BytesIO(f"{resp.reason}: {exc}".encode()) - 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": str(stats.st_size), - "Last-Modified": modified, - } - ) - - resp.raw = open(pathname, "rb") - resp.close = resp.raw.close # type: ignore[method-assign] - - return resp - - def close(self) -> None: - pass - - -class _SSLContextAdapterMixin: - """Mixin to add the ``ssl_context`` constructor argument to HTTP adapters. - - The additional argument is forwarded directly to the pool manager. This allows us - to dynamically decide what SSL store to use at runtime, which is used to implement - the optional ``truststore`` backend. - """ - - def __init__( - self, - *, - ssl_context: SSLContext | None = None, - **kwargs: Any, - ) -> None: - self._ssl_context = ssl_context - super().__init__(**kwargs) - - def init_poolmanager( - self, - connections: int, - maxsize: int, - block: bool = DEFAULT_POOLBLOCK, - **pool_kwargs: Any, - ) -> None: - if self._ssl_context is not None: - pool_kwargs.setdefault("ssl_context", self._ssl_context) - super().init_poolmanager( # type: ignore[misc] - connections=connections, - maxsize=maxsize, - block=block, - **pool_kwargs, - ) - - def proxy_manager_for(self, proxy: str, **proxy_kwargs: Any) -> ProxyManager: - # Proxy manager replaces the pool manager, so inject our SSL - # context here too. https://github.com/pypa/pip/issues/13288 - if self._ssl_context is not None: - proxy_kwargs.setdefault("ssl_context", self._ssl_context) - # For HTTPS proxies, urllib3 also opens a separate TLS connection - # to the proxy itself (before tunnelling to the destination) and - # uses "proxy_ssl_context" for that handshake. - # https://github.com/pypa/pip/issues/13465 - proxy_kwargs.setdefault("proxy_ssl_context", self._ssl_context) - return super().proxy_manager_for(proxy, **proxy_kwargs) # type: ignore[misc] - - -class HTTPAdapter(_SSLContextAdapterMixin, _BaseHTTPAdapter): - pass - - -class CacheControlAdapter(_SSLContextAdapterMixin, _BaseCacheControlAdapter): - pass - - -class InsecureHTTPAdapter(HTTPAdapter): - def cert_verify( - self, - conn: ConnectionPool, - url: str, - verify: bool | str, - cert: str | tuple[str, str] | None, - ) -> None: - super().cert_verify(conn=conn, url=url, verify=False, cert=cert) - - -class InsecureCacheControlAdapter(CacheControlAdapter): - def cert_verify( - self, - conn: ConnectionPool, - url: str, - verify: bool | str, - cert: str | tuple[str, str] | None, - ) -> None: - super().cert_verify(conn=conn, url=url, verify=False, cert=cert) - - -class PipSession(requests.Session): - timeout: int | None = None - - def __init__( - self, - *args: Any, - retries: int = 0, - resume_retries: int = 0, - cache: str | None = None, - trusted_hosts: Sequence[str] = (), - index_urls: list[str] | None = None, - ssl_context: SSLContext | None = None, - refresh_package: set[str] | None = None, - **kwargs: Any, - ) -> None: - """ - :param trusted_hosts: Domains not to emit warnings for when not using - HTTPS. - """ - super().__init__(*args, **kwargs) - - # Namespace the attribute with "pip_" just in case to prevent - # possible conflicts with the base class. - self.pip_trusted_origins: list[tuple[str, int | None]] = [] - # "" disables proxying; None means no --proxy was given. - self.pip_proxy: str | None = None - self.pip_no_proxy_env = False - self.refresh_package: set[str] = refresh_package or set() - - # Attach our User Agent to the request - self.headers["User-Agent"] = user_agent() - - # Pin Accept-Encoding so it doesn't vary with zstd availability (Python - # 3.14+ or backports.zstd); a varying value misses the cache for "Vary: - # Accept-Encoding" responses shared across interpreters (pypa/pip#13979). - self.headers["Accept-Encoding"] = "gzip, deflate" - - # Attach our Authentication handler to the session - self.auth: MultiDomainBasicAuth = MultiDomainBasicAuth(index_urls=index_urls) - - # Create our urllib3.Retry instance which will allow us to customize - # how we handle retries. - retries = urllib3.Retry( - # Set the total number of retries that a particular request can - # have. - total=retries, - # A 503 error from PyPI typically means that the Fastly -> Origin - # connection got interrupted in some way. A 503 error in general - # is typically considered a transient error so we'll go ahead and - # retry it. - # A 500 may indicate transient error in Amazon S3 - # A 502 may be a transient error from a CDN like CloudFlare or CloudFront - # A 520 or 527 - may indicate transient error in CloudFlare - status_forcelist=[500, 502, 503, 520, 527], - # Add a small amount of back off between failed requests in - # order to prevent hammering the service. - backoff_factor=0.25, - ) # type: ignore - self.resume_retries = resume_retries - - # Our Insecure HTTPAdapter disables HTTPS validation. It does not - # support caching so we'll use it for all http:// URLs. - # If caching is disabled, we will also use it for - # https:// hosts that we've marked as ignoring - # TLS errors for (trusted-hosts). - insecure_adapter = InsecureHTTPAdapter(max_retries=retries) - - # We want to _only_ cache responses on securely fetched origins or when - # the host is specified as trusted. We do this because - # we can't validate the response of an insecurely/untrusted 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. - self._trusted_host_adapter: InsecureCacheControlAdapter | InsecureHTTPAdapter - if cache: - secure_adapter: _BaseHTTPAdapter = CacheControlAdapter( - cache=SafeFileCache(cache), - max_retries=retries, - ssl_context=ssl_context, - ) - self._trusted_host_adapter = InsecureCacheControlAdapter( - cache=SafeFileCache(cache), - max_retries=retries, - ) - else: - secure_adapter = HTTPAdapter(max_retries=retries, ssl_context=ssl_context) - self._trusted_host_adapter = insecure_adapter - - self.mount("https://", secure_adapter) - self.mount("http://", insecure_adapter) - - # Enable file:// urls - self.mount("file://", LocalFSAdapter()) - - for host in trusted_hosts: - self.add_trusted_host(host, suppress_logging=True) - - def update_index_urls(self, new_index_urls: list[str]) -> None: - """ - :param new_index_urls: New index urls to update the authentication - handler with. - """ - self.auth.index_urls = new_index_urls - - def add_trusted_host( - self, host: str, source: str | None = None, suppress_logging: bool = False - ) -> None: - """ - :param host: It is okay to provide a host that has previously been - added. - :param source: An optional source string, for logging where the host - string came from. - """ - if not suppress_logging: - msg = f"adding trusted host: {host!r}" - if source is not None: - msg += f" (from {source})" - logger.info(msg) - - parsed_host, parsed_port = parse_netloc(host) - if parsed_host is None: - raise ValueError(f"Trusted host URL must include a host part: {host!r}") - if (parsed_host, parsed_port) not in self.pip_trusted_origins: - self.pip_trusted_origins.append((parsed_host, parsed_port)) - - self.mount( - build_url_from_netloc(host, scheme="http") + "/", self._trusted_host_adapter - ) - self.mount(build_url_from_netloc(host) + "/", self._trusted_host_adapter) - if not parsed_port: - self.mount( - build_url_from_netloc(host, scheme="http") + ":", - self._trusted_host_adapter, - ) - # Mount wildcard ports for the same host. - self.mount(build_url_from_netloc(host) + ":", self._trusted_host_adapter) - - def iter_secure_origins(self) -> Generator[SecureOrigin, None, None]: - yield from SECURE_ORIGINS - for host, port in self.pip_trusted_origins: - yield ("*", host, "*" if port is None else port) - - def is_secure_origin(self, location: Link) -> bool: - # Determine if this url used a secure transport mechanism - parsed = urllib.parse.urlparse(str(location)) - origin_protocol, origin_host, origin_port = ( - 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.) - origin_protocol = origin_protocol.rsplit("+", 1)[-1] - - # Determine if our origin is a secure origin by looking through our - # hardcoded list of secure origins, as well as any additional ones - # configured on this PackageFinder instance. - for secure_origin in self.iter_secure_origins(): - secure_protocol, secure_host, secure_port = secure_origin - if origin_protocol != secure_protocol and secure_protocol != "*": - continue - - try: - addr = ipaddress.ip_address(origin_host or "") - network = ipaddress.ip_network(secure_host) - except ValueError: - # We don't have both a valid address or a valid network, so - # we'll check this origin against hostnames. - if ( - origin_host - and origin_host.lower() != secure_host.lower() - and secure_host != "*" - ): - 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 matches. - if ( - origin_port != secure_port - and secure_port != "*" - and secure_port 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'.", - origin_host, - origin_host, - ) - - return False - - def request(self, method: str, url: str, *args: Any, **kwargs: Any) -> Response: # type: ignore[override] - # Allow setting a default timeout on a session - kwargs.setdefault("timeout", self.timeout) - # Allow setting a default proxies on a session - kwargs.setdefault("proxies", self.proxies) - - # Dispatch the actual request - try: - return super().request(method, url, *args, **kwargs) - except (requests.ConnectionError, requests.Timeout) as e: - request = getattr(e, "request", None) - failed_url = getattr(request, "url", None) or url - raise_connection_error(e, url=failed_url, timeout=kwargs["timeout"]) - except ImportError as e: - if "ssl" in str(e).lower(): - # Unfortunately, if this TLS error was the result of a redirect from - # a HTTP to a HTTPS url, we don't know what the final url was. - raise SSLMissingError(redact_auth_from_url(url)) - raise diff --git a/venv/lib/python3.11/site-packages/pip/_internal/network/utils.py b/venv/lib/python3.11/site-packages/pip/_internal/network/utils.py deleted file mode 100755 index 0f50607..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/network/utils.py +++ /dev/null @@ -1,206 +0,0 @@ -from collections.abc import Generator -from typing import Literal, NoReturn, TypeAlias, cast -from urllib.parse import urlsplit - -from pip._vendor import requests, urllib3 -from pip._vendor.requests.models import Response -from pip._vendor.urllib3.exceptions import TimeoutStateError - -from pip._internal.exceptions import ( - ConnectionFailedError, - ConnectionTimeoutError, - NetworkConnectionError, - ProxyConnectionError, - SSLVerificationError, -) -from pip._internal.utils.misc import redact_auth_from_url - -TimeoutValue: TypeAlias = ( - float | tuple[float | None, float | None] | urllib3.util.Timeout | None -) - -# The following comments and HTTP headers were originally added by -# Donald Stufft in git commit 22c562429a61bb77172039e480873fb239dd8c03. -# -# 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, adding 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: dict[str, str] = {"Accept-Encoding": "identity"} - -DOWNLOAD_CHUNK_SIZE = 256 * 1024 - - -def raise_for_status(resp: Response) -> None: - http_error_msg = "" - if isinstance(resp.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. - try: - reason = resp.reason.decode("utf-8") - except UnicodeDecodeError: - reason = resp.reason.decode("iso-8859-1") - else: - reason = resp.reason - - if 400 <= resp.status_code < 500: - http_error_msg = ( - f"{resp.status_code} Client Error: {reason} for url: {resp.url}" - ) - - elif 500 <= resp.status_code < 600: - http_error_msg = ( - f"{resp.status_code} Server Error: {reason} for url: {resp.url}" - ) - - if http_error_msg: - raise NetworkConnectionError(http_error_msg, response=resp) - - -def response_chunks( - response: Response, chunk_size: int = DOWNLOAD_CHUNK_SIZE -) -> Generator[bytes, None, None]: - """Given a requests Response, provide the data chunks.""" - try: - # Special case for urllib3. - for chunk in response.raw.stream( - chunk_size, - # We use decode_content=False here because we don't - # want urllib3 to mess with the raw bytes we get - # from the server. If we decompress inside of - # urllib3 then we cannot verify the checksum - # because the checksum will be of the compressed - # file. This breakage will only occur if the - # server adds a Content-Encoding header, which - # depends on how the server was configured: - # - Some servers will notice that the file isn't a - # compressible file and will leave the file alone - # and with an empty Content-Encoding - # - Some servers will notice that the file is - # already compressed and will leave the file - # alone and will add a Content-Encoding: gzip - # header - # - Some servers won't notice anything at all and - # will take a file that's already been compressed - # and compress it again and set the - # Content-Encoding: gzip header - # - # By setting this not to decode automatically we - # hope to eliminate problems with the second case. - decode_content=False, - ): - yield chunk - except AttributeError: - # Standard file-like object. - while True: - chunk = response.raw.read(chunk_size) - if not chunk: - break - yield chunk - - -def _parse_timeout(timeout: TimeoutValue, kind: Literal["connect", "read"]) -> float: - connect_timeout: float | None - read_timeout: float | None - if isinstance(timeout, tuple): - connect_timeout, read_timeout = timeout - elif isinstance(timeout, urllib3.util.Timeout): - connect_timeout = cast(float | None, timeout.connect_timeout) - try: - read_timeout = timeout.read_timeout - except TimeoutStateError: - read_timeout = None - else: - connect_timeout = read_timeout = timeout - - if kind == "connect": - assert connect_timeout is not None - return connect_timeout - else: - assert read_timeout is not None - return read_timeout - - -def _raise_timeout_error( - reason: urllib3.exceptions.TimeoutError, - url: str, - host: str, - timeout: TimeoutValue, -) -> NoReturn: - if isinstance(reason, urllib3.exceptions.ConnectTimeoutError): - raise ConnectionTimeoutError( - url, host, kind="connect", timeout=_parse_timeout(timeout, "connect") - ) - else: - raise ConnectionTimeoutError( - url, host, kind="read", timeout=_parse_timeout(timeout, "read") - ) - - -def raise_connection_error( - error: requests.ConnectionError | requests.Timeout, - *, - url: str, - timeout: TimeoutValue, -) -> NoReturn: - """Raise a specific error for a given connection error, if possible. - - Note: requests.ConnectionError is the parent class of - requests.ProxyError, requests.SSLError, and requests.ConnectTimeout - so these errors are also handled here. - """ - url = redact_auth_from_url(url) - raw_hostname = urlsplit(url).hostname or urlsplit(url).netloc - reason = error.args[0] if error.args else error - - # NewConnectionError is a subclass of TimeoutError for some reason... - if isinstance(reason, urllib3.exceptions.TimeoutError) and not isinstance( - reason, urllib3.exceptions.NewConnectionError - ): - # A bare timeout error can occur during non-streamed responses. Don't - # ask me how. - _raise_timeout_error(reason, url, raw_hostname, timeout) - if isinstance(reason, urllib3.exceptions.SSLError): - # A bare SSL error can occur during non-streamed responses, after the - # initial connection and TLS handshake have completed. - raise SSLVerificationError(url, raw_hostname, reason) - - # At this point, all errors should be wrapped in MaxRetryError. - if not isinstance(reason, urllib3.exceptions.MaxRetryError): - raise ConnectionFailedError(url, raw_hostname, reason) - - max_retry_error = reason - assert isinstance(max_retry_error.pool, urllib3.connectionpool.HTTPConnectionPool) - host = max_retry_error.pool.host - proxy = max_retry_error.pool.proxy - # Narrow the reason further to the specific error from the last retry. - reason = max_retry_error.reason - - if isinstance(reason, urllib3.exceptions.SSLError): - raise SSLVerificationError(url, host, reason) - if isinstance(reason, urllib3.exceptions.TimeoutError) and not isinstance( - reason, urllib3.exceptions.NewConnectionError - ): - _raise_timeout_error(reason, url, host, timeout) - if isinstance(reason, urllib3.exceptions.ProxyError): - assert proxy is not None - raise ProxyConnectionError(url, redact_auth_from_url(str(proxy)), reason) - - # Unknown error, give up and raise a generic error. - raise ConnectionFailedError( - url, host, reason if isinstance(reason, Exception) else max_retry_error - ) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/network/xmlrpc.py b/venv/lib/python3.11/site-packages/pip/_internal/network/xmlrpc.py deleted file mode 100755 index f4bddb4..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/network/xmlrpc.py +++ /dev/null @@ -1,61 +0,0 @@ -"""xmlrpclib.Transport implementation""" - -import logging -import urllib.parse -import xmlrpc.client -from typing import TYPE_CHECKING - -from pip._internal.exceptions import NetworkConnectionError -from pip._internal.network.session import PipSession -from pip._internal.network.utils import raise_for_status - -if TYPE_CHECKING: - from xmlrpc.client import _HostType, _Marshallable - - from _typeshed import SizedBuffer - -logger = logging.getLogger(__name__) - - -class PipXmlrpcTransport(xmlrpc.client.Transport): - """Provide a `xmlrpclib.Transport` implementation via a `PipSession` - object. - """ - - def __init__( - self, index_url: str, session: PipSession, use_datetime: bool = False - ) -> None: - super().__init__(use_datetime) - index_parts = urllib.parse.urlparse(index_url) - self._scheme = index_parts.scheme - self._session = session - - def request( - self, - host: "_HostType", - handler: str, - request_body: "SizedBuffer", - verbose: bool = False, - ) -> tuple["_Marshallable", ...]: - assert isinstance(host, str) - 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, - ) - raise_for_status(response) - self.verbose = verbose - return self.parse_response(response.raw) - except NetworkConnectionError as exc: - assert exc.response - logger.critical( - "HTTP error %s while getting %s", - exc.response.status_code, - url, - ) - raise diff --git a/venv/lib/python3.11/site-packages/pip/_internal/operations/__init__.py b/venv/lib/python3.11/site-packages/pip/_internal/operations/__init__.py deleted file mode 100755 index e69de29..0000000 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-311.pyc deleted file mode 100755 index b6fc5b4a1628e1614b4e187212befbd5b2573a94..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 201 zcmZ3^%ge<81lOj_$^y}kK?DpiLK&agfQ;!3DGb33nv8xc8H$*I{LdiCUorX_`MIh3 zxrs%|`TAb@>G{U`i3J7vWvO{(`Z<|N`URCG8Tom}dWMGj#hE3kx&?{J*@@|?#rg%A z1^V%sc_pbud5Jmt`30#(i6xo&dBytiK+(*S_;|g7%3mBdx%nxjIjMFx S5+9fu85ut?z=$Gdpcnvr1~iTU diff --git a/venv/lib/python3.11/site-packages/pip/_internal/operations/__pycache__/check.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/operations/__pycache__/check.cpython-311.pyc deleted file mode 100755 index 7ce17c54c5aa85c54af0bf2c48331f48969b207d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8080 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 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-311.pyc deleted file mode 100755 index 068b916f996b5e3edcb9bda6f346cea503362c33..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11687 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 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-311.pyc deleted file mode 100755 index 8945e23cc6ffeb7fa5fdac128041dfd34382b8c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34239 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 DyWhMw diff --git a/venv/lib/python3.11/site-packages/pip/_internal/operations/build/__init__.py b/venv/lib/python3.11/site-packages/pip/_internal/operations/build/__init__.py deleted file mode 100755 index e69de29..0000000 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-311.pyc deleted file mode 100755 index 3c8c22307714b24da59b9947058d2ba5cfbe3a31..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 207 zcmZ3^%ge<81lOj_$^y}kK?DpiLK&agfQ;!3DGb33nv8xc8H$*I{LdiCUrG8I`MIh3 zxrs%|`TAb@>G{U`i3J7vWvO{(`Z<|N`URCG8Tom}dWMGj#hE3kx&?{J*@@|?#rg%A z1^V%sc_pbud5Jmt`30#(i6xo&dByrkrI|S?`td-y%#!$cy@JYL95%W6DWy57c15f} YD?yGb<_8iVm>C%vKQO?EB4(f%0P{#T(*OVf diff --git a/venv/lib/python3.11/site-packages/pip/_internal/operations/build/__pycache__/build_tracker.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/operations/build/__pycache__/build_tracker.cpython-311.pyc deleted file mode 100755 index 6ef18dfe66dfa3e73ea018413b61c492bae6ea44..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8703 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 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/operations/build/__pycache__/metadata.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/operations/build/__pycache__/metadata.cpython-311.pyc deleted file mode 100755 index 7d068e7f93c497f9704d52cc607aec2420cd7edd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2271 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 Generator[None, None, None]: - target = os.environ - - # Save values from the target and change them. - non_existent_marker = object() - saved_values: dict[str, object | str] = {} - for name, new_value in changes.items(): - try: - saved_values[name] = target[name] - except KeyError: - saved_values[name] = non_existent_marker - target[name] = new_value - - try: - yield - finally: - # Restore original values in the target. - for name, original_value in saved_values.items(): - if original_value is non_existent_marker: - del target[name] - else: - assert isinstance(original_value, str) # for mypy - target[name] = original_value - - -@contextlib.contextmanager -def get_build_tracker() -> Generator[BuildTracker, None, None]: - root = os.environ.get("PIP_BUILD_TRACKER") - with contextlib.ExitStack() as ctx: - if root is None: - root = ctx.enter_context(TempDirectory(kind="build-tracker")).path - ctx.enter_context(update_env_context_manager(PIP_BUILD_TRACKER=root)) - logger.debug("Initialized build tracking at %s", root) - - with BuildTracker(root) as tracker: - yield tracker - - -class TrackerId(str): - """Uniquely identifying string provided to the build tracker.""" - - -class BuildTracker: - """Ensure that an sdist cannot request itself as a setup requirement. - - When an sdist is prepared, it identifies its setup requirements in the - context of ``BuildTracker.track()``. If a requirement shows up recursively, this - raises an exception. - - This stops fork bombs embedded in malicious packages.""" - - def __init__(self, root: str) -> None: - self._root = root - self._entries: dict[TrackerId, InstallRequirement] = {} - logger.debug("Created build tracker: %s", self._root) - - def __enter__(self) -> BuildTracker: - logger.debug("Entered build tracker: %s", self._root) - return self - - def __exit__( - self, - exc_type: type[BaseException] | None, - exc_val: BaseException | None, - exc_tb: TracebackType | None, - ) -> None: - self.cleanup() - - def _entry_path(self, key: TrackerId) -> str: - hashed = hashlib.sha224(key.encode()).hexdigest() - return os.path.join(self._root, hashed) - - def add(self, req: InstallRequirement, key: TrackerId) -> None: - """Add an InstallRequirement to build tracking.""" - - # Get the file to write information about this requirement. - entry_path = self._entry_path(key) - - # Try reading from the file. If it exists and can be read from, a build - # is already in progress, so a LookupError is raised. - try: - with open(entry_path) as fp: - contents = fp.read() - except FileNotFoundError: - pass - else: - message = f"{req.link} is already being built: {contents}" - raise LookupError(message) - - # If we're here, req should really not be building already. - assert key not in self._entries - - # Start tracking this requirement. - with open(entry_path, "w", encoding="utf-8") as fp: - fp.write(str(req)) - self._entries[key] = req - - logger.debug("Added %s to build tracker %r", req, self._root) - - def remove(self, req: InstallRequirement, key: TrackerId) -> None: - """Remove an InstallRequirement from build tracking.""" - - # Delete the created file and the corresponding entry. - os.unlink(self._entry_path(key)) - del self._entries[key] - - logger.debug("Removed %s from build tracker %r", req, self._root) - - def cleanup(self) -> None: - for key, req in list(self._entries.items()): - self.remove(req, key) - - logger.debug("Removed build tracker: %r", self._root) - - @contextlib.contextmanager - def track(self, req: InstallRequirement, key: str) -> Generator[None, None, None]: - """Ensure that `key` cannot install itself as a setup requirement. - - :raises LookupError: If `key` was already provided in a parent invocation of - the context introduced by this method.""" - tracker_id = TrackerId(key) - self.add(req, tracker_id) - yield - self.remove(req, tracker_id) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/operations/build/metadata.py b/venv/lib/python3.11/site-packages/pip/_internal/operations/build/metadata.py deleted file mode 100755 index a546809..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/operations/build/metadata.py +++ /dev/null @@ -1,38 +0,0 @@ -"""Metadata generation logic for source distributions.""" - -import os - -from pip._vendor.pyproject_hooks import BuildBackendHookCaller - -from pip._internal.build_env import BuildEnvironment -from pip._internal.exceptions import ( - InstallationSubprocessError, - MetadataGenerationFailed, -) -from pip._internal.utils.subprocess import runner_with_spinner_message -from pip._internal.utils.temp_dir import TempDirectory - - -def generate_metadata( - build_env: BuildEnvironment, backend: BuildBackendHookCaller, details: str -) -> str: - """Generate metadata using mechanisms described in PEP 517. - - Returns the generated metadata directory. - """ - metadata_tmpdir = TempDirectory(kind="modern-metadata", globally_managed=True) - - metadata_dir = metadata_tmpdir.path - - with build_env: - # Note that BuildBackendHookCaller implements a fallback for - # prepare_metadata_for_build_wheel, so we don't have to - # consider the possibility that this hook doesn't exist. - runner = runner_with_spinner_message("Preparing metadata (pyproject.toml)") - with backend.subprocess_runner(runner): - try: - distinfo_dir = backend.prepare_metadata_for_build_wheel(metadata_dir) - except InstallationSubprocessError as error: - raise MetadataGenerationFailed(package_details=details) from error - - return os.path.join(metadata_dir, distinfo_dir) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/operations/build/metadata_editable.py b/venv/lib/python3.11/site-packages/pip/_internal/operations/build/metadata_editable.py deleted file mode 100755 index 27ecd7d..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/operations/build/metadata_editable.py +++ /dev/null @@ -1,41 +0,0 @@ -"""Metadata generation logic for source distributions.""" - -import os - -from pip._vendor.pyproject_hooks import BuildBackendHookCaller - -from pip._internal.build_env import BuildEnvironment -from pip._internal.exceptions import ( - InstallationSubprocessError, - MetadataGenerationFailed, -) -from pip._internal.utils.subprocess import runner_with_spinner_message -from pip._internal.utils.temp_dir import TempDirectory - - -def generate_editable_metadata( - build_env: BuildEnvironment, backend: BuildBackendHookCaller, details: str -) -> str: - """Generate metadata using mechanisms described in PEP 660. - - Returns the generated metadata directory. - """ - metadata_tmpdir = TempDirectory(kind="modern-metadata", globally_managed=True) - - metadata_dir = metadata_tmpdir.path - - with build_env: - # Note that BuildBackendHookCaller implements a fallback for - # prepare_metadata_for_build_wheel/editable, so we don't have to - # consider the possibility that this hook doesn't exist. - runner = runner_with_spinner_message( - "Preparing editable metadata (pyproject.toml)" - ) - with backend.subprocess_runner(runner): - try: - distinfo_dir = backend.prepare_metadata_for_build_editable(metadata_dir) - except InstallationSubprocessError as error: - raise MetadataGenerationFailed(package_details=details) from error - - assert distinfo_dir is not None - return os.path.join(metadata_dir, distinfo_dir) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/operations/build/wheel.py b/venv/lib/python3.11/site-packages/pip/_internal/operations/build/wheel.py deleted file mode 100755 index 8595e45..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/operations/build/wheel.py +++ /dev/null @@ -1,38 +0,0 @@ -from __future__ import annotations - -import logging -import os - -from pip._vendor.pyproject_hooks import BuildBackendHookCaller - -from pip._internal.utils.subprocess import runner_with_spinner_message - -logger = logging.getLogger(__name__) - - -def build_wheel_pep517( - name: str, - backend: BuildBackendHookCaller, - metadata_directory: str, - wheel_directory: str, -) -> str | None: - """Build one InstallRequirement using the PEP 517 build process. - - Returns path to wheel if successfully built. Otherwise, returns None. - """ - assert metadata_directory is not None - try: - logger.debug("Destination directory: %s", wheel_directory) - - runner = runner_with_spinner_message( - f"Building wheel for {name} (pyproject.toml)" - ) - with backend.subprocess_runner(runner): - wheel_name = backend.build_wheel( - wheel_directory=wheel_directory, - metadata_directory=metadata_directory, - ) - except Exception: - logger.error("Failed building wheel for %s", name) - return None - return os.path.join(wheel_directory, wheel_name) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/operations/build/wheel_editable.py b/venv/lib/python3.11/site-packages/pip/_internal/operations/build/wheel_editable.py deleted file mode 100755 index f00d9b2..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/operations/build/wheel_editable.py +++ /dev/null @@ -1,47 +0,0 @@ -from __future__ import annotations - -import logging -import os - -from pip._vendor.pyproject_hooks import BuildBackendHookCaller, HookMissing - -from pip._internal.utils.subprocess import runner_with_spinner_message - -logger = logging.getLogger(__name__) - - -def build_wheel_editable( - name: str, - backend: BuildBackendHookCaller, - metadata_directory: str, - wheel_directory: str, -) -> str | None: - """Build one InstallRequirement using the PEP 660 build process. - - Returns path to wheel if successfully built. Otherwise, returns None. - """ - assert metadata_directory is not None - try: - logger.debug("Destination directory: %s", wheel_directory) - - runner = runner_with_spinner_message( - f"Building editable for {name} (pyproject.toml)" - ) - with backend.subprocess_runner(runner): - try: - wheel_name = backend.build_editable( - wheel_directory=wheel_directory, - metadata_directory=metadata_directory, - ) - except HookMissing as e: - logger.error( - "Cannot build editable %s because the build " - "backend does not have the %s hook", - name, - e, - ) - return None - except Exception: - logger.error("Failed building editable for %s", name) - return None - return os.path.join(wheel_directory, wheel_name) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/operations/check.py b/venv/lib/python3.11/site-packages/pip/_internal/operations/check.py deleted file mode 100755 index 00cb6c5..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/operations/check.py +++ /dev/null @@ -1,174 +0,0 @@ -"""Validation of dependencies of packages""" - -from __future__ import annotations - -import logging -from collections.abc import Callable, Generator, Iterable -from contextlib import suppress -from email.parser import Parser -from functools import reduce -from typing import ( - NamedTuple, -) - -from pip._vendor.packaging.requirements import Requirement -from pip._vendor.packaging.tags import Tag, parse_tag -from pip._vendor.packaging.utils import NormalizedName, canonicalize_name -from pip._vendor.packaging.version import Version - -from pip._internal.distributions import make_distribution_for_install_requirement -from pip._internal.metadata import get_default_environment -from pip._internal.metadata.base import BaseDistribution -from pip._internal.req.req_install import InstallRequirement - -logger = logging.getLogger(__name__) - - -class PackageDetails(NamedTuple): - version: Version - dependencies: list[Requirement] - - -# Shorthands -PackageSet = dict[NormalizedName, PackageDetails] -Missing = tuple[NormalizedName, Requirement] -Conflicting = tuple[NormalizedName, Version, Requirement] - -MissingDict = dict[NormalizedName, list[Missing]] -ConflictingDict = dict[NormalizedName, list[Conflicting]] -CheckResult = tuple[MissingDict, ConflictingDict] -ConflictDetails = tuple[PackageSet, CheckResult] - - -def create_package_set_from_installed() -> tuple[PackageSet, bool]: - """Converts a list of distributions into a PackageSet.""" - package_set = {} - problems = False - env = get_default_environment() - for dist in env.iter_installed_distributions(local_only=False, skip=()): - name = dist.canonical_name - try: - dependencies = list(dist.iter_dependencies()) - package_set[name] = PackageDetails(dist.version, dependencies) - except (OSError, ValueError) as e: - # Don't crash on unreadable or broken metadata. - logger.warning("Error parsing dependencies of %s: %s", name, e) - problems = True - return package_set, problems - - -def check_package_set( - package_set: PackageSet, should_ignore: Callable[[str], bool] | None = None -) -> 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. - """ - - missing = {} - conflicting = {} - - for package_name, package_detail in package_set.items(): - # Info about dependencies of package_name - missing_deps: set[Missing] = set() - conflicting_deps: set[Conflicting] = set() - - if should_ignore and should_ignore(package_name): - continue - - for req in package_detail.dependencies: - name = canonicalize_name(req.name) - - # Check if it's missing - if name not in package_set: - missed = True - if req.marker is not None: - missed = req.marker.evaluate({"extra": ""}) - if missed: - missing_deps.add((name, req)) - continue - - # Check if there's a conflict - version = package_set[name].version - 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: list[InstallRequirement]) -> ConflictDetails: - """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 - ), - ) - - -def check_unsupported( - packages: Iterable[BaseDistribution], - supported_tags: Iterable[Tag], -) -> Generator[BaseDistribution, None, None]: - for p in packages: - with suppress(FileNotFoundError): - wheel_file = p.read_text("WHEEL") - wheel_tags: frozenset[Tag] = reduce( - frozenset.union, - map(parse_tag, Parser().parsestr(wheel_file).get_all("Tag", [])), - frozenset(), - ) - if wheel_tags.isdisjoint(supported_tags): - yield p - - -def _simulate_installation_of( - to_install: list[InstallRequirement], package_set: PackageSet -) -> set[NormalizedName]: - """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: - abstract_dist = make_distribution_for_install_requirement(inst_req) - dist = abstract_dist.get_metadata_distribution() - name = dist.canonical_name - package_set[name] = PackageDetails(dist.version, list(dist.iter_dependencies())) - - installed.add(name) - - return installed - - -def _create_whitelist( - would_be_installed: set[NormalizedName], package_set: PackageSet -) -> set[NormalizedName]: - 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].dependencies: - if canonicalize_name(req.name) in would_be_installed: - packages_affected.add(package_name) - break - - return packages_affected diff --git a/venv/lib/python3.11/site-packages/pip/_internal/operations/freeze.py b/venv/lib/python3.11/site-packages/pip/_internal/operations/freeze.py deleted file mode 100755 index 486a833..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/operations/freeze.py +++ /dev/null @@ -1,259 +0,0 @@ -from __future__ import annotations - -import collections -import logging -import os -from collections.abc import Container, Generator, Iterable -from dataclasses import dataclass, field -from typing import NamedTuple - -from pip._vendor.packaging.utils import NormalizedName, canonicalize_name -from pip._vendor.packaging.version import InvalidVersion - -from pip._internal.exceptions import BadCommand, InstallationError -from pip._internal.metadata import BaseDistribution, get_environment -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.direct_url_helpers import direct_url_as_pep440_direct_reference - -logger = logging.getLogger(__name__) - - -class _EditableInfo(NamedTuple): - requirement: str - comments: list[str] - - -def freeze( - requirement: list[str] | None = None, - local_only: bool = False, - user_only: bool = False, - paths: list[str] | None = None, - isolated: bool = False, - exclude_editable: bool = False, - skip: Container[str] = (), -) -> Generator[str, None, None]: - installations: dict[str, FrozenRequirement] = {} - - dists = get_environment(paths).iter_installed_distributions( - local_only=local_only, - skip=(), - user_only=user_only, - ) - for dist in dists: - req = FrozenRequirement.from_dist(dist) - if exclude_editable and req.editable: - continue - installations[req.canonical_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[str] = 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: dict[str, list[str]] = 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 line.startswith( - ( - "-r", - "--requirement", - "-f", - "--find-links", - "-i", - "--index-url", - "--pre", - "--trusted-host", - "--process-dependency-links", - "--extra-index-url", - "--use-feature", - ) - ) - ): - line = line.rstrip() - if line not in emitted_options: - emitted_options.add(line) - yield line - continue - - if line.startswith(("-e", "--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, - ) - else: - line_req = install_req_from_line( - COMMENT_RE.sub("", line).strip(), - isolated=isolated, - ) - - 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)" - ) - else: - line_req_canonical_name = canonicalize_name(line_req.name) - if line_req_canonical_name not in installations: - # either it's not installed, or it is installed - # but has been processed already - if not req_files[line_req.name]: - logger.warning( - "Requirement file [%s] contains %s, but " - "package %r is not installed", - req_file_path, - COMMENT_RE.sub("", line).strip(), - line_req.name, - ) - else: - req_files[line_req.name].append(req_file_path) - else: - yield str(installations[line_req_canonical_name]).rstrip() - del installations[line_req_canonical_name] - req_files[line_req.name].append(req_file_path) - - # Warn about requirements that were included multiple times (in a - # single requirements file or in different requirements files). - for name, files in req_files.items(): - 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 installation.canonical_name not in skip: - yield str(installation).rstrip() - - -def _format_as_name_version(dist: BaseDistribution) -> str: - try: - dist_version = dist.version - except InvalidVersion: - # legacy version - return f"{dist.raw_name}==={dist.raw_version}" - else: - return f"{dist.raw_name}=={dist_version}" - - -def _get_editable_info(dist: BaseDistribution) -> _EditableInfo: - """ - Compute and return values (req, comments) for use in - FrozenRequirement.from_dist(). - """ - editable_project_location = dist.editable_project_location - assert editable_project_location - location = os.path.normcase(os.path.abspath(editable_project_location)) - - from pip._internal.vcs import RemoteNotFoundError, RemoteNotValidError, vcs - - vcs_backend = vcs.get_backend_for_dir(location) - - if vcs_backend is None: - display = _format_as_name_version(dist) - logger.debug( - 'No VCS found for editable requirement "%s" in: %r', - display, - location, - ) - return _EditableInfo( - requirement=location, - comments=[f"# Editable install with no version control ({display})"], - ) - - vcs_name = type(vcs_backend).__name__ - - try: - req = vcs_backend.get_src_requirement(location, dist.raw_name) - except RemoteNotFoundError: - display = _format_as_name_version(dist) - return _EditableInfo( - requirement=location, - comments=[f"# Editable {vcs_name} install with no remote ({display})"], - ) - except RemoteNotValidError as ex: - display = _format_as_name_version(dist) - return _EditableInfo( - requirement=location, - comments=[ - f"# Editable {vcs_name} install ({display}) with either a deleted " - f"local remote or invalid URI:", - f"# '{ex.url}'", - ], - ) - except BadCommand: - logger.warning( - "cannot determine version of editable source in %s " - "(%s command not found in path)", - location, - vcs_backend.name, - ) - return _EditableInfo(requirement=location, comments=[]) - except InstallationError as exc: - logger.warning("Error when trying to get requirement for VCS system %s", exc) - else: - return _EditableInfo(requirement=req, comments=[]) - - logger.warning("Could not determine repository location of %s", location) - - return _EditableInfo( - requirement=location, - comments=["## !! Could not determine repository location"], - ) - - -@dataclass(frozen=True) -class FrozenRequirement: - name: str - req: str - editable: bool - comments: Iterable[str] = field(default_factory=tuple) - - @property - def canonical_name(self) -> NormalizedName: - return canonicalize_name(self.name) - - @classmethod - def from_dist(cls, dist: BaseDistribution) -> FrozenRequirement: - editable = dist.editable - if editable: - req, comments = _get_editable_info(dist) - else: - comments = [] - direct_url = dist.direct_url - if direct_url: - # if PEP 610 metadata is present, use it - req = direct_url_as_pep440_direct_reference(direct_url, dist.raw_name) - else: - # name==version requirement - req = _format_as_name_version(dist) - - return cls(dist.raw_name, req, editable, comments=comments) - - def __str__(self) -> str: - req = self.req - if self.editable: - req = f"-e {req}" - return "\n".join(list(self.comments) + [str(req)]) + "\n" diff --git a/venv/lib/python3.11/site-packages/pip/_internal/operations/install/__init__.py b/venv/lib/python3.11/site-packages/pip/_internal/operations/install/__init__.py deleted file mode 100755 index 2645a4a..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/operations/install/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""For modules related to installing packages.""" diff --git a/venv/lib/python3.11/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-311.pyc deleted file mode 100755 index 4f0706fd701081e89d4a91f9519357b3c2f20f91..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 266 zcmXv}&1wQM5Kd~bB6#Q<GZDhkh1qzlpcm Q{q{KLM^^4T3)i{(2gR{Y@Bjb+ diff --git a/venv/lib/python3.11/site-packages/pip/_internal/operations/install/__pycache__/wheel.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/operations/install/__pycache__/wheel.cpython-311.pyc deleted file mode 100755 index 4680f2bdfde99084a2d39aba4bad80368cbee62c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40533 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 C`f0TQ diff --git a/venv/lib/python3.11/site-packages/pip/_internal/operations/install/wheel.py b/venv/lib/python3.11/site-packages/pip/_internal/operations/install/wheel.py deleted file mode 100755 index c026005..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/operations/install/wheel.py +++ /dev/null @@ -1,764 +0,0 @@ -"""Support for installing and building the "wheel" binary package format.""" - -from __future__ import annotations - -import collections -import compileall -import contextlib -import csv -import importlib -import logging -import os.path -import re -import shutil -import sys -import textwrap -import warnings -from base64 import urlsafe_b64encode -from collections.abc import Callable, Generator, Iterable, Iterator, Sequence -from email.message import Message -from itertools import chain, filterfalse, starmap -from pathlib import Path -from typing import ( - IO, - Any, - BinaryIO, - NewType, - Protocol, - cast, -) -from zipfile import ZipFile, ZipInfo - -from pip._vendor.distlib.scripts import ScriptMaker -from pip._vendor.distlib.util import get_export_entry -from pip._vendor.packaging.utils import canonicalize_name - -from pip._internal.exceptions import InstallationError -from pip._internal.locations import get_major_minor_version -from pip._internal.metadata import ( - BaseDistribution, - FilesystemWheel, - get_wheel_distribution, -) -from pip._internal.models.direct_url import DIRECT_URL_METADATA_NAME, DirectUrl -from pip._internal.models.scheme import SCHEME_KEYS, Scheme -from pip._internal.utils.filesystem import adjacent_tmp_file, replace -from pip._internal.utils.misc import StreamWrapper, ensure_dir, hash_file, partition -from pip._internal.utils.unpacking import ( - current_umask, - is_within_directory, - set_extracted_file_to_default_mode_plus_executable, - zip_item_is_executable, -) -from pip._internal.utils.wheel import parse_wheel - - -class File(Protocol): - src_record_path: RecordPath - dest_path: str - changed: bool - - def save(self) -> None: - pass - - -logger = logging.getLogger(__name__) - -RecordPath = NewType("RecordPath", str) -InstalledCSVRow = tuple[RecordPath, str, int | str] - - -def rehash(path: str, blocksize: int = 1 << 20) -> tuple[str, str]: - """Return (encoded_digest, length) for path using hashlib.sha256()""" - h, length = hash_file(path, blocksize) - digest = "sha256=" + urlsafe_b64encode(h.digest()).decode("latin1").rstrip("=") - return (digest, str(length)) - - -def csv_io_kwargs(mode: str) -> dict[str, Any]: - """Return keyword arguments to properly open a CSV file - in the given mode. - """ - return {"mode": mode, "newline": "", "encoding": "utf-8"} - - -def fix_script(path: str) -> bool: - """Replace #!python with #!/path/to/python - Return True if file was changed. - """ - # XXX RECORD hashes will need to be updated - assert 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 - - -def wheel_root_is_purelib(metadata: Message) -> bool: - return metadata.get("Root-Is-Purelib", "").lower() == "true" - - -def get_entrypoints(dist: BaseDistribution) -> tuple[dict[str, str], dict[str, str]]: - console_scripts = {} - gui_scripts = {} - for entry_point in dist.iter_entry_points(): - if entry_point.group == "console_scripts": - console_scripts[entry_point.name] = entry_point.value - elif entry_point.group == "gui_scripts": - gui_scripts[entry_point.name] = entry_point.value - return console_scripts, gui_scripts - - -def message_about_scripts_not_on_PATH(scripts: Sequence[str]) -> str | None: - """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: dict[Path, set[str]] = collections.defaultdict(set) - for destfile in scripts: - dest_path = Path(destfile) - parent_dir = dest_path.parent.resolve() - script_name = dest_path.name - grouped_by_dir[parent_dir].add(script_name) - - # We don't want to warn for directories that are on PATH. - not_warn_dirs = [ - Path(i).resolve() 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(Path(sys.executable).parent.resolve()) - warn_for: dict[Path, set[str]] = { - parent_dir: scripts - for parent_dir, scripts in grouped_by_dir.items() - if parent_dir not in not_warn_dirs - } - if not warn_for: - return None - - # Format a message - msg_lines = [] - for parent_dir, dir_scripts in warn_for.items(): - sorted_scripts: list[str] = sorted(dir_scripts) - if len(sorted_scripts) == 1: - start_text = f"script {sorted_scripts[0]} is" - else: - start_text = "scripts {} are".format( - ", ".join(sorted_scripts[:-1]) + " and " + sorted_scripts[-1] - ) - - msg_lines.append( - f"The {start_text} installed in '{parent_dir}' which is not on PATH." - ) - - last_line_fmt = ( - "Consider adding {} to PATH or, if you prefer " - "to suppress this warning, use --no-warn-script-location." - ) - if len(msg_lines) == 1: - msg_lines.append(last_line_fmt.format("this directory")) - else: - msg_lines.append(last_line_fmt.format("these directories")) - - # Add a note if any directory starts with ~ - warn_for_tilde = any( - i[0] == "~" for i in os.environ.get("PATH", "").split(os.pathsep) if i - ) - if warn_for_tilde: - tilde_warning_msg = ( - "NOTE: The current PATH contains path(s) starting with `~`, " - "which may not be expanded by all applications." - ) - msg_lines.append(tilde_warning_msg) - - # Returns the formatted multiline message - return "\n".join(msg_lines) - - -def _normalized_outrows( - outrows: Iterable[InstalledCSVRow], -) -> list[tuple[str, str, str]]: - """Normalize the given rows of a RECORD file. - - Items in each row are converted into str. Rows are then sorted to make - the value more predictable for tests. - - Each row is a 3-tuple (path, hash, size) and corresponds to a record of - a RECORD file (see PEP 376 and PEP 427 for details). For the rows - passed to this function, the size can be an integer as an int or string, - or the empty string. - """ - # Normally, there should only be one row per path, in which case the - # second and third elements don't come into play when sorting. - # However, in cases in the wild where a path might happen to occur twice, - # we don't want the sort operation to trigger an error (but still want - # determinism). Since the third element can be an int or string, we - # coerce each element to a string to avoid a TypeError in this case. - # For additional background, see-- - # https://github.com/pypa/pip/issues/5868 - return sorted( - (record_path, hash_, str(size)) for record_path, hash_, size in outrows - ) - - -def _record_to_fs_path(record_path: RecordPath, lib_dir: str) -> str: - return os.path.join(lib_dir, record_path) - - -def _fs_to_record_path(path: str, lib_dir: str) -> RecordPath: - # On Windows, do not handle relative paths if they belong to different - # logical disks - if os.path.splitdrive(path)[0].lower() == os.path.splitdrive(lib_dir)[0].lower(): - path = os.path.relpath(path, lib_dir) - - path = path.replace(os.path.sep, "/") - return cast("RecordPath", path) - - -def get_csv_rows_for_installed( - old_csv_rows: list[list[str]], - installed: dict[RecordPath, RecordPath], - changed: set[RecordPath], - generated: list[str], - lib_dir: str, -) -> list[InstalledCSVRow]: - """ - :param installed: A map from archive RECORD path to installation RECORD - path. - """ - installed_rows: list[InstalledCSVRow] = [] - for row in old_csv_rows: - if len(row) > 3: - logger.warning("RECORD line has more than three elements: %s", row) - old_record_path = cast("RecordPath", row[0]) - new_record_path = installed.pop(old_record_path, old_record_path) - if new_record_path in changed: - digest, length = rehash(_record_to_fs_path(new_record_path, lib_dir)) - else: - digest = row[1] if len(row) > 1 else "" - length = row[2] if len(row) > 2 else "" - installed_rows.append((new_record_path, digest, length)) - for f in generated: - path = _fs_to_record_path(f, lib_dir) - digest, length = rehash(f) - installed_rows.append((path, digest, length)) - return installed_rows + [ - (installed_record_path, "", "") for installed_record_path in installed.values() - ] - - -def get_console_script_specs(console: dict[str, str]) -> list[str]: - """ - Given the mapping from entrypoint name to callable, return the relevant - console script specs. - """ - # Don't mutate caller's version - console = console.copy() - - scripts_to_generate = [] - - # Special case pip and setuptools to generate versioned wrappers - # - # The issue is that some projects (specifically, pip and setuptools) use - # code in setup.py to create "versioned" entry points - pip2.7 on Python - # 2.7, pip3.3 on Python 3.3, etc. But these entry points are baked into - # the wheel metadata at build time, and so if the wheel is installed with - # a *different* version of Python the entry points will be wrong. The - # correct fix for this is to enhance the metadata to be able to describe - # such versioned entry points. - # Currently, 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. As a workaround, we - # override the versioned entry points in the wheel and generate the - # correct ones. - # - # To add the level of hack in this section of code, in order to support - # ensurepip this code will look for an ``ENSUREPIP_OPTIONS`` environment - # variable which will control which version scripts get installed. - # - # ENSUREPIP_OPTIONS=altinstall - # - Only pipX.Y and easy_install-X.Y will be generated and installed - # ENSUREPIP_OPTIONS=install - # - pipX.Y, pipX, easy_install-X.Y will be generated and installed. Note - # that this option is technically if ENSUREPIP_OPTIONS is set and is - # not altinstall - # DEFAULT - # - The default behavior is to install pip, pipX, pipX.Y, easy_install - # and easy_install-X.Y. - pip_script = console.pop("pip", None) - if pip_script: - if "ENSUREPIP_OPTIONS" not in os.environ: - scripts_to_generate.append("pip = " + pip_script) - - if os.environ.get("ENSUREPIP_OPTIONS", "") != "altinstall": - scripts_to_generate.append(f"pip{sys.version_info[0]} = {pip_script}") - - scripts_to_generate.append(f"pip{get_major_minor_version()} = {pip_script}") - # Delete any other versioned pip entry points - pip_ep = [k for k in console if re.match(r"pip(\d+(\.\d+)?)?$", k)] - for k in pip_ep: - del console[k] - easy_install_script = console.pop("easy_install", None) - if easy_install_script: - if "ENSUREPIP_OPTIONS" not in os.environ: - scripts_to_generate.append("easy_install = " + easy_install_script) - - scripts_to_generate.append( - f"easy_install-{get_major_minor_version()} = {easy_install_script}" - ) - # Delete any other versioned easy_install entry points - easy_install_ep = [ - k for k in console if re.match(r"easy_install(-\d+\.\d+)?$", k) - ] - for k in easy_install_ep: - del console[k] - - # Generate the console entry points specified in the wheel - scripts_to_generate.extend(starmap("{} = {}".format, console.items())) - - return scripts_to_generate - - -class ZipBackedFile: - def __init__( - self, src_record_path: RecordPath, dest_path: str, zip_file: ZipFile - ) -> None: - self.src_record_path = src_record_path - self.dest_path = dest_path - self._zip_file = zip_file - self.changed = False - - def _getinfo(self) -> ZipInfo: - return self._zip_file.getinfo(self.src_record_path) - - def save(self) -> None: - # When we open the output file below, any existing file is truncated - # before we start writing 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(self.dest_path): - os.unlink(self.dest_path) - - zipinfo = self._getinfo() - - # optimization: the file is created by open(), - # skip the decompression when there is 0 bytes to decompress. - with open(self.dest_path, "wb") as dest: - if zipinfo.file_size > 0: - with self._zip_file.open(zipinfo) as f: - blocksize = min(zipinfo.file_size, 1024 * 1024) - shutil.copyfileobj(f, dest, blocksize) - - if zip_item_is_executable(zipinfo): - set_extracted_file_to_default_mode_plus_executable(self.dest_path) - - -class ScriptFile: - def __init__(self, file: File) -> None: - self._file = file - self.src_record_path = self._file.src_record_path - self.dest_path = self._file.dest_path - self.changed = False - - def save(self) -> None: - self._file.save() - self.changed = fix_script(self.dest_path) - - -class MissingCallableSuffix(InstallationError): - def __init__(self, entry_point: str) -> None: - super().__init__( - f"Invalid script entry point: {entry_point} - A callable " - "suffix is required. See https://packaging.python.org/" - "specifications/entry-points/#use-for-scripts for more " - "information." - ) - - -def _raise_for_invalid_entrypoint(specification: str, scripts_dir: str) -> None: - entry = get_export_entry(specification) - if entry is None: - return - - if entry.suffix is None: - raise MissingCallableSuffix(str(entry)) - - # distlib joins the entry point name onto the scripts directory, so a name - # with path separators or ``..`` components can resolve elsewhere. The script - # must resolve to a path strictly inside the scripts directory. - dest = os.path.join(scripts_dir, entry.name) - resolves_to_scripts_dir = os.path.abspath(dest) == os.path.abspath(scripts_dir) - if resolves_to_scripts_dir or not is_within_directory(scripts_dir, dest): - raise InstallationError( - f"Invalid script entry point name {entry.name!r}: the script " - f"would be installed outside the scripts directory ({scripts_dir})." - ) - - -class PipScriptMaker(ScriptMaker): - # Override distlib's default script template with one that - # doesn't import `re` module, allowing scripts to load faster. - script_template = textwrap.dedent("""\ - import sys - from %(module)s import %(import_name)s - if __name__ == '__main__': - sys.argv[0] = sys.argv[0].removesuffix('.exe') - sys.exit(%(func)s()) -""") - - def make( - self, specification: str, options: dict[str, Any] | None = None - ) -> list[str]: - _raise_for_invalid_entrypoint(specification, self.target_dir) - return super().make(specification, options) - - -def _install_wheel( # noqa: C901, PLR0915 function is too long - name: str, - wheel_zip: ZipFile, - wheel_path: str, - scheme: Scheme, - pycompile: bool = True, - warn_script_location: bool = True, - direct_url: DirectUrl | None = None, - requested: bool = False, - script_executable: str | None = None, -) -> None: - """Install a wheel. - - :param name: Name of the project to install - :param wheel_zip: open ZipFile for wheel being installed - :param scheme: Distutils scheme dictating the install directories - :param req_description: String used in place of the requirement, for - logging - :param pycompile: Whether to byte-compile installed Python files - :param warn_script_location: Whether to check that scripts are installed - into a directory on PATH - :param script_executable: Python executable to use for console scripts - :raises UnsupportedWheel: - * when the directory holds an unpacked wheel with incompatible - Wheel-Version - * when the .dist-info dir does not match the wheel - """ - info_dir, metadata = parse_wheel(wheel_zip, name) - - if wheel_root_is_purelib(metadata): - lib_dir = scheme.purelib - else: - lib_dir = scheme.platlib - - # 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: dict[RecordPath, RecordPath] = {} - changed: set[RecordPath] = set() - generated: list[str] = [] - - def record_installed( - srcfile: RecordPath, destfile: str, modified: bool = False - ) -> None: - """Map archive RECORD paths to installation RECORD paths.""" - newpath = _fs_to_record_path(destfile, lib_dir) - installed[srcfile] = newpath - if modified: - changed.add(newpath) - - def is_dir_path(path: RecordPath) -> bool: - return path.endswith("/") - - def assert_no_path_traversal(dest_dir_path: str, target_path: str) -> None: - if not is_within_directory(dest_dir_path, target_path): - message = ( - "The wheel {!r} has a file {!r} trying to install" - " outside the target directory {!r}" - ) - raise InstallationError( - message.format(wheel_path, target_path, dest_dir_path) - ) - - def root_scheme_file_maker( - zip_file: ZipFile, dest: str - ) -> Callable[[RecordPath], File]: - def make_root_scheme_file(record_path: RecordPath) -> File: - normed_path = os.path.normpath(record_path) - dest_path = os.path.join(dest, normed_path) - assert_no_path_traversal(dest, dest_path) - return ZipBackedFile(record_path, dest_path, zip_file) - - return make_root_scheme_file - - def data_scheme_file_maker( - zip_file: ZipFile, scheme: Scheme - ) -> Callable[[RecordPath], File]: - scheme_paths = {key: getattr(scheme, key) for key in SCHEME_KEYS} - - def make_data_scheme_file(record_path: RecordPath) -> File: - normed_path = os.path.normpath(record_path) - try: - _, scheme_key, dest_subpath = normed_path.split(os.path.sep, 2) - except ValueError: - message = ( - f"Unexpected file in {wheel_path}: {record_path!r}. .data directory" - " contents should be named like: '/'." - ) - raise InstallationError(message) - - try: - scheme_path = scheme_paths[scheme_key] - except KeyError: - valid_scheme_keys = ", ".join(sorted(scheme_paths)) - message = ( - f"Unknown scheme key used in {wheel_path}: {scheme_key} " - f"(for file {record_path!r}). .data directory contents " - f"should be in subdirectories named with a valid scheme " - f"key ({valid_scheme_keys})" - ) - raise InstallationError(message) - - dest_path = os.path.join(scheme_path, dest_subpath) - assert_no_path_traversal(scheme_path, dest_path) - return ZipBackedFile(record_path, dest_path, zip_file) - - return make_data_scheme_file - - def is_data_scheme_path(path: RecordPath) -> bool: - return path.split("/", 1)[0].endswith(".data") - - paths = cast(list[RecordPath], wheel_zip.namelist()) - file_paths = filterfalse(is_dir_path, paths) - root_scheme_paths, data_scheme_paths = partition(is_data_scheme_path, file_paths) - - make_root_scheme_file = root_scheme_file_maker(wheel_zip, lib_dir) - files: Iterator[File] = map(make_root_scheme_file, root_scheme_paths) - - def is_script_scheme_path(path: RecordPath) -> bool: - parts = path.split("/", 2) - return len(parts) > 2 and parts[0].endswith(".data") and parts[1] == "scripts" - - other_scheme_paths, script_scheme_paths = partition( - is_script_scheme_path, data_scheme_paths - ) - - make_data_scheme_file = data_scheme_file_maker(wheel_zip, scheme) - other_scheme_files = map(make_data_scheme_file, other_scheme_paths) - files = chain(files, other_scheme_files) - - # Get the defined entry points - distribution = get_wheel_distribution( - FilesystemWheel(wheel_path), - canonicalize_name(name), - ) - console, gui = get_entrypoints(distribution) - - def is_entrypoint_wrapper(file: File) -> bool: - # EP, EP.exe and EP-script.py are scripts generated for - # entry point EP by setuptools - path = file.dest_path - name = os.path.basename(path) - 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 - - script_scheme_files: Iterator[File] = map( - make_data_scheme_file, script_scheme_paths - ) - script_scheme_files = filterfalse(is_entrypoint_wrapper, script_scheme_files) - script_scheme_files = map(ScriptFile, script_scheme_files) - files = chain(files, script_scheme_files) - - existing_parents = set() - for file in files: - # directory creation is lazy and after file filtering - # to ensure we don't install empty dirs; empty dirs can't be - # uninstalled. - parent_dir = os.path.dirname(file.dest_path) - if parent_dir not in existing_parents: - ensure_dir(parent_dir) - existing_parents.add(parent_dir) - file.save() - record_installed(file.src_record_path, file.dest_path, file.changed) - - def pyc_source_file_paths() -> Generator[str, None, None]: - # We de-duplicate installation paths, since there can be overlap (e.g. - # file in .data maps to same location as file in wheel root). - # Sorting installation paths makes it easier to reproduce and debug - # issues related to permissions on existing files. - for installed_path in sorted(set(installed.values())): - full_installed_path = os.path.join(lib_dir, installed_path) - if not os.path.isfile(full_installed_path): - continue - if not full_installed_path.endswith(".py"): - continue - yield full_installed_path - - def pyc_output_path(path: str) -> str: - """Return the path the pyc file would have been written to.""" - return importlib.util.cache_from_source(path) - - # Compile all of the pyc files for the installed files - if pycompile: - with contextlib.redirect_stdout( - StreamWrapper.from_stream(sys.stdout) - ) as stdout: - with warnings.catch_warnings(): - warnings.filterwarnings("ignore") - for path in pyc_source_file_paths(): - success = compileall.compile_file(path, force=True, quiet=True) - if success: - pyc_path = pyc_output_path(path) - assert os.path.exists(pyc_path) - pyc_record_path = cast( - "RecordPath", pyc_path.replace(os.path.sep, "/") - ) - record_installed(pyc_record_path, pyc_path) - logger.debug(stdout.getvalue()) - - maker = PipScriptMaker(None, scheme.scripts) - - # Embed the target environment's interpreter in console-script launchers - # rather than the one running pip, so an in-process install into another - # environment (e.g. a venv build environment) produces working launchers. - if script_executable is not None: - maker.executable = script_executable # type: ignore # it's untyped in distlib - - # 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 - - # Generate the console and GUI entry points specified in the wheel - scripts_to_generate = get_console_script_specs(console) - - gui_scripts_to_generate = list(starmap("{} = {}".format, gui.items())) - - generated_console_scripts = maker.make_multiple(scripts_to_generate) - generated.extend(generated_console_scripts) - - generated.extend(maker.make_multiple(gui_scripts_to_generate, {"gui": True})) - - if warn_script_location: - msg = message_about_scripts_not_on_PATH(generated_console_scripts) - if msg is not None: - logger.warning(msg) - - generated_file_mode = 0o666 & ~current_umask() - - @contextlib.contextmanager - def _generate_file(path: str, **kwargs: Any) -> Generator[BinaryIO, None, None]: - with adjacent_tmp_file(path, **kwargs) as f: - yield f - os.chmod(f.name, generated_file_mode) - replace(f.name, path) - - dest_info_dir = os.path.join(lib_dir, info_dir) - - # Record pip as the installer - installer_path = os.path.join(dest_info_dir, "INSTALLER") - with _generate_file(installer_path) as installer_file: - installer_file.write(b"pip\n") - generated.append(installer_path) - - # Record the PEP 610 direct URL reference - if direct_url is not None: - direct_url_path = os.path.join(dest_info_dir, DIRECT_URL_METADATA_NAME) - with _generate_file(direct_url_path) as direct_url_file: - direct_url_file.write(direct_url.to_json().encode("utf-8")) - generated.append(direct_url_path) - - # Record the REQUESTED file - if requested: - requested_path = os.path.join(dest_info_dir, "REQUESTED") - with open(requested_path, "wb"): - pass - generated.append(requested_path) - - record_text = distribution.read_text("RECORD") - record_rows = list(csv.reader(record_text.splitlines())) - - rows = get_csv_rows_for_installed( - record_rows, - installed=installed, - changed=changed, - generated=generated, - lib_dir=lib_dir, - ) - - # Record details of all files installed - record_path = os.path.join(dest_info_dir, "RECORD") - - with _generate_file(record_path, **csv_io_kwargs("w")) as record_file: - # Explicitly cast to typing.IO[str] as a workaround for the mypy error: - # "writer" has incompatible type "BinaryIO"; expected "_Writer" - writer = csv.writer(cast("IO[str]", record_file)) - writer.writerows(_normalized_outrows(rows)) - - -@contextlib.contextmanager -def req_error_context(req_description: str) -> Generator[None, None, None]: - try: - yield - except InstallationError as e: - message = f"For req: {req_description}. {e.args[0]}" - raise InstallationError(message) from e - - -def install_wheel( - name: str, - wheel_path: str, - scheme: Scheme, - req_description: str, - pycompile: bool = True, - warn_script_location: bool = True, - direct_url: DirectUrl | None = None, - requested: bool = False, - script_executable: str | None = None, -) -> None: - with ZipFile(wheel_path, allowZip64=True) as z: - with req_error_context(req_description): - _install_wheel( - name=name, - wheel_zip=z, - wheel_path=wheel_path, - scheme=scheme, - pycompile=pycompile, - warn_script_location=warn_script_location, - direct_url=direct_url, - requested=requested, - script_executable=script_executable, - ) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/operations/prepare.py b/venv/lib/python3.11/site-packages/pip/_internal/operations/prepare.py deleted file mode 100755 index 34a07a1..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/operations/prepare.py +++ /dev/null @@ -1,896 +0,0 @@ -"""Prepares a distribution for installation""" - -# The following comment should be removed at some point in the future. -# mypy: strict-optional=False -from __future__ import annotations - -import mimetypes -import os -import shutil -from collections.abc import Iterable -from dataclasses import dataclass -from pathlib import Path -from typing import TYPE_CHECKING - -from pip._vendor.packaging.requirements import InvalidRequirement -from pip._vendor.packaging.utils import canonicalize_name - -from pip._internal.build_env import BuildEnvironmentInstaller, BuildIsolationMode -from pip._internal.distributions import make_distribution_for_install_requirement -from pip._internal.distributions.installed import InstalledDistribution -from pip._internal.exceptions import ( - DirectoryUrlHashUnsupported, - HashMismatch, - HashUnpinned, - InstallationError, - MetadataInconsistent, - MetadataInvalid, - NetworkConnectionError, - SidecarMetadataInconsistent, - VcsHashUnsupported, -) -from pip._internal.index.package_finder import PackageFinder -from pip._internal.metadata import BaseDistribution, get_metadata_distribution -from pip._internal.models.direct_url import ArchiveInfo, DirectUrl -from pip._internal.models.link import Link, join_within_directory -from pip._internal.models.wheel import Wheel -from pip._internal.network.download import Downloader -from pip._internal.network.lazy_wheel import ( - HTTPRangeRequestUnsupported, - dist_from_wheel_url, -) -from pip._internal.network.session import PipSession -from pip._internal.operations.build.build_tracker import BuildTracker -from pip._internal.req.req_install import InstallRequirement -from pip._internal.utils._log import getLogger -from pip._internal.utils.direct_url_helpers import ( - direct_url_for_editable, - direct_url_from_link, -) -from pip._internal.utils.hashes import Hashes, MissingHashes -from pip._internal.utils.logging import indent_log -from pip._internal.utils.misc import ( - display_path, - hash_file, - hide_url, - redact_auth_from_requirement, -) -from pip._internal.utils.packaging import get_requirement -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.utils.unpacking import unpack_file -from pip._internal.vcs import vcs - -if TYPE_CHECKING: - from pip._internal.cli.progress_bars import BarType - -logger = getLogger(__name__) - - -def _get_prepared_distribution( - req: InstallRequirement, - build_tracker: BuildTracker, - build_env_installer: BuildEnvironmentInstaller, - build_isolation: BuildIsolationMode, - check_build_deps: bool, - allow_editables: bool, -) -> BaseDistribution: - """Prepare a distribution for installation.""" - abstract_dist = make_distribution_for_install_requirement(req) - tracker_id = abstract_dist.build_tracker_id - if tracker_id is not None: - with build_tracker.track(req, tracker_id): - abstract_dist.prepare_distribution_metadata( - build_env_installer, build_isolation, check_build_deps, allow_editables - ) - return abstract_dist.get_metadata_distribution() - - -def unpack_vcs_link(link: Link, location: str, verbosity: int) -> None: - vcs_backend = vcs.get_backend_for_scheme(link.scheme) - assert vcs_backend is not None - vcs_backend.unpack(location, url=hide_url(link.url), verbosity=verbosity) - - -@dataclass -class File: - path: str - content_type: str | None = None - - def __post_init__(self) -> None: - if self.content_type is None: - # Try to guess the file's MIME type. If the system MIME tables - # can't be loaded, give up. - try: - self.content_type = mimetypes.guess_type(self.path)[0] - except OSError: - pass - - -def get_http_url( - link: Link, - download: Downloader, - download_dir: str | None = None, - hashes: Hashes | None = None, -) -> File: - temp_dir = TempDirectory(kind="unpack", globally_managed=True) - # If a download dir is specified, is the file already downloaded there? - already_downloaded_path = None - if download_dir: - already_downloaded_path = _check_download_dir(link, download_dir, hashes) - - if already_downloaded_path: - from_path = already_downloaded_path - content_type = None - else: - # let's download to a tmp dir - from_path, content_type = download(link, temp_dir.path) - if hashes: - hashes.check_against_path(from_path) - - return File(from_path, content_type) - - -def get_file_url( - link: Link, download_dir: str | None = None, hashes: Hashes | None = None -) -> File: - """Get file and optionally check its hash.""" - # If a download dir is specified, is the file already there and valid? - already_downloaded_path = None - if download_dir: - already_downloaded_path = _check_download_dir(link, download_dir, hashes) - - if already_downloaded_path: - from_path = already_downloaded_path - else: - from_path = link.file_path - - # If --require-hashes is off, `hashes` is either empty, the - # link's embedded hash, or MissingHashes; it is required to - # match. If --require-hashes is on, we are satisfied by any - # hash in `hashes` matching: a URL-based or an option-based - # one; no internet-sourced hash will be in `hashes`. - if hashes: - hashes.check_against_path(from_path) - return File(from_path, None) - - -def unpack_url( - link: Link, - location: str, - download: Downloader, - verbosity: int, - download_dir: str | None = None, - hashes: Hashes | None = None, -) -> File | None: - """Unpack link into location, downloading if required. - - :param hashes: A Hashes object, one of whose embedded hashes must match, - or HashMismatch will be raised. If the Hashes is empty, no matches are - required, and unhashable types of requirements (like VCS ones, which - would ordinarily raise HashUnsupported) are allowed. - """ - # non-editable vcs urls - if link.is_vcs: - unpack_vcs_link(link, location, verbosity=verbosity) - return None - - assert not link.is_existing_dir() - - # file urls - if link.is_file: - file = get_file_url(link, download_dir, hashes=hashes) - - # http urls - else: - file = get_http_url( - link, - download, - download_dir, - hashes=hashes, - ) - - # unpack the archive to the build dir location. even when only downloading - # archives, they have to be unpacked to parse dependencies, except wheels - if not link.is_wheel: - unpack_file(file.path, location, file.content_type) - - return file - - -def _check_download_dir( - link: Link, - download_dir: str, - hashes: Hashes | None, - warn_on_hash_mismatch: bool = True, -) -> str | None: - """Check download_dir for previously downloaded file with correct hash - If a correct file is found return its path else None - """ - download_path = join_within_directory(download_dir, link.filename) - - if not os.path.exists(download_path): - return None - - # If already downloaded, does its hash match? - logger.info("File was already downloaded %s", download_path) - if hashes: - try: - hashes.check_against_path(download_path) - except HashMismatch: - if warn_on_hash_mismatch: - logger.warning( - "Previously-downloaded file %s has bad hash. Re-downloading.", - download_path, - ) - os.unlink(download_path) - return None - return download_path - - -def _canonicalize_requirement(raw: str) -> str: - """Return a normalized form of a PEP 508 requirement string. - - Used to compare ``Requires-Dist`` entries from two sources of metadata - for the same distribution without being confused by superficial - differences in name casing, extra casing, or extras ordering. May raise - ``InvalidRequirement`` if ``raw`` is not a valid PEP 508 string. - - TODO: once https://github.com/pypa/packaging/pull/1278 is released and - vendored, ``Requirement.__eq__`` will canonicalize requested extras and - this manual normalization can be dropped in favour of comparing - ``Requirement`` objects directly. - """ - parsed = get_requirement(raw) - parts: list[str] = [canonicalize_name(parsed.name)] - if parsed.extras: - normalized_extras = sorted(canonicalize_name(e) for e in parsed.extras) - parts.append(f"[{','.join(normalized_extras)}]") - if parsed.specifier: - parts.append(str(parsed.specifier)) - if parsed.url: - parts.append(f" @ {parsed.url}") - if parsed.marker: - parts.append(f"; {parsed.marker}") - return "".join(parts) - - -def _canonical_requires( - req: InstallRequirement, dist: BaseDistribution, source: str -) -> frozenset[str]: - """Return the canonicalized ``Requires-Dist`` entries of ``dist``. - - ``source`` describes which metadata file ``dist`` was parsed from, for - use in error messages. - """ - canonical: set[str] = set() - for raw in dist.iter_raw_dependencies(): - try: - # strip() because a folded metadata header may be returned - # with a leading newline; iter_dependencies() strips for the - # same reason. - canonical.add(_canonicalize_requirement(raw.strip())) - except InvalidRequirement as e: - raise MetadataInvalid(req, f"Requires-Dist in {source}: {e}") - return frozenset(canonical) - - -def _check_sidecar_matches_wheel( - req: InstallRequirement, - sidecar_dist: BaseDistribution, - wheel_dist: BaseDistribution, -) -> None: - """Check that a .metadata-based distribution matches the wheel's METADATA. - - Compare ``Name``, ``Version``, ``Requires-Dist``, ``Requires-Python`` - and ``Provides-Extra`` between the two and abort the install on any - mismatch as PEP 658 requires the metadata files "MUST be identical". - - While the PEP doesn't mandate that consumers enforce the identical - requirement, it's good nonetheless to check to prevent confusing - behaviour when an index misbehaves. - - Also note for name and version, pip usually rejects wheels if they're - inconsistent already. Checking them again here is purely defensive. - """ - - sidecar_name = canonicalize_name(sidecar_dist.raw_name) - wheel_name = canonicalize_name(wheel_dist.raw_name) - if sidecar_name != wheel_name: - raise SidecarMetadataInconsistent(req, "Name", sidecar_name, wheel_name) - - if sidecar_dist.version != wheel_dist.version: - raise SidecarMetadataInconsistent( - req, - "Version", - str(sidecar_dist.version), - str(wheel_dist.version), - ) - - # For multi-use fields, only report the symmetric difference to avoid - # unnecessarily flagging matching values. - sidecar_requires = _canonical_requires( - req, sidecar_dist, "the PEP 658 .metadata file" - ) - wheel_requires = _canonical_requires(req, wheel_dist, "the wheel's METADATA") - if sidecar_requires != wheel_requires: - raise SidecarMetadataInconsistent( - req, - "Requires-Dist", - ", ".join(sorted(sidecar_requires - wheel_requires)), - ", ".join(sorted(wheel_requires - sidecar_requires)), - ) - - if sidecar_dist.requires_python != wheel_dist.requires_python: - raise SidecarMetadataInconsistent( - req, - "Requires-Python", - str(sidecar_dist.requires_python), - str(wheel_dist.requires_python), - ) - - sidecar_extras = frozenset(sidecar_dist.iter_provided_extras()) - wheel_extras = frozenset(wheel_dist.iter_provided_extras()) - if sidecar_extras != wheel_extras: - raise SidecarMetadataInconsistent( - req, - "Provides-Extra", - ", ".join(sorted(sidecar_extras - wheel_extras)), - ", ".join(sorted(wheel_extras - sidecar_extras)), - ) - - -class RequirementPreparer: - """Prepares a Requirement""" - - def __init__( - self, - *, - build_dir: str, - download_dir: str | None, - src_dir: str, - build_isolation: BuildIsolationMode, - build_isolation_installer: BuildEnvironmentInstaller, - check_build_deps: bool, - build_tracker: BuildTracker, - session: PipSession, - progress_bar: BarType, - finder: PackageFinder, - require_hashes: bool, - use_user_site: bool, - lazy_wheel: bool, - verbosity: int, - legacy_resolver: bool, - allow_editables: bool, - ) -> None: - super().__init__() - - self.src_dir = src_dir - self.build_dir = build_dir - self.build_tracker = build_tracker - self._session = session - self._download = Downloader(session, progress_bar) - self.finder = finder - - # Where still-packed archives should be written to. If None, they are - # not saved, and are deleted immediately after unpacking. - self.download_dir = download_dir - - # Is build isolation allowed? - self.build_isolation = build_isolation - self.build_env_installer = build_isolation_installer - - # Should check build dependencies? - self.check_build_deps = check_build_deps - - # Should hash-checking be required? - self.require_hashes = require_hashes - - # Should install in user site-packages? - self.use_user_site = use_user_site - - # Should wheels be downloaded lazily? - self.use_lazy_wheel = lazy_wheel - - # How verbose should underlying tooling be? - self.verbosity = verbosity - - # Are we using the legacy resolver? - self.legacy_resolver = legacy_resolver - - # Memoized downloaded files, as mapping of url: path. - self._downloaded: dict[str, str] = {} - - # Previous "header" printed for a link-based InstallRequirement - self._previous_requirement_header = ("", "") - - # Do we allow preparing editable wheels? - # When using pip wheel, editables must still produce regular wheels - self.allow_editables = allow_editables - - def _log_preparing_link(self, req: InstallRequirement) -> None: - """Provide context for the requirement being prepared.""" - if req.link.is_file and not req.is_wheel_from_cache: - message = "Processing %s" - information = str(display_path(req.link.file_path)) - else: - message = "Collecting %s" - information = redact_auth_from_requirement(req.req) if req.req else str(req) - - # If we used req.req, inject requirement source if available (this - # would already be included if we used req directly) - if req.req and req.comes_from: - if isinstance(req.comes_from, str): - comes_from: str | None = req.comes_from - else: - comes_from = req.comes_from.from_path() - if comes_from: - information += f" (from {comes_from})" - - if (message, information) != self._previous_requirement_header: - self._previous_requirement_header = (message, information) - logger.info(message, information) - - if req.is_wheel_from_cache: - with indent_log(): - logger.info("Using cached %s", req.link.filename) - - def _ensure_link_req_src_dir( - self, req: InstallRequirement, parallel_builds: bool - ) -> None: - """Ensure source_dir of a linked InstallRequirement.""" - # Since source_dir is only set for editable requirements. - if req.link.is_wheel: - # We don't need to unpack wheels, so no need for a source - # directory. - return - assert req.source_dir is None - if req.link.is_existing_dir(): - # build local directories in-tree - req.source_dir = req.link.file_path - return - - # We always delete unpacked sdists after pip runs. - req.ensure_has_source_dir( - self.build_dir, - autodelete=True, - parallel_builds=parallel_builds, - ) - req.ensure_pristine_source_checkout() - - def _get_linked_req_hashes(self, req: InstallRequirement) -> Hashes: - # By the time this is called, the requirement's link should have - # been checked so we can tell what kind of requirements req is - # and raise some more informative errors than otherwise. - # (For example, we can raise VcsHashUnsupported for a VCS URL - # rather than HashMissing.) - if not self.require_hashes: - return req.hashes(trust_internet=True) - - # We could check these first 2 conditions inside unpack_url - # and save repetition of conditions, but then we would - # report less-useful error messages for unhashable - # requirements, complaining that there's no hash provided. - if req.link.is_vcs: - raise VcsHashUnsupported() - if req.link.is_existing_dir(): - raise DirectoryUrlHashUnsupported() - - # Unpinned packages are asking for trouble when a new version - # is uploaded. This isn't a security check, but it saves users - # a surprising hash mismatch in the future. - # file:/// URLs aren't pinnable, so don't complain about them - # not being pinned. - if not req.is_direct and not req.is_pinned: - raise HashUnpinned() - - # If known-good hashes are missing for this requirement, - # shim it with a facade object that will provoke hash - # computation and then raise a HashMissing exception - # showing the user what the hash should be. - return req.hashes(trust_internet=False) or MissingHashes() - - def _fetch_metadata_only( - self, - req: InstallRequirement, - ) -> BaseDistribution | None: - if self.legacy_resolver: - logger.debug( - "Metadata-only fetching is not used in the legacy resolver", - ) - return None - if self.require_hashes: - logger.debug( - "Metadata-only fetching is not used as hash checking is required", - ) - return None - # Try PEP 658 metadata first, then fall back to lazy wheel if unavailable. - return self._fetch_metadata_using_link_data_attr( - req - ) or self._fetch_metadata_using_lazy_wheel(req.link) - - def _fetch_metadata_using_link_data_attr( - self, - req: InstallRequirement, - ) -> BaseDistribution | None: - """Fetch metadata from the data-dist-info-metadata attribute, if possible.""" - # (1) Get the link to the metadata file, if provided by the backend. - metadata_link = req.link.metadata_link() - if metadata_link is None: - return None - assert req.req is not None - logger.verbose( - "Obtaining dependency information for %s from %s", - req.req, - metadata_link, - ) - # (2) Download the contents of the METADATA file, separate from the dist itself. - metadata_file = get_http_url( - metadata_link, - self._download, - hashes=metadata_link.as_hashes(), - ) - with open(metadata_file.path, "rb") as f: - metadata_contents = f.read() - # (3) Generate a dist just from those file contents. - metadata_dist = get_metadata_distribution( - metadata_contents, - req.link.filename, - req.req.name, - ) - # (4) Ensure the Name: field from the METADATA file matches the name from the - # install requirement. - # - # NB: raw_name will fall back to the name from the install requirement if - # the Name: field is not present, but it's noted in the raw_name docstring - # that that should NEVER happen anyway. - if canonicalize_name(metadata_dist.raw_name) != canonicalize_name(req.req.name): - raise MetadataInconsistent( - req, "Name", req.req.name, metadata_dist.raw_name - ) - return metadata_dist - - def _fetch_metadata_using_lazy_wheel( - self, - link: Link, - ) -> BaseDistribution | None: - """Fetch metadata using lazy wheel, if possible.""" - # --use-feature=fast-deps must be provided. - if not self.use_lazy_wheel: - return None - if link.is_file or not link.is_wheel: - logger.debug( - "Lazy wheel is not used as %r does not point to a remote wheel", - link, - ) - return None - - wheel = Wheel(link.filename) - name = wheel.name - logger.info( - "Obtaining dependency information from %s %s", - name, - wheel.version, - ) - url = link.url.split("#", 1)[0] - try: - return dist_from_wheel_url(name, url, self._session) - except HTTPRangeRequestUnsupported: - logger.debug("%s does not support range requests", url) - return None - - def _complete_partial_requirements( - self, - partially_downloaded_reqs: Iterable[InstallRequirement], - parallel_builds: bool = False, - ) -> None: - """Download any requirements which were only fetched by metadata.""" - # Download to a temporary directory. These will be copied over as - # needed for downstream 'download', 'wheel', and 'install' commands. - temp_dir = TempDirectory(kind="unpack", globally_managed=True).path - - # Map each link to the requirement that owns it. This allows us to set - # `req.local_file_path` on the appropriate requirement after passing - # all the links at once into BatchDownloader. - links_to_fully_download: dict[Link, InstallRequirement] = {} - for req in partially_downloaded_reqs: - assert req.link - links_to_fully_download[req.link] = req - - batch_download = self._download.batch(links_to_fully_download.keys(), temp_dir) - for link, (filepath, _) in batch_download: - logger.debug("Downloading link %s to %s", link, filepath) - req = links_to_fully_download[link] - # Record the downloaded file path so wheel reqs can extract a Distribution - # in .get_dist(). - req.local_file_path = filepath - # Record that the file is downloaded so we don't do it again in - # _prepare_linked_requirement(). - self._downloaded[req.link.url] = filepath - - # If this is an sdist, we need to unpack it after downloading, but the - # .source_dir won't be set up until we are in _prepare_linked_requirement(). - # Add the downloaded archive to the install requirement to unpack after - # preparing the source dir. - if not req.is_wheel: - req.needs_unpacked_archive(Path(filepath)) - - # This step is necessary to ensure all lazy wheels are processed - # successfully by the 'download', 'wheel', and 'install' commands. - for req in partially_downloaded_reqs: - self._prepare_linked_requirement(req, parallel_builds) - - def prepare_linked_requirement( - self, req: InstallRequirement, parallel_builds: bool = False - ) -> BaseDistribution: - """Prepare a requirement to be obtained from req.link.""" - assert req.link - self._log_preparing_link(req) - with indent_log(): - # Check if the relevant file is already available - # in the download directory - file_path = None - if self.download_dir is not None and req.link.is_wheel: - hashes = self._get_linked_req_hashes(req) - file_path = _check_download_dir( - req.link, - self.download_dir, - hashes, - # When a locally built wheel has been found in cache, we don't warn - # about re-downloading when the already downloaded wheel hash does - # not match. This is because the hash must be checked against the - # original link, not the cached link. It that case the already - # downloaded file will be removed and re-fetched from cache (which - # implies a hash check against the cache entry's origin.json). - warn_on_hash_mismatch=not req.is_wheel_from_cache, - ) - - if file_path is not None: - # The file is already available, so mark it as downloaded - self._downloaded[req.link.url] = file_path - else: - # The file is not available, attempt to fetch only metadata - metadata_dist = self._fetch_metadata_only(req) - if metadata_dist is not None: - req.needs_more_preparation = True - req.set_dist(metadata_dist) - # Ensure download_info is available even in dry-run mode - if req.download_info is None: - req.download_info = direct_url_from_link( - req.link, req.source_dir - ) - return metadata_dist - - # None of the optimizations worked, fully prepare the requirement - return self._prepare_linked_requirement(req, parallel_builds) - - def prepare_linked_requirements_more( - self, reqs: Iterable[InstallRequirement], parallel_builds: bool = False - ) -> None: - """Prepare linked requirements more, if needed.""" - reqs = [req for req in reqs if req.needs_more_preparation] - for req in reqs: - # Determine if any of these requirements were already downloaded. - if self.download_dir is not None and req.link.is_wheel: - hashes = self._get_linked_req_hashes(req) - file_path = _check_download_dir(req.link, self.download_dir, hashes) - if file_path is not None: - self._downloaded[req.link.url] = file_path - req.needs_more_preparation = False - - # Prepare requirements we found were already downloaded for some - # reason. The other downloads will be completed separately. - partially_downloaded_reqs: list[InstallRequirement] = [] - for req in reqs: - if req.needs_more_preparation: - partially_downloaded_reqs.append(req) - else: - self._prepare_linked_requirement(req, parallel_builds) - - # TODO: separate this part out from RequirementPreparer when the v1 - # resolver can be removed! - self._complete_partial_requirements( - partially_downloaded_reqs, - parallel_builds=parallel_builds, - ) - - def _prepare_linked_requirement( - self, req: InstallRequirement, parallel_builds: bool - ) -> BaseDistribution: - assert req.link - link = req.link - - hashes = self._get_linked_req_hashes(req) - - if hashes and req.is_wheel_from_cache: - assert req.download_info is not None - assert link.is_wheel - assert link.is_file - # We need to verify hashes, and we have found the requirement in the cache - # of locally built wheels. - if ( - req.download_info.archive_info - and req.download_info.archive_info.hashes - and hashes.has_one_of(req.download_info.archive_info.hashes) - ): - # At this point we know the requirement was built from a hashable source - # artifact, and we verified that the cache entry's hash of the original - # artifact matches one of the hashes we expect. We don't verify hashes - # against the cached wheel, because the wheel is not the original. - hashes = None - else: - logger.warning( - "The hashes of the source archive found in cache entry " - "don't match, ignoring cached built wheel " - "and re-downloading source." - ) - req.link = req.cached_wheel_source_link - link = req.link - - self._ensure_link_req_src_dir(req, parallel_builds) - - if link.is_existing_dir(): - local_file = None - elif link.url not in self._downloaded: - try: - local_file = unpack_url( - link, - req.source_dir, - self._download, - self.verbosity, - self.download_dir, - hashes, - ) - except NetworkConnectionError as exc: - raise InstallationError( - f"Could not install requirement {req} because of HTTP " - f"error {exc} for URL {link}" - ) - else: - file_path = self._downloaded[link.url] - if hashes: - hashes.check_against_path(file_path) - local_file = File(file_path, content_type=None) - - # If download_info is set, we got it from the wheel cache. - if req.download_info is None: - # Editables don't go through this function (see - # prepare_editable_requirement). - assert not req.editable - req.download_info = direct_url_from_link(link, req.source_dir) - # Make sure we have a hash in download_info. If we got it as part of the - # URL, it will have been verified and we can rely on it. Otherwise we - # compute it from the downloaded file. - # FIXME: https://github.com/pypa/pip/issues/11943 - if ( - req.download_info.archive_info - and not req.download_info.archive_info.hashes - and local_file - ): - hash = hash_file(local_file.path)[0].hexdigest() - # We populate archive_info.hashes. For backward compatibility, - # the legacy hash field will be generated when converting to JSON. - req.download_info = DirectUrl( - url=req.download_info.url, - archive_info=ArchiveInfo(hashes={"sha256": hash}), - subdirectory=req.download_info.subdirectory, - ) - - # For use in later processing, - # preserve the file path on the requirement. - if local_file: - req.local_file_path = local_file.path - - dist = _get_prepared_distribution( - req, - self.build_tracker, - self.build_env_installer, - self.build_isolation, - self.check_build_deps, - self.allow_editables, - ) - - # If a PEP 658 .metadata file was used, check that fields relevant for - # dependency resolution match with the wheel's METADATA file. - # - # NOTE: PEP 658 also permits .metadata files for source distributions, - # but PyPI doesn't serve such files. In addition, an sdist's metadata - # is generated at build time and may legitimately differ from what the - # index declared, so it's been decided to skip this check for sdists. - # This can change later if needed. - # - # TODO: this is a hack for checking whether a distribution is metadata- - # only or not. If/when we refactor distributions to delineate between - # metadata-only and concrete distributions, clean this up. - if ( - link.is_wheel - and req._distribution is not None - and req._distribution is not dist - and link.metadata_link() is not None - ): - _check_sidecar_matches_wheel(req, req._distribution, dist) - - return dist - - def save_linked_requirement(self, req: InstallRequirement) -> None: - assert self.download_dir is not None - assert req.link is not None - link = req.link - if link.is_vcs or (link.is_existing_dir() and req.editable): - # Make a .zip of the source_dir we already created. - req.archive(self.download_dir) - return - - if link.is_existing_dir(): - logger.debug( - "Not copying link to destination directory " - "since it is a directory: %s", - link, - ) - return - if req.local_file_path is None: - # No distribution was downloaded for this requirement. - return - - download_location = join_within_directory(self.download_dir, link.filename) - if not os.path.exists(download_location): - shutil.copy(req.local_file_path, download_location) - download_path = display_path(download_location) - logger.info("Saved %s", download_path) - - def prepare_editable_requirement( - self, - req: InstallRequirement, - ) -> BaseDistribution: - """Prepare an editable requirement.""" - assert req.editable, "cannot prepare a non-editable req as editable" - - logger.info("Obtaining %s", req) - - with indent_log(): - if self.require_hashes: - raise InstallationError( - f"The editable requirement {req} cannot be installed when " - "requiring hashes, because there is no single file to " - "hash." - ) - req.ensure_has_source_dir(self.src_dir) - req.update_editable() - assert req.source_dir - req.download_info = direct_url_for_editable(req.unpacked_source_directory) - - dist = _get_prepared_distribution( - req, - self.build_tracker, - self.build_env_installer, - self.build_isolation, - self.check_build_deps, - self.allow_editables, - ) - - req.check_if_exists(self.use_user_site) - - return dist - - def prepare_installed_requirement( - self, - req: InstallRequirement, - skip_reason: str, - ) -> BaseDistribution: - """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 " - f"is set to {req.satisfied_by}" - ) - logger.info( - "Requirement %s: %s (%s)", skip_reason, req, req.satisfied_by.version - ) - with indent_log(): - if self.require_hashes: - logger.debug( - "Since it is already installed, we are trusting this " - "package without checking its hash. To ensure a " - "completely repeatable environment, install into an " - "empty virtualenv." - ) - return InstalledDistribution(req).get_metadata_distribution() diff --git a/venv/lib/python3.11/site-packages/pip/_internal/pyproject.py b/venv/lib/python3.11/site-packages/pip/_internal/pyproject.py deleted file mode 100755 index 8c2f722..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/pyproject.py +++ /dev/null @@ -1,123 +0,0 @@ -from __future__ import annotations - -import os -from collections import namedtuple -from typing import Any - -from pip._vendor.packaging.requirements import InvalidRequirement - -from pip._internal.exceptions import ( - InstallationError, - InvalidPyProjectBuildRequires, - MissingPyProjectBuildRequires, -) -from pip._internal.utils.compat import tomllib -from pip._internal.utils.packaging import get_requirement - - -def _is_list_of_str(obj: Any) -> bool: - return isinstance(obj, list) and all(isinstance(item, str) for item in obj) - - -def make_pyproject_path(unpacked_source_directory: str) -> str: - return os.path.join(unpacked_source_directory, "pyproject.toml") - - -BuildSystemDetails = namedtuple( - "BuildSystemDetails", ["requires", "backend", "check", "backend_path"] -) - - -def load_pyproject_toml( - pyproject_toml: str, setup_py: str, req_name: str -) -> BuildSystemDetails: - """Load the pyproject.toml file. - - Parameters: - 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 - directory paths to import the backend from (backend-path), - relative to the project root. - ) - """ - has_pyproject = os.path.isfile(pyproject_toml) - has_setup = os.path.isfile(setup_py) - - if not has_pyproject and not has_setup: - raise InstallationError( - f"{req_name} does not appear to be a Python project: " - f"neither 'setup.py' nor 'pyproject.toml' found." - ) - - if has_pyproject: - with open(pyproject_toml, encoding="utf-8") as f: - pp_toml = tomllib.loads(f.read()) - build_system = pp_toml.get("build-system") - else: - build_system = None - - if build_system is None: - # In the absence of any explicit backend specification, we - # assume the setuptools backend that most closely emulates the - # traditional direct setup.py execution, and require wheel and - # a version of setuptools that supports that backend. - - build_system = { - "requires": ["setuptools>=40.8.0"], - "build-backend": "setuptools.build_meta:__legacy__", - } - - # Ensure that the build-system section in pyproject.toml conforms - # to PEP 518. - - # Specifying the build-system table but not the requires key is invalid - if "requires" not in build_system: - raise MissingPyProjectBuildRequires(package=req_name) - - # Error out if requires is not a list of strings - requires = build_system["requires"] - if not _is_list_of_str(requires): - raise InvalidPyProjectBuildRequires( - package=req_name, - reason="It is not a list of strings.", - ) - - # Each requirement must be valid as per PEP 508 - for requirement in requires: - try: - get_requirement(requirement) - except InvalidRequirement as error: - raise InvalidPyProjectBuildRequires( - package=req_name, - reason=f"It contains an invalid requirement: {requirement!r}", - ) from error - - backend = build_system.get("build-backend") - backend_path = build_system.get("backend-path", []) - check: list[str] = [] - 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. So we - # make a note to check that this requirement is present once - # we have set up the environment. - # This is quite a lot of work to check for a very specific case. But - # 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:__legacy__" - check = ["setuptools>=40.8.0"] - - return BuildSystemDetails(requires, backend, check, backend_path) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/req/__init__.py b/venv/lib/python3.11/site-packages/pip/_internal/req/__init__.py deleted file mode 100755 index ed2ca30..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/req/__init__.py +++ /dev/null @@ -1,105 +0,0 @@ -from __future__ import annotations - -import collections -import logging -from collections.abc import Generator -from dataclasses import dataclass - -from pip._internal.cli.progress_bars import BarType, get_install_progress_renderer -from pip._internal.utils.logging import indent_log - -from .req_file import parse_requirements -from .req_install import InstallRequirement -from .req_set import RequirementSet - -__all__ = [ - "RequirementSet", - "InstallRequirement", - "parse_requirements", - "install_given_reqs", -] - -logger = logging.getLogger(__name__) - - -@dataclass(frozen=True) -class InstallationResult: - name: str - - -def _validate_requirements( - requirements: list[InstallRequirement], -) -> Generator[tuple[str, InstallRequirement], None, None]: - for req in requirements: - assert req.name, f"invalid to-be-installed requirement: {req}" - yield req.name, req - - -def install_given_reqs( - requirements: list[InstallRequirement], - root: str | None, - home: str | None, - prefix: str | None, - warn_script_location: bool, - use_user_site: bool, - pycompile: bool, - progress_bar: BarType, - script_executable: str | None = None, -) -> list[InstallationResult]: - """ - Install everything in the given list. - - (to be called after having downloaded and unpacked the packages) - """ - to_install = collections.OrderedDict(_validate_requirements(requirements)) - - if to_install: - logger.info( - "Installing collected packages: %s", - ", ".join(to_install.keys()), - ) - - installed = [] - - show_progress = logger.isEnabledFor(logging.INFO) and len(to_install) > 1 - - items = iter(to_install.values()) - if show_progress: - renderer = get_install_progress_renderer( - bar_type=progress_bar, total=len(to_install) - ) - items = renderer(items) - - with indent_log(): - for requirement in items: - req_name = requirement.name - assert req_name is not None - if requirement.should_reinstall: - logger.info("Attempting uninstall: %s", req_name) - with indent_log(): - uninstalled_pathset = requirement.uninstall(auto_confirm=True) - else: - uninstalled_pathset = None - - try: - requirement.install( - root=root, - home=home, - prefix=prefix, - warn_script_location=warn_script_location, - use_user_site=use_user_site, - pycompile=pycompile, - script_executable=script_executable, - ) - except Exception: - # if install did not succeed, rollback previous uninstall - if uninstalled_pathset and not requirement.install_succeeded: - uninstalled_pathset.rollback() - raise - else: - if uninstalled_pathset and requirement.install_succeeded: - uninstalled_pathset.commit() - - installed.append(InstallationResult(req_name)) - - return installed diff --git a/venv/lib/python3.11/site-packages/pip/_internal/req/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/req/__pycache__/__init__.cpython-311.pyc deleted file mode 100755 index c4cc889a962c1b8bb35ee7793d8307f6d54c9144..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4674 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 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/req/__pycache__/constructors.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/req/__pycache__/constructors.cpython-311.pyc deleted file mode 100755 index b1d5f6a3d36721753ac28178432ab318f323875d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26726 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 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/req/__pycache__/pep723.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/req/__pycache__/pep723.cpython-311.pyc deleted file mode 100755 index 5f94e2234ca6ee274841852b2ed3ced53909ae90..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3187 zcmahLTWlN0aqmI$j(X5~L^`Q{Tr2^WY>>3AG*MiEX;8^F8p&~G$4Qtb#F@L4C>`%E zd#A`IsDcetgbw_nrVivfDZ-D!RbhYR!vzEs1@hqn{iFn;5e^Vwpg;8=4LN|2ug)Gt zQj~3U?rwH=W_EXWc6R3e($W${0RO&qXT}u~`VZ?=!M{svr+`>S7-3FFan|xWm*L|) z$7n$pGGbf=T8#U6bPi$PBEo*+zbhbg555Y-12{k=ED@PVgirB3RRKzgSY8z4LCjr3 zgTcp)e_@bwg*T1s&;%SaqwDFb*>eMLWClO#Q=`$SI`GED5$C!^VjpPX?3>~E$?)sp z4^IsC|Jr7fq-i+BaAE@=^$q0I$Z^IWJh3~rKUrHC2-va*+ee{UMg+wFB3qXA$H@~&tTJ>_+5Hc(Z6ycC@_GbEbPXwr=S(ws7fqMBtz zKOx2^QSfcly6#My#!%$csi>WHNZ8Vnv)UA~qgL9ACeq+eYG`_tl8>Vnv0w`k>$)o? zK$3P6iLA2ECy}b88J4$O0OiqUM^{0-DHY(^1_pB_Okijkl1RA0L?UD2Ii1nXiNwcq zn!YOuBof$60$Z>hO4)pWMU>4*n;2pt>LD2jdjwFv_H2riC2_JWa=z}{zbGSUilbih zLR6WU&FKa!XOc?mgi63ja)7G97W0nd&*0zB0?WwRBhA4zxzFDP$vx(M4}OXkxExp9 zqg9n4bQj2bweA8BR|=lS@f%+z!p=FDBl?X$OW^}AsAy_)R{f)lEaLntRSO0jR&yHoTfr>(Aq{Wk(% z@i>q}U-5qu8%KP~{h#?fFVfGjRNS+VJ#)*8Uj|nCN#5g;LY}Z*3sMsX7YM747Mr(}URI83>)WMJ|nlOW11)UgPJ#fVtGi}hHFw=szrKcUwos=E8 z>(fmQ+pb(I;)4=pmDS}^RPi>G(VXNovFS0^ld4ha3glXn9s-`tYJysUpL?g{hV~r^ zeH~N|Fx`Jb#6Z+;$t{JM;;SY3_?motLq5*RQ16Pi+19??^+nh3m0L=|UlxGp2|VHj@4u3k#eNSeI5K>8CX{aR(jTyp$%o|dnLB6#Qr6g zl-Qawv7tt8qZ^uC|Fl?f*e};bBfUz2v`ENzXSw3=`Zd0*Kta@}S0 mELxg*!njZCqShX+vnZ4iG%MoDrEmLI-n-xGbzg`)v;PN4v*R-W diff --git a/venv/lib/python3.11/site-packages/pip/_internal/req/__pycache__/req_dependency_group.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/req/__pycache__/req_dependency_group.cpython-311.pyc deleted file mode 100755 index c1055d1f64a97f9b0434b4fb53c88db1e4a0c3dc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5511 zcmb_gU2Gf25#IabulOfYQtaB!MN}fwkx2`(<=BzsT9Ol~aqJ*Y)kKLQpLr*V?(vS< zJ4qHx1%?q63g8Df4Pd8<0iq}z8OeizqNv*D!8Qssk7U8N!T|yd6aiYG4-Aw7hMzjS zM^Yq3J9+48Z#cU&yNs& z?2hXD&=x1VU_7wZp5bNp`}|Z;_9!8k<*1+aJ#?`Rx*W0>bhXQE3RB+??w%Go@>E1bRXfnqf++Dv{2U7*j<~Q%|dE>VoB%B?=77ffaKe zYf1P_wc-GdgJ)9%avhm0tT%AqlI3r0SN$1b-(;`5r+GGmh2m0}824xt>AL$_Fv zg~u+9GvOfE?1vr^%4-rf6j842SG3nF%91IGk|AcWzL1g?SzJg-qB*CCqo*eN#FQpV z;`z5Tk~w$u9G!7qG?p||x)k?NwXaJlLovi{M`MVo8Bx-f%(;{{E6(a5vxs$VHcn?X zoDSLB06d!_kXH}`CzM0y-0#4imYHQX$4sK@41=zEWONqYW=`KmG0tM+2P~c}%VMSt zq5-z}NJ`Ah6USWvWu1bm}J29~311M&X;gpo3p{TV6wQ)yN) z5}8ycF`d%DQZz|TVC7x%Om7|5G~IeUv-HS4G^=RJr3@aHi%J(A`X-8uE#7E?}Sk=JjM|qm(hRQQ0N(ZEq4~+wOwI%SPBjny@yNQ!v+2@?ts~tU_`QJiqHTQLs57(BVf#xPs@y< zb64ocWtX`e%GF`cGVcal1Bc-AFll?qagFBP>^3I>1%JkYxv)P69K3okip;vz^dLO4 zEXW+_7cSQNn{_NZ%qrHx0%ShNeS%~m#{zZ8&OE<;Rp5q>#&vyyZZ`Ggge$DfE(`Ao zi_9Xr#Jzb=o-(Ty~*7e{n+)X3mQ$8+TQ5~NFfkO%zm>E z$aOSJ044O~J^g~c+77!3zy!P-$nDBr7^QwEk32)f1Cx3>Go0;x@`h@H-DD+ufPm+B z4cax|4;wo1vEx%mt&8p>`~2Hmu(RLB=yP>eAb32mH_P=N6(6xL ziZQ`*RuO>MvE@;!_n3iQq=Ubxr?i-pIxB??Owh@4(|2i78ZOGJ0*h5>4k@SX=A*a3iq0j2v!ITqO_ak*=~|_~0aqU4x~r z!Ikli_Gp=9LNBbP$_RcaS>Lg{%+(s*&wUpAb!>IK*nOzfeQ0ao8;%S6zePaG4ixDu zJ2_wHLnvh@ypa65tJ^Zju7COL5%v$B5ka`e9UDQyeIx*H3FKxn8cdRaGr6ZWSHQ8Z zqZHh2>!Se~W&<>FH=CgG3dqXLR?xQ0 zH^dFRNn(;pX^bF@M*Te1FKpNEMy9)}0U&~JTrET<><|oJeHTEOhPAdVfbekuVFv}_ z+8SDbFgdGAk)3o6F4>*0gXZdJOZaVG4S`?O2){W7;Ma3H8`|b?*}hgjXp$gOT!c_5 zoiYpp$`p!wv(etTI4WtHZrXmjpoqQuZP)D;bs9p(Tf23gN=XHePJ?4Z#Fg#-ZiNlD z^?!gn{0y9DJ^I_EZa|bV(b+x ztEsU%u(Y^6M8nS$S#mjS2enQzL`aMb4}!N|M(e@$%McAWe%%|mcBJ6l z1$DhG@^vJdA1g*;rATbWz3$zUPZhigs1+a@SThL*4Q!D*oI#w=Uv{Bq_7(OWgJ7%R z+Px9jQP`RIU8EQoECmM3h(LUzN}_>=l{cHQilw0<`yRW*r(Wb@X3#YSvB7w&leO{Bl8{4venq7+|Wg$3=55N&rJFz0kq%-EUczB_P z$t47N5p2T>y#%q*Y2AE@yoc(rVI)AdGNvSTS)sj_^UPVw#5fx;*qIC_QCc;Vw8NWz z=)r`Hlc52M1m!lDaFW^Zg|7A7;ETT9B_G5ijJqe_z7gK}(NLZ(hNGo$6ygbY4;|Pd z-w?TP3EApv#StHRqSV8$y}Lj{_z6=_H~dfM4;I89+qLMQEcqu3uE`B=d&vvI7z4|$ zryyPshwemxKwS&jzeWGClK8eHaPWDYz3M3{SM-^gC>-oDNe#N9_e;P3l7N21*Qr~v%wScerz>Z%I& z0whL8T)L3N1S>GfUMz>XlmUyt#NVu5Naf?xknzhpj@$V?jK#O^_)5A=FA{54YiWgK zS_Zvltf#0*^?w8L=4g6n<1l1ysu3sYfn-w4#9d@nf;pd26-;sfns8&1a@pZCy>6(b z(bR+H(IjnL7mRo78xp|L(duM`^VIyzivtPjv& zp|Nh)Uv@Z|7xH7P9jnHj(bY>|JYDKJQby3XCf^ zN`d||N4j1-epk4g{A%Ft+@Axb7hj{D4+P&z^8IsV0R+mZk?h^YbliXx@Y7ez2-sEm p&cGUX=Y=mc+H5Ane&!@|BU(n}H{X*tR!8%feiOIbPo^|}`5#&8UyuL* diff --git a/venv/lib/python3.11/site-packages/pip/_internal/req/__pycache__/req_file.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/req/__pycache__/req_file.cpython-311.pyc deleted file mode 100755 index 2e0645940bf9df4bc063d0188f0cf8470a5392e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26021 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 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/req/__pycache__/req_set.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/req/__pycache__/req_set.cpython-311.pyc deleted file mode 100755 index 068c3eb78584aab0aae458ca8da98c9d993742ba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5931 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 N6ZZW3eR>&${|2`}R(}8h diff --git a/venv/lib/python3.11/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-311.pyc deleted file mode 100755 index 92f13274017ee08b565a77ad91e566a02433f177..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36139 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 WV`$Pj$O8-JgU96es{#QGGyeZ7b4R2A diff --git a/venv/lib/python3.11/site-packages/pip/_internal/req/constructors.py b/venv/lib/python3.11/site-packages/pip/_internal/req/constructors.py deleted file mode 100755 index 4915894..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/req/constructors.py +++ /dev/null @@ -1,662 +0,0 @@ -"""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. -""" - -from __future__ import annotations - -import copy -import logging -import os -import re -from collections.abc import Collection, Mapping -from dataclasses import dataclass - -from pip._vendor.packaging import pylock -from pip._vendor.packaging.markers import InvalidMarker, Marker -from pip._vendor.packaging.requirements import InvalidRequirement, Requirement -from pip._vendor.packaging.utils import parse_sdist_filename, parse_wheel_filename - -from pip._internal.exceptions import InstallationError -from pip._internal.models.index import PyPI, TestPyPI -from pip._internal.models.link import Link -from pip._internal.models.wheel import Wheel -from pip._internal.req.req_file import ParsedRequirement -from pip._internal.req.req_install import InstallRequirement -from pip._internal.utils.filetypes import is_archive_file -from pip._internal.utils.misc import is_installable_dir -from pip._internal.utils.packaging import get_requirement -from pip._internal.utils.pylock import ( - package_archive_requirement_url, - package_directory_requirement_url, - package_sdist_requirement_url, - package_vcs_requirement_url, - package_wheel_requirement_url, -) -from pip._internal.utils.urls import path_to_url -from pip._internal.vcs import is_url, vcs - -__all__ = [ - "install_req_from_editable", - "install_req_from_line", - "parse_editable", -] - -logger = logging.getLogger(__name__) - -# All standard version specifier operators -# https://packaging.python.org/en/latest/specifications/version-specifiers/#id5 -operators = ("~=", "==", "!=", "<=", ">=", "<", ">", "===") - - -def strip_extras(path: str) -> tuple[str, set[str]]: - m = re.match(r"^(.+)(\[[^\]]+\])$", path) - extras = None - if m: - path_no_extras = m.group(1).rstrip() - extras = m.group(2) - else: - path_no_extras = path - - return path_no_extras, _convert_extras(extras) - - -def _convert_extras(extras: str | None) -> set[str]: - if not extras: - return set() - return get_requirement("placeholder" + extras.lower()).extras - - -def _set_requirement_extras(req: Requirement, new_extras: set[str]) -> Requirement: - """ - Returns a new requirement based on the given one, with the supplied extras. If the - given requirement already has extras those are replaced (or dropped if no new extras - are given). - """ - match: re.Match[str] | None = re.fullmatch( - # see https://peps.python.org/pep-0508/#complete-grammar - r"([\w\t .-]+)(\[[^\]]*\])?(.*)", - str(req), - flags=re.ASCII, - ) - # ireq.req is a valid requirement so the regex should always match - assert ( - match is not None - ), f"regex match on requirement {req} failed, this should never happen" - pre: str | None = match.group(1) - post: str | None = match.group(3) - assert ( - pre is not None and post is not None - ), f"regex group selection for requirement {req} failed, this should never happen" - extras: str = "[{}]".format(",".join(sorted(new_extras)) if new_extras else "") - return get_requirement(f"{pre}{extras}{post}") - - -def _parse_direct_url_editable(editable_req: str) -> tuple[str | None, str, set[str]]: - try: - req = Requirement(editable_req) - except InvalidRequirement: - pass - else: - if req.url: - # Join the marker back into the name part. This will be parsed out - # later into a Requirement again. - if req.marker: - name = f"{req.name} ; {req.marker}" - else: - name = req.name - return (name, req.url, req.extras) - - raise ValueError - - -def _parse_pip_syntax_editable(editable_req: str) -> tuple[str | None, str, set[str]]: - 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): - # 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 - return (package_name, url_no_extras, extras) - - for version_control in vcs: - if url.lower().startswith(f"{version_control}:"): - url = f"{version_control}+{url}" - break - - return Link(url).egg_fragment, url, set() - - -def parse_editable(editable_req: str) -> tuple[str | None, str, set[str]]: - """Parses an editable requirement into: - - a requirement name with environment markers - - an URL - - extras - Accepted requirements: - - svn+http://blahblah@rev#egg=Foobar[baz]&subdirectory=version_subdir - - local_path[some_extra] - - Foobar[extra] @ svn+http://blahblah@rev#subdirectory=subdir ; markers - """ - try: - package_name, url, extras = _parse_direct_url_editable(editable_req) - except ValueError: - package_name, url, extras = _parse_pip_syntax_editable(editable_req) - - link = Link(url) - - if not link.is_vcs and not link.url.startswith("file:"): - backends = ", ".join(vcs.all_schemes) - raise InstallationError( - f"{editable_req} is not a valid editable requirement. " - f"It should either be a path to a local project or a VCS URL " - f"(beginning with {backends})." - ) - - # The project name can be inferred from local file URIs easily. - if not package_name and not link.url.startswith("file:"): - raise InstallationError( - f"Could not detect requirement name for '{editable_req}', " - "please specify one with your_package_name @ URL" - ) - return package_name, url, extras - - -def check_first_requirement_in_file(filename: str) -> None: - """Check if file is parsable as a requirements file. - - This is heavily based on ``pkg_resources.parse_requirements``, but - simplified to just check the first meaningful line. - - :raises InvalidRequirement: If the first meaningful line cannot be parsed - as an requirement. - """ - with open(filename, encoding="utf-8", errors="ignore") as f: - # Create a steppable iterator, so we can handle \-continuations. - lines = ( - line - for line in (line.strip() for line in f) - if line and not line.startswith("#") # Skip blank lines/comments. - ) - - 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() + next(lines, "") - get_requirement(line) - return - - -def deduce_helpful_msg(req: str) -> str: - """Returns helpful msg in case requirements file does not exist, - or cannot be parsed. - - :params req: Requirements file path - """ - if not os.path.exists(req): - return f" File '{req}' does not exist." - msg = " The path does exist. " - # Try to parse and check if it is a requirements file. - try: - check_first_requirement_in_file(req) - except InvalidRequirement: - logger.debug("Cannot parse '%s' as requirements file", req) - else: - msg += ( - f"The argument you provided " - f"({req}) appears to be a" - f" requirements file. If that is the" - f" case, use the '-r' flag to install" - f" the packages specified within it." - ) - return msg - - -@dataclass(frozen=True) -class RequirementParts: - requirement: Requirement | None - link: Link | None - markers: Marker | None - extras: set[str] - - -def parse_req_from_editable(editable_req: str) -> RequirementParts: - name, url, extras_override = parse_editable(editable_req) - - if name is not None: - try: - req: Requirement | None = get_requirement(name) - except InvalidRequirement as exc: - raise InstallationError(f"Invalid requirement: {name!r}: {exc}") - else: - req = None - - link = Link(url) - - return RequirementParts(req, link, None, extras_override) - - -# ---- The actual constructors follow ---- - - -def install_req_from_editable( - editable_req: str, - comes_from: InstallRequirement | str | None = None, - *, - isolated: bool = False, - hash_options: dict[str, list[str]] | None = None, - constraint: bool = False, - user_supplied: bool = False, - config_settings: dict[str, str | list[str]] | None = None, -) -> InstallRequirement: - if constraint: - raise InstallationError("Editable requirements are not allowed as constraints") - - parts = parse_req_from_editable(editable_req) - return InstallRequirement( - parts.requirement, - comes_from=comes_from, - user_supplied=user_supplied, - editable=True, - link=parts.link, - constraint=constraint, - isolated=isolated, - hash_options=hash_options, - config_settings=config_settings, - extras=parts.extras, - ) - - -def _looks_like_path(name: str) -> bool: - """Checks whether the string "looks like" a path on the filesystem. - - This does not check whether the target actually exists, only judge from the - appearance. - - Returns true if any of the following conditions is true: - * a path separator is found (either os.path.sep or os.path.altsep); - * a dot is found (which represents the current directory). - """ - if os.path.sep in name: - return True - if os.path.altsep is not None and os.path.altsep in name: - return True - if name.startswith("."): - return True - return False - - -def _get_url_from_path(path: str, name: str) -> str | None: - """ - First, it checks whether a provided path is an installable directory. If it - is, returns the path. - - If false, check if the path is an archive file (such as a .whl). - The function checks if the path is a file. If false, if the path has - an @, it will treat it as a PEP 440 URL requirement and return the path. - """ - if _looks_like_path(name) and os.path.isdir(path): - if is_installable_dir(path): - return path_to_url(path) - # TODO: The is_installable_dir test here might not be necessary - # now that it is done in load_pyproject_toml too. - raise InstallationError( - f"Directory {name!r} is not installable. Neither 'setup.py' " - "nor 'pyproject.toml' found." - ) - if not is_archive_file(path): - return None - if os.path.isfile(path): - return path_to_url(path) - urlreq_parts = name.split("@", 1) - if len(urlreq_parts) >= 2 and not _looks_like_path(urlreq_parts[0]): - # If the path contains '@' and the part before it does not look - # like a path, try to treat it as a PEP 440 URL req instead. - return None - logger.warning( - "Requirement %r looks like a filename, but the file does not exist", - name, - ) - return path_to_url(path) - - -def parse_req_from_line(name: str, line_source: str | None) -> RequirementParts: - if is_url(name): - marker_sep = "; " - else: - marker_sep = ";" - if marker_sep in name: - name, markers_as_string = name.split(marker_sep, 1) - markers_as_string = markers_as_string.strip() - if not markers_as_string: - markers = None - else: - try: - markers = Marker(markers_as_string) - except InvalidMarker as exc: - raise InstallationError(f"Invalid requirement: {name.strip()!r}: {exc}") - else: - markers = None - name = name.strip() - req_as_string = None - path = os.path.normpath(os.path.abspath(name)) - link = None - - if is_url(name): - link = Link(name) - extras: set[str] = set() - else: - p, extras = strip_extras(path) - url = _get_url_from_path(p, name) - if url is not None: - link = Link(url) - - # it's a local file, dir, or url - if link: - # 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_as_string = f"{wheel.name}=={wheel.version}" - else: - # set the req to the egg fragment. when it's not there, this - # will become an 'unnamed' requirement - req_as_string = link.egg_fragment - - # a requirement specifier - else: - req_as_string = name - - def with_source(text: str) -> str: - if not line_source: - return text - return f"{text} (from {line_source})" - - def _parse_req_string(req_as_string: str) -> Requirement: - try: - return get_requirement(req_as_string) - except InvalidRequirement as exc: - if os.path.sep in req_as_string: - add_msg = "It looks like a path." - add_msg += deduce_helpful_msg(req_as_string) - elif "=" in req_as_string and not any( - op in req_as_string for op in operators - ): - add_msg = "= is not a valid operator. Did you mean == ?" - else: - add_msg = "" - msg = with_source(f"Invalid requirement: {req_as_string!r}: {exc}") - if add_msg: - msg += f"\nHint: {add_msg}" - raise InstallationError(msg) - - if req_as_string is not None: - req: Requirement | None = _parse_req_string(req_as_string) - else: - req = None - - return RequirementParts(req, link, markers, extras) - - -def install_req_from_line( - name: str, - comes_from: str | InstallRequirement | None = None, - *, - isolated: bool = False, - hash_options: dict[str, list[str]] | None = None, - constraint: bool = False, - line_source: str | None = None, - user_supplied: bool = False, - config_settings: dict[str, str | list[str]] | None = None, -) -> InstallRequirement: - """Creates an InstallRequirement from a name, which might be a - requirement, directory containing 'setup.py', filename, or URL. - - :param line_source: An optional string describing where the line is from, - for logging purposes in case of an error. - """ - parts = parse_req_from_line(name, line_source) - - return InstallRequirement( - parts.requirement, - comes_from, - link=parts.link, - markers=parts.markers, - isolated=isolated, - hash_options=hash_options, - config_settings=config_settings, - constraint=constraint, - extras=parts.extras, - user_supplied=user_supplied, - ) - - -def install_req_from_req_string( - req_string: str, - comes_from: InstallRequirement | None = None, - isolated: bool = False, - user_supplied: bool = False, -) -> InstallRequirement: - try: - req = get_requirement(req_string) - except InvalidRequirement as exc: - raise InstallationError(f"Invalid requirement: {req_string!r}: {exc}") - - domains_not_allowed = [ - PyPI.file_storage_domain, - TestPyPI.file_storage_domain, - ] - if ( - req.url - and comes_from - and comes_from.link - 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" - f"{comes_from.name} depends on {req} " - ) - - return InstallRequirement( - req, - comes_from, - isolated=isolated, - user_supplied=user_supplied, - ) - - -def install_req_from_parsed_requirement( - parsed_req: ParsedRequirement, - isolated: bool = False, - user_supplied: bool = False, - config_settings: dict[str, str | list[str]] | None = None, -) -> InstallRequirement: - if parsed_req.is_editable: - req = install_req_from_editable( - parsed_req.requirement, - comes_from=parsed_req.comes_from, - constraint=parsed_req.constraint, - isolated=isolated, - user_supplied=user_supplied, - config_settings=config_settings, - ) - - else: - req = install_req_from_line( - parsed_req.requirement, - comes_from=parsed_req.comes_from, - isolated=isolated, - hash_options=( - parsed_req.options.get("hashes", {}) if parsed_req.options else {} - ), - constraint=parsed_req.constraint, - line_source=parsed_req.line_source, - user_supplied=user_supplied, - config_settings=config_settings, - ) - return req - - -def install_req_from_link_and_ireq( - link: Link, ireq: InstallRequirement -) -> InstallRequirement: - return InstallRequirement( - req=ireq.req, - comes_from=ireq.comes_from, - editable=ireq.editable, - link=link, - markers=ireq.markers, - isolated=ireq.isolated, - hash_options=ireq.hash_options, - config_settings=ireq.config_settings, - user_supplied=ireq.user_supplied, - ) - - -def install_req_drop_extras(ireq: InstallRequirement) -> InstallRequirement: - """ - Creates a new InstallationRequirement using the given template but without - any extras. Sets the original requirement as the new one's parent - (comes_from). - """ - return InstallRequirement( - req=( - _set_requirement_extras(ireq.req, set()) if ireq.req is not None else None - ), - comes_from=ireq, - editable=ireq.editable, - link=ireq.link, - markers=ireq.markers, - isolated=ireq.isolated, - hash_options=ireq.hash_options, - constraint=ireq.constraint, - extras=[], - config_settings=ireq.config_settings, - user_supplied=ireq.user_supplied, - ) - - -def install_req_extend_extras( - ireq: InstallRequirement, - extras: Collection[str], -) -> InstallRequirement: - """ - Returns a copy of an installation requirement with some additional extras. - Makes a shallow copy of the ireq object. - """ - result = copy.copy(ireq) - result.extras = {*ireq.extras, *extras} - result.req = ( - _set_requirement_extras(ireq.req, result.extras) - if ireq.req is not None - else None - ) - return result - - -def _pylock_hashes_to_hash_options(hashes: Mapping[str, str]) -> dict[str, list[str]]: - return {k: [v] for k, v in hashes.items()} - - -def install_req_from_pylock_package( - package: pylock.Package, - package_dist: ( - pylock.PackageVcs - | pylock.PackageArchive - | pylock.PackageDirectory - | pylock.PackageSdist - | pylock.PackageWheel - ), - pylock_path_or_url: str, - user_supplied: bool, -) -> tuple[InstallRequirement, Link | None]: - """Construct an InstallRequirement from a pylock package and artifact. - - If the artifact is a Sdist or Wheel, also return a locked Link which - is meant to override candidates from indexes or --find-links. - """ - # TODO: validate file size - if isinstance(package_dist, pylock.PackageVcs): - req_url = package_vcs_requirement_url(pylock_path_or_url, package_dist) - return ( - InstallRequirement( - req=Requirement(f"{package.name} @ {req_url}"), - comes_from=pylock_path_or_url, - user_supplied=user_supplied, - ), - None, - ) - elif isinstance(package_dist, pylock.PackageArchive): - req_url = package_archive_requirement_url(pylock_path_or_url, package_dist) - return ( - InstallRequirement( - req=Requirement(f"{package.name} @ {req_url}"), - comes_from=pylock_path_or_url, - hash_options=_pylock_hashes_to_hash_options(package_dist.hashes), - user_supplied=user_supplied, - ), - None, - ) - elif isinstance(package_dist, pylock.PackageDirectory): - req_url = package_directory_requirement_url(pylock_path_or_url, package_dist) - if package_dist.editable: - return ( - install_req_from_editable( - req_url, - comes_from=pylock_path_or_url, - user_supplied=user_supplied, - ), - None, - ) - else: - return ( - install_req_from_line( - req_url, - comes_from=pylock_path_or_url, - user_supplied=user_supplied, - ), - None, - ) - else: - # wheel or sdist - version = package.version - if isinstance(package_dist, pylock.PackageWheel): - if not version: - _, version, _, _ = parse_wheel_filename(package_dist.filename) - requirement_url = package_wheel_requirement_url( - pylock_path_or_url, package_dist - ) - elif isinstance(package_dist, pylock.PackageSdist): - if not version: - _, version = parse_sdist_filename(package_dist.filename) - requirement_url = package_sdist_requirement_url( - pylock_path_or_url, package_dist - ) - ireq = InstallRequirement( - req=Requirement(f"{package.name}=={version}"), - comes_from=pylock_path_or_url, - hash_options=_pylock_hashes_to_hash_options(package_dist.hashes), - user_supplied=user_supplied, - ) - locked_link = Link( - requirement_url, - comes_from=pylock_path_or_url, - upload_time=package_dist.upload_time, - ) - return ireq, locked_link diff --git a/venv/lib/python3.11/site-packages/pip/_internal/req/pep723.py b/venv/lib/python3.11/site-packages/pip/_internal/req/pep723.py deleted file mode 100755 index 2e0c1b9..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/req/pep723.py +++ /dev/null @@ -1,41 +0,0 @@ -import re -from typing import Any - -from pip._internal.utils.compat import tomllib - -REGEX = r"(?m)^# /// (?P[a-zA-Z0-9-]+)$\s(?P(^#(| .*)$\s)+)^# ///$" - - -class PEP723Exception(ValueError): - """Raised to indicate a problem when parsing PEP 723 metadata from a script""" - - def __init__(self, msg: str) -> None: - self.msg = msg - - -def pep723_metadata(scriptfile: str) -> dict[str, Any]: - with open(scriptfile, encoding="utf8") as f: - script = f.read() - - name = "script" - matches = list( - filter(lambda m: m.group("type") == name, re.finditer(REGEX, script)) - ) - - if len(matches) > 1: - raise PEP723Exception(f"Multiple {name!r} blocks found in {scriptfile!r}") - elif len(matches) == 1: - content = "".join( - line[2:] if line.startswith("# ") else line[1:] - for line in matches[0].group("content").splitlines(keepends=True) - ) - try: - metadata = tomllib.loads(content) - except Exception as exc: - raise PEP723Exception(f"Failed to parse TOML in {scriptfile!r}") from exc - else: - raise PEP723Exception( - f"File does not contain {name!r} metadata: {scriptfile!r}" - ) - - return metadata diff --git a/venv/lib/python3.11/site-packages/pip/_internal/req/req_dependency_group.py b/venv/lib/python3.11/site-packages/pip/_internal/req/req_dependency_group.py deleted file mode 100755 index eb9d802..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/req/req_dependency_group.py +++ /dev/null @@ -1,86 +0,0 @@ -from collections.abc import Iterable, Iterator -from typing import Any - -from pip._vendor.packaging.dependency_groups import DependencyGroupResolver -from pip._vendor.packaging.errors import ExceptionGroup - -from pip._internal.exceptions import InstallationError -from pip._internal.utils.compat import tomllib - - -def parse_dependency_groups(groups: list[tuple[str, str]]) -> list[str]: - """ - Parse dependency groups data as provided via the CLI, in a `[path:]group` syntax. - - Raises InstallationErrors if anything goes wrong. - """ - resolvers = _build_resolvers(path for (path, _) in groups) - return list(_resolve_all_groups(resolvers, groups)) - - -def _resolve_all_groups( - resolvers: dict[str, DependencyGroupResolver], groups: list[tuple[str, str]] -) -> Iterator[str]: - """ - Run all resolution, converting any error from `DependencyGroupResolver` into - an InstallationError. - """ - for path, groupname in groups: - resolver = resolvers[path] - try: - yield from (str(req) for req in resolver.resolve(groupname)) - except ExceptionGroup as eg: - # Convert ExceptionGroup to a single InstallationError with all messages - messages = [str(e) for e in eg.exceptions] - raise InstallationError( - f"[dependency-groups] resolution failed for '{groupname}' " - f"from '{path}': {'; '.join(messages)}" - ) from eg - - -def _build_resolvers(paths: Iterable[str]) -> dict[str, Any]: - resolvers = {} - for path in paths: - if path in resolvers: - continue - - pyproject = _load_pyproject(path) - if "dependency-groups" not in pyproject: - raise InstallationError( - f"[dependency-groups] table was missing from '{path}'. " - "Cannot resolve '--group' option." - ) - raw_dependency_groups = pyproject["dependency-groups"] - if not isinstance(raw_dependency_groups, dict): - raise InstallationError( - f"[dependency-groups] table was malformed in {path}. " - "Cannot resolve '--group' option." - ) - - try: - resolvers[path] = DependencyGroupResolver(raw_dependency_groups) - except ExceptionGroup as eg: - # Handle ExceptionGroup from resolver initialization - messages = [str(e) for e in eg.exceptions] - raise InstallationError( - f"[dependency-groups] data was invalid in {path}: {'; '.join(messages)}" - ) from eg - - return resolvers - - -def _load_pyproject(path: str) -> dict[str, Any]: - """ - This helper loads a pyproject.toml as TOML. - - It raises an InstallationError if the operation fails. - """ - try: - with open(path, "rb") as fp: - return tomllib.load(fp) - except FileNotFoundError: - raise InstallationError(f"{path} not found. Cannot resolve '--group' option.") - except tomllib.TOMLDecodeError as e: - raise InstallationError(f"Error parsing {path}: {e}") from e - except OSError as e: - raise InstallationError(f"Error reading {path}: {e}") from e diff --git a/venv/lib/python3.11/site-packages/pip/_internal/req/req_file.py b/venv/lib/python3.11/site-packages/pip/_internal/req/req_file.py deleted file mode 100755 index 400bb86..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/req/req_file.py +++ /dev/null @@ -1,622 +0,0 @@ -""" -Requirements file parsing -""" - -from __future__ import annotations - -import codecs -import logging -import optparse -import os -import re -import shlex -import sys -import urllib.parse -from collections.abc import Callable, Generator, Iterable -from dataclasses import dataclass -from optparse import Values -from typing import ( - TYPE_CHECKING, - Any, - NoReturn, -) - -from pip._internal.cli import cmdoptions -from pip._internal.exceptions import InstallationError, RequirementsFileParseError -from pip._internal.models.release_control import ReleaseControl -from pip._internal.models.search_scope import SearchScope -from pip._internal.utils.compat import get_locale_encoding - -if TYPE_CHECKING: - from pip._internal.index.package_finder import PackageFinder - from pip._internal.network.session import PipSession - -__all__ = ["parse_requirements"] - -ReqFileLines = Iterable[tuple[int, str]] - -LineParser = Callable[[str], tuple[str, Values]] - -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: list[Callable[..., optparse.Option]] = [ - cmdoptions.index_url, - cmdoptions.extra_index_url, - cmdoptions.no_index, - cmdoptions.constraints, - cmdoptions.requirements, - cmdoptions.editable, - cmdoptions.find_links, - cmdoptions.no_binary, - cmdoptions.only_binary, - cmdoptions.prefer_binary, - cmdoptions.require_hashes, - cmdoptions.no_require_hashes, - cmdoptions.pre, - cmdoptions.all_releases, - cmdoptions.only_final, - cmdoptions.trusted_host, - cmdoptions.use_new_feature, -] - -# options to be passed to requirements -SUPPORTED_OPTIONS_REQ: list[Callable[..., optparse.Option]] = [ - cmdoptions.hash, - cmdoptions.config_settings, -] - -SUPPORTED_OPTIONS_EDITABLE_REQ: list[Callable[..., optparse.Option]] = [ - cmdoptions.config_settings, -] - - -# the 'dest' string values -SUPPORTED_OPTIONS_REQ_DEST = [str(o().dest) for o in SUPPORTED_OPTIONS_REQ] -SUPPORTED_OPTIONS_EDITABLE_REQ_DEST = [ - str(o().dest) for o in SUPPORTED_OPTIONS_EDITABLE_REQ -] - -# order of BOMS is important: codecs.BOM_UTF16_LE is a prefix of codecs.BOM_UTF32_LE -# so data.startswith(BOM_UTF16_LE) would be true for UTF32_LE data -BOMS: list[tuple[bytes, str]] = [ - (codecs.BOM_UTF8, "utf-8"), - (codecs.BOM_UTF32, "utf-32"), - (codecs.BOM_UTF32_BE, "utf-32-be"), - (codecs.BOM_UTF32_LE, "utf-32-le"), - (codecs.BOM_UTF16, "utf-16"), - (codecs.BOM_UTF16_BE, "utf-16-be"), - (codecs.BOM_UTF16_LE, "utf-16-le"), -] - -PEP263_ENCODING_RE = re.compile(rb"coding[:=]\s*([-\w.]+)") -DEFAULT_ENCODING = "utf-8" - -logger = logging.getLogger(__name__) - - -@dataclass(frozen=True, slots=True) -class ParsedRequirement: - requirement: str - is_editable: bool - comes_from: str - constraint: bool - options: dict[str, Any] | None - line_source: str | None - - -@dataclass(frozen=True, slots=True) -class ParsedLine: - filename: str - lineno: int - args: str - opts: Values - constraint: bool - - @property - def is_editable(self) -> bool: - return bool(self.opts.editables) - - @property - def requirement(self) -> str | None: - if self.args: - return self.args - elif self.is_editable: - # We don't support multiple -e on one line - return self.opts.editables[0] - return None - - -def parse_requirements( - filename: str, - session: PipSession, - finder: PackageFinder | None = None, - options: optparse.Values | None = None, - constraint: bool = False, -) -> Generator[ParsedRequirement, None, None]: - """Parse a requirements file and yield ParsedRequirement instances. - - :param filename: Path or url of requirements file. - :param session: PipSession instance. - :param finder: Instance of pip.index.PackageFinder. - :param options: cli options. - :param constraint: If true, parsing a constraint file rather than - requirements file. - """ - line_parser = get_line_parser(finder) - parser = RequirementsFileParser(session, line_parser) - - for parsed_line in parser.parse(filename, constraint): - parsed_req = handle_line( - parsed_line, options=options, finder=finder, session=session - ) - if parsed_req is not None: - yield parsed_req - - -def preprocess(content: str) -> ReqFileLines: - """Split, filter, and join lines, and return a line iterator - - :param content: the content of the requirements file - """ - lines_enum: ReqFileLines = enumerate(content.splitlines(), start=1) - lines_enum = join_lines(lines_enum) - lines_enum = ignore_comments(lines_enum) - lines_enum = expand_env_variables(lines_enum) - return lines_enum - - -def handle_requirement_line( - line: ParsedLine, - options: optparse.Values | None = None, -) -> ParsedRequirement: - # preserve for the nested code path - line_comes_from = "{} {} (line {})".format( - "-c" if line.constraint else "-r", - line.filename, - line.lineno, - ) - - assert line.requirement is not None - - # get the options that apply to requirements - if line.is_editable: - supported_dest = SUPPORTED_OPTIONS_EDITABLE_REQ_DEST - else: - supported_dest = SUPPORTED_OPTIONS_REQ_DEST - req_options = {} - for dest in supported_dest: - if dest in line.opts.__dict__ and line.opts.__dict__[dest]: - req_options[dest] = line.opts.__dict__[dest] - - line_source = f"line {line.lineno} of {line.filename}" - return ParsedRequirement( - requirement=line.requirement, - is_editable=line.is_editable, - comes_from=line_comes_from, - constraint=line.constraint, - options=req_options, - line_source=line_source, - ) - - -def handle_option_line( - opts: Values, - filename: str, - lineno: int, - finder: PackageFinder | None = None, - options: optparse.Values | None = None, - session: PipSession | None = None, -) -> None: - if opts.hashes: - logger.warning( - "%s line %s has --hash but no requirement, and will be ignored.", - filename, - lineno, - ) - - if options: - # percolate options upward - if opts.require_hashes: - options.require_hashes = opts.require_hashes - if opts.no_require_hashes: - options.no_require_hashes = opts.no_require_hashes - if opts.features_enabled: - options.features_enabled.extend( - f for f in opts.features_enabled if f not in options.features_enabled - ) - - # set finder options - if finder: - find_links = finder.find_links - index_urls = finder.index_urls - no_index = finder.search_scope.no_index - if opts.no_index is True: - no_index = True - index_urls = [] - if opts.index_url and not no_index: - index_urls = [opts.index_url] - if opts.extra_index_urls and not no_index: - 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 - find_links.append(value) - - if session: - # We need to update the auth urls in session - session.update_index_urls(index_urls) - - search_scope = SearchScope( - find_links=find_links, - index_urls=index_urls, - no_index=no_index, - ) - finder.search_scope = search_scope - - # Transform --pre into --all-releases :all: - if opts.pre: - if not opts.release_control: - opts.release_control = ReleaseControl() - opts.release_control.all_releases.add(":all:") - - if opts.release_control: - if not finder.release_control: - # First time seeing release_control, set it on finder - finder.set_release_control(opts.release_control) - - if opts.prefer_binary: - finder.set_prefer_binary() - - if session: - for host in opts.trusted_hosts or []: - source = f"line {lineno} of {filename}" - session.add_trusted_host(host, source=source) - - -def handle_line( - line: ParsedLine, - options: optparse.Values | None = None, - finder: PackageFinder | None = None, - session: PipSession | None = None, -) -> ParsedRequirement | None: - """Handle a single parsed requirements line; This can result in - creating/yielding requirements, or updating the finder. - - :param line: The parsed line to be processed. - :param options: CLI options. - :param finder: The finder - updated by non-requirement lines. - :param session: The session - updated by non-requirement lines. - - Returns a ParsedRequirement object if the line is a requirement line, - otherwise returns None. - - For lines that contain requirements, the only options that have an effect - are from SUPPORTED_OPTIONS_REQ, and they are scoped to the - requirement. Other options from SUPPORTED_OPTIONS may be present, but are - ignored. - - For lines that do not contain requirements, the only options that have an - effect are from SUPPORTED_OPTIONS. Options from SUPPORTED_OPTIONS_REQ may - be present, but are ignored. These lines may contain multiple options - (although our docs imply only one is supported), and all our parsed and - affect the finder. - """ - - if line.requirement is not None: - parsed_req = handle_requirement_line(line, options) - return parsed_req - else: - handle_option_line( - line.opts, - line.filename, - line.lineno, - finder, - options, - session, - ) - return None - - -class RequirementsFileParser: - def __init__( - self, - session: PipSession, - line_parser: LineParser, - ) -> None: - self._session = session - self._line_parser = line_parser - - def parse( - self, filename: str, constraint: bool - ) -> Generator[ParsedLine, None, None]: - """Parse a given file, yielding parsed lines.""" - yield from self._parse_and_recurse( - filename, constraint, [{os.path.abspath(filename): None}] - ) - - def _parse_and_recurse( - self, - filename: str, - constraint: bool, - parsed_files_stack: list[dict[str, str | None]], - ) -> Generator[ParsedLine, None, None]: - for line in self._parse_file(filename, constraint): - if line.requirement is None and ( - line.opts.requirements or line.opts.constraints - ): - # parse a nested requirements file - if line.opts.requirements: - req_path = line.opts.requirements[0] - nested_constraint = False - else: - req_path = line.opts.constraints[0] - nested_constraint = True - - # original file is over http - if SCHEME_RE.search(filename): - # do a url join so relative paths work - req_path = urllib.parse.urljoin(filename, req_path) - # original file and nested file are paths - elif not SCHEME_RE.search(req_path): - # do a join so relative paths work - # and then abspath so that we can identify recursive references - req_path = os.path.abspath( - os.path.join( - os.path.dirname(filename), - req_path, - ) - ) - parsed_files = parsed_files_stack[0] - if req_path in parsed_files: - initial_file = parsed_files[req_path] - tail = ( - f" and again in {initial_file}" - if initial_file is not None - else "" - ) - raise RequirementsFileParseError( - f"{req_path} recursively references itself in {filename}{tail}" - ) - # Keeping a track where was each file first included in - new_parsed_files = parsed_files.copy() - new_parsed_files[req_path] = filename - yield from self._parse_and_recurse( - req_path, nested_constraint, [new_parsed_files, *parsed_files_stack] - ) - else: - yield line - - def _parse_file( - self, filename: str, constraint: bool - ) -> Generator[ParsedLine, None, None]: - _, content = get_file_content(filename, self._session, constraint=constraint) - - lines_enum = preprocess(content) - - for line_number, line in lines_enum: - try: - args_str, opts = self._line_parser(line) - except OptionParsingError as e: - # add offending line - msg = f"Invalid requirement: {line}\n{e.msg}" - raise RequirementsFileParseError(msg) - - yield ParsedLine( - filename, - line_number, - args_str, - opts, - constraint, - ) - - -def get_line_parser(finder: PackageFinder | None) -> LineParser: - def parse_line(line: str) -> tuple[str, Values]: - # Build new parser for each line since it accumulates appendable - # options. - parser = build_parser() - defaults = parser.get_default_values() - defaults.index_url = None - if finder: - defaults.format_control = finder.format_control - defaults.release_control = finder.release_control - - args_str, options_str = break_args_options(line) - - try: - options = shlex.split(options_str) - except ValueError as e: - raise OptionParsingError(f"Could not split options: {options_str}") from e - - opts, _ = parser.parse_args(options, defaults) - - return args_str, opts - - return parse_line - - -def break_args_options(line: str) -> tuple[str, str]: - """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(("-", "--")): - break - else: - args.append(token) - options.pop(0) - return " ".join(args), " ".join(options) - - -class OptionParsingError(Exception): - def __init__(self, msg: str) -> None: - self.msg = msg - - -def build_parser() -> optparse.OptionParser: - """ - 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: Any, msg: str) -> NoReturn: - raise OptionParsingError(msg) - - # NOTE: mypy disallows assigning to a method - # https://github.com/python/mypy/issues/2427 - parser.exit = parser_exit # type: ignore - - return parser - - -def join_lines(lines_enum: ReqFileLines) -> ReqFileLines: - """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: list[str] = [] - 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) - assert primary_line_number is not None - 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: - assert primary_line_number is not None - yield primary_line_number, "".join(new_line) - - -def ignore_comments(lines_enum: ReqFileLines) -> ReqFileLines: - """ - 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 expand_env_variables(lines_enum: ReqFileLines) -> ReqFileLines: - """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 discussion 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 - - -def get_file_content( - url: str, session: PipSession, *, constraint: bool = False -) -> tuple[str, str]: - """Gets the content of a file; it may be a filename, file: URL, or - http: URL. Returns (location, content). Content is unicode. - Respects # -*- coding: declarations on the retrieved files. - - :param url: File path or url. - :param session: PipSession instance. - """ - scheme = urllib.parse.urlsplit(url).scheme - # Pip has special support for file:// URLs (LocalFSAdapter). - if scheme in ["http", "https", "file"]: - # Delay importing heavy network modules until absolutely necessary. - from pip._internal.network.utils import raise_for_status - - resp = session.get(url) - raise_for_status(resp) - return resp.url, resp.text - - # Assume this is a bare path. - try: - with open(url, "rb") as f: - raw_content = f.read() - except OSError as exc: - kind = "constraint" if constraint else "requirements" - raise InstallationError(f"Could not open {kind} file: {exc}") - - content = _decode_req_file(raw_content, url) - - return url, content - - -def _decode_req_file(data: bytes, url: str) -> str: - for bom, encoding in BOMS: - if data.startswith(bom): - return data[len(bom) :].decode(encoding) - - for line in data.split(b"\n")[:2]: - if line[0:1] == b"#": - result = PEP263_ENCODING_RE.search(line) - if result is not None: - encoding = result.groups()[0].decode("ascii") - return data.decode(encoding) - - try: - return data.decode(DEFAULT_ENCODING) - except UnicodeDecodeError: - locale_encoding = get_locale_encoding() or sys.getdefaultencoding() - logging.warning( - "unable to decode data from %s with default encoding %s, " - "falling back to encoding from locale: %s. " - "If this is intentional you should specify the encoding with a " - "PEP-263 style comment, e.g. '# -*- coding: %s -*-'", - url, - DEFAULT_ENCODING, - locale_encoding, - locale_encoding, - ) - return data.decode(locale_encoding) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/req/req_install.py b/venv/lib/python3.11/site-packages/pip/_internal/req/req_install.py deleted file mode 100755 index f20707f..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/req/req_install.py +++ /dev/null @@ -1,842 +0,0 @@ -from __future__ import annotations - -import functools -import logging -import os -import shutil -import sys -import uuid -import zipfile -from collections.abc import Collection, Iterable -from optparse import Values -from pathlib import Path -from typing import Any - -from pip._vendor.packaging.markers import Marker -from pip._vendor.packaging.requirements import Requirement -from pip._vendor.packaging.specifiers import SpecifierSet -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.pyproject_hooks import BuildBackendHookCaller - -from pip._internal.build_env import BuildEnvironment, NoOpBuildEnvironment -from pip._internal.exceptions import InstallationError, PreviousBuildDirError -from pip._internal.locations import get_scheme -from pip._internal.metadata import ( - BaseDistribution, - get_default_environment, - get_directory_distribution, - get_wheel_distribution, -) -from pip._internal.metadata.base import FilesystemWheel -from pip._internal.models.direct_url import DirectUrl -from pip._internal.models.link import Link -from pip._internal.operations.build.metadata import generate_metadata -from pip._internal.operations.build.metadata_editable import generate_editable_metadata -from pip._internal.pyproject import load_pyproject_toml, make_pyproject_path -from pip._internal.req.req_uninstall import UninstallPathSet -from pip._internal.utils.deprecation import deprecated -from pip._internal.utils.hashes import Hashes -from pip._internal.utils.misc import ( - ConfiguredBuildBackendHookCaller, - ask_path_exists, - backup_dir, - display_path, - hide_url, - is_installable_dir, - redact_auth_from_requirement, - redact_auth_from_url, -) -from pip._internal.utils.packaging import get_requirement -from pip._internal.utils.subprocess import runner_with_spinner_message -from pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds -from pip._internal.utils.unpacking import unpack_file -from pip._internal.utils.virtualenv import running_under_virtualenv -from pip._internal.vcs import vcs - -logger = logging.getLogger(__name__) - - -class InstallRequirement: - """ - Represents something that may be installed later on, may have information - about where to fetch the relevant requirement and also contains logic for - installing the said requirement. - """ - - def __init__( - self, - req: Requirement | None, - comes_from: str | InstallRequirement | None, - editable: bool = False, - link: Link | None = None, - markers: Marker | None = None, - isolated: bool = False, - *, - hash_options: dict[str, list[str]] | None = None, - config_settings: dict[str, str | list[str]] | None = None, - constraint: bool = False, - extras: Collection[str] = (), - user_supplied: bool = False, - ) -> None: - assert req is None or isinstance(req, Requirement), req - self.req = req - self.comes_from = comes_from - self.constraint = constraint - self.editable = editable - - # source_dir is the local directory where the linked requirement is - # located, or unpacked. In case unpacking is needed, creating and - # populating source_dir is done by the RequirementPreparer. Note this - # is not necessarily the directory where pyproject.toml or setup.py is - # located - that one is obtained via unpacked_source_directory. - self.source_dir: str | None = None - if self.editable: - assert link - if link.is_file: - self.source_dir = os.path.normpath(os.path.abspath(link.file_path)) - - # original_link is the direct URL that was provided by the user for the - # requirement, either directly or via a constraints file. - if link is None and req and req.url: - # PEP 508 URL requirement - link = Link(req.url) - self.link = self.original_link = link - - # When this InstallRequirement is a wheel obtained from the cache of locally - # built wheels, this is the source link corresponding to the cache entry, which - # was used to download and build the cached wheel. - self.cached_wheel_source_link: Link | None = None - - # Information about the location of the artifact that was downloaded . This - # property is guaranteed to be set in resolver results. - self.download_info: DirectUrl | None = None - - # Path to any downloaded or already-existing package. - self.local_file_path: str | None = None - if self.link and self.link.is_file: - self.local_file_path = self.link.file_path - - if extras: - self.extras = extras - elif req: - self.extras = req.extras - else: - self.extras = set() - if markers is None and req: - markers = req.marker - self.markers = markers - - # This holds the Distribution object if this requirement is already installed. - self.satisfied_by: BaseDistribution | None = None - # Whether the installation process should try to uninstall an existing - # distribution before installing this requirement. - self.should_reinstall = False - # Temporary build location - self._temp_build_dir: TempDirectory | None = None - # Set to True after successful installation - self.install_succeeded: bool | None = None - # Supplied options - self.hash_options = hash_options if hash_options else {} - self.config_settings = config_settings - # Set to True after successful preparation of this requirement - self.prepared = False - # User supplied requirement are explicitly requested for installation - # by the user via CLI arguments or requirements files, as opposed to, - # e.g. dependencies, extras or constraints. - self.user_supplied = user_supplied - - self.isolated = isolated - self.build_env: BuildEnvironment = NoOpBuildEnvironment() - - # For PEP 517, the directory where we request the project metadata - # gets stored. We need this to pass to build_wheel, so the backend - # can ensure that the wheel matches the metadata (see the PEP for - # details). - self.metadata_directory: str | None = None - - # The cached metadata distribution that this requirement represents. - # See get_dist / set_dist. - self._distribution: BaseDistribution | None = None - - # The static build requirements (from pyproject.toml) - self.pyproject_requires: list[str] | None = None - - # Build requirements that we will check are available - self.requirements_to_check: list[str] = [] - - # The PEP 517 backend we should use to build the project - self._pep517_backend_spec: str - self._pep517_backend_path: str | None - self.pep517_backend: BuildBackendHookCaller | None = None - - # This requirement needs more preparation before it can be built - self.needs_more_preparation = False - - # This requirement needs to be unpacked before it can be installed. - self._archive_source: Path | None = None - - def __str__(self) -> str: - if self.req: - s = redact_auth_from_requirement(self.req) - if self.link: - s += f" from {redact_auth_from_url(self.link.url)}" - elif self.link: - s = redact_auth_from_url(self.link.url) - else: - s = "" - if self.satisfied_by is not None: - if self.satisfied_by.location is not None: - location = display_path(self.satisfied_by.location) - else: - location = "" - s += f" in {location}" - if self.comes_from: - if isinstance(self.comes_from, str): - comes_from: str | None = self.comes_from - else: - comes_from = self.comes_from.from_path() - if comes_from: - s += f" (from {comes_from})" - return s - - def __repr__(self) -> str: - return ( - f"<{self.__class__.__name__} object: " - f"{str(self)} editable={self.editable!r}>" - ) - - def format_debug(self) -> str: - """An un-tested helper for getting state, for debugging.""" - attributes = vars(self) - names = sorted(attributes) - - state = (f"{attr}={attributes[attr]!r}" for attr in sorted(names)) - return "<{name} object: {{{state}}}>".format( - name=self.__class__.__name__, - state=", ".join(state), - ) - - # Things that are valid for all kinds of requirements? - @property - def name(self) -> str | None: - if self.req is None: - return None - return self.req.name - - @functools.cached_property - def supports_pyproject_editable(self) -> bool: - assert self.pep517_backend - with self.build_env: - runner = runner_with_spinner_message( - "Checking if build backend supports build_editable" - ) - with self.pep517_backend.subprocess_runner(runner): - return "build_editable" in self.pep517_backend._supported_features() - - @property - def specifier(self) -> SpecifierSet: - assert self.req is not None - return self.req.specifier - - @property - def is_direct(self) -> bool: - """Whether this requirement was specified as a direct URL.""" - return self.original_link is not None - - @property - def is_pinned(self) -> bool: - """Return whether I am pinned to an exact version. - - For example, some-package==1.2 is pinned; some-package>1.2 is not. - """ - assert self.req is not None - specifiers = self.req.specifier - return len(specifiers) == 1 and next(iter(specifiers)).operator in {"==", "==="} - - def match_markers(self, extras_requested: Iterable[str] | None = None) -> bool: - 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) -> bool: - """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.hash_options) - - def hashes(self, trust_internet: bool = True) -> Hashes: - """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.hash_options.copy() - if trust_internet: - link = self.link - elif self.is_direct and self.user_supplied: - link = self.original_link - else: - link = None - if link and link.hash: - assert link.hash_name is not None - good_hashes.setdefault(link.hash_name, []).append(link.hash) - return Hashes(good_hashes) - - def from_path(self) -> str | None: - """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: - comes_from: str | None - if isinstance(self.comes_from, str): - comes_from = self.comes_from - else: - comes_from = self.comes_from.from_path() - if comes_from: - s += "->" + comes_from - return s - - def ensure_build_location( - self, build_dir: str, autodelete: bool, parallel_builds: bool - ) -> str: - assert build_dir is not None - if self._temp_build_dir is not None: - assert self._temp_build_dir.path - return self._temp_build_dir.path - if self.req is None: - # 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 = TempDirectory( - kind=tempdir_kinds.REQ_BUILD, globally_managed=True - ) - - return self._temp_build_dir.path - - # This is the only remaining place where we manually determine the path - # for the temporary directory. It is only needed for editables where - # it is the value of the --src option. - - # When parallel builds are enabled, add a UUID to the build directory - # name so multiple builds do not interfere with each other. - dir_name: str = canonicalize_name(self.req.name) - if parallel_builds: - dir_name = f"{dir_name}_{uuid.uuid4().hex}" - - # FIXME: Is there a better place to create the build_dir? (hg and bzr - # need this) - if not os.path.exists(build_dir): - logger.debug("Creating directory %s", build_dir) - os.makedirs(build_dir) - actual_build_dir = os.path.join(build_dir, dir_name) - # `None` indicates that we respect the globally-configured deletion - # settings, which is what we actually want when auto-deleting. - delete_arg = None if autodelete else False - return TempDirectory( - path=actual_build_dir, - delete=delete_arg, - kind=tempdir_kinds.REQ_BUILD, - globally_managed=True, - ).path - - def _set_requirement(self) -> None: - """Set requirement after generating metadata.""" - assert self.req is None - assert self.metadata is not None - assert self.source_dir is not None - - # Construct a Requirement object from the generated metadata - if isinstance(parse_version(self.metadata["Version"]), Version): - op = "==" - else: - op = "===" - - self.req = get_requirement( - "".join( - [ - self.metadata["Name"], - op, - self.metadata["Version"], - ] - ) - ) - - def warn_on_mismatching_name(self) -> None: - assert self.req is not None - metadata_name = canonicalize_name(self.metadata["Name"]) - if canonicalize_name(self.req.name) == metadata_name: - # Everything is fine. - return - - # If we're here, there's a mismatch. Log a warning about it. - logger.warning( - "Generating metadata for package %s " - "produced metadata for project name %s. Fix your " - "#egg=%s fragments.", - self.name, - metadata_name, - self.name, - ) - self.req = get_requirement(metadata_name) - - def check_if_exists(self, use_user_site: bool) -> None: - """Find an installed distribution that satisfies or conflicts - with this requirement, and set self.satisfied_by or - self.should_reinstall appropriately. - """ - if self.req is None: - return - existing_dist = get_default_environment().get_distribution(self.req.name) - if not existing_dist: - return - - version_compatible = self.req.specifier.contains( - existing_dist.version, - prereleases=True, - ) - if not version_compatible: - self.satisfied_by = None - if use_user_site: - if existing_dist.in_usersite: - self.should_reinstall = True - elif running_under_virtualenv() and existing_dist.in_site_packages: - raise InstallationError( - f"Will not install to the user site because it will " - f"lack sys.path precedence to {existing_dist.raw_name} " - f"in {existing_dist.location}" - ) - else: - self.should_reinstall = True - else: - if self.editable: - self.should_reinstall = True - # when installing editables, nothing pre-existing should ever - # satisfy - self.satisfied_by = None - else: - self.satisfied_by = existing_dist - - # Things valid for wheels - @property - def is_wheel(self) -> bool: - if not self.link: - return False - return self.link.is_wheel - - @property - def is_wheel_from_cache(self) -> bool: - # When True, it means that this InstallRequirement is a local wheel file in the - # cache of locally built wheels. - return self.cached_wheel_source_link is not None - - # Things valid for sdists - @property - def unpacked_source_directory(self) -> str: - assert self.source_dir, f"No source dir for {self}" - return os.path.join( - self.source_dir, self.link and self.link.subdirectory_fragment or "" - ) - - @property - def setup_py_path(self) -> str: - assert self.source_dir, f"No source dir for {self}" - setup_py = os.path.join(self.unpacked_source_directory, "setup.py") - - return setup_py - - @property - def pyproject_toml_path(self) -> str: - assert self.source_dir, f"No source dir for {self}" - return make_pyproject_path(self.unpacked_source_directory) - - def load_pyproject_toml(self) -> None: - """Load the pyproject.toml file. - - After calling this routine, all of the attributes related to PEP 517 - processing for this requirement have been set. - """ - pyproject_toml_data = load_pyproject_toml( - self.pyproject_toml_path, self.setup_py_path, str(self) - ) - assert pyproject_toml_data - requires, backend, check, backend_path = pyproject_toml_data - self.requirements_to_check = check - self.pyproject_requires = requires - self._pep517_backend_spec = backend - self._pep517_backend_path = backend_path - - def configure_backend(self, python_executable: str) -> None: - """Set up the build backend hook caller. - - This is done separately after pyproject.toml loading as the backend - need to be called with the build environment's Python executable, - which can vary.""" - self.pep517_backend = ConfiguredBuildBackendHookCaller( - self, - self.unpacked_source_directory, - self._pep517_backend_spec, - backend_path=self._pep517_backend_path, - python_executable=python_executable, - ) - - def editable_sanity_check(self) -> None: - """Check that an editable requirement if valid for use with PEP 517/518. - - This verifies that an editable has a build backend that supports PEP 660. - """ - if self.editable and not self.supports_pyproject_editable: - raise InstallationError( - f"Project {self} uses a build backend " - f"that is missing the 'build_editable' hook, so " - f"it cannot be installed in editable mode. " - f"Consider using a build backend that supports PEP 660." - ) - - def prepare_metadata(self, allow_editables: bool) -> None: - """Ensure that project metadata is available. - - Under PEP 517 and PEP 660, call the backend hook to prepare the metadata. - Under legacy processing, call setup.py egg-info. - """ - assert self.source_dir, f"No source dir for {self}" - details = self.name or f"from {self.link}" - - assert self.pep517_backend is not None - if self.editable and allow_editables and self.supports_pyproject_editable: - self.metadata_directory = generate_editable_metadata( - build_env=self.build_env, - backend=self.pep517_backend, - details=details, - ) - else: - self.metadata_directory = generate_metadata( - build_env=self.build_env, - backend=self.pep517_backend, - details=details, - ) - - # Act on the newly generated metadata, based on the name and version. - if not self.name: - self._set_requirement() - else: - self.warn_on_mismatching_name() - - self.assert_source_matches_version() - - @property - def metadata(self) -> Any: - if not hasattr(self, "_metadata"): - self._metadata = self.get_dist().metadata - - return self._metadata - - def set_dist(self, distribution: BaseDistribution) -> None: - self._distribution = distribution - - def get_dist(self) -> BaseDistribution: - if self._distribution is not None: - return self._distribution - elif self.metadata_directory: - return get_directory_distribution(self.metadata_directory) - elif self.local_file_path and self.is_wheel: - assert self.req is not None - return get_wheel_distribution( - FilesystemWheel(self.local_file_path), - canonicalize_name(self.req.name), - ) - raise AssertionError( - f"InstallRequirement {self} has no metadata directory and no wheel: " - f"can't make a distribution." - ) - - def assert_source_matches_version(self) -> None: - assert self.source_dir, f"No source dir for {self}" - version = self.metadata["version"] - if self.req and 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: str, - autodelete: bool = False, - parallel_builds: bool = False, - ) -> None: - """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.ensure_build_location( - parent_dir, - autodelete=autodelete, - parallel_builds=parallel_builds, - ) - - def needs_unpacked_archive(self, archive_source: Path) -> None: - assert self._archive_source is None - self._archive_source = archive_source - - def ensure_pristine_source_checkout(self) -> None: - """Ensure the source directory has not yet been built in.""" - assert self.source_dir is not None - if self._archive_source is not None: - unpack_file(str(self._archive_source), self.source_dir) - elif is_installable_dir(self.source_dir): - # If a checkout exists, it's unwise to keep going. - # version inconsistencies are logged later, but do not fail - # the installation. - raise PreviousBuildDirError( - f"pip can't proceed with requirements '{self}' due to a " - f"pre-existing build directory ({self.source_dir}). 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." - ) - - # For editable installations - def update_editable(self) -> None: - 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 - vcs_backend = vcs.get_backend_for_scheme(self.link.scheme) - # Editable requirements are validated in Requirement constructors. - # So here, if it's neither a path nor a valid VCS URL, it's a bug. - assert vcs_backend, f"Unsupported VCS URL {self.link.url}" - hidden_url = hide_url(self.link.url) - vcs_backend.obtain(self.source_dir, url=hidden_url, verbosity=0) - - # Top-level Actions - def uninstall( - self, auto_confirm: bool = False, verbose: bool = False - ) -> UninstallPathSet | None: - """ - 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. - - """ - assert self.req - dist = get_default_environment().get_distribution(self.req.name) - if not dist: - logger.warning("Skipping %s as it is not installed.", self.name) - return None - logger.info("Found existing installation: %s", dist) - - uninstalled_pathset = UninstallPathSet.from_dist(dist) - uninstalled_pathset.remove(auto_confirm, verbose) - return uninstalled_pathset - - def _get_archive_name(self, path: str, parentdir: str, rootdir: str) -> str: - def _clean_zip_name(name: str, prefix: str) -> str: - assert name.startswith( - prefix + os.path.sep - ), f"name {name!r} doesn't start with prefix {prefix!r}" - name = name[len(prefix) + 1 :] - name = name.replace(os.path.sep, "/") - return name - - assert self.req is not None - path = os.path.join(parentdir, path) - name = _clean_zip_name(path, rootdir) - return self.req.name + "/" + name - - def archive(self, build_dir: str | None) -> None: - """Saves archive to provided build_dir. - - Used for saving downloaded VCS requirements as part of `pip download`. - """ - assert self.source_dir - if build_dir is None: - return - - create_archive = True - archive_name = "{}-{}.zip".format(self.name, self.metadata["version"]) - archive_path = os.path.join(build_dir, archive_name) - - if os.path.exists(archive_path): - response = ask_path_exists( - f"The file {display_path(archive_path)} exists. (i)gnore, (w)ipe, " - "(b)ackup, (a)bort ", - ("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 not create_archive: - return - - zip_output = zipfile.ZipFile( - archive_path, - "w", - zipfile.ZIP_DEFLATED, - allowZip64=True, - ) - with zip_output: - dir = os.path.normcase(os.path.abspath(self.unpacked_source_directory)) - for dirpath, dirnames, filenames in os.walk(dir): - for dirname in dirnames: - dir_arcname = self._get_archive_name( - dirname, - parentdir=dirpath, - rootdir=dir, - ) - zipdir = zipfile.ZipInfo(dir_arcname + "/") - zipdir.external_attr = 0x1ED << 16 # 0o755 - zip_output.writestr(zipdir, "") - for filename in filenames: - file_arcname = self._get_archive_name( - filename, - parentdir=dirpath, - rootdir=dir, - ) - filename = os.path.join(dirpath, filename) - zip_output.write(filename, file_arcname) - - logger.info("Saved %s", display_path(archive_path)) - - def install( - self, - root: str | None = None, - home: str | None = None, - prefix: str | None = None, - warn_script_location: bool = True, - use_user_site: bool = False, - pycompile: bool = True, - script_executable: str | None = None, - ) -> None: - # Lazy import to avoid transitively importing `_vendor.distlib.compat` - # which in turn imports `urllib.request` which is slow. - # During an actual installation, `urllib.request` will end up imported anyway, - # but `req.req_install` (this module) is also imported from commands that - # don't actually install anything (e.g. `pip freeze` or `pip show`). - from pip._internal.operations.install.wheel import install_wheel - - assert self.req is not None - scheme = get_scheme( - self.req.name, - user=use_user_site, - home=home, - root=root, - isolated=self.isolated, - prefix=prefix, - ) - - assert self.is_wheel - assert self.local_file_path - - install_wheel( - self.req.name, - self.local_file_path, - scheme=scheme, - req_description=str(self.req), - pycompile=pycompile, - warn_script_location=warn_script_location, - direct_url=self.download_info if self.is_direct else None, - requested=self.user_supplied, - script_executable=script_executable, - ) - self.install_succeeded = True - - -def check_invalid_constraint_type(req: InstallRequirement) -> str: - # Check for unsupported forms - problem = "" - if not req.name: - problem = "Unnamed requirements are not allowed as constraints" - elif req.editable: - problem = "Editable requirements are not allowed as constraints" - elif req.extras: - problem = "Constraints cannot have extras" - - if problem: - deprecated( - reason=( - "Constraints are only allowed to take the form of a package " - "name and a version specifier. Other forms were originally " - "permitted as an accident of the implementation, but were " - "undocumented. The new implementation of the resolver no " - "longer supports these forms." - ), - replacement="replacing the constraint with a requirement", - # No plan yet for when the new resolver becomes default - gone_in=None, - issue=8210, - ) - - return problem - - -def _has_option(options: Values, reqs: list[InstallRequirement], option: str) -> bool: - if getattr(options, option, None): - return True - for req in reqs: - if getattr(req, option, None): - return True - return False diff --git a/venv/lib/python3.11/site-packages/pip/_internal/req/req_set.py b/venv/lib/python3.11/site-packages/pip/_internal/req/req_set.py deleted file mode 100755 index 3451b24..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/req/req_set.py +++ /dev/null @@ -1,81 +0,0 @@ -import logging -from collections import OrderedDict - -from pip._vendor.packaging.utils import canonicalize_name - -from pip._internal.req.req_install import InstallRequirement - -logger = logging.getLogger(__name__) - - -class RequirementSet: - def __init__(self, check_supported_wheels: bool = True) -> None: - """Create a RequirementSet.""" - - self.requirements: dict[str, InstallRequirement] = OrderedDict() - self.check_supported_wheels = check_supported_wheels - - self.unnamed_requirements: list[InstallRequirement] = [] - - def __str__(self) -> str: - requirements = sorted( - (req for req in self.requirements.values() if not req.comes_from), - key=lambda req: canonicalize_name(req.name or ""), - ) - return " ".join(str(req.req) for req in requirements) - - def __repr__(self) -> str: - requirements = sorted( - self.requirements.values(), - key=lambda req: canonicalize_name(req.name or ""), - ) - - format_string = "<{classname} object; {count} requirement(s): {reqs}>" - return format_string.format( - classname=self.__class__.__name__, - count=len(requirements), - reqs=", ".join(str(req.req) for req in requirements), - ) - - def add_unnamed_requirement(self, install_req: InstallRequirement) -> None: - assert not install_req.name - self.unnamed_requirements.append(install_req) - - def add_named_requirement(self, install_req: InstallRequirement) -> None: - assert install_req.name - - project_name = canonicalize_name(install_req.name) - self.requirements[project_name] = install_req - - def has_requirement(self, name: str) -> bool: - project_name = canonicalize_name(name) - - return ( - project_name in self.requirements - and not self.requirements[project_name].constraint - ) - - def get_requirement(self, name: str) -> InstallRequirement: - project_name = canonicalize_name(name) - - if project_name in self.requirements: - return self.requirements[project_name] - - raise KeyError(f"No project with the name {name!r}") - - @property - def all_requirements(self) -> list[InstallRequirement]: - return self.unnamed_requirements + list(self.requirements.values()) - - @property - def requirements_to_install(self) -> list[InstallRequirement]: - """Return the list of requirements that need to be installed. - - TODO remove this property together with the legacy resolver, since the new - resolver only returns requirements that need to be installed. - """ - return [ - install_req - for install_req in self.all_requirements - if not install_req.constraint and not install_req.satisfied_by - ] diff --git a/venv/lib/python3.11/site-packages/pip/_internal/req/req_uninstall.py b/venv/lib/python3.11/site-packages/pip/_internal/req/req_uninstall.py deleted file mode 100755 index 0459c7b..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/req/req_uninstall.py +++ /dev/null @@ -1,644 +0,0 @@ -from __future__ import annotations - -import functools -import os -import sys -import sysconfig -from collections.abc import Callable, Generator, Iterable -from importlib.util import cache_from_source -from typing import Any - -from pip._internal.exceptions import LegacyDistutilsInstall, UninstallMissingRecord -from pip._internal.locations import get_bin_prefix, get_bin_user -from pip._internal.metadata import BaseDistribution -from pip._internal.utils.compat import WINDOWS -from pip._internal.utils.egg_link import egg_link_path_from_location -from pip._internal.utils.logging import getLogger, indent_log -from pip._internal.utils.misc import ask, normalize_path, renames, rmtree -from pip._internal.utils.temp_dir import AdjacentTempDirectory, TempDirectory -from pip._internal.utils.virtualenv import running_under_virtualenv - -logger = getLogger(__name__) - - -def _script_names( - bin_dir: str, script_name: str, is_gui: bool -) -> Generator[str, None, None]: - """Create the fully qualified name of the files created by - {console,gui}_scripts for the given ``dist``. - Returns the list of file names - """ - exe_name = os.path.join(bin_dir, script_name) - yield exe_name - if not WINDOWS: - return - yield f"{exe_name}.exe" - yield f"{exe_name}.exe.manifest" - if is_gui: - yield f"{exe_name}-script.pyw" - else: - yield f"{exe_name}-script.py" - - -def _unique( - fn: Callable[..., Generator[Any, None, None]], -) -> Callable[..., Generator[Any, None, None]]: - @functools.wraps(fn) - def unique(*args: Any, **kw: Any) -> Generator[Any, None, None]: - seen: set[Any] = set() - for item in fn(*args, **kw): - if item not in seen: - seen.add(item) - yield item - - return unique - - -@_unique -def uninstallation_paths(dist: BaseDistribution) -> Generator[str, None, None]: - """ - 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]. - - If RECORD is not found, raises an error, - with possible information from the INSTALLER file. - - https://packaging.python.org/specifications/recording-installed-packages/ - """ - location = dist.location - assert location is not None, "not installed" - - entries = dist.iter_declared_entries() - if entries is None: - raise UninstallMissingRecord(distribution=dist) - - for entry in entries: - path = os.path.join(location, entry) - 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: Iterable[str]) -> set[str]: - """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[str] = set() - prefixes: set[str] = set() - - for path in sorted(paths, key=len): - current = path[:-1] if path.endswith(sep + "*") else path - parent = current.rstrip(sep) - while parent: - if parent in prefixes: - break - next_parent = os.path.dirname(parent).rstrip(sep) - parent = "" if next_parent == parent else next_parent - else: - short_paths.add(path) - prefixes.add(current.rstrip(sep)) - return short_paths - - -def compress_for_rename(paths: Iterable[str]) -> set[str]: - """Returns a set containing the paths that need to be renamed. - - This set may include directories when the original sequence of paths - included every file on disk. - """ - case_map = {os.path.normcase(p): p for p in paths} - remaining = set(case_map) - unchecked = sorted({os.path.split(p)[0] for p in case_map.values()}, key=len) - wildcards: set[str] = set() - - def norm_join(*a: str) -> str: - return os.path.normcase(os.path.join(*a)) - - for root in unchecked: - if any(os.path.normcase(root).startswith(w) for w in wildcards): - # This directory has already been handled. - continue - - all_files: set[str] = set() - all_subdirs: set[str] = set() - for dirname, subdirs, files in os.walk(root): - all_subdirs.update(norm_join(root, dirname, d) for d in subdirs) - all_files.update(norm_join(root, dirname, f) for f in files) - # If all the files we found are in our remaining set of files to - # remove, then remove them from the latter set and add a wildcard - # for the directory. - if not (all_files - remaining): - remaining.difference_update(all_files) - wildcards.add(root + os.sep) - - return set(map(case_map.__getitem__, remaining)) | wildcards - - -def compress_for_output_listing(paths: Iterable[str]) -> tuple[set[str], set[str]]: - """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 = set(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 StashedUninstallPathSet: - """A set of file rename operations to stash files while - tentatively uninstalling them.""" - - def __init__(self) -> None: - # Mapping from source file root to [Adjacent]TempDirectory - # for files under that directory. - self._save_dirs: dict[str, TempDirectory] = {} - # (old path, new path) tuples for each move that may need - # to be undone. - self._moves: list[tuple[str, str]] = [] - - def _get_directory_stash(self, path: str) -> str: - """Stashes a directory. - - Directories are stashed adjacent to their original location if - possible, or else moved/copied into the user's temp dir.""" - - try: - save_dir: TempDirectory = AdjacentTempDirectory(path) - except OSError: - save_dir = TempDirectory(kind="uninstall") - self._save_dirs[os.path.normcase(path)] = save_dir - - return save_dir.path - - def _get_file_stash(self, path: str) -> str: - """Stashes a file. - - If no root has been provided, one will be created for the directory - in the user's temp directory.""" - path = os.path.normcase(path) - head, old_head = os.path.dirname(path), None - save_dir = None - - while head != old_head: - try: - save_dir = self._save_dirs[head] - break - except KeyError: - pass - head, old_head = os.path.dirname(head), head - else: - # Did not find any suitable root - head = os.path.dirname(path) - save_dir = TempDirectory(kind="uninstall") - self._save_dirs[head] = save_dir - - relpath = os.path.relpath(path, head) - if relpath and relpath != os.path.curdir: - return os.path.join(save_dir.path, relpath) - return save_dir.path - - def stash(self, path: str) -> str: - """Stashes the directory or file and returns its new location. - Handle symlinks as files to avoid modifying the symlink targets. - """ - path_is_dir = os.path.isdir(path) and not os.path.islink(path) - if path_is_dir: - new_path = self._get_directory_stash(path) - else: - new_path = self._get_file_stash(path) - - self._moves.append((path, new_path)) - if path_is_dir and os.path.isdir(new_path): - # If we're moving a directory, we need to - # remove the destination first or else it will be - # moved to inside the existing directory. - # We just created new_path ourselves, so it will - # be removable. - os.rmdir(new_path) - renames(path, new_path) - return new_path - - def commit(self) -> None: - """Commits the uninstall by removing stashed files.""" - for save_dir in self._save_dirs.values(): - save_dir.cleanup() - self._moves = [] - self._save_dirs = {} - - def rollback(self) -> None: - """Undoes the uninstall by moving stashed files back.""" - for p in self._moves: - logger.info("Moving to %s\n from %s", *p) - - for new_path, path in self._moves: - try: - logger.debug("Replacing %s from %s", new_path, path) - if os.path.isfile(new_path) or os.path.islink(new_path): - os.unlink(new_path) - elif os.path.isdir(new_path): - rmtree(new_path) - renames(path, new_path) - except OSError as ex: - logger.error("Failed to restore %s", new_path) - logger.debug("Exception: %s", ex) - - self.commit() - - @property - def can_rollback(self) -> bool: - return bool(self._moves) - - -class UninstallPathSet: - """A set of file paths to be removed in the uninstallation of a - requirement.""" - - def __init__(self, dist: BaseDistribution) -> None: - self._paths: set[str] = set() - self._refuse: set[str] = set() - self._pth: dict[str, UninstallPthEntries] = {} - self._dist = dist - self._moved_paths = StashedUninstallPathSet() - # Create local cache of normalize_path results. Creating an UninstallPathSet - # can result in hundreds/thousands of redundant calls to normalize_path with - # the same args, which hurts performance. - self._normalize_path_cached = functools.lru_cache(normalize_path) - - def _permitted(self, path: str) -> bool: - """ - Return True if the given path is one we are permitted to - remove/modify, False otherwise. - - """ - # aka is_local, but caching normalized sys.prefix - if not running_under_virtualenv(): - return True - return path.startswith(self._normalize_path_cached(sys.prefix)) - - def add(self, path: str) -> None: - 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(self._normalize_path_cached(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": - self.add(cache_from_source(path)) - - def add_pth(self, pth_file: str, entry: str) -> None: - pth_file = self._normalize_path_cached(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 remove(self, auto_confirm: bool = False, verbose: bool = False) -> None: - """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.raw_name, - ) - return - - dist_name_version = f"{self._dist.raw_name}-{self._dist.raw_version}" - logger.info("Uninstalling %s:", dist_name_version) - - with indent_log(): - if auto_confirm or self._allowed_to_proceed(verbose): - moved = self._moved_paths - - for_rename = compress_for_rename(self._paths) - - for path in sorted(compact(for_rename)): - moved.stash(path) - logger.verbose("Removing file or directory %s", path) - - for pth in self._pth.values(): - pth.remove() - - logger.info("Successfully uninstalled %s", dist_name_version) - - def _allowed_to_proceed(self, verbose: bool) -> bool: - """Display which files would be deleted and prompt for confirmation""" - - def _display(msg: str, paths: Iterable[str]) -> None: - 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 = set(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) - if verbose: - _display("Will actually move:", compress_for_rename(self._paths)) - - return ask("Proceed (Y/n)? ", ("y", "n", "")) != "n" - - def rollback(self) -> None: - """Rollback the changes previously made by remove().""" - if not self._moved_paths.can_rollback: - logger.error( - "Can't roll back %s; was not uninstalled", - self._dist.raw_name, - ) - return - logger.info("Rolling back uninstall of %s", self._dist.raw_name) - self._moved_paths.rollback() - for pth in self._pth.values(): - pth.rollback() - - def commit(self) -> None: - """Remove temporary save dir: rollback will no longer be possible.""" - self._moved_paths.commit() - - @classmethod - def from_dist(cls, dist: BaseDistribution) -> UninstallPathSet: - dist_location = dist.location - info_location = dist.info_location - if dist_location is None: - logger.info( - "Not uninstalling %s since it is not installed", - dist.canonical_name, - ) - return cls(dist) - - normalized_dist_location = normalize_path(dist_location) - if not dist.local: - logger.info( - "Not uninstalling %s at %s, outside environment %s", - dist.canonical_name, - normalized_dist_location, - sys.prefix, - ) - return cls(dist) - - if normalized_dist_location 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.canonical_name, - normalized_dist_location, - ) - return cls(dist) - - paths_to_remove = cls(dist) - develop_egg_link = egg_link_path_from_location(dist.raw_name) - - # Distribution is installed with metadata in a "flat" .egg-info - # directory. This means it is not a modern .dist-info installation, an - # egg, or legacy editable. - setuptools_flat_installation = ( - dist.installed_with_setuptools_egg_info - and info_location is not None - and os.path.exists(info_location) - # If dist is editable and the location points to a ``.egg-info``, - # we are in fact in the legacy editable case. - and not info_location.endswith(f"{dist.setuptools_filename}.egg-info") - ) - - # 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 setuptools_flat_installation: - if info_location is not None: - paths_to_remove.add(info_location) - installed_files = dist.iter_declared_entries() - if installed_files is not None: - for installed_file in installed_files: - paths_to_remove.add(os.path.join(dist_location, installed_file)) - # FIXME: need a test for this elif block - # occurs with --single-version-externally-managed/--record outside - # of pip - elif dist.is_file("top_level.txt"): - try: - namespace_packages = dist.read_text("namespace_packages.txt") - except FileNotFoundError: - namespaces = [] - else: - namespaces = namespace_packages.splitlines(keepends=False) - for top_level_pkg in [ - p - for p in dist.read_text("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(f"{path}.py") - paths_to_remove.add(f"{path}.pyc") - paths_to_remove.add(f"{path}.pyo") - - elif dist.installed_by_distutils: - raise LegacyDistutilsInstall(distribution=dist) - - elif dist.installed_as_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 - # XXX We use normalized_dist_location because dist_location my contain - # a trailing / if the distribution is a zipped egg - # (which is not a directory). - paths_to_remove.add(normalized_dist_location) - easy_install_egg = os.path.split(normalized_dist_location)[1] - easy_install_pth = os.path.join( - os.path.dirname(normalized_dist_location), - "easy-install.pth", - ) - paths_to_remove.add_pth(easy_install_pth, "./" + easy_install_egg) - - elif dist.installed_with_dist_info: - for path in uninstallation_paths(dist): - paths_to_remove.add(path) - - elif develop_egg_link: - # PEP 660 modern editable is handled in the ``.dist-info`` case - # above, so this only covers the setuptools-style editable. - with open(develop_egg_link) as fh: - link_pointer = os.path.normcase(fh.readline().strip()) - normalized_link_pointer = paths_to_remove._normalize_path_cached( - link_pointer - ) - assert os.path.samefile( - normalized_link_pointer, normalized_dist_location - ), ( - f"Egg-link {develop_egg_link} (to {link_pointer}) does not match " - f"installed location of {dist.raw_name} (at {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, - ) - - if dist.in_usersite: - bin_dir = get_bin_user() - else: - bin_dir = get_bin_prefix() - - # find distutils scripts= scripts - try: - for script in dist.iter_distutils_script_names(): - paths_to_remove.add(os.path.join(bin_dir, script)) - if WINDOWS: - paths_to_remove.add(os.path.join(bin_dir, f"{script}.bat")) - except (FileNotFoundError, NotADirectoryError): - pass - - # find console_scripts and gui_scripts - def iter_scripts_to_remove( - dist: BaseDistribution, - bin_dir: str, - ) -> Generator[str, None, None]: - for entry_point in dist.iter_entry_points(): - if entry_point.group == "console_scripts": - yield from _script_names(bin_dir, entry_point.name, False) - elif entry_point.group == "gui_scripts": - yield from _script_names(bin_dir, entry_point.name, True) - - for s in iter_scripts_to_remove(dist, bin_dir): - paths_to_remove.add(s) - - return paths_to_remove - - -class UninstallPthEntries: - def __init__(self, pth_file: str) -> None: - self.file = pth_file - self.entries: set[str] = set() - self._saved_lines: list[bytes] | None = None - - def add(self, entry: str) -> None: - 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. - # os.path.splitdrive is used instead of os.path.isabs because isabs - # treats non-absolute paths with drive letter markings like c:foo\bar - # as absolute paths. It also does not recognize UNC paths if they don't - # have more than "\\sever\share". Valid examples: "\\server\share\" or - # "\\server\share\folder". - if WINDOWS and not os.path.splitdrive(entry)[0]: - entry = entry.replace("\\", "/") - self.entries.add(entry) - - def remove(self) -> None: - logger.verbose("Removing pth entries from %s:", self.file) - - # If the file doesn't exist, log a warning and return - if not os.path.isfile(self.file): - logger.warning("Cannot remove entries from nonexistent file %s", self.file) - return - with open(self.file, "rb") as fh: - # windows uses '\r\n' with py3k, but uses '\n' with py2.x - lines = fh.readlines() - 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.verbose("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) -> bool: - 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.11/site-packages/pip/_internal/resolution/__init__.py b/venv/lib/python3.11/site-packages/pip/_internal/resolution/__init__.py deleted file mode 100755 index e69de29..0000000 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-311.pyc deleted file mode 100755 index f09706b0e0c4e1ea70c1f0946e9858179fc3bf60..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 201 zcmZ3^%ge<81lOj_$^y}kK?DpiLK&agfQ;!3DGb33nv8xc8H$*I{LdiCUorX_`MIh3 zxrs%|`TAb@>G{U`i3J7vWvO{(`Z<|N`URCG8Tom}dWMGj#hE3kx&?{J*@@|?#rg%A z1^V%sc_pbud5JmtMXAO4Ii)3;`FZ;BK+(*S_;|g7%3mBdx%nxjIjMFx S5+9fu85ut?z=$Gdpcnvu`ZS&Z diff --git a/venv/lib/python3.11/site-packages/pip/_internal/resolution/__pycache__/base.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/resolution/__pycache__/base.cpython-311.pyc deleted file mode 100755 index 2a8fb5185ea4feb33beee68098285e0cc5cc8cd3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1330 zcmb7DOK;Oa5Z?7GPUwS2)v8rn1yYc5Af|#t4}}8=p%$qixS(7t$2)BUYp=6*g6OG2 zJ#s`U;s+E}{23!vsPd^2CvHK33nylsG&G_Y*7oObX2;{1Z+Ab9kCzCJukSy;ysHuN zO&O=d7?55A$v$C(QBDF{r&Mu`Yk^+ZbFOnEFzY5IK*0i?89N0+wlvT;wb|2bq+Za- zBf`u*!mI=Q*JphCqi!?fIjI)DE3-;7`+>)~*WiHs@>&=tXg-5hyD1@nFhTFc8S^tajXcDyKZIuLdo-fTG0n`B#rw`$&|9ck^cF8Y`OkVpkQ8}8Zq;{o;KB7KuxiKXE zaM{uOA6iJ2UydVGH94vH6hf>rl*>~6H=Evq1RKcri>E4gg=8RiDkJ5dA9P7&ysY2~ z!bY{2*{&OU0l02fa@|0%HdlPibz5zZ4`vMBj1#F2N@g^K;L=nX@?6u%4*S{i>LeZs zlEVcgafGltytHzXW|zCVvK~Ll-zUYHu8DS+j6zAp%v>MDjHeUjqvF+b zBZnX6t>qfRQo4ez)esaZUS7|mU>P_?RPqRehjW{-hQT|B-z}* z=k}=-ohGhFUx|4ohtfJ%=eNDum-wE%hCX#B;&%vLol<&CmeSGtgsi5c_c6JXj@~B= t*N;s*EzN&OzLYAdv6S9eNsX1Cy0)mLWUgB(QWW)H_@R71&zZ=p{R2HZQVIY7 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/resolution/base.py b/venv/lib/python3.11/site-packages/pip/_internal/resolution/base.py deleted file mode 100755 index 3e35de7..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/resolution/base.py +++ /dev/null @@ -1,20 +0,0 @@ -from collections.abc import Callable - -from pip._internal.req.req_install import InstallRequirement -from pip._internal.req.req_set import RequirementSet - -InstallRequirementProvider = Callable[ - [str, InstallRequirement | None], InstallRequirement -] - - -class BaseResolver: - def resolve( - self, root_reqs: list[InstallRequirement], check_supported_wheels: bool - ) -> RequirementSet: - raise NotImplementedError() - - def get_installation_order( - self, req_set: RequirementSet - ) -> list[InstallRequirement]: - raise NotImplementedError() diff --git a/venv/lib/python3.11/site-packages/pip/_internal/resolution/legacy/__init__.py b/venv/lib/python3.11/site-packages/pip/_internal/resolution/legacy/__init__.py deleted file mode 100755 index e69de29..0000000 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/resolution/legacy/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/resolution/legacy/__pycache__/__init__.cpython-311.pyc deleted file mode 100755 index da61dde45f35a506173bf96ccc15f21666f18ab9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 208 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 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/resolution/legacy/resolver.py b/venv/lib/python3.11/site-packages/pip/_internal/resolution/legacy/resolver.py deleted file mode 100755 index f2b0379..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/resolution/legacy/resolver.py +++ /dev/null @@ -1,598 +0,0 @@ -"""Dependency Resolution - -The dependency resolution in pip is performed as follows: - -for top-level requirements: - a. only one spec allowed per project, regardless of conflicts or not. - otherwise a "double requirement" exception is raised - b. they override sub-dependency requirements. -for sub-dependencies - a. "first found, wins" (where the order is breadth first) -""" - -from __future__ import annotations - -import logging -import sys -from collections import defaultdict -from collections.abc import Iterable -from itertools import chain - -from pip._vendor.packaging import specifiers -from pip._vendor.packaging.requirements import Requirement - -from pip._internal.cache import WheelCache -from pip._internal.exceptions import ( - BestVersionAlreadyInstalled, - DistributionNotFound, - HashError, - HashErrors, - InstallationError, - NoneMetadataError, - UnsupportedPythonVersion, -) -from pip._internal.index.package_finder import PackageFinder -from pip._internal.metadata import BaseDistribution -from pip._internal.models.link import Link -from pip._internal.models.wheel import Wheel -from pip._internal.operations.prepare import RequirementPreparer -from pip._internal.req.req_install import ( - InstallRequirement, - check_invalid_constraint_type, -) -from pip._internal.req.req_set import RequirementSet -from pip._internal.resolution.base import BaseResolver, InstallRequirementProvider -from pip._internal.utils import compatibility_tags -from pip._internal.utils.compatibility_tags import get_supported -from pip._internal.utils.direct_url_helpers import direct_url_from_link -from pip._internal.utils.logging import indent_log -from pip._internal.utils.misc import normalize_version_info -from pip._internal.utils.packaging import check_requires_python - -logger = logging.getLogger(__name__) - -DiscoveredDependencies = defaultdict[str | None, list[InstallRequirement]] - - -def _check_dist_requires_python( - dist: BaseDistribution, - version_info: tuple[int, int, int], - ignore_requires_python: bool = False, -) -> None: - """ - Check whether the given Python version is compatible with a distribution's - "Requires-Python" value. - - :param version_info: A 3-tuple of ints representing the Python - major-minor-micro version to check. - :param ignore_requires_python: Whether to ignore the "Requires-Python" - value if the given Python version isn't compatible. - - :raises UnsupportedPythonVersion: When the given Python version isn't - compatible. - """ - # This idiosyncratically converts the SpecifierSet to str and let - # check_requires_python then parse it again into SpecifierSet. But this - # is the legacy resolver so I'm just not going to bother refactoring. - try: - requires_python = str(dist.requires_python) - except FileNotFoundError as e: - raise NoneMetadataError(dist, str(e)) - try: - is_compatible = check_requires_python( - requires_python, - version_info=version_info, - ) - except specifiers.InvalidSpecifier as exc: - logger.warning( - "Package %r has an invalid Requires-Python: %s", dist.raw_name, exc - ) - return - - if is_compatible: - return - - version = ".".join(map(str, version_info)) - if ignore_requires_python: - logger.debug( - "Ignoring failed Requires-Python check for package %r: %s not in %r", - dist.raw_name, - version, - requires_python, - ) - return - - raise UnsupportedPythonVersion( - f"Package {dist.raw_name!r} requires a different Python: " - f"{version} not in {requires_python!r}" - ) - - -class Resolver(BaseResolver): - """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: RequirementPreparer, - finder: PackageFinder, - wheel_cache: WheelCache | None, - make_install_req: InstallRequirementProvider, - use_user_site: bool, - ignore_dependencies: bool, - only_dependencies: bool, # unused, for compatibility with new resolver - ignore_installed: bool, - ignore_requires_python: bool, - force_reinstall: bool, - upgrade_strategy: str, - py_version_info: tuple[int, ...] | None = None, - ) -> None: - super().__init__() - assert upgrade_strategy in self._allowed_strategies - - if py_version_info is None: - py_version_info = sys.version_info[:3] - else: - py_version_info = normalize_version_info(py_version_info) - - self._py_version_info = py_version_info - - self.preparer = preparer - self.finder = finder - self.wheel_cache = wheel_cache - - self.upgrade_strategy = upgrade_strategy - self.force_reinstall = force_reinstall - 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._make_install_req = make_install_req - - self._discovered_dependencies: DiscoveredDependencies = defaultdict(list) - - def resolve( - self, root_reqs: list[InstallRequirement], check_supported_wheels: bool - ) -> RequirementSet: - """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. - """ - requirement_set = RequirementSet(check_supported_wheels=check_supported_wheels) - for req in root_reqs: - if req.constraint: - check_invalid_constraint_type(req) - self._add_requirement_to_set(requirement_set, req) - - # Actually prepare the files, and collect any exceptions. Most hash - # exceptions cannot be checked ahead of time, because - # _populate_link() needs to be called before we can make decisions - # based on link type. - discovered_reqs: list[InstallRequirement] = [] - hash_errors = HashErrors() - for req in chain(requirement_set.all_requirements, 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 - - return requirement_set - - def _add_requirement_to_set( - self, - requirement_set: RequirementSet, - install_req: InstallRequirement, - parent_req_name: str | None = None, - extras_requested: Iterable[str] | None = None, - ) -> tuple[list[InstallRequirement], InstallRequirement | 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. - """ - # 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", - install_req.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) - tags = compatibility_tags.get_supported() - if requirement_set.check_supported_wheels and not wheel.supported(tags): - raise InstallationError( - f"{wheel.filename} is not a supported wheel on this platform." - ) - - # This next bit is really a sanity check. - assert ( - not install_req.user_supplied or parent_req_name is None - ), "a user supplied req shouldn't have a parent" - - # Unnamed requirements are scanned again and the requirement won't be - # added as a dependency until after scanning. - if not install_req.name: - requirement_set.add_unnamed_requirement(install_req) - return [install_req], None - - try: - existing_req: InstallRequirement | None = requirement_set.get_requirement( - install_req.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 - and install_req.req - and existing_req.req.specifier != install_req.req.specifier - ) - if has_conflicting_requirement: - raise InstallationError( - f"Double requirement given: {install_req} " - f"(already in {existing_req}, name={install_req.name!r})" - ) - - # When no existing requirement exists, add the requirement as a - # dependency and it will be scanned again after. - if not existing_req: - requirement_set.add_named_requirement(install_req) - # We'd want to rescan this requirement later - return [install_req], install_req - - # Assume there's no need to scan, and that we've already - # 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: - raise InstallationError( - f"Could not satisfy constraints for '{install_req.name}': " - "installation from path or url cannot be " - "constrained to a version" - ) - # If we're now installing a constraint, mark the existing - # object for real installation. - existing_req.constraint = False - # If we're now installing a user supplied requirement, - # mark the existing object as such. - if install_req.user_supplied: - existing_req.user_supplied = True - existing_req.extras = tuple( - sorted(set(existing_req.extras) | set(install_req.extras)) - ) - 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 _is_upgrade_allowed(self, req: InstallRequirement) -> bool: - if self.upgrade_strategy == "to-satisfy-only": - return False - elif self.upgrade_strategy == "eager": - return True - else: - assert self.upgrade_strategy == "only-if-needed" - return req.user_supplied or req.constraint - - def _set_req_to_reinstall(self, req: InstallRequirement) -> None: - """ - Set a requirement to be installed. - """ - # Don't uninstall the conflict if doing a user install and the - # conflict is not a user install. - assert req.satisfied_by is not None - if not self.use_user_site or req.satisfied_by.in_usersite: - req.should_reinstall = True - req.satisfied_by = None - - def _check_skip_installed(self, req_to_install: InstallRequirement) -> str | None: - """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 _find_requirement_link(self, req: InstallRequirement) -> Link | None: - upgrade = self._is_upgrade_allowed(req) - best_candidate = self.finder.find_requirement(req, upgrade) - if not best_candidate: - return None - - # Log a warning per PEP 592 if necessary before returning. - link = best_candidate.link - if link.is_yanked: - reason = link.yanked_reason or "" - msg = ( - # Mark this as a unicode string to prevent - # "UnicodeEncodeError: 'ascii' codec can't encode character" - # in Python 2 when the reason contains non-ascii characters. - "The candidate selected for download or install is a " - f"yanked version: {best_candidate}\n" - f"Reason for being yanked: {reason}" - ) - logger.warning(msg) - - return link - - def _populate_link(self, req: InstallRequirement) -> None: - """Ensure that if a link can be found for this, that it is found. - - Note that req.link may still be None - if the requirement is already - installed and not needed to be upgraded based on the return value of - _is_upgrade_allowed(). - - If preparer.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 nondeterministic - contents due to file modification times. - """ - if req.link is None: - req.link = self._find_requirement_link(req) - - if self.wheel_cache is None or self.preparer.require_hashes: - return - - assert req.link is not None, "_find_requirement_link unexpectedly returned None" - cache_entry = self.wheel_cache.get_cache_entry( - link=req.link, - package_name=req.name, - supported_tags=get_supported(), - ) - if cache_entry is not None: - logger.debug("Using cached wheel link: %s", cache_entry.link) - if req.link is req.original_link and cache_entry.persistent: - req.cached_wheel_source_link = req.link - if cache_entry.origin is not None: - req.download_info = cache_entry.origin - else: - # Legacy cache entry that does not have origin.json. - # download_info may miss the archive_info.hashes field. - req.download_info = direct_url_from_link( - req.link, link_is_in_wheel_cache=cache_entry.persistent - ) - req.link = cache_entry.link - - def _get_dist_for(self, req: InstallRequirement) -> BaseDistribution: - """Takes a InstallRequirement and returns a single AbstractDist \ - representing a prepared variant of the same. - """ - if req.editable: - return self.preparer.prepare_editable_requirement(req) - - # 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, skip_reason) - - # We eagerly populate the link, since that's our "legacy" behavior. - self._populate_link(req) - dist = self.preparer.prepare_linked_requirement(req) - - # 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 dist - - def _resolve_one( - self, - requirement_set: RequirementSet, - req_to_install: InstallRequirement, - ) -> list[InstallRequirement]: - """Prepare a single requirements file. - - :return: A list of additional InstallRequirements to also install. - """ - # Tell user what we are doing for this requirement: - # obtain (editable), skipping, processing (local url), collecting - # (remote url or package name) - if req_to_install.constraint or req_to_install.prepared: - return [] - - req_to_install.prepared = True - - # Parse and return dependencies - dist = self._get_dist_for(req_to_install) - # This will raise UnsupportedPythonVersion if the given Python - # version isn't compatible with the distribution's Requires-Python. - _check_dist_requires_python( - dist, - version_info=self._py_version_info, - ignore_requires_python=self.ignore_requires_python, - ) - - more_reqs: list[InstallRequirement] = [] - - def add_req(subreq: Requirement, extras_requested: Iterable[str]) -> None: - # This idiosyncratically converts the Requirement to str and let - # make_install_req then parse it again into Requirement. But this is - # the legacy resolver so I'm just not going to bother refactoring. - sub_install_req = self._make_install_req(str(subreq), req_to_install) - parent_req_name = req_to_install.name - to_scan_again, add_to_parent = self._add_requirement_to_set( - requirement_set, - 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. - assert req_to_install.name is not None - if not requirement_set.has_requirement(req_to_install.name): - # 'unnamed' requirements will get added here - # 'unnamed' requirements can only come from being directly - # provided by the user. - assert req_to_install.user_supplied - self._add_requirement_to_set( - requirement_set, 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.iter_provided_extras()) - ) - for missing in missing_requested: - logger.warning( - "%s %s does not provide the extra '%s'", - dist.raw_name, - dist.version, - missing, - ) - - available_requested = sorted( - set(dist.iter_provided_extras()) & set(req_to_install.extras) - ) - for subreq in dist.iter_dependencies(available_requested): - add_req(subreq, extras_requested=available_requested) - - return more_reqs - - def get_installation_order( - self, req_set: RequirementSet - ) -> list[InstallRequirement]: - """Create the installation order. - - The installation order is topological - requirements are installed - before the requiring thing. We break cycles at an arbitrary point, - and make no other guarantees. - """ - # The current implementation, which we may change at any point - # installs the user specified things in the order given, except when - # dependencies must come earlier to achieve topological order. - order = [] - ordered_reqs: set[InstallRequirement] = set() - - def schedule(req: InstallRequirement) -> None: - 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.11/site-packages/pip/_internal/resolution/resolvelib/__init__.py b/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__init__.py deleted file mode 100755 index e69de29..0000000 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-311.pyc deleted file mode 100755 index c72881651f3f656bf311bcc8ff4bc83f9760c01a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 212 zcmZ3^%ge<81lOj_$^y}kK?DpiLK&agfQ;!3DGb33nv8xc8H$*I{LdiCU+MZ8`MIh3 zxrs%|`TAb@>G{U`i3J7vWvO{(`Z<|N`URCG8Tom}dWMGj#hE3kx&?{J*@@|?#rg%A z1^V%sc_pbud5JmtMXAO4Ii)3;`FRj#St>|#JWxSqNqoFsLFF$Fo80`A(wtPgB37Wi XAeR;M1BnmJjEsyQ7+^#ZGf)fwOvO15 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/base.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/base.cpython-311.pyc deleted file mode 100755 index 36f1cb8321a4da64ec7e4805a8560f93f7b0964b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11571 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 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-311.pyc deleted file mode 100755 index 5e5e2955cb394770db4be70995a1fe3852e4e666..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30420 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 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-311.pyc deleted file mode 100755 index 4a3763cd7c2117ea96c1a5f4573460e9d042f217..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 39787 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 DRj*@J diff --git a/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-311.pyc deleted file mode 100755 index 7d648cefd7b691bb5d221d6941022e962ea3b73b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7152 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 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-311.pyc deleted file mode 100755 index 3ad5781fad503cdc52381d38b55a3b4eae8cc100..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13613 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 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-311.pyc deleted file mode 100755 index 8bad74a9846f2f27a003688dace904ba5f2473ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15867 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 BM}PnT diff --git a/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/base.py b/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/base.py deleted file mode 100755 index 9d75183..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/base.py +++ /dev/null @@ -1,164 +0,0 @@ -from __future__ import annotations - -from collections.abc import Iterable -from dataclasses import dataclass -from typing import Optional - -from pip._vendor.packaging.specifiers import SpecifierSet -from pip._vendor.packaging.utils import NormalizedName -from pip._vendor.packaging.version import Version - -from pip._internal.models.link import Link, links_equivalent -from pip._internal.req.req_install import InstallRequirement -from pip._internal.utils.hashes import Hashes - -CandidateLookup = tuple[Optional["Candidate"], InstallRequirement | None] - - -def format_name(project: NormalizedName, extras: frozenset[NormalizedName]) -> str: - if not extras: - return project - extras_expr = ",".join(sorted(extras)) - return f"{project}[{extras_expr}]" - - -@dataclass(frozen=True) -class Constraint: - specifier: SpecifierSet - hashes: Hashes - hash_options: dict[str, list[str]] - links: frozenset[Link] - - @classmethod - def empty(cls) -> Constraint: - return Constraint(SpecifierSet(), Hashes(), {}, frozenset()) - - @classmethod - def from_ireq(cls, ireq: InstallRequirement) -> Constraint: - links = frozenset([ireq.link]) if ireq.link else frozenset() - hash_options = {alg: list(v) for alg, v in ireq.hash_options.items()} - return Constraint( - ireq.specifier, - ireq.hashes(trust_internet=False), - hash_options, - links, - ) - - def __bool__(self) -> bool: - return bool(self.specifier) or bool(self.hashes) or bool(self.links) - - def __and__(self, other: InstallRequirement) -> Constraint: - if not isinstance(other, InstallRequirement): - return NotImplemented - specifier = self.specifier & other.specifier - hashes = self.hashes & other.hashes(trust_internet=False) - if not self.hash_options: - hash_options = {alg: list(v) for alg, v in other.hash_options.items()} - elif not other.hash_options: - hash_options = {alg: list(v) for alg, v in self.hash_options.items()} - else: - hash_options = { - alg: [v for v in other.hash_options[alg] if v in self.hash_options[alg]] - for alg in self.hash_options.keys() & other.hash_options.keys() - } - links = self.links - if other.link: - links = links.union([other.link]) - return Constraint(specifier, hashes, hash_options, links) - - def is_satisfied_by(self, candidate: Candidate) -> bool: - # Reject if there are any mismatched URL constraints on this package. - if self.links and not all(_match_link(link, candidate) for link in self.links): - return False - # We can safely always allow prereleases here since PackageFinder - # already implements the prerelease logic, and would have filtered out - # prerelease candidates if the user does not expect them. - return self.specifier.contains(candidate.version, prereleases=True) - - def format_for_error(self) -> str: - s = str(self.specifier) - if self.links: - s += f" (from {', '.join(str(link) for link in self.links)})" - return s - - -class Requirement: - @property - def project_name(self) -> NormalizedName: - """The "project name" of a requirement. - - This is different from ``name`` if this requirement contains extras, - in which case ``name`` would contain the ``[...]`` part, while this - refers to the name of the project. - """ - raise NotImplementedError("Subclass should override") - - @property - def name(self) -> str: - """The name identifying this requirement in the resolver. - - This is different from ``project_name`` if this requirement contains - extras, where ``project_name`` would not contain the ``[...]`` part. - """ - raise NotImplementedError("Subclass should override") - - def is_satisfied_by(self, candidate: Candidate) -> bool: - return False - - def get_candidate_lookup(self) -> CandidateLookup: - raise NotImplementedError("Subclass should override") - - def format_for_error(self) -> str: - raise NotImplementedError("Subclass should override") - - -def _match_link(link: Link, candidate: Candidate) -> bool: - if candidate.source_link: - return links_equivalent(link, candidate.source_link) - return False - - -class Candidate: - @property - def project_name(self) -> NormalizedName: - """The "project name" of the candidate. - - This is different from ``name`` if this candidate contains extras, - in which case ``name`` would contain the ``[...]`` part, while this - refers to the name of the project. - """ - raise NotImplementedError("Override in subclass") - - @property - def name(self) -> str: - """The name identifying this candidate in the resolver. - - This is different from ``project_name`` if this candidate contains - extras, where ``project_name`` would not contain the ``[...]`` part. - """ - raise NotImplementedError("Override in subclass") - - @property - def version(self) -> Version: - raise NotImplementedError("Override in subclass") - - @property - def is_installed(self) -> bool: - raise NotImplementedError("Override in subclass") - - @property - def is_editable(self) -> bool: - raise NotImplementedError("Override in subclass") - - @property - def source_link(self) -> Link | None: - raise NotImplementedError("Override in subclass") - - def iter_dependencies(self, with_requires: bool) -> Iterable[Requirement | None]: - raise NotImplementedError("Override in subclass") - - def get_install_requirement(self) -> InstallRequirement | None: - raise NotImplementedError("Override in subclass") - - def format_for_error(self) -> str: - raise NotImplementedError("Subclass should override") diff --git a/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/candidates.py b/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/candidates.py deleted file mode 100755 index b8b853c..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/candidates.py +++ /dev/null @@ -1,598 +0,0 @@ -from __future__ import annotations - -import logging -import sys -from collections.abc import Iterable -from typing import TYPE_CHECKING, Any, Union, cast - -from pip._vendor.packaging.requirements import InvalidRequirement -from pip._vendor.packaging.utils import NormalizedName, canonicalize_name -from pip._vendor.packaging.version import Version - -from pip._internal.exceptions import ( - FailedToPrepareCandidate, - HashError, - InstallationSubprocessError, - InvalidInstalledPackage, - MetadataInconsistent, - MetadataInvalid, -) -from pip._internal.metadata import BaseDistribution -from pip._internal.models.link import Link, links_equivalent -from pip._internal.models.wheel import Wheel -from pip._internal.req.constructors import ( - install_req_from_editable, - install_req_from_line, -) -from pip._internal.req.req_install import InstallRequirement -from pip._internal.utils.direct_url_helpers import direct_url_from_link -from pip._internal.utils.misc import normalize_version_info - -from .base import Candidate, Requirement, format_name - -if TYPE_CHECKING: - from .factory import Factory - -logger = logging.getLogger(__name__) - -BaseCandidate = Union[ - "AlreadyInstalledCandidate", - "EditableCandidate", - "LinkCandidate", -] - -# Avoid conflicting with the PyPI package "Python". -REQUIRES_PYTHON_IDENTIFIER = cast(NormalizedName, "") - - -def as_base_candidate(candidate: Candidate) -> BaseCandidate | None: - """The runtime version of BaseCandidate.""" - base_candidate_classes = ( - AlreadyInstalledCandidate, - EditableCandidate, - LinkCandidate, - ) - if isinstance(candidate, base_candidate_classes): - return candidate - return None - - -def make_install_req_from_link( - link: Link, - template: InstallRequirement, - version: Version | None = None, -) -> InstallRequirement: - assert not template.editable, "template is editable" - if version is not None and template.req and template.hash_options: - # When hashes are provided via constraints for an unpinned requirement, - # the resulting install requirement must appear pinned so that the - # hash-checking logic does not reject it as HashUnpinned. - line = f"{template.req.name}=={version}" - elif template.req: - line = str(template.req) - else: - line = link.url - ireq = install_req_from_line( - line, - user_supplied=template.user_supplied, - comes_from=template.comes_from, - isolated=template.isolated, - constraint=template.constraint, - hash_options=template.hash_options, - config_settings=template.config_settings, - ) - ireq.original_link = template.original_link - ireq.link = link - ireq.extras = template.extras - return ireq - - -def make_install_req_from_editable( - link: Link, template: InstallRequirement -) -> InstallRequirement: - assert template.editable, "template not editable" - if template.name: - req_string = f"{template.name} @ {link.url}" - else: - req_string = link.url - ireq = install_req_from_editable( - req_string, - user_supplied=template.user_supplied, - comes_from=template.comes_from, - isolated=template.isolated, - constraint=template.constraint, - hash_options=template.hash_options, - config_settings=template.config_settings, - ) - ireq.extras = template.extras - return ireq - - -def _make_install_req_from_dist( - dist: BaseDistribution, template: InstallRequirement -) -> InstallRequirement: - if template.req: - line = str(template.req) - elif template.link: - line = f"{dist.canonical_name} @ {template.link.url}" - else: - line = f"{dist.canonical_name}=={dist.version}" - ireq = install_req_from_line( - line, - user_supplied=template.user_supplied, - comes_from=template.comes_from, - isolated=template.isolated, - constraint=template.constraint, - hash_options=template.hash_options, - config_settings=template.config_settings, - ) - ireq.satisfied_by = dist - return ireq - - -class _InstallRequirementBackedCandidate(Candidate): - """A candidate backed by an ``InstallRequirement``. - - This represents a package request with the target not being already - in the environment, and needs to be fetched and installed. The backing - ``InstallRequirement`` is responsible for most of the leg work; this - class exposes appropriate information to the resolver. - - :param link: The link passed to the ``InstallRequirement``. The backing - ``InstallRequirement`` will use this link to fetch the distribution. - :param source_link: The link this candidate "originates" from. This is - different from ``link`` when the link is found in the wheel cache. - ``link`` would point to the wheel cache, while this points to the - found remote link (e.g. from pypi.org). - """ - - dist: BaseDistribution - is_installed = False - - def __init__( - self, - link: Link, - source_link: Link, - ireq: InstallRequirement, - factory: Factory, - name: NormalizedName | None = None, - version: Version | None = None, - ) -> None: - self._link = link - self._source_link = source_link - self._factory = factory - self._ireq = ireq - self._name = name - self._version = version - self.dist = self._prepare() - self._hash: int | None = None - - def __str__(self) -> str: - return f"{self.name} {self.version}" - - def __repr__(self) -> str: - return f"{self.__class__.__name__}({str(self._link)!r})" - - def __hash__(self) -> int: - if self._hash is not None: - return self._hash - - self._hash = hash((self.__class__, self._link)) - return self._hash - - def __eq__(self, other: Any) -> bool: - if isinstance(other, self.__class__): - return links_equivalent(self._link, other._link) - return False - - @property - def source_link(self) -> Link | None: - return self._source_link - - @property - def project_name(self) -> NormalizedName: - """The normalised name of the project the candidate refers to""" - if self._name is None: - self._name = self.dist.canonical_name - return self._name - - @property - def name(self) -> str: - return self.project_name - - @property - def version(self) -> Version: - if self._version is None: - self._version = self.dist.version - return self._version - - def format_for_error(self) -> str: - return ( - f"{self.name} {self.version} " - f"(from {'editable ' if self.is_editable else ''}" - f"{self._link.file_path if self._link.is_file else self._link})" - ) - - def _prepare_distribution(self) -> BaseDistribution: - raise NotImplementedError("Override in subclass") - - def _check_metadata_consistency(self, dist: BaseDistribution) -> None: - """Check for consistency of project name and version of dist.""" - if self._name is not None and self._name != dist.canonical_name: - raise MetadataInconsistent( - self._ireq, - "name", - self._name, - dist.canonical_name, - ) - if self._version is not None and self._version != dist.version: - raise MetadataInconsistent( - self._ireq, - "version", - str(self._version), - str(dist.version), - ) - # check dependencies are valid - # TODO performance: this means we iterate the dependencies at least twice, - # we may want to cache parsed Requires-Dist - try: - list(dist.iter_dependencies(list(dist.iter_provided_extras()))) - except InvalidRequirement as e: - raise MetadataInvalid(self._ireq, str(e)) - - def _prepare(self) -> BaseDistribution: - try: - dist = self._prepare_distribution() - except HashError as e: - # Provide HashError the underlying ireq that caused it. This - # provides context for the resulting error message to show the - # offending line to the user. - e.req = self._ireq - raise - except InstallationSubprocessError as exc: - if isinstance(self._ireq.comes_from, InstallRequirement): - request_chain = self._ireq.comes_from.from_path() - else: - request_chain = self._ireq.comes_from - - if request_chain is None: - request_chain = "directly requested" - - raise FailedToPrepareCandidate( - package_name=self._ireq.name or str(self._link), - requirement_chain=request_chain, - failed_step=exc.command_description, - ) - - self._check_metadata_consistency(dist) - return dist - - def iter_dependencies(self, with_requires: bool) -> Iterable[Requirement | None]: - # Emit the Requires-Python requirement first to fail fast on - # unsupported candidates and avoid pointless downloads/preparation. - yield self._factory.make_requires_python_requirement(self.dist.requires_python) - requires = self.dist.iter_dependencies() if with_requires else () - for r in requires: - yield from self._factory.make_requirements_from_spec(str(r), self._ireq) - - def get_install_requirement(self) -> InstallRequirement | None: - return self._ireq - - -class LinkCandidate(_InstallRequirementBackedCandidate): - is_editable = False - - def __init__( - self, - link: Link, - template: InstallRequirement, - factory: Factory, - name: NormalizedName | None = None, - version: Version | None = None, - ) -> None: - source_link = link - cache_entry = factory.get_wheel_cache_entry(source_link, name) - if cache_entry is not None: - logger.debug("Using cached wheel link: %s", cache_entry.link) - link = cache_entry.link - ireq = make_install_req_from_link(link, template, version=version) - assert ireq.link == link - if ireq.link.is_wheel and not ireq.link.is_file: - wheel = Wheel(ireq.link.filename) - wheel_name = wheel.name - assert name == wheel_name, f"{name!r} != {wheel_name!r} for wheel" - # Version may not be present for PEP 508 direct URLs - if version is not None: - wheel_version = Version(wheel.version) - assert ( - version == wheel_version - ), f"{version!r} != {wheel_version!r} for wheel {name}" - - if cache_entry is not None: - assert ireq.link.is_wheel - assert ireq.link.is_file - if cache_entry.persistent and template.link is template.original_link: - ireq.cached_wheel_source_link = source_link - if cache_entry.origin is not None: - ireq.download_info = cache_entry.origin - else: - # Legacy cache entry that does not have origin.json. - # download_info may miss the archive_info.hashes field. - ireq.download_info = direct_url_from_link( - source_link, link_is_in_wheel_cache=cache_entry.persistent - ) - - super().__init__( - link=link, - source_link=source_link, - ireq=ireq, - factory=factory, - name=name, - version=version, - ) - - def _prepare_distribution(self) -> BaseDistribution: - preparer = self._factory.preparer - return preparer.prepare_linked_requirement(self._ireq, parallel_builds=True) - - -class EditableCandidate(_InstallRequirementBackedCandidate): - is_editable = True - - def __init__( - self, - link: Link, - template: InstallRequirement, - factory: Factory, - name: NormalizedName | None = None, - version: Version | None = None, - ) -> None: - super().__init__( - link=link, - source_link=link, - ireq=make_install_req_from_editable(link, template), - factory=factory, - name=name, - version=version, - ) - - def _prepare_distribution(self) -> BaseDistribution: - return self._factory.preparer.prepare_editable_requirement(self._ireq) - - -class AlreadyInstalledCandidate(Candidate): - is_installed = True - source_link = None - - def __init__( - self, - dist: BaseDistribution, - template: InstallRequirement, - factory: Factory, - ) -> None: - self.dist = dist - self._ireq = _make_install_req_from_dist(dist, template) - self._factory = factory - self._version = None - - # This is just logging some messages, so we can do it eagerly. - # The returned dist would be exactly the same as self.dist because we - # set satisfied_by in _make_install_req_from_dist. - # TODO: Supply reason based on force_reinstall and upgrade_strategy. - skip_reason = "already satisfied" - factory.preparer.prepare_installed_requirement(self._ireq, skip_reason) - - def __str__(self) -> str: - return str(self.dist) - - def __repr__(self) -> str: - return f"{self.__class__.__name__}({self.dist!r})" - - def __eq__(self, other: object) -> bool: - if not isinstance(other, AlreadyInstalledCandidate): - return NotImplemented - return self.name == other.name and self.version == other.version - - def __hash__(self) -> int: - return hash((self.name, self.version)) - - @property - def project_name(self) -> NormalizedName: - return self.dist.canonical_name - - @property - def name(self) -> str: - return self.project_name - - @property - def version(self) -> Version: - if self._version is None: - self._version = self.dist.version - return self._version - - @property - def is_editable(self) -> bool: - return self.dist.editable - - def format_for_error(self) -> str: - return f"{self.name} {self.version} (Installed)" - - def iter_dependencies(self, with_requires: bool) -> Iterable[Requirement | None]: - if not with_requires: - return - - try: - for r in self.dist.iter_dependencies(): - yield from self._factory.make_requirements_from_spec(str(r), self._ireq) - except InvalidRequirement as exc: - raise InvalidInstalledPackage(dist=self.dist, invalid_exc=exc) from None - - def get_install_requirement(self) -> InstallRequirement | None: - return None - - -class ExtrasCandidate(Candidate): - """A candidate that has 'extras', indicating additional dependencies. - - Requirements can be for a project with dependencies, something like - foo[extra]. The extras don't affect the project/version being installed - directly, but indicate that we need additional dependencies. We model that - by having an artificial ExtrasCandidate that wraps the "base" candidate. - - The ExtrasCandidate differs from the base in the following ways: - - 1. It has a unique name, of the form foo[extra]. This causes the resolver - to treat it as a separate node in the dependency graph. - 2. When we're getting the candidate's dependencies, - a) We specify that we want the extra dependencies as well. - b) We add a dependency on the base candidate. - See below for why this is needed. - 3. We return None for the underlying InstallRequirement, as the base - candidate will provide it, and we don't want to end up with duplicates. - - The dependency on the base candidate is needed so that the resolver can't - decide that it should recommend foo[extra1] version 1.0 and foo[extra2] - version 2.0. Having those candidates depend on foo=1.0 and foo=2.0 - respectively forces the resolver to recognise that this is a conflict. - """ - - def __init__( - self, - base: BaseCandidate, - extras: frozenset[str], - *, - comes_from: InstallRequirement | None = None, - ) -> None: - """ - :param comes_from: the InstallRequirement that led to this candidate if it - differs from the base's InstallRequirement. This will often be the - case in the sense that this candidate's requirement has the extras - while the base's does not. Unlike the InstallRequirement backed - candidates, this requirement is used solely for reporting purposes, - it does not do any leg work. - """ - self.base = base - self.extras = frozenset(canonicalize_name(e) for e in extras) - self._comes_from = comes_from if comes_from is not None else self.base._ireq - - def __str__(self) -> str: - name, rest = str(self.base).split(" ", 1) - return "{}[{}] {}".format(name, ",".join(self.extras), rest) - - def __repr__(self) -> str: - return f"{self.__class__.__name__}(base={self.base!r}, extras={self.extras!r})" - - def __hash__(self) -> int: - return hash((self.base, self.extras)) - - def __eq__(self, other: Any) -> bool: - if isinstance(other, self.__class__): - return self.base == other.base and self.extras == other.extras - return False - - @property - def project_name(self) -> NormalizedName: - return self.base.project_name - - @property - def name(self) -> str: - """The normalised name of the project the candidate refers to""" - return format_name(self.base.project_name, self.extras) - - @property - def version(self) -> Version: - return self.base.version - - def format_for_error(self) -> str: - return "{} [{}]".format( - self.base.format_for_error(), ", ".join(sorted(self.extras)) - ) - - @property - def is_installed(self) -> bool: - return self.base.is_installed - - @property - def is_editable(self) -> bool: - return self.base.is_editable - - @property - def source_link(self) -> Link | None: - return self.base.source_link - - def iter_dependencies(self, with_requires: bool) -> Iterable[Requirement | None]: - factory = self.base._factory - - # Add a dependency on the exact base - # (See note 2b in the class docstring) - yield factory.make_requirement_from_candidate(self.base) - if not with_requires: - return - - # The user may have specified extras that the candidate doesn't - # support. We ignore any unsupported extras here. - valid_extras = self.extras.intersection(self.base.dist.iter_provided_extras()) - invalid_extras = self.extras.difference(self.base.dist.iter_provided_extras()) - for extra in sorted(invalid_extras): - logger.warning( - "%s %s does not provide the extra '%s'", - self.base.name, - self.version, - extra, - ) - - for r in self.base.dist.iter_dependencies(valid_extras): - yield from factory.make_requirements_from_spec( - str(r), - self._comes_from, - valid_extras, - ) - - def get_install_requirement(self) -> InstallRequirement | None: - # We don't return anything here, because we always - # depend on the base candidate, and we'll get the - # install requirement from that. - return None - - -class RequiresPythonCandidate(Candidate): - is_installed = False - source_link = None - - def __init__(self, py_version_info: tuple[int, ...] | None) -> None: - if py_version_info is not None: - version_info = normalize_version_info(py_version_info) - else: - version_info = sys.version_info[:3] - self._version = Version(".".join(str(c) for c in version_info)) - - # We don't need to implement __eq__() and __ne__() since there is always - # only one RequiresPythonCandidate in a resolution, i.e. the host Python. - # The built-in object.__eq__() and object.__ne__() do exactly what we want. - - def __str__(self) -> str: - return f"Python {self._version}" - - def __repr__(self) -> str: - return f"{self.__class__.__name__}({self._version!r})" - - @property - def project_name(self) -> NormalizedName: - return REQUIRES_PYTHON_IDENTIFIER - - @property - def name(self) -> str: - return REQUIRES_PYTHON_IDENTIFIER - - @property - def version(self) -> Version: - return self._version - - def format_for_error(self) -> str: - return f"Python {self.version}" - - def iter_dependencies(self, with_requires: bool) -> Iterable[Requirement | None]: - return () - - def get_install_requirement(self) -> InstallRequirement | None: - return None diff --git a/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/factory.py b/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/factory.py deleted file mode 100755 index c9fb839..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/factory.py +++ /dev/null @@ -1,901 +0,0 @@ -from __future__ import annotations - -import contextlib -import copy -import functools -import logging -from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence -from typing import ( - TYPE_CHECKING, - NamedTuple, - Protocol, - TypeVar, - cast, -) - -from pip._vendor.packaging.requirements import InvalidRequirement -from pip._vendor.packaging.specifiers import SpecifierSet -from pip._vendor.packaging.utils import NormalizedName, canonicalize_name -from pip._vendor.packaging.version import InvalidVersion, Version -from pip._vendor.resolvelib import ResolutionImpossible -from pip._vendor.rich.markup import escape - -from pip._internal.cache import CacheEntry, WheelCache -from pip._internal.exceptions import ( - DistributionNotFound, - InstallationError, - InvalidInstalledPackage, - MetadataInconsistent, - MetadataInvalid, - UnsupportedPythonVersion, - UnsupportedWheel, -) -from pip._internal.index.package_finder import PackageFinder -from pip._internal.metadata import BaseDistribution, get_default_environment -from pip._internal.models.link import Link -from pip._internal.models.wheel import Wheel -from pip._internal.operations.prepare import RequirementPreparer -from pip._internal.req.constructors import ( - install_req_drop_extras, - install_req_from_link_and_ireq, -) -from pip._internal.req.req_install import ( - InstallRequirement, - check_invalid_constraint_type, -) -from pip._internal.resolution.base import InstallRequirementProvider -from pip._internal.utils.compatibility_tags import get_supported -from pip._internal.utils.hashes import Hashes -from pip._internal.utils.packaging import get_requirement -from pip._internal.utils.virtualenv import running_under_virtualenv - -from .base import Candidate, Constraint, Requirement -from .candidates import ( - AlreadyInstalledCandidate, - BaseCandidate, - EditableCandidate, - ExtrasCandidate, - LinkCandidate, - RequiresPythonCandidate, - as_base_candidate, -) -from .found_candidates import FoundCandidates, IndexCandidateInfo -from .requirements import ( - ExplicitRequirement, - RequiresPythonRequirement, - SpecifierRequirement, - SpecifierWithoutExtrasRequirement, - UnsatisfiableRequirement, -) - -if TYPE_CHECKING: - - class ConflictCause(Protocol): - requirement: RequiresPythonRequirement - parent: Candidate - - -logger = logging.getLogger(__name__) - -C = TypeVar("C") -Cache = dict[Link, C] - - -class CollectedRootRequirements(NamedTuple): - requirements: list[Requirement] - constraints: dict[str, Constraint] - user_requested: dict[str, int] - - -class Factory: - def __init__( - self, - finder: PackageFinder, - preparer: RequirementPreparer, - make_install_req: InstallRequirementProvider, - wheel_cache: WheelCache | None, - use_user_site: bool, - force_reinstall: bool, - ignore_installed: bool, - ignore_requires_python: bool, - py_version_info: tuple[int, ...] | None = None, - ) -> None: - self._finder = finder - self.preparer = preparer - self._wheel_cache = wheel_cache - self._python_candidate = RequiresPythonCandidate(py_version_info) - self._make_install_req_from_spec = make_install_req - self._use_user_site = use_user_site - self._force_reinstall = force_reinstall - self._ignore_requires_python = ignore_requires_python - - self._build_failures: Cache[InstallationError] = {} - self._link_candidate_cache: Cache[LinkCandidate] = {} - self._editable_candidate_cache: Cache[EditableCandidate] = {} - self._installed_candidate_cache: dict[str, AlreadyInstalledCandidate] = {} - self._extras_candidate_cache: dict[ - tuple[int, frozenset[NormalizedName]], ExtrasCandidate - ] = {} - self._supported_tags_cache = get_supported() - - if not ignore_installed: - env = get_default_environment() - self._installed_dists = { - dist.canonical_name: dist - for dist in env.iter_installed_distributions(local_only=False) - } - else: - self._installed_dists = {} - - @property - def force_reinstall(self) -> bool: - return self._force_reinstall - - def _fail_if_link_is_unsupported_wheel(self, link: Link) -> None: - if not link.is_wheel: - return - wheel = Wheel(link.filename) - if wheel.supported(self._finder.target_python.get_unsorted_tags()): - return - msg = f"{link.filename} is not a supported wheel on this platform." - raise UnsupportedWheel(msg) - - def _make_extras_candidate( - self, - base: BaseCandidate, - extras: frozenset[str], - *, - comes_from: InstallRequirement | None = None, - ) -> ExtrasCandidate: - cache_key = (id(base), frozenset(canonicalize_name(e) for e in extras)) - try: - candidate = self._extras_candidate_cache[cache_key] - except KeyError: - candidate = ExtrasCandidate(base, extras, comes_from=comes_from) - self._extras_candidate_cache[cache_key] = candidate - return candidate - - def _make_candidate_from_dist( - self, - dist: BaseDistribution, - extras: frozenset[str], - template: InstallRequirement, - ) -> Candidate: - try: - base = self._installed_candidate_cache[dist.canonical_name] - except KeyError: - base = AlreadyInstalledCandidate(dist, template, factory=self) - self._installed_candidate_cache[dist.canonical_name] = base - if not extras: - return base - return self._make_extras_candidate(base, extras, comes_from=template) - - def _make_candidate_from_link( - self, - link: Link, - extras: frozenset[str], - template: InstallRequirement, - name: NormalizedName | None, - version: Version | None, - ) -> Candidate | None: - base: BaseCandidate | None = self._make_base_candidate_from_link( - link, template, name, version - ) - if not extras or base is None: - return base - return self._make_extras_candidate(base, extras, comes_from=template) - - def _make_base_candidate_from_link( - self, - link: Link, - template: InstallRequirement, - name: NormalizedName | None, - version: Version | None, - ) -> BaseCandidate | None: - # TODO: Check already installed candidate, and use it if the link and - # editable flag match. - - if link in self._build_failures: - # We already tried this candidate before, and it does not build. - # Don't bother trying again. - return None - - if template.editable: - if link not in self._editable_candidate_cache: - try: - self._editable_candidate_cache[link] = EditableCandidate( - link, - template, - factory=self, - name=name, - version=version, - ) - except (MetadataInconsistent, MetadataInvalid) as e: - logger.info( - "Discarding [blue underline]%s[/]: [yellow]%s[reset]", - escape(str(link)), - escape(str(e)), - extra={"markup": True}, - ) - self._build_failures[link] = e - return None - - return self._editable_candidate_cache[link] - else: - if link not in self._link_candidate_cache: - try: - self._link_candidate_cache[link] = LinkCandidate( - link, - template, - factory=self, - name=name, - version=version, - ) - except MetadataInconsistent as e: - logger.info( - "Discarding [blue underline]%s[/]: [yellow]%s[reset]", - escape(str(link)), - escape(str(e)), - extra={"markup": True}, - ) - self._build_failures[link] = e - return None - return self._link_candidate_cache[link] - - def _iter_found_candidates( - self, - ireqs: Sequence[InstallRequirement], - specifier: SpecifierSet, - hashes: Hashes, - prefers_installed: bool, - incompatible_ids: set[int], - constraint_hash_options: dict[str, list[str]] | None = None, - ) -> Iterable[Candidate]: - if not ireqs: - return () - - # The InstallRequirement implementation requires us to give it a - # "template". Here we just choose the first requirement to represent - # all of them. - # Hopefully the Project model can correct this mismatch in the future. - template = ireqs[0] - assert template.req, "Candidates found on index must be PEP 508" - if ( - constraint_hash_options - and not template.hash_options - and any(constraint_hash_options.values()) - ): - template = copy.copy(template) - template.hash_options = { - k: list(v) for k, v in constraint_hash_options.items() - } - assert template.req # to prevent mypy from being confused by the copy - name = canonicalize_name(template.req.name) - - extras: frozenset[str] = frozenset() - for ireq in ireqs: - assert ireq.req, "Candidates found on index must be PEP 508" - specifier &= ireq.req.specifier - hashes &= ireq.hashes(trust_internet=False) - extras |= frozenset(ireq.extras) - - def _get_installed_candidate() -> Candidate | None: - """Get the candidate for the currently-installed version.""" - # If --force-reinstall is set, we want the version from the index - # instead, so we "pretend" there is nothing installed. - if self._force_reinstall: - return None - try: - installed_dist = self._installed_dists[name] - except KeyError: - return None - - try: - # Don't use the installed distribution if its version - # does not fit the current dependency graph. - if not specifier.contains(installed_dist.version, prereleases=True): - return None - except InvalidVersion as e: - raise InvalidInstalledPackage(dist=installed_dist, invalid_exc=e) - - candidate = self._make_candidate_from_dist( - dist=installed_dist, - extras=extras, - template=template, - ) - # The candidate is a known incompatibility. Don't use it. - if id(candidate) in incompatible_ids: - return None - return candidate - - def iter_index_candidate_infos() -> Iterator[IndexCandidateInfo]: - result = self._finder.find_best_candidate( - project_name=name, - specifier=specifier, - hashes=hashes, - ) - icans = result.applicable_candidates - - # PEP 592: Yanked releases are ignored unless the specifier - # explicitly pins a version (via '==' or '===') that can be - # solely satisfied by a yanked release. - all_yanked = all(ican.link.is_yanked for ican in icans) - - def is_pinned(specifier: SpecifierSet) -> bool: - for sp in specifier: - if sp.operator == "===": - return True - if sp.operator != "==": - continue - if sp.version.endswith(".*"): - continue - return True - return False - - pinned = is_pinned(specifier) - - # PackageFinder returns earlier versions first, so we reverse. - for ican in reversed(icans): - if not (all_yanked and pinned) and ican.link.is_yanked: - continue - func = functools.partial( - self._make_candidate_from_link, - link=ican.link, - extras=extras, - template=template, - name=name, - version=ican.version, - ) - yield ican.version, func - - return FoundCandidates( - iter_index_candidate_infos, - _get_installed_candidate(), - prefers_installed, - incompatible_ids, - ) - - def _iter_explicit_candidates_from_base( - self, - base_requirements: Iterable[Requirement], - extras: frozenset[str], - ) -> Iterator[Candidate]: - """Produce explicit candidates from the base given an extra-ed package. - - :param base_requirements: Requirements known to the resolver. The - requirements are guaranteed to not have extras. - :param extras: The extras to inject into the explicit requirements' - candidates. - """ - for req in base_requirements: - lookup_cand, _ = req.get_candidate_lookup() - if lookup_cand is None: # Not explicit. - continue - # We've stripped extras from the identifier, and should always - # get a BaseCandidate here, unless there's a bug elsewhere. - base_cand = as_base_candidate(lookup_cand) - assert base_cand is not None, "no extras here" - yield self._make_extras_candidate(base_cand, extras) - - def _iter_candidates_from_constraints( - self, - identifier: str, - constraint: Constraint, - template: InstallRequirement, - ) -> Iterator[Candidate]: - """Produce explicit candidates from constraints. - - This creates "fake" InstallRequirement objects that are basically clones - of what "should" be the template, but with original_link set to link. - """ - extras: frozenset[str] = frozenset() - base_identifier = identifier - with contextlib.suppress(InvalidRequirement): - parsed_requirement = get_requirement(identifier) - if parsed_requirement.name != identifier: - base_identifier = canonicalize_name(parsed_requirement.name) - extras = frozenset(parsed_requirement.extras) - - for link in constraint.links: - self._fail_if_link_is_unsupported_wheel(link) - base_candidate = self._make_base_candidate_from_link( - link, - template=install_req_from_link_and_ireq(link, template), - name=canonicalize_name(base_identifier), - version=None, - ) - if base_candidate is None: - continue - if extras: - yield self._make_extras_candidate(base_candidate, extras) - else: - yield base_candidate - - def find_candidates( - self, - identifier: str, - requirements: Mapping[str, Iterable[Requirement]], - incompatibilities: Mapping[str, Iterator[Candidate]], - constraint: Constraint, - prefers_installed: bool, - is_satisfied_by: Callable[[Requirement, Candidate], bool], - ) -> Iterable[Candidate]: - # Collect basic lookup information from the requirements. - explicit_candidates: set[Candidate] = set() - ireqs: list[InstallRequirement] = [] - for req in requirements[identifier]: - cand, ireq = req.get_candidate_lookup() - if cand is not None: - explicit_candidates.add(cand) - if ireq is not None: - ireqs.append(ireq) - - # If the current identifier contains extras, add requires and explicit - # candidates from entries from extra-less identifier. - with contextlib.suppress(InvalidRequirement): - parsed_requirement = get_requirement(identifier) - if parsed_requirement.name != identifier: - explicit_candidates.update( - self._iter_explicit_candidates_from_base( - requirements.get(parsed_requirement.name, ()), - frozenset(parsed_requirement.extras), - ), - ) - for req in requirements.get(parsed_requirement.name, []): - _, ireq = req.get_candidate_lookup() - if ireq is not None: - ireqs.append(ireq) - - # Add explicit candidates from constraints. We only do this if there are - # known ireqs, which represent requirements not already explicit. If - # there are no ireqs, we're constraining already-explicit requirements, - # which is handled later when we return the explicit candidates. - if ireqs: - try: - explicit_candidates.update( - self._iter_candidates_from_constraints( - identifier, - constraint, - template=ireqs[0], - ), - ) - except UnsupportedWheel: - # If we're constrained to install a wheel incompatible with the - # target architecture, no candidates will ever be valid. - return () - - # Since we cache all the candidates, incompatibility identification - # can be made quicker by comparing only the id() values. - incompat_ids = {id(c) for c in incompatibilities.get(identifier, ())} - - # If none of the requirements want an explicit candidate, we can ask - # the finder for candidates. - if not explicit_candidates: - return self._iter_found_candidates( - ireqs, - constraint.specifier, - constraint.hashes, - prefers_installed, - incompat_ids, - constraint.hash_options, - ) - - return ( - c - for c in explicit_candidates - if id(c) not in incompat_ids - and constraint.is_satisfied_by(c) - and all(is_satisfied_by(req, c) for req in requirements[identifier]) - ) - - def _make_requirements_from_install_req( - self, ireq: InstallRequirement, requested_extras: Iterable[str] - ) -> Iterator[Requirement]: - """ - Returns requirement objects associated with the given InstallRequirement. In - most cases this will be a single object but the following special cases exist: - - the InstallRequirement has markers that do not apply -> result is empty - - the InstallRequirement has both a constraint (or link) and extras - -> result is split in two requirement objects: one with the constraint - (or link) and one with the extra. This allows centralized constraint - handling for the base, resulting in fewer candidate rejections. - """ - if not ireq.match_markers(requested_extras): - logger.info( - "Ignoring %s: markers '%s' don't match your environment", - ireq.name, - ireq.markers, - ) - elif not ireq.link: - if ireq.extras and ireq.req is not None and ireq.req.specifier: - yield SpecifierWithoutExtrasRequirement(ireq) - yield SpecifierRequirement(ireq) - else: - self._fail_if_link_is_unsupported_wheel(ireq.link) - # Always make the link candidate for the base requirement to make it - # available to `find_candidates` for explicit candidate lookup for any - # set of extras. - # The extras are required separately via a second requirement. - cand = self._make_base_candidate_from_link( - ireq.link, - template=install_req_drop_extras(ireq) if ireq.extras else ireq, - name=canonicalize_name(ireq.name) if ireq.name else None, - version=None, - ) - if cand is None: - # There's no way we can satisfy a URL requirement if the underlying - # candidate fails to build. An unnamed URL must be user-supplied, so - # we fail eagerly. If the URL is named, an unsatisfiable requirement - # can make the resolver do the right thing, either backtrack (and - # maybe find some other requirement that's buildable) or raise a - # ResolutionImpossible eventually. - if not ireq.name: - raise self._build_failures[ireq.link] - yield UnsatisfiableRequirement(canonicalize_name(ireq.name)) - else: - # require the base from the link - yield self.make_requirement_from_candidate(cand) - if ireq.extras: - # require the extras on top of the base candidate - yield self.make_requirement_from_candidate( - self._make_extras_candidate(cand, frozenset(ireq.extras)) - ) - - def collect_root_requirements( - self, root_ireqs: list[InstallRequirement] - ) -> CollectedRootRequirements: - collected = CollectedRootRequirements([], {}, {}) - for i, ireq in enumerate(root_ireqs): - if ireq.constraint: - # Ensure we only accept valid constraints - problem = check_invalid_constraint_type(ireq) - if problem: - raise InstallationError(problem) - if not ireq.match_markers(): - continue - assert ireq.name, "Constraint must be named" - name = canonicalize_name(ireq.name) - if name in collected.constraints: - collected.constraints[name] &= ireq - else: - collected.constraints[name] = Constraint.from_ireq(ireq) - else: - reqs = list( - self._make_requirements_from_install_req( - ireq, - requested_extras=(), - ) - ) - if not reqs: - continue - template = reqs[0] - if ireq.user_supplied and template.name not in collected.user_requested: - collected.user_requested[template.name] = i - collected.requirements.extend(reqs) - # Put requirements with extras at the end of the root requires. This does not - # affect resolvelib's picking preference but it does affect its initial criteria - # population: by putting extras at the end we enable the candidate finder to - # present resolvelib with a smaller set of candidates to resolvelib, already - # taking into account any non-transient constraints on the associated base. This - # means resolvelib will have fewer candidates to visit and reject. - # Python's list sort is stable, meaning relative order is kept for objects with - # the same key. - collected.requirements.sort(key=lambda r: r.name != r.project_name) - return collected - - def make_requirement_from_candidate( - self, candidate: Candidate - ) -> ExplicitRequirement: - return ExplicitRequirement(candidate) - - def make_requirements_from_spec( - self, - specifier: str, - comes_from: InstallRequirement | None, - requested_extras: Iterable[str] = (), - ) -> Iterator[Requirement]: - """ - Returns requirement objects associated with the given specifier. In most cases - this will be a single object but the following special cases exist: - - the specifier has markers that do not apply -> result is empty - - the specifier has both a constraint and extras -> result is split - in two requirement objects: one with the constraint and one with the - extra. This allows centralized constraint handling for the base, - resulting in fewer candidate rejections. - """ - ireq = self._make_install_req_from_spec(specifier, comes_from) - return self._make_requirements_from_install_req(ireq, requested_extras) - - def make_requires_python_requirement( - self, - specifier: SpecifierSet, - ) -> Requirement | None: - if self._ignore_requires_python: - return None - # Don't bother creating a dependency for an empty Requires-Python. - if not str(specifier): - return None - return RequiresPythonRequirement(specifier, self._python_candidate) - - def get_wheel_cache_entry(self, link: Link, name: str | None) -> CacheEntry | None: - """Look up the link in the wheel cache. - - If ``preparer.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 - nondeterministic contents due to file modification times. - """ - if self._wheel_cache is None: - return None - return self._wheel_cache.get_cache_entry( - link=link, - package_name=name, - supported_tags=self._supported_tags_cache, - ) - - def get_dist_to_uninstall(self, candidate: Candidate) -> BaseDistribution | None: - # TODO: Are there more cases this needs to return True? Editable? - dist = self._installed_dists.get(candidate.project_name) - if dist is None: # Not installed, no uninstallation required. - return None - - # We're installing into global site. The current installation must - # be uninstalled, no matter it's in global or user site, because the - # user site installation has precedence over global. - if not self._use_user_site: - return dist - - # We're installing into user site. Remove the user site installation. - if dist.in_usersite: - return dist - - # We're installing into user site, but the installed incompatible - # package is in global site. We can't uninstall that, and would let - # the new user installation to "shadow" it. But shadowing won't work - # in virtual environments, so we error out. - if running_under_virtualenv() and dist.in_site_packages: - message = ( - f"Will not install to the user site because it will lack " - f"sys.path precedence to {dist.raw_name} in {dist.location}" - ) - raise InstallationError(message) - return None - - def _report_requires_python_error( - self, causes: Sequence[ConflictCause] - ) -> UnsupportedPythonVersion: - assert causes, "Requires-Python error reported with no cause" - - version = self._python_candidate.version - - if len(causes) == 1: - specifier = str(causes[0].requirement.specifier) - message = ( - f"Package {causes[0].parent.name!r} requires a different " - f"Python: {version} not in {specifier!r}" - ) - return UnsupportedPythonVersion(message) - - message = f"Packages require a different Python. {version} not in:" - for cause in causes: - package = cause.parent.format_for_error() - specifier = str(cause.requirement.specifier) - message += f"\n{specifier!r} (required by {package})" - return UnsupportedPythonVersion(message) - - def _report_single_requirement_conflict( - self, req: Requirement, parent: Candidate | None - ) -> DistributionNotFound: - if parent is None: - req_disp = str(req) - else: - req_disp = f"{req} (from {parent.name})" - - cands = self._finder.find_all_candidates(req.project_name) - skipped_by_requires_python = self._finder.requires_python_skipped_reasons() - - versions_set: set[Version] = set() - yanked_versions_set: set[Version] = set() - for c in cands: - is_yanked = c.link.is_yanked if c.link else False - if is_yanked: - yanked_versions_set.add(c.version) - else: - versions_set.add(c.version) - - versions = [str(v) for v in sorted(versions_set)] - yanked_versions = [str(v) for v in sorted(yanked_versions_set)] - - if yanked_versions: - # Saying "version X is yanked" isn't entirely accurate. - # https://github.com/pypa/pip/issues/11745#issuecomment-1402805842 - logger.critical( - "Ignored the following yanked versions: %s", - ", ".join(yanked_versions) or "none", - ) - if skipped_by_requires_python: - logger.critical( - "Ignored the following versions that require a different python " - "version: %s", - "; ".join(skipped_by_requires_python) or "none", - ) - - # Check if only final releases are allowed for this package - version_type = "version" - allows_pre = None - if self._finder.release_control is not None: - allows_pre = self._finder.release_control.allows_prereleases( - canonicalize_name(req.project_name) - ) - if allows_pre is False: - version_type = "final version" - - if len(cands) == 1 and cands[0].locked: - # The package finder ensures that requirements from pylock files - # have exactly one candidate. So we can provide a specific error - # message in this case. - if cands[0].version.is_prerelease and allows_pre is False: - logger.critical( - "A pre-release version %s is specified in a provided lock file " - "for %s but only final versions are allowed", - cands[0].version, - cands[0].name, - ) - else: - logger.critical( - "The requirement %s is not compatible with " - "version %s specified in a provided lock file", - req_disp, - ", ".join(versions), - ) - else: - logger.critical( - "Could not find a %s that satisfies the requirement %s " - "(from versions: %s)", - version_type, - req_disp, - ", ".join(versions) or "none", - ) - if str(req) == "requirements.txt": - logger.info( - "HINT: You are attempting to install a package literally " - 'named "requirements.txt" (which cannot exist). Consider ' - "using the '-r' flag to install the packages listed in " - "requirements.txt" - ) - - return DistributionNotFound(f"No matching distribution found for {req}") - - def _has_any_candidates(self, project_name: str) -> bool: - """ - Check if there are any candidates available for the project name. - """ - return any( - self.find_candidates( - project_name, - requirements={project_name: []}, - incompatibilities={}, - constraint=Constraint.empty(), - prefers_installed=True, - is_satisfied_by=lambda r, c: True, - ) - ) - - def get_installation_error( - self, - e: ResolutionImpossible[Requirement, Candidate], - constraints: dict[str, Constraint], - ) -> InstallationError: - assert e.causes, "Installation error reported with no cause" - - # If one of the things we can't solve is "we need Python X.Y", - # that is what we report. - requires_python_causes = [ - cause - for cause in e.causes - if isinstance(cause.requirement, RequiresPythonRequirement) - and not cause.requirement.is_satisfied_by(self._python_candidate) - ] - if requires_python_causes: - # The comprehension above makes sure all Requirement instances are - # RequiresPythonRequirement, so let's cast for convenience. - return self._report_requires_python_error( - cast("Sequence[ConflictCause]", requires_python_causes), - ) - - # Otherwise, we have a set of causes which can't all be satisfied - # at once. - - # The simplest case is when we have *one* cause that can't be - # satisfied. We just report that case. - if len(e.causes) == 1: - req, parent = next(iter(e.causes)) - if req.name not in constraints: - return self._report_single_requirement_conflict(req, parent) - - # OK, we now have a list of requirements that can't all be - # satisfied at once. - - # A couple of formatting helpers - def text_join(parts: list[str]) -> str: - if len(parts) == 1: - return parts[0] - - return ", ".join(parts[:-1]) + " and " + parts[-1] - - def describe_trigger(parent: Candidate) -> str: - ireq = parent.get_install_requirement() - if not ireq or not ireq.comes_from: - return f"{parent.name}=={parent.version}" - if isinstance(ireq.comes_from, InstallRequirement): - return str(ireq.comes_from.name) - return str(ireq.comes_from) - - triggers = set() - for req, parent in e.causes: - if parent is None: - # This is a root requirement, so we can report it directly - trigger = req.format_for_error() - else: - trigger = describe_trigger(parent) - triggers.add(trigger) - - if triggers: - info = text_join(sorted(triggers)) - else: - info = "the requested packages" - - msg = ( - f"Cannot install {info} because these package versions " - "have conflicting dependencies." - ) - logger.critical(msg) - msg = "\nThe conflict is caused by:" - - relevant_constraints = set() - for req, parent in e.causes: - if req.name in constraints: - relevant_constraints.add(req.name) - msg = msg + "\n " - if parent: - msg = msg + f"{parent.name} {parent.version} depends on " - else: - msg = msg + "The user requested " - msg = msg + req.format_for_error() - for key in relevant_constraints: - constraint_text = f"{key}{constraints[key].format_for_error()}" - msg += f"\n The user requested (constraint) {constraint_text}" - - # Check for causes that had no candidates - causes = set() - for req, _ in e.causes: - causes.add(req.name) - - no_candidates = {c for c in causes if not self._has_any_candidates(c)} - if no_candidates: - msg = ( - msg - + "\n\n" - + "Additionally, some packages in these conflicts have no " - + "matching distributions available for your environment:" - + "\n " - + "\n ".join(sorted(no_candidates)) - ) - - msg = ( - msg - + "\n\n" - + "To fix this you could try to:\n" - + "1. loosen the range of package versions you've specified\n" - + "2. remove package versions to allow pip to attempt to solve " - + "the dependency conflict\n" - ) - - logger.info(msg) - - return DistributionNotFound( - "ResolutionImpossible: for help visit " - "https://pip.pypa.io/en/latest/topics/dependency-resolution/" - "#dealing-with-dependency-conflicts" - ) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py b/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py deleted file mode 100755 index 6701673..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py +++ /dev/null @@ -1,166 +0,0 @@ -"""Utilities to lazily create and visit candidates found. - -Creating and visiting a candidate is a *very* costly operation. It involves -fetching, extracting, potentially building modules from source, and verifying -distribution metadata. It is therefore crucial for performance to keep -everything here lazy all the way down, so we only touch candidates that we -absolutely need, and not "download the world" when we only need one version of -something. -""" - -from __future__ import annotations - -import logging -from collections.abc import Callable, Iterator, Sequence -from typing import Any - -from pip._vendor.packaging.version import _BaseVersion - -from pip._internal.exceptions import MetadataInvalid - -from .base import Candidate - -logger = logging.getLogger(__name__) - -IndexCandidateInfo = tuple[_BaseVersion, Callable[[], Candidate | None]] - - -def _iter_built(infos: Iterator[IndexCandidateInfo]) -> Iterator[Candidate]: - """Iterator for ``FoundCandidates``. - - This iterator is used when the package is not already installed. Candidates - from index come later in their normal ordering. - """ - versions_found: set[_BaseVersion] = set() - for version, func in infos: - if version in versions_found: - continue - try: - candidate = func() - except MetadataInvalid as e: - logger.warning( - "Ignoring version %s of %s since it has invalid metadata:\n" - "%s\n" - "Please use pip<24.1 if you need to use this version.", - version, - e.ireq.name, - e, - ) - # Mark version as found to avoid trying other candidates with the same - # version, since they most likely have invalid metadata as well. - versions_found.add(version) - else: - if candidate is None: - continue - yield candidate - versions_found.add(version) - - -def _iter_built_with_prepended( - installed: Candidate, infos: Iterator[IndexCandidateInfo] -) -> Iterator[Candidate]: - """Iterator for ``FoundCandidates``. - - This iterator is used when the resolver prefers the already-installed - candidate and NOT to upgrade. The installed candidate is therefore - always yielded first, and candidates from index come later in their - normal ordering, except skipped when the version is already installed. - """ - yield installed - versions_found: set[_BaseVersion] = {installed.version} - for version, func in infos: - if version in versions_found: - continue - candidate = func() - if candidate is None: - continue - yield candidate - versions_found.add(version) - - -def _iter_built_with_inserted( - installed: Candidate, infos: Iterator[IndexCandidateInfo] -) -> Iterator[Candidate]: - """Iterator for ``FoundCandidates``. - - This iterator is used when the resolver prefers to upgrade an - already-installed package. Candidates from index are returned in their - normal ordering, except replaced when the version is already installed. - - The implementation iterates through and yields other candidates, inserting - the installed candidate exactly once before we start yielding older or - equivalent candidates, or after all other candidates if they are all newer. - """ - versions_found: set[_BaseVersion] = set() - for version, func in infos: - if version in versions_found: - continue - # If the installed candidate is better, yield it first. - if installed.version >= version: - yield installed - versions_found.add(installed.version) - candidate = func() - if candidate is None: - continue - yield candidate - versions_found.add(version) - - # If the installed candidate is older than all other candidates. - if installed.version not in versions_found: - yield installed - - -class FoundCandidates(Sequence[Candidate]): - """A lazy sequence to provide candidates to the resolver. - - The intended usage is to return this from `find_matches()` so the resolver - can iterate through the sequence multiple times, but only access the index - page when remote packages are actually needed. This improve performances - when suitable candidates are already installed on disk. - """ - - def __init__( - self, - get_infos: Callable[[], Iterator[IndexCandidateInfo]], - installed: Candidate | None, - prefers_installed: bool, - incompatible_ids: set[int], - ): - self._get_infos = get_infos - self._installed = installed - self._prefers_installed = prefers_installed - self._incompatible_ids = incompatible_ids - self._bool: bool | None = None - - def __getitem__(self, index: Any) -> Any: - # Implemented to satisfy the ABC check. This is not needed by the - # resolver, and should not be used by the provider either (for - # performance reasons). - raise NotImplementedError("don't do this") - - def __iter__(self) -> Iterator[Candidate]: - infos = self._get_infos() - if not self._installed: - iterator = _iter_built(infos) - elif self._prefers_installed: - iterator = _iter_built_with_prepended(self._installed, infos) - else: - iterator = _iter_built_with_inserted(self._installed, infos) - return (c for c in iterator if id(c) not in self._incompatible_ids) - - def __len__(self) -> int: - # Implemented to satisfy the ABC check. This is not needed by the - # resolver, and should not be used by the provider either (for - # performance reasons). - raise NotImplementedError("don't do this") - - def __bool__(self) -> bool: - if self._bool is not None: - return self._bool - - if self._prefers_installed and self._installed: - self._bool = True - return True - - self._bool = any(self) - return self._bool diff --git a/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/provider.py b/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/provider.py deleted file mode 100755 index 766fa84..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/provider.py +++ /dev/null @@ -1,309 +0,0 @@ -from __future__ import annotations - -import math -from collections import defaultdict -from collections.abc import Iterable, Iterator, Mapping, Sequence -from functools import cache -from typing import ( - TYPE_CHECKING, - TypeVar, -) - -from pip._vendor.resolvelib.providers import AbstractProvider - -from pip._internal.req.req_install import InstallRequirement - -from .base import Candidate, Constraint, Requirement -from .candidates import REQUIRES_PYTHON_IDENTIFIER -from .factory import Factory -from .requirements import ExplicitRequirement - -if TYPE_CHECKING: - from pip._vendor.resolvelib.providers import Preference - from pip._vendor.resolvelib.resolvers import RequirementInformation - - PreferenceInformation = RequirementInformation[Requirement, Candidate] - - _ProviderBase = AbstractProvider[Requirement, Candidate, str] -else: - _ProviderBase = AbstractProvider - -_CONFLICT_PRIORITY_THRESHOLD = 5 - -# Notes on the relationship between the provider, the factory, and the -# candidate and requirement classes. -# -# The provider is a direct implementation of the resolvelib class. Its role -# is to deliver the API that resolvelib expects. -# -# Rather than work with completely abstract "requirement" and "candidate" -# concepts as resolvelib does, pip has concrete classes implementing these two -# ideas. The API of Requirement and Candidate objects are defined in the base -# classes, but essentially map fairly directly to the equivalent provider -# methods. In particular, `find_matches` and `is_satisfied_by` are -# requirement methods, and `get_dependencies` is a candidate method. -# -# The factory is the interface to pip's internal mechanisms. It is stateless, -# and is created by the resolver and held as a property of the provider. It is -# responsible for creating Requirement and Candidate objects, and provides -# services to those objects (access to pip's finder and preparer). - - -D = TypeVar("D") -V = TypeVar("V") - - -def _get_with_identifier( - mapping: Mapping[str, V], - identifier: str, - default: D, -) -> D | V: - """Get item from a package name lookup mapping with a resolver identifier. - - This extra logic is needed when the target mapping is keyed by package - name, which cannot be directly looked up with an identifier (which may - contain requested extras). Additional logic is added to also look up a value - by "cleaning up" the extras from the identifier. - """ - if identifier in mapping: - return mapping[identifier] - # HACK: Theoretically we should check whether this identifier is a valid - # "NAME[EXTRAS]" format, and parse out the name part with packaging or - # some regular expression. But since pip's resolver only spits out three - # kinds of identifiers: normalized PEP 503 names, normalized names plus - # extras, and Requires-Python, we can cheat a bit here. - name, open_bracket, _ = identifier.partition("[") - if open_bracket and name in mapping: - return mapping[name] - return default - - -class PipProvider(_ProviderBase): - """Pip's provider implementation for resolvelib. - - :params constraints: A mapping of constraints specified by the user. Keys - are canonicalized project names. - :params ignore_dependencies: Whether the user specified ``--no-deps``. - :params only_dependencies: Whether the user specified ``--only-deps``. - :params upgrade_strategy: The user-specified upgrade strategy. - :params user_requested: A set of canonicalized package names that the user - supplied for pip to install/upgrade. - """ - - def __init__( - self, - factory: Factory, - constraints: dict[str, Constraint], - ignore_dependencies: bool, - only_dependencies: bool, - upgrade_strategy: str, - user_requested: dict[str, int], - ) -> None: - self._factory = factory - self._constraints = constraints - self._ignore_dependencies = ignore_dependencies - self._only_dependencies = only_dependencies - self._upgrade_strategy = upgrade_strategy - self._user_requested = user_requested - self._conflict_counts: defaultdict[str, int] = defaultdict(int) - self._conflict_promoted: set[str] = set() - - @property - def constraints(self) -> dict[str, Constraint]: - """Public view of user-specified constraints. - - Exposes the provider's constraints mapping without encouraging - external callers to reach into private attributes. - """ - return self._constraints - - def identify(self, requirement_or_candidate: Requirement | Candidate) -> str: - return requirement_or_candidate.name - - def narrow_requirement_selection( - self, - identifiers: Iterable[str], - resolutions: Mapping[str, Candidate], - candidates: Mapping[str, Iterator[Candidate]], - information: Mapping[str, Iterator[PreferenceInformation]], - backtrack_causes: Sequence[PreferenceInformation], - ) -> Iterable[str]: - """Produce a subset of identifiers that should be considered before others. - - Currently pip narrows the following selection: - * Requires-Python, if present is always returned by itself - * Backtrack causes are considered next because they can be identified - in linear time here, whereas because get_preference() is called - for each identifier, it would be quadratic to check for them there. - Further, the current backtrack causes likely need to be resolved - before other requirements as a resolution can't be found while - there is a conflict. - * Identifiers that repeatedly appear as not-yet-pinned in conflicts - get promoted so they are resolved earlier. This lets their - constraints take effect before other packages pick a version. - """ - backtrack_identifiers = set() - for info in backtrack_causes: - names = [info.requirement.name] - if info.parent is not None: - names.append(info.parent.name) - for name in names: - backtrack_identifiers.add(name) - if name not in resolutions: - self._conflict_counts[name] += 1 - if self._conflict_counts[name] >= _CONFLICT_PRIORITY_THRESHOLD: - self._conflict_promoted.add(name) - - current_backtrack_causes = [] - promoted = [] - for identifier in identifiers: - if identifier == REQUIRES_PYTHON_IDENTIFIER: - return [identifier] - - if identifier in backtrack_identifiers: - current_backtrack_causes.append(identifier) - continue - - if identifier in self._conflict_promoted: - promoted.append(identifier) - continue - - if current_backtrack_causes: - return current_backtrack_causes - - if promoted: - return promoted - - return identifiers - - def get_preference( - self, - identifier: str, - resolutions: Mapping[str, Candidate], - candidates: Mapping[str, Iterator[Candidate]], - information: Mapping[str, Iterable[PreferenceInformation]], - backtrack_causes: Sequence[PreferenceInformation], - ) -> Preference: - """Produce a sort key for given requirement based on preference. - - The lower the return value is, the more preferred this group of - arguments is. - - Currently pip considers the following in order: - - * Any requirement that is "direct", e.g., points to an explicit URL. - * Any requirement that is "pinned", i.e., contains the operator ``===`` - or ``==`` without a wildcard. - * Any requirement that imposes an upper version limit, i.e., contains the - operator ``<``, ``<=``, ``~=``, or ``==`` with a wildcard. Because - pip prioritizes the latest version, preferring explicit upper bounds - can rule out infeasible candidates sooner. This does not imply that - upper bounds are good practice; they can make dependency management - and resolution harder. - * Order user-specified requirements as they are specified, placing - other requirements afterward. - * Any "non-free" requirement, i.e., one that contains at least one - operator, such as ``>=`` or ``!=``. - * Alphabetical order for consistency (aids debuggability). - """ - try: - next(iter(information[identifier])) - except StopIteration: - # There is no information for this identifier, so there's no known - # candidates. - has_information = False - else: - has_information = True - - if not has_information: - direct = False - ireqs: tuple[InstallRequirement | None, ...] = () - else: - # Go through the information and for each requirement, - # check if it's explicit (e.g., a direct link) and get the - # InstallRequirement (the second element) from get_candidate_lookup() - directs, ireqs = zip( - *( - (isinstance(r, ExplicitRequirement), r.get_candidate_lookup()[1]) - for r, _ in information[identifier] - ) - ) - direct = any(directs) - - operators: list[tuple[str, str]] = [ - (specifier.operator, specifier.version) - for specifier_set in (ireq.specifier for ireq in ireqs if ireq) - for specifier in specifier_set - ] - - pinned = any(((op[:2] == "==") and ("*" not in ver)) for op, ver in operators) - upper_bounded = any( - ((op in ("<", "<=", "~=")) or (op == "==" and "*" in ver)) - for op, ver in operators - ) - unfree = bool(operators) - requested_order = self._user_requested.get(identifier, math.inf) - - conflict_promoted = identifier in self._conflict_promoted - - return ( - not conflict_promoted, - not direct, - not pinned, - not upper_bounded, - requested_order, - not unfree, - identifier, - ) - - def find_matches( - self, - identifier: str, - requirements: Mapping[str, Iterator[Requirement]], - incompatibilities: Mapping[str, Iterator[Candidate]], - ) -> Iterable[Candidate]: - def _eligible_for_upgrade(identifier: str) -> bool: - """Are upgrades allowed for this project? - - This checks the upgrade strategy, and whether the project was one - that the user specified in the command line, in order to decide - whether we should upgrade if there's a newer version available. - - (Note that we don't need access to the `--upgrade` flag, because - an upgrade strategy of "to-satisfy-only" means that `--upgrade` - was not specified). - """ - if self._upgrade_strategy == "eager": - return True - elif self._upgrade_strategy == "only-if-needed": - user_order = _get_with_identifier( - self._user_requested, - identifier, - default=None, - ) - return user_order is not None - return False - - constraint = _get_with_identifier( - self._constraints, - identifier, - default=Constraint.empty(), - ) - return self._factory.find_candidates( - identifier=identifier, - requirements=requirements, - constraint=constraint, - prefers_installed=(not _eligible_for_upgrade(identifier)), - incompatibilities=incompatibilities, - is_satisfied_by=self.is_satisfied_by, - ) - - @staticmethod - @cache - def is_satisfied_by(requirement: Requirement, candidate: Candidate) -> bool: - return requirement.is_satisfied_by(candidate) - - def get_dependencies(self, candidate: Candidate) -> Iterable[Requirement]: - with_requires = not self._ignore_dependencies - # iter_dependencies() can perform nontrivial work so delay until needed. - return (r for r in candidate.iter_dependencies(with_requires) if r is not None) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/reporter.py b/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/reporter.py deleted file mode 100755 index de0deb2..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/reporter.py +++ /dev/null @@ -1,98 +0,0 @@ -from __future__ import annotations - -from collections import defaultdict -from collections.abc import Mapping -from logging import getLogger -from typing import Any - -from pip._vendor.resolvelib.reporters import BaseReporter - -from .base import Candidate, Constraint, Requirement - -logger = getLogger(__name__) - - -class PipReporter(BaseReporter[Requirement, Candidate, str]): - def __init__(self, constraints: Mapping[str, Constraint] | None = None) -> None: - self.reject_count_by_package: defaultdict[str, int] = defaultdict(int) - self._constraints = constraints or {} - - self._messages_at_reject_count = { - 1: ( - "pip is looking at multiple versions of {package_name} to " - "determine which version is compatible with other " - "requirements. This could take a while." - ), - 8: ( - "pip is still looking at multiple versions of {package_name} to " - "determine which version is compatible with other " - "requirements. This could take a while." - ), - 13: ( - "This is taking longer than usual. You might need to provide " - "the dependency resolver with stricter constraints to reduce " - "runtime. See https://pip.pypa.io/warnings/backtracking for " - "guidance. If you want to abort this run, press Ctrl + C." - ), - } - - def rejecting_candidate(self, criterion: Any, candidate: Candidate) -> None: - """Report a candidate being rejected. - - Logs both the rejection count message (if applicable) and details about - the requirements and constraints that caused the rejection. - """ - self.reject_count_by_package[candidate.name] += 1 - - count = self.reject_count_by_package[candidate.name] - if count in self._messages_at_reject_count: - message = self._messages_at_reject_count[count] - logger.info("INFO: %s", message.format(package_name=candidate.name)) - - msg = "Will try a different candidate, due to conflict:" - for req_info in criterion.information: - req, parent = req_info.requirement, req_info.parent - msg += "\n " - if parent: - msg += f"{parent.name} {parent.version} depends on " - else: - msg += "The user requested " - msg += req.format_for_error() - - # Add any relevant constraints - if self._constraints: - name = candidate.name - constraint = self._constraints.get(name) - if constraint and constraint.specifier: - constraint_text = f"{name}{constraint.format_for_error()}" - msg += f"\n The user requested (constraint) {constraint_text}" - - logger.debug(msg) - - -class PipDebuggingReporter(BaseReporter[Requirement, Candidate, str]): - """A reporter that does an info log for every event it sees.""" - - def starting(self) -> None: - logger.info("Reporter.starting()") - - def starting_round(self, index: int) -> None: - logger.info("Reporter.starting_round(%r)", index) - - def ending_round(self, index: int, state: Any) -> None: - logger.info("Reporter.ending_round(%r, state)", index) - logger.debug("Reporter.ending_round(%r, %r)", index, state) - - def ending(self, state: Any) -> None: - logger.info("Reporter.ending(%r)", state) - - def adding_requirement( - self, requirement: Requirement, parent: Candidate | None - ) -> None: - logger.info("Reporter.adding_requirement(%r, %r)", requirement, parent) - - def rejecting_candidate(self, criterion: Any, candidate: Candidate) -> None: - logger.info("Reporter.rejecting_candidate(%r, %r)", criterion, candidate) - - def pinning(self, candidate: Candidate) -> None: - logger.info("Reporter.pinning(%r)", candidate) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/requirements.py b/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/requirements.py deleted file mode 100755 index 9c5e233..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/requirements.py +++ /dev/null @@ -1,251 +0,0 @@ -from __future__ import annotations - -from typing import Any - -from pip._vendor.packaging.specifiers import SpecifierSet -from pip._vendor.packaging.utils import NormalizedName, canonicalize_name - -from pip._internal.req.constructors import install_req_drop_extras -from pip._internal.req.req_install import InstallRequirement - -from .base import Candidate, CandidateLookup, Requirement, format_name - - -class ExplicitRequirement(Requirement): - def __init__(self, candidate: Candidate) -> None: - self.candidate = candidate - - def __str__(self) -> str: - return str(self.candidate) - - def __repr__(self) -> str: - return f"{self.__class__.__name__}({self.candidate!r})" - - def __hash__(self) -> int: - return hash(self.candidate) - - def __eq__(self, other: Any) -> bool: - if not isinstance(other, ExplicitRequirement): - return False - return self.candidate == other.candidate - - @property - def project_name(self) -> NormalizedName: - # No need to canonicalize - the candidate did this - return self.candidate.project_name - - @property - def name(self) -> str: - # No need to canonicalize - the candidate did this - return self.candidate.name - - def format_for_error(self) -> str: - return self.candidate.format_for_error() - - def get_candidate_lookup(self) -> CandidateLookup: - return self.candidate, None - - def is_satisfied_by(self, candidate: Candidate) -> bool: - return candidate == self.candidate - - -class SpecifierRequirement(Requirement): - def __init__(self, ireq: InstallRequirement) -> None: - assert ireq.link is None, "This is a link, not a specifier" - self._ireq = ireq - self._equal_cache: str | None = None - self._hash: int | None = None - self._extras = frozenset(canonicalize_name(e) for e in self._ireq.extras) - - @property - def _equal(self) -> str: - if self._equal_cache is not None: - return self._equal_cache - - self._equal_cache = str(self._ireq) - return self._equal_cache - - def __str__(self) -> str: - return str(self._ireq.req) - - def __repr__(self) -> str: - return f"{self.__class__.__name__}({str(self._ireq.req)!r})" - - def __eq__(self, other: object) -> bool: - if not isinstance(other, SpecifierRequirement): - return NotImplemented - return self._equal == other._equal - - def __hash__(self) -> int: - if self._hash is not None: - return self._hash - - self._hash = hash(self._equal) - return self._hash - - @property - def project_name(self) -> NormalizedName: - assert self._ireq.req, "Specifier-backed ireq is always PEP 508" - return canonicalize_name(self._ireq.req.name) - - @property - def name(self) -> str: - return format_name(self.project_name, self._extras) - - def format_for_error(self) -> str: - # Convert comma-separated specifiers into "A, B, ..., F and G" - # This makes the specifier a bit more "human readable", without - # risking a change in meaning. (Hopefully! Not all edge cases have - # been checked) - parts = [s.strip() for s in str(self).split(",")] - if len(parts) == 0: - return "" - elif len(parts) == 1: - return parts[0] - - return ", ".join(parts[:-1]) + " and " + parts[-1] - - def get_candidate_lookup(self) -> CandidateLookup: - return None, self._ireq - - def is_satisfied_by(self, candidate: Candidate) -> bool: - assert candidate.name == self.name, ( - f"Internal issue: Candidate is not for this requirement " - f"{candidate.name} vs {self.name}" - ) - # We can safely always allow prereleases here since PackageFinder - # already implements the prerelease logic, and would have filtered out - # prerelease candidates if the user does not expect them. - assert self._ireq.req, "Specifier-backed ireq is always PEP 508" - spec = self._ireq.req.specifier - return spec.contains(candidate.version, prereleases=True) - - -class SpecifierWithoutExtrasRequirement(SpecifierRequirement): - """ - Requirement backed by an install requirement on a base package. - Trims extras from its install requirement if there are any. - """ - - def __init__(self, ireq: InstallRequirement) -> None: - assert ireq.link is None, "This is a link, not a specifier" - self._ireq = install_req_drop_extras(ireq) - self._equal_cache: str | None = None - self._hash: int | None = None - self._extras = frozenset(canonicalize_name(e) for e in self._ireq.extras) - - @property - def _equal(self) -> str: - if self._equal_cache is not None: - return self._equal_cache - - self._equal_cache = str(self._ireq) - return self._equal_cache - - def __eq__(self, other: object) -> bool: - if not isinstance(other, SpecifierWithoutExtrasRequirement): - return NotImplemented - return self._equal == other._equal - - def __hash__(self) -> int: - if self._hash is not None: - return self._hash - - self._hash = hash(self._equal) - return self._hash - - -class RequiresPythonRequirement(Requirement): - """A requirement representing Requires-Python metadata.""" - - def __init__(self, specifier: SpecifierSet, match: Candidate) -> None: - self.specifier = specifier - self._specifier_string = str(specifier) # for faster __eq__ - self._hash: int | None = None - self._candidate = match - - # Pre-compute candidate lookup to avoid repeated specifier checks - if specifier.contains(match.version, prereleases=True): - self._candidate_lookup: CandidateLookup = (match, None) - else: - self._candidate_lookup = (None, None) - - def __str__(self) -> str: - return f"Python {self.specifier}" - - def __repr__(self) -> str: - return f"{self.__class__.__name__}({str(self.specifier)!r})" - - def __hash__(self) -> int: - if self._hash is not None: - return self._hash - - self._hash = hash((self._specifier_string, self._candidate)) - return self._hash - - def __eq__(self, other: Any) -> bool: - if not isinstance(other, RequiresPythonRequirement): - return False - return ( - self._specifier_string == other._specifier_string - and self._candidate == other._candidate - ) - - @property - def project_name(self) -> NormalizedName: - return self._candidate.project_name - - @property - def name(self) -> str: - return self._candidate.name - - def format_for_error(self) -> str: - return str(self) - - def get_candidate_lookup(self) -> CandidateLookup: - return self._candidate_lookup - - def is_satisfied_by(self, candidate: Candidate) -> bool: - assert candidate.name == self._candidate.name, "Not Python candidate" - # We can safely always allow prereleases here since PackageFinder - # already implements the prerelease logic, and would have filtered out - # prerelease candidates if the user does not expect them. - return self.specifier.contains(candidate.version, prereleases=True) - - -class UnsatisfiableRequirement(Requirement): - """A requirement that cannot be satisfied.""" - - def __init__(self, name: NormalizedName) -> None: - self._name = name - - def __str__(self) -> str: - return f"{self._name} (unavailable)" - - def __repr__(self) -> str: - return f"{self.__class__.__name__}({str(self._name)!r})" - - def __eq__(self, other: object) -> bool: - if not isinstance(other, UnsatisfiableRequirement): - return NotImplemented - return self._name == other._name - - def __hash__(self) -> int: - return hash(self._name) - - @property - def project_name(self) -> NormalizedName: - return self._name - - @property - def name(self) -> str: - return self._name - - def format_for_error(self) -> str: - return str(self) - - def get_candidate_lookup(self) -> CandidateLookup: - return None, None - - def is_satisfied_by(self, candidate: Candidate) -> bool: - return False diff --git a/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/resolver.py b/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/resolver.py deleted file mode 100755 index 6e49c9e..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/resolver.py +++ /dev/null @@ -1,341 +0,0 @@ -from __future__ import annotations - -import contextlib -import functools -import logging -import os -from typing import TYPE_CHECKING, cast - -from pip._vendor.packaging.utils import canonicalize_name -from pip._vendor.resolvelib import BaseReporter, ResolutionImpossible, ResolutionTooDeep -from pip._vendor.resolvelib import Resolver as RLResolver -from pip._vendor.resolvelib.structs import DirectedGraph - -from pip._internal.cache import WheelCache -from pip._internal.exceptions import ResolutionTooDeepError -from pip._internal.index.package_finder import PackageFinder -from pip._internal.operations.prepare import RequirementPreparer -from pip._internal.req.constructors import install_req_extend_extras -from pip._internal.req.req_install import InstallRequirement -from pip._internal.req.req_set import RequirementSet -from pip._internal.resolution.base import BaseResolver, InstallRequirementProvider -from pip._internal.resolution.resolvelib.provider import PipProvider -from pip._internal.resolution.resolvelib.reporter import ( - PipDebuggingReporter, - PipReporter, -) -from pip._internal.utils.packaging import get_requirement - -from .base import Candidate, Requirement -from .factory import Factory - -if TYPE_CHECKING: - from pip._vendor.resolvelib.resolvers import Result as RLResult - - Result = RLResult[Requirement, Candidate, str] - - -logger = logging.getLogger(__name__) - - -class Resolver(BaseResolver): - _allowed_strategies = {"eager", "only-if-needed", "to-satisfy-only"} - - def __init__( - self, - preparer: RequirementPreparer, - finder: PackageFinder, - wheel_cache: WheelCache | None, - make_install_req: InstallRequirementProvider, - use_user_site: bool, - ignore_dependencies: bool, - only_dependencies: bool, - ignore_installed: bool, - ignore_requires_python: bool, - force_reinstall: bool, - upgrade_strategy: str, - py_version_info: tuple[int, ...] | None = None, - ): - super().__init__() - assert upgrade_strategy in self._allowed_strategies - assert not (ignore_dependencies and only_dependencies) - - self.factory = Factory( - finder=finder, - preparer=preparer, - make_install_req=make_install_req, - wheel_cache=wheel_cache, - use_user_site=use_user_site, - force_reinstall=force_reinstall, - ignore_installed=ignore_installed, - ignore_requires_python=ignore_requires_python, - py_version_info=py_version_info, - ) - self.ignore_dependencies = ignore_dependencies - self.only_dependencies = only_dependencies - self.upgrade_strategy = upgrade_strategy - self._result: Result | None = None - - def resolve( - self, root_reqs: list[InstallRequirement], check_supported_wheels: bool - ) -> RequirementSet: - collected = self.factory.collect_root_requirements(root_reqs) - provider = PipProvider( - factory=self.factory, - constraints=collected.constraints, - ignore_dependencies=self.ignore_dependencies, - only_dependencies=self.only_dependencies, - upgrade_strategy=self.upgrade_strategy, - user_requested=collected.user_requested, - ) - if "PIP_RESOLVER_DEBUG" in os.environ: - reporter: BaseReporter[Requirement, Candidate, str] = PipDebuggingReporter() - else: - reporter = PipReporter(constraints=provider.constraints) - - resolver: RLResolver[Requirement, Candidate, str] = RLResolver( - provider, - reporter, - ) - - try: - limit_how_complex_resolution_can_be = 200000 - result = self._result = resolver.resolve( - collected.requirements, max_rounds=limit_how_complex_resolution_can_be - ) - - except ResolutionImpossible as e: - error = self.factory.get_installation_error( - cast("ResolutionImpossible[Requirement, Candidate]", e), - collected.constraints, - ) - raise error from e - except ResolutionTooDeep: - raise ResolutionTooDeepError from None - - req_set = RequirementSet(check_supported_wheels=check_supported_wheels) - # process candidates with extras last to ensure their base equivalent is - # already in the req_set if appropriate. - # Python's sort is stable so using a binary key function keeps relative order - # within both subsets. - for candidate in sorted( - result.mapping.values(), key=lambda c: c.name != c.project_name - ): - ireq = candidate.get_install_requirement() - if ireq is None: - if candidate.name != candidate.project_name: - # extend existing req's extras - with contextlib.suppress(KeyError): - req = req_set.get_requirement(candidate.project_name) - req_set.add_named_requirement( - install_req_extend_extras( - req, get_requirement(candidate.name).extras - ) - ) - continue - - # Check if there is already an installation under the same name, - # and set a flag for later stages to uninstall it, if needed. - installed_dist = self.factory.get_dist_to_uninstall(candidate) - if installed_dist is None: - # There is no existing installation -- nothing to uninstall. - ireq.should_reinstall = False - elif self.factory.force_reinstall: - # The --force-reinstall flag is set -- reinstall. - ireq.should_reinstall = True - elif installed_dist.version != candidate.version: - # The installation is different in version -- reinstall. - ireq.should_reinstall = True - elif candidate.is_editable or installed_dist.editable: - # The incoming distribution is editable, or different in - # editable-ness to installation -- reinstall. - ireq.should_reinstall = True - elif candidate.source_link and candidate.source_link.is_file: - # The incoming distribution is under file:// - if candidate.source_link.is_wheel: - # is a local wheel -- do nothing. - logger.info( - "%s is already installed with the same version as the " - "provided wheel. Use --force-reinstall to force an " - "installation of the wheel.", - ireq.name, - ) - continue - - # is a local sdist or path -- reinstall - ireq.should_reinstall = True - else: - continue - - link = candidate.source_link - if link and link.is_yanked: - # The reason can contain non-ASCII characters, Unicode - # is required for Python 2. - msg = ( - "The candidate selected for download or install is a " - "yanked version: {name!r} candidate (version {version} " - "at {link})\nReason for being yanked: {reason}" - ).format( - name=candidate.name, - version=candidate.version, - link=link, - reason=link.yanked_reason or "", - ) - logger.warning(msg) - - req_set.add_named_requirement(ireq) - - if self.only_dependencies: - for requested in collected.user_requested: - project_name = requested.partition("[")[0] - req_set.requirements.pop(project_name, None) - - return req_set - - def get_installation_order( - self, req_set: RequirementSet - ) -> list[InstallRequirement]: - """Get order for installation of requirements in RequirementSet. - - The returned list contains a requirement before another that depends on - it. This helps ensure that the environment is kept consistent as they - get installed one-by-one. - - The current implementation creates a topological ordering of the - dependency graph, giving more weight to packages with less - or no dependencies, while breaking any cycles in the graph at - arbitrary points. We make no guarantees about where the cycle - would be broken, other than it *would* be broken. - """ - assert self._result is not None, "must call resolve() first" - - if not req_set.requirements: - # Nothing is left to install, so we do not need an order. - return [] - - graph = self._result.graph - weights = get_topological_weights(graph, set(req_set.requirements.keys())) - - sorted_items = sorted( - req_set.requirements.items(), - key=functools.partial(_req_set_item_sorter, weights=weights), - reverse=True, - ) - return [ireq for _, ireq in sorted_items] - - -def get_topological_weights( - graph: DirectedGraph[str | None], requirement_keys: set[str] -) -> dict[str | None, int]: - """Assign weights to each node based on how "deep" they are. - - This implementation may change at any point in the future without prior - notice. - - We first simplify the dependency graph by pruning any leaves and giving them - the highest weight: a package without any dependencies should be installed - first. This is done again and again in the same way, giving ever less weight - to the newly found leaves. The loop stops when no leaves are left: all - remaining packages have at least one dependency left in the graph. - - Then we continue with the remaining graph, by taking the length for the - longest path to any node from root, ignoring any paths that contain a single - node twice (i.e. cycles). This is done through a depth-first search through - the graph, while keeping track of the path to the node. - - Cycles in the graph result would result in node being revisited while also - being on its own path. In this case, take no action. This helps ensure we - don't get stuck in a cycle. - - When assigning weight, the longer path (i.e. larger length) is preferred. - - We are only interested in the weights of packages that are in the - requirement_keys. - """ - path: set[str | None] = set() - weights: dict[str | None, list[int]] = {} - - def visit(node: str | None) -> None: - if node in path: - # We hit a cycle, so we'll break it here. - return - - # The walk is exponential and for pathologically connected graphs (which - # are the ones most likely to contain cycles in the first place) it can - # take until the heat-death of the universe. To counter this we limit - # the number of attempts to visit (i.e. traverse through) any given - # node. We choose a value here which gives decent enough coverage for - # fairly well behaved graphs, and still limits the walk complexity to be - # linear in nature. - cur_weights = weights.get(node, []) - if len(cur_weights) >= 5: - return - - # Time to visit the children! - path.add(node) - for child in graph.iter_children(node): - visit(child) - path.remove(node) - - if node not in requirement_keys: - return - - cur_weights.append(len(path)) - weights[node] = cur_weights - - # Simplify the graph, pruning leaves that have no dependencies. This is - # needed for large graphs (say over 200 packages) because the `visit` - # function is slower for large/densely connected graphs, taking minutes. - # See https://github.com/pypa/pip/issues/10557 - # We repeat the pruning step until we have no more leaves to remove. - while True: - leaves = set() - for key in graph: - if key is None: - continue - for _child in graph.iter_children(key): - # This means we have at least one child - break - else: - # No child. - leaves.add(key) - if not leaves: - # We are done simplifying. - break - # Calculate the weight for the leaves. - weight = len(graph) - 1 - for leaf in leaves: - if leaf not in requirement_keys: - continue - weights[leaf] = [weight] - # Remove the leaves from the graph, making it simpler. - for leaf in leaves: - graph.remove(leaf) - - # Visit the remaining graph, this will only have nodes to handle if the - # graph had a cycle in it, which the pruning step above could not handle. - # `None` is guaranteed to be the root node by resolvelib. - visit(None) - - # Sanity check: all requirement keys should be in the weights, - # and no other keys should be in the weights. - difference = set(weights.keys()).difference(requirement_keys) - assert not difference, difference - - # Now give back all the weights, choosing the largest ones from what we - # accumulated. - return {node: max(wgts) for (node, wgts) in weights.items()} - - -def _req_set_item_sorter( - item: tuple[str, InstallRequirement], - weights: dict[str | None, int], -) -> tuple[int, str]: - """Key function used to sort install requirements for installation. - - Based on the "weight" mapping calculated in ``get_installation_order()``. - The canonical package name is returned as the second member as a tie- - breaker to ensure the result is predictable, which is useful in tests. - """ - name = canonicalize_name(item[0]) - return weights[name], name diff --git a/venv/lib/python3.11/site-packages/pip/_internal/self_outdated_check.py b/venv/lib/python3.11/site-packages/pip/_internal/self_outdated_check.py deleted file mode 100755 index 4b5248e..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/self_outdated_check.py +++ /dev/null @@ -1,246 +0,0 @@ -from __future__ import annotations - -import datetime -import hashlib -import json -import logging -import optparse -import os.path -import sys -from dataclasses import dataclass - -from pip._vendor.packaging.version import Version -from pip._vendor.packaging.version import parse as parse_version -from pip._vendor.rich.console import Group -from pip._vendor.rich.markup import escape -from pip._vendor.rich.text import Text - -from pip._internal.index.collector import LinkCollector -from pip._internal.index.package_finder import PackageFinder -from pip._internal.metadata import get_default_environment -from pip._internal.models.release_control import ReleaseControl -from pip._internal.models.selection_prefs import SelectionPreferences -from pip._internal.network.session import PipSession -from pip._internal.utils.compat import WINDOWS -from pip._internal.utils.datetime import parse_iso_datetime -from pip._internal.utils.entrypoints import ( - get_best_invocation_for_this_pip, - get_best_invocation_for_this_python, -) -from pip._internal.utils.filesystem import ( - adjacent_tmp_file, - check_path_owner, - copy_directory_permissions, - replace, -) -from pip._internal.utils.misc import ( - ExternallyManagedEnvironment, - check_externally_managed, - ensure_dir, -) - -_WEEK = datetime.timedelta(days=7) - -logger = logging.getLogger(__name__) - - -def _get_statefile_name(key: str) -> str: - key_bytes = key.encode() - name = hashlib.sha224(key_bytes).hexdigest() - return name - - -class SelfCheckState: - def __init__(self, cache_dir: str) -> None: - self._state: dict[str, str] = {} - self._statefile_path = None - - # Try to load the existing state - if cache_dir: - self._statefile_path = os.path.join( - cache_dir, "selfcheck", _get_statefile_name(self.key) - ) - try: - with open(self._statefile_path, encoding="utf-8") as statefile: - self._state = json.load(statefile) - except (OSError, ValueError, KeyError): - # Explicitly suppressing exceptions, since we don't want to - # error out if the cache file is invalid. - pass - - @property - def key(self) -> str: - return sys.prefix - - def get(self, current_time: datetime.datetime) -> str | None: - """Check if we have a not-outdated version loaded already.""" - if not self._state: - return None - - if "last_check" not in self._state: - return None - - if "pypi_version" not in self._state: - return None - - # Determine if we need to refresh the state - last_check = parse_iso_datetime(self._state["last_check"]) - time_since_last_check = current_time - last_check - if time_since_last_check > _WEEK: - return None - - return self._state["pypi_version"] - - def set(self, pypi_version: str, current_time: datetime.datetime) -> None: - # If we do not have a path to cache in, don't bother saving. - if not self._statefile_path: - return - - statefile_directory = os.path.dirname(self._statefile_path) - - # Check to make sure that we own the directory - if not check_path_owner(statefile_directory): - 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(statefile_directory) - - state = { - # Include the key so it's easy to tell which pip wrote the - # file. - "key": self.key, - "last_check": current_time.isoformat(), - "pypi_version": pypi_version, - } - - text = json.dumps(state, sort_keys=True, separators=(",", ":")) - - with adjacent_tmp_file(self._statefile_path) as f: - f.write(text.encode()) - copy_directory_permissions(statefile_directory, f) - - try: - # Since we have a prefix-specific state file, we can just - # overwrite whatever is there, no need to check. - replace(f.name, self._statefile_path) - except OSError: - # Best effort. - pass - - -@dataclass -class UpgradePrompt: - old: str - new: str - - def __rich__(self) -> Group: - if WINDOWS: - pip_cmd = f"{get_best_invocation_for_this_python()} -m pip" - else: - pip_cmd = get_best_invocation_for_this_pip() - - notice = "[bold][[reset][blue]notice[reset][bold]][reset]" - return Group( - Text(), - Text.from_markup( - f"{notice} A new release of pip is available: " - f"[red]{self.old}[reset] -> [green]{self.new}[reset]" - ), - Text.from_markup( - f"{notice} To update, run: " - f"[green]{escape(pip_cmd)} install --upgrade pip" - ), - ) - - -def _get_current_remote_pip_version( - session: PipSession, options: optparse.Values -) -> str | None: - # Lets use PackageFinder to see what the latest pip version is - link_collector = LinkCollector.create( - session, - options=options, - suppress_no_index=True, - ) - - # Pass allow_yanked=False so we don't suggest upgrading to a - # yanked version. - selection_prefs = SelectionPreferences( - allow_yanked=False, - release_control=ReleaseControl(only_final={"pip"}), - ) - - finder = PackageFinder.create( - link_collector=link_collector, - selection_prefs=selection_prefs, - ) - best_candidate = finder.find_best_candidate("pip").best_candidate - if best_candidate is None: - return None - - return str(best_candidate.version) - - -def _compute_upgrade_prompt( - local_version: Version, remote_version_str: str, installed_by_pip: bool -) -> UpgradePrompt | None: - remote_version = parse_version(remote_version_str) - logger.debug("Remote version of pip: %s", remote_version) - logger.debug("Local version of pip: %s", local_version) - logger.debug("Was pip installed by pip? %s", installed_by_pip) - - if not installed_by_pip: - return None # Only suggest upgrade if pip is installed by pip. - - local_version_is_older = ( - local_version < remote_version - and local_version.base_version != remote_version.base_version - ) - if local_version_is_older: - return UpgradePrompt(old=str(local_version), new=remote_version_str) - - return None - - -def pip_self_version_check_fetch( - session: PipSession, options: optparse.Values -) -> UpgradePrompt | None: - """Compute the pip upgrade prompt, if any, before the command runs. - - 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. - - Pair with :func:`pip_self_version_check_emit`, which displays the prompt - after the command body runs. - """ - installed_dist = get_default_environment().get_distribution("pip") - if not installed_dist: - return None - try: - check_externally_managed() - except ExternallyManagedEnvironment: - return None - - state = SelfCheckState(cache_dir=options.cache_dir) - current_time = datetime.datetime.now(datetime.timezone.utc) - remote_version_str = state.get(current_time) - if remote_version_str is None: - remote_version_str = _get_current_remote_pip_version(session, options) - if remote_version_str is None: - logger.debug("No remote pip version found") - return None - state.set(remote_version_str, current_time) - - return _compute_upgrade_prompt( - local_version=installed_dist.version, - remote_version_str=remote_version_str, - installed_by_pip=installed_dist.installer == "pip", - ) - - -def pip_self_version_check_emit(upgrade_prompt: UpgradePrompt | None) -> None: - """Emit the upgrade prompt captured by :func:`pip_self_version_check_fetch`.""" - if upgrade_prompt is not None: - logger.warning("%s", upgrade_prompt, extra={"rich": True}) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/__init__.py b/venv/lib/python3.11/site-packages/pip/_internal/utils/__init__.py deleted file mode 100755 index e69de29..0000000 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-311.pyc deleted file mode 100755 index e9513a70c3a0e29af155298b48fa61f9d538730d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 196 zcmZ3^%ge<81lOj_$^y}kK?DpiLK&agfQ;!3DGb33nv8xc8H$*I{LdiCU*Y;0`MIh3 zxrs%|`TAb@>G{U`i3J7vWvO{(`Z<|N`URCG8Tom}dWMGj#hE3kx&?{J*@@|?#rg%A z1^V%sc_pbud5Jmtr6rj;#rp9;fy|Qlc)fzkUmP~M`6;D2sdh!IKzl$gDdq<8a0o7?bBYNLMyVgr)kpq<|&#K(8J3dj5DPV}GTO`qffr7?Wm@270L%Jr3U*9#K z+VVcT)}l%C{yLKCf1lmQ$AkI=yVk0;ZnQN%n_jd-_a#8$sa|U90o-=A4IDbuLl|Y% zmtjNg%9pK-jg`#2r(34WXB?|ESMa#CpgDZjv5I_Nag@9@;%T?N5n0X_G*{!Z4S2=T zxM_LZE!no^YAW|EKBMsxy)NorK{xqLTenAYy6I_-sTem$c$Ee)<$`9|#HT^-Ap4t5 z{BII<%~WO#jW1}XYB{<&$4zZfbL6~b>zd20S@63xmvc1NDmi)0y(z@7N**sL3j_`l zRb0N8v|_4U_gv8Tbcm*EHaKWzeu?KTQ#;FDtEiDapiod?ppw%hgR6NZo9nKyMZV-X zpke@1v4ybKtXu$n1K6-(LeFa^tmtUAW2vP)OeHK0b>?)K2&_nS*wL^S-;(8sWiMd~ zUb(2amdVp2JYreJ8CRAkG^eP$E?h^<3!0=7t-P*)9#^e=sR+ds3Kc%98?g7FSI~H0 zriRfsL`+~iC;`vYT79YE26)DEbP;Yr0OgI6N-|Keke3X-sMk0ET^4$~BsoGVDC7+C zqNVDyOZe4 zd>0Eyf@WA)TAnRACRkSEUA15`!Es*8dqjo6XDtKnBh?T;sxHzC&dg#-nL&C9U8-(H z0zp(^Zs7nSMAfUcCAXkJb|hBSVBo8pGELRhaY$j;gX4AB-nN`-It!QXI)M^+JjOGr zvFz1wI>zG}K9NpciAQ5m-WSf`yD!ME#?n2g4g7x;PLB~w|Rh+mFpK{T7<#IQyx9s}MOzZ^?P#z8rJ zKAwnYr-JfWJewq%W2rO`^NDae8;?vT!f8G+nVv{xVqhNy*W#Q3SI00H28OXF)2Og2XrAnX7H%dOf zsLjyx_y-u)*$T6IR@esK4_>OYw_zM+Xb8UKQ>lMQD$58a$8#wy@zsLFa)}LpdOd`M z&_YGU$y=d|)|~ZbNU`k@YU)DB&}TyS5)#>bbL5RTLay#<-?x?gEoDw~Ludn`MjHr~ zJl$|ZxoUOKiSA-Al{<2#WzHCidCO@Bw=;O$?_yYGJAtmv!0?*8{_e-`ZsfOmhqrr& zH@k;7{lky3&i2@V+M}?+EMC@`M*y{JzG15kUwy9m*E_WP<&g-rYlYnh{DTJ0UdzF5 zlJX0XmN~8|T{Bd^pcuM}a%NV$lESGrp&D2Y+KlEjSfvH4x+jGm0~CqmHm=^2NvmHf<8-|B5(m3e_3380llp6}ZuW9ZQL)Q` zCTkwgS=Z zKy=d|bvgjJCm<=1L_n_M1p(OzLdLvCNZ}n@vHImT?eXUQ^;x8H6HI-U?b{>n3)MY= zOQD(^YAd&)f5S{7&73Y!a)@EMm7>%}_S=T;iAaQP{FI(eb}36a=QyCx;&I6|tL$%q zW1kNFCiA=Q-=6qG^o!IVQ(M8ew}WqQogUpjJ-QV*w;edQ=|6YSGL3TeW00Y8wSnJ* z*Zxwa`c5=}pi#^6pG2HT9m_^b6tUa2gP zci5=FV&gzQ5Y7-KSj1-eaI;d*Nua!g$32B%l~umO4j=t!^n=lRXSM>bZ3kZ4khTMT zoBqCo9-w&Y$Md)g#4j;vUwoqQVg5lQV(-95QFg<=BdtgqjalF~uKm7pCOg;)PC9DK zFPpsf{PKGrRCdog&Bb`X9Ls>bBbl%Cv*t2=hB>Vgn}QZ}x>;nmTc+6JOH2A_az(nr z)+LF3_;YbO@+&`sFN9+*TG-H5t2y>_o^F<~3BzVv;hv-DSeQdZiOut%DBOH{x?a0$rEE_Lr>LpV3lSQ9;{Q&sA?fnoN(>QE{!w{_d`WQ*#JORy zfXz9!;Ugm>VuAL&bOurKs5snqG#q)zV6;tc7>y1vis9mbhrX$)FJr?wG%#U8)mUm0 zY|awj^^B$}r_+%UWR*Q~#bHoy$*6sN9Z&r`UKo-3aos-$eB-cV;}xj$>H_(2%d( zDr6BTMVBfD=heb+>_B)pXRw^Y<37Uhcid=WBdqh-TF+gO1-d6A6cJJWBA3kdR z?Cj@fw|alH=3nza`AaviFsZY5ci1_4e65Y{N(<(nJb6+%#Ex_yWFceru3WtM?1slsUdM+@_v+?_kae4XD&Jzq;b mYxyk+3nwc+NqPssG!pQs-MRL|Qh$XthF4#e;Jkx_Q0U*5Z~nIc diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/_log.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/_log.cpython-311.pyc deleted file mode 100755 index ef47bab7318e98cecba2d63e086248e70d222c4a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2017 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 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/compat.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/compat.cpython-311.pyc deleted file mode 100755 index ad9571761c7a43eed659a5fc0a447a98ca57aa87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3644 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 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/datetime.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/datetime.cpython-311.pyc deleted file mode 100755 index 2a645f75034f6d1242c6d093d9147b61c4673c42..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1600 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 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-311.pyc deleted file mode 100755 index 28b9a9a192b3e7e418913549f9e98c258341d279..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3835 zcmai1-EZ606~7cIiIQkpP9#}U<5;z0yUK^9%-w*jw%awW0cV5vkhExp0t78G7F~(d zE-AP1K?C;C0tRBV7^a88%Md^0q5r}D0m&d{f`EYld)ga~*GHA3rpk8dl;4u=BNYzlCDpM302Wo*j zU8d_ynW+cM!Fs41a@OfuxXzYYXUx&kuAihLwvsiJ>^YgQPB z&RY1>ibe(?%KS=Jz9cFdf?nlym2cu2OzEA9W<^Culq}&OoMbVIP?s!P)3Fu8lHSBh zB|uE*w-9_G7SxM*SbdCIs598{eGg&w)LWrYixR0_nC}I)&>r1F+tgqaFSG)q^KI|6 z?;)@jYAA*-pJx~3!FTl?|W-r*HJ5JUOb-1Gz1O76tAoxc6B`Ks_1e;<5 z2`z93{hoS*r`&)GPrd0RF$mf`KJqKQdR~jhZ?ytqNDOx%%CEQ9D;5$R{a6PehuPiI zZB^Nku$~w4UaIDG6{Zcjk;l?+nvjKcNzwC=ce1jzxJ&0h$e&Z!&Z!U1sg>O^t-0wY zs)`@1oKv&s)O;asu{%Od76n~`QAOirNOw$vY0;3*R-~fV>$1+vqQwdBZE;wvP*u>X zk_M?ReXU!JtV`Gm0+{3{;DE)Gc+X2qqMFBxR>qlQ)Zv z2YOXimKJZ`ENWoljfPP9QrMETA_T4o7J}`HP%Acdxuz9|cbTtBwT6VX#l{0`Ze&@| z_=ePY_uUfTU&PXV2}?>v!V6#&$!YCV$k>PIITJr&CXboP9+NegY?sNJ7t#l*Z?8Z6 zrJ1{eBMUXSjizzaz~ekGc%Dh60=6)hD{F`&S*Lk zZO7U%n?=#25y{&q;wbxOcmH=icCH;WV<{sxW5fzJVj}OK7H*s-lHZh#)O91ZbdtJt zoVwLZy=SD}>m`|6H%X45SMCsi(ow*_dqf{Xp?T^RRk)7K#yzP1tR%|1uvwD|0Xzu@ z;%OiS+5rJf@&FTi3KTBDM>$mB&Jd87gxH7Z>Wl7 zrO7fclUvSzRh6U~UlA%*$znEDwN@F44) z-7m0o#{-;!KJo=w?-%gPegQg3iQfyg0yx|X_Von!!b-M9d0I)FUu!MOuWK(n3QsM@ z2T=632SzP8=ZHFllb?DXfrTE#Kz{i4?h*+1pk&mHLzoO99KYi`f5c}!JCyRv_|BzY zKX=;$6Py9w_&`rTGHAFzx+_zAtP&8>9{Wa%NGkVRi#=lek@Q&=eATK#Xag<*2^Y=) zu`ZDEE@`?X@>trDHF$o(zH?#HgeebXut1J=7bu(?StkK<*ArFX+iT=(~Z@f!STsslbyxmoVfZ*8;~jGm^mM!NJY`NLbi z^oo&QfnqwI>$3fB&XrE)K0coN*yIuhHwPFn9|a7UkM`J^Hr*YY?o0r@a5FX%lj zO3rt=Ik%gctL^pnx*bKy%Uy2D?Pg~7BvU%hl%C~!nPnrh++IH&&zOmer>RS3a@t5< zF>|x#>`(15la8MuATJ34CArH+cF7)R6VWpS4Jl<#&R}vmF}ah@sKB^C{cx3V z76Kb<1=h_BQg&UQMKU5ef=h%rIvnnV73KN+P57rm;(1K!lQj+Rm__d$vshO}sirLs zbHqtLH=RkH#3ZM!?2ih0xM5}d`_AKN5pIp<0Gl=8-yU2?=LO`T7$)iXcjN@d$=Y*v z87ynoq*c5ITLcZYe*l5U3`Ln}rt9y|(Y@~f>n6I|^>-7My8dpWx4ZsshceWpjr`K|3w@p{|h!^b$tK; diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/egg_link.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/egg_link.cpython-311.pyc deleted file mode 100755 index d97c6076a0488b82abadefc9d57eecbbbf994946..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3490 zcmbtW-)kJl9iQF%eY(@hwPndpBaMA_?5nNYDl#!~<3MTMBu3FgoRV(_`>2kj=|hK_g&X^%ewEH zFuG-P&o>;)-3rc(c->`s*L-UMc!cw=)LL*7(OwMm}9x~K5; zni<*#rb#{rm42a?Q88g-7d}Z+Xuo3amc>14&^0&-ty-R88lFM749B;q$6z84H(bIS zQatQ+y568ht>!d9Nm7JYv8ce0g}*L5+w)P+)DX0`S=PBFn9qxrxFTRt$&weQCEqRL zs=O4i#ysm5ty{Dx?L@&G$THV18jii)|7P7P8aQKnv;x8nYTBie#VyyP4lCQmd{PSg zz@mmD7>uz^T4J2y@j%n^@bqfk_A1QxsLOa2g-cW9@U#NdU-KAq1byvwTC5mu*)oS0 ztQ!s788slrG*Yr1c)wclyqdVBX=RY^ujh-bs?{1bLmSD|Y$1G0Xg8K$yP4}sj1291X1G2yFn~e60~=^ue1nlHjLd zKYYY8kX`b_8IqWK7(L7^9-Ka?wBlMjuKn#=D}K8(b^0*A(EE2Ip;WX>LXqe*_=p@Q z0m!sT*O+Tfz&Q$&08!=H*T77|82}77eL4j7j^gzr2uj=-^1mkcS9jE=0{vS%ArB?? z+i1-}crZ5JH`Qk73CMXml(iE+;d^wu=UOv7c|sm-hKs5~@VQ4GzWwlBQvo+qx9>{) ztPY?!?n{UqiO(8m8& zpuk*2A|;rfv}BNwu?f&n4bl@+L45Ek@TM3MDE|p?JU$>7fe{!&00D7w_VU4pt=W8g zHov=eG&}$J!!8L&s3d!d&db-p^a*$cviI)M+_}f~{pM%QgLl5%Y0cek&)wd8`zUkj zVg1o34?g*0rIoqT&RppdB~3eXi=So&zitRd07xJxPEs>_H~1OY{>AY52f$>XlnH=j z2pB@1!1|}~^cuh0R1U^w2jhfzWAKV@{YnRo|IbcS227I#t+9jaF|A^>HwEuhD!n1a2|uRFMg-vxQfRcm?KNJYvK}&xB1`RyYrrY@16JW zT*s6328XqV{P5LWPoB$`dPT&4CwWrHN?%CB691c&vEz--Jh<3Zlet$gu|g7si}jB= zC|z>BRQnsquGwX3z~!?mQXGfG&3wnC>lS6E30YiNpz}Iv7quaEY`7GHPOqW>*{{ky z2cpH$Ahy72q{2*Ew;hLW_`;*T5=mOTWOEn*3xe69R2u}zB*#1uL?IOtxc_gnF7JDxp^XOA-3R_1a$a~a}a;?iGp zvg@QyJz9OR`o+0cD%(zF4^!EHem8aIgsJCcem8q*6rDRWvlx~aCD{x2V>7&l5{nR< z&(1$C?>nD42RFWaxpnqt`|QoVw??tK+{(Pt&b)%Ld9gFM@agp6hp~APWAoy8Y|e$H z{x}8~jxmF$fjmDti=&w!sp};lid{?BITQh;XObD@=70oqP^#pIrAmH?jh;EtlEK2{ z5?RgUM-D1cAPpbHblq?q*a=ISURpzo{e{S^B9q;5{EaFzeaCu}{|u%uRfw;Ez-1Ms zLoOap{=XrKUHR*bnB=bfeM8P>Tax?N-0oHO_GJA RGSelKj&N)vUUsCmK>2j{aC2<0Y6=|y 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 abwj_EaKO^qc-^@hQus)_M9TfLuB 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 SREs*kEsEIF{3^&r>Hh^H85l?a diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/misc.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/misc.cpython-311.pyc deleted file mode 100755 index 7be78b3370cc005035c8ca371c1034d7554f0bea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37717 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 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-311.pyc deleted file mode 100755 index ae09de9e2ccb050205e5d9216ec8f3fccad880ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2030 zcmaJ>&1)M+6rWwKB}=j`lUOx&6El?!t%|)Om^en1LgG-8Qry-~p(r)0^=c%ovR|E9 zIkizhhaPh5Az;%}=)oblExi=_H}oWdC}yExC_Ut+VtVnZZ+5lo$POK?-oBlg_w{?f znHS^ZDFow>XWut&#}WFAe}p3zD8lLQpzNaxst5)$g_0m}T{Og!=)Ys77`$VKWR8?Z z%y=p8uS-V494(CsNJJ#oNQO>H>QF%F2>!t+rD0ucjD_Eoksss3J1SQzVlvmir0^rU_I1hUt66%g|tvDbB82x2>}jb181&b=xA|*uaURTUGlk<2D_G zJk%|B5zDf?<;5v+o7D28ZQC|9k!Lj+qwog!h0~uw*+(tZ7J2G!1RFw)NN=HGz@CWi zNazUm4cdsHMbD-4`E$)pzotixK&T}gLQY3fUc*s_zn;Wev6i@l0A5KwfYeeL##)_d zkFZ|FZk^zozC$ehnU4}40E11{)#`*{73T&hv!!554oBUPQ@*#Nqf*rjO?^y@_%>c% z@^Qs>6$7*kQ{qsNo{p#7@D`w+n&YvV7x4f$1(;a#Zb+S|hCB=uQDz?GkFKMxp8I z2F&@3&|cZu^|F4`lnXi0S%}QDWuJp+qy8Kko$e&&PBK@Yx_{#Ld-&FGnJ&K9!}mJU z^}n;%o^3r}ezE$)>Q8IG#(w##yLhL!c&9tR)|+4JX7Bd0ciZd7>6y;;l}>u4Bdwf* zQ>0J63uvSuvH}o6I`l1=r3nyPbU5LIA3*pErx=v|p+kJ}=)&<4_HM4hedN-n<^p}s zYuz}%g|NNdAh7&cck5VFwK@+D*Ed+xYw%(`Jf<@sy-ba`Av&CNbPi@0_@*l$+UVa& zG&cR+UN@cVrE?uAN8g6&d_3qkzZv|d({Zj%aFOBbk{>51*q`N9=QCbPQL0TKFi{lB z>-Lh>rlq-XzrmGi*tHsD>Sdv+GH}GI*i?=R^eGvTF!#m{@}S4O3g*M?C84-az$>BN zsG?Y^330tRj{`GFgEke84)NLG7yc6Y_4&}8jecO-m8L;HqZdX7=CGyI$+XP-{@lCuY^-Q+?qxzLXH<4DZ5XL`ca!A3{G vT>WTYVIYe_}{{Cz_TcgD*P5d{>z73G;n10Rn}B8!TL&_N)F6TZ15o diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/pylock.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/pylock.cpython-311.pyc deleted file mode 100755 index 06c953542ef7fdcedb7fd6a89307dfbadba46f23..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12074 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 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/retry.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/retry.cpython-311.pyc deleted file mode 100755 index 7b22f3e7682d2f22b15bff1a8e9705a7400e4406..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2305 zcmaJ?-HQ}Q5bvIu{g}Po`_PMP^gcSCglux|YD`{43}TK%h2y{@!4+BiW_oW&=Zo%H z*OOC@Ah;Kfph1a|JopgQ;2+>~{)07yunY)7$V1*XNZ`1qRL|_5x2LhUr@FejySnOE z)wPduxeS8#$DR8ZTM2~zl#^alV+Ozc7MLH9iA-!G2bVFHykaY51xD3Y9j&ZIGR;mn z$#T+3l~d6?VW%CvtUH-<1|z2PG1#B92b^pZsi^6|P}lVW8d#nyW?`N_L2a8Z*sP$0S)cK0#qjEGz<8JtHe)`B zbMt5CW-2GXoH=p&K`mMp)M143#k#}XKt##_Ov@%#Aa4cV1(6nk z_P~Ozw&lP|q>36fW){iUHRis)9%&MF?o%O{8Czmg5fFC8V1DF7WTYAEiutZLM|>G1 zA|rEz%=c~vP^5%J;UTmO09jyFkFyvd%Uzr%mP-U6>6)S#8PV0YJ+xai$3De+8#T+Q zMcOPT04Cce2BU&aN4g}|+x3TB~Mg)`x6`8Jlhm;OVk_95|U#eKL;JDN-)#0s(QuIEH{!*BWxJrYAE@oam z5HB3HJ$QHGSTUCK;-;W)I|KrW0Lc0Z`ZtaCy#M3GPZP~k9VM9~9VIbB+IuJOeez(m zwfErTT|i_XJ-GfnPdZ2)*+QP@r*2=rbNzAVS^neJr!&9hXIlB0_U`fLqwn6^fBW>E z)3>5uCk3b0*Vj8KxIoB+{XVq^-7g)_s=p3kpgmZ3!BT`Rmu2i#DnY5$qmtx#wg?l_ zJ5kVL(8uM@SIEnNUjX3w7%*X~3&ho3Zw5#n7AJwM0~CMhJJu%ejXu*Se%B{DN=64y z-$wpXQD$;;>uxkW-b#*zQmsSLWt9q-Ch!R$ z;gI1$(T)ngDAEOkOE5z%N^toaq9+h0gC!pdAWun2TJ9K$B^7ohV6Kq=pIn!VvI_74 zNu*1BpCr=2$lHzdQO7guHao@(Ad^)|JO$EGF~)7QuhrjQpy5`px6%Gqe}7#PZ)l@J z>rMTII^01T&bPIXTK)Y+dZ?MYrLJbzvMa~i>5-;>Yif0HZE)pyCpn3CcF_Nj$g%$b Dv#ng7 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-311.pyc deleted file mode 100755 index 97972115c36fa11462bfb20e0d222acabf2653af..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9462 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 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-311.pyc deleted file mode 100755 index 2c0338a119cd8c6e83509f156a3ab29d839ce51a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13282 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 asQ<{oQ)spH)^Z=!uJ7HU|7bgp@c#lOMH^=T diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/urls.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/urls.cpython-311.pyc deleted file mode 100755 index 1ac1a5fe2c1d091d0569651f2983a18b873ebe68..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2288 zcmZ`(O=ufO6rTN+w5vbI&0p;%3n^}-CSK%_w3ybA*dh1_h1P9CO~7oln@G-TSD9TY zwJL$=54gcl6;kcw1FM+@DNTA9N*RH^A4L+?6kvU&CX*Z zMRt1)JVOlp+y4LoPbihvQJJ#oo&Z8i-h7=%zSRClws*%q`4V~n)*pEu^smaOL@jZ> z1M9@Mmzv6ejIYOD_xEP|$Cs?Y4IX*7DAOex-ij@z1qs@uX%sYUONvAuNwQ6t-N@+L zxb*RdbEA^+M3!G&neipMqM^0 zwv$Dlt5%j{0VkZtx}Lc{inZH$&9WWZv@p52<2Ov4b))426YhiqO_t{P;K-7hF&tm- zP>^gJN>&?#tr*i)z;`t}42%|u7hG{?UQU}?P0lJfWy&+=P4kSbAVDbH4I)%x@+K1nJzPB z7ARd}FkfO+{+6o+Gpeu57{~2>>5F;QUt)@26Lt>RqGueb0pisf-S4mKlLwJ?4-$Ll z5GpYxmT2rhS!Vm}&XyQ!+9uDr+e&P|yeiysL5a_mSd}{36GN)Fdz(1$gL{1YfG2{M z+#*QU1%wZQTu2RnMeoU~5#S5tyh`uqm)Q~vAdMDJz5r4Wnq8!l9P9%b=L!@PpO|?m zr5KWF=*to*d%K_}*(*Uto9>#R$C6GOrY-GIF(;s#DMe44fJjuNuU#v?YnaAqm+6W_ zNtm`I1#1#HVdZl<6BEFjhGeHRmXy;K`vw4bT-qX;xI@X9j9Vn=TcjYy=pAajNRP`g z5tGv(lP=|x@IgdioD*N^H>U3@3ZgM5r3P!5~tCyb_gjyP@Gz zCMo#ca5E4}x0bq5_!YSt+!*cn-^-e6Ue_k@DbPepn)L;c4nt8?3k53f*FvF+`?b(u sz1Q1lsNUZ@e1M8nQ}E7Iq}CnW`95-Fgo;+@I|znacW~#gBCeDF0U{9>uK)l5 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-311.pyc deleted file mode 100755 index be2fc1b3b5dcf5f0abbe8e11a746a3c4fefb308f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3293 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 D(X2z7 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/wheel.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/wheel.cpython-311.pyc deleted file mode 100755 index 5b31036980ecfee3ada13001aebdaa4285c5959e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6933 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 Ha-9DIIX$=z diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/_jaraco_text.py b/venv/lib/python3.11/site-packages/pip/_internal/utils/_jaraco_text.py deleted file mode 100755 index 6ccf53b..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/utils/_jaraco_text.py +++ /dev/null @@ -1,109 +0,0 @@ -"""Functions brought over from jaraco.text. - -These functions are not supposed to be used within `pip._internal`. These are -helper functions brought over from `jaraco.text` to enable vendoring newer -copies of `pkg_resources` without having to vendor `jaraco.text` and its entire -dependency cone; something that our vendoring setup is not currently capable of -handling. - -License reproduced from original source below: - -Copyright Jason R. Coombs - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -IN THE SOFTWARE. -""" - -import functools -import itertools - - -def _nonblank(str): - return str and not str.startswith("#") - - -@functools.singledispatch -def yield_lines(iterable): - r""" - Yield valid lines of a string or iterable. - - >>> list(yield_lines('')) - [] - >>> list(yield_lines(['foo', 'bar'])) - ['foo', 'bar'] - >>> list(yield_lines('foo\nbar')) - ['foo', 'bar'] - >>> list(yield_lines('\nfoo\n#bar\nbaz #comment')) - ['foo', 'baz #comment'] - >>> list(yield_lines(['foo\nbar', 'baz', 'bing\n\n\n'])) - ['foo', 'bar', 'baz', 'bing'] - """ - return itertools.chain.from_iterable(map(yield_lines, iterable)) - - -@yield_lines.register(str) -def _(text): - return filter(_nonblank, map(str.strip, text.splitlines())) - - -def drop_comment(line): - """ - Drop comments. - - >>> drop_comment('foo # bar') - 'foo' - - A hash without a space may be in a URL. - - >>> drop_comment('http://example.com/foo#bar') - 'http://example.com/foo#bar' - """ - return line.partition(" #")[0] - - -def join_continuation(lines): - r""" - Join lines continued by a trailing backslash. - - >>> list(join_continuation(['foo \\', 'bar', 'baz'])) - ['foobar', 'baz'] - >>> list(join_continuation(['foo \\', 'bar', 'baz'])) - ['foobar', 'baz'] - >>> list(join_continuation(['foo \\', 'bar \\', 'baz'])) - ['foobarbaz'] - - Not sure why, but... - The character preceding the backslash is also elided. - - >>> list(join_continuation(['goo\\', 'dly'])) - ['godly'] - - A terrible idea, but... - If no line is available to continue, suppress the lines. - - >>> list(join_continuation(['foo', 'bar\\', 'baz\\'])) - ['foo'] - """ - lines = iter(lines) - for item in lines: - while item.endswith("\\"): - try: - item = item[:-2].strip() + next(lines) - except StopIteration: - return - yield item diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/_log.py b/venv/lib/python3.11/site-packages/pip/_internal/utils/_log.py deleted file mode 100755 index 92c4c6a..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/utils/_log.py +++ /dev/null @@ -1,38 +0,0 @@ -"""Customize logging - -Defines custom logger class for the `logger.verbose(...)` method. - -init_logging() must be called before any other modules that call logging.getLogger. -""" - -import logging -from typing import Any, cast - -# custom log level for `--verbose` output -# between DEBUG and INFO -VERBOSE = 15 - - -class VerboseLogger(logging.Logger): - """Custom Logger, defining a verbose log-level - - VERBOSE is between INFO and DEBUG. - """ - - def verbose(self, msg: str, *args: Any, **kwargs: Any) -> None: - return self.log(VERBOSE, msg, *args, **kwargs) - - -def getLogger(name: str) -> VerboseLogger: - """logging.getLogger, but ensures our VerboseLogger class is returned""" - return cast(VerboseLogger, logging.getLogger(name)) - - -def init_logging() -> None: - """Register our VerboseLogger and VERBOSE log level. - - Should be called before any calls to getLogger(), - i.e. in pip._internal.__init__ - """ - logging.setLoggerClass(VerboseLogger) - logging.addLevelName(VERBOSE, "VERBOSE") diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/appdirs.py b/venv/lib/python3.11/site-packages/pip/_internal/utils/appdirs.py deleted file mode 100755 index 4152528..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/utils/appdirs.py +++ /dev/null @@ -1,52 +0,0 @@ -""" -This code wraps the vendored appdirs module to so the return values are -compatible for the current pip code base. - -The intention is to rewrite current usages gradually, keeping the tests pass, -and eventually drop this after all usages are changed. -""" - -import os -import sys - -from pip._vendor import platformdirs as _appdirs - - -def user_cache_dir(appname: str) -> str: - return _appdirs.user_cache_dir(appname, appauthor=False) - - -def _macos_user_config_dir(appname: str, roaming: bool = True) -> str: - # Use ~/Application Support/pip, if the directory exists. - path = _appdirs.user_data_dir(appname, appauthor=False, roaming=roaming) - if os.path.isdir(path): - return path - - # Use a Linux-like ~/.config/pip, by default. - linux_like_path = "~/.config/" - if appname: - linux_like_path = os.path.join(linux_like_path, appname) - - return os.path.expanduser(linux_like_path) - - -def user_config_dir(appname: str, roaming: bool = True) -> str: - if sys.platform == "darwin": - return _macos_user_config_dir(appname, roaming) - - return _appdirs.user_config_dir(appname, appauthor=False, roaming=roaming) - - -# for the discussion regarding site_config_dir locations -# see -def site_config_dirs(appname: str) -> list[str]: - if sys.platform == "darwin": - dirval = _appdirs.site_data_dir(appname, appauthor=False, multipath=True) - return dirval.split(os.pathsep) - - dirval = _appdirs.site_config_dir(appname, appauthor=False, multipath=True) - if sys.platform == "win32": - return [dirval] - - # Unix-y system. Look in /etc as well. - return dirval.split(os.pathsep) + ["/etc"] diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/compat.py b/venv/lib/python3.11/site-packages/pip/_internal/utils/compat.py deleted file mode 100755 index b3f70cf..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/utils/compat.py +++ /dev/null @@ -1,91 +0,0 @@ -"""Stuff that differs in different Python versions and platform -distributions.""" - -import importlib.resources -import locale -import logging -import os -import sys -from typing import IO - -__all__ = ["get_locale_encoding", "get_path_uid", "tomllib", "WINDOWS"] - - -logger = logging.getLogger(__name__) - - -def has_tls() -> bool: - try: - import _ssl # noqa: F401 # ignore unused - - return True - except ImportError: - pass - - from pip._vendor.urllib3.util import IS_PYOPENSSL - - return IS_PYOPENSSL - - -def get_locale_encoding() -> str: - """Return the locale encoding. - - Uses ``locale.getencoding()`` when available (Python 3.11+) to avoid the - ``EncodingWarning`` that ``locale.getpreferredencoding(False)`` raises - under UTF-8 Mode. - """ - # TODO: Remove the 3.10 fallback once pip drops Python 3.10 support. - if sys.version_info >= (3, 11): - return locale.getencoding() - return locale.getpreferredencoding(False) - - -def get_path_uid(path: str) -> int: - """ - 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(f"{path} is a symlink; Will not return uid for symlinks") - return file_uid - - -# The importlib.resources.open_text function was deprecated in 3.11 with suggested -# replacement we use below. -if sys.version_info < (3, 11): - open_text_resource = importlib.resources.open_text -else: - - def open_text_resource( - package: str, resource: str, encoding: str = "utf-8", errors: str = "strict" - ) -> IO[str]: - return (importlib.resources.files(package) / resource).open( - "r", encoding=encoding, errors=errors - ) - - -if sys.version_info >= (3, 11): - import tomllib -else: - from pip._vendor import tomli as tomllib - - -# windows detection, covers cpython and ironpython -WINDOWS = sys.platform.startswith("win") or (sys.platform == "cli" and os.name == "nt") diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/compatibility_tags.py b/venv/lib/python3.11/site-packages/pip/_internal/utils/compatibility_tags.py deleted file mode 100755 index 6d98171..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/utils/compatibility_tags.py +++ /dev/null @@ -1,201 +0,0 @@ -"""Generate and work with PEP 425 Compatibility Tags.""" - -from __future__ import annotations - -import re - -from pip._vendor.packaging.tags import ( - PythonVersion, - Tag, - android_platforms, - compatible_tags, - cpython_tags, - generic_tags, - interpreter_name, - interpreter_version, - ios_platforms, - mac_platforms, -) - -_apple_arch_pat = re.compile(r"(.+)_(\d+)_(\d+)_(.+)") - - -def version_info_to_nodot(version_info: tuple[int, ...]) -> str: - # Only use up to the first two numbers. - return "".join(map(str, version_info[:2])) - - -def _mac_platforms(arch: str) -> list[str]: - match = _apple_arch_pat.match(arch) - if match: - name, major, minor, actual_arch = match.groups() - mac_version = (int(major), int(minor)) - arches = [ - # Since we have always only checked that the platform starts - # with "macosx", for backwards-compatibility we extract the - # actual prefix provided by the user in case they provided - # something like "macosxcustom_". It may be good to remove - # this as undocumented or deprecate it in the future. - "{}_{}".format(name, arch[len("macosx_") :]) - for arch in mac_platforms(mac_version, actual_arch) - ] - else: - # arch pattern didn't match (?!) - arches = [arch] - return arches - - -def _ios_platforms(arch: str) -> list[str]: - match = _apple_arch_pat.match(arch) - if match: - name, major, minor, actual_multiarch = match.groups() - ios_version = (int(major), int(minor)) - arches = [ - # Since we have always only checked that the platform starts - # with "ios", for backwards-compatibility we extract the - # actual prefix provided by the user in case they provided - # something like "ioscustom_". It may be good to remove - # this as undocumented or deprecate it in the future. - "{}_{}".format(name, arch[len("ios_") :]) - for arch in ios_platforms(ios_version, actual_multiarch) - ] - else: - # arch pattern didn't match (?!) - arches = [arch] - return arches - - -def _android_platforms(arch: str) -> list[str]: - match = re.fullmatch(r"android_(\d+)_(.+)", arch) - if match: - api_level, abi = match.groups() - return list(android_platforms(int(api_level), abi)) - else: - # arch pattern didn't match (?!) - return [arch] - - -def _custom_manylinux_platforms(arch: str) -> list[str]: - arches = [arch] - arch_prefix, arch_sep, arch_suffix = arch.partition("_") - if arch_prefix == "manylinux2014": - # manylinux1/manylinux2010 wheels run on most manylinux2014 systems - # with the exception of wheels depending on ncurses. PEP 599 states - # manylinux1/manylinux2010 wheels should be considered - # manylinux2014 wheels: - # https://www.python.org/dev/peps/pep-0599/#backwards-compatibility-with-manylinux2010-wheels - if arch_suffix in {"i686", "x86_64"}: - arches.append("manylinux2010" + arch_sep + arch_suffix) - arches.append("manylinux1" + arch_sep + arch_suffix) - elif arch_prefix == "manylinux2010": - # manylinux1 wheels run on most manylinux2010 systems with the - # exception of wheels depending on ncurses. PEP 571 states - # manylinux1 wheels should be considered manylinux2010 wheels: - # https://www.python.org/dev/peps/pep-0571/#backwards-compatibility-with-manylinux1-wheels - arches.append("manylinux1" + arch_sep + arch_suffix) - return arches - - -def _get_custom_platforms(arch: str) -> list[str]: - arch_prefix, arch_sep, arch_suffix = arch.partition("_") - if arch.startswith("macosx"): - arches = _mac_platforms(arch) - elif arch.startswith("ios"): - arches = _ios_platforms(arch) - elif arch_prefix == "android": - arches = _android_platforms(arch) - elif arch_prefix in ["manylinux2014", "manylinux2010"]: - arches = _custom_manylinux_platforms(arch) - else: - arches = [arch] - return arches - - -def _expand_allowed_platforms(platforms: list[str] | None) -> list[str] | None: - if not platforms: - return None - - seen = set() - result = [] - - for p in platforms: - if p in seen: - continue - additions = [c for c in _get_custom_platforms(p) if c not in seen] - seen.update(additions) - result.extend(additions) - - return result - - -def _get_python_version(version: str) -> PythonVersion: - if len(version) > 1: - return int(version[0]), int(version[1:]) - else: - return (int(version[0]),) - - -def _get_custom_interpreter( - implementation: str | None = None, version: str | None = None -) -> str: - if implementation is None: - implementation = interpreter_name() - if version is None: - version = interpreter_version() - return f"{implementation}{version}" - - -def get_supported( - version: str | None = None, - platforms: list[str] | None = None, - impl: str | None = None, - abis: list[str] | None = None, -) -> list[Tag]: - """Return a list of supported tags for each version specified in - `versions`. - - :param version: a string version, of the form "33" or "32", - or None. The version will be assumed to support our ABI. - :param platform: specify a list of platforms 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 abis: specify a list of abis you want valid - tags for, or None. If None, use the local interpreter abi. - """ - supported: list[Tag] = [] - - python_version: PythonVersion | None = None - if version is not None: - python_version = _get_python_version(version) - - interpreter = _get_custom_interpreter(impl, version) - - platforms = _expand_allowed_platforms(platforms) - - is_cpython = (impl or interpreter_name()) == "cp" - if is_cpython: - supported.extend( - cpython_tags( - python_version=python_version, - abis=abis, - platforms=platforms, - ) - ) - else: - supported.extend( - generic_tags( - interpreter=interpreter, - abis=abis, - platforms=platforms, - ) - ) - supported.extend( - compatible_tags( - python_version=python_version, - interpreter=interpreter, - platforms=platforms, - ) - ) - - return supported diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/datetime.py b/venv/lib/python3.11/site-packages/pip/_internal/utils/datetime.py deleted file mode 100755 index f8870ea..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/utils/datetime.py +++ /dev/null @@ -1,28 +0,0 @@ -"""For when pip wants to check the date or time.""" - -import datetime -import sys - - -def today_is_later_than(year: int, month: int, day: int) -> bool: - today = datetime.date.today() - given = datetime.date(year, month, day) - - return today > given - - -def parse_iso_datetime(isodate: str) -> datetime.datetime: - """Convert an ISO format string to a datetime. - - Handles the format 2020-01-22T14:24:01Z (trailing Z) - which is not supported by older versions of fromisoformat. - """ - # Python 3.11+ supports Z suffix natively in fromisoformat - if sys.version_info >= (3, 11): - return datetime.datetime.fromisoformat(isodate) - else: - return datetime.datetime.fromisoformat( - isodate.replace("Z", "+00:00") - if isodate.endswith("Z") and ("T" in isodate or " " in isodate.strip()) - else isodate - ) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/deprecation.py b/venv/lib/python3.11/site-packages/pip/_internal/utils/deprecation.py deleted file mode 100755 index c272671..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/utils/deprecation.py +++ /dev/null @@ -1,144 +0,0 @@ -""" -A module that implements tooling to enable easy warnings about deprecations. -""" - -from __future__ import annotations - -import logging -import os -import warnings -from typing import Any, TextIO - -from pip._vendor.packaging.version import parse - -from pip import __version__ as current_version # NOTE: tests patch this name. - -DEPRECATION_MSG_PREFIX = "DEPRECATION: " - - -class PipDeprecationWarning(Warning): - include_source: bool = False - - -_original_showwarning: Any = None - - -# Warnings <-> Logging Integration -def _showwarning( - message: Warning | str, - category: type[Warning], - filename: str, - lineno: int, - file: TextIO | None = None, - line: str | None = None, -) -> 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") - if isinstance(message, PipDeprecationWarning) and message.include_source: - logger.warning("%s (%s:%s)", message, filename, lineno) - else: - logger.warning(message) - else: - _original_showwarning(message, category, filename, lineno, file, line) - - -def install_warning_logger() -> None: - # Enable our Deprecation Warnings - # If we're running pip test suite, promote the PipDeprecationWarning into errors. - if os.environ.get("_PIP_TEST_ENV", None): - warnings.simplefilter("error", PipDeprecationWarning) - else: - warnings.simplefilter("default", PipDeprecationWarning, append=True) - - global _original_showwarning - - if _original_showwarning is None: - _original_showwarning = warnings.showwarning - warnings.showwarning = _showwarning - - -def deprecated( - *, - reason: str, - replacement: str | None, - gone_in: str | None, - feature_flag: str | None = None, - issue: int | None = None, - stacklevel: int = 2, - include_source: bool = False, -) -> None: - """Helper to deprecate existing functionality. - - reason: - Textual reason shown to the user about why this functionality has - been deprecated. Should be a complete sentence. - 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 an error if pip's current version is greater than or equal to - this. - feature_flag: - Command-line flag of the form --use-feature={feature_flag} for testing - upcoming functionality. - issue: - Issue number on the tracker that would serve as a useful place for - users to find related discussion and provide feedback. - stacklevel: - How many frames up the call stack to attribute the warning to. - Defaults to 2 (the caller of deprecated()). - include_source: - If True, include the source filename and line number in the warning - output. Useful when the warning originates from external code. - """ - - # Determine whether or not the feature is already gone in this version. - is_gone = gone_in is not None and parse(current_version) >= parse(gone_in) - - message_parts = [ - (reason, f"{DEPRECATION_MSG_PREFIX}{{}}"), - ( - gone_in, - ( - "pip {} will enforce this behaviour change." - if not is_gone - else "Since pip {}, this is no longer supported." - ), - ), - ( - replacement, - "A possible replacement is {}.", - ), - ( - feature_flag, - ( - "You can use the flag --use-feature={} to test the upcoming behaviour." - if not is_gone - else None - ), - ), - ( - issue, - "Discussion can be found at https://github.com/pypa/pip/issues/{}", - ), - ] - - message = " ".join( - format_str.format(value) - for value, format_str in message_parts - if format_str is not None and value is not None - ) - - # Raise as an error if this behaviour is deprecated. - if is_gone: - raise PipDeprecationWarning(message) - - warning = PipDeprecationWarning(message) - warning.include_source = include_source - warnings.warn(warning, stacklevel=stacklevel) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/direct_url_helpers.py b/venv/lib/python3.11/site-packages/pip/_internal/utils/direct_url_helpers.py deleted file mode 100755 index f2d6e90..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/utils/direct_url_helpers.py +++ /dev/null @@ -1,92 +0,0 @@ -from __future__ import annotations - -from pip._internal.models.direct_url import ArchiveInfo, DirectUrl, DirInfo, VcsInfo -from pip._internal.models.link import Link -from pip._internal.utils.urls import path_to_url -from pip._internal.vcs import vcs - - -def direct_url_as_pep440_direct_reference(direct_url: DirectUrl, name: str) -> str: - """Convert a DirectUrl to a pip requirement string.""" - direct_url.validate() # if invalid, this is a pip bug - requirement = name + " @ " - fragments = [] - if direct_url.vcs_info: - requirement += ( - f"{direct_url.vcs_info.vcs}+{direct_url.url}" - f"@{direct_url.vcs_info.commit_id}" - ) - elif direct_url.archive_info: - requirement += direct_url.url - if direct_url.archive_info.hashes: - hash_algorithm, hash_value = next( - iter(direct_url.archive_info.hashes.items()) - ) - fragments.append(f"{hash_algorithm}={hash_value}") - else: - assert direct_url.dir_info - requirement += direct_url.url - if direct_url.subdirectory: - fragments.append("subdirectory=" + direct_url.subdirectory) - if fragments: - requirement += "#" + "&".join(fragments) - return requirement - - -def direct_url_for_editable(source_dir: str) -> DirectUrl: - return DirectUrl( - url=path_to_url(source_dir), - dir_info=DirInfo(editable=True), - ) - - -def direct_url_from_link( - link: Link, source_dir: str | None = None, link_is_in_wheel_cache: bool = False -) -> DirectUrl: - if link.is_vcs: - vcs_backend = vcs.get_backend_for_scheme(link.scheme) - assert vcs_backend - url, requested_revision, _ = vcs_backend.get_url_rev_and_auth( - link.url_without_fragment - ) - # For VCS links, we need to find out and add commit_id. - if link_is_in_wheel_cache: - # If the requested VCS link corresponds to a cached - # wheel, it means the requested revision was an - # immutable commit hash, otherwise it would not have - # been cached. In that case we don't have a source_dir - # with the VCS checkout. - assert requested_revision - commit_id = requested_revision - else: - # If the wheel was not in cache, it means we have - # had to checkout from VCS to build and we have a source_dir - # which we can inspect to find out the commit id. - assert source_dir - commit_id = vcs_backend.get_revision(source_dir) - return DirectUrl( - url=url, - vcs_info=VcsInfo( - vcs=vcs_backend.name, - commit_id=commit_id, - requested_revision=requested_revision, - ), - subdirectory=link.subdirectory_fragment, - ) - elif link.is_existing_dir(): - return DirectUrl( - url=link.url_without_fragment, - dir_info=DirInfo(), - subdirectory=link.subdirectory_fragment, - ) - else: - if link.hash_name: - assert link.hash - hashes = {link.hash_name: link.hash} - else: - hashes = None - return DirectUrl( - url=link.url_without_fragment, - archive_info=ArchiveInfo(hashes=hashes), - subdirectory=link.subdirectory_fragment, - ) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/egg_link.py b/venv/lib/python3.11/site-packages/pip/_internal/utils/egg_link.py deleted file mode 100755 index dc85a58..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/utils/egg_link.py +++ /dev/null @@ -1,81 +0,0 @@ -from __future__ import annotations - -import os -import re -import sys - -from pip._internal.locations import site_packages, user_site -from pip._internal.utils.virtualenv import ( - running_under_virtualenv, - virtualenv_no_global, -) - -__all__ = [ - "egg_link_path_from_sys_path", - "egg_link_path_from_location", -] - - -def _egg_link_names(raw_name: str) -> list[str]: - """ - Convert a Name metadata value to a .egg-link name, by applying - the same substitution as pkg_resources's safe_name function. - Note: we cannot use canonicalize_name because it has a different logic. - - We also look for the raw name (without normalization) as setuptools 69 changed - the way it names .egg-link files (https://github.com/pypa/setuptools/issues/4167). - """ - return [ - re.sub("[^A-Za-z0-9.]+", "-", raw_name) + ".egg-link", - f"{raw_name}.egg-link", - ] - - -def egg_link_path_from_sys_path(raw_name: str) -> str | None: - """ - Look for a .egg-link file for project name, by walking sys.path. - """ - egg_link_names = _egg_link_names(raw_name) - for path_item in sys.path: - for egg_link_name in egg_link_names: - egg_link = os.path.join(path_item, egg_link_name) - if os.path.isfile(egg_link): - return egg_link - return None - - -def egg_link_path_from_location(raw_name: str) -> str | None: - """ - 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: list[str] = [] - if running_under_virtualenv(): - sites.append(site_packages) - if not virtualenv_no_global() and user_site: - sites.append(user_site) - else: - if user_site: - sites.append(user_site) - sites.append(site_packages) - - egg_link_names = _egg_link_names(raw_name) - for site in sites: - for egg_link_name in egg_link_names: - egglink = os.path.join(site, egg_link_name) - if os.path.isfile(egglink): - return egglink - return None diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/entrypoints.py b/venv/lib/python3.11/site-packages/pip/_internal/utils/entrypoints.py deleted file mode 100755 index e3a150e..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/utils/entrypoints.py +++ /dev/null @@ -1,88 +0,0 @@ -from __future__ import annotations - -import itertools -import os -import shutil -import sys - -from pip._internal.cli.main import main -from pip._internal.utils.compat import WINDOWS - -_EXECUTABLE_NAMES = [ - "pip", - f"pip{sys.version_info.major}", - f"pip{sys.version_info.major}.{sys.version_info.minor}", -] -if WINDOWS: - _allowed_extensions = {"", ".exe"} - _EXECUTABLE_NAMES = [ - "".join(parts) - for parts in itertools.product(_EXECUTABLE_NAMES, _allowed_extensions) - ] - - -def _wrapper(args: list[str] | None = None) -> int: - """Central wrapper for all old entrypoints. - - Historically pip has had several entrypoints defined. Because of issues - arising from PATH, sys.path, multiple Pythons, their interactions, and most - of them having a pip installed, users suffer every time an entrypoint gets - moved. - - To alleviate this pain, and provide a mechanism for warning users and - directing them to an appropriate place for help, we now define all of - our old entrypoints as wrappers for the current one. - """ - sys.stderr.write( - "WARNING: pip is being invoked by an old script wrapper. This will " - "fail in a future version of pip.\n" - "Please see https://github.com/pypa/pip/issues/5599 for advice on " - "fixing the underlying issue.\n" - "To avoid this problem you can invoke Python with '-m pip' instead of " - "running pip directly.\n" - ) - return main(args) - - -def get_best_invocation_for_this_pip() -> str: - """Try to figure out the best way to invoke pip in the current environment.""" - binary_directory = "Scripts" if WINDOWS else "bin" - binary_prefix = os.path.join(sys.prefix, binary_directory) - - # Try to use pip[X[.Y]] names, if those executables for this environment are - # the first on PATH with that name. - path_parts = os.path.normcase(os.environ.get("PATH", "")).split(os.pathsep) - exe_are_in_PATH = os.path.normcase(binary_prefix) in path_parts - if exe_are_in_PATH: - for exe_name in _EXECUTABLE_NAMES: - found_executable = shutil.which(exe_name) - binary_executable = os.path.join(binary_prefix, exe_name) - if ( - found_executable - and os.path.exists(binary_executable) - and os.path.samefile( - found_executable, - binary_executable, - ) - ): - return exe_name - - # Use the `-m` invocation, if there's no "nice" invocation. - return f"{get_best_invocation_for_this_python()} -m pip" - - -def get_best_invocation_for_this_python() -> str: - """Try to figure out the best way to invoke the current Python.""" - exe = sys.executable - exe_name = os.path.basename(exe) - - # Try to use the basename, if it's the first executable. - found_executable = shutil.which(exe_name) - # Virtual environments often symlink to their parent Python binaries, but we don't - # want to treat the Python binaries as equivalent when the environment's Python is - # not on PATH (not activated). Thus, we don't follow symlinks. - if found_executable and os.path.samestat(os.lstat(found_executable), os.lstat(exe)): - return exe_name - - # Use the full executable name, because we couldn't find something simpler. - return exe diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/filesystem.py b/venv/lib/python3.11/site-packages/pip/_internal/utils/filesystem.py deleted file mode 100755 index 806aae0..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/utils/filesystem.py +++ /dev/null @@ -1,201 +0,0 @@ -from __future__ import annotations - -import fnmatch -import os -import os.path -import random -import sys -from collections.abc import Callable, Generator -from contextlib import contextmanager -from pathlib import Path -from tempfile import NamedTemporaryFile -from typing import Any, BinaryIO, cast - -from pip._internal.utils.compat import get_path_uid -from pip._internal.utils.misc import format_size -from pip._internal.utils.retry import retry - - -def check_path_owner(path: str) -> bool: - # If we don't have a way to check the effective uid of this process, then - # we'll just assume that we own the directory. - if sys.platform == "win32" or not hasattr(os, "geteuid"): - return True - - assert os.path.isabs(path) - - previous = None - while path != previous: - if os.path.lexists(path): - # 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) - return False # assume we don't own the path - - -@contextmanager -def adjacent_tmp_file(path: str, **kwargs: Any) -> Generator[BinaryIO, None, None]: - """Return a file-like object pointing to a tmp file next to path. - - The file is created securely and is ensured to be written to disk - after the context reaches its end. - - kwargs will be passed to tempfile.NamedTemporaryFile to control - the way the temporary file will be opened. - """ - with NamedTemporaryFile( - delete=False, - dir=os.path.dirname(path), - prefix=os.path.basename(path), - suffix=".tmp", - **kwargs, - ) as f: - result = cast(BinaryIO, f) - try: - yield result - finally: - result.flush() - os.fsync(result.fileno()) - - -replace = retry(stop_after_delay=1, wait=0.25)(os.replace) - - -# test_writable_dir and _test_writable_dir_win are copied from Flit, -# with the author's agreement to also place them under pip's license. -def test_writable_dir(path: str) -> bool: - """Check if a directory is writable. - - Uses os.access() on POSIX, tries creating files on Windows. - """ - # If the directory doesn't exist, find the closest parent that does. - while not os.path.isdir(path): - parent = os.path.dirname(path) - if parent == path: - break # Should never get here, but infinite loops are bad - path = parent - - if os.name == "posix": - return os.access(path, os.W_OK) - - return _test_writable_dir_win(path) - - -def _test_writable_dir_win(path: str) -> bool: - # os.access doesn't work on Windows: http://bugs.python.org/issue2528 - # and we can't use tempfile: http://bugs.python.org/issue22107 - basename = "accesstest_deleteme_fishfingers_custard_" - alphabet = "abcdefghijklmnopqrstuvwxyz0123456789" - for _ in range(10): - name = basename + "".join(random.choice(alphabet) for _ in range(6)) - file = os.path.join(path, name) - try: - fd = os.open(file, os.O_RDWR | os.O_CREAT | os.O_EXCL) - except FileExistsError: - pass - except PermissionError: - # This could be because there's a directory with the same name. - # But it's highly unlikely there's a directory called that, - # so we'll assume it's because the parent dir is not writable. - # This could as well be because the parent dir is not readable, - # due to non-privileged user access. - return False - else: - os.close(fd) - os.unlink(file) - return True - - # This should never be reached - raise OSError("Unexpected condition testing for writable directory") - - -def find_files(path: str, pattern: str) -> list[str]: - """Returns a list of absolute paths of files beneath path, recursively, - with filenames which match the UNIX-style shell glob pattern.""" - result: list[str] = [] - for root, _, files in os.walk(path): - matches = fnmatch.filter(files, pattern) - result.extend(os.path.join(root, f) for f in matches) - return result - - -def file_size(path: str) -> int | float: - # If it's a symlink, return 0. - if os.path.islink(path): - return 0 - return os.path.getsize(path) - - -def format_file_size(path: str) -> str: - return format_size(file_size(path)) - - -def directory_size(path: str) -> int | float: - size = 0.0 - for root, _dirs, files in os.walk(path): - for filename in files: - file_path = os.path.join(root, filename) - size += file_size(file_path) - return size - - -def format_directory_size(path: str) -> str: - return format_size(directory_size(path)) - - -def copy_directory_permissions(directory: str, target_file: BinaryIO) -> None: - mode = ( - os.stat(directory).st_mode & 0o666 # select read/write permissions of directory - | 0o600 # set owner read/write permissions - ) - # Change permissions only if there is no risk of following a symlink. - if os.chmod in os.supports_fd: - os.chmod(target_file.fileno(), mode) - elif os.chmod in os.supports_follow_symlinks: - os.chmod(target_file.name, mode, follow_symlinks=False) - - -def _subdirs_without_generic( - path: str, predicate: Callable[[str, list[str]], bool] -) -> Generator[Path]: - """Yields every subdirectory of +path+ that has no files matching the - predicate under it.""" - - directories = [] - excluded: set[Path] = set() - - for root_str, _, filenames in os.walk(Path(path).resolve()): - root = Path(root_str) - if predicate(root_str, filenames): - # This directory should be excluded, so exclude it and all of its - # parent directories. - # The last item in root.parents is ".", so we ignore it. - excluded.update(root.parents[:-1]) - excluded.add(root) - directories.append(root) - - for d in sorted(directories, reverse=True): - if d not in excluded: - yield d - - -def subdirs_without_files(path: str) -> Generator[Path]: - """Yields every subdirectory of +path+ that has no files under it.""" - return _subdirs_without_generic(path, lambda root, filenames: len(filenames) > 0) - - -def subdirs_without_wheels(path: str) -> Generator[Path]: - """Yields every subdirectory of +path+ that has no .whl files under it.""" - return _subdirs_without_generic( - path, lambda root, filenames: any(x.endswith(".whl") for x in filenames) - ) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/filetypes.py b/venv/lib/python3.11/site-packages/pip/_internal/utils/filetypes.py deleted file mode 100755 index 2b8baad..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/utils/filetypes.py +++ /dev/null @@ -1,24 +0,0 @@ -"""Filetype information.""" - -from pip._internal.utils.misc import splitext - -WHEEL_EXTENSION = ".whl" -BZ2_EXTENSIONS: tuple[str, ...] = (".tar.bz2", ".tbz") -XZ_EXTENSIONS: tuple[str, ...] = ( - ".tar.xz", - ".txz", - ".tlz", - ".tar.lz", - ".tar.lzma", -) -ZIP_EXTENSIONS: tuple[str, ...] = (".zip", WHEEL_EXTENSION) -TAR_EXTENSIONS: tuple[str, ...] = (".tar.gz", ".tgz", ".tar") -ARCHIVE_EXTENSIONS = ZIP_EXTENSIONS + BZ2_EXTENSIONS + TAR_EXTENSIONS + XZ_EXTENSIONS - - -def is_archive_file(name: str) -> bool: - """Return True if `name` is a considered as an archive file.""" - ext = splitext(name)[1].lower() - if ext in ARCHIVE_EXTENSIONS: - return True - return False diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/glibc.py b/venv/lib/python3.11/site-packages/pip/_internal/utils/glibc.py deleted file mode 100755 index 2cb3013..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/utils/glibc.py +++ /dev/null @@ -1,102 +0,0 @@ -from __future__ import annotations - -import os -import sys - - -def glibc_version_string() -> str | None: - "Returns glibc version string, or None if not using glibc." - return glibc_version_string_confstr() or glibc_version_string_ctypes() - - -def glibc_version_string_confstr() -> str | None: - "Primary implementation of glibc_version_string using os.confstr." - # os.confstr is quite a bit faster than ctypes.DLL. It's also less likely - # to be broken or missing. This strategy is used in the standard library - # platform module: - # https://github.com/python/cpython/blob/fcf1d003bf4f0100c9d0921ff3d70e1127ca1b71/Lib/platform.py#L175-L183 - if sys.platform == "win32": - return None - try: - gnu_libc_version = os.confstr("CS_GNU_LIBC_VERSION") - if gnu_libc_version is None: - return None - # os.confstr("CS_GNU_LIBC_VERSION") returns a string like "glibc 2.17": - _, version = gnu_libc_version.split() - except (AttributeError, OSError, ValueError): - # os.confstr() or CS_GNU_LIBC_VERSION not available (or a bad value)... - return None - return version - - -def glibc_version_string_ctypes() -> str | None: - "Fallback implementation of glibc_version_string using ctypes." - - try: - import ctypes - except ImportError: - return None - - # ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen - # manpage says, "If filename is NULL, then the returned handle is for the - # main program". This way we can let the linker do the work to figure out - # which libc our process is actually using. - # - # We must also handle the special case where the executable is not a - # dynamically linked executable. This can occur when using musl libc, - # for example. In this situation, dlopen() will error, leading to an - # OSError. Interestingly, at least in the case of musl, there is no - # errno set on the OSError. The single string argument used to construct - # OSError comes from libc itself and is therefore not portable to - # hard code here. In any case, failure to call dlopen() means we - # can't proceed, so we bail on our attempt. - try: - process_namespace = ctypes.CDLL(None) - except OSError: - return None - - try: - gnu_get_libc_version = process_namespace.gnu_get_libc_version - except AttributeError: - # Symbol doesn't exist -> therefore, we are not linked to - # glibc. - return None - - # Call gnu_get_libc_version, which returns a string like "2.5" - gnu_get_libc_version.restype = ctypes.c_char_p - version_str: str = gnu_get_libc_version() - # py2 / py3 compatibility: - if not isinstance(version_str, str): - version_str = version_str.decode("ascii") - - return version_str - - -# 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() -> tuple[str, str]: - """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.11/site-packages/pip/_internal/utils/hashes.py b/venv/lib/python3.11/site-packages/pip/_internal/utils/hashes.py deleted file mode 100755 index 43f14cf..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/utils/hashes.py +++ /dev/null @@ -1,150 +0,0 @@ -from __future__ import annotations - -import hashlib -from collections.abc import Iterable -from typing import TYPE_CHECKING, BinaryIO, NoReturn - -from pip._internal.exceptions import HashMismatch, HashMissing, InstallationError -from pip._internal.utils.misc import read_chunks - -if TYPE_CHECKING: - from collections.abc import Mapping - from hashlib import _Hash - -# 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: - """A wrapper that builds multiple hashes at once and checks them against - known-good values - - """ - - def __init__(self, hashes: dict[str, list[str]] | None = None) -> None: - """ - :param hashes: A dict of algorithm names pointing to lists of allowed - hex digests - """ - allowed = {} - if hashes is not None: - for alg, keys in hashes.items(): - # Make sure values are always sorted (to ease equality checks) - allowed[alg] = [k.lower() for k in sorted(keys)] - self._allowed = allowed - - def __and__(self, other: Hashes) -> Hashes: - if not isinstance(other, Hashes): - return NotImplemented - - # If either of the Hashes object is entirely empty (i.e. no hash - # specified at all), all hashes from the other object are allowed. - if not other: - return self - if not self: - return other - - # Otherwise only hashes that present in both objects are allowed. - new = {} - for alg, values in other._allowed.items(): - if alg not in self._allowed: - continue - new[alg] = [v for v in values if v in self._allowed[alg]] - return Hashes(new) - - @property - def digest_count(self) -> int: - return sum(len(digests) for digests in self._allowed.values()) - - def is_hash_allowed(self, hash_name: str, hex_digest: str) -> bool: - """Return whether the given hex digest is allowed.""" - return hex_digest in self._allowed.get(hash_name, []) - - def check_against_chunks(self, chunks: Iterable[bytes]) -> None: - """Check good hashes against ones built from iterable of chunks of - data. - - Raise HashMismatch if none match. - - """ - gots = {} - for hash_name in self._allowed.keys(): - try: - gots[hash_name] = hashlib.new(hash_name) - except (ValueError, TypeError): - raise InstallationError(f"Unknown hash name: {hash_name}") - - for chunk in chunks: - for hash in gots.values(): - hash.update(chunk) - - for hash_name, got in gots.items(): - if got.hexdigest() in self._allowed[hash_name]: - return - self._raise(gots) - - def _raise(self, gots: dict[str, _Hash]) -> NoReturn: - raise HashMismatch(self._allowed, gots) - - def check_against_file(self, file: BinaryIO) -> None: - """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: str) -> None: - with open(path, "rb") as file: - return self.check_against_file(file) - - def has_one_of(self, hashes: Mapping[str, str]) -> bool: - """Return whether any of the given hashes are allowed.""" - for hash_name, hex_digest in hashes.items(): - if self.is_hash_allowed(hash_name, hex_digest): - return True - return False - - def __bool__(self) -> bool: - """Return whether I know any known-good hashes.""" - return bool(self._allowed) - - def __eq__(self, other: object) -> bool: - if not isinstance(other, Hashes): - return NotImplemented - return self._allowed == other._allowed - - def __hash__(self) -> int: - return hash( - ",".join( - sorted( - ":".join((alg, digest)) - for alg, digest_list in self._allowed.items() - for digest in digest_list - ) - ) - ) - - -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) -> None: - """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().__init__(hashes={FAVORITE_HASH: []}) - - def _raise(self, gots: dict[str, _Hash]) -> NoReturn: - raise HashMissing(gots[FAVORITE_HASH].hexdigest()) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/logging.py b/venv/lib/python3.11/site-packages/pip/_internal/utils/logging.py deleted file mode 100755 index 233ce4e..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/utils/logging.py +++ /dev/null @@ -1,404 +0,0 @@ -from __future__ import annotations - -import contextlib -import errno -import logging -import logging.handlers -import os -import sys -import threading -from collections.abc import Generator -from dataclasses import dataclass -from io import StringIO, TextIOWrapper -from logging import Filter -from typing import Any, ClassVar - -from pip._vendor.rich.console import ( - Console, - ConsoleOptions, - ConsoleRenderable, - RenderableType, - RenderResult, - RichCast, -) -from pip._vendor.rich.highlighter import NullHighlighter -from pip._vendor.rich.logging import RichHandler -from pip._vendor.rich.segment import Segment -from pip._vendor.rich.style import Style - -from pip._internal.utils._log import VERBOSE, getLogger -from pip._internal.utils.compat import WINDOWS -from pip._internal.utils.deprecation import DEPRECATION_MSG_PREFIX -from pip._internal.utils.misc import StreamWrapper, ensure_dir, looks_like_ci - -_log_state = threading.local() -_stdout_console = None -_stderr_console = None -subprocess_logger = getLogger("pip.subprocessor") - - -class BrokenStdoutLoggingError(Exception): - """ - Raised if BrokenPipeError occurs for the stdout stream while logging. - """ - - -def _is_broken_pipe_error(exc_class: type[BaseException], exc: BaseException) -> bool: - if exc_class is BrokenPipeError: - return True - - # On Windows, a broken pipe can show up as EINVAL rather than EPIPE: - # https://bugs.python.org/issue19612 - # https://bugs.python.org/issue30418 - if not WINDOWS: - return False - - return isinstance(exc, OSError) and exc.errno in (errno.EINVAL, errno.EPIPE) - - -@contextlib.contextmanager -def capture_logging() -> Generator[StringIO, None, None]: - """Capture all pip logs in a buffer temporarily.""" - # Patching sys.std(out|err) directly is not viable as the caller - # may want to emit non-logging output (e.g. a rich spinner). To - # avoid capturing that, temporarily patch the root logging handlers - # to use new rich consoles that write to a StringIO. - handlers = {} - for handler in logging.getLogger().handlers: - if isinstance(handler, RichPipStreamHandler): - # Also store the handler's original console so it can be - # restored on context exit. - handlers[handler] = handler.console - - fake_stream = StreamWrapper.from_stream(sys.stdout) - if not handlers: - yield fake_stream - return - - # HACK: grab no_color attribute from a random handler console since - # it's a global option anyway. - no_color = next(iter(handlers.values())).no_color - fake_console = PipConsole(file=fake_stream, no_color=no_color, soft_wrap=True) - try: - for handler in handlers: - handler.console = fake_console - yield fake_stream - finally: - for handler, original_console in handlers.items(): - handler.console = original_console - - -@contextlib.contextmanager -def indent_log(num: int = 2) -> Generator[None, None, None]: - """ - A context manager which will cause the log output to be indented for any - log messages emitted inside it. - """ - # For thread-safety - _log_state.indentation = get_indentation() - _log_state.indentation += num - try: - yield - finally: - _log_state.indentation -= num - - -def get_indentation() -> int: - return getattr(_log_state, "indentation", 0) - - -class IndentingFormatter(logging.Formatter): - default_time_format = "%Y-%m-%dT%H:%M:%S" - - def __init__( - self, - *args: Any, - add_timestamp: bool = False, - **kwargs: Any, - ) -> None: - """ - A logging.Formatter that obeys the indent_log() context manager. - - :param add_timestamp: A bool indicating output lines should be prefixed - with their record's timestamp. - """ - self.add_timestamp = add_timestamp - super().__init__(*args, **kwargs) - - def get_message_start(self, formatted: str, levelno: int) -> str: - """ - Return the start of the formatted log message (not counting the - prefix to add to each line). - """ - if levelno < logging.WARNING: - return "" - if formatted.startswith(DEPRECATION_MSG_PREFIX): - # Then the message already has a prefix. We don't want it to - # look like "WARNING: DEPRECATION: ...." - return "" - if levelno < logging.ERROR: - return "WARNING: " - - return "ERROR: " - - def format(self, record: logging.LogRecord) -> str: - """ - Calls the standard formatter, but will indent all of the log message - lines by our current indentation level. - """ - formatted = super().format(record) - message_start = self.get_message_start(formatted, record.levelno) - formatted = message_start + formatted - - prefix = "" - if self.add_timestamp: - prefix = f"{self.formatTime(record)} " - prefix += " " * get_indentation() - formatted = "".join([prefix + line for line in formatted.splitlines(True)]) - return formatted - - -@dataclass -class IndentedRenderable: - renderable: RenderableType - indent: int - - def __rich_console__( - self, console: Console, options: ConsoleOptions - ) -> RenderResult: - segments = console.render(self.renderable, options) - lines = Segment.split_lines(segments) - for line in lines: - yield Segment(" " * self.indent) - yield from line - yield Segment("\n") - - -class PipConsole(Console): - def on_broken_pipe(self) -> None: - # Reraise the original exception, rich 13.8.0+ exits by default - # instead, preventing our handler from firing. - raise BrokenPipeError() from None - - -def get_console(*, stderr: bool = False) -> Console: - if stderr: - assert _stderr_console is not None, "stderr rich console is missing!" - return _stderr_console - else: - assert _stdout_console is not None, "stdout rich console is missing!" - return _stdout_console - - -class RichPipStreamHandler(RichHandler): - KEYWORDS: ClassVar[list[str] | None] = [] - - def __init__(self, console: Console) -> None: - super().__init__( - console=console, - show_time=False, - show_level=False, - show_path=False, - highlighter=NullHighlighter(), - ) - - # Our custom override on Rich's logger, to make things work as we need them to. - def emit(self, record: logging.LogRecord) -> None: - style: Style | None = None - - # If we are given a diagnostic error to present, present it with indentation. - if getattr(record, "rich", False): - assert isinstance(record.args, tuple) - (rich_renderable,) = record.args - assert isinstance( - rich_renderable, (ConsoleRenderable, RichCast, str) - ), f"{rich_renderable} is not rich-console-renderable" - - renderable: RenderableType = IndentedRenderable( - rich_renderable, indent=get_indentation() - ) - else: - message = self.format(record) - renderable = self.render_message(record, message) - if record.levelno is not None: - if record.levelno >= logging.ERROR: - style = Style(color="red") - elif record.levelno >= logging.WARNING: - style = Style(color="yellow") - - try: - self.console.print(renderable, overflow="ignore", crop=False, style=style) - except Exception: - self.handleError(record) - - def handleError(self, record: logging.LogRecord) -> None: - """Called when logging is unable to log some output.""" - - exc_class, exc = sys.exc_info()[:2] - # If a broken pipe occurred while calling write() or flush() on the - # stdout stream in logging's Handler.emit(), then raise our special - # exception so we can handle it in main() instead of logging the - # broken pipe error and continuing. - if ( - exc_class - and exc - and self.console.file is sys.stdout - and _is_broken_pipe_error(exc_class, exc) - ): - raise BrokenStdoutLoggingError() - - return super().handleError(record) - - -class BetterRotatingFileHandler(logging.handlers.RotatingFileHandler): - def _open(self) -> TextIOWrapper: - ensure_dir(os.path.dirname(self.baseFilename)) - return super()._open() - - -class MaxLevelFilter(Filter): - def __init__(self, level: int) -> None: - self.level = level - - def filter(self, record: logging.LogRecord) -> bool: - return record.levelno < self.level - - -class ExcludeLoggerFilter(Filter): - """ - A logging Filter that excludes records from a logger (or its children). - """ - - def filter(self, record: logging.LogRecord) -> bool: - # The base Filter class allows only records from a logger (or its - # children). - return not super().filter(record) - - -def setup_logging(verbosity: int, no_color: bool, user_log_file: str | None) -> int: - """Configures and sets up all of the logging - - Returns the requested logging level, as its integer value. - """ - - # Determine the level to be logging at. - if verbosity >= 2: - level_number = logging.DEBUG - elif verbosity == 1: - level_number = VERBOSE - elif verbosity == -1: - level_number = logging.WARNING - elif verbosity == -2: - level_number = logging.ERROR - elif verbosity <= -3: - level_number = logging.CRITICAL - else: - level_number = logging.INFO - - level = logging.getLevelName(level_number) - - # 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 - handler_classes = { - "stream": "pip._internal.utils.logging.RichPipStreamHandler", - "file": "pip._internal.utils.logging.BetterRotatingFileHandler", - } - handlers = ["console", "console_errors", "console_subprocess"] + ( - ["user_log"] if include_user_log else [] - ) - global _stdout_console, stderr_console - console_options: dict[str, Any] = {"no_color": no_color, "soft_wrap": True} - if looks_like_ci(): - # Don't animate progress bars and status spinners when running - # in CI. A lot of CI workflows use FORCE_COLOR and similar envvars - # so their CI output remains colorized, but this causes rich to - # assume a fully interactive terminal, resulting in any animated - # output to span many lines which is distracting (and unhelpful). - console_options["force_interactive"] = False - _stdout_console = PipConsole(file=sys.stdout, **console_options) - _stderr_console = PipConsole(file=sys.stderr, **console_options) - - logging.config.dictConfig( - { - "version": 1, - "disable_existing_loggers": False, - "filters": { - "exclude_warnings": { - "()": "pip._internal.utils.logging.MaxLevelFilter", - "level": logging.WARNING, - }, - "restrict_to_subprocess": { - "()": "logging.Filter", - "name": subprocess_logger.name, - }, - "exclude_subprocess": { - "()": "pip._internal.utils.logging.ExcludeLoggerFilter", - "name": subprocess_logger.name, - }, - }, - "formatters": { - "indent": { - "()": IndentingFormatter, - "format": "%(message)s", - }, - "indent_with_timestamp": { - "()": IndentingFormatter, - "format": "%(message)s", - "add_timestamp": True, - }, - }, - "handlers": { - "console": { - "level": level, - "class": handler_classes["stream"], - "console": _stdout_console, - "filters": ["exclude_subprocess", "exclude_warnings"], - "formatter": "indent", - }, - "console_errors": { - "level": "WARNING", - "class": handler_classes["stream"], - "console": _stderr_console, - "filters": ["exclude_subprocess"], - "formatter": "indent", - }, - # A handler responsible for logging to the console messages - # from the "subprocessor" logger. - "console_subprocess": { - "level": level, - "class": handler_classes["stream"], - "console": _stderr_console, - "filters": ["restrict_to_subprocess"], - "formatter": "indent", - }, - "user_log": { - "level": "DEBUG", - "class": handler_classes["file"], - "filename": additional_log_file, - "encoding": "utf-8", - "delay": True, - "formatter": "indent_with_timestamp", - }, - }, - "root": { - "level": root_level, - "handlers": handlers, - }, - "loggers": {"pip._vendor": {"level": vendored_log_level}}, - } - ) - - return level_number diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/misc.py b/venv/lib/python3.11/site-packages/pip/_internal/utils/misc.py deleted file mode 100755 index c676029..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/utils/misc.py +++ /dev/null @@ -1,815 +0,0 @@ -from __future__ import annotations - -import errno -import getpass -import hashlib -import logging -import os -import pathlib -import posixpath -import shutil -import stat -import sys -import sysconfig -import urllib.parse -from collections.abc import Callable, Generator, Iterable, Iterator, Mapping, Sequence -from dataclasses import dataclass -from functools import partial -from io import StringIO -from itertools import filterfalse, tee, zip_longest -from pathlib import Path -from types import FunctionType, TracebackType -from typing import ( - Any, - BinaryIO, - TextIO, - TypeVar, - cast, -) - -from pip._vendor.packaging.requirements import Requirement -from pip._vendor.pyproject_hooks import BuildBackendHookCaller - -from pip import __file__ as pip_location -from pip import __version__ -from pip._internal.exceptions import CommandError, ExternallyManagedEnvironment -from pip._internal.locations import get_major_minor_version -from pip._internal.utils.compat import WINDOWS -from pip._internal.utils.retry import retry -from pip._internal.utils.virtualenv import running_under_virtualenv - -__all__ = [ - "rmtree", - "display_path", - "backup_dir", - "ask", - "splitext", - "format_size", - "is_installable_dir", - "normalize_path", - "renames", - "get_prog", - "ensure_dir", - "remove_auth_from_url", - "check_externally_managed", - "looks_like_ci", - "ConfiguredBuildBackendHookCaller", -] - -logger = logging.getLogger(__name__) - -T = TypeVar("T") -ExcInfo = tuple[type[BaseException], BaseException, TracebackType] -VersionInfo = tuple[int, int, int] -NetlocTuple = tuple[str, tuple[str | None, str | None]] -OnExc = Callable[[FunctionType, Path, BaseException], Any] -OnErr = Callable[[FunctionType, Path, ExcInfo], Any] - -FILE_CHUNK_SIZE = 1024 * 1024 -# These are environment variables present when running under various -# CI systems. For each variable, some CI systems that use the variable -# are indicated. The collection was chosen so that for each of a number -# of popular systems, at least one of the environment variables is used. -# This list is used to provide some indication of and lower bound for -# CI traffic to PyPI. Thus, it is okay if the list is not comprehensive. -# For more background, see: https://github.com/pypa/pip/issues/5499 -CI_ENVIRONMENT_VARIABLES = ( - # Azure Pipelines - "BUILD_BUILDID", - # Jenkins - "BUILD_ID", - # AppVeyor, CircleCI, Codeship, Gitlab CI, Shippable, Travis CI - "CI", - # Explicit environment variable. - "PIP_IS_CI", -) - - -def get_pip_version() -> str: - pip_pkg_dir = os.path.join(os.path.dirname(__file__), "..", "..") - pip_pkg_dir = os.path.abspath(pip_pkg_dir) - - return f"pip {__version__} from {pip_pkg_dir} (python {get_major_minor_version()})" - - -def get_runnable_pip() -> str: - """Get a file to pass to a Python executable, to run the currently-running pip. - - This is used to run a pip subprocess, for installing requirements into the build - environment. - """ - source = pathlib.Path(pip_location).resolve().parent - - if not source.is_dir(): - # This would happen if someone is using pip from inside a zip file. In that - # case, we can use that directly. - return str(source) - - return os.fsdecode(source / "__pip-runner__.py") - - -def normalize_version_info(py_version_info: tuple[int, ...]) -> tuple[int, int, int]: - """ - Convert a tuple of ints representing a Python version to one of length - three. - - :param py_version_info: a tuple of ints representing a Python version, - or None to specify no version. The tuple can have any length. - - :return: a tuple of length three if `py_version_info` is non-None. - Otherwise, return `py_version_info` unchanged (i.e. None). - """ - if len(py_version_info) < 3: - py_version_info += (3 - len(py_version_info)) * (0,) - elif len(py_version_info) > 3: - py_version_info = py_version_info[:3] - - return cast("VersionInfo", py_version_info) - - -def ensure_dir(path: str) -> None: - """os.path.makedirs without EEXIST.""" - try: - os.makedirs(path) - except OSError as e: - # Windows can raise spurious ENOTEMPTY errors. See #6426. - if e.errno != errno.EEXIST and e.errno != errno.ENOTEMPTY: - raise - - -def get_prog() -> str: - try: - prog = os.path.basename(sys.argv[0]) - if prog in ("__main__.py", "-c"): - return f"{sys.executable} -m pip" - else: - return prog - except (AttributeError, TypeError, IndexError): - pass - return "pip" - - -# Retry every half second for up to 3 seconds -@retry(stop_after_delay=3, wait=0.5) -def rmtree(dir: str, ignore_errors: bool = False, onexc: OnExc | None = None) -> None: - if ignore_errors: - onexc = _onerror_ignore - if onexc is None: - onexc = _onerror_reraise - handler: OnErr = partial(rmtree_errorhandler, onexc=onexc) - if sys.version_info >= (3, 12): - # See https://docs.python.org/3.12/whatsnew/3.12.html#shutil. - shutil.rmtree(dir, onexc=handler) # type: ignore - else: - shutil.rmtree(dir, onerror=handler) # type: ignore - - -def _onerror_ignore(*_args: Any) -> None: - pass - - -def _onerror_reraise(*_args: Any) -> None: - raise # noqa: PLE0704 - Bare exception used to reraise existing exception - - -def rmtree_errorhandler( - func: FunctionType, - path: Path, - exc_info: ExcInfo | BaseException, - *, - onexc: OnExc = _onerror_reraise, -) -> None: - """ - `rmtree` error handler to 'force' a file remove (i.e. like `rm -f`). - - * If a file is readonly then it's write flag is set and operation is - retried. - - * `onerror` is the original callback from `rmtree(... onerror=onerror)` - that is chained at the end if the "rm -f" still fails. - """ - try: - st_mode = os.stat(path).st_mode - except OSError: - # it's equivalent to os.path.exists - return - - if not st_mode & stat.S_IWRITE: - # convert to read/write - try: - os.chmod(path, st_mode | stat.S_IWRITE) - except OSError: - pass - else: - # use the original function to repeat the operation - try: - func(path) - return - except OSError: - pass - - if not isinstance(exc_info, BaseException): - _, exc_info, _ = exc_info - onexc(func, path, exc_info) - - -def display_path(path: str) -> str: - """Gives the display value for a given path, making it relative to cwd - if possible.""" - try: - relative = Path(path).relative_to(Path.cwd()) - except ValueError: - # If the path isn't relative to the CWD, leave it alone - return path - return os.path.join(".", relative) - - -def backup_dir(dir: str, ext: str = ".bak") -> str: - """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: str, options: Iterable[str]) -> str: - for action in os.environ.get("PIP_EXISTS_ACTION", "").split(): - if action in options: - return action - return ask(message, options) - - -def _check_no_input(message: str) -> None: - """Raise an error if no input is allowed.""" - if os.environ.get("PIP_NO_INPUT"): - raise Exception( - f"No input was expected ($PIP_NO_INPUT set); question: {message}" - ) - - -def ask(message: str, options: Iterable[str]) -> str: - """Ask the message interactively, with the given possible responses""" - while 1: - _check_no_input(message) - response = input(message) - response = response.strip().lower() - if response not in options: - print( - "Your response ({!r}) was not one of the expected responses: " - "{}".format(response, ", ".join(options)) - ) - else: - return response - - -def ask_input(message: str) -> str: - """Ask for input interactively.""" - _check_no_input(message) - return input(message) - - -def ask_password(message: str) -> str: - """Ask for a password interactively.""" - _check_no_input(message) - return getpass.getpass(message) - - -def strtobool(val: str) -> int: - """Convert a string representation of truth to true (1) or false (0). - - True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values - are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if - 'val' is anything else. - """ - val = val.lower() - if val in ("y", "yes", "t", "true", "on", "1"): - return 1 - elif val in ("n", "no", "f", "false", "off", "0"): - return 0 - else: - raise ValueError(f"invalid truth value {val!r}") - - -def format_size(bytes: float) -> str: - if bytes > 1000 * 1000: - return f"{bytes / 1000.0 / 1000:.1f} MB" - elif bytes > 10 * 1000: - return f"{int(bytes / 1000)} kB" - elif bytes > 1000: - return f"{bytes / 1000.0:.1f} kB" - else: - return f"{int(bytes)} bytes" - - -def tabulate(rows: Iterable[Iterable[Any]]) -> tuple[list[str], list[int]]: - """Return a list of formatted rows and a list of column sizes. - - For example:: - - >>> tabulate([['foobar', 2000], [0xdeadbeef]]) - (['foobar 2000', '3735928559'], [10, 4]) - """ - rows = [tuple(map(str, row)) for row in rows] - sizes = [max(map(len, col)) for col in zip_longest(*rows, fillvalue="")] - table = [" ".join(map(str.ljust, row, sizes)).rstrip() for row in rows] - return table, sizes - - -def is_installable_dir(path: str) -> bool: - """Is path is a directory containing pyproject.toml or setup.py? - - If pyproject.toml exists, this is a PEP 517 project. Otherwise we look for - a legacy setuptools layout by identifying setup.py. We don't check for the - setup.cfg because using it without setup.py is only available for PEP 517 - projects, which are already covered by the pyproject.toml check. - """ - if not os.path.isdir(path): - return False - if os.path.isfile(os.path.join(path, "pyproject.toml")): - return True - if os.path.isfile(os.path.join(path, "setup.py")): - return True - return False - - -def read_chunks( - file: BinaryIO, size: int = FILE_CHUNK_SIZE -) -> Generator[bytes, None, None]: - """Yield pieces of data from a file-like object until EOF.""" - while True: - chunk = file.read(size) - if not chunk: - break - yield chunk - - -def normalize_path(path: str, resolve_symlinks: bool = True) -> str: - """ - Convert a path to its canonical, case-normalized, absolute version. - - """ - path = os.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: str) -> tuple[str, str]: - """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: str, new: str) -> None: - """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: str) -> bool: - """ - 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." - - Caution: this function assumes the head of path has been normalized - with normalize_path. - """ - if not running_under_virtualenv(): - return True - return path.startswith(normalize_path(sys.prefix)) - - -def write_output(msg: Any, *args: Any) -> None: - logger.info(msg, *args) - - -class StreamWrapper(StringIO): - orig_stream: TextIO - - @classmethod - def from_stream(cls, orig_stream: TextIO) -> StreamWrapper: - ret = cls() - ret.orig_stream = orig_stream - return ret - - # compileall.compile_dir() needs stdout.encoding to print to stdout - # type ignore is because TextIOBase.encoding is writeable - @property - def encoding(self) -> str: # type: ignore - return self.orig_stream.encoding - - -# Simulates an enum -def enum(*sequential: Any, **named: Any) -> type[Any]: - 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 build_netloc(host: str, port: int | None) -> str: - """ - Build a netloc from a host-port pair - """ - if port is None: - return host - if ":" in host: - # Only wrap host with square brackets when it is IPv6 - host = f"[{host}]" - return f"{host}:{port}" - - -def build_url_from_netloc(netloc: str, scheme: str = "https") -> str: - """ - Build a full URL from a netloc. - """ - if netloc.count(":") >= 2 and "@" not in netloc and "[" not in netloc: - # It must be a bare IPv6 address, so wrap it with brackets. - netloc = f"[{netloc}]" - return f"{scheme}://{netloc}" - - -def parse_netloc(netloc: str) -> tuple[str | None, int | None]: - """ - Return the host-port pair from a netloc. - """ - url = build_url_from_netloc(netloc) - parsed = urllib.parse.urlparse(url) - return parsed.hostname, parsed.port - - -def split_auth_from_netloc(netloc: str) -> NetlocTuple: - """ - 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) - pw: str | None = None - 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, pw = auth.split(":", 1) - else: - user, pw = auth, None - - user = urllib.parse.unquote(user) - if pw is not None: - pw = urllib.parse.unquote(pw) - - return netloc, (user, pw) - - -def redact_netloc(netloc: str) -> str: - """ - Replace the sensitive data in a netloc with "****", if it exists. - - For example: - - "user:pass@example.com" returns "user:****@example.com" - - "accesstoken@example.com" returns "****@example.com" - """ - netloc, (user, password) = split_auth_from_netloc(netloc) - if user is None: - return netloc - if password is None: - user = "****" - password = "" - else: - user = urllib.parse.quote(user) - password = ":****" - return f"{user}{password}@{netloc}" - - -def _transform_url( - url: str, transform_netloc: Callable[[str], tuple[Any, ...]] -) -> tuple[str, NetlocTuple]: - """Transform and replace netloc in a url. - - transform_netloc is a function taking the netloc and returning a - tuple. The first element of this tuple is the new netloc. The - entire tuple is returned. - - Returns a tuple containing the transformed url as item 0 and the - original tuple returned by transform_netloc as item 1. - """ - purl = urllib.parse.urlsplit(url) - netloc_tuple = transform_netloc(purl.netloc) - # stripped url - url_pieces = (purl.scheme, netloc_tuple[0], purl.path, purl.query, purl.fragment) - surl = urllib.parse.urlunsplit(url_pieces) - return surl, cast("NetlocTuple", netloc_tuple) - - -def _get_netloc(netloc: str) -> NetlocTuple: - return split_auth_from_netloc(netloc) - - -def _redact_netloc(netloc: str) -> tuple[str]: - return (redact_netloc(netloc),) - - -def split_auth_netloc_from_url( - url: str, -) -> tuple[str, str, tuple[str | None, str | None]]: - """ - Parse a url into separate netloc, auth, and url with no auth. - - Returns: (url_without_auth, netloc, (username, password)) - """ - url_without_auth, (netloc, auth) = _transform_url(url, _get_netloc) - return url_without_auth, netloc, auth - - -def remove_auth_from_url(url: str) -> str: - """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. - return _transform_url(url, _get_netloc)[0] - - -def redact_auth_from_url(url: str) -> str: - """Replace the password in a given url with ****.""" - return _transform_url(url, _redact_netloc)[0] - - -def redact_auth_from_requirement(req: Requirement) -> str: - """Replace the password in a given requirement url with ****.""" - if not req.url: - return str(req) - return str(req).replace(req.url, redact_auth_from_url(req.url)) - - -@dataclass(frozen=True) -class HiddenText: - secret: str - redacted: str - - def __repr__(self) -> str: - return f"" - - def __str__(self) -> str: - return self.redacted - - def __eq__(self, other: object) -> bool: - # Equality is particularly useful for testing. - if type(self) is type(other): - # The string being used for redaction doesn't also have to match, - # just the raw, original string. - return self.secret == other.secret - return NotImplemented - - # Disable hashing, since we have a custom __eq__ and don't need hash-ability - # (yet). The only required property of hashing is that objects which compare - # equal have the same hash value. - __hash__ = None # type: ignore[assignment] - - -def hide_value(value: str) -> HiddenText: - return HiddenText(value, redacted="****") - - -def hide_url(url: str) -> HiddenText: - redacted = redact_auth_from_url(url) - return HiddenText(url, redacted=redacted) - - -def protect_pip_from_modification_on_windows(modifying_pip: bool) -> None: - """Protection of pip.exe from modification on Windows - - On Windows, any operation modifying pip should be run as: - python -m pip ... - """ - pip_names = [ - "pip", - f"pip{sys.version_info.major}", - f"pip{sys.version_info.major}.{sys.version_info.minor}", - ] - - # 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) - ) - ) - - -def check_externally_managed() -> None: - """Check whether the current environment is externally managed. - - If the ``EXTERNALLY-MANAGED`` config file is found, the current environment - is considered externally managed, and an ExternallyManagedEnvironment is - raised. - """ - if running_under_virtualenv(): - return - marker = os.path.join(sysconfig.get_path("stdlib"), "EXTERNALLY-MANAGED") - if not os.path.isfile(marker): - return - raise ExternallyManagedEnvironment.from_config(marker) - - -def is_console_interactive() -> bool: - """Is this console interactive?""" - return sys.stdin is not None and sys.stdin.isatty() - - -def hash_file(path: str, blocksize: int = 1 << 20) -> tuple[Any, int]: - """Return (hash, length) for path using hashlib.sha256()""" - - h = hashlib.sha256() - length = 0 - with open(path, "rb") as f: - for block in read_chunks(f, size=blocksize): - length += len(block) - h.update(block) - return h, length - - -def pairwise(iterable: Iterable[Any]) -> Iterator[tuple[Any, Any]]: - """ - Return paired elements. - - For example: - s -> (s0, s1), (s2, s3), (s4, s5), ... - """ - iterable = iter(iterable) - return zip_longest(iterable, iterable) - - -def partition( - pred: Callable[[T], bool], iterable: Iterable[T] -) -> tuple[Iterable[T], Iterable[T]]: - """ - Use a predicate to partition entries into false entries and true entries, - like - - partition(is_odd, range(10)) --> 0 2 4 6 8 and 1 3 5 7 9 - """ - t1, t2 = tee(iterable) - return filterfalse(pred, t1), filter(pred, t2) - - -class ConfiguredBuildBackendHookCaller(BuildBackendHookCaller): - def __init__( - self, - config_holder: Any, - source_dir: str, - build_backend: str, - backend_path: str | None = None, - runner: Callable[..., None] | None = None, - python_executable: str | None = None, - ): - super().__init__( - source_dir, build_backend, backend_path, runner, python_executable - ) - self.config_holder = config_holder - - def build_wheel( - self, - wheel_directory: str, - config_settings: Mapping[str, Any] | None = None, - metadata_directory: str | None = None, - ) -> str: - cs = self.config_holder.config_settings - return super().build_wheel( - wheel_directory, config_settings=cs, metadata_directory=metadata_directory - ) - - def build_sdist( - self, - sdist_directory: str, - config_settings: Mapping[str, Any] | None = None, - ) -> str: - cs = self.config_holder.config_settings - return super().build_sdist(sdist_directory, config_settings=cs) - - def build_editable( - self, - wheel_directory: str, - config_settings: Mapping[str, Any] | None = None, - metadata_directory: str | None = None, - ) -> str: - cs = self.config_holder.config_settings - return super().build_editable( - wheel_directory, config_settings=cs, metadata_directory=metadata_directory - ) - - def get_requires_for_build_wheel( - self, config_settings: Mapping[str, Any] | None = None - ) -> Sequence[str]: - cs = self.config_holder.config_settings - return super().get_requires_for_build_wheel(config_settings=cs) - - def get_requires_for_build_sdist( - self, config_settings: Mapping[str, Any] | None = None - ) -> Sequence[str]: - cs = self.config_holder.config_settings - return super().get_requires_for_build_sdist(config_settings=cs) - - def get_requires_for_build_editable( - self, config_settings: Mapping[str, Any] | None = None - ) -> Sequence[str]: - cs = self.config_holder.config_settings - return super().get_requires_for_build_editable(config_settings=cs) - - def prepare_metadata_for_build_wheel( - self, - metadata_directory: str, - config_settings: Mapping[str, Any] | None = None, - _allow_fallback: bool = True, - ) -> str: - cs = self.config_holder.config_settings - return super().prepare_metadata_for_build_wheel( - metadata_directory=metadata_directory, - config_settings=cs, - _allow_fallback=_allow_fallback, - ) - - def prepare_metadata_for_build_editable( - self, - metadata_directory: str, - config_settings: Mapping[str, Any] | None = None, - _allow_fallback: bool = True, - ) -> str | None: - cs = self.config_holder.config_settings - return super().prepare_metadata_for_build_editable( - metadata_directory=metadata_directory, - config_settings=cs, - _allow_fallback=_allow_fallback, - ) - - -def warn_if_run_as_root() -> None: - """Output a warning for sudo users on Unix. - - In a virtual environment, sudo pip still writes to virtualenv. - On Windows, users may run pip as Administrator without issues. - This warning only applies to Unix root users outside of virtualenv. - """ - if running_under_virtualenv(): - return - if not hasattr(os, "getuid"): - return - # On Windows, there are no "system managed" Python packages. Installing as - # Administrator via pip is the correct way of updating system environments. - # - # We choose sys.platform over utils.compat.WINDOWS here to enable Mypy platform - # checks: https://mypy.readthedocs.io/en/stable/common_issues.html - if sys.platform == "win32" or sys.platform == "cygwin": - return - - if os.getuid() != 0: - return - - logger.warning( - "Running pip as the 'root' user can result in broken permissions and " - "conflicting behaviour with the system package manager, possibly " - "rendering your system unusable. " - "It is recommended to use a virtual environment instead: " - "https://pip.pypa.io/warnings/venv. " - "Use the --root-user-action option if you know what you are doing and " - "want to suppress this warning." - ) - - -def looks_like_ci() -> bool: - """ - Return whether it looks like pip is running under CI. - """ - # We don't use the method of checking for a tty (e.g. using isatty()) - # because some CI systems mimic a tty (e.g. Travis CI). Thus that - # method doesn't provide definitive information in either direction. - return any(name in os.environ for name in CI_ENVIRONMENT_VARIABLES) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/packaging.py b/venv/lib/python3.11/site-packages/pip/_internal/utils/packaging.py deleted file mode 100755 index 3cbc049..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/utils/packaging.py +++ /dev/null @@ -1,44 +0,0 @@ -from __future__ import annotations - -import functools -import logging - -from pip._vendor.packaging import specifiers, version -from pip._vendor.packaging.requirements import Requirement - -logger = logging.getLogger(__name__) - - -@functools.lru_cache(maxsize=32) -def check_requires_python( - requires_python: str | None, version_info: tuple[int, ...] -) -> bool: - """ - Check if the given Python version matches a "Requires-Python" specifier. - - :param version_info: A 3-tuple of ints representing a Python - major-minor-micro version to check (e.g. `sys.version_info[:3]`). - - :return: `True` if the given Python version satisfies the requirement. - Otherwise, return `False`. - - :raises InvalidSpecifier: If `requires_python` has an invalid format. - """ - if requires_python is None: - # The package provides no information - return True - requires_python_specifier = specifiers.SpecifierSet(requires_python) - - python_version = version.parse(".".join(map(str, version_info))) - return python_version in requires_python_specifier - - -@functools.lru_cache(maxsize=10000) -def get_requirement(req_string: str) -> Requirement: - """Construct a packaging.Requirement object with caching""" - # Parsing requirement strings is expensive, and is also expected to happen - # with a low diversity of different arguments (at least relative the number - # constructed). This method adds a cache to requirement object creation to - # minimize repeated parsing of the same string to construct equivalent - # Requirement objects. - return Requirement(req_string) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/pylock.py b/venv/lib/python3.11/site-packages/pip/_internal/utils/pylock.py deleted file mode 100755 index 70df986..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/utils/pylock.py +++ /dev/null @@ -1,299 +0,0 @@ -from __future__ import annotations - -import os -import re -from collections.abc import Iterable, Iterator -from pathlib import Path -from typing import TYPE_CHECKING -from urllib.parse import urljoin, urlsplit - -from pip._vendor.packaging.pylock import ( - Package, - PackageArchive, - PackageDirectory, - PackageSdist, - PackageVcs, - PackageWheel, - Pylock, - is_valid_pylock_path, -) -from pip._vendor.packaging.version import Version - -from pip._internal.exceptions import DiagnosticPipError, InstallationError -from pip._internal.models.link import Link -from pip._internal.utils.compat import tomllib -from pip._internal.utils.urls import path_to_url, url_to_path - -if TYPE_CHECKING: - from pip._internal.network.session import PipSession - from pip._internal.req.req_install import InstallRequirement - - -def _pylock_package_from_install_requirement( - ireq: InstallRequirement, base_dir: Path -) -> Package: - base_dir = base_dir.resolve() - dist = ireq.get_dist() - download_info = ireq.download_info - assert download_info - package_version = None - package_vcs = None - package_directory = None - package_archive = None - package_sdist = None - package_wheels = None - if ireq.is_direct: - if download_info.vcs_info: - package_vcs = PackageVcs( - type=download_info.vcs_info.vcs, - url=download_info.url, - path=None, - requested_revision=download_info.vcs_info.requested_revision, - commit_id=download_info.vcs_info.commit_id, - subdirectory=download_info.subdirectory, - ) - elif download_info.dir_info: - package_directory = PackageDirectory( - path=( - Path(url_to_path(download_info.url)) - .resolve() - .relative_to(base_dir) - .as_posix() - ), - editable=( - download_info.dir_info.editable - if download_info.dir_info.editable - else None - ), - subdirectory=download_info.subdirectory, - ) - elif download_info.archive_info: - if not download_info.archive_info.hashes: - raise NotImplementedError() - package_archive = PackageArchive( - url=download_info.url, - path=None, - hashes=download_info.archive_info.hashes, - subdirectory=download_info.subdirectory, - ) - else: - # should never happen - raise NotImplementedError() - else: - package_version = dist.version - if download_info.archive_info: - if not download_info.archive_info.hashes: - raise NotImplementedError() - link = Link(download_info.url) - if link.is_wheel: - package_wheels = [ - PackageWheel( - name=link.filename, - url=download_info.url, - hashes=download_info.archive_info.hashes, - ) - ] - else: - package_sdist = PackageSdist( - name=link.filename, - url=download_info.url, - hashes=download_info.archive_info.hashes, - ) - else: - # should never happen - raise NotImplementedError() - return Package( - name=dist.canonical_name, - version=package_version, - vcs=package_vcs, - directory=package_directory, - archive=package_archive, - sdist=package_sdist, - wheels=package_wheels, - ) - - -def pylock_from_install_requirements( - install_requirements: Iterable[InstallRequirement], base_dir: Path -) -> Pylock: - return Pylock( - lock_version=Version("1.0"), - created_by="pip", - packages=sorted( - ( - _pylock_package_from_install_requirement(ireq, base_dir) - for ireq in install_requirements - ), - key=lambda p: p.name, - ), - ) - - -_SCHEME_RE = re.compile("^(http|https|file)://", re.IGNORECASE) - - -def _is_url(s: str) -> bool: - return bool(_SCHEME_RE.match(s)) - - -def is_valid_pylock_filename(filename: str) -> bool: - if _is_url(filename): - path = Path(urlsplit(filename).path.rpartition("/")[-1]) - else: - path = Path(filename) - return is_valid_pylock_path(path) - - -def _package_dist_url( - pylock_path_or_url: str, path: str | None, url: str | None -) -> str: - """Compute an url from a Pylock package path and url. - - Give priority to path over url. If path is relative, - compute an url using the pylock file location as base. - """ - if path is not None: - if not os.path.isabs(path): - # relative path, join to pylock location - if _is_url(pylock_path_or_url): - dist_url = urljoin(pylock_path_or_url, path) - # os.path.isabs does not treat a scheme-carrying value like - # "file:..." as absolute, so it reaches here and urljoin honors - # its scheme, discarding the pylock base. Only keep the result - # if its scheme and host still match the lock's own. - base = urlsplit(pylock_path_or_url) - target = urlsplit(dist_url) - if (target.scheme, target.netloc) != (base.scheme, base.netloc): - raise InstallationError( - f"Path {path!r} in pylock file obtained from a URL " - f"resolves outside its location: {pylock_path_or_url!r}" - ) - return dist_url - else: - return path_to_url( - os.path.join(os.path.dirname(pylock_path_or_url), path) - ) - else: - # absolute path, reject if pylock comes from a URL - if _is_url(pylock_path_or_url): - raise InstallationError( - f"Absolute paths are not supported in pylock files obtained " - f"from a URL: {path!r} in {pylock_path_or_url!r}" - ) - return path_to_url(path) - else: - assert url is not None # guaranteed by packaging.pylock validation - return url - - -def package_vcs_requirement_url( - pylock_path_or_url: str, package_vcs: PackageVcs -) -> str: - dist_url = _package_dist_url(pylock_path_or_url, package_vcs.path, package_vcs.url) - url = f"{package_vcs.type}+{dist_url}@{package_vcs.commit_id}" - if package_vcs.subdirectory: - if "#" in url: - raise InstallationError( - f"Package URL {url!r} cannot contain fragments in combination " - f"with subdirectory field (in {pylock_path_or_url!r})" - ) - url += "#subdirectory=" + package_vcs.subdirectory - return url - - -def package_archive_requirement_url( - pylock_path_or_url: str, package_archive: PackageArchive -) -> str: - url = _package_dist_url( - pylock_path_or_url, package_archive.path, package_archive.url - ) - if package_archive.subdirectory: - if "#" in url: - raise InstallationError( - f"Package URL {url!r} cannot contain fragments in combination " - f"with subdirectory field (in {pylock_path_or_url!r})" - ) - url += "#subdirectory=" + package_archive.subdirectory - return url - - -def package_directory_requirement_url( - pylock_path_or_url: str, package_directory: PackageDirectory -) -> str: - if _is_url(pylock_path_or_url) and not pylock_path_or_url.startswith("file://"): - raise InstallationError( - f"Directory entries are not supported in remote pylock.toml " - f"{pylock_path_or_url!r}" - ) - url = _package_dist_url(pylock_path_or_url, package_directory.path, None) - assert url.startswith("file://") - if not url.endswith("/"): - url += "/" - if package_directory.subdirectory: - url += package_directory.subdirectory - if not url.endswith("/"): - url += "/" - return url - - -def package_sdist_requirement_url( - pylock_path_or_url: str, package_sdist: PackageSdist -) -> str: - return _package_dist_url(pylock_path_or_url, package_sdist.path, package_sdist.url) - - -def package_wheel_requirement_url( - pylock_path_or_url: str, package_wheel: PackageWheel -) -> str: - return _package_dist_url(pylock_path_or_url, package_wheel.path, package_wheel.url) - - -def _get_pylock_path_or_url_content(path_or_url: str, session: PipSession) -> str: - # TODO: refactor - this is similar to req_file.get_file_content - scheme = urlsplit(path_or_url).scheme - # Pip has special support for file:// URLs (LocalFSAdapter). - if scheme in ["http", "https", "file"]: - # Delay importing heavy network modules until absolutely necessary. - from pip._internal.network.utils import raise_for_status - - resp = session.get(path_or_url) - raise_for_status(resp) - return resp.text - - # Assume this is a bare path. - return Path(path_or_url).read_text(encoding="utf-8") - - -def select_from_pylock_path_or_url( - pylock_path_or_url: str, - session: PipSession, -) -> Iterator[ - tuple[ - Package, - PackageVcs | PackageDirectory | PackageArchive | PackageWheel | PackageSdist, - ] -]: - try: - pylock_content = _get_pylock_path_or_url_content(pylock_path_or_url, session) - except DiagnosticPipError: - raise - except Exception as exc: - raise InstallationError( - f"Error reading pylock file {pylock_path_or_url!r}: {exc}" - ) from exc - - try: - lock = Pylock.from_dict(tomllib.loads(pylock_content)) - except Exception as exc: - raise InstallationError( - f"Invalid pylock file {pylock_path_or_url!r}: {exc}" - ) from exc - - try: - # TODO: for completeness, pylock.select should support preferring sdist - # over wheels to support --no-binary - yield from lock.select() - except Exception as exc: - raise InstallationError( - f"Cannot select requirements from pylock file {pylock_path_or_url!r}: {exc}" - ) from exc diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/retry.py b/venv/lib/python3.11/site-packages/pip/_internal/utils/retry.py deleted file mode 100755 index 1392c8f..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/utils/retry.py +++ /dev/null @@ -1,46 +0,0 @@ -from __future__ import annotations - -import functools -from collections.abc import Callable -from time import perf_counter, sleep -from typing import TYPE_CHECKING, TypeVar - -if TYPE_CHECKING: - from typing_extensions import ParamSpec - - T = TypeVar("T") - P = ParamSpec("P") - - -def retry( - wait: float, stop_after_delay: float -) -> Callable[[Callable[P, T]], Callable[P, T]]: - """Decorator to automatically retry a function on error. - - If the function raises, the function is recalled with the same arguments - until it returns or the time limit is reached. When the time limit is - surpassed, the last exception raised is reraised. - - :param wait: The time to wait after an error before retrying, in seconds. - :param stop_after_delay: The time limit after which retries will cease, - in seconds. - """ - - def wrapper(func: Callable[P, T]) -> Callable[P, T]: - - @functools.wraps(func) - def retry_wrapped(*args: P.args, **kwargs: P.kwargs) -> T: - # The performance counter is monotonic on all platforms we care - # about and has much better resolution than time.monotonic(). - start_time = perf_counter() - while True: - try: - return func(*args, **kwargs) - except Exception: - if perf_counter() - start_time > stop_after_delay: - raise - sleep(wait) - - return retry_wrapped - - return wrapper diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/subprocess.py b/venv/lib/python3.11/site-packages/pip/_internal/utils/subprocess.py deleted file mode 100755 index 06f4564..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/utils/subprocess.py +++ /dev/null @@ -1,249 +0,0 @@ -from __future__ import annotations - -import logging -import os -import shlex -import subprocess -from collections.abc import Callable, Iterable, Mapping -from typing import Any, Literal - -from pip._vendor.rich.markup import escape - -from pip._internal.cli.spinners import SpinnerInterface, open_spinner -from pip._internal.exceptions import InstallationSubprocessError -from pip._internal.utils.logging import VERBOSE, subprocess_logger -from pip._internal.utils.misc import HiddenText - -CommandArgs = list[str | HiddenText] - - -def make_command(*args: str | HiddenText | CommandArgs) -> CommandArgs: - """ - Create a CommandArgs object. - """ - command_args: CommandArgs = [] - for arg in args: - # Check for list instead of CommandArgs since CommandArgs is - # only known during type-checking. - if isinstance(arg, list): - command_args.extend(arg) - else: - # Otherwise, arg is str or HiddenText. - command_args.append(arg) - - return command_args - - -def format_command_args(args: list[str] | CommandArgs) -> str: - """ - Format command arguments for display. - """ - # For HiddenText arguments, display the redacted form by calling str(). - # Also, we don't apply str() to arguments that aren't HiddenText since - # this can trigger a UnicodeDecodeError in Python 2 if the argument - # has type unicode and includes a non-ascii character. (The type - # checker doesn't ensure the annotations are correct in all cases.) - return " ".join( - shlex.quote(str(arg)) if isinstance(arg, HiddenText) else shlex.quote(arg) - for arg in args - ) - - -def reveal_command_args(args: list[str] | CommandArgs) -> list[str]: - """ - Return the arguments in their raw, unredacted form. - """ - return [arg.secret if isinstance(arg, HiddenText) else arg for arg in args] - - -def call_subprocess( - cmd: list[str] | CommandArgs, - show_stdout: bool = False, - cwd: str | None = None, - on_returncode: Literal["raise", "warn", "ignore"] = "raise", - extra_ok_returncodes: Iterable[int] | None = None, - extra_environ: Mapping[str, Any] | None = None, - unset_environ: Iterable[str] | None = None, - spinner: SpinnerInterface | None = None, - log_failed_cmd: bool | None = True, - stdout_only: bool | None = False, - *, - command_desc: str, -) -> str: - """ - Args: - show_stdout: if true, use INFO to log the subprocess's stderr and - stdout streams. Otherwise, use DEBUG. Defaults to False. - extra_ok_returncodes: an iterable of integer return codes that are - acceptable, in addition to 0. Defaults to None, which means []. - unset_environ: an iterable of environment variable names to unset - prior to calling subprocess.Popen(). - log_failed_cmd: if false, failed commands are not logged, only raised. - stdout_only: if true, return only stdout, else return both. When true, - logging of both stdout and stderr occurs when the subprocess has - terminated, else logging occurs as subprocess output is produced. - """ - if extra_ok_returncodes is None: - extra_ok_returncodes = [] - if unset_environ is None: - unset_environ = [] - # Most places in pip use show_stdout=False. What this means is-- - # - # - We connect the child's output (combined stderr and stdout) to a - # single pipe, which we read. - # - We log this output to stderr at DEBUG level as it is received. - # - If DEBUG logging isn't enabled (e.g. if --verbose logging wasn't - # requested), then we show a spinner so the user can still see the - # subprocess is in progress. - # - If the subprocess exits with an error, we log the output to stderr - # at ERROR level if it hasn't already been displayed to the console - # (e.g. if --verbose logging wasn't enabled). This way we don't log - # the output to the console twice. - # - # If show_stdout=True, then the above is still done, but with DEBUG - # replaced by INFO. - if show_stdout: - # Then log the subprocess output at INFO level. - log_subprocess: Callable[..., None] = subprocess_logger.info - used_level = logging.INFO - else: - # Then log the subprocess output using VERBOSE. This also ensures - # it will be logged to the log file (aka user_log), if enabled. - log_subprocess = subprocess_logger.verbose - used_level = VERBOSE - - # Whether the subprocess will be visible in the console. - showing_subprocess = subprocess_logger.getEffectiveLevel() <= used_level - - # Only use the spinner if we're not showing the subprocess output - # and we have a spinner. - use_spinner = not showing_subprocess and spinner is not None - - log_subprocess("Running command %s", command_desc) - env = os.environ.copy() - if extra_environ: - env.update(extra_environ) - for name in unset_environ: - env.pop(name, None) - try: - proc = subprocess.Popen( - # Convert HiddenText objects to the underlying str. - reveal_command_args(cmd), - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT if not stdout_only else subprocess.PIPE, - cwd=cwd, - env=env, - encoding="locale", - errors="backslashreplace", - ) - except Exception as exc: - if log_failed_cmd: - subprocess_logger.critical( - "Error %s while executing command %s", - exc, - command_desc, - ) - raise - all_output = [] - if not stdout_only: - assert proc.stdout - assert proc.stdin - proc.stdin.close() - # In this mode, stdout and stderr are in the same pipe. - while True: - line: str = proc.stdout.readline() - if not line: - break - line = line.rstrip() - all_output.append(line + "\n") - - # Show the line immediately. - log_subprocess(line) - # Update the spinner. - if use_spinner: - assert spinner - spinner.spin() - try: - proc.wait() - finally: - if proc.stdout: - proc.stdout.close() - output = "".join(all_output) - else: - # In this mode, stdout and stderr are in different pipes. - # We must use communicate() which is the only safe way to read both. - out, err = proc.communicate() - # log line by line to preserve pip log indenting - for out_line in out.splitlines(): - log_subprocess(out_line) - all_output.append(out) - for err_line in err.splitlines(): - log_subprocess(err_line) - all_output.append(err) - output = out - - proc_had_error = proc.returncode and proc.returncode not in extra_ok_returncodes - if use_spinner: - assert spinner - if proc_had_error: - spinner.finish("error") - else: - spinner.finish("done") - if proc_had_error: - if on_returncode == "raise": - error = InstallationSubprocessError( - command_description=command_desc, - exit_code=proc.returncode, - output_lines=all_output if not showing_subprocess else None, - ) - if log_failed_cmd: - subprocess_logger.error("%s", error, extra={"rich": True}) - subprocess_logger.verbose( - "[bold magenta]full command[/]: [blue]%s[/]", - escape(format_command_args(cmd)), - extra={"markup": True}, - ) - subprocess_logger.verbose( - "[bold magenta]cwd[/]: %s", - escape(cwd or "[inherit]"), - extra={"markup": True}, - ) - - raise error - elif on_returncode == "warn": - subprocess_logger.warning( - 'Command "%s" had error code %s in %s', - command_desc, - proc.returncode, - cwd, - ) - elif on_returncode == "ignore": - pass - else: - raise ValueError(f"Invalid value: on_returncode={on_returncode!r}") - return output - - -def runner_with_spinner_message(message: str) -> Callable[..., None]: - """Provide a subprocess_runner that shows a spinner message. - - Intended for use with for BuildBackendHookCaller. Thus, the runner has - an API that matches what's expected by BuildBackendHookCaller.subprocess_runner. - """ - - def runner( - cmd: list[str], - cwd: str | None = None, - extra_environ: Mapping[str, Any] | None = None, - ) -> None: - with open_spinner(message) as spinner: - call_subprocess( - cmd, - command_desc=message, - cwd=cwd, - extra_environ=extra_environ, - spinner=spinner, - ) - - return runner diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/temp_dir.py b/venv/lib/python3.11/site-packages/pip/_internal/utils/temp_dir.py deleted file mode 100755 index 336c618..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/utils/temp_dir.py +++ /dev/null @@ -1,293 +0,0 @@ -from __future__ import annotations - -import errno -import itertools -import logging -import os.path -import tempfile -import traceback -from collections.abc import Callable, Generator -from contextlib import ExitStack, contextmanager -from pathlib import Path -from typing import ( - Any, - TypeVar, -) - -from pip._internal.utils.misc import enum, rmtree - -logger = logging.getLogger(__name__) - -_T = TypeVar("_T", bound="TempDirectory") - - -# Kinds of temporary directories. Only needed for ones that are -# globally-managed. -tempdir_kinds = enum( - BUILD_ENV="build-env", - EPHEM_WHEEL_CACHE="ephem-wheel-cache", - REQ_BUILD="req-build", -) - - -_tempdir_manager: ExitStack | None = None - - -@contextmanager -def global_tempdir_manager() -> Generator[None, None, None]: - global _tempdir_manager - with ExitStack() as stack: - old_tempdir_manager, _tempdir_manager = _tempdir_manager, stack - try: - yield - finally: - _tempdir_manager = old_tempdir_manager - - -class TempDirectoryTypeRegistry: - """Manages temp directory behavior""" - - def __init__(self) -> None: - self._should_delete: dict[str, bool] = {} - - def set_delete(self, kind: str, value: bool) -> None: - """Indicate whether a TempDirectory of the given kind should be - auto-deleted. - """ - self._should_delete[kind] = value - - def get_delete(self, kind: str) -> bool: - """Get configured auto-delete flag for a given TempDirectory type, - default True. - """ - return self._should_delete.get(kind, True) - - -_tempdir_registry: TempDirectoryTypeRegistry | None = None - - -@contextmanager -def tempdir_registry() -> Generator[TempDirectoryTypeRegistry, None, None]: - """Provides a scoped global tempdir registry that can be used to dictate - whether directories should be deleted. - """ - global _tempdir_registry - old_tempdir_registry = _tempdir_registry - _tempdir_registry = TempDirectoryTypeRegistry() - try: - yield _tempdir_registry - finally: - _tempdir_registry = old_tempdir_registry - - -class _Default: - pass - - -_default = _Default() - - -class TempDirectory: - """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 - delete - Whether the directory should be deleted when exiting - (when used as a contextmanager) - - Methods: - cleanup() - Deletes the temporary directory - - When used as a context manager, if the delete attribute is True, on - exiting the context the temporary directory is deleted. - """ - - def __init__( - self, - path: str | None = None, - delete: bool | None | _Default = _default, - kind: str = "temp", - globally_managed: bool = False, - ignore_cleanup_errors: bool = True, - ): - super().__init__() - - if delete is _default: - if path is not None: - # If we were given an explicit directory, resolve delete option - # now. - delete = False - else: - # Otherwise, we wait until cleanup and see what - # tempdir_registry says. - delete = None - - # The only time we specify path is in for editables where it - # is the value of the --src option. - if path is None: - path = self._create(kind) - - self._path = path - self._deleted = False - self.delete = delete - self.kind = kind - self.ignore_cleanup_errors = ignore_cleanup_errors - - if globally_managed: - assert _tempdir_manager is not None - _tempdir_manager.enter_context(self) - - @property - def path(self) -> str: - assert not self._deleted, f"Attempted to access deleted path: {self._path}" - return self._path - - def __repr__(self) -> str: - return f"<{self.__class__.__name__} {self.path!r}>" - - def __enter__(self: _T) -> _T: - return self - - def __exit__(self, exc: Any, value: Any, tb: Any) -> None: - if self.delete is not None: - delete = self.delete - elif _tempdir_registry: - delete = _tempdir_registry.get_delete(self.kind) - else: - delete = True - - if delete: - self.cleanup() - - def _create(self, kind: str) -> str: - """Create a temporary directory and store its path in self.path""" - # 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. - path = os.path.realpath(tempfile.mkdtemp(prefix=f"pip-{kind}-")) - logger.debug("Created temporary directory: %s", path) - return path - - def cleanup(self) -> None: - """Remove the temporary directory created and reset state""" - self._deleted = True - if not os.path.exists(self._path): - return - - errors: list[BaseException] = [] - - def onerror( - func: Callable[..., Any], - path: Path, - exc_val: BaseException, - ) -> None: - """Log a warning for a `rmtree` error and continue""" - formatted_exc = "\n".join( - traceback.format_exception_only(type(exc_val), exc_val) - ) - formatted_exc = formatted_exc.rstrip() # remove trailing new line - if func in (os.unlink, os.remove, os.rmdir): - logger.debug( - "Failed to remove a temporary file '%s' due to %s.\n", - path, - formatted_exc, - ) - else: - logger.debug("%s failed with %s.", func.__qualname__, formatted_exc) - errors.append(exc_val) - - if self.ignore_cleanup_errors: - try: - # first try with @retry; retrying to handle ephemeral errors - rmtree(self._path, ignore_errors=False) - except OSError: - # last pass ignore/log all errors - rmtree(self._path, onexc=onerror) - if errors: - logger.warning( - "Failed to remove contents in a temporary directory '%s'.\n" - "You can safely remove it manually.", - self._path, - ) - else: - rmtree(self._path) - - -class AdjacentTempDirectory(TempDirectory): - """Helper class that creates a temporary directory adjacent to a real one. - - Attributes: - original - The original directory to create a temp directory for. - path - After calling create() or entering, contains the full - path to the temporary directory. - delete - Whether the directory should be deleted when exiting - (when used as a contextmanager) - - """ - - # The characters that may be used to name the temp directory - # We always prepend a ~ and then rotate through these until - # a usable name is found. - # pkg_resources raises a different error for .dist-info folder - # with leading '-' and invalid metadata - LEADING_CHARS = "-~.=%0123456789" - - def __init__(self, original: str, delete: bool | None = None) -> None: - self.original = original.rstrip("/\\") - super().__init__(delete=delete) - - @classmethod - def _generate_names(cls, name: str) -> Generator[str, None, None]: - """Generates a series of temporary names. - - The algorithm replaces the leading characters in the name - with ones that are valid filesystem characters, but are not - valid package names (for both Python and pip definitions of - package). - """ - for i in range(1, len(name)): - for candidate in itertools.combinations_with_replacement( - cls.LEADING_CHARS, i - 1 - ): - new_name = "~" + "".join(candidate) + name[i:] - if new_name != name: - yield new_name - - # If we make it this far, we will have to make a longer name - for i in range(len(cls.LEADING_CHARS)): - for candidate in itertools.combinations_with_replacement( - cls.LEADING_CHARS, i - ): - new_name = "~" + "".join(candidate) + name - if new_name != name: - yield new_name - - def _create(self, kind: str) -> str: - root, name = os.path.split(self.original) - for candidate in self._generate_names(name): - path = os.path.join(root, candidate) - try: - os.mkdir(path) - except OSError as ex: - # Continue if the name exists already - if ex.errno != errno.EEXIST: - raise - else: - path = os.path.realpath(path) - break - else: - # Final fallback on the default behavior. - path = os.path.realpath(tempfile.mkdtemp(prefix=f"pip-{kind}-")) - - logger.debug("Created temporary directory: %s", path) - return path diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/unpacking.py b/venv/lib/python3.11/site-packages/pip/_internal/utils/unpacking.py deleted file mode 100755 index 5771648..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/utils/unpacking.py +++ /dev/null @@ -1,407 +0,0 @@ -"""Utilities related archives.""" - -from __future__ import annotations - -import logging -import os -import shutil -import stat -import sys -import tarfile -import zipfile -from collections.abc import Iterable -from zipfile import ZipInfo - -from pip._internal.exceptions import InstallationError -from pip._internal.utils.filetypes import ( - BZ2_EXTENSIONS, - TAR_EXTENSIONS, - XZ_EXTENSIONS, - ZIP_EXTENSIONS, -) -from pip._internal.utils.misc import ensure_dir - -logger = logging.getLogger(__name__) - - -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 current_umask() -> int: - """Get the current umask which involves having to set it temporarily.""" - mask = os.umask(0) - os.umask(mask) - return mask - - -def split_leading_dir(path: str) -> list[str]: - 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: Iterable[str]) -> bool: - """Returns true if all the paths have the same leading path name - (i.e., everything is in one subdirectory in an archive)""" - common_prefix = None - for path in paths: - prefix, rest = split_leading_dir(path) - if not prefix: - return False - elif common_prefix is None: - common_prefix = prefix - elif prefix != common_prefix: - return False - return True - - -def is_within_directory( - directory: str, target: str, *, resolve_symlinks: bool = False -) -> bool: - """ - Return true if the absolute path of target is within the directory - (including when target is equal to the directory). - - When ``resolve_symlinks`` is true, resolve symlinks before comparing so - traversal through a symlink (e.g. "link/../file") is also caught. - """ - if resolve_symlinks: - abs_directory = os.path.realpath(directory) - abs_target = os.path.realpath(target) - else: - abs_directory = os.path.abspath(directory) - abs_target = os.path.abspath(target) - - return abs_target == abs_directory or abs_target.startswith(abs_directory + os.sep) - - -def _get_default_mode_plus_executable() -> int: - return 0o777 & ~current_umask() | 0o111 - - -def set_extracted_file_to_default_mode_plus_executable(path: str) -> None: - """ - Make file present at path have execute for user/group/world - (chmod +x) is no-op on windows per python docs - """ - os.chmod(path, _get_default_mode_plus_executable()) - - -def zip_item_is_executable(info: ZipInfo) -> bool: - mode = info.external_attr >> 16 - # if mode and regular file and any execute permissions for - # user/group/world? - return bool(mode and stat.S_ISREG(mode) and mode & 0o111) - - -def unzip_file(filename: str, location: str, flatten: bool = True) -> None: - """ - Unzip the file (with path `filename`) to the destination `location`. All - files are written based on system defaults and umask (i.e. permissions are - not preserved), except that regular file members with any execute - permissions (user, group, or world) have "chmod +x" applied after being - written. Note that for windows, any execute changes using os.chmod are - no-ops per the python docs. - """ - ensure_dir(location) - zipfp = open(filename, "rb") - try: - zip = zipfile.ZipFile(zipfp, allowZip64=True) - leading = has_leading_dir(zip.namelist()) and flatten - for info in zip.infolist(): - name = info.filename - fn = name - if leading: - fn = split_leading_dir(name)[1] - fn = os.path.join(location, fn) - dir = os.path.dirname(fn) - if not is_within_directory(location, fn): - message = ( - "The zip file ({}) has a file ({}) trying to install " - "outside target directory ({})" - ) - raise InstallationError(message.format(filename, fn, location)) - if fn.endswith(("/", "\\")): - # A directory - ensure_dir(fn) - else: - ensure_dir(dir) - # Don't use read() to avoid allocating an arbitrarily large - # chunk of memory for the file's content - fp = zip.open(name) - try: - with open(fn, "wb") as destfp: - shutil.copyfileobj(fp, destfp) - finally: - fp.close() - if zip_item_is_executable(info): - set_extracted_file_to_default_mode_plus_executable(fn) - finally: - zipfp.close() - - -def untar_file(filename: str, location: str) -> None: - """ - Untar the file (with path `filename`) to the destination `location`. - All files are written based on system defaults and umask (i.e. permissions - are not preserved), except that regular file members with any execute - permissions (user, group, or world) have "chmod +x" applied on top of the - default. 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, encoding="utf-8") # type: ignore - try: - leading = has_leading_dir([member.name for member in tar.getmembers()]) - - # PEP 706 added `tarfile.data_filter`, and made some other changes to - # Python's tarfile module (see below). The features were backported to - # security releases. - try: - data_filter = tarfile.data_filter - except AttributeError: - _untar_without_filter(filename, location, tar, leading) - else: - default_mode_plus_executable = _get_default_mode_plus_executable() - - if leading: - # Strip the leading directory from all files in the archive, - # including hardlink targets (which are relative to the - # unpack location). - for member in tar.getmembers(): - name_lead, name_rest = split_leading_dir(member.name) - member.name = name_rest - if member.islnk(): - lnk_lead, lnk_rest = split_leading_dir(member.linkname) - if lnk_lead == name_lead: - member.linkname = lnk_rest - - def pip_filter(member: tarfile.TarInfo, path: str) -> tarfile.TarInfo: - orig_mode = member.mode - try: - try: - member = data_filter(member, location) - except tarfile.LinkOutsideDestinationError: - if sys.version_info[:3] in { - (3, 9, 17), - (3, 10, 12), - (3, 11, 4), - }: - # The tarfile filter in specific Python versions - # raises LinkOutsideDestinationError on valid input - # (https://github.com/python/cpython/issues/107845) - # Ignore the error there, but do use the - # more lax `tar_filter` - member = tarfile.tar_filter(member, location) - else: - raise - except tarfile.TarError as exc: - message = "Invalid member in the tar file {}: {}" - # Filter error messages mention the member name. - # No need to add it here. - raise InstallationError( - message.format( - filename, - exc, - ) - ) - if member.isfile() and orig_mode & 0o111: - member.mode = default_mode_plus_executable - else: - # See PEP 706 note above. - # The PEP changed this from `int` to `Optional[int]`, - # where None means "use the default". Mypy doesn't - # know this yet. - member.mode = None # type: ignore [assignment] - return member - - tar.extractall(location, filter=pip_filter) - - finally: - tar.close() - - -def is_symlink_target_in_tar(tar: tarfile.TarFile, tarinfo: tarfile.TarInfo) -> bool: - """Check if the file pointed to by the symbolic link is in the tar archive""" - linkname = os.path.join(os.path.dirname(tarinfo.name), tarinfo.linkname) - - linkname = os.path.normpath(linkname) - linkname = linkname.replace("\\", "/") - - try: - tar.getmember(linkname) - return True - except KeyError: - return False - - -def _untar_without_filter( - filename: str, - location: str, - tar: tarfile.TarFile, - leading: bool, -) -> None: - """Fallback for Python without tarfile.data_filter""" - # NOTE: This function can be removed once pip requires CPython ≥ 3.12.​ - # PEP 706 added tarfile.data_filter, made tarfile extraction operations more secure. - # This feature is fully supported from CPython 3.12 onward. - for member in tar.getmembers(): - fn = member.name - if leading: - fn = split_leading_dir(fn)[1] - path = os.path.join(location, fn) - - # The plain check rejects textual ".." escapes; resolving symlinks also - # catches a later member redirected outside by an earlier member's - # symlink (e.g. "link/../file"). - if not is_within_directory(location, path) or not is_within_directory( - location, path, resolve_symlinks=True - ): - message = ( - "The tar file ({}) has a file ({}) trying to install " - "outside target directory ({})" - ) - raise InstallationError(message.format(filename, path, location)) - if member.isdir(): - ensure_dir(path) - elif member.issym(): - # Reject symlinks resolving outside the destination, so a later - # member cannot be written through them. - target = os.path.join(os.path.dirname(path), member.linkname) - if not is_within_directory(location, target, resolve_symlinks=True): - message = ( - "The tar file ({}) has a file ({}) trying to install " - "outside target directory ({})" - ) - raise InstallationError( - message.format(filename, member.name, member.linkname) - ) - if not is_symlink_target_in_tar(tar, member): - message = ( - "The tar file ({}) has a file ({}) trying to install " - "outside target directory ({})" - ) - raise InstallationError( - message.format(filename, member.name, member.linkname) - ) - 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)) - assert fp is not None - 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: - set_extracted_file_to_default_mode_plus_executable(path) - - -def unpack_file( - filename: str, - location: str, - content_type: str | None = None, -) -> None: - """Unpack ``filename`` into ``location``. - - Archive format is chosen in order of decreasing reliability: - ``content_type``, then filename extension, then magic signature - (unambiguous matches only). - """ - filename = os.path.realpath(filename) - zip_flatten = not filename.endswith(".whl") - - def _unzip() -> None: - unzip_file(filename, location, flatten=zip_flatten) - - def _untar() -> None: - untar_file(filename, location) - - if content_type == "application/zip": - return _unzip() - if content_type == "application/x-gzip": - return _untar() - - if filename.lower().endswith(ZIP_EXTENSIONS): - return _unzip() - if filename.lower().endswith(TAR_EXTENSIONS + BZ2_EXTENSIONS + XZ_EXTENSIONS): - return _untar() - - # avoid ambiguous case where both signature checks return True - is_zipfile = zipfile.is_zipfile(filename) - is_tarfile = tarfile.is_tarfile(filename) - if is_zipfile and not is_tarfile: - return _unzip() - if is_tarfile and not is_zipfile: - return _untar() - if is_zipfile and is_tarfile: - logger.error("Ambiguous file signature in %s.", filename) - - logger.critical( - "Cannot unpack file %s (downloaded from %s, content-type: %s); " - "cannot detect archive format", - filename, - location, - content_type, - ) - raise InstallationError(f"Cannot determine archive format of {location}") diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/urls.py b/venv/lib/python3.11/site-packages/pip/_internal/utils/urls.py deleted file mode 100755 index 2df515d..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/utils/urls.py +++ /dev/null @@ -1,58 +0,0 @@ -import os -import string -import urllib.parse # noqa: F401 - -from .compat import WINDOWS - - -def path_to_url(path: str) -> str: - """ - Convert a path to a file: URL. The path will be made absolute and have - quoted path parts. - """ - import urllib.request - - path = os.path.normpath(os.path.abspath(path)) - url = urllib.parse.urljoin("file://", urllib.request.pathname2url(path)) - return url - - -def url_to_path(url: str) -> str: - """ - Convert a file: URL to a path. - """ - import urllib.request - - assert url.startswith( - "file:" - ), f"You can only turn file: urls into filenames (not {url!r})" - - _, netloc, path, _, _ = urllib.parse.urlsplit(url) - - if not netloc or netloc == "localhost": - # According to RFC 8089, same as empty authority. - netloc = "" - elif WINDOWS: - # If we have a UNC path, prepend UNC share notation. - netloc = "\\\\" + netloc - else: - raise ValueError( - f"non-local file URIs are not supported on this platform: {url!r}" - ) - - path = urllib.request.url2pathname(netloc + path) - - # On Windows, urlsplit parses the path as something like "/C:/Users/foo". - # This creates issues for path-related functions like io.open(), so we try - # to detect and strip the leading slash. - if ( - WINDOWS - and not netloc # Not UNC. - and len(path) >= 3 - and path[0] == "/" # Leading slash to strip. - and path[1] in string.ascii_letters # Drive letter. - and path[2:4] in (":", ":/") # Colon + end of string, or colon + absolute path. - ): - path = path[1:] - - return path diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/virtualenv.py b/venv/lib/python3.11/site-packages/pip/_internal/utils/virtualenv.py deleted file mode 100755 index fa94813..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/utils/virtualenv.py +++ /dev/null @@ -1,71 +0,0 @@ -from __future__ import annotations - -import logging -import os -import re -import sys - -logger = logging.getLogger(__name__) -_INCLUDE_SYSTEM_SITE_PACKAGES_REGEX = re.compile( - r"include-system-site-packages\s*=\s*(?Ptrue|false)" -) - - -def running_under_virtualenv() -> bool: - """Checks if sys.base_prefix and sys.prefix match. - - This handles PEP 405 compliant virtual environments. - """ - return sys.prefix != getattr(sys, "base_prefix", sys.prefix) - - -def _get_pyvenv_cfg_lines() -> list[str] | None: - """Reads {sys.prefix}/pyvenv.cfg and returns its contents as list of lines - - Returns None, if it could not read/access the file. - """ - pyvenv_cfg_file = os.path.join(sys.prefix, "pyvenv.cfg") - try: - # Although PEP 405 does not specify, the built-in venv module always - # writes with UTF-8. (pypa/pip#8717) - with open(pyvenv_cfg_file, encoding="utf-8") as f: - return f.read().splitlines() # avoids trailing newlines - except OSError: - return None - - -def _no_global_under_venv() -> bool: - """Check `{sys.prefix}/pyvenv.cfg` for system site-packages inclusion - - PEP 405 specifies that when system site-packages are not supposed to be - visible from a virtual environment, `pyvenv.cfg` must contain the following - line: - - include-system-site-packages = false - - Additionally, log a warning if accessing the file fails. - """ - cfg_lines = _get_pyvenv_cfg_lines() - if cfg_lines is None: - # We're not in a "sane" venv, so assume there is no system - # site-packages access (since that's PEP 405's default state). - logger.warning( - "Could not access 'pyvenv.cfg' despite a virtual environment " - "being active. Assuming global site-packages is not accessible " - "in this environment." - ) - return True - - for line in cfg_lines: - match = _INCLUDE_SYSTEM_SITE_PACKAGES_REGEX.match(line) - if match is not None and match.group("value") == "false": - return True - return False - - -def virtualenv_no_global() -> bool: - """Returns a boolean, whether running in venv with no system site-packages.""" - if running_under_virtualenv(): - return _no_global_under_venv() - - return False diff --git a/venv/lib/python3.11/site-packages/pip/_internal/utils/wheel.py b/venv/lib/python3.11/site-packages/pip/_internal/utils/wheel.py deleted file mode 100755 index 789e736..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/utils/wheel.py +++ /dev/null @@ -1,132 +0,0 @@ -"""Support functions for working with wheel files.""" - -import logging -from email.message import Message -from email.parser import Parser -from zipfile import BadZipFile, ZipFile - -from pip._vendor.packaging.utils import canonicalize_name - -from pip._internal.exceptions import UnsupportedWheel - -VERSION_COMPATIBLE = (1, 0) - - -logger = logging.getLogger(__name__) - - -def parse_wheel(wheel_zip: ZipFile, name: str) -> tuple[str, Message]: - """Extract information from the provided wheel, ensuring it meets basic - standards. - - Returns the name of the .dist-info directory and the parsed WHEEL metadata. - """ - try: - info_dir = wheel_dist_info_dir(wheel_zip, name) - metadata = wheel_metadata(wheel_zip, info_dir) - version = wheel_version(metadata) - except UnsupportedWheel as e: - raise UnsupportedWheel(f"{name} has an invalid wheel, {e}") - - check_compatibility(version, name) - - return info_dir, metadata - - -def wheel_dist_info_dir(source: ZipFile, name: str) -> str: - """Returns the name of the contained .dist-info directory. - - Raises AssertionError or UnsupportedWheel if not found, >1 found, or - it doesn't match the provided name. - """ - # Zip file path separators must be / - subdirs = {p.split("/", 1)[0] for p in source.namelist()} - - info_dirs = [s for s in subdirs if s.endswith(".dist-info")] - - if not info_dirs: - raise UnsupportedWheel(".dist-info directory not found") - - if len(info_dirs) > 1: - raise UnsupportedWheel( - "multiple .dist-info directories found: {}".format(", ".join(info_dirs)) - ) - - info_dir = info_dirs[0] - - info_dir_name = canonicalize_name(info_dir) - canonical_name = canonicalize_name(name) - if not info_dir_name.startswith(canonical_name): - raise UnsupportedWheel( - f".dist-info directory {info_dir!r} does not start with {canonical_name!r}" - ) - - return info_dir - - -def read_wheel_metadata_file(source: ZipFile, path: str) -> bytes: - try: - return source.read(path) - # BadZipFile for general corruption, KeyError for missing entry, - # and RuntimeError for password-protected files - except (BadZipFile, KeyError, RuntimeError) as e: - raise UnsupportedWheel(f"could not read {path!r} file: {e!r}") - - -def wheel_metadata(source: ZipFile, dist_info_dir: str) -> Message: - """Return the WHEEL metadata of an extracted wheel, if possible. - Otherwise, raise UnsupportedWheel. - """ - path = f"{dist_info_dir}/WHEEL" - # Zip file path separators must be / - wheel_contents = read_wheel_metadata_file(source, path) - - try: - wheel_text = wheel_contents.decode() - except UnicodeDecodeError as e: - raise UnsupportedWheel(f"error decoding {path!r}: {e!r}") - - # FeedParser (used by Parser) does not raise any exceptions. The returned - # message may have .defects populated, but for backwards-compatibility we - # currently ignore them. - return Parser().parsestr(wheel_text) - - -def wheel_version(wheel_data: Message) -> tuple[int, ...]: - """Given WHEEL metadata, return the parsed Wheel-Version. - Otherwise, raise UnsupportedWheel. - """ - version_text = wheel_data["Wheel-Version"] - if version_text is None: - raise UnsupportedWheel("WHEEL is missing Wheel-Version") - - version = version_text.strip() - - try: - return tuple(map(int, version.split("."))) - except ValueError: - raise UnsupportedWheel(f"invalid Wheel-Version: {version!r}") - - -def check_compatibility(version: tuple[int, ...], name: str) -> None: - """Raises errors or warns if called with an incompatible Wheel-Version. - - pip should refuse to install a Wheel-Version that's a major series - ahead of what it's compatible with (e.g 2.0 > 1.1); and warn when - installing a version only minor version ahead (e.g 1.2 > 1.1). - - version: a 2-tuple representing a Wheel-Version (Major, Minor) - name: name of wheel or package to raise exception about - - :raises UnsupportedWheel: when an incompatible Wheel-Version is given - """ - if version[0] > VERSION_COMPATIBLE[0]: - raise UnsupportedWheel( - "{}'s Wheel-Version ({}) is not compatible with this version " - "of pip".format(name, ".".join(map(str, version))) - ) - elif version > VERSION_COMPATIBLE: - logger.warning( - "Installing from a newer Wheel-Version (%s)", - ".".join(map(str, version)), - ) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/vcs/__init__.py b/venv/lib/python3.11/site-packages/pip/_internal/vcs/__init__.py deleted file mode 100755 index b6beddb..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/vcs/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# Expose a limited set of classes and functions so callers outside of -# the vcs package don't need to import deeper than `pip._internal.vcs`. -# (The test directory may still need to import from a vcs sub-package.) -# Import all vcs modules to register each VCS in the VcsSupport object. -import pip._internal.vcs.bazaar -import pip._internal.vcs.git -import pip._internal.vcs.mercurial -import pip._internal.vcs.subversion # noqa: F401 -from pip._internal.vcs.versioncontrol import ( # noqa: F401 - RemoteNotFoundError, - RemoteNotValidError, - is_url, - make_vcs_requirement_url, - vcs, -) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-311.pyc deleted file mode 100755 index 2a0cbc29807397696793fa360764c7624aaa4bc3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 631 zcmb_XJxc>Y5Z%2qmlzQd5dsDjtx|YPNGleC78WV|Dy}&;mnE+5-kx)Nf%pgf1A^cm z5dTdo3D;WL1=6K*E+!(Rb$I(8^B%ji^R~WTC0HNNuXk4tA)iIFDC}o7IYD_LUDBnB z1azj(T-~{@%+ygO?FF7L2W4FeDta|o)zzR%@#ZCIxL?I{?M5lzx)9n}(KhzXWO4Tt zz`!5#hATNYJ(-3XsJy26y$JhJ8iIJpBnT~HJ4;+N8*6zjk%=G5*b0cb^3n7={E>6W zT}<-r<+vwpzO!s=0Z|5$tGvD(rdg*iAeAQ0_m9K_nDF%mJIBziCccN$x>;>VZx((-V-Uq$?SJkhO4p= zTWQ14PX^PL3 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-311.pyc deleted file mode 100755 index 121651186ac6fc92a1ce0df97baab09c5a9b8659..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5874 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 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/vcs/__pycache__/git.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/vcs/__pycache__/git.cpython-311.pyc deleted file mode 100755 index 55c9fd6b62c1504d23fd0d79c40785ff896269bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22548 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 diff --git a/venv/lib/python3.11/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-311.pyc deleted file mode 100755 index b9042c092a026371b75f2f1f0f105279cacc96e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8777 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 N$HG5 list[str]: - return ["-r", rev] - - def fetch_new( - self, dest: str, url: HiddenText, rev_options: RevOptions, verbosity: int - ) -> None: - rev_display = rev_options.to_display() - logger.info( - "Checking out %s%s to %s", - url, - rev_display, - display_path(dest), - ) - if verbosity <= 0: - flags = ["--quiet"] - elif verbosity == 1: - flags = [] - else: - flags = [f"-{'v'*verbosity}"] - cmd_args = make_command( - "checkout", "--lightweight", *flags, rev_options.to_args(), url, dest - ) - self.run_command(cmd_args) - - def switch( - self, - dest: str, - url: HiddenText, - rev_options: RevOptions, - verbosity: int = 0, - ) -> None: - self.run_command(make_command("switch", url), cwd=dest) - - def update( - self, - dest: str, - url: HiddenText, - rev_options: RevOptions, - verbosity: int = 0, - ) -> None: - flags = [] - - if verbosity <= 0: - flags.append("-q") - - output = self.run_command( - make_command("info"), show_stdout=False, stdout_only=True, cwd=dest - ) - if output.startswith("Standalone "): - # Older versions of pip used to create standalone branches. - # Convert the standalone branch to a checkout by calling "bzr bind". - cmd_args = make_command("bind", *flags, url) - self.run_command(cmd_args, cwd=dest) - - cmd_args = make_command("update", *flags, rev_options.to_args()) - self.run_command(cmd_args, cwd=dest) - - @classmethod - def get_url_rev_and_auth(cls, url: str) -> tuple[str, str | None, AuthInfo]: - # hotfix the URL scheme after removing bzr+ from bzr+ssh:// re-add it - url, rev, user_pass = super().get_url_rev_and_auth(url) - if url.startswith("ssh://"): - url = "bzr+" + url - return url, rev, user_pass - - @classmethod - def get_remote_url(cls, location: str) -> str: - urls = cls.run_command( - ["info"], show_stdout=False, stdout_only=True, 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 cls._is_local_repository(repo): - return path_to_url(repo) - return repo - raise RemoteNotFoundError - - @classmethod - def get_revision(cls, location: str) -> str: - revision = cls.run_command( - ["revno"], - show_stdout=False, - stdout_only=True, - cwd=location, - ) - return revision.splitlines()[-1] - - @classmethod - def is_commit_id_equal(cls, dest: str, name: str | None) -> bool: - """Always assume the versions don't match""" - return False - - -vcs.register(Bazaar) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/vcs/git.py b/venv/lib/python3.11/site-packages/pip/_internal/vcs/git.py deleted file mode 100755 index 5cc393f..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/vcs/git.py +++ /dev/null @@ -1,574 +0,0 @@ -from __future__ import annotations - -import logging -import os.path -import pathlib -import re -import urllib.parse -from dataclasses import replace -from typing import Any - -from pip._internal.exceptions import BadCommand, InstallationError -from pip._internal.utils.misc import HiddenText, display_path, hide_url, strtobool -from pip._internal.utils.subprocess import make_command -from pip._internal.vcs.versioncontrol import ( - AuthInfo, - RemoteNotFoundError, - RemoteNotValidError, - RevOptions, - VersionControl, - find_path_to_project_root_from_repo_root, - vcs, -) - -urlsplit = urllib.parse.urlsplit -urlunsplit = urllib.parse.urlunsplit - - -logger = logging.getLogger(__name__) - - -GIT_VERSION_REGEX = re.compile( - r"^git version " # Prefix. - r"(\d+)" # Major. - r"\.(\d+)" # Dot, minor. - r"(?:\.(\d+))?" # Optional dot, patch. - r".*$" # Suffix, including any pre- and post-release segments we don't care about. -) - -HASH_REGEX = re.compile("^[a-fA-F0-9]{40}$") - -# SCP (Secure copy protocol) shorthand. e.g. 'git@example.com:foo/bar.git' -SCP_REGEX = re.compile( - r"""^ - # Optional user, e.g. 'git@' - (\w+@)? - # Server, e.g. 'github.com'. - ([^/:]+): - # The server-side path. e.g. 'user/project.git'. Must start with an - # alphanumeric character so as not to be confusable with a Windows paths - # like 'C:/foo/bar' or 'C:\foo\bar'. - (\w[^:]*) - $""", - re.VERBOSE, -) - - -def looks_like_hash(sha: str) -> bool: - return bool(HASH_REGEX.match(sha)) - - -class Git(VersionControl): - name = "git" - dirname = ".git" - repo_name = "clone" - schemes = ( - "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" - - @staticmethod - def get_base_rev_args(rev: str) -> list[str]: - return [rev] - - @classmethod - def run_command(cls, *args: Any, **kwargs: Any) -> str: - if os.environ.get("PIP_NO_INPUT"): - extra_environ = kwargs.get("extra_environ", {}) - extra_environ["GIT_TERMINAL_PROMPT"] = "0" - extra_environ["GIT_SSH_COMMAND"] = "ssh -oBatchMode=yes" - kwargs["extra_environ"] = extra_environ - return super().run_command(*args, **kwargs) - - def is_immutable_rev_checkout(self, url: str, dest: str) -> bool: - _, rev_options = self.get_url_rev_options(hide_url(url)) - if not rev_options.rev: - return False - if not self.is_commit_id_equal(dest, rev_options.rev): - # the current commit is different from rev, - # which means rev was something else than a commit hash - return False - # return False in the rare case rev is both a commit hash - # and a tag or a branch; we don't want to cache in that case - # because that branch/tag could point to something else in the future - is_tag_or_branch = bool(self.get_revision_sha(dest, rev_options.rev)[0]) - return not is_tag_or_branch - - def get_git_version(self) -> tuple[int, ...]: - version = self.run_command( - ["version"], - command_desc="git version", - show_stdout=False, - stdout_only=True, - ) - match = GIT_VERSION_REGEX.match(version) - if not match: - logger.warning("Can't parse git version: %s", version) - return () - return (int(match.group(1)), int(match.group(2))) - - @classmethod - def get_current_branch(cls, location: str) -> str | None: - """ - Return the current branch, or None if HEAD isn't at a branch - (e.g. detached HEAD). - """ - # git-symbolic-ref exits with empty stdout if "HEAD" is a detached - # HEAD rather than a symbolic ref. In addition, the -q causes the - # command to exit with status code 1 instead of 128 in this case - # and to suppress the message to stderr. - args = ["symbolic-ref", "-q", "HEAD"] - output = cls.run_command( - args, - extra_ok_returncodes=(1,), - show_stdout=False, - stdout_only=True, - cwd=location, - ) - ref = output.strip() - - if ref.startswith("refs/heads/"): - return ref[len("refs/heads/") :] - - return None - - @classmethod - def get_revision_sha(cls, dest: str, rev: str) -> tuple[str | None, bool]: - """ - 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 = cls.run_command( - ["show-ref", rev], - cwd=dest, - show_stdout=False, - stdout_only=True, - on_returncode="ignore", - ) - refs = {} - # NOTE: We do not use splitlines here since that would split on other - # unicode separators, which can be maliciously used to install a - # different revision. - for line in output.strip().split("\n"): - line = line.rstrip("\r") - if not line: - continue - try: - ref_sha, ref_name = line.split(" ", maxsplit=2) - except ValueError: - # Include the offending line to simplify troubleshooting if - # this error ever occurs. - raise ValueError(f"unexpected show-ref line: {line!r}") - - refs[ref_name] = ref_sha - - branch_ref = f"refs/remotes/origin/{rev}" - tag_ref = f"refs/tags/{rev}" - - sha = refs.get(branch_ref) - if sha is not None: - return (sha, True) - - sha = refs.get(tag_ref) - - return (sha, False) - - @classmethod - def _should_fetch(cls, dest: str, rev: str) -> bool: - """ - Return true if rev is a ref or is a commit that we don't have locally. - - Branches and tags are not considered in this method because they are - assumed to be always available locally (which is a normal outcome of - ``git clone`` and ``git fetch --tags``). - """ - if rev.startswith("refs/"): - # Always fetch remote refs. - return True - - if not looks_like_hash(rev): - # Git fetch would fail with abbreviated commits. - return False - - if cls.has_commit(dest, rev): - # Don't fetch if we have the commit locally. - return False - - return True - - @classmethod - def resolve_revision( - cls, dest: str, url: HiddenText, rev_options: RevOptions - ) -> RevOptions: - """ - 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 - # The arg_rev property's implementation for Git ensures that the - # rev return value is always non-None. - assert rev is not None - - sha, is_branch = cls.get_revision_sha(dest, rev) - - if sha is not None: - rev_options = rev_options.make_new(sha) - rev_options = replace(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.info( - "Did not find branch or tag '%s', assuming revision or ref.", - rev, - ) - - if not cls._should_fetch(dest, rev): - return rev_options - - # fetch the requested revision - cls.run_command( - make_command("fetch", "-q", url, rev_options.to_args()), - cwd=dest, - ) - # Change the revision to the SHA of the ref we fetched - sha = cls.get_revision(dest, rev="FETCH_HEAD") - rev_options = rev_options.make_new(sha) - - return rev_options - - @classmethod - def is_commit_id_equal(cls, dest: str, name: str | None) -> bool: - """ - 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 cls.get_revision(dest) == name - - def fetch_new( - self, dest: str, url: HiddenText, rev_options: RevOptions, verbosity: int - ) -> None: - rev_display = rev_options.to_display() - logger.info("Cloning %s%s to %s", url, rev_display, display_path(dest)) - if verbosity <= 0: - flags: tuple[str, ...] = ("--quiet",) - elif verbosity == 1: - flags = () - else: - flags = ("--verbose", "--progress") - if self.get_git_version() >= (2, 17) and not strtobool( - os.environ.get("PIP_NO_PARTIAL_CLONE_FOR_BROKEN_GIT_SERVER", "no") - ): - # Git added support for partial clone in 2.17 - # https://git-scm.com/docs/partial-clone - # Speeds up cloning by functioning without a complete copy of repository - self.run_command( - make_command( - "clone", - "--filter=blob:none", - *flags, - url, - dest, - ) - ) - else: - self.run_command(make_command("clone", *flags, 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) - logger.debug("Rev options %s, branch_name %s", rev_options, branch_name) - 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 = make_command( - "checkout", - "-q", - rev_options.to_args(), - ) - self.run_command(cmd_args, cwd=dest) - elif self.get_current_branch(dest) != branch_name: - # Then a specific branch was requested, and that branch - # is not yet checked out. - track_branch = f"origin/{branch_name}" - cmd_args = [ - "checkout", - "-b", - branch_name, - "--track", - track_branch, - ] - self.run_command(cmd_args, cwd=dest) - else: - sha = self.get_revision(dest) - rev_options = rev_options.make_new(sha) - - logger.info("Resolved %s to commit %s", url, rev_options.rev) - - #: repo may contain submodules - self.update_submodules(dest, verbosity=verbosity) - - def switch( - self, - dest: str, - url: HiddenText, - rev_options: RevOptions, - verbosity: int = 0, - ) -> None: - self.run_command( - make_command("config", "remote.origin.url", url), - cwd=dest, - ) - - extra_flags = [] - - if verbosity <= 0: - extra_flags.append("-q") - - cmd_args = make_command("checkout", *extra_flags, rev_options.to_args()) - self.run_command(cmd_args, cwd=dest) - - self.update_submodules(dest, verbosity=verbosity) - - def update( - self, - dest: str, - url: HiddenText, - rev_options: RevOptions, - verbosity: int = 0, - ) -> None: - extra_flags = [] - - if verbosity <= 0: - extra_flags.append("-q") - - # First fetch changes from the default remote - if self.get_git_version() >= (1, 9): - # fetch tags in addition to everything else - self.run_command(["fetch", "--tags", *extra_flags], cwd=dest) - else: - self.run_command(["fetch", *extra_flags], cwd=dest) - # Then reset to wanted revision (maybe even origin/master) - rev_options = self.resolve_revision(dest, url, rev_options) - cmd_args = make_command( - "reset", - "--hard", - *extra_flags, - rev_options.to_args(), - ) - self.run_command(cmd_args, cwd=dest) - #: update submodules - self.update_submodules(dest, verbosity=verbosity) - - @classmethod - def get_remote_url(cls, location: str) -> str: - """ - Return URL of the first remote encountered. - - Raises RemoteNotFoundError if the repository does not have a remote - url configured. - """ - # We need to pass 1 for extra_ok_returncodes since the command - # exits with return code 1 if there are no matching lines. - stdout = cls.run_command( - ["config", "--get-regexp", r"remote\..*\.url"], - extra_ok_returncodes=(1,), - show_stdout=False, - stdout_only=True, - cwd=location, - ) - remotes = stdout.splitlines() - try: - found_remote = remotes[0] - except IndexError: - raise RemoteNotFoundError - - for remote in remotes: - if remote.startswith("remote.origin.url "): - found_remote = remote - break - url = found_remote.split(" ")[1] - return cls._git_remote_to_pip_url(url.strip()) - - @staticmethod - def _git_remote_to_pip_url(url: str) -> str: - """ - Convert a remote url from what git uses to what pip accepts. - - There are 3 legal forms **url** may take: - - 1. A fully qualified url: ssh://git@example.com/foo/bar.git - 2. A local project.git folder: /path/to/bare/repository.git - 3. SCP shorthand for form 1: git@example.com:foo/bar.git - - Form 1 is output as-is. Form 2 must be converted to URI and form 3 must - be converted to form 1. - - See the corresponding test test_git_remote_url_to_pip() for examples of - sample inputs/outputs. - """ - if re.match(r"\w+://", url): - # This is already valid. Pass it though as-is. - return url - if os.path.exists(url): - # A local bare remote (git clone --mirror). - # Needs a file:// prefix. - return pathlib.Path(url).as_uri() - scp_match = SCP_REGEX.match(url) - if scp_match: - # Add an ssh:// prefix and replace the ':' with a '/'. - return scp_match.expand(r"ssh://\1\2/\3") - # Otherwise, bail out. - raise RemoteNotValidError(url) - - @classmethod - def has_commit(cls, location: str, rev: str) -> bool: - """ - Check if rev is a commit that is available in the local repository. - """ - try: - cls.run_command( - ["rev-parse", "-q", "--verify", rev + "^{commit}"], - cwd=location, - log_failed_cmd=False, - ) - except InstallationError: - return False - else: - return True - - @classmethod - def get_revision(cls, location: str, rev: str | None = None) -> str: - if rev is None: - rev = "HEAD" - current_rev = cls.run_command( - ["rev-parse", rev], - show_stdout=False, - stdout_only=True, - cwd=location, - ) - return current_rev.strip() - - @classmethod - def get_subdirectory(cls, location: str) -> str | None: - """ - Return the path to Python project root, relative to the repo root. - Return None if the project root is in the repo root. - """ - # find the repo root - git_dir = cls.run_command( - ["rev-parse", "--git-dir"], - show_stdout=False, - stdout_only=True, - cwd=location, - ).strip() - if not os.path.isabs(git_dir): - git_dir = os.path.join(location, git_dir) - repo_root = os.path.abspath(os.path.join(git_dir, "..")) - return find_path_to_project_root_from_repo_root(location, repo_root) - - @classmethod - def get_url_rev_and_auth(cls, url: str) -> tuple[str, str | None, AuthInfo]: - """ - 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. - """ - import urllib.request - - # Works around an apparent Git bug - # (see https://article.gmane.org/gmane.comp.version-control.git/146500) - 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("/") - after_plus = scheme.find("+") + 1 - url = scheme[:after_plus] + urlunsplit( - (scheme[after_plus:], netloc, newpath, query, fragment), - ) - - if "://" not in url: - assert "file:" not in url - url = url.replace("git+", "git+ssh://") - url, rev, user_pass = super().get_url_rev_and_auth(url) - url = url.replace("ssh://", "") - else: - url, rev, user_pass = super().get_url_rev_and_auth(url) - - return url, rev, user_pass - - @classmethod - def update_submodules(cls, location: str, verbosity: int = 0) -> None: - argv = ["submodule", "update", "--init", "--recursive"] - - if verbosity <= 0: - argv.append("-q") - - if not os.path.exists(os.path.join(location, ".gitmodules")): - return - cls.run_command( - argv, - cwd=location, - ) - - @classmethod - def get_repository_root(cls, location: str) -> str | None: - loc = super().get_repository_root(location) - if loc: - return loc - try: - r = cls.run_command( - ["rev-parse", "--show-toplevel"], - cwd=location, - show_stdout=False, - stdout_only=True, - on_returncode="raise", - log_failed_cmd=False, - ) - except BadCommand: - logger.debug( - "could not determine if %s is under git control " - "because git is not available", - location, - ) - return None - except InstallationError: - return None - return os.path.normpath(r.rstrip("\r\n")) - - @staticmethod - def should_add_vcs_url_prefix(repo_url: str) -> bool: - """In either https or ssh form, requirements must be prefixed with git+.""" - return True - - -vcs.register(Git) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/vcs/mercurial.py b/venv/lib/python3.11/site-packages/pip/_internal/vcs/mercurial.py deleted file mode 100755 index c875803..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/vcs/mercurial.py +++ /dev/null @@ -1,186 +0,0 @@ -from __future__ import annotations - -import configparser -import logging -import os - -from pip._internal.exceptions import BadCommand, InstallationError -from pip._internal.utils.misc import HiddenText, display_path -from pip._internal.utils.subprocess import make_command -from pip._internal.utils.urls import path_to_url -from pip._internal.vcs.versioncontrol import ( - RevOptions, - VersionControl, - find_path_to_project_root_from_repo_root, - vcs, -) - -logger = logging.getLogger(__name__) - - -class Mercurial(VersionControl): - name = "hg" - dirname = ".hg" - repo_name = "clone" - schemes = ( - "hg+file", - "hg+http", - "hg+https", - "hg+ssh", - "hg+static-http", - ) - - @staticmethod - def get_base_rev_args(rev: str) -> list[str]: - return [f"--rev={rev}"] - - def fetch_new( - self, dest: str, url: HiddenText, rev_options: RevOptions, verbosity: int - ) -> None: - rev_display = rev_options.to_display() - logger.info( - "Cloning hg %s%s to %s", - url, - rev_display, - display_path(dest), - ) - if verbosity <= 0: - flags: tuple[str, ...] = ("--quiet",) - elif verbosity == 1: - flags = () - elif verbosity == 2: - flags = ("--verbose",) - else: - flags = ("--verbose", "--debug") - self.run_command(make_command("clone", "--noupdate", *flags, url, dest)) - self.run_command( - make_command("update", *flags, rev_options.to_args()), - cwd=dest, - ) - - def switch( - self, - dest: str, - url: HiddenText, - rev_options: RevOptions, - verbosity: int = 0, - ) -> None: - extra_flags = [] - repo_config = os.path.join(dest, self.dirname, "hgrc") - config = configparser.RawConfigParser() - - if verbosity <= 0: - extra_flags.append("-q") - - try: - config.read(repo_config) - config.set("paths", "default", url.secret) - 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 = make_command("update", *extra_flags, rev_options.to_args()) - self.run_command(cmd_args, cwd=dest) - - def update( - self, - dest: str, - url: HiddenText, - rev_options: RevOptions, - verbosity: int = 0, - ) -> None: - extra_flags = [] - - if verbosity <= 0: - extra_flags.append("-q") - - self.run_command(["pull", *extra_flags], cwd=dest) - cmd_args = make_command("update", *extra_flags, rev_options.to_args()) - self.run_command(cmd_args, cwd=dest) - - @classmethod - def get_remote_url(cls, location: str) -> str: - url = cls.run_command( - ["showconfig", "paths.default"], - show_stdout=False, - stdout_only=True, - cwd=location, - ).strip() - if cls._is_local_repository(url): - url = path_to_url(url) - return url.strip() - - @classmethod - def get_revision(cls, location: str) -> str: - """ - Return the repository-local changeset revision number, as an integer. - """ - current_revision = cls.run_command( - ["parents", "--template={rev}"], - show_stdout=False, - stdout_only=True, - cwd=location, - ).strip() - return current_revision - - @classmethod - def get_requirement_revision(cls, location: str) -> str: - """ - Return the changeset identification hash, as a 40-character - hexadecimal string - """ - current_rev_hash = cls.run_command( - ["parents", "--template={node}"], - show_stdout=False, - stdout_only=True, - cwd=location, - ).strip() - return current_rev_hash - - @classmethod - def is_commit_id_equal(cls, dest: str, name: str | None) -> bool: - """Always assume the versions don't match""" - return False - - @classmethod - def get_subdirectory(cls, location: str) -> str | None: - """ - Return the path to Python project root, relative to the repo root. - Return None if the project root is in the repo root. - """ - # find the repo root - repo_root = cls.run_command( - ["root"], show_stdout=False, stdout_only=True, cwd=location - ).strip() - if not os.path.isabs(repo_root): - repo_root = os.path.abspath(os.path.join(location, repo_root)) - return find_path_to_project_root_from_repo_root(location, repo_root) - - @classmethod - def get_repository_root(cls, location: str) -> str | None: - loc = super().get_repository_root(location) - if loc: - return loc - try: - r = cls.run_command( - ["root"], - cwd=location, - show_stdout=False, - stdout_only=True, - on_returncode="raise", - log_failed_cmd=False, - ) - except BadCommand: - logger.debug( - "could not determine if %s is under hg control " - "because hg is not available", - location, - ) - return None - except InstallationError: - return None - return os.path.normpath(r.rstrip("\r\n")) - - -vcs.register(Mercurial) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/vcs/subversion.py b/venv/lib/python3.11/site-packages/pip/_internal/vcs/subversion.py deleted file mode 100755 index 579f428..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/vcs/subversion.py +++ /dev/null @@ -1,335 +0,0 @@ -from __future__ import annotations - -import logging -import os -import re - -from pip._internal.utils.misc import ( - HiddenText, - display_path, - is_console_interactive, - is_installable_dir, - split_auth_from_netloc, -) -from pip._internal.utils.subprocess import CommandArgs, make_command -from pip._internal.vcs.versioncontrol import ( - AuthInfo, - RemoteNotFoundError, - RevOptions, - VersionControl, - vcs, -) - -logger = logging.getLogger(__name__) - -_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"(.*)") - - -class Subversion(VersionControl): - name = "svn" - dirname = ".svn" - repo_name = "checkout" - schemes = ("svn+ssh", "svn+http", "svn+https", "svn+svn", "svn+file") - - @classmethod - def should_add_vcs_url_prefix(cls, remote_url: str) -> bool: - return True - - @staticmethod - def get_base_rev_args(rev: str) -> list[str]: - return ["-r", rev] - - @classmethod - def get_revision(cls, location: str) -> str: - """ - Return the maximum revision for all files under a given location - """ - # Note: taken from setuptools.command.egg_info - revision = 0 - - for base, dirs, _ in os.walk(location): - if cls.dirname not in dirs: - dirs[:] = [] - continue # no sense walking uncontrolled subdirs - dirs.remove(cls.dirname) - entries_fn = os.path.join(base, cls.dirname, "entries") - if not os.path.exists(entries_fn): - # FIXME: should we warn? - continue - - dirurl, localrev = cls._get_svn_url_rev(base) - - if base == location: - assert dirurl is not None - 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 str(revision) - - @classmethod - def get_netloc_and_auth( - cls, netloc: str, scheme: str - ) -> tuple[str, tuple[str | None, str | None]]: - """ - 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().get_netloc_and_auth(netloc, scheme) - - return split_auth_from_netloc(netloc) - - @classmethod - def get_url_rev_and_auth(cls, url: str) -> tuple[str, str | None, AuthInfo]: - # hotfix the URL scheme after removing svn+ from svn+ssh:// re-add it - url, rev, user_pass = super().get_url_rev_and_auth(url) - if url.startswith("ssh://"): - url = "svn+" + url - return url, rev, user_pass - - @staticmethod - def make_rev_args(username: str | None, password: HiddenText | None) -> CommandArgs: - extra_args: CommandArgs = [] - if username: - extra_args += ["--username", username] - if password: - extra_args += ["--password", password] - - return extra_args - - @classmethod - def get_remote_url(cls, location: str) -> str: - # In cases where the source is in a subdirectory, we have to look up in - # the location until we find a valid project root. - orig_location = location - while not is_installable_dir(location): - last_location = location - location = os.path.dirname(location) - if location == last_location: - # We've traversed up to the root of the filesystem without - # finding a Python project. - logger.warning( - "Could not find Python project for directory %s (tried all " - "parent directories)", - orig_location, - ) - raise RemoteNotFoundError - - url, _rev = cls._get_svn_url_rev(location) - if url is None: - raise RemoteNotFoundError - - return url - - @classmethod - def _get_svn_url_rev(cls, location: str) -> tuple[str | None, int]: - from pip._internal.exceptions import InstallationError - - entries_path = os.path.join(location, cls.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 = "" - - url = None - if data.startswith(("8", "9", "10")): - entries = list(map(str.splitlines, data.split("\n\x0c\n"))) - del entries[0][0] # get rid of the '8' - url = entries[0][3] - revs = [int(d[9]) for d in entries if len(d) > 9 and d[9]] + [0] - elif data.startswith("= 1.7 - # Note that using get_remote_call_options is not necessary here - # because `svn info` is being run against a local directory. - # We don't need to worry about making sure interactive mode - # is being used to prompt for passwords, because passwords - # are only potentially needed for remote server requests. - xml = cls.run_command( - ["info", "--xml", location], - show_stdout=False, - stdout_only=True, - ) - match = _svn_info_xml_url_re.search(xml) - assert match is not None - url = match.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 - - @classmethod - def is_commit_id_equal(cls, dest: str, name: str | None) -> bool: - """Always assume the versions don't match""" - return False - - def __init__(self, use_interactive: bool | None = None) -> None: - if use_interactive is None: - use_interactive = is_console_interactive() - self.use_interactive = use_interactive - - # This member is used to cache the fetched version of the current - # ``svn`` client. - # Special value definitions: - # None: Not evaluated yet. - # Empty tuple: Could not parse version. - self._vcs_version: tuple[int, ...] | None = None - - super().__init__() - - def call_vcs_version(self) -> tuple[int, ...]: - """Query the version of the currently installed Subversion client. - - :return: A tuple containing the parts of the version information or - ``()`` if the version returned from ``svn`` could not be parsed. - :raises: BadCommand: If ``svn`` is not installed. - """ - # Example versions: - # svn, version 1.10.3 (r1842928) - # compiled Feb 25 2019, 14:20:39 on x86_64-apple-darwin17.0.0 - # svn, version 1.7.14 (r1542130) - # compiled Mar 28 2018, 08:49:13 on x86_64-pc-linux-gnu - # svn, version 1.12.0-SlikSvn (SlikSvn/1.12.0) - # compiled May 28 2019, 13:44:56 on x86_64-microsoft-windows6.2 - version_prefix = "svn, version " - version = self.run_command(["--version"], show_stdout=False, stdout_only=True) - if not version.startswith(version_prefix): - return () - - version = version[len(version_prefix) :].split()[0] - version_list = version.partition("-")[0].split(".") - try: - parsed_version = tuple(map(int, version_list)) - except ValueError: - return () - - return parsed_version - - def get_vcs_version(self) -> tuple[int, ...]: - """Return the version of the currently installed Subversion client. - - If the version of the Subversion client has already been queried, - a cached value will be used. - - :return: A tuple containing the parts of the version information or - ``()`` if the version returned from ``svn`` could not be parsed. - :raises: BadCommand: If ``svn`` is not installed. - """ - if self._vcs_version is not None: - # Use cached version, if available. - # If parsing the version failed previously (empty tuple), - # do not attempt to parse it again. - return self._vcs_version - - vcs_version = self.call_vcs_version() - self._vcs_version = vcs_version - return vcs_version - - def get_remote_call_options(self) -> CommandArgs: - """Return options to be used on calls to Subversion that contact the server. - - These options are applicable for the following ``svn`` subcommands used - in this class. - - - checkout - - switch - - update - - :return: A list of command line arguments to pass to ``svn``. - """ - if not self.use_interactive: - # --non-interactive switch is available since Subversion 0.14.4. - # Subversion < 1.8 runs in interactive mode by default. - return ["--non-interactive"] - - svn_version = self.get_vcs_version() - # By default, Subversion >= 1.8 runs in non-interactive mode if - # stdin is not a TTY. Since that is how pip invokes SVN, in - # call_subprocess(), pip must pass --force-interactive to ensure - # the user can be prompted for a password, if required. - # SVN added the --force-interactive option in SVN 1.8. Since - # e.g. RHEL/CentOS 7, which is supported until 2024, ships with - # SVN 1.7, pip should continue to support SVN 1.7. Therefore, pip - # can't safely add the option if the SVN version is < 1.8 (or unknown). - if svn_version >= (1, 8): - return ["--force-interactive"] - - return [] - - def fetch_new( - self, dest: str, url: HiddenText, rev_options: RevOptions, verbosity: int - ) -> None: - rev_display = rev_options.to_display() - logger.info( - "Checking out %s%s to %s", - url, - rev_display, - display_path(dest), - ) - if verbosity <= 0: - flags = ["--quiet"] - else: - flags = [] - cmd_args = make_command( - "checkout", - *flags, - self.get_remote_call_options(), - rev_options.to_args(), - url, - dest, - ) - self.run_command(cmd_args) - - def switch( - self, - dest: str, - url: HiddenText, - rev_options: RevOptions, - verbosity: int = 0, - ) -> None: - cmd_args = make_command( - "switch", - self.get_remote_call_options(), - rev_options.to_args(), - url, - dest, - ) - self.run_command(cmd_args) - - def update( - self, - dest: str, - url: HiddenText, - rev_options: RevOptions, - verbosity: int = 0, - ) -> None: - cmd_args = make_command( - "update", - self.get_remote_call_options(), - rev_options.to_args(), - dest, - ) - self.run_command(cmd_args) - - -vcs.register(Subversion) diff --git a/venv/lib/python3.11/site-packages/pip/_internal/vcs/versioncontrol.py b/venv/lib/python3.11/site-packages/pip/_internal/vcs/versioncontrol.py deleted file mode 100755 index 33c6b7f..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/vcs/versioncontrol.py +++ /dev/null @@ -1,694 +0,0 @@ -"""Handles all VCS (version control) support""" - -from __future__ import annotations - -import logging -import os -import shutil -import sys -import urllib.parse -from collections.abc import Iterable, Iterator, Mapping -from dataclasses import dataclass, field -from typing import ( - Any, - Literal, -) - -from pip._internal.cli.spinners import SpinnerInterface -from pip._internal.exceptions import BadCommand, InstallationError -from pip._internal.utils.misc import ( - HiddenText, - ask_path_exists, - backup_dir, - display_path, - hide_url, - hide_value, - is_installable_dir, - rmtree, -) -from pip._internal.utils.subprocess import ( - CommandArgs, - call_subprocess, - format_command_args, - make_command, -) - -__all__ = ["vcs"] - - -logger = logging.getLogger(__name__) - -AuthInfo = tuple[str | None, str | None] - - -def is_url(name: str) -> bool: - """ - Return true if the name looks like a URL. - """ - scheme = urllib.parse.urlsplit(name).scheme - if not scheme: - return False - return scheme in ["http", "https", "file", "ftp"] + vcs.all_schemes - - -def make_vcs_requirement_url( - repo_url: str, rev: str, project_name: str, subdir: str | None = None -) -> str: - """ - Return the URL for a VCS requirement. - - Args: - repo_url: the remote VCS url, with any needed VCS prefix (e.g. "git+"). - project_name: the (unescaped) project name. - """ - quoted_rev = urllib.parse.quote(rev, "/") - egg_project_name = project_name.replace("-", "_") - req = f"{repo_url}@{quoted_rev}#egg={egg_project_name}" - if subdir: - req += f"&subdirectory={subdir}" - - return req - - -def find_path_to_project_root_from_repo_root( - location: str, repo_root: str -) -> str | None: - """ - Find the the Python project's root by searching up the filesystem from - `location`. Return the path to project root relative to `repo_root`. - Return None if the project root is `repo_root`, or cannot be found. - """ - # find project root. - orig_location = location - while not is_installable_dir(location): - last_location = location - location = os.path.dirname(location) - if location == last_location: - # We've traversed up to the root of the filesystem without - # finding a Python project. - logger.warning( - "Could not find a Python project for directory %s (tried all " - "parent directories)", - orig_location, - ) - return None - - if os.path.samefile(repo_root, location): - return None - - return os.path.relpath(location, repo_root) - - -class RemoteNotFoundError(Exception): - pass - - -class RemoteNotValidError(Exception): - def __init__(self, url: str): - super().__init__(url) - self.url = url - - -@dataclass(frozen=True) -class RevOptions: - """ - Encapsulates a VCS-specific revision to install, along with any VCS - install options. - - Args: - vc_class: a VersionControl subclass. - rev: the name of the revision to install. - extra_args: a list of extra options. - """ - - vc_class: type[VersionControl] - rev: str | None = None - extra_args: CommandArgs = field(default_factory=list) - branch_name: str | None = None - - def __repr__(self) -> str: - return f"" - - @property - def arg_rev(self) -> str | None: - if self.rev is None: - return self.vc_class.default_arg_rev - - return self.rev - - def to_args(self) -> CommandArgs: - """ - Return the VCS-specific command arguments. - """ - args: CommandArgs = [] - rev = self.arg_rev - if rev is not None: - args += self.vc_class.get_base_rev_args(rev) - args += self.extra_args - - return args - - def to_display(self) -> str: - if not self.rev: - return "" - - return f" (to revision {self.rev})" - - def make_new(self, rev: str) -> RevOptions: - """ - 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.vc_class.make_rev_options(rev, extra_args=self.extra_args) - - -class VcsSupport: - _registry: dict[str, VersionControl] = {} - schemes = ["ssh", "git", "hg", "bzr", "sftp", "svn"] - - def __init__(self) -> None: - # Register more schemes with urlparse for various version control - # systems - urllib.parse.uses_netloc.extend(self.schemes) - super().__init__() - - def __iter__(self) -> Iterator[str]: - return self._registry.__iter__() - - @property - def backends(self) -> list[VersionControl]: - return list(self._registry.values()) - - @property - def dirnames(self) -> list[str]: - return [backend.dirname for backend in self.backends] - - @property - def all_schemes(self) -> list[str]: - schemes: list[str] = [] - for backend in self.backends: - schemes.extend(backend.schemes) - return schemes - - def register(self, cls: type[VersionControl]) -> None: - 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, name: str) -> None: - if name in self._registry: - del self._registry[name] - - def get_backend_for_dir(self, location: str) -> VersionControl | None: - """ - Return a VersionControl object if a repository of that type is found - at the given directory. - """ - vcs_backends = {} - for vcs_backend in self._registry.values(): - repo_path = vcs_backend.get_repository_root(location) - if not repo_path: - continue - logger.debug("Determine that %s uses VCS: %s", location, vcs_backend.name) - vcs_backends[repo_path] = vcs_backend - - if not vcs_backends: - return None - - # Choose the VCS in the inner-most directory. Since all repository - # roots found here would be either `location` or one of its - # parents, the longest path should have the most path components, - # i.e. the backend representing the inner-most repository. - inner_most_repo_path = max(vcs_backends, key=len) - return vcs_backends[inner_most_repo_path] - - def get_backend_for_scheme(self, scheme: str) -> VersionControl | None: - """ - Return a VersionControl object or None. - """ - for vcs_backend in self._registry.values(): - if scheme in vcs_backend.schemes: - return vcs_backend - return None - - def get_backend(self, name: str) -> VersionControl | None: - """ - Return a VersionControl object or None. - """ - name = name.lower() - return self._registry.get(name) - - -vcs = VcsSupport() - - -class VersionControl: - name = "" - dirname = "" - repo_name = "" - # List of supported schemes for this Version Control - schemes: tuple[str, ...] = () - # Iterable of environment variable names to pass to call_subprocess(). - unset_environ: tuple[str, ...] = () - default_arg_rev: str | None = None - - @classmethod - def should_add_vcs_url_prefix(cls, remote_url: str) -> bool: - """ - Return whether the vcs prefix (e.g. "git+") should be added to a - repository's remote url when used in a requirement. - """ - return not remote_url.lower().startswith(f"{cls.name}:") - - @classmethod - def get_subdirectory(cls, location: str) -> str | None: - """ - Return the path to Python project root, relative to the repo root. - Return None if the project root is in the repo root. - """ - return None - - @classmethod - def get_requirement_revision(cls, repo_dir: str) -> str: - """ - Return the revision string that should be used in a requirement. - """ - return cls.get_revision(repo_dir) - - @classmethod - def get_src_requirement(cls, repo_dir: str, project_name: str) -> str: - """ - Return the requirement string to use to redownload the files - currently at the given repository directory. - - Args: - project_name: the (unescaped) project name. - - The return value has a form similar to the following: - - {repository_url}@{revision}#egg={project_name} - """ - repo_url = cls.get_remote_url(repo_dir) - - if cls.should_add_vcs_url_prefix(repo_url): - repo_url = f"{cls.name}+{repo_url}" - - revision = cls.get_requirement_revision(repo_dir) - subdir = cls.get_subdirectory(repo_dir) - req = make_vcs_requirement_url(repo_url, revision, project_name, subdir=subdir) - - return req - - @staticmethod - def get_base_rev_args(rev: str) -> list[str]: - """ - Return the base revision arguments for a vcs command. - - Args: - rev: the name of a revision to install. Cannot be None. - """ - raise NotImplementedError - - def is_immutable_rev_checkout(self, url: str, dest: str) -> bool: - """ - Return true if the commit hash checked out at dest matches - the revision in url. - - Always return False, if the VCS does not support immutable commit - hashes. - - This method does not check if there are local uncommitted changes - in dest after checkout, as pip currently has no use case for that. - """ - return False - - @classmethod - def make_rev_options( - cls, rev: str | None = None, extra_args: CommandArgs | None = None - ) -> RevOptions: - """ - Return a RevOptions object. - - Args: - rev: the name of a revision to install. - extra_args: a list of extra options. - """ - return RevOptions(cls, rev, extra_args=extra_args or []) - - @classmethod - def _is_local_repository(cls, repo: str) -> bool: - """ - 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 bool(drive) - - @classmethod - def get_netloc_and_auth( - cls, netloc: str, scheme: str - ) -> tuple[str, tuple[str | None, str | None]]: - """ - 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) - - @classmethod - def get_url_rev_and_auth(cls, url: str) -> tuple[str, str | None, AuthInfo]: - """ - 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( - f"Sorry, {url!r} is a malformed VCS url. " - "The format is +://, " - "e.g. svn+http://myrepo/svn/MyApp#egg=MyApp" - ) - # Remove the vcs prefix. - scheme = scheme.split("+", 1)[1] - netloc, user_pass = cls.get_netloc_and_auth(netloc, scheme) - rev = None - if "@" in path: - path, rev = path.rsplit("@", 1) - if not rev: - raise InstallationError( - f"The URL {url!r} has an empty revision (after @) " - "which is not supported. Include a revision after @ " - "or remove @ from the URL." - ) - rev = urllib.parse.unquote(rev) - url = urllib.parse.urlunsplit((scheme, netloc, path, query, "")) - return url, rev, user_pass - - @staticmethod - def make_rev_args(username: str | None, password: HiddenText | None) -> CommandArgs: - """ - Return the RevOptions "extra arguments" to use in obtain(). - """ - return [] - - def get_url_rev_options(self, url: HiddenText) -> tuple[HiddenText, RevOptions]: - """ - Return the URL and RevOptions object to use in obtain(), - as a tuple (url, rev_options). - """ - secret_url, rev, user_pass = self.get_url_rev_and_auth(url.secret) - username, secret_password = user_pass - password: HiddenText | None = None - if secret_password is not None: - password = hide_value(secret_password) - extra_args = self.make_rev_args(username, password) - rev_options = self.make_rev_options(rev, extra_args=extra_args) - - return hide_url(secret_url), rev_options - - @staticmethod - def normalize_url(url: str) -> str: - """ - Normalize a URL for comparison by unquoting it and removing any - trailing slash. - """ - return urllib.parse.unquote(url).rstrip("/") - - @classmethod - def compare_urls(cls, url1: str, url2: str) -> bool: - """ - Compare two repo URLs for identity, ignoring incidental differences. - """ - return cls.normalize_url(url1) == cls.normalize_url(url2) - - def fetch_new( - self, dest: str, url: HiddenText, rev_options: RevOptions, verbosity: int - ) -> None: - """ - 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. - verbosity: verbosity level. - """ - raise NotImplementedError - - def switch( - self, - dest: str, - url: HiddenText, - rev_options: RevOptions, - verbosity: int = 0, - ) -> None: - """ - Switch the repo at ``dest`` to point to ``URL``. - - Args: - rev_options: a RevOptions object. - """ - raise NotImplementedError - - def update( - self, - dest: str, - url: HiddenText, - rev_options: RevOptions, - verbosity: int = 0, - ) -> None: - """ - Update an already-existing repo to the given ``rev_options``. - - Args: - rev_options: a RevOptions object. - """ - raise NotImplementedError - - @classmethod - def is_commit_id_equal(cls, dest: str, name: str | None) -> bool: - """ - 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: str, url: HiddenText, verbosity: int) -> None: - """ - Install or update in editable mode the package represented by this - VersionControl object. - - :param dest: the repository directory in which to install or update. - :param url: the repository URL starting with a vcs prefix. - :param verbosity: verbosity level. - """ - url, rev_options = self.get_url_rev_options(url) - - if not os.path.exists(dest): - self.fetch_new(dest, url, rev_options, verbosity=verbosity) - return - - rev_display = rev_options.to_display() - if self.is_repository_directory(dest): - existing_url = self.get_remote_url(dest) - if self.compare_urls(existing_url, url.secret): - 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, verbosity=verbosity) - 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, - ) - # https://github.com/python/mypy/issues/1174 - prompt = ("(i)gnore, (w)ipe, (b)ackup ", ("i", "w", "b")) # type: ignore - - logger.warning( - "The plan is to install the %s repository %s", - self.name, - url, - ) - response = ask_path_exists(f"What to do? {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, verbosity=verbosity) - 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, verbosity=verbosity) - 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, verbosity=verbosity) - - def unpack(self, location: str, url: HiddenText, verbosity: int) -> None: - """ - Clean up current location and download the url repository - (and vcs infos) into location - - :param url: the repository URL starting with a vcs prefix. - :param verbosity: verbosity level. - """ - if os.path.exists(location): - rmtree(location) - self.obtain(location, url=url, verbosity=verbosity) - - @classmethod - def get_remote_url(cls, location: str) -> str: - """ - Return the url used at location - - Raises RemoteNotFoundError if the repository does not have a remote - url configured. - """ - raise NotImplementedError - - @classmethod - def get_revision(cls, location: str) -> str: - """ - Return the current commit id of the files at the given location. - """ - raise NotImplementedError - - @classmethod - def run_command( - cls, - cmd: list[str] | CommandArgs, - show_stdout: bool = True, - cwd: str | None = None, - on_returncode: Literal["raise", "warn", "ignore"] = "raise", - extra_ok_returncodes: Iterable[int] | None = None, - command_desc: str | None = None, - extra_environ: Mapping[str, Any] | None = None, - spinner: SpinnerInterface | None = None, - log_failed_cmd: bool = True, - stdout_only: bool = False, - ) -> str: - """ - 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 = make_command(cls.name, *cmd) - if command_desc is None: - command_desc = format_command_args(cmd) - try: - return call_subprocess( - cmd, - show_stdout, - cwd, - on_returncode=on_returncode, - extra_ok_returncodes=extra_ok_returncodes, - command_desc=command_desc, - extra_environ=extra_environ, - unset_environ=cls.unset_environ, - spinner=spinner, - log_failed_cmd=log_failed_cmd, - stdout_only=stdout_only, - ) - except NotADirectoryError: - raise BadCommand(f"Cannot find command {cls.name!r} - invalid PATH") - except FileNotFoundError: - # errno.ENOENT = no such file or directory - # In other words, the VCS executable isn't available - raise BadCommand( - f"Cannot find command {cls.name!r} - do you have " - f"{cls.name!r} installed and in your PATH?" - ) - except PermissionError: - # errno.EACCES = Permission denied - # This error occurs, for instance, when the command is installed - # only for another user. So, the current user don't have - # permission to call the other user command. - raise BadCommand( - f"No permission to execute {cls.name!r} - install it " - f"locally, globally (ask admin), or check your PATH. " - f"See possible solutions at " - f"https://pip.pypa.io/en/latest/reference/pip_freeze/" - f"#fixing-permission-denied." - ) - - @classmethod - def is_repository_directory(cls, path: str) -> bool: - """ - 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 get_repository_root(cls, location: str) -> str | None: - """ - Return the "root" (top-level) directory controlled by the vcs, - or `None` if the directory is not in any. - - It is meant to be overridden to implement smarter detection - mechanisms for specific vcs. - - This can do more than is_repository_directory() alone. For - example, the Git override checks that Git is actually available. - """ - if cls.is_repository_directory(location): - return location - return None diff --git a/venv/lib/python3.11/site-packages/pip/_internal/wheel_builder.py b/venv/lib/python3.11/site-packages/pip/_internal/wheel_builder.py deleted file mode 100755 index 8a55261..0000000 --- a/venv/lib/python3.11/site-packages/pip/_internal/wheel_builder.py +++ /dev/null @@ -1,265 +0,0 @@ -"""Orchestrator for building wheels from InstallRequirements.""" - -from __future__ import annotations - -import logging -import os.path -import re -from collections.abc import Iterable -from tempfile import TemporaryDirectory - -from pip._vendor.packaging.utils import canonicalize_name, canonicalize_version -from pip._vendor.packaging.version import InvalidVersion, Version - -from pip._internal.cache import WheelCache -from pip._internal.exceptions import InvalidWheelFilename, UnsupportedWheel -from pip._internal.metadata import FilesystemWheel, get_wheel_distribution -from pip._internal.models.link import Link -from pip._internal.models.wheel import Wheel -from pip._internal.operations.build.wheel import build_wheel_pep517 -from pip._internal.operations.build.wheel_editable import build_wheel_editable -from pip._internal.req.req_install import InstallRequirement -from pip._internal.utils.logging import indent_log -from pip._internal.utils.misc import ensure_dir, hash_file -from pip._internal.utils.urls import path_to_url -from pip._internal.vcs import vcs - -logger = logging.getLogger(__name__) - -_egg_info_re = re.compile(r"([a-z0-9_.]+)-([a-z0-9_.!+-]+)", re.IGNORECASE) - -BuildResult = tuple[list[InstallRequirement], list[InstallRequirement]] - - -def _contains_egg_info(s: str) -> bool: - """Determine whether the string looks like an egg_info. - - :param s: The string to parse. E.g. foo-2.1 - """ - return bool(_egg_info_re.search(s)) - - -def _should_cache( - req: InstallRequirement, -) -> bool | None: - """ - Return whether a built InstallRequirement can be stored in the persistent - wheel cache, assuming the wheel cache is available. - """ - if req.editable or not req.source_dir: - # never cache editable requirements - return False - if req.link and req.link.is_existing_dir(): - # never cache local directory requirements - return False - - if req.link and req.link.is_vcs: - # VCS checkout. Do not cache - # unless it points to an immutable commit hash. - assert not req.editable - assert req.source_dir - vcs_backend = vcs.get_backend_for_scheme(req.link.scheme) - assert vcs_backend - if vcs_backend.is_immutable_rev_checkout(req.link.url, req.source_dir): - return True - return False - - assert req.link - base, ext = req.link.splitext() - if _contains_egg_info(base): - return True - - # Otherwise, do not cache. - return False - - -def _get_cache_dir( - req: InstallRequirement, - wheel_cache: WheelCache, -) -> str: - """Return the persistent or temporary cache directory where the built - wheel need to be stored. - """ - cache_available = bool(wheel_cache.cache_dir) - assert req.link - if cache_available and _should_cache(req): - cache_dir = wheel_cache.get_path_for_link(req.link) - else: - cache_dir = wheel_cache.get_ephem_path_for_link(req.link) - return cache_dir - - -def _verify_one(req: InstallRequirement, wheel_path: str) -> None: - canonical_name = canonicalize_name(req.name or "") - w = Wheel(os.path.basename(wheel_path)) - if w.name != canonical_name: - raise InvalidWheelFilename( - f"Wheel has unexpected file name: expected {canonical_name!r}, " - f"got {w.name!r}", - ) - dist = get_wheel_distribution(FilesystemWheel(wheel_path), canonical_name) - dist_verstr = str(dist.version) - if canonicalize_version(dist_verstr) != canonicalize_version(w.version): - raise InvalidWheelFilename( - f"Wheel has unexpected file name: expected {dist_verstr!r}, " - f"got {w.version!r}", - ) - metadata_version_value = dist.metadata_version - if metadata_version_value is None: - raise UnsupportedWheel("Missing Metadata-Version") - try: - metadata_version = Version(metadata_version_value) - except InvalidVersion: - msg = f"Invalid Metadata-Version: {metadata_version_value}" - raise UnsupportedWheel(msg) - if metadata_version >= Version("1.2") and not isinstance(dist.version, Version): - raise UnsupportedWheel( - f"Metadata 1.2 mandates PEP 440 version, but {dist_verstr!r} is not" - ) - - -def _build_one( - req: InstallRequirement, - output_dir: str, - verify: bool, - editable: bool, -) -> str | None: - """Build one wheel. - - :return: The filename of the built wheel, or None if the build failed. - """ - artifact = "editable" if editable else "wheel" - try: - ensure_dir(output_dir) - except OSError as e: - logger.warning( - "Building %s for %s failed: %s", - artifact, - req.name, - e, - ) - return None - - # Install build deps into temporary directory (PEP 518) - with req.build_env: - wheel_path = _build_one_inside_env(req, output_dir, editable) - if wheel_path and verify: - try: - _verify_one(req, wheel_path) - except (InvalidWheelFilename, UnsupportedWheel) as e: - logger.warning("Built %s for %s is invalid: %s", artifact, req.name, e) - return None - return wheel_path - - -def _build_one_inside_env( - req: InstallRequirement, - output_dir: str, - editable: bool, -) -> str | None: - with TemporaryDirectory(dir=output_dir) as wheel_directory: - assert req.name - assert req.metadata_directory - assert req.pep517_backend - if editable: - wheel_path = build_wheel_editable( - name=req.name, - backend=req.pep517_backend, - metadata_directory=req.metadata_directory, - wheel_directory=wheel_directory, - ) - else: - wheel_path = build_wheel_pep517( - name=req.name, - backend=req.pep517_backend, - metadata_directory=req.metadata_directory, - wheel_directory=wheel_directory, - ) - - if wheel_path is not None: - wheel_name = os.path.basename(wheel_path) - dest_path = os.path.join(output_dir, wheel_name) - try: - wheel_hash, length = hash_file(wheel_path) - # We can do a replace here because wheel_path is guaranteed to - # be in the same filesystem as output_dir. This will perform an - # atomic rename, which is necessary to avoid concurrency issues - # when populating the cache. - os.replace(wheel_path, dest_path) - logger.info( - "Created wheel for %s: filename=%s size=%d sha256=%s", - req.name, - wheel_name, - length, - wheel_hash.hexdigest(), - ) - logger.info("Stored in directory: %s", output_dir) - return dest_path - except Exception as e: - logger.warning( - "Building wheel for %s failed: %s", - req.name, - e, - ) - return None - - -def build( - requirements: Iterable[InstallRequirement], - wheel_cache: WheelCache, - verify: bool, - allow_editables: bool, -) -> BuildResult: - """Build wheels. - - :return: The list of InstallRequirement that succeeded to build and - the list of InstallRequirement that failed to build. - """ - if not requirements: - return [], [] - - # Build the wheels. - logger.info( - "Building wheels for collected packages: %s", - ", ".join(req.name for req in requirements), # type: ignore - ) - - with indent_log(): - build_successes, build_failures = [], [] - for req in requirements: - assert req.name - cache_dir = _get_cache_dir(req, wheel_cache) - wheel_file = _build_one( - req, - cache_dir, - verify, - req.editable and allow_editables, - ) - if wheel_file: - # Record the download origin in the cache - if req.download_info is not None: - # download_info is guaranteed to be set because when we build an - # InstallRequirement it has been through the preparer before, but - # let's be cautious. - wheel_cache.record_download_origin(cache_dir, req.download_info) - # Update the link for this. - req.link = Link(path_to_url(wheel_file)) - req.local_file_path = req.link.file_path - assert req.link.is_wheel - build_successes.append(req) - else: - build_failures.append(req) - - # notify success/failure - if build_successes: - logger.info( - "Successfully built %s", - " ".join([req.name for req in build_successes]), # type: ignore - ) - if build_failures: - logger.info( - "Failed to build %s", - " ".join([req.name for req in build_failures]), # type: ignore - ) - # Return a list of requirements that failed to build - return build_successes, build_failures diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/README.rst b/venv/lib/python3.11/site-packages/pip/_vendor/README.rst deleted file mode 100755 index 7429a52..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/README.rst +++ /dev/null @@ -1,178 +0,0 @@ -================ -Vendoring Policy -================ - -* Vendored libraries **MUST** not be modified except as required to - successfully vendor them. -* Vendored libraries **MUST** be released copies of libraries available on - PyPI. -* Vendored libraries **MUST** be available under a license that allows - them to be integrated into ``pip``, which is released under the MIT license. -* Vendored libraries **MUST** be accompanied with LICENSE files. -* The versions of libraries vendored in pip **MUST** be reflected in - ``pip/_vendor/vendor.txt``. -* Vendored libraries **MUST** function without any build steps such as ``2to3`` - or compilation of C code, practically this limits to single source 2.x/3.x and - pure Python. -* Any modifications made to libraries **MUST** be noted in - ``pip/_vendor/README.rst`` and their corresponding patches **MUST** be - included ``tools/vendoring/patches``. -* Vendored libraries should have corresponding ``vendored()`` entries in - ``pip/_vendor/__init__.py``. - -Rationale -========= - -Historically pip has not had any dependencies except for ``setuptools`` itself, -choosing instead to implement any functionality it needed to prevent needing -a dependency. However, starting with pip 1.5, we began to replace code that was -implemented inside of pip with reusable libraries from PyPI. This brought the -typical benefits of reusing libraries instead of reinventing the wheel like -higher quality and more battle tested code, centralization of bug fixes -(particularly security sensitive ones), and better/more features for less work. - -However, there are several issues with having dependencies in the traditional -way (via ``install_requires``) for pip. These issues are: - -**Fragility** - When pip depends on another library to function then if for whatever reason - that library either isn't installed or an incompatible version is installed - then pip ceases to function. This is of course true for all Python - applications, however for every application *except* for pip the way you fix - it is by re-running pip. Obviously, when pip can't run, you can't use pip to - fix pip, so you're left having to manually resolve dependencies and - installing them by hand. - -**Making other libraries uninstallable** - One of pip's current dependencies is the ``requests`` library, for which pip - requires a fairly recent version to run. If pip depended on ``requests`` in - the traditional manner, then we'd either have to maintain compatibility with - every ``requests`` version that has ever existed (and ever will), OR allow - pip to render certain versions of ``requests`` uninstallable. (The second - issue, although technically true for any Python application, is magnified by - pip's ubiquity; pip is installed by default in Python, in ``pyvenv``, and in - ``virtualenv``.) - -**Security** - This might seem puzzling at first glance, since vendoring has a tendency to - complicate updating dependencies for security updates, and that holds true - for pip. However, given the *other* reasons for avoiding dependencies, the - alternative is for pip to reinvent the wheel itself. This is what pip did - historically. It forced pip to re-implement its own HTTPS verification - routines as a workaround for the Python standard library's lack of SSL - validation, which resulted in similar bugs in the validation routine in - ``requests`` and ``urllib3``, except that they had to be discovered and - fixed independently. Even though we're vendoring, reusing libraries keeps - pip more secure by relying on the great work of our dependencies, *and* - allowing for faster, easier security fixes by simply pulling in newer - versions of dependencies. - -**Bootstrapping** - Currently most popular methods of installing pip rely on pip's - self-contained nature to install pip itself. These tools work by bundling a - copy of pip, adding it to ``sys.path``, and then executing that copy of pip. - This is done instead of implementing a "mini installer" (to reduce - duplication); pip already knows how to install a Python package, and is far - more battle-tested than any "mini installer" could ever possibly be. - -Many downstream redistributors have policies against this kind of bundling, and -instead opt to patch the software they distribute to debundle it and make it -rely on the global versions of the software that they already have packaged -(which may have its own patches applied to it). We (the pip team) would prefer -it if pip was *not* debundled in this manner due to the above reasons and -instead we would prefer it if pip would be left intact as it is now. - -In the longer term, if someone has a *portable* solution to the above problems, -other than the bundling method we currently use, that doesn't add additional -problems that are unreasonable then we would be happy to consider, and possibly -switch to said method. This solution must function correctly across all of the -situation that we expect pip to be used and not mandate some external mechanism -such as OS packages. - - -Modifications -============= - -* ``setuptools`` is completely stripped to only keep ``pkg_resources``. -* ``pkg_resources`` has been modified to import its dependencies from - ``pip._vendor``, and to use the vendored copy of ``platformdirs`` - rather than ``appdirs``. -* ``packaging`` has been modified to import its dependencies from - ``pip._vendor``. -* ``CacheControl`` has been modified to import its dependencies from - ``pip._vendor``. -* ``requests`` has been modified to import its other dependencies from - ``pip._vendor`` and to *not* load ``simplejson`` (all platforms) and - ``pyopenssl`` (Windows). -* ``platformdirs`` has been modified to import its submodules from ``pip._vendor.platformdirs``. - -Automatic Vendoring -=================== - -Vendoring is automated via the `vendoring `_ tool from the content of -``pip/_vendor/vendor.txt`` and the different patches in -``tools/vendoring/patches``. -Launch it via ``vendoring sync . -v`` (requires ``vendoring>=0.2.2``). -Tool configuration is done via ``pyproject.toml``. - -To update the vendored library versions, we have a session defined in ``nox``. -The command to upgrade everything is:: - - nox -s vendoring -- --upgrade-all --skip setuptools - -We do not upgrade ``setuptools``, because we only rely on ``pkg_resources``, -and tracking every ``setuptools`` change is unnecessary for our needs. - - -Managing Local Patches -====================== - -The ``vendoring`` tool automatically applies our local patches, but updating, -the patches sometimes no longer apply cleanly. In that case, the update will -fail. To resolve this, take the following steps: - -1. Revert any incomplete changes in the revendoring branch, to ensure you have - a clean starting point. -2. Run the revendoring of the library with a problem again: ``nox -s vendoring - -- --upgrade ``. -3. This will fail again, but you will have the original source in your working - directory. Review the existing patch against the source, and modify the patch - to reflect the new version of the source. If you ``git add`` the changes the - vendoring made, you can modify the source to reflect the patch file and then - generate a new patch with ``git diff``. -4. Now, revert everything *except* the patch file changes. Leave the modified - patch file unstaged but saved in the working tree. -5. Re-run the vendoring. This time, it should pick up the changed patch file - and apply it cleanly. The patch file changes will be committed along with the - revendoring, so the new commit should be ready to test and publish as a PR. - - -Debundling -========== - -As mentioned in the rationale, we, the pip team, would prefer it if pip was not -debundled (other than optionally ``pip/_vendor/requests/cacert.pem``) and that -pip was left intact. However, if you insist on doing so, we have a -semi-supported method (that we don't test in our CI) and requires a bit of -extra work on your end in order to solve the problems described above. - -1. Delete everything in ``pip/_vendor/`` **except** for - ``pip/_vendor/__init__.py`` and ``pip/_vendor/vendor.txt``. -2. Generate wheels for each of pip's dependencies (and any of their - dependencies) using your patched copies of these libraries. These must be - placed somewhere on the filesystem that pip can access (``pip/_vendor`` is - the default assumption). -3. Modify ``pip/_vendor/__init__.py`` so that the ``DEBUNDLED`` variable is - ``True``. -4. Upon installation, the ``INSTALLER`` file in pip's own ``dist-info`` - directory should be set to something other than ``pip``, so that pip - can detect that it wasn't installed using itself. -5. *(optional)* If you've placed the wheels in a location other than - ``pip/_vendor/``, then modify ``pip/_vendor/__init__.py`` so that the - ``WHEEL_DIR`` variable points to the location you've placed them. -6. *(optional)* Update the ``pip_self_version_check`` logic to use the - appropriate logic for determining the latest available version of pip and - prompt the user with the correct upgrade message. - -Note that partial debundling is **NOT** supported. You need to prepare wheels -for all dependencies for successful debundling. diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/__init__.py b/venv/lib/python3.11/site-packages/pip/_vendor/__init__.py deleted file mode 100755 index 34ccb99..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/__init__.py +++ /dev/null @@ -1,117 +0,0 @@ -""" -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__(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("certifi") - vendored("dependency-groups") - vendored("distlib") - vendored("distro") - vendored("packaging") - vendored("packaging.version") - vendored("packaging.specifiers") - vendored("pkg_resources") - vendored("platformdirs") - vendored("progress") - vendored("pyproject_hooks") - vendored("requests") - vendored("requests.exceptions") - 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("resolvelib") - vendored("rich") - vendored("rich.console") - vendored("rich.highlighter") - vendored("rich.logging") - vendored("rich.markup") - vendored("rich.progress") - vendored("rich.segment") - vendored("rich.style") - vendored("rich.text") - vendored("rich.traceback") - if sys.version_info < (3, 11): - vendored("tomli") - vendored("truststore") - vendored("urllib3") diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/__pycache__/__init__.cpython-311.pyc deleted file mode 100755 index 6a377e286ebb8ec8b5f34d6e0d5736d269b19312..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5481 zcmbW3-*4O26~`~7qaT(fJMoX$j_sI^ogYdT$&P=PP1H7Tb@{nO!&|-O5vlK~zJPmssw*3KQK&%F_0tNOIU=J>`0zsa3NKvwE zUn|8Z@$%l!{oZpg?~il%r$iz~@cQSSdrQY#3Hi5Ms9a$`^ZY*{LViaCGDieX2uNHZ zFc;w5d{7F`1-&QCg}i5YE-b)Ygoc))6*Ko6D!JO{7KJy4+FCbH8y|3lJi@ztZ7t2k zh0up&E9onMwCB>0TynVbWG6ZDZ1QCf&!R9ZcHE zq+Lw9pGmu!w1-K1ne+gY_Ax2Xr2R~KkVyxabdX68G3j9@J;J0%nKa3y$C&gulYWOu zPcUhUNz+U^#H7PadXh;;m~@m$$Cz}SNhg?el1Wc7>C|?L-l*AkTSPd0&C9Bdo;RA_ zuJz~{COx~I3c3q#7?T@F?bW znO9Vb8l5jvD!8&Tj+NECT;w&mK=r&^MQ`dwUE`F zXeLw47HB5p#4`RGV?MGd$@5uBbHb9GbDu$NS#u%*5-oLE`t8g>%pBS8hP9|z{M8g(E~vx4TX6_3};E9pG$`g9?y=H&GEcd+L)LzhC}%`SZh{ z9esTCFa2h8+KNuw(P_+l(@72||M>2c{q~{hUk5*Gy#1CHJ-FU}@Qe23)Ar=Ufrsx~ z?ZbBa@GoO)uqJ#NZT@ZWPUGDfdr$xU(a&2ScR!i4li#(Xui4Sp%*y}8H{B%Ou|XO_ ziJGK^G$halY_uYO@#2N%?yFCZpC2KA8;QNn1^-SsOpVa7)Q!C4#Biz#+ldIGrsH%vVK<}7PD6Pf(bpJztJ#$A5{$M@q$xCqM$uO| z3FX>iMx~luQggTy;);~j-K`{uSQ%ARc@Zl$r&(FX{1VOSnY=7t!zz`&U!t0>8LgFE zir&moMR(ngv9}55|B9{Jr(;`&K~W*n@ikfj)2#=tAgxhqv~={-}rSfFyL?!NPMc>bN3>wF{(X6VR36?1tb?xyZk zAg9J2uap-T^Ag_p1?AUE^5UZF=^DLy3^mtEijnXN6|dzhHM;2T2P5WHYWgx-ZSe9s zev%nY<*b^`(RqwR$-px=LO*N7#0lwgK@y#qu9nc%>9R_li0`zLdz?rnBgnaOs9h-O zB^AT2>Na-3jkiuj)>2AV&pQEGQxh(4n3+BQqsudwW@jAmY9jbOR?eWq_2MfA@CE!j zM5_%yxi~v}DKqot551`8z>+K$ow)DMF*+{DpONQimZUQ{ z^1+k^r)@ZG!f7AuFq*bt$c7;khJ3}a1t)DdX~N0fz*!5<*>KK;bG~B7&}S@|wPDtT zSx>P+xTe0Z2^Zr3>n2zX@n5-%Z6-!77_(u_gfZXNj(6HIo)Z?NY)F}q@|#RraLR^L zCY;)BJmVHj*f3$jgs<2!4JR!av0=o7k=<-;8^_vv7VNiSzX|)j7HdDYpv{Ih6WYq< zZJWqU^jW~$z?;A`1#3UGpxcIS6S~XwuiBN{2e4z`_gZkkh65%XSdYZ)NXOkHPb2+i rq<=lSXDxcW!-{s<(JnJuJ|;WfXY(B5QN;ho3g@15_qeMQ=zRVM+W55v diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/bom.cdx.json b/venv/lib/python3.11/site-packages/pip/_vendor/bom.cdx.json deleted file mode 100755 index 7f2d285..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/bom.cdx.json +++ /dev/null @@ -1,231 +0,0 @@ -{ - "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", - "bomFormat": "CycloneDX", - "components": [ - { - "bom-ref": "bom-ref:pip", - "name": "pip", - "type": "library" - }, - { - "bom-ref": "pkg:pypi/CacheControl@0.14.4", - "name": "CacheControl", - "purl": "pkg:pypi/CacheControl@0.14.4", - "type": "library", - "version": "0.14.4" - }, - { - "bom-ref": "pkg:pypi/certifi@2026.6.17", - "name": "certifi", - "purl": "pkg:pypi/certifi@2026.6.17", - "type": "library", - "version": "2026.6.17" - }, - { - "bom-ref": "pkg:pypi/distlib@0.4.2", - "name": "distlib", - "purl": "pkg:pypi/distlib@0.4.2", - "type": "library", - "version": "0.4.2" - }, - { - "bom-ref": "pkg:pypi/distro@1.9.0", - "name": "distro", - "purl": "pkg:pypi/distro@1.9.0", - "type": "library", - "version": "1.9.0" - }, - { - "bom-ref": "pkg:pypi/idna@3.18", - "name": "idna", - "purl": "pkg:pypi/idna@3.18", - "type": "library", - "version": "3.18" - }, - { - "bom-ref": "pkg:pypi/msgpack@1.1.2", - "name": "msgpack", - "purl": "pkg:pypi/msgpack@1.1.2", - "type": "library", - "version": "1.1.2" - }, - { - "bom-ref": "pkg:pypi/packaging@26.2", - "name": "packaging", - "purl": "pkg:pypi/packaging@26.2", - "type": "library", - "version": "26.2" - }, - { - "bom-ref": "pkg:pypi/platformdirs@4.10.0", - "name": "platformdirs", - "purl": "pkg:pypi/platformdirs@4.10.0", - "type": "library", - "version": "4.10.0" - }, - { - "bom-ref": "pkg:pypi/pygments@2.20.0", - "name": "pygments", - "purl": "pkg:pypi/pygments@2.20.0", - "type": "library", - "version": "2.20.0" - }, - { - "bom-ref": "pkg:pypi/pyproject-hooks@1.2.0", - "name": "pyproject-hooks", - "purl": "pkg:pypi/pyproject-hooks@1.2.0", - "type": "library", - "version": "1.2.0" - }, - { - "bom-ref": "pkg:pypi/requests@2.34.2", - "name": "requests", - "purl": "pkg:pypi/requests@2.34.2", - "type": "library", - "version": "2.34.2" - }, - { - "bom-ref": "pkg:pypi/resolvelib@1.2.1", - "name": "resolvelib", - "purl": "pkg:pypi/resolvelib@1.2.1", - "type": "library", - "version": "1.2.1" - }, - { - "bom-ref": "pkg:pypi/rich@14.2.0", - "name": "rich", - "purl": "pkg:pypi/rich@14.2.0", - "type": "library", - "version": "14.2.0" - }, - { - "bom-ref": "pkg:pypi/setuptools@70.3.0", - "name": "setuptools", - "purl": "pkg:pypi/setuptools@70.3.0", - "type": "library", - "version": "70.3.0" - }, - { - "bom-ref": "pkg:pypi/tomli@2.4.1", - "name": "tomli", - "purl": "pkg:pypi/tomli@2.4.1", - "type": "library", - "version": "2.4.1" - }, - { - "bom-ref": "pkg:pypi/tomli-w@1.2.0", - "name": "tomli-w", - "purl": "pkg:pypi/tomli-w@1.2.0", - "type": "library", - "version": "1.2.0" - }, - { - "bom-ref": "pkg:pypi/truststore@0.10.4", - "name": "truststore", - "purl": "pkg:pypi/truststore@0.10.4", - "type": "library", - "version": "0.10.4" - }, - { - "bom-ref": "pkg:pypi/urllib3@2.7.0", - "name": "urllib3", - "purl": "pkg:pypi/urllib3@2.7.0", - "type": "library", - "version": "2.7.0" - } - ], - "dependencies": [ - { - "dependsOn": [ - "pkg:pypi/CacheControl@0.14.4", - "pkg:pypi/certifi@2026.6.17", - "pkg:pypi/distlib@0.4.2", - "pkg:pypi/distro@1.9.0", - "pkg:pypi/idna@3.18", - "pkg:pypi/msgpack@1.1.2", - "pkg:pypi/packaging@26.2", - "pkg:pypi/platformdirs@4.10.0", - "pkg:pypi/pygments@2.20.0", - "pkg:pypi/pyproject-hooks@1.2.0", - "pkg:pypi/requests@2.34.2", - "pkg:pypi/resolvelib@1.2.1", - "pkg:pypi/rich@14.2.0", - "pkg:pypi/setuptools@70.3.0", - "pkg:pypi/tomli@2.4.1", - "pkg:pypi/tomli-w@1.2.0", - "pkg:pypi/truststore@0.10.4", - "pkg:pypi/urllib3@2.7.0" - ], - "ref": "bom-ref:pip" - }, - { - "ref": "pkg:pypi/CacheControl@0.14.4" - }, - { - "ref": "pkg:pypi/certifi@2026.6.17" - }, - { - "ref": "pkg:pypi/distlib@0.4.2" - }, - { - "ref": "pkg:pypi/distro@1.9.0" - }, - { - "ref": "pkg:pypi/idna@3.18" - }, - { - "ref": "pkg:pypi/msgpack@1.1.2" - }, - { - "ref": "pkg:pypi/packaging@26.2" - }, - { - "ref": "pkg:pypi/platformdirs@4.10.0" - }, - { - "ref": "pkg:pypi/pygments@2.20.0" - }, - { - "ref": "pkg:pypi/pyproject-hooks@1.2.0" - }, - { - "ref": "pkg:pypi/requests@2.34.2" - }, - { - "ref": "pkg:pypi/resolvelib@1.2.1" - }, - { - "ref": "pkg:pypi/rich@14.2.0" - }, - { - "ref": "pkg:pypi/setuptools@70.3.0" - }, - { - "ref": "pkg:pypi/tomli@2.4.1" - }, - { - "ref": "pkg:pypi/tomli-w@1.2.0" - }, - { - "ref": "pkg:pypi/truststore@0.10.4" - }, - { - "ref": "pkg:pypi/urllib3@2.7.0" - } - ], - "metadata": { - "component": { - "bom-ref": "bom-ref:pip", - "name": "pip", - "type": "library" - }, - "tools": [ - { - "name": "vendoring", - "version": "1.4.0" - } - ] - }, - "specVersion": "1.4", - "version": 1 -} \ No newline at end of file diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/LICENSE.txt b/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/LICENSE.txt deleted file mode 100755 index d8b3b56..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/LICENSE.txt +++ /dev/null @@ -1,13 +0,0 @@ -Copyright 2012-2021 Eric Larson - -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. diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__init__.py b/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__init__.py deleted file mode 100755 index 3f8c36f..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__init__.py +++ /dev/null @@ -1,32 +0,0 @@ -# SPDX-FileCopyrightText: 2015 Eric Larson -# -# SPDX-License-Identifier: Apache-2.0 - -"""CacheControl import Interface. - -Make it easy to import from cachecontrol without long namespaces. -""" - -import importlib.metadata - -from pip._vendor.cachecontrol.adapter import CacheControlAdapter -from pip._vendor.cachecontrol.controller import CacheController -from pip._vendor.cachecontrol.wrapper import CacheControl - -__author__ = "Eric Larson" -__email__ = "eric@ionrock.org" -# pip patch: this won't work when vendored, so just patch it out as it's unused -# __version__ = importlib.metadata.version("cachecontrol") - -__all__ = [ - "__author__", - "__email__", - "__version__", - "CacheControlAdapter", - "CacheController", - "CacheControl", -] - -import logging - -logging.getLogger(__name__).addHandler(logging.NullHandler()) diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-311.pyc deleted file mode 100755 index 5af8b916d08e359838114724e7c0f88fedad1f4f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1004 zcmaJ<&ui2`6n@#=Zg#V~{UwODAOWH49!x0pVrjKf1eMy0w;&ADWSUJo$%IL^r9JJR z;6V^P6%Q4u__u6j(UMcaledN5dh*S7BfAHkyu5ku<-PaK_a>hk4Fhofc>i(lQ4!#m za`IIg8CT!X_y8U_;AvigYfb_8A}@v|r=+P^iBE-Pr#!T$xE@xV3fg6->gkT*gID>a zIkjPJ-KiIV)%O}X2%A3D0M78eStm2OHNFpPX7k7?8fUo!ll6#Ocmu8K@y;f7+iX)r zsTAA{!dS@Ed>N%o?oyXohVh#2Gc!m{Mw25m6?w|86rt&=T6a`?7^H2{Nlh*y-;8L; zk{CNAmhoGiVY{Vex5lxac{D~849|>*`7l%;4;|N@%fL0as7yq3Jj>A82t*`>yKf2U zx5}A82<;%cBqXa6!a^EwG;4$$FqvR3Arh|*q`E6Pg{n1|>4bQ~#kBbw);!p;LY7jG zrZlVmjb&yW#1=M+JRz-d#ulb33d7df{ePy7287Ip`2T5mC}|vHnmVB@E2X1SC#75w z(z)>cAo8=S&(bZlnanDLsA1z*gL>Wz8hHqm)wVmFkDM=Xg#lDFd{9AUI#EicY$?63IoVhS0BuSHq)I}&n3)t^*+qKdvFemeOUYnOW$Fs*IYe0>^E1>n``~%+BvNE MVZE1&yp0F`13S7ZqyPW_ diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-311.pyc deleted file mode 100755 index 1059ad13deb58c06ff1764e97fc7a4e3e2534e2d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3026 zcmaJ@&2Jk;6rc5u?Ty!VlIF8CN!>UtH4?U}Mo?1PQsOqHElx#R34B>C-o*)XF8EmDkTqa0ELBn)fyz*@c8UM35H ztS{RK^q>-1!`XgiNa=X0&Uo1K+}eMlXA3a4G~yaNJz-vS$n zk-sQ6!P%l*D(R+d7W9&lf#>K&lCKoil6gZWhDv}Fx%tVBOVaF>OS9KL$jkvlAnNB8 z)i4d92WI8mqB^UWOrmQS6}fCOo1SzbXEG7!1T;OLci0)Zs2XKCrvkgT+f-AD9U!V% zAtf7U^pcu$PYnd`3~u)!5Z@t_+Y>Iiw28a8)Pl9AAYXTNIAr=e5`>mq3$LG6y*s!T zRrK;|3R(asW)cC?1IyZip_}={pxndE1}9^!}|mJF;LBRW4qUOA39}kgO8Y!FUO%0Z%jMJ^wR9(?6+TUsm(4}JbUJzJRLUrr z>YL!t+j3qtQsqK9C4rivlT?o4l5=oLNx7nuEHB#;IA5hKwa-R|VLLjEcVMcaEgV{# z|90-thfO?b;mHP`+=>oa(Red@+=?Er&4Jv)Ll5&!JYnI9MyKzBF?!M035w)`Y8Vhr z9snVoD2Uvy4TKj!(}fBlFANF?X@H*jo&rqkE>r-H3kX2yT6=9*xhhw8ZRiO*P2mAX zNRjn+O2etpfx37fU9{xxU*#nFW~@~?2nB!UW`egx=6p#t<-B2sAd3pJR#*YpdluCS zDHvuUw-Q`5&GJktwIWc$04fnAL0E|hbfU}J!L}=He^IZLOgq%ZlSWXVv&SAM;j@FX zlYllh00V=*U@S(4=u%={H6_XgWJnx1V=#={Fahq-V_QQ1eer=ka&k zVETtnwYh%-C_HG1N1EceC63q9Ei8O>^~7cY+`^$vJhFjD9{U?p=NovWi7#0A zLIYoDiT#`6*oHXP6elc^CLVL-{yw|`{`r3&9-MG2Y4-J4wL8&ZhrNor>N9ESYd5cF zX=3dq%PL>x>ol%kX;t46jeORCrU}5>D|qttuDv>12zA?gD>UghY52FB!g;0iZe2hg z4c~qm2|lwDoTUX-IkpnX=%y1CN^It2LS&G#l(Kn%nH-1BSY;(KpzNrVrv$D&xM5X0 z*shZ{PvkG!Qbp=8{bf=pnF(xT7A=!>1x#((Vg`-97&IrUa8WLl$TaYhFpM8yf@Bs4 z?$11!sin8X;rr(voU5gGAbb11IrH_Ihv`RGIw=e(?LTyPer>)szayZYh$W2g@W?*| z%Ko8E9N)n4diu%r=TkqQY~r&PKHI=&K_-lD22X4RPt?sP)n;(o3Qq4J-hXsUh}El3hQxg;fgBn*cp5tuskXctW@MPk?vNz!K(_%cu> zi9nq|qz@)r01r8t#xgQsE|=lHCA2o%BHV<@_D$%N(pVQK$slQ0&Sbl0vf67;9H_=@ zSZ%iB2P--EE!1cBJ-|vG5$TcXHOqp;2^R_)^+O51ha~AIARQLF4x!(f*8LBZ06Aa011P$M*si- diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-311.pyc deleted file mode 100755 index f94de8ef4a294cb2c9f545e68e9880ded7771ead..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7106 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 Ro#DzG&sfjzcIjsa{(q4h$P54g diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-311.pyc deleted file mode 100755 index eac31c0c66dc55eff478236ead6d7511dd51b31a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4499 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 diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-311.pyc deleted file mode 100755 index 7c7b160f084833c6ed5bf41efc37cf36e7d97673..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4818 zcmd5=-ESMm5#Kw0h@T>DNwhv}`6Ai1>DXdbyRB1y6pB9+$4n3jC`=Fe2`Vc@CNigyBA4Mftn(V5 z;oUujtSCi(Q$nVjvUXh~lRa;PGj}Vki@0Jbo=)jASAl;mI{3cRe6- z;2BTI3-~!D6P5W%k_>)}%_L`sC0#cx$x;p7OhbErS}H2?lu|4iRHE}&RZU5H?C8|3 zkFJQ9u3x!yWojn)>Kt#Vmn7CD)piy*y5X z+qw*u6{3&~ClgpCm+{C4rJ}CD-@MQw>Avpm( zK{*bK7`A)RhOCsEMLT~(rBX?uQWwk=5}-^LVN{rNx&?_EWnC5|Azu=V?2MALgt>y6 zD+qHca9N5XD0dY)ZxvL1TA+#~3#x7zg2Ys1+4@cj5@?t!D7s)3BumJ{tb%F^In6K? z;0KMUOSz}y%9a9CUXuB|cSP21%wVlueK?D#ffqO~(RBkc~39%u!+H3{ZYt z6qAAm>qUJfs^rysf(h$3nKcj`IIWb+sWR9M>zNnKf+QPrfW@|*?&OLfOO}M7m=Hx8i5&T6o`rDK+7siH)4 zM(TZI+Bltpypp=B=yy|^noX4;MHu?&vGMVgsanb@Kzml2R?JjMEu}aZ3 z4K0NZZDpac5+qJhRCU!7#f5`=ENrYjI)X->0J22>?I(%jU-`a~t9|Ecedp?Z=PKSu zp+;{4UctuT2)tqy_}c<*VtaK+;kL)LDD^`-=b{b`*MlEGV}&e|HF*E9$lNpV+zZ!x z_j$|p79rq0uG7=tKR!)+K~a*o(5QVWMbvwc1G!O#lxaM1sh-L8k|xVTWBo zz=nnCuG9|Lv@}7^Lh<83mPm6y>E6E)9a)c#R7Wq=q8IDYixvK5Eb)Y{o~gxzdQ7MW z1Ui6oc(aC~<=llqmkY_~&{!cs0A&VhPML8zWm1MP9VHg>x5^PhJsi13bnhIw=eb4Z zxLwjNX!p5A?#HEN-~k}7LgXWs3?jRGqK)JgN)2lJozo`CJ6MhaqlqpS1P8@#2q06; zmqdqeVdM=#wu9&AsN+*0fFkn8$AP+n?EWOBJsXT+3bf|Kaa-Alh7g0Q|^%GkI@wQ zI&|LiSMI#0!%bbl2yk*+zXg|IDmjAFaoaR^vxs4vfC+?O%RxRen0NF`QZ-PSu9T>%-&U zjQ?$_e&J@dH(l#Z*L&07dHBKo-xDC9%TJ>F9)I}o!_}*`$Y?z>T8)f0yUEaDOwr8% z2}U1vae&p6$cfmz{@OU`GzeD1aZg^>?Ur?u0dW z7r>BPc1OW|evzkx;Cpwcthtfp3PEL&-yJ;=XFJm0Hg9K?&|ctk_rNw6A)S02%rHrw zbLpg?h^~WpzdWLSLJ#C6e_-vf^!oV@=`-jxygqdVeEwa6NKxb*dH_sYgbtkr5c* z2oJA^hihS>9u_c34nlr>eB8>P$BzeGySFoKnErosCZwiTItwiF zGT*9$lP57v{$Dsb=}CW!hOq4%4YeH}5=|+uh_2h|FMx;s5(#>ho<$LiO}Ln`(~Vw$ z#=`Jkj@(wIqtq;rmOD2RC)N`uzB*k?r0R(jI<))ATMy4x&aQgby1tC9#=x_^{goS= zfk=CIuJ+af!}Y*$H8A{NxEGei?vr>fuuCQF###(X90;82?CLY*_WH4xcQ}L{b>yaJ zu)|9+rs+5mrs!uodVkf~8^XIK-u~du6%xgwA(u6*M?~>c_!4Q2bcv#D{cDXOo1N*k6Mjt9CvOlB&M>+4RJlgy)hC?@y|o bPs4k>+W9p7GaLuN?M=U9{olV~l&$SQ0C;=X diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-311.pyc deleted file mode 100755 index 45c8a91bb457ee203bf8e7f65e021163993ad8b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7566 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 diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-311.pyc deleted file mode 100755 index d8fb9085f4dd812da1c8795f4dfb383ac04147d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5936 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 diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/_cmd.py b/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/_cmd.py deleted file mode 100755 index 2c84208..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/_cmd.py +++ /dev/null @@ -1,70 +0,0 @@ -# SPDX-FileCopyrightText: 2015 Eric Larson -# -# SPDX-License-Identifier: Apache-2.0 -from __future__ import annotations - -import logging -from argparse import ArgumentParser -from typing import TYPE_CHECKING - -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 - -if TYPE_CHECKING: - from argparse import Namespace - - from pip._vendor.cachecontrol.controller import CacheController - - -def setup_logging() -> None: - logger.setLevel(logging.DEBUG) - handler = logging.StreamHandler() - logger.addHandler(handler) - - -def get_session() -> requests.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 # type: ignore[attr-defined] - return sess - - -def get_args() -> Namespace: - parser = ArgumentParser() - parser.add_argument("url", help="The URL to try and cache") - return parser.parse_args() - - -def main() -> 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 - cache_controller: CacheController = ( - sess.cache_controller # type: ignore[attr-defined] - ) - cache_controller.cache_response(resp.request, resp.raw) - - # Now try to get it - if cache_controller.cached_request(resp.request): - print("Cached!") - else: - print("Not cached :(") - - -if __name__ == "__main__": - main() diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/adapter.py b/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/adapter.py deleted file mode 100755 index 01f1253..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/adapter.py +++ /dev/null @@ -1,167 +0,0 @@ -# SPDX-FileCopyrightText: 2015 Eric Larson -# -# SPDX-License-Identifier: Apache-2.0 -from __future__ import annotations - -import functools -import weakref -import zlib -from typing import TYPE_CHECKING, Any, Collection, Mapping - -from pip._vendor.requests.adapters import HTTPAdapter - -from pip._vendor.cachecontrol.cache import DictCache -from pip._vendor.cachecontrol.controller import PERMANENT_REDIRECT_STATUSES, CacheController -from pip._vendor.cachecontrol.filewrapper import CallbackFileWrapper - -if TYPE_CHECKING: - from pip._vendor.requests import PreparedRequest, Response - from pip._vendor.urllib3 import HTTPResponse - - from pip._vendor.cachecontrol.cache import BaseCache - from pip._vendor.cachecontrol.heuristics import BaseHeuristic - from pip._vendor.cachecontrol.serialize import Serializer - - -class CacheControlAdapter(HTTPAdapter): - invalidating_methods = {"PUT", "PATCH", "DELETE"} - - def __init__( - self, - cache: BaseCache | None = None, - cache_etags: bool = True, - controller_class: type[CacheController] | None = None, - serializer: Serializer | None = None, - heuristic: BaseHeuristic | None = None, - cacheable_methods: Collection[str] | None = None, - *args: Any, - **kw: Any, - ) -> None: - super().__init__(*args, **kw) - self.cache = DictCache() if cache is None else cache - 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: PreparedRequest, - stream: bool = False, - timeout: None | float | tuple[float, float] | tuple[float, None] = None, - verify: bool | str = True, - cert: (None | bytes | str | tuple[bytes | str, bytes | str]) = None, - proxies: Mapping[str, str] | None = None, - cacheable_methods: Collection[str] | None = None, - ) -> Response: - """ - 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().send(request, stream, timeout, verify, cert, proxies) - - return resp - - def build_response( # type: ignore[override] - self, - request: PreparedRequest, - response: HTTPResponse, - from_cache: bool = False, - cacheable_methods: Collection[str] | None = None, - ) -> Response: - """ - 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 int(response.status) in PERMANENT_REDIRECT_STATUSES: - 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( # type: ignore[assignment] - response._fp, # type: ignore[arg-type] - functools.partial( - self.controller.cache_response, request, weakref.ref(response) - ), - ) - if response.chunked: - super_update_chunk_length = response.__class__._update_chunk_length - - def _update_chunk_length( - weak_self: weakref.ReferenceType[HTTPResponse], - ) -> None: - self = weak_self() - if self is None: - return - - super_update_chunk_length(self) - if self.chunk_left == 0: - self._fp._close() # type: ignore[union-attr] - - response._update_chunk_length = functools.partial( # type: ignore[method-assign] - _update_chunk_length, weakref.ref(response) - ) - - resp: Response = super().build_response(request, response) - - # See if we should invalidate the cache. - if request.method in self.invalidating_methods and resp.ok: - assert request.url is not None - 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 # type: ignore[attr-defined] - - return resp - - def close(self) -> None: - self.cache.close() - super().close() # type: ignore[no-untyped-call] diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/cache.py b/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/cache.py deleted file mode 100755 index 91598e9..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/cache.py +++ /dev/null @@ -1,75 +0,0 @@ -# SPDX-FileCopyrightText: 2015 Eric Larson -# -# SPDX-License-Identifier: Apache-2.0 - -""" -The cache object API for implementing caches. The default is a thread -safe in-memory dictionary. -""" - -from __future__ import annotations - -from threading import Lock -from typing import IO, TYPE_CHECKING, MutableMapping - -if TYPE_CHECKING: - from datetime import datetime - - -class BaseCache: - def get(self, key: str) -> bytes | None: - raise NotImplementedError() - - def set( - self, key: str, value: bytes, expires: int | datetime | None = None - ) -> None: - raise NotImplementedError() - - def delete(self, key: str) -> None: - raise NotImplementedError() - - def close(self) -> None: - pass - - -class DictCache(BaseCache): - def __init__(self, init_dict: MutableMapping[str, bytes] | None = None) -> None: - self.lock = Lock() - self.data = init_dict or {} - - def get(self, key: str) -> bytes | None: - return self.data.get(key, None) - - def set( - self, key: str, value: bytes, expires: int | datetime | None = None - ) -> None: - with self.lock: - self.data.update({key: value}) - - def delete(self, key: str) -> None: - with self.lock: - if key in self.data: - self.data.pop(key) - - -class SeparateBodyBaseCache(BaseCache): - """ - In this variant, the body is not stored mixed in with the metadata, but is - passed in (as a bytes-like object) in a separate call to ``set_body()``. - - That is, the expected interaction pattern is:: - - cache.set(key, serialized_metadata) - cache.set_body(key) - - Similarly, the body should be loaded separately via ``get_body()``. - """ - - def set_body(self, key: str, body: bytes) -> None: - raise NotImplementedError() - - def get_body(self, key: str) -> IO[bytes] | None: - """ - Return the body as file-like object. - """ - raise NotImplementedError() diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/caches/__init__.py b/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/caches/__init__.py deleted file mode 100755 index 24ff469..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/caches/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-FileCopyrightText: 2015 Eric Larson -# -# SPDX-License-Identifier: Apache-2.0 - -from pip._vendor.cachecontrol.caches.file_cache import FileCache, SeparateBodyFileCache -from pip._vendor.cachecontrol.caches.redis_cache import RedisCache - -__all__ = ["FileCache", "SeparateBodyFileCache", "RedisCache"] diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-311.pyc deleted file mode 100755 index 4f3a8564e8051af75a78ddf2b241e5cbe61b7d77..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 476 zcmah`ze@u#6n?q8T0QLOA8{2gl&(^+f`fyD9h6%_yu>z|yM)|X=;j|G2#zkr|E813 zO@fnKp<5@DYyE|TFOQG+<>kxwNT#h;2sWPY9qtm`NYfFob_QHiLrdOQZ1S}op(;G(OceE@ z$Tz+fn!rKB!b!AIwYAVO8S|Ve6Q}O3ROO{naz%>x(t41(@vW|Q|5F*~x|TVss!0fy zl8`4@SPIJ&k5tBSMop^lu^Or_rdne=$QVm;f%T*usk|F^I=B!e-_ta`rbAv}>x|d) z;-B-bNP!6vxhM&V^<=rZpDA`DdCzQHPy7B*99Wq92%&ih=p4=9>~Fq6fA%|H!``gU K+ooH_ed-70YmJfs diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-311.pyc deleted file mode 100755 index 4cb15f5093e7526f65ab2a66d641a5a01953dd24..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8201 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 SfDV(VgMT6S?>7u_*!}@;c$vun diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py b/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py deleted file mode 100755 index 45c632c..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py +++ /dev/null @@ -1,145 +0,0 @@ -# SPDX-FileCopyrightText: 2015 Eric Larson -# -# SPDX-License-Identifier: Apache-2.0 -from __future__ import annotations - -import hashlib -import os -import tempfile -from textwrap import dedent -from typing import IO, TYPE_CHECKING -from pathlib import Path - -from pip._vendor.cachecontrol.cache import BaseCache, SeparateBodyBaseCache -from pip._vendor.cachecontrol.controller import CacheController - -if TYPE_CHECKING: - from datetime import datetime - - from filelock import BaseFileLock - - -class _FileCacheMixin: - """Shared implementation for both FileCache variants.""" - - def __init__( - self, - directory: str | Path, - forever: bool = False, - filemode: int = 0o0600, - dirmode: int = 0o0700, - lock_class: type[BaseFileLock] | None = None, - ) -> None: - try: - if lock_class is None: - from filelock import FileLock - - lock_class = FileLock - except ImportError: - notice = dedent( - """ - NOTE: In order to use the FileCache you must have - filelock installed. You can install it via pip: - pip install cachecontrol[filecache] - """ - ) - raise ImportError(notice) - - self.directory = directory - self.forever = forever - self.filemode = filemode - self.dirmode = dirmode - self.lock_class = lock_class - - @staticmethod - def encode(x: str) -> str: - return hashlib.sha224(x.encode()).hexdigest() - - def _fn(self, name: str) -> str: - # 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: str) -> bytes | None: - name = self._fn(key) - try: - with open(name, "rb") as fh: - return fh.read() - - except FileNotFoundError: - return None - - def set( - self, key: str, value: bytes, expires: int | datetime | None = None - ) -> None: - name = self._fn(key) - self._write(name, value) - - def _write(self, path: str, data: bytes) -> None: - """ - Safely write the data to the given path. - """ - # Make sure the directory exists - dirname = os.path.dirname(path) - os.makedirs(dirname, self.dirmode, exist_ok=True) - - with self.lock_class(path + ".lock"): - # Write our actual file - (fd, name) = tempfile.mkstemp(dir=dirname) - try: - os.write(fd, data) - finally: - os.close(fd) - os.chmod(name, self.filemode) - os.replace(name, path) - - def _delete(self, key: str, suffix: str) -> None: - name = self._fn(key) + suffix - if not self.forever: - try: - os.remove(name) - except FileNotFoundError: - pass - - -class FileCache(_FileCacheMixin, BaseCache): - """ - Traditional FileCache: body is stored in memory, so not suitable for large - downloads. - """ - - def delete(self, key: str) -> None: - self._delete(key, "") - - -class SeparateBodyFileCache(_FileCacheMixin, SeparateBodyBaseCache): - """ - Memory-efficient FileCache: body is stored in a separate file, reducing - peak memory usage. - """ - - def get_body(self, key: str) -> IO[bytes] | None: - name = self._fn(key) + ".body" - try: - return open(name, "rb") - except FileNotFoundError: - return None - - def set_body(self, key: str, body: bytes) -> None: - name = self._fn(key) + ".body" - self._write(name, body) - - def delete(self, key: str) -> None: - self._delete(key, "") - self._delete(key, ".body") - - -def url_to_file_path(url: str, filecache: FileCache) -> str: - """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.11/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py b/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py deleted file mode 100755 index f4f68c4..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py +++ /dev/null @@ -1,48 +0,0 @@ -# SPDX-FileCopyrightText: 2015 Eric Larson -# -# SPDX-License-Identifier: Apache-2.0 -from __future__ import annotations - - -from datetime import datetime, timezone -from typing import TYPE_CHECKING - -from pip._vendor.cachecontrol.cache import BaseCache - -if TYPE_CHECKING: - from redis import Redis - - -class RedisCache(BaseCache): - def __init__(self, conn: Redis[bytes]) -> None: - self.conn = conn - - def get(self, key: str) -> bytes | None: - return self.conn.get(key) - - def set( - self, key: str, value: bytes, expires: int | datetime | None = None - ) -> None: - if not expires: - self.conn.set(key, value) - elif isinstance(expires, datetime): - now_utc = datetime.now(timezone.utc) - if expires.tzinfo is None: - now_utc = now_utc.replace(tzinfo=None) - delta = expires - now_utc - self.conn.setex(key, int(delta.total_seconds()), value) - else: - self.conn.setex(key, expires, value) - - def delete(self, key: str) -> None: - self.conn.delete(key) - - def clear(self) -> None: - """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) -> None: - """Redis uses connection pooling, no need to close the connection.""" - pass diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/controller.py b/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/controller.py deleted file mode 100755 index 0bf3801..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/controller.py +++ /dev/null @@ -1,511 +0,0 @@ -# SPDX-FileCopyrightText: 2015 Eric Larson -# -# SPDX-License-Identifier: Apache-2.0 - -""" -The httplib2 algorithms ported for use with requests. -""" - -from __future__ import annotations - -import calendar -import logging -import re -import time -import weakref -from email.utils import parsedate_tz -from typing import TYPE_CHECKING, Collection, Mapping - -from pip._vendor.requests.structures import CaseInsensitiveDict - -from pip._vendor.cachecontrol.cache import DictCache, SeparateBodyBaseCache -from pip._vendor.cachecontrol.serialize import Serializer - -if TYPE_CHECKING: - from typing import Literal - - from pip._vendor.requests import PreparedRequest - from pip._vendor.urllib3 import HTTPResponse - - from pip._vendor.cachecontrol.cache import BaseCache - -logger = logging.getLogger(__name__) - -URI = re.compile(r"^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?") - -PERMANENT_REDIRECT_STATUSES = (301, 308) - - -def parse_uri(uri: str) -> tuple[str, str, str, str, str]: - """Parses a URI using the regex given in Appendix B of RFC 3986. - - (scheme, authority, path, query, fragment) = parse_uri(uri) - """ - match = URI.match(uri) - assert match is not None - groups = match.groups() - return (groups[1], groups[3], groups[4], groups[6], groups[8]) - - -class CacheController: - """An interface to see if request should cached or not.""" - - def __init__( - self, - cache: BaseCache | None = None, - cache_etags: bool = True, - serializer: Serializer | None = None, - status_codes: Collection[int] | None = None, - ): - self.cache = DictCache() if cache is None else cache - self.cache_etags = cache_etags - self.serializer = serializer or Serializer() - self.cacheable_status_codes = status_codes or (200, 203, 300, 301, 308) - - @classmethod - def _urlnorm(cls, uri: str) -> str: - """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: str) -> str: - return cls._urlnorm(uri) - - def parse_cache_control(self, headers: Mapping[str, str]) -> dict[str, int | None]: - 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: dict[str, int | None] = {} - - 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 _load_from_cache(self, request: PreparedRequest) -> HTTPResponse | None: - """ - Load a cached response, or return None if it's not available. - """ - # We do not support caching of partial content: so if the request contains a - # Range header then we don't want to load anything from the cache. - if "Range" in request.headers: - return None - - cache_url = request.url - assert cache_url is not None - cache_data = self.cache.get(cache_url) - if cache_data is None: - logger.debug("No cache entry available") - return None - - if isinstance(self.cache, SeparateBodyBaseCache): - body_file = self.cache.get_body(cache_url) - else: - body_file = None - - result = self.serializer.loads(request, cache_data, body_file) - if result is None: - logger.warning("Cache entry deserialization failed, entry ignored") - return result - - def cached_request(self, request: PreparedRequest) -> HTTPResponse | Literal[False]: - """ - Return a cached response if it exists in the cache, otherwise - return False. - """ - assert request.url is not None - 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 - - # Check whether we can load the response from the cache: - resp = self._load_from_cache(request) - if not resp: - return False - - # If we have a cached permanent redirect, 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 int(resp.status) in PERMANENT_REDIRECT_STATUSES: - msg = ( - "Returning cached permanent redirect response " - "(ignoring date and etag information)" - ) - logger.debug(msg) - return resp - - headers: CaseInsensitiveDict[str] = 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() - time_tuple = parsedate_tz(headers["date"]) - assert time_tuple is not None - date = calendar.timegm(time_tuple[:6]) - 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 - max_age = resp_cc.get("max-age") - if max_age is not None: - freshness_lifetime = 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[:6]) - 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. - max_age = cc.get("max-age") - if max_age is not None: - freshness_lifetime = max_age - logger.debug( - "Freshness lifetime from request max-age: %i", freshness_lifetime - ) - - min_fresh = cc.get("min-fresh") - if min_fresh is not None: - # 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: PreparedRequest) -> dict[str, str]: - resp = self._load_from_cache(request) - new_headers = {} - - if resp: - headers: CaseInsensitiveDict[str] = 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_set( - self, - cache_url: str, - request: PreparedRequest, - response: HTTPResponse, - body: bytes | None = None, - expires_time: int | None = None, - ) -> None: - """ - Store the data in the cache. - """ - if isinstance(self.cache, SeparateBodyBaseCache): - # We pass in the body separately; just put a placeholder empty - # string in the metadata. - self.cache.set( - cache_url, - self.serializer.dumps(request, response, b""), - expires=expires_time, - ) - # body is None can happen when, for example, we're only updating - # headers, as is the case in update_cached_response(). - if body is not None: - self.cache.set_body(cache_url, body) - else: - self.cache.set( - cache_url, - self.serializer.dumps(request, response, body), - expires=expires_time, - ) - - def cache_response( - self, - request: PreparedRequest, - response_or_ref: HTTPResponse | weakref.ReferenceType[HTTPResponse], - body: bytes | None = None, - status_codes: Collection[int] | None = None, - ) -> None: - """ - Algorithm for caching requests. - - This assumes a requests Response object. - """ - if isinstance(response_or_ref, weakref.ReferenceType): - response = response_or_ref() - if response is None: - # The weakref can be None only in case the user used streamed request - # and did not consume or close it, and holds no reference to requests.Response. - # In such case, we don't want to cache the response. - return - else: - response = response_or_ref - - # 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[str] = CaseInsensitiveDict( - response.headers - ) - - if "date" in response_headers: - time_tuple = parsedate_tz(response_headers["date"]) - assert time_tuple is not None - date = calendar.timegm(time_tuple[:6]) - else: - date = 0 - - # 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) - - assert request.url is not None - 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 - - # https://tools.ietf.org/html/rfc7234#section-4.1: - # A Vary header field-value of "*" always fails to match. - # Storing such a response leads to a deserialization warning - # during cache lookup and is not allowed to ever be served, - # so storing it can be avoided. - if "*" in response_headers.get("vary", ""): - logger.debug('Response header has "Vary: *"') - return - - # If we've been given an etag, then keep the response - if self.cache_etags and "etag" in response_headers: - expires_time = 0 - if response_headers.get("expires"): - expires = parsedate_tz(response_headers["expires"]) - if expires is not None: - expires_time = calendar.timegm(expires[:6]) - date - - expires_time = max(expires_time, 14 * 86400) - - logger.debug(f"etag object cached for {expires_time} seconds") - logger.debug("Caching due to etag") - self._cache_set(cache_url, request, response, body, expires_time) - - # Add to the cache any permanent redirects. We do this before looking - # that the Date headers. - elif int(response.status) in PERMANENT_REDIRECT_STATUSES: - logger.debug("Caching permanent redirect") - self._cache_set(cache_url, request, response, b"") - - # 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: - time_tuple = parsedate_tz(response_headers["date"]) - assert time_tuple is not None - date = calendar.timegm(time_tuple[:6]) - # cache when there is a max-age > 0 - max_age = cc.get("max-age") - if max_age is not None and max_age > 0: - logger.debug("Caching b/c date exists and max-age > 0") - expires_time = max_age - self._cache_set( - cache_url, - request, - response, - body, - expires_time, - ) - - # If the request can expire, it means we should cache it - # in the meantime. - elif "expires" in response_headers: - if response_headers["expires"]: - expires = parsedate_tz(response_headers["expires"]) - if expires is not None: - expires_time = calendar.timegm(expires[:6]) - date - else: - expires_time = None - - logger.debug( - "Caching b/c of expires header. expires in {} seconds".format( - expires_time - ) - ) - self._cache_set( - cache_url, - request, - response, - body, - expires_time, - ) - - def update_cached_response( - self, request: PreparedRequest, response: HTTPResponse - ) -> HTTPResponse: - """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. - """ - assert request.url is not None - cache_url = self.cache_url(request.url) - cached_response = self._load_from_cache(request) - - 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 problematic due to - # typical assumptions. - excluded_headers = ["content-length"] - - cached_response.headers.update( - { - 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, request, cached_response) - - return cached_response diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/filewrapper.py b/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/filewrapper.py deleted file mode 100755 index 6569fb5..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/filewrapper.py +++ /dev/null @@ -1,121 +0,0 @@ -# SPDX-FileCopyrightText: 2015 Eric Larson -# -# SPDX-License-Identifier: Apache-2.0 -from __future__ import annotations - -import mmap -from tempfile import NamedTemporaryFile -from typing import TYPE_CHECKING, Any, Callable - -if TYPE_CHECKING: - from collections.abc import Buffer - from http.client import HTTPResponse - - -class CallbackFileWrapper: - """ - 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. - - The data is stored in a temporary file until it is all available. As long - as the temporary files directory is disk-based (sometimes it's a - memory-backed-``tmpfs`` on Linux), data will be unloaded to disk if memory - pressure is high. For small files the disk usually won't be used at all, - it'll all be in the filesystem memory cache, so there should be no - performance impact. - """ - - def __init__( - self, fp: HTTPResponse, callback: Callable[[Buffer], None] | None - ) -> None: - self.__buf = NamedTemporaryFile("rb+", delete=True) - self.__fp = fp - self.__callback = callback - - def __getattr__(self, name: str) -> Any: - # The vagaries 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 things 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) -> bool: - try: - return self.__fp.fp is None - - except AttributeError: - pass - - try: - closed: bool = self.__fp.closed - return closed - - except AttributeError: - pass - - # We just don't cache it then. - # TODO: Add some logging here... - return False - - def _close(self) -> None: - result: Buffer - if self.__callback: - if self.__buf.tell() == 0: - # Empty file: - result = b"" - else: - # Return the data without actually loading it into memory, - # relying on Python's buffer API and mmap(). mmap() just gives - # a view directly into the filesystem's memory cache, so it - # doesn't result in duplicate memory use. - self.__buf.seek(0, 0) - result = memoryview( - mmap.mmap(self.__buf.fileno(), 0, access=mmap.ACCESS_READ) - ) - self.__callback(result) - - # 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 - - # Closing the temporary file releases memory and frees disk space. - # Important when caching big files. - self.__buf.close() - - def read(self, amt: int | None = None) -> bytes: - data: bytes = self.__fp.read(amt) - if data: - # We may be dealing with b'', a sign that things are over: - # it's passed e.g. after we've already closed self.__buf. - self.__buf.write(data) - if self.__is_fp_closed(): - self._close() - - return data - - def _safe_read(self, amt: int) -> bytes: - data: bytes = self.__fp._safe_read(amt) # type: ignore[attr-defined] - 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.11/site-packages/pip/_vendor/cachecontrol/heuristics.py b/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/heuristics.py deleted file mode 100755 index b778c4f..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/heuristics.py +++ /dev/null @@ -1,157 +0,0 @@ -# SPDX-FileCopyrightText: 2015 Eric Larson -# -# SPDX-License-Identifier: Apache-2.0 -from __future__ import annotations - -import calendar -import time -from datetime import datetime, timedelta, timezone -from email.utils import formatdate, parsedate, parsedate_tz -from typing import TYPE_CHECKING, Any, Mapping - -if TYPE_CHECKING: - from pip._vendor.urllib3 import HTTPResponse - -TIME_FMT = "%a, %d %b %Y %H:%M:%S GMT" - - -def expire_after(delta: timedelta, date: datetime | None = None) -> datetime: - date = date or datetime.now(timezone.utc) - return date + delta - - -def datetime_to_header(dt: datetime) -> str: - return formatdate(calendar.timegm(dt.timetuple())) - - -class BaseHeuristic: - def warning(self, response: HTTPResponse) -> str | None: - """ - 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: HTTPResponse) -> dict[str, str]: - """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: HTTPResponse) -> HTTPResponse: - 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: HTTPResponse) -> dict[str, str]: - headers = {} - - if "expires" not in response.headers: - date = parsedate(response.headers["date"]) - expires = expire_after( - timedelta(days=1), - date=datetime(*date[:6], tzinfo=timezone.utc), # type: ignore[index,misc] - ) - 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: Any) -> None: - self.delta = timedelta(**kw) - - def update_headers(self, response: HTTPResponse) -> dict[str, str]: - expires = expire_after(self.delta) - return {"expires": datetime_to_header(expires), "cache-control": "public"} - - def warning(self, response: HTTPResponse) -> str | None: - 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: HTTPResponse) -> dict[str, str]: - headers: Mapping[str, str] = 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 {} - - time_tuple = parsedate_tz(headers["date"]) - assert time_tuple is not None - date = calendar.timegm(time_tuple[:6]) - last_modified = parsedate(headers["last-modified"]) - if 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: HTTPResponse) -> str | None: - return None diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/py.typed b/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/py.typed deleted file mode 100755 index e69de29..0000000 diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/serialize.py b/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/serialize.py deleted file mode 100755 index a49487a..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/serialize.py +++ /dev/null @@ -1,146 +0,0 @@ -# SPDX-FileCopyrightText: 2015 Eric Larson -# -# SPDX-License-Identifier: Apache-2.0 -from __future__ import annotations - -import io -from typing import IO, TYPE_CHECKING, Any, Mapping, cast - -from pip._vendor import msgpack -from pip._vendor.requests.structures import CaseInsensitiveDict -from pip._vendor.urllib3 import HTTPResponse - -if TYPE_CHECKING: - from pip._vendor.requests import PreparedRequest - - -class Serializer: - serde_version = "4" - - def dumps( - self, - request: PreparedRequest, - response: HTTPResponse, - body: bytes | None = None, - ) -> bytes: - response_headers: CaseInsensitiveDict[str] = CaseInsensitiveDict( - response.headers - ) - - if body is None: - # When a body isn't passed in, we'll read the response. We - # also update the response with a new file handler to be - # sure it acts as though it was never read. - body = response.read(decode_content=False) - response._fp = io.BytesIO(body) # type: ignore[assignment] - response.length_remaining = len(body) - - data = { - "response": { - "body": body, # Empty bytestring if body is stored separately - "headers": {str(k): str(v) for k, v in response.headers.items()}, - "status": response.status, - "version": response.version, - "reason": str(response.reason), - "decode_content": response.decode_content, - } - } - - # Construct our vary headers - data["vary"] = {} - if "vary" in response_headers: - varied_headers = response_headers["vary"].split(",") - for header in varied_headers: - header = str(header).strip() - header_value = request.headers.get(header, None) - if header_value is not None: - header_value = str(header_value) - data["vary"][header] = header_value - - return b",".join([f"cc={self.serde_version}".encode(), self.serialize(data)]) - - def serialize(self, data: dict[str, Any]) -> bytes: - return cast(bytes, msgpack.dumps(data, use_bin_type=True)) - - def loads( - self, - request: PreparedRequest, - data: bytes, - body_file: IO[bytes] | None = None, - ) -> HTTPResponse | None: - # Short circuit if we've been given an empty set of data - if not data: - return None - - # Previous versions of this library supported other serialization - # formats, but these have all been removed. - if not data.startswith(f"cc={self.serde_version},".encode()): - return None - - data = data[5:] - return self._loads_v4(request, data, body_file) - - def prepare_response( - self, - request: PreparedRequest, - cached: Mapping[str, Any], - body_file: IO[bytes] | None = None, - ) -> HTTPResponse | None: - """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. - # This case is also handled in the controller code when creating - # a cache entry, but is left here for backwards compatibility. - if "*" in cached.get("vary", {}): - return None - - # 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 None - - body_raw = cached["response"].pop("body") - - headers: CaseInsensitiveDict[str] = CaseInsensitiveDict( - data=cached["response"]["headers"] - ) - if headers.get("transfer-encoding", "") == "chunked": - headers.pop("transfer-encoding") - - cached["response"]["headers"] = headers - - try: - body: IO[bytes] - if body_file is None: - body = io.BytesIO(body_raw) - else: - body = body_file - 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")) - - # Discard any `strict` parameter serialized by older version of cachecontrol. - cached["response"].pop("strict", None) - - return HTTPResponse(body=body, preload_content=False, **cached["response"]) - - def _loads_v4( - self, - request: PreparedRequest, - data: bytes, - body_file: IO[bytes] | None = None, - ) -> HTTPResponse | None: - try: - cached = msgpack.loads(data, raw=False) - except ValueError: - return None - - return self.prepare_response(request, cached, body_file) diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/wrapper.py b/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/wrapper.py deleted file mode 100755 index f618bc3..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/wrapper.py +++ /dev/null @@ -1,43 +0,0 @@ -# SPDX-FileCopyrightText: 2015 Eric Larson -# -# SPDX-License-Identifier: Apache-2.0 -from __future__ import annotations - -from typing import TYPE_CHECKING, Collection - -from pip._vendor.cachecontrol.adapter import CacheControlAdapter -from pip._vendor.cachecontrol.cache import DictCache - -if TYPE_CHECKING: - from pip._vendor import requests - - from pip._vendor.cachecontrol.cache import BaseCache - from pip._vendor.cachecontrol.controller import CacheController - from pip._vendor.cachecontrol.heuristics import BaseHeuristic - from pip._vendor.cachecontrol.serialize import Serializer - - -def CacheControl( - sess: requests.Session, - cache: BaseCache | None = None, - cache_etags: bool = True, - serializer: Serializer | None = None, - heuristic: BaseHeuristic | None = None, - controller_class: type[CacheController] | None = None, - adapter_class: type[CacheControlAdapter] | None = None, - cacheable_methods: Collection[str] | None = None, -) -> requests.Session: - cache = DictCache() if cache is None else cache - 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.11/site-packages/pip/_vendor/certifi/LICENSE b/venv/lib/python3.11/site-packages/pip/_vendor/certifi/LICENSE deleted file mode 100755 index 62b076c..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/certifi/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -This package contains a modified version of ca-bundle.crt: - -ca-bundle.crt -- Bundle of CA Root Certificates - -This is a bundle of X.509 certificates of public Certificate Authorities -(CA). These were automatically extracted from Mozilla's root certificates -file (certdata.txt). This file can be found in the mozilla source tree: -https://hg.mozilla.org/mozilla-central/file/tip/security/nss/lib/ckfw/builtins/certdata.txt -It contains the certificates in PEM format and therefore -can be directly used with curl / libcurl / php_curl, or with -an Apache+mod_ssl webserver for SSL client authentication. -Just configure this file as the SSLCACertificateFile.# - -***** BEGIN LICENSE BLOCK ***** -This Source Code Form is subject to the terms of the Mozilla Public License, -v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain -one at http://mozilla.org/MPL/2.0/. - -***** END LICENSE BLOCK ***** -@(#) $RCSfile: certdata.txt,v $ $Revision: 1.80 $ $Date: 2011/11/03 15:11:58 $ diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/certifi/__init__.py b/venv/lib/python3.11/site-packages/pip/_vendor/certifi/__init__.py deleted file mode 100755 index ed9a74b..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/certifi/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from .core import contents, where - -__all__ = ["contents", "where"] -__version__ = "2026.06.17" diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/certifi/__main__.py b/venv/lib/python3.11/site-packages/pip/_vendor/certifi/__main__.py deleted file mode 100755 index 0037634..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/certifi/__main__.py +++ /dev/null @@ -1,12 +0,0 @@ -import argparse - -from pip._vendor.certifi import contents, where - -parser = argparse.ArgumentParser() -parser.add_argument("-c", "--contents", action="store_true") -args = parser.parse_args() - -if args.contents: - print(contents()) -else: - print(where()) diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-311.pyc deleted file mode 100755 index eac73d67fe7e7b538bc47247fcb818ccb9c5dfc3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 338 zcmZusy-ve05VoC!mPBP^VL`BEAWmATEQkkSU|~SYfE8ks7!uoZOsg{W5jr3t@dAjq z>4d6GNK9-<-8$h&ATjXW>F&FK-OFI$1B+D#TB;e1eF@+OdEc~F(F)VLrA1%oBl~H>3zjcbztvwPc*SLUk-$D b1rC<~>3gudm@fVOd2h9|HxD||+ji(11x#D+ diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/certifi/__pycache__/__main__.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/certifi/__pycache__/__main__.cpython-311.pyc deleted file mode 100755 index e1f087fc611cd9a382eaaeab2cc8d47bc860673d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 739 zcmah_&ubGw6rS1NyBIAlfzVSals3g=D80slpcfB8@F3)}th-~fF}t(OZYnJvw$MWg zJ$MilFM5iK{xL~eY?xEPlec1Tz39v~TdD}YnK$pfdEa~QoB3F&Sb)p7*YEnjxcx4I zQq+ZW{*yazfDe2)03Bha0Su*%6v`bL0tsNySIVL>cfOPX=%`rzpk0O69AEYoU;V0$ zWsc{1DG+eHUPjmLUwsX1^rbRStDJ+$Rr(V(hP*e|OM#sKW5HG+<^Ln=`VUdqu1n1D zNR;9zO_=(khbi8d8s5IuXk1-eNlGYoQaZ$S$TZhW0}|COX1KH)yEMVfj)S=A?Bd8L zwCQ1*2G0U2-c7~Vv77g3cNp>!j|7@Bt*D~xhU@zdZ&Ku#Rosd=VM=kTF%6>hGdLGi zFP@+t2{8&?>Jjvibjdby;~4R&yJ!$RMe$zRBhhwqYYQboiW{-(J$Jh}L7W^~kV6Y{ z$Zedw!hB5W*R_l@)6a(BxlxZmx`Kxw$emS95bU z(`G!fF3=9FwH2df9Kk|NVac z|M#B1|NEbR>+OvqkiUQWd6V=a^bdPzNx(Bse*xnWQc(e^oEj)`16mJfLFK_Du)ZyV37`iAGn7nwcsa>Q)J-2&P*^H&e8TQ<`p4 zxm1#=X6UJsp)?I+J*CKOrfdb5QwB+C)J!RcPO(nSZ1jYE*P;_{PNcA>matC_LOY!W z^$5|{IQ08m+kKM$}TM$`gC?`DragGe^`-~`|<`h za}}+UlfX?iNX~;Srx*kSZjR`#(F8zJ=mWyI!J3%@RYk|Vc*G~_eB$xoW4gam%WIx=p+WP}|IP?d)=0a5TU!hHZF4})S+8M!haAO%g z4KAJyKvuF|R2;R_47;|$pZr%$T0+uYy@L-dldPTUpnwm4ju9LRofy8QqPnua-#Wlx zzH?E7zw@25K@LKTbI5A zre8Xg@zRq{pu4G0`oJwCkOAl%VFOdiCo*9?BtuLMGnHV99YtN3yPS2^O?YX}gK8sg z0wu3lS8o0>SsR(NN9O(qlKO|%2e48%N!5T$F38RKk-m&b5?nJJVR`J{J>!W>mb+k> z>?0Xj64s^cv-tBJOU&2Aye;M}A@6a5u*5HB`kaU)sfGd-9yE8&CPoY%C%%n|3I8-n z)7K4WKr2@aLg9~)CD=5!h=R@Y!^1r?T=bi8v-)>;LsHC2GxdgDp9vo|f2gzMD!8yZ zH7|p11UZgt1VS9&KupCE7pq3u^#b))-K)WK+(ZL)Dgp5kJ2!O@reHS10H z%l@J2{ELC%>OzAb4qe`xZXoEo)io|8aeE4^0sT946oo$JEdG<%@AkD4&9$IwpiVWz Qg_gXvmfW@8uHE$g2RX~}>;M1& diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/certifi/cacert.pem b/venv/lib/python3.11/site-packages/pip/_vendor/certifi/cacert.pem deleted file mode 100755 index 1c2dbfe..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/certifi/cacert.pem +++ /dev/null @@ -1,3863 +0,0 @@ - -# 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=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=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=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=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=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=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: 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=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=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 - 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=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=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=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=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=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----- - -# Issuer: CN=UCA Global G2 Root O=UniTrust -# Subject: CN=UCA Global G2 Root O=UniTrust -# Label: "UCA Global G2 Root" -# Serial: 124779693093741543919145257850076631279 -# MD5 Fingerprint: 80:fe:f0:c4:4a:f0:5c:62:32:9f:1c:ba:78:a9:50:f8 -# SHA1 Fingerprint: 28:f9:78:16:19:7a:ff:18:25:18:aa:44:fe:c1:a0:ce:5c:b6:4c:8a -# SHA256 Fingerprint: 9b:ea:11:c9:76:fe:01:47:64:c1:be:56:a6:f9:14:b5:a5:60:31:7a:bd:99:88:39:33:82:e5:16:1a:a0:49:3c ------BEGIN CERTIFICATE----- -MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9 -MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBH -bG9iYWwgRzIgUm9vdDAeFw0xNjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0x -CzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlUcnVzdDEbMBkGA1UEAwwSVUNBIEds -b2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxeYr -b3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmToni9 -kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzm -VHqUwCoV8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/R -VogvGjqNO7uCEeBHANBSh6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDc -C/Vkw85DvG1xudLeJ1uK6NjGruFZfc8oLTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIj -tm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/R+zvWr9LesGtOxdQXGLY -D0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBeKW4bHAyv -j5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6Dl -NaBa4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6 -iIis7nCs+dwp4wwcOxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznP -O6Q0ibd5Ei9Hxeepl2n8pndntd978XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/ -BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIHEjMz15DD/pQwIX4wV -ZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo5sOASD0Ee/oj -L3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5 -1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl -1qnN3e92mI0ADs0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oU -b3n09tDh05S60FdRvScFDcH9yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LV -PtateJLbXDzz2K36uGt/xDYotgIVilQsnLAXc47QN6MUPJiVAAwpBVueSUmxX8fj -y88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHojhJi6IjMtX9Gl8Cb -EGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZkbxqg -DMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI -+Vg7RE+xygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGy -YiGqhkCyLmTTX8jjfhFnRR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bX -UB+K+wb1whnw0A== ------END CERTIFICATE----- - -# Issuer: CN=UCA Extended Validation Root O=UniTrust -# Subject: CN=UCA Extended Validation Root O=UniTrust -# Label: "UCA Extended Validation Root" -# Serial: 106100277556486529736699587978573607008 -# MD5 Fingerprint: a1:f3:5f:43:c6:34:9b:da:bf:8c:7e:05:53:ad:96:e2 -# SHA1 Fingerprint: a3:a1:b0:6f:24:61:23:4a:e3:36:a5:c2:37:fc:a6:ff:dd:f0:d7:3a -# SHA256 Fingerprint: d4:3a:f9:b3:54:73:75:5c:96:84:fc:06:d7:d8:cb:70:ee:5c:28:e7:73:fb:29:4e:b4:1e:e7:17:22:92:4d:24 ------BEGIN CERTIFICATE----- -MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBH -MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBF -eHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMx -MDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNV -BAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIiMA0GCSqGSIb3DQEB -AQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrsiWog -D4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvS -sPGP2KxFRv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aop -O2z6+I9tTcg1367r3CTueUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dk -sHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR59mzLC52LqGj3n5qiAno8geK+LLNEOfi -c0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH0mK1lTnj8/FtDw5lhIpj -VMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KRel7sFsLz -KuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/ -TuDvB0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41G -sx2VYVdWf6/wFlthWG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs -1+lvK9JKBZP8nm9rZ/+I8U6laUpSNwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQD -fwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS3H5aBZ8eNJr34RQwDwYDVR0T -AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBADaN -l8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR -ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQ -VBcZEhrxH9cMaVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5 -c6sq1WnIeJEmMX3ixzDx/BR4dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp -4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb+7lsq+KePRXBOy5nAliRn+/4Qh8s -t2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOWF3sGPjLtx7dCvHaj -2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwiGpWO -vpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2C -xR9GUeOcGMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmx -cmtpzyKEC2IPrNkZAJSidjzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbM -fjKaiJUINlK73nZfdklJrX+9ZSCyycErdhh2n1ax ------END CERTIFICATE----- - -# Issuer: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 -# Subject: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 -# Label: "Certigna Root CA" -# Serial: 269714418870597844693661054334862075617 -# MD5 Fingerprint: 0e:5c:30:62:27:eb:5b:bc:d7:ae:62:ba:e9:d5:df:77 -# SHA1 Fingerprint: 2d:0d:52:14:ff:9e:ad:99:24:01:74:20:47:6e:6c:85:27:27:f5:43 -# SHA256 Fingerprint: d4:8d:3d:23:ee:db:50:a4:59:e5:51:97:60:1c:27:77:4b:9d:7b:18:c9:4d:5a:05:95:11:a1:02:50:b9:31:68 ------BEGIN CERTIFICATE----- -MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw -WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw -MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x -MzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD -VQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX -BgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw -ggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO -ty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M -CiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu -I9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm -TLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh -C59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf -ePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz -IoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT -Co/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k -JWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5 -hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB -GjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE -FBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of -1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov -L3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo -dHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr -aHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq -hkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L -6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG -HVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6 -0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB -lA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi -o2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1 -gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v -faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63 -Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh -jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw -3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= ------END CERTIFICATE----- - -# Issuer: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI -# Subject: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI -# Label: "emSign Root CA - G1" -# Serial: 235931866688319308814040 -# MD5 Fingerprint: 9c:42:84:57:dd:cb:0b:a7:2e:95:ad:b6:f3:da:bc:ac -# SHA1 Fingerprint: 8a:c7:ad:8f:73:ac:4e:c1:b5:75:4d:a5:40:f4:fc:cf:7c:b5:8e:8c -# SHA256 Fingerprint: 40:f6:af:03:46:a9:9a:a1:cd:1d:55:5a:4e:9c:ce:62:c7:f9:63:46:03:ee:40:66:15:83:3d:c8:c8:d0:03:67 ------BEGIN CERTIFICATE----- -MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD -VQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU -ZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH -MTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgxODMwMDBaMGcxCzAJBgNVBAYTAklO -MRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVkaHJhIFRlY2hub2xv -Z2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIBIjAN -BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQz -f2N4aLTNLnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO -8oG0x5ZOrRkVUkr+PHB1cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aq -d7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHWDV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhM -tTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ6DqS0hdW5TUaQBw+jSzt -Od9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrHhQIDAQAB -o0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQD -AgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31x -PaOfG1vR2vjTnGs2vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjM -wiI/aTvFthUvozXGaCocV685743QNcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6d -GNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q+Mri/Tm3R7nrft8EI6/6nAYH -6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeihU80Bv2noWgby -RQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx -iN66zB+Afko= ------END CERTIFICATE----- - -# Issuer: CN=emSign ECC Root CA - G3 O=eMudhra Technologies Limited OU=emSign PKI -# Subject: CN=emSign ECC Root CA - G3 O=eMudhra Technologies Limited OU=emSign PKI -# Label: "emSign ECC Root CA - G3" -# Serial: 287880440101571086945156 -# MD5 Fingerprint: ce:0b:72:d1:9f:88:8e:d0:50:03:e8:e3:b8:8b:67:40 -# SHA1 Fingerprint: 30:43:fa:4f:f2:57:dc:a0:c3:80:ee:2e:58:ea:78:b2:3f:e6:bb:c1 -# SHA256 Fingerprint: 86:a1:ec:ba:08:9c:4a:8d:3b:be:27:34:c6:12:ba:34:1d:81:3e:04:3c:f9:e8:a8:62:cd:5c:57:a3:6b:be:6b ------BEGIN CERTIFICATE----- -MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG -EwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo -bm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g -RzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJ -TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s -b2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMw -djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0 -WXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xyS -fvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuB -zhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq -hkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB -CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD -+JbNR6iC8hZVdyR+EhCVBCyj ------END CERTIFICATE----- - -# Issuer: CN=emSign Root CA - C1 O=eMudhra Inc OU=emSign PKI -# Subject: CN=emSign Root CA - C1 O=eMudhra Inc OU=emSign PKI -# Label: "emSign Root CA - C1" -# Serial: 825510296613316004955058 -# MD5 Fingerprint: d8:e3:5d:01:21:fa:78:5a:b0:df:ba:d2:ee:2a:5f:68 -# SHA1 Fingerprint: e7:2e:f1:df:fc:b2:09:28:cf:5d:d4:d5:67:37:b1:51:cb:86:4f:01 -# SHA256 Fingerprint: 12:56:09:aa:30:1d:a0:a2:49:b9:7a:82:39:cb:6a:34:21:6f:44:dc:ac:9f:39:54:b1:42:92:f2:e8:c8:60:8f ------BEGIN CERTIFICATE----- -MIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkG -A1UEBhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEg -SW5jMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAw -MFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln -biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNpZ24gUm9v -dCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+upufGZ -BczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZ -HdPIWoU/Xse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH -3DspVpNqs8FqOp099cGXOFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvH -GPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4VI5b2P/AgNBbeCsbEBEV5f6f9vtKppa+c -xSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleoomslMuoaJuvimUnzYnu3Yy1 -aylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+XJGFehiq -TbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL -BQADggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87 -/kOXSTKZEhVb3xEp/6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4 -kqNPEjE2NuLe/gDEo2APJ62gsIq1NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrG -YQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9wC68AivTxEDkigcxHpvOJpkT -+xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQBmIMMMAVSKeo -WXzhriKi4gp6D/piq1JM4fHfyr6DDUI= ------END CERTIFICATE----- - -# Issuer: CN=emSign ECC Root CA - C3 O=eMudhra Inc OU=emSign PKI -# Subject: CN=emSign ECC Root CA - C3 O=eMudhra Inc OU=emSign PKI -# Label: "emSign ECC Root CA - C3" -# Serial: 582948710642506000014504 -# MD5 Fingerprint: 3e:53:b3:a3:81:ee:d7:10:f8:d3:b0:1d:17:92:f5:d5 -# SHA1 Fingerprint: b6:af:43:c2:9b:81:53:7d:f6:ef:6b:c3:1f:1f:60:15:0c:ee:48:66 -# SHA256 Fingerprint: bc:4d:80:9b:15:18:9d:78:db:3e:1d:8c:f4:f9:72:6a:79:5d:a1:64:3c:a5:f1:35:8e:1d:db:0e:dc:0d:7e:b3 ------BEGIN CERTIFICATE----- -MIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQG -EwJVUzETMBEGA1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMx -IDAeBgNVBAMTF2VtU2lnbiBFQ0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAw -MFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln -biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQDExdlbVNpZ24gRUND -IFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd6bci -MK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4Ojavti -sIGJAnB9SMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0O -BBYEFPtaSNCAIEDyqOkAB2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB -Af8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQC02C8Cif22TGK6Q04ThHK1rt0c -3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwUZOR8loMRnLDRWmFLpg9J -0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ== ------END CERTIFICATE----- - -# Issuer: CN=Hongkong Post Root CA 3 O=Hongkong Post -# Subject: CN=Hongkong Post Root CA 3 O=Hongkong Post -# Label: "Hongkong Post Root CA 3" -# Serial: 46170865288971385588281144162979347873371282084 -# MD5 Fingerprint: 11:fc:9f:bd:73:30:02:8a:fd:3f:f3:58:b9:cb:20:f0 -# SHA1 Fingerprint: 58:a2:d0:ec:20:52:81:5b:c1:f3:f8:64:02:24:4e:c2:8e:02:4b:02 -# SHA256 Fingerprint: 5a:2f:c0:3f:0c:83:b0:90:bb:fa:40:60:4b:09:88:44:6c:76:36:18:3d:f9:84:6e:17:10:1a:44:7f:b8:ef:d6 ------BEGIN CERTIFICATE----- -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 -mpv0 ------END CERTIFICATE----- - -# Issuer: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation -# Subject: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation -# Label: "Microsoft ECC Root Certificate Authority 2017" -# Serial: 136839042543790627607696632466672567020 -# MD5 Fingerprint: dd:a1:03:e6:4a:93:10:d1:bf:f0:19:42:cb:fe:ed:67 -# SHA1 Fingerprint: 99:9a:64:c3:7f:f4:7d:9f:ab:95:f1:47:69:89:14:60:ee:c4:c3:c5 -# SHA256 Fingerprint: 35:8d:f3:9d:76:4a:f9:e1:b7:66:e9:c9:72:df:35:2e:e1:5c:fa:c2:27:af:6a:d1:d7:0e:8e:4a:6e:dc:ba:02 ------BEGIN CERTIFICATE----- -MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQsw -CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYD -VQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw -MTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4MjMxNjA0WjBlMQswCQYDVQQGEwJV -UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNy -b3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQBgcq -hkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZR -ogPZnZH6thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYb -hGBKia/teQ87zvH2RPUBeMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8E -BTADAQH/MB0GA1UdDgQWBBTIy5lycFIM+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3 -FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlfXu5gKcs68tvWMoQZP3zV -L8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaReNtUjGUB -iudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M= ------END CERTIFICATE----- - -# Issuer: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation -# Subject: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation -# Label: "Microsoft RSA Root Certificate Authority 2017" -# Serial: 40975477897264996090493496164228220339 -# MD5 Fingerprint: 10:ff:00:ff:cf:c9:f8:c7:7a:c0:ee:35:8e:c9:0f:47 -# SHA1 Fingerprint: 73:a5:e6:4a:3b:ff:83:16:ff:0e:dc:cc:61:8a:90:6e:4e:ae:4d:74 -# SHA256 Fingerprint: c7:41:f7:0f:4b:2a:8d:88:bf:2e:71:c1:41:22:ef:53:ef:10:eb:a0:cf:a5:e6:4c:fa:20:f4:18:85:30:73:e0 ------BEGIN CERTIFICATE----- -MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBl -MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw -NAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 -IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIwNzE4MjMwMDIzWjBlMQswCQYDVQQG -EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1N -aWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZ -Nt9GkMml7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0 -ZdDMbRnMlfl7rEqUrQ7eS0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1 -HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw71VdyvD/IybLeS2v4I2wDwAW9lcfNcztm -gGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+dkC0zVJhUXAoP8XFWvLJ -jEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49FyGcohJUc -aDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaG -YaRSMLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6 -W6IYZVcSn2i51BVrlMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4K -UGsTuqwPN1q3ErWQgR5WrlcihtnJ0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH -+FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJClTUFLkqqNfs+avNJVgyeY+Q -W5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/ -BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC -NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZC -LgLNFgVZJ8og6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OC -gMNPOsduET/m4xaRhPtthH80dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6 -tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk+ONVFT24bcMKpBLBaYVu32TxU5nh -SnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex/2kskZGT4d9Mozd2 -TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDyAmH3 -pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGR -xpl/j8nWZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiApp -GWSZI1b7rCoucL5mxAyE7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9 -dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKTc0QWbej09+CVgI+WXTik9KveCjCHk9hN -AHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D5KbvtwEwXlGjefVwaaZB -RA+GsCyRxj3qrg+E ------END CERTIFICATE----- - -# Issuer: CN=e-Szigno Root CA 2017 O=Microsec Ltd. -# Subject: CN=e-Szigno Root CA 2017 O=Microsec Ltd. -# Label: "e-Szigno Root CA 2017" -# Serial: 411379200276854331539784714 -# MD5 Fingerprint: de:1f:f6:9e:84:ae:a7:b4:21:ce:1e:58:7d:d1:84:98 -# SHA1 Fingerprint: 89:d4:83:03:4f:9e:9a:48:80:5f:72:37:d4:a9:a6:ef:cb:7c:1f:d1 -# SHA256 Fingerprint: be:b0:0b:30:83:9b:9b:c3:2c:32:e4:44:79:05:95:06:41:f2:64:21:b1:5e:d0:89:19:8b:51:8a:e2:ea:1b:99 ------BEGIN CERTIFICATE----- -MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNV -BAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRk -LjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJv -b3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZaFw00MjA4MjIxMjA3MDZaMHExCzAJ -BgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMg -THRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25v -IFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtv -xie+RJCxs1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+H -Wyx7xf58etqjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G -A1UdDgQWBBSHERUI0arBeAyxr87GyZDvvzAEwDAfBgNVHSMEGDAWgBSHERUI0arB -eAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEAtVfd14pVCzbhhkT61Nlo -jbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxOsvxyqltZ -+efcMQ== ------END CERTIFICATE----- - -# Issuer: O=CERTSIGN SA OU=certSIGN ROOT CA G2 -# Subject: O=CERTSIGN SA OU=certSIGN ROOT CA G2 -# Label: "certSIGN Root CA G2" -# Serial: 313609486401300475190 -# MD5 Fingerprint: 8c:f1:75:8a:c6:19:cf:94:b7:f7:65:20:87:c3:97:c7 -# SHA1 Fingerprint: 26:f9:93:b4:ed:3d:28:27:b0:b9:4b:a7:e9:15:1d:a3:8d:92:e5:32 -# SHA256 Fingerprint: 65:7c:fe:2f:a7:3f:aa:38:46:25:71:f3:32:a2:36:3a:46:fc:e7:02:09:51:71:07:02:cd:fb:b6:ee:da:33:05 ------BEGIN CERTIFICATE----- -MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV -BAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04g -Uk9PVCBDQSBHMjAeFw0xNzAyMDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJ -BgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJ -R04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDF -dRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05N0Iw -vlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZ -uIt4ImfkabBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhp -n+Sc8CnTXPnGFiWeI8MgwT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKs -cpc/I1mbySKEwQdPzH/iV8oScLumZfNpdWO9lfsbl83kqK/20U6o2YpxJM02PbyW -xPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91QqhngLjYl/rNUssuHLoPj1P -rCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732jcZZroiF -DsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fx -DTvf95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgy -LcsUDFDYg2WD7rlcz8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6C -eWRgKRM+o/1Pcmqr4tTluCRVLERLiohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB -/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSCIS1mxteg4BXrzkwJ -d8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOBywaK8SJJ6ejq -kX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC -b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQl -qiCA2ClV9+BB/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0 -OJD7uNGzcgbJceaBxXntC6Z58hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+c -NywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5BiKDUyUM/FHE5r7iOZULJK2v0ZXk -ltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklWatKcsWMy5WHgUyIO -pwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tUSxfj -03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZk -PuXaTH4MNMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE -1LlSVHJ7liXMvGnjSG4N0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MX -QRBdJ3NghVdJIgc= ------END CERTIFICATE----- - -# Issuer: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp. -# Subject: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp. -# Label: "NAVER Global Root Certification Authority" -# Serial: 9013692873798656336226253319739695165984492813 -# MD5 Fingerprint: c8:7e:41:f6:25:3b:f5:09:b3:17:e8:46:3d:bf:d0:9b -# SHA1 Fingerprint: 8f:6b:f2:a9:27:4a:da:14:a0:c4:f4:8e:61:27:f9:c0:1e:78:5d:d1 -# SHA256 Fingerprint: 88:f4:38:dc:f8:ff:d1:fa:8f:42:91:15:ff:e5:f8:2a:e1:e0:6e:0c:70:c3:75:fa:ad:71:7b:34:a4:9e:72:65 ------BEGIN CERTIFICATE----- -MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEM -BQAwaTELMAkGA1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRG -T1JNIENvcnAuMTIwMAYDVQQDDClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0 -aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4NDJaFw0zNzA4MTgyMzU5NTlaMGkx -CzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVTUyBQTEFURk9STSBD -b3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlvbiBB -dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVA -iQqrDZBbUGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH -38dq6SZeWYp34+hInDEW+j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lE -HoSTGEq0n+USZGnQJoViAbbJAh2+g1G7XNr4rRVqmfeSVPc0W+m/6imBEtRTkZaz -kVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2aacp+yPOiNgSnABIqKYP -szuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4Yb8Obtoq -vC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHf -nZ3zVHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaG -YQ5fG8Ir4ozVu53BA0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo -0es+nPxdGoMuK8u180SdOqcXYZaicdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3a -CJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejyYhbLgGvtPe31HzClrkvJE+2K -AQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNVHQ4EFgQU0p+I -36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB -Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoN -qo0hV4/GPnrK21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatj -cu3cvuzHV+YwIHHW1xDBE1UBjCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm -+LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bxhYTeodoS76TiEJd6eN4MUZeoIUCL -hr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTgE34h5prCy8VCZLQe -lHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTHD8z7 -p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8 -piKCk5XQA76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLR -LBT/DShycpWbXgnbiUSYqqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX -5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oGI/hGoiLtk/bdmuYqh7GYVPEi92tF4+KO -dh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmgkpzNNIaRkPpkUZ3+/uul -9XXeifdy ------END CERTIFICATE----- - -# Issuer: CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS O=FNMT-RCM OU=Ceres -# Subject: CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS O=FNMT-RCM OU=Ceres -# Label: "AC RAIZ FNMT-RCM SERVIDORES SEGUROS" -# Serial: 131542671362353147877283741781055151509 -# MD5 Fingerprint: 19:36:9c:52:03:2f:d2:d1:bb:23:cc:dd:1e:12:55:bb -# SHA1 Fingerprint: 62:ff:d9:9e:c0:65:0d:03:ce:75:93:d2:ed:3f:2d:32:c9:e3:e5:4a -# SHA256 Fingerprint: 55:41:53:b1:3d:2c:f9:dd:b7:53:bf:be:1a:4e:0a:e0:8d:0a:a4:18:70:58:fe:60:a2:b8:62:b2:e4:b8:7b:cb ------BEGIN CERTIFICATE----- -MIICbjCCAfOgAwIBAgIQYvYybOXE42hcG2LdnC6dlTAKBggqhkjOPQQDAzB4MQsw -CQYDVQQGEwJFUzERMA8GA1UECgwIRk5NVC1SQ00xDjAMBgNVBAsMBUNlcmVzMRgw -FgYDVQRhDA9WQVRFUy1RMjgyNjAwNEoxLDAqBgNVBAMMI0FDIFJBSVogRk5NVC1S -Q00gU0VSVklET1JFUyBTRUdVUk9TMB4XDTE4MTIyMDA5MzczM1oXDTQzMTIyMDA5 -MzczM1oweDELMAkGA1UEBhMCRVMxETAPBgNVBAoMCEZOTVQtUkNNMQ4wDAYDVQQL -DAVDZXJlczEYMBYGA1UEYQwPVkFURVMtUTI4MjYwMDRKMSwwKgYDVQQDDCNBQyBS -QUlaIEZOTVQtUkNNIFNFUlZJRE9SRVMgU0VHVVJPUzB2MBAGByqGSM49AgEGBSuB -BAAiA2IABPa6V1PIyqvfNkpSIeSX0oNnnvBlUdBeh8dHsVnyV0ebAAKTRBdp20LH -sbI6GA60XYyzZl2hNPk2LEnb80b8s0RpRBNm/dfF/a82Tc4DTQdxz69qBdKiQ1oK -Um8BA06Oi6NCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD -VR0OBBYEFAG5L++/EYZg8k/QQW6rcx/n0m5JMAoGCCqGSM49BAMDA2kAMGYCMQCu -SuMrQMN0EfKVrRYj3k4MGuZdpSRea0R7/DjiT8ucRRcRTBQnJlU5dUoDzBOQn5IC -MQD6SmxgiHPz7riYYqnOK8LZiqZwMR2vsJRM60/G49HzYqc8/5MuB1xJAWdpEgJy -v+c= ------END CERTIFICATE----- - -# Issuer: CN=GlobalSign Root R46 O=GlobalSign nv-sa -# Subject: CN=GlobalSign Root R46 O=GlobalSign nv-sa -# Label: "GlobalSign Root R46" -# Serial: 1552617688466950547958867513931858518042577 -# MD5 Fingerprint: c4:14:30:e4:fa:66:43:94:2a:6a:1b:24:5f:19:d0:ef -# SHA1 Fingerprint: 53:a2:b0:4b:ca:6b:d6:45:e6:39:8a:8e:c4:0d:d2:bf:77:c3:a2:90 -# SHA256 Fingerprint: 4f:a3:12:6d:8d:3a:11:d1:c4:85:5a:4f:80:7c:ba:d6:cf:91:9d:3a:5a:88:b0:3b:ea:2c:63:72:d9:3c:40:c9 ------BEGIN CERTIFICATE----- -MIIFWjCCA0KgAwIBAgISEdK7udcjGJ5AXwqdLdDfJWfRMA0GCSqGSIb3DQEBDAUA -MEYxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYD -VQQDExNHbG9iYWxTaWduIFJvb3QgUjQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMy -MDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYt -c2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB -AQUAA4ICDwAwggIKAoICAQCsrHQy6LNl5brtQyYdpokNRbopiLKkHWPd08EsCVeJ -OaFV6Wc0dwxu5FUdUiXSE2te4R2pt32JMl8Nnp8semNgQB+msLZ4j5lUlghYruQG -vGIFAha/r6gjA7aUD7xubMLL1aa7DOn2wQL7Id5m3RerdELv8HQvJfTqa1VbkNud -316HCkD7rRlr+/fKYIje2sGP1q7Vf9Q8g+7XFkyDRTNrJ9CG0Bwta/OrffGFqfUo -0q3v84RLHIf8E6M6cqJaESvWJ3En7YEtbWaBkoe0G1h6zD8K+kZPTXhc+CtI4wSE -y132tGqzZfxCnlEmIyDLPRT5ge1lFgBPGmSXZgjPjHvjK8Cd+RTyG/FWaha/LIWF -zXg4mutCagI0GIMXTpRW+LaCtfOW3T3zvn8gdz57GSNrLNRyc0NXfeD412lPFzYE -+cCQYDdF3uYM2HSNrpyibXRdQr4G9dlkbgIQrImwTDsHTUB+JMWKmIJ5jqSngiCN -I/onccnfxkF0oE32kRbcRoxfKWMxWXEM2G/CtjJ9++ZdU6Z+Ffy7dXxd7Pj2Fxzs -x2sZy/N78CsHpdlseVR2bJ0cpm4O6XkMqCNqo98bMDGfsVR7/mrLZqrcZdCinkqa -ByFrgY/bxFn63iLABJzjqls2k+g9vXqhnQt2sQvHnf3PmKgGwvgqo6GDoLclcqUC -4wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV -HQ4EFgQUA1yrc4GHqMywptWU4jaWSf8FmSwwDQYJKoZIhvcNAQEMBQADggIBAHx4 -7PYCLLtbfpIrXTncvtgdokIzTfnvpCo7RGkerNlFo048p9gkUbJUHJNOxO97k4Vg -JuoJSOD1u8fpaNK7ajFxzHmuEajwmf3lH7wvqMxX63bEIaZHU1VNaL8FpO7XJqti -2kM3S+LGteWygxk6x9PbTZ4IevPuzz5i+6zoYMzRx6Fcg0XERczzF2sUyQQCPtIk -pnnpHs6i58FZFZ8d4kuaPp92CC1r2LpXFNqD6v6MVenQTqnMdzGxRBF6XLE+0xRF -FRhiJBPSy03OXIPBNvIQtQ6IbbjhVp+J3pZmOUdkLG5NrmJ7v2B0GbhWrJKsFjLt -rWhV/pi60zTe9Mlhww6G9kuEYO4Ne7UyWHmRVSyBQ7N0H3qqJZ4d16GLuc1CLgSk -ZoNNiTW2bKg2SnkheCLQQrzRQDGQob4Ez8pn7fXwgNNgyYMqIgXQBztSvwyeqiv5 -u+YfjyW6hY0XHgL+XVAEV8/+LbzvXMAaq7afJMbfc2hIkCwU9D9SGuTSyxTDYWnP -4vkYxboznxSjBF25cfe1lNj2M8FawTSLfJvdkzrnE6JwYZ+vj+vYxXX4M2bUdGc6 -N3ec592kD3ZDZopD8p/7DEJ4Y9HiD2971KE9dJeFt0g5QdYg/NA6s/rob8SKunE3 -vouXsXgxT7PntgMTzlSdriVZzH81Xwj3QEUxeCp6 ------END CERTIFICATE----- - -# Issuer: CN=GlobalSign Root E46 O=GlobalSign nv-sa -# Subject: CN=GlobalSign Root E46 O=GlobalSign nv-sa -# Label: "GlobalSign Root E46" -# Serial: 1552617690338932563915843282459653771421763 -# MD5 Fingerprint: b5:b8:66:ed:de:08:83:e3:c9:e2:01:34:06:ac:51:6f -# SHA1 Fingerprint: 39:b4:6c:d5:fe:80:06:eb:e2:2f:4a:bb:08:33:a0:af:db:b9:dd:84 -# SHA256 Fingerprint: cb:b9:c4:4d:84:b8:04:3e:10:50:ea:31:a6:9f:51:49:55:d7:bf:d2:e2:c6:b4:93:01:01:9a:d6:1d:9f:50:58 ------BEGIN CERTIFICATE----- -MIICCzCCAZGgAwIBAgISEdK7ujNu1LzmJGjFDYQdmOhDMAoGCCqGSM49BAMDMEYx -CzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQD -ExNHbG9iYWxTaWduIFJvb3QgRTQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAw -MDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2Ex -HDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA -IgNiAAScDrHPt+ieUnd1NPqlRqetMhkytAepJ8qUuwzSChDH2omwlwxwEwkBjtjq -R+q+soArzfwoDdusvKSGN+1wCAB16pMLey5SnCNoIwZD7JIvU4Tb+0cUB+hflGdd -yXqBPCCjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud -DgQWBBQxCpCPtsad0kRLgLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ -7Zvvi5QCkxeCmb6zniz2C5GMn0oUsfZkvLtoURMMA/cVi4RguYv/Uo7njLwcAjA8 -+RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+CAezNIm8BZ/3Hobui3A= ------END CERTIFICATE----- - -# Issuer: CN=ANF Secure Server Root CA O=ANF Autoridad de Certificacion OU=ANF CA Raiz -# Subject: CN=ANF Secure Server Root CA O=ANF Autoridad de Certificacion OU=ANF CA Raiz -# Label: "ANF Secure Server Root CA" -# Serial: 996390341000653745 -# MD5 Fingerprint: 26:a6:44:5a:d9:af:4e:2f:b2:1d:b6:65:b0:4e:e8:96 -# SHA1 Fingerprint: 5b:6e:68:d0:cc:15:b6:a0:5f:1e:c1:5f:ae:02:fc:6b:2f:5d:6f:74 -# SHA256 Fingerprint: fb:8f:ec:75:91:69:b9:10:6b:1e:51:16:44:c6:18:c5:13:04:37:3f:6c:06:43:08:8d:8b:ef:fd:1b:99:75:99 ------BEGIN CERTIFICATE----- -MIIF7zCCA9egAwIBAgIIDdPjvGz5a7EwDQYJKoZIhvcNAQELBQAwgYQxEjAQBgNV -BAUTCUc2MzI4NzUxMDELMAkGA1UEBhMCRVMxJzAlBgNVBAoTHkFORiBBdXRvcmlk -YWQgZGUgQ2VydGlmaWNhY2lvbjEUMBIGA1UECxMLQU5GIENBIFJhaXoxIjAgBgNV -BAMTGUFORiBTZWN1cmUgU2VydmVyIFJvb3QgQ0EwHhcNMTkwOTA0MTAwMDM4WhcN -MzkwODMwMTAwMDM4WjCBhDESMBAGA1UEBRMJRzYzMjg3NTEwMQswCQYDVQQGEwJF -UzEnMCUGA1UEChMeQU5GIEF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uMRQwEgYD -VQQLEwtBTkYgQ0EgUmFpejEiMCAGA1UEAxMZQU5GIFNlY3VyZSBTZXJ2ZXIgUm9v -dCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANvrayvmZFSVgpCj -cqQZAZ2cC4Ffc0m6p6zzBE57lgvsEeBbphzOG9INgxwruJ4dfkUyYA8H6XdYfp9q -yGFOtibBTI3/TO80sh9l2Ll49a2pcbnvT1gdpd50IJeh7WhM3pIXS7yr/2WanvtH -2Vdy8wmhrnZEE26cLUQ5vPnHO6RYPUG9tMJJo8gN0pcvB2VSAKduyK9o7PQUlrZX -H1bDOZ8rbeTzPvY1ZNoMHKGESy9LS+IsJJ1tk0DrtSOOMspvRdOoiXsezx76W0OL -zc2oD2rKDF65nkeP8Nm2CgtYZRczuSPkdxl9y0oukntPLxB3sY0vaJxizOBQ+OyR -p1RMVwnVdmPF6GUe7m1qzwmd+nxPrWAI/VaZDxUse6mAq4xhj0oHdkLePfTdsiQz -W7i1o0TJrH93PB0j7IKppuLIBkwC/qxcmZkLLxCKpvR/1Yd0DVlJRfbwcVw5Kda/ -SiOL9V8BY9KHcyi1Swr1+KuCLH5zJTIdC2MKF4EA/7Z2Xue0sUDKIbvVgFHlSFJn -LNJhiQcND85Cd8BEc5xEUKDbEAotlRyBr+Qc5RQe8TZBAQIvfXOn3kLMTOmJDVb3 -n5HUA8ZsyY/b2BzgQJhdZpmYgG4t/wHFzstGH6wCxkPmrqKEPMVOHj1tyRRM4y5B -u8o5vzY8KhmqQYdOpc5LMnndkEl/AgMBAAGjYzBhMB8GA1UdIwQYMBaAFJxf0Gxj -o1+TypOYCK2Mh6UsXME3MB0GA1UdDgQWBBScX9BsY6Nfk8qTmAitjIelLFzBNzAO -BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC -AgEATh65isagmD9uw2nAalxJUqzLK114OMHVVISfk/CHGT0sZonrDUL8zPB1hT+L -9IBdeeUXZ701guLyPI59WzbLWoAAKfLOKyzxj6ptBZNscsdW699QIyjlRRA96Gej -rw5VD5AJYu9LWaL2U/HANeQvwSS9eS9OICI7/RogsKQOLHDtdD+4E5UGUcjohybK -pFtqFiGS3XNgnhAY3jyB6ugYw3yJ8otQPr0R4hUDqDZ9MwFsSBXXiJCZBMXM5gf0 -vPSQ7RPi6ovDj6MzD8EpTBNO2hVWcXNyglD2mjN8orGoGjR0ZVzO0eurU+AagNjq -OknkJjCb5RyKqKkVMoaZkgoQI1YS4PbOTOK7vtuNknMBZi9iPrJyJ0U27U1W45eZ -/zo1PqVUSlJZS2Db7v54EX9K3BR5YLZrZAPbFYPhor72I5dQ8AkzNqdxliXzuUJ9 -2zg/LFis6ELhDtjTO0wugumDLmsx2d1Hhk9tl5EuT+IocTUW0fJz/iUrB0ckYyfI -+PbZa/wSMVYIwFNCr5zQM378BvAxRAMU8Vjq8moNqRGyg77FGr8H6lnco4g175x2 -MjxNBiLOFeXdntiP2t7SxDnlF4HPOEfrf4htWRvfn0IUrn7PqLBmZdo3r5+qPeoo -tt7VMVgWglvquxl1AnMaykgaIZOQCo6ThKd9OyMYkomgjaw= ------END CERTIFICATE----- - -# Issuer: CN=Certum EC-384 CA O=Asseco Data Systems S.A. OU=Certum Certification Authority -# Subject: CN=Certum EC-384 CA O=Asseco Data Systems S.A. OU=Certum Certification Authority -# Label: "Certum EC-384 CA" -# Serial: 160250656287871593594747141429395092468 -# MD5 Fingerprint: b6:65:b3:96:60:97:12:a1:ec:4e:e1:3d:a3:c6:c9:f1 -# SHA1 Fingerprint: f3:3e:78:3c:ac:df:f4:a2:cc:ac:67:55:69:56:d7:e5:16:3c:e1:ed -# SHA256 Fingerprint: 6b:32:80:85:62:53:18:aa:50:d1:73:c9:8d:8b:da:09:d5:7e:27:41:3d:11:4c:f7:87:a0:f5:d0:6c:03:0c:f6 ------BEGIN CERTIFICATE----- -MIICZTCCAeugAwIBAgIQeI8nXIESUiClBNAt3bpz9DAKBggqhkjOPQQDAzB0MQsw -CQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScw -JQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAXBgNVBAMT -EENlcnR1bSBFQy0zODQgQ0EwHhcNMTgwMzI2MDcyNDU0WhcNNDMwMzI2MDcyNDU0 -WjB0MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBT -LkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAX -BgNVBAMTEENlcnR1bSBFQy0zODQgQ0EwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATE -KI6rGFtqvm5kN2PkzeyrOvfMobgOgknXhimfoZTy42B4mIF4Bk3y7JoOV2CDn7Tm -Fy8as10CW4kjPMIRBSqniBMY81CE1700LCeJVf/OTOffph8oxPBUw7l8t1Ot68Kj -QjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI0GZnQkdjrzife81r1HfS+8 -EF9LMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNoADBlAjADVS2m5hjEfO/J -UG7BJw+ch69u1RsIGL2SKcHvlJF40jocVYli5RsJHrpka/F2tNQCMQC0QoSZ/6vn -nvuRlydd3LBbMHHOXjgaatkl5+r3YZJW+OraNsKHZZYuciUvf9/DE8k= ------END CERTIFICATE----- - -# Issuer: CN=Certum Trusted Root CA O=Asseco Data Systems S.A. OU=Certum Certification Authority -# Subject: CN=Certum Trusted Root CA O=Asseco Data Systems S.A. OU=Certum Certification Authority -# Label: "Certum Trusted Root CA" -# Serial: 40870380103424195783807378461123655149 -# MD5 Fingerprint: 51:e1:c2:e7:fe:4c:84:af:59:0e:2f:f4:54:6f:ea:29 -# SHA1 Fingerprint: c8:83:44:c0:18:ae:9f:cc:f1:87:b7:8f:22:d1:c5:d7:45:84:ba:e5 -# SHA256 Fingerprint: fe:76:96:57:38:55:77:3e:37:a9:5e:7a:d4:d9:cc:96:c3:01:57:c1:5d:31:76:5b:a9:b1:57:04:e1:ae:78:fd ------BEGIN CERTIFICATE----- -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 ------END CERTIFICATE----- - -# Issuer: CN=TunTrust Root CA O=Agence Nationale de Certification Electronique -# Subject: CN=TunTrust Root CA O=Agence Nationale de Certification Electronique -# Label: "TunTrust Root CA" -# Serial: 108534058042236574382096126452369648152337120275 -# MD5 Fingerprint: 85:13:b9:90:5b:36:5c:b6:5e:b8:5a:f8:e0:31:57:b4 -# SHA1 Fingerprint: cf:e9:70:84:0f:e0:73:0f:9d:f6:0c:7f:2c:4b:ee:20:46:34:9c:bb -# SHA256 Fingerprint: 2e:44:10:2a:b5:8c:b8:54:19:45:1c:8e:19:d9:ac:f3:66:2c:af:bc:61:4b:6a:53:96:0a:30:f7:d0:e2:eb:41 ------BEGIN CERTIFICATE----- -MIIFszCCA5ugAwIBAgIUEwLV4kBMkkaGFmddtLu7sms+/BMwDQYJKoZIhvcNAQEL -BQAwYTELMAkGA1UEBhMCVE4xNzA1BgNVBAoMLkFnZW5jZSBOYXRpb25hbGUgZGUg -Q2VydGlmaWNhdGlvbiBFbGVjdHJvbmlxdWUxGTAXBgNVBAMMEFR1blRydXN0IFJv -b3QgQ0EwHhcNMTkwNDI2MDg1NzU2WhcNNDQwNDI2MDg1NzU2WjBhMQswCQYDVQQG -EwJUTjE3MDUGA1UECgwuQWdlbmNlIE5hdGlvbmFsZSBkZSBDZXJ0aWZpY2F0aW9u -IEVsZWN0cm9uaXF1ZTEZMBcGA1UEAwwQVHVuVHJ1c3QgUm9vdCBDQTCCAiIwDQYJ -KoZIhvcNAQEBBQADggIPADCCAgoCggIBAMPN0/y9BFPdDCA61YguBUtB9YOCfvdZ -n56eY+hz2vYGqU8ftPkLHzmMmiDQfgbU7DTZhrx1W4eI8NLZ1KMKsmwb60ksPqxd -2JQDoOw05TDENX37Jk0bbjBU2PWARZw5rZzJJQRNmpA+TkBuimvNKWfGzC3gdOgF -VwpIUPp6Q9p+7FuaDmJ2/uqdHYVy7BG7NegfJ7/Boce7SBbdVtfMTqDhuazb1YMZ -GoXRlJfXyqNlC/M4+QKu3fZnz8k/9YosRxqZbwUN/dAdgjH8KcwAWJeRTIAAHDOF -li/LQcKLEITDCSSJH7UP2dl3RxiSlGBcx5kDPP73lad9UKGAwqmDrViWVSHbhlnU -r8a83YFuB9tgYv7sEG7aaAH0gxupPqJbI9dkxt/con3YS7qC0lH4Zr8GRuR5KiY2 -eY8fTpkdso8MDhz/yV3A/ZAQprE38806JG60hZC/gLkMjNWb1sjxVj8agIl6qeIb -MlEsPvLfe/ZdeikZjuXIvTZxi11Mwh0/rViizz1wTaZQmCXcI/m4WEEIcb9PuISg -jwBUFfyRbVinljvrS5YnzWuioYasDXxU5mZMZl+QviGaAkYt5IPCgLnPSz7ofzwB -7I9ezX/SKEIBlYrilz0QIX32nRzFNKHsLA4KUiwSVXAkPcvCFDVDXSdOvsC9qnyW -5/yeYa1E0wCXAgMBAAGjYzBhMB0GA1UdDgQWBBQGmpsfU33x9aTI04Y+oXNZtPdE -ITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFAaamx9TffH1pMjThj6hc1m0 -90QhMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAqgVutt0Vyb+z -xiD2BkewhpMl0425yAA/l/VSJ4hxyXT968pk21vvHl26v9Hr7lxpuhbI87mP0zYu -QEkHDVneixCwSQXi/5E/S7fdAo74gShczNxtr18UnH1YeA32gAm56Q6XKRm4t+v4 -FstVEuTGfbvE7Pi1HE4+Z7/FXxttbUcoqgRYYdZ2vyJ/0Adqp2RT8JeNnYA/u8EH -22Wv5psymsNUk8QcCMNE+3tjEUPRahphanltkE8pjkcFwRJpadbGNjHh/PqAulxP -xOu3Mqz4dWEX1xAZufHSCe96Qp1bWgvUxpVOKs7/B9dPfhgGiPEZtdmYu65xxBzn -dFlY7wyJz4sfdZMaBBSSSFCp61cpABbjNhzI+L/wM9VBD8TMPN3pM0MBkRArHtG5 -Xc0yGYuPjCB31yLEQtyEFpslbei0VXF/sHyz03FJuc9SpAQ/3D2gu68zngowYI7b -nV2UqL1g52KAdoGDDIzMMEZJ4gzSqK/rYXHv5yJiqfdcZGyfFoxnNidF9Ql7v/YQ -CvGwjVRDjAS6oz/v4jXH+XTgbzRB0L9zZVcg+ZtnemZoJE6AZb0QmQZZ8mWvuMZH -u/2QeItBcy6vVR/cO5JyboTT0GFMDcx2V+IthSIVNg3rAZ3r2OvEhJn7wAzMMujj -d9qDRIueVSjAi1jTkD5OGwDxFa2DK5o= ------END CERTIFICATE----- - -# Issuer: CN=HARICA TLS RSA Root CA 2021 O=Hellenic Academic and Research Institutions CA -# Subject: CN=HARICA TLS RSA Root CA 2021 O=Hellenic Academic and Research Institutions CA -# Label: "HARICA TLS RSA Root CA 2021" -# Serial: 76817823531813593706434026085292783742 -# MD5 Fingerprint: 65:47:9b:58:86:dd:2c:f0:fc:a2:84:1f:1e:96:c4:91 -# SHA1 Fingerprint: 02:2d:05:82:fa:88:ce:14:0c:06:79:de:7f:14:10:e9:45:d7:a5:6d -# SHA256 Fingerprint: d9:5d:0e:8e:da:79:52:5b:f9:be:b1:1b:14:d2:10:0d:32:94:98:5f:0c:62:d9:fa:bd:9c:d9:99:ec:cb:7b:1d ------BEGIN CERTIFICATE----- -MIIFpDCCA4ygAwIBAgIQOcqTHO9D88aOk8f0ZIk4fjANBgkqhkiG9w0BAQsFADBs -MQswCQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl -c2VhcmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBSU0Eg -Um9vdCBDQSAyMDIxMB4XDTIxMDIxOTEwNTUzOFoXDTQ1MDIxMzEwNTUzN1owbDEL -MAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl -YXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgUlNBIFJv -b3QgQ0EgMjAyMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIvC569l -mwVnlskNJLnQDmT8zuIkGCyEf3dRywQRNrhe7Wlxp57kJQmXZ8FHws+RFjZiPTgE -4VGC/6zStGndLuwRo0Xua2s7TL+MjaQenRG56Tj5eg4MmOIjHdFOY9TnuEFE+2uv -a9of08WRiFukiZLRgeaMOVig1mlDqa2YUlhu2wr7a89o+uOkXjpFc5gH6l8Cct4M -pbOfrqkdtx2z/IpZ525yZa31MJQjB/OCFks1mJxTuy/K5FrZx40d/JiZ+yykgmvw -Kh+OC19xXFyuQnspiYHLA6OZyoieC0AJQTPb5lh6/a6ZcMBaD9YThnEvdmn8kN3b -LW7R8pv1GmuebxWMevBLKKAiOIAkbDakO/IwkfN4E8/BPzWr8R0RI7VDIp4BkrcY -AuUR0YLbFQDMYTfBKnya4dC6s1BG7oKsnTH4+yPiAwBIcKMJJnkVU2DzOFytOOqB -AGMUuTNe3QvboEUHGjMJ+E20pwKmafTCWQWIZYVWrkvL4N48fS0ayOn7H6NhStYq -E613TBoYm5EPWNgGVMWX+Ko/IIqmhaZ39qb8HOLubpQzKoNQhArlT4b4UEV4AIHr -W2jjJo3Me1xR9BQsQL4aYB16cmEdH2MtiKrOokWQCPxrvrNQKlr9qEgYRtaQQJKQ -CoReaDH46+0N0x3GfZkYVVYnZS6NRcUk7M7jAgMBAAGjQjBAMA8GA1UdEwEB/wQF -MAMBAf8wHQYDVR0OBBYEFApII6ZgpJIKM+qTW8VX6iVNvRLuMA4GA1UdDwEB/wQE -AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAPpBIqm5iFSVmewzVjIuJndftTgfvnNAU -X15QvWiWkKQUEapobQk1OUAJ2vQJLDSle1mESSmXdMgHHkdt8s4cUCbjnj1AUz/3 -f5Z2EMVGpdAgS1D0NTsY9FVqQRtHBmg8uwkIYtlfVUKqrFOFrJVWNlar5AWMxaja -H6NpvVMPxP/cyuN+8kyIhkdGGvMA9YCRotxDQpSbIPDRzbLrLFPCU3hKTwSUQZqP -JzLB5UkZv/HywouoCjkxKLR9YjYsTewfM7Z+d21+UPCfDtcRj88YxeMn/ibvBZ3P -zzfF0HvaO7AWhAw6k9a+F9sPPg4ZeAnHqQJyIkv3N3a6dcSFA1pj1bF1BcK5vZSt -jBWZp5N99sXzqnTPBIWUmAD04vnKJGW/4GKvyMX6ssmeVkjaef2WdhW+o45WxLM0 -/L5H9MG0qPzVMIho7suuyWPEdr6sOBjhXlzPrjoiUevRi7PzKzMHVIf6tLITe7pT -BGIBnfHAT+7hOtSLIBD6Alfm78ELt5BGnBkpjNxvoEppaZS3JGWg/6w/zgH7IS79 -aPib8qXPMThcFarmlwDB31qlpzmq6YR/PFGoOtmUW4y/Twhx5duoXNTSpv4Ao8YW -xw/ogM4cKGR0GQjTQuPOAF1/sdwTsOEFy9EgqoZ0njnnkf3/W9b3raYvAwtt41dU -63ZTGI0RmLo= ------END CERTIFICATE----- - -# Issuer: CN=HARICA TLS ECC Root CA 2021 O=Hellenic Academic and Research Institutions CA -# Subject: CN=HARICA TLS ECC Root CA 2021 O=Hellenic Academic and Research Institutions CA -# Label: "HARICA TLS ECC Root CA 2021" -# Serial: 137515985548005187474074462014555733966 -# MD5 Fingerprint: ae:f7:4c:e5:66:35:d1:b7:9b:8c:22:93:74:d3:4b:b0 -# SHA1 Fingerprint: bc:b0:c1:9d:e9:98:92:70:19:38:57:e9:8d:a7:b4:5d:6e:ee:01:48 -# SHA256 Fingerprint: 3f:99:cc:47:4a:cf:ce:4d:fe:d5:87:94:66:5e:47:8d:15:47:73:9f:2e:78:0f:1b:b4:ca:9b:13:30:97:d4:01 ------BEGIN CERTIFICATE----- -MIICVDCCAdugAwIBAgIQZ3SdjXfYO2rbIvT/WeK/zjAKBggqhkjOPQQDAzBsMQsw -CQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2Vh -cmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBFQ0MgUm9v -dCBDQSAyMDIxMB4XDTIxMDIxOTExMDExMFoXDTQ1MDIxMzExMDEwOVowbDELMAkG -A1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj -aCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgRUNDIFJvb3Qg -Q0EgMjAyMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABDgI/rGgltJ6rK9JOtDA4MM7 -KKrxcm1lAEeIhPyaJmuqS7psBAqIXhfyVYf8MLA04jRYVxqEU+kw2anylnTDUR9Y -STHMmE5gEYd103KUkE+bECUqqHgtvpBBWJAVcqeht6NCMEAwDwYDVR0TAQH/BAUw -AwEB/zAdBgNVHQ4EFgQUyRtTgRL+BNUW0aq8mm+3oJUZbsowDgYDVR0PAQH/BAQD -AgGGMAoGCCqGSM49BAMDA2cAMGQCMBHervjcToiwqfAircJRQO9gcS3ujwLEXQNw -SaSS6sUUiHCm0w2wqsosQJz76YJumgIwK0eaB8bRwoF8yguWGEEbo/QwCZ61IygN -nxS2PFOiTAZpffpskcYqSUXm7LcT4Tps ------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: 1977337328857672817 -# MD5 Fingerprint: 4e:6e:9b:54:4c:ca:b7:fa:48:e4:90:b1:15:4b:1c:a3 -# SHA1 Fingerprint: 0b:be:c2:27:22:49:cb:39:aa:db:35:5c:53:e3:8c:ae:78:ff:b6:fe -# SHA256 Fingerprint: 57:de:05:83:ef:d2:b2:6e:03:61:da:99:da:9d:f4:64:8d:ef:7e:e8:44:1c:3b:72:8a:fa:9b:cd:e0:f9:b2:6a ------BEGIN CERTIFICATE----- -MIIGFDCCA/ygAwIBAgIIG3Dp0v+ubHEwDQYJKoZIhvcNAQELBQAwUTELMAkGA1UE -BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h -cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0xNDA5MjMxNTIyMDdaFw0zNjA1 -MDUxNTIyMDdaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg -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+JIwuwIDAQABo4HvMIHsMB0GA1UdDgQWBBRlzeurNR4APn7VdMAc -tHNHDhpkLzASBgNVHRMBAf8ECDAGAQH/AgEBMIGmBgNVHSAEgZ4wgZswgZgGBFUd -IAAwgY8wLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuZmlybWFwcm9mZXNpb25hbC5j -b20vY3BzMFwGCCsGAQUFBwICMFAeTgBQAGEAcwBlAG8AIABkAGUAIABsAGEAIABC -AG8AbgBhAG4AbwB2AGEAIAA0ADcAIABCAGEAcgBjAGUAbABvAG4AYQAgADAAOAAw -ADEANzAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAHSHKAIrdx9m -iWTtj3QuRhy7qPj4Cx2Dtjqn6EWKB7fgPiDL4QjbEwj4KKE1soCzC1HA01aajTNF -Sa9J8OA9B3pFE1r/yJfY0xgsfZb43aJlQ3CTkBW6kN/oGbDbLIpgD7dvlAceHabJ -hfa9NPhAeGIQcDq+fUs5gakQ1JZBu/hfHAsdCPKxsIl68veg4MSPi3i1O1ilI45P -Vf42O+AMt8oqMEEgtIDNrvx2ZnOorm7hfNoD6JQg5iKj0B+QXSBTFCZX2lSX3xZE -EAEeiGaPcjiT3SC3NL7X8e5jjkd5KAb881lFJWAiMxujX6i6KtoaPc1A6ozuBRWV -1aUsIC+nmCjuRfzxuIgALI9C2lHVnOUTaHFFQ4ueCyE8S1wF3BqfmI7avSKecs2t -CsvMo2ebKHTEm9caPARYpoKdrcd7b/+Alun4jWq9GJAd/0kakFI3ky88Al2CdgtR -5xbHV/g4+afNmyJU72OwFW1TZQNKXkqgsqeOSQBZONXH9IBk9W6VULgRfhVwOEqw -f9DEMnDAGf/JOC0ULGb0QkTmVXYbgBVX/8Cnp6o5qtjTcNAuuuuUavpfNIbnYrX9 -ivAwhZTJryQCL2/W3Wf+47BVTwSYT6RBVuKT0Gro1vP7ZeDOdcQxWQzugsgMYDNK -GbqEZycPvEJdvSRUDewdcAZfpLz6IHxV ------END CERTIFICATE----- - -# Issuer: CN=vTrus ECC Root CA O=iTrusChina Co.,Ltd. -# Subject: CN=vTrus ECC Root CA O=iTrusChina Co.,Ltd. -# Label: "vTrus ECC Root CA" -# Serial: 630369271402956006249506845124680065938238527194 -# MD5 Fingerprint: de:4b:c1:f5:52:8c:9b:43:e1:3e:8f:55:54:17:8d:85 -# SHA1 Fingerprint: f6:9c:db:b0:fc:f6:02:13:b6:52:32:a6:a3:91:3f:16:70:da:c3:e1 -# SHA256 Fingerprint: 30:fb:ba:2c:32:23:8e:2a:98:54:7a:f9:79:31:e5:50:42:8b:9b:3f:1c:8e:eb:66:33:dc:fa:86:c5:b2:7d:d3 ------BEGIN CERTIFICATE----- -MIICDzCCAZWgAwIBAgIUbmq8WapTvpg5Z6LSa6Q75m0c1towCgYIKoZIzj0EAwMw -RzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4xGjAY -BgNVBAMTEXZUcnVzIEVDQyBSb290IENBMB4XDTE4MDczMTA3MjY0NFoXDTQzMDcz -MTA3MjY0NFowRzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28u -LEx0ZC4xGjAYBgNVBAMTEXZUcnVzIEVDQyBSb290IENBMHYwEAYHKoZIzj0CAQYF -K4EEACIDYgAEZVBKrox5lkqqHAjDo6LN/llWQXf9JpRCux3NCNtzslt188+cToL0 -v/hhJoVs1oVbcnDS/dtitN9Ti72xRFhiQgnH+n9bEOf+QP3A2MMrMudwpremIFUd -e4BdS49nTPEQo0IwQDAdBgNVHQ4EFgQUmDnNvtiyjPeyq+GtJK97fKHbH88wDwYD -VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwCgYIKoZIzj0EAwMDaAAwZQIw -V53dVvHH4+m4SVBrm2nDb+zDfSXkV5UTQJtS0zvzQBm8JsctBp61ezaf9SXUY2sA -AjEA6dPGnlaaKsyh2j/IZivTWJwghfqrkYpwcBE4YGQLYgmRWAD5Tfs0aNoJrSEG -GJTO ------END CERTIFICATE----- - -# Issuer: CN=vTrus Root CA O=iTrusChina Co.,Ltd. -# Subject: CN=vTrus Root CA O=iTrusChina Co.,Ltd. -# Label: "vTrus Root CA" -# Serial: 387574501246983434957692974888460947164905180485 -# MD5 Fingerprint: b8:c9:37:df:fa:6b:31:84:64:c5:ea:11:6a:1b:75:fc -# SHA1 Fingerprint: 84:1a:69:fb:f5:cd:1a:25:34:13:3d:e3:f8:fc:b8:99:d0:c9:14:b7 -# SHA256 Fingerprint: 8a:71:de:65:59:33:6f:42:6c:26:e5:38:80:d0:0d:88:a1:8d:a4:c6:a9:1f:0d:cb:61:94:e2:06:c5:c9:63:87 ------BEGIN CERTIFICATE----- -MIIFVjCCAz6gAwIBAgIUQ+NxE9izWRRdt86M/TX9b7wFjUUwDQYJKoZIhvcNAQEL -BQAwQzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4x -FjAUBgNVBAMTDXZUcnVzIFJvb3QgQ0EwHhcNMTgwNzMxMDcyNDA1WhcNNDMwNzMx -MDcyNDA1WjBDMQswCQYDVQQGEwJDTjEcMBoGA1UEChMTaVRydXNDaGluYSBDby4s -THRkLjEWMBQGA1UEAxMNdlRydXMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQAD -ggIPADCCAgoCggIBAL1VfGHTuB0EYgWgrmy3cLRB6ksDXhA/kFocizuwZotsSKYc -IrrVQJLuM7IjWcmOvFjai57QGfIvWcaMY1q6n6MLsLOaXLoRuBLpDLvPbmyAhykU -AyyNJJrIZIO1aqwTLDPxn9wsYTwaP3BVm60AUn/PBLn+NvqcwBauYv6WTEN+VRS+ -GrPSbcKvdmaVayqwlHeFXgQPYh1jdfdr58tbmnDsPmcF8P4HCIDPKNsFxhQnL4Z9 -8Cfe/+Z+M0jnCx5Y0ScrUw5XSmXX+6KAYPxMvDVTAWqXcoKv8R1w6Jz1717CbMdH -flqUhSZNO7rrTOiwCcJlwp2dCZtOtZcFrPUGoPc2BX70kLJrxLT5ZOrpGgrIDajt -J8nU57O5q4IikCc9Kuh8kO+8T/3iCiSn3mUkpF3qwHYw03dQ+A0Em5Q2AXPKBlim -0zvc+gRGE1WKyURHuFE5Gi7oNOJ5y1lKCn+8pu8fA2dqWSslYpPZUxlmPCdiKYZN -pGvu/9ROutW04o5IWgAZCfEF2c6Rsffr6TlP9m8EQ5pV9T4FFL2/s1m02I4zhKOQ -UqqzApVg+QxMaPnu1RcN+HFXtSXkKe5lXa/R7jwXC1pDxaWG6iSe4gUH3DRCEpHW -OXSuTEGC2/KmSNGzm/MzqvOmwMVO9fSddmPmAsYiS8GVP1BkLFTltvA8Kc9XAgMB -AAGjQjBAMB0GA1UdDgQWBBRUYnBj8XWEQ1iO0RYgscasGrz2iTAPBgNVHRMBAf8E -BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAKbqSSaet -8PFww+SX8J+pJdVrnjT+5hpk9jprUrIQeBqfTNqK2uwcN1LgQkv7bHbKJAs5EhWd -nxEt/Hlk3ODg9d3gV8mlsnZwUKT+twpw1aA08XXXTUm6EdGz2OyC/+sOxL9kLX1j -bhd47F18iMjrjld22VkE+rxSH0Ws8HqA7Oxvdq6R2xCOBNyS36D25q5J08FsEhvM -Kar5CKXiNxTKsbhm7xqC5PD48acWabfbqWE8n/Uxy+QARsIvdLGx14HuqCaVvIiv -TDUHKgLKeBRtRytAVunLKmChZwOgzoy8sHJnxDHO2zTlJQNgJXtxmOTAGytfdELS -S8VZCAeHvsXDf+eW2eHcKJfWjwXj9ZtOyh1QRwVTsMo554WgicEFOwE30z9J4nfr -I8iIZjs9OXYhRvHsXyO466JmdXTBQPfYaJqT4i2pLr0cox7IdMakLXogqzu4sEb9 -b91fUlV1YvCXoHzXOP0l382gmxDPi7g4Xl7FtKYCNqEeXxzP4padKar9mK5S4fNB -UvupLnKWnyfjqnN9+BojZns7q2WwMgFLFT49ok8MKzWixtlnEjUwzXYuFrOZnk1P -Ti07NEPhmg4NpGaXutIcSkwsKouLgU9xGqndXHt7CMUADTdA43x7VF8vhV929ven -sBxXVsFy6K2ir40zSbofitzmdHxghm+Hl3s= ------END CERTIFICATE----- - -# Issuer: CN=ISRG Root X2 O=Internet Security Research Group -# Subject: CN=ISRG Root X2 O=Internet Security Research Group -# Label: "ISRG Root X2" -# Serial: 87493402998870891108772069816698636114 -# MD5 Fingerprint: d3:9e:c4:1e:23:3c:a6:df:cf:a3:7e:6d:e0:14:e6:e5 -# SHA1 Fingerprint: bd:b1:b9:3c:d5:97:8d:45:c6:26:14:55:f8:db:95:c7:5a:d1:53:af -# SHA256 Fingerprint: 69:72:9b:8e:15:a8:6e:fc:17:7a:57:af:b7:17:1d:fc:64:ad:d2:8c:2f:ca:8c:f1:50:7e:34:45:3c:cb:14:70 ------BEGIN CERTIFICATE----- -MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw -CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg -R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00 -MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVTMSkwJwYDVQQKEyBJbnRlcm5ldCBT -ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNSRyBSb290IFgyMHYw -EAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0HttwW -+1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9 -ItgKbppbd9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T -AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI -zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW -tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1 -/q4AaOeMSQ+2b1tbFfLn ------END CERTIFICATE----- - -# Issuer: CN=HiPKI Root CA - G1 O=Chunghwa Telecom Co., Ltd. -# Subject: CN=HiPKI Root CA - G1 O=Chunghwa Telecom Co., Ltd. -# Label: "HiPKI Root CA - G1" -# Serial: 60966262342023497858655262305426234976 -# MD5 Fingerprint: 69:45:df:16:65:4b:e8:68:9a:8f:76:5f:ff:80:9e:d3 -# SHA1 Fingerprint: 6a:92:e4:a8:ee:1b:ec:96:45:37:e3:29:57:49:cd:96:e3:e5:d2:60 -# SHA256 Fingerprint: f0:15:ce:3c:c2:39:bf:ef:06:4b:e9:f1:d2:c4:17:e1:a0:26:4a:0a:94:be:1f:0c:8d:12:18:64:eb:69:49:cc ------BEGIN CERTIFICATE----- -MIIFajCCA1KgAwIBAgIQLd2szmKXlKFD6LDNdmpeYDANBgkqhkiG9w0BAQsFADBP -MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 -ZC4xGzAZBgNVBAMMEkhpUEtJIFJvb3QgQ0EgLSBHMTAeFw0xOTAyMjIwOTQ2MDRa -Fw0zNzEyMzExNTU5NTlaME8xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3 -YSBUZWxlY29tIENvLiwgTHRkLjEbMBkGA1UEAwwSSGlQS0kgUm9vdCBDQSAtIEcx -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA9B5/UnMyDHPkvRN0o9Qw -qNCuS9i233VHZvR85zkEHmpwINJaR3JnVfSl6J3VHiGh8Ge6zCFovkRTv4354twv -Vcg3Px+kwJyz5HdcoEb+d/oaoDjq7Zpy3iu9lFc6uux55199QmQ5eiY29yTw1S+6 -lZgRZq2XNdZ1AYDgr/SEYYwNHl98h5ZeQa/rh+r4XfEuiAU+TCK72h8q3VJGZDnz -Qs7ZngyzsHeXZJzA9KMuH5UHsBffMNsAGJZMoYFL3QRtU6M9/Aes1MU3guvklQgZ -KILSQjqj2FPseYlgSGDIcpJQ3AOPgz+yQlda22rpEZfdhSi8MEyr48KxRURHH+CK -FgeW0iEPU8DtqX7UTuybCeyvQqww1r/REEXgphaypcXTT3OUM3ECoWqj1jOXTyFj -HluP2cFeRXF3D4FdXyGarYPM+l7WjSNfGz1BryB1ZlpK9p/7qxj3ccC2HTHsOyDr -y+K49a6SsvfhhEvyovKTmiKe0xRvNlS9H15ZFblzqMF8b3ti6RZsR1pl8w4Rm0bZ -/W3c1pzAtH2lsN0/Vm+h+fbkEkj9Bn8SV7apI09bA8PgcSojt/ewsTu8mL3WmKgM -a/aOEmem8rJY5AIJEzypuxC00jBF8ez3ABHfZfjcK0NVvxaXxA/VLGGEqnKG/uY6 -fsI/fe78LxQ+5oXdUG+3Se0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNV -HQ4EFgQU8ncX+l6o/vY9cdVouslGDDjYr7AwDgYDVR0PAQH/BAQDAgGGMA0GCSqG -SIb3DQEBCwUAA4ICAQBQUfB13HAE4/+qddRxosuej6ip0691x1TPOhwEmSKsxBHi -7zNKpiMdDg1H2DfHb680f0+BazVP6XKlMeJ45/dOlBhbQH3PayFUhuaVevvGyuqc -SE5XCV0vrPSltJczWNWseanMX/mF+lLFjfiRFOs6DRfQUsJ748JzjkZ4Bjgs6Fza -ZsT0pPBWGTMpWmWSBUdGSquEwx4noR8RkpkndZMPvDY7l1ePJlsMu5wP1G4wB9Tc -XzZoZjmDlicmisjEOf6aIW/Vcobpf2Lll07QJNBAsNB1CI69aO4I1258EHBGG3zg -iLKecoaZAeO/n0kZtCW+VmWuF2PlHt/o/0elv+EmBYTksMCv5wiZqAxeJoBF1Pho -L5aPruJKHJwWDBNvOIf2u8g0X5IDUXlwpt/L9ZlNec1OvFefQ05rLisY+GpzjLrF -Ne85akEez3GoorKGB1s6yeHvP2UEgEcyRHCVTjFnanRbEEV16rCf0OY1/k6fi8wr -kkVbbiVghUbN0aqwdmaTd5a+g744tiROJgvM7XpWGuDpWsZkrUx6AEhEL7lAuxM+ -vhV4nYWBSipX3tUZQ9rbyltHhoMLP7YNdnhzeSJesYAfz77RP1YQmCuVh6EfnWQU -YDksswBVLuT1sw5XxJFBAJw/6KXf6vb/yPCtbVKoF6ubYfwSUTXkJf2vqmqGOQ== ------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: 159662223612894884239637590694 -# MD5 Fingerprint: 26:29:f8:6d:e1:88:bf:a2:65:7f:aa:c4:cd:0f:7f:fc -# SHA1 Fingerprint: 6b:a0:b0:98:e1:71:ef:5a:ad:fe:48:15:80:77:10:f4:bd:6f:0b:28 -# SHA256 Fingerprint: b0:85:d7:0b:96:4f:19:1a:73:e4:af:0d:54:ae:7a:0e:07:aa:fd:af:9b:71:dd:08:62:13:8a:b7:32:5a:24:a2 ------BEGIN CERTIFICATE----- -MIIB3DCCAYOgAwIBAgINAgPlfvU/k/2lCSGypjAKBggqhkjOPQQDAjBQMSQwIgYD -VQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2Jh -bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTIxMTEzMDAwMDAwWhcNMzgw -MTE5MDMxNDA3WjBQMSQwIgYDVQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0g -UjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wWTAT -BgcqhkjOPQIBBggqhkjOPQMBBwNCAAS4xnnTj2wlDp8uORkcA6SumuU5BwkWymOx -uYb4ilfBV85C+nOh92VC/x7BALJucw7/xyHlGKSq2XE/qNS5zowdo0IwQDAOBgNV -HQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVLB7rUW44kB/ -+wpu+74zyTyjhNUwCgYIKoZIzj0EAwIDRwAwRAIgIk90crlgr/HmnKAWBVBfw147 -bmF0774BxL4YSFlhgjICICadVGNA3jdgUM/I2O2dgq43mLyjj0xMqTQrbO/7lZsm ------END CERTIFICATE----- - -# Issuer: CN=GTS Root R1 O=Google Trust Services LLC -# Subject: CN=GTS Root R1 O=Google Trust Services LLC -# Label: "GTS Root R1" -# Serial: 159662320309726417404178440727 -# MD5 Fingerprint: 05:fe:d0:bf:71:a8:a3:76:63:da:01:e0:d8:52:dc:40 -# SHA1 Fingerprint: e5:8c:1c:c4:91:3b:38:63:4b:e9:10:6e:e3:ad:8e:6b:9d:d9:81:4a -# SHA256 Fingerprint: d9:47:43:2a:bd:e7:b7:fa:90:fc:2e:6b:59:10:1b:12:80:e0:e1:c7:e4:e4:0f:a3:c6:88:7f:ff:57:a7:f4:cf ------BEGIN CERTIFICATE----- -MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw -CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU -MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw -MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp -Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA -A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo -27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w -Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw -TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl -qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH -szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 -Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk -MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 -wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p -aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN -VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID -AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E -FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb -C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe -QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy -h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 -7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J -ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef -MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ -Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT -6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ -0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm -2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb -bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c ------END CERTIFICATE----- - -# Issuer: CN=GTS Root R3 O=Google Trust Services LLC -# Subject: CN=GTS Root R3 O=Google Trust Services LLC -# Label: "GTS Root R3" -# Serial: 159662495401136852707857743206 -# MD5 Fingerprint: 3e:e7:9d:58:02:94:46:51:94:e5:e0:22:4a:8b:e7:73 -# SHA1 Fingerprint: ed:e5:71:80:2b:c8:92:b9:5b:83:3c:d2:32:68:3f:09:cd:a0:1e:46 -# SHA256 Fingerprint: 34:d8:a7:3e:e2:08:d9:bc:db:0d:95:65:20:93:4b:4e:40:e6:94:82:59:6e:8b:6f:73:c8:42:6b:01:0a:6f:48 ------BEGIN CERTIFICATE----- -MIICCTCCAY6gAwIBAgINAgPluILrIPglJ209ZjAKBggqhkjOPQQDAzBHMQswCQYD -VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG -A1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw -WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz -IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQAIgNi -AAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout736G -jOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL2 -4CejQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW -BBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEA9uEglRR7 -VKOQFhG/hMjqb2sXnh5GmCCbn9MN2azTL818+FsuVbu/3ZL3pAzcMeGiAjEA/Jdm -ZuVDFhOD3cffL74UOO0BzrEXGhF16b0DjyZ+hOXJYKaV11RZt+cRLInUue4X ------END CERTIFICATE----- - -# Issuer: CN=GTS Root R4 O=Google Trust Services LLC -# Subject: CN=GTS Root R4 O=Google Trust Services LLC -# Label: "GTS Root R4" -# Serial: 159662532700760215368942768210 -# MD5 Fingerprint: 43:96:83:77:19:4d:76:b3:9d:65:52:e4:1d:22:a5:e8 -# SHA1 Fingerprint: 77:d3:03:67:b5:e0:0c:15:f6:0c:38:61:df:7c:e1:3b:92:46:4d:47 -# SHA256 Fingerprint: 34:9d:fa:40:58:c5:e2:63:12:3b:39:8a:e7:95:57:3c:4e:13:13:c8:3f:e6:8f:93:55:6c:d5:e8:03:1b:3c:7d ------BEGIN CERTIFICATE----- -MIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYD -VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG -A1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw -WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz -IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi -AATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzuhXyi -QHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvR -HYqjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW -BBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D -9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/Cr8deVl5c1RxYIigL9zC2L7F8AjEA8GE8 -p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh4rsUecrNIdSUtUlD ------END CERTIFICATE----- - -# Issuer: CN=Telia Root CA v2 O=Telia Finland Oyj -# Subject: CN=Telia Root CA v2 O=Telia Finland Oyj -# Label: "Telia Root CA v2" -# Serial: 7288924052977061235122729490515358 -# MD5 Fingerprint: 0e:8f:ac:aa:82:df:85:b1:f4:dc:10:1c:fc:99:d9:48 -# SHA1 Fingerprint: b9:99:cd:d1:73:50:8a:c4:47:05:08:9c:8c:88:fb:be:a0:2b:40:cd -# SHA256 Fingerprint: 24:2b:69:74:2f:cb:1e:5b:2a:bf:98:89:8b:94:57:21:87:54:4e:5b:4d:99:11:78:65:73:62:1f:6a:74:b8:2c ------BEGIN CERTIFICATE----- -MIIFdDCCA1ygAwIBAgIPAWdfJ9b+euPkrL4JWwWeMA0GCSqGSIb3DQEBCwUAMEQx -CzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZMBcGA1UE -AwwQVGVsaWEgUm9vdCBDQSB2MjAeFw0xODExMjkxMTU1NTRaFw00MzExMjkxMTU1 -NTRaMEQxCzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZ -MBcGA1UEAwwQVGVsaWEgUm9vdCBDQSB2MjCCAiIwDQYJKoZIhvcNAQEBBQADggIP -ADCCAgoCggIBALLQPwe84nvQa5n44ndp586dpAO8gm2h/oFlH0wnrI4AuhZ76zBq -AMCzdGh+sq/H1WKzej9Qyow2RCRj0jbpDIX2Q3bVTKFgcmfiKDOlyzG4OiIjNLh9 -vVYiQJ3q9HsDrWj8soFPmNB06o3lfc1jw6P23pLCWBnglrvFxKk9pXSW/q/5iaq9 -lRdU2HhE8Qx3FZLgmEKnpNaqIJLNwaCzlrI6hEKNfdWV5Nbb6WLEWLN5xYzTNTOD -n3WhUidhOPFZPY5Q4L15POdslv5e2QJltI5c0BE0312/UqeBAMN/mUWZFdUXyApT -7GPzmX3MaRKGwhfwAZ6/hLzRUssbkmbOpFPlob/E2wnW5olWK8jjfN7j/4nlNW4o -6GwLI1GpJQXrSPjdscr6bAhR77cYbETKJuFzxokGgeWKrLDiKca5JLNrRBH0pUPC -TEPlcDaMtjNXepUugqD0XBCzYYP2AgWGLnwtbNwDRm41k9V6lS/eINhbfpSQBGq6 -WT0EBXWdN6IOLj3rwaRSg/7Qa9RmjtzG6RJOHSpXqhC8fF6CfaamyfItufUXJ63R -DolUK5X6wK0dmBR4M0KGCqlztft0DbcbMBnEWg4cJ7faGND/isgFuvGqHKI3t+ZI -pEYslOqodmJHixBTB0hXbOKSTbauBcvcwUpej6w9GU7C7WB1K9vBykLVAgMBAAGj -YzBhMB8GA1UdIwQYMBaAFHKs5DN5qkWH9v2sHZ7Wxy+G2CQ5MB0GA1UdDgQWBBRy -rOQzeapFh/b9rB2e1scvhtgkOTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw -AwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAoDtZpwmUPjaE0n4vOaWWl/oRrfxn83EJ -8rKJhGdEr7nv7ZbsnGTbMjBvZ5qsfl+yqwE2foH65IRe0qw24GtixX1LDoJt0nZi -0f6X+J8wfBj5tFJ3gh1229MdqfDBmgC9bXXYfef6xzijnHDoRnkDry5023X4blMM -A8iZGok1GTzTyVR8qPAs5m4HeW9q4ebqkYJpCh3DflminmtGFZhb069GHWLIzoBS -SRE/yQQSwxN8PzuKlts8oB4KtItUsiRnDe+Cy748fdHif64W1lZYudogsYMVoe+K -TTJvQS8TUoKU1xrBeKJR3Stwbbca+few4GeXVtt8YVMJAygCQMez2P2ccGrGKMOF -6eLtGpOg3kuYooQ+BXcBlj37tCAPnHICehIv1aO6UXivKitEZU61/Qrowc15h2Er -3oBXRb9n8ZuRXqWk7FlIEA04x7D6w0RtBPV4UBySllva9bguulvP5fBqnUsvWHMt -Ty3EHD70sz+rFQ47GUGKpMFXEmZxTPpT41frYpUJnlTd0cI8Vzy9OK2YZLe4A5pT -VmBds9hCG1xLEooc6+t9xnppxyd/pPiL8uSUZodL6ZQHCRJ5irLrdATczvREWeAW -ysUsWNc8e89ihmpQfTU2Zqf7N+cox9jQraVplI/owd8k+BsHMYeB2F326CjYSlKA -rBPuUBQemMc= ------END CERTIFICATE----- - -# Issuer: CN=D-TRUST BR Root CA 1 2020 O=D-Trust GmbH -# Subject: CN=D-TRUST BR Root CA 1 2020 O=D-Trust GmbH -# Label: "D-TRUST BR Root CA 1 2020" -# Serial: 165870826978392376648679885835942448534 -# MD5 Fingerprint: b5:aa:4b:d5:ed:f7:e3:55:2e:8f:72:0a:f3:75:b8:ed -# SHA1 Fingerprint: 1f:5b:98:f0:e3:b5:f7:74:3c:ed:e6:b0:36:7d:32:cd:f4:09:41:67 -# SHA256 Fingerprint: e5:9a:aa:81:60:09:c2:2b:ff:5b:25:ba:d3:7d:f3:06:f0:49:79:7c:1f:81:d8:5a:b0:89:e6:57:bd:8f:00:44 ------BEGIN CERTIFICATE----- -MIIC2zCCAmCgAwIBAgIQfMmPK4TX3+oPyWWa00tNljAKBggqhkjOPQQDAzBIMQsw -CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS -VVNUIEJSIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTA5NDUwMFoXDTM1MDIxMTA5 -NDQ1OVowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAG -A1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDEgMjAyMDB2MBAGByqGSM49AgEGBSuB -BAAiA2IABMbLxyjR+4T1mu9CFCDhQ2tuda38KwOE1HaTJddZO0Flax7mNCq7dPYS -zuht56vkPE4/RAiLzRZxy7+SmfSk1zxQVFKQhYN4lGdnoxwJGT11NIXe7WB9xwy0 -QVK5buXuQqOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFHOREKv/ -VbNafAkl1bK6CKBrqx9tMA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6g -PKA6hjhodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X2JyX3Jvb3Rf -Y2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVjdG9yeS5kLXRydXN0Lm5l -dC9DTj1ELVRSVVNUJTIwQlIlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxPPUQtVHJ1 -c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO -PQQDAwNpADBmAjEAlJAtE/rhY/hhY+ithXhUkZy4kzg+GkHaQBZTQgjKL47xPoFW -wKrY7RjEsK70PvomAjEA8yjixtsrmfu3Ubgko6SUeho/5jbiA1czijDLgsfWFBHV -dWNbFJWcHwHP2NVypw87 ------END CERTIFICATE----- - -# Issuer: CN=D-TRUST EV Root CA 1 2020 O=D-Trust GmbH -# Subject: CN=D-TRUST EV Root CA 1 2020 O=D-Trust GmbH -# Label: "D-TRUST EV Root CA 1 2020" -# Serial: 126288379621884218666039612629459926992 -# MD5 Fingerprint: 8c:2d:9d:70:9f:48:99:11:06:11:fb:e9:cb:30:c0:6e -# SHA1 Fingerprint: 61:db:8c:21:59:69:03:90:d8:7c:9c:12:86:54:cf:9d:3d:f4:dd:07 -# SHA256 Fingerprint: 08:17:0d:1a:a3:64:53:90:1a:2f:95:92:45:e3:47:db:0c:8d:37:ab:aa:bc:56:b8:1a:a1:00:dc:95:89:70:db ------BEGIN CERTIFICATE----- -MIIC2zCCAmCgAwIBAgIQXwJB13qHfEwDo6yWjfv/0DAKBggqhkjOPQQDAzBIMQsw -CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS -VVNUIEVWIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTEwMDAwMFoXDTM1MDIxMTA5 -NTk1OVowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAG -A1UEAxMZRC1UUlVTVCBFViBSb290IENBIDEgMjAyMDB2MBAGByqGSM49AgEGBSuB -BAAiA2IABPEL3YZDIBnfl4XoIkqbz52Yv7QFJsnL46bSj8WeeHsxiamJrSc8ZRCC -/N/DnU7wMyPE0jL1HLDfMxddxfCxivnvubcUyilKwg+pf3VlSSowZ/Rk99Yad9rD -wpdhQntJraOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFH8QARY3 -OqQo5FD4pPfsazK2/umLMA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6g -PKA6hjhodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X2V2X3Jvb3Rf -Y2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVjdG9yeS5kLXRydXN0Lm5l -dC9DTj1ELVRSVVNUJTIwRVYlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxPPUQtVHJ1 -c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO -PQQDAwNpADBmAjEAyjzGKnXCXnViOTYAYFqLwZOZzNnbQTs7h5kXO9XMT8oi96CA -y/m0sRtW9XLS/BnRAjEAkfcwkz8QRitxpNA7RJvAKQIFskF3UfN5Wp6OFKBOQtJb -gfM0agPnIjhQW+0ZT0MW ------END CERTIFICATE----- - -# Issuer: CN=DigiCert TLS ECC P384 Root G5 O=DigiCert, Inc. -# Subject: CN=DigiCert TLS ECC P384 Root G5 O=DigiCert, Inc. -# Label: "DigiCert TLS ECC P384 Root G5" -# Serial: 13129116028163249804115411775095713523 -# MD5 Fingerprint: d3:71:04:6a:43:1c:db:a6:59:e1:a8:a3:aa:c5:71:ed -# SHA1 Fingerprint: 17:f3:de:5e:9f:0f:19:e9:8e:f6:1f:32:26:6e:20:c4:07:ae:30:ee -# SHA256 Fingerprint: 01:8e:13:f0:77:25:32:cf:80:9b:d1:b1:72:81:86:72:83:fc:48:c6:e1:3b:e9:c6:98:12:85:4a:49:0c:1b:05 ------BEGIN CERTIFICATE----- -MIICGTCCAZ+gAwIBAgIQCeCTZaz32ci5PhwLBCou8zAKBggqhkjOPQQDAzBOMQsw -CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJjAkBgNVBAMTHURp -Z2lDZXJ0IFRMUyBFQ0MgUDM4NCBSb290IEc1MB4XDTIxMDExNTAwMDAwMFoXDTQ2 -MDExNDIzNTk1OVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ -bmMuMSYwJAYDVQQDEx1EaWdpQ2VydCBUTFMgRUNDIFAzODQgUm9vdCBHNTB2MBAG -ByqGSM49AgEGBSuBBAAiA2IABMFEoc8Rl1Ca3iOCNQfN0MsYndLxf3c1TzvdlHJS -7cI7+Oz6e2tYIOyZrsn8aLN1udsJ7MgT9U7GCh1mMEy7H0cKPGEQQil8pQgO4CLp -0zVozptjn4S1mU1YoI71VOeVyaNCMEAwHQYDVR0OBBYEFMFRRVBZqz7nLFr6ICIS -B4CIfBFqMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49 -BAMDA2gAMGUCMQCJao1H5+z8blUD2WdsJk6Dxv3J+ysTvLd6jLRl0mlpYxNjOyZQ -LgGheQaRnUi/wr4CMEfDFXuxoJGZSZOoPHzoRgaLLPIxAJSdYsiJvRmEFOml+wG4 -DXZDjC5Ty3zfDBeWUA== ------END CERTIFICATE----- - -# Issuer: CN=DigiCert TLS RSA4096 Root G5 O=DigiCert, Inc. -# Subject: CN=DigiCert TLS RSA4096 Root G5 O=DigiCert, Inc. -# Label: "DigiCert TLS RSA4096 Root G5" -# Serial: 11930366277458970227240571539258396554 -# MD5 Fingerprint: ac:fe:f7:34:96:a9:f2:b3:b4:12:4b:e4:27:41:6f:e1 -# SHA1 Fingerprint: a7:88:49:dc:5d:7c:75:8c:8c:de:39:98:56:b3:aa:d0:b2:a5:71:35 -# SHA256 Fingerprint: 37:1a:00:dc:05:33:b3:72:1a:7e:eb:40:e8:41:9e:70:79:9d:2b:0a:0f:2c:1d:80:69:31:65:f7:ce:c4:ad:75 ------BEGIN CERTIFICATE----- -MIIFZjCCA06gAwIBAgIQCPm0eKj6ftpqMzeJ3nzPijANBgkqhkiG9w0BAQwFADBN -MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMT -HERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcN -NDYwMTE0MjM1OTU5WjBNMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQs -IEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz0PTJeRGd/fxmgefM1eS87IE+ -ajWOLrfn3q/5B03PMJ3qCQuZvWxX2hhKuHisOjmopkisLnLlvevxGs3npAOpPxG0 -2C+JFvuUAT27L/gTBaF4HI4o4EXgg/RZG5Wzrn4DReW+wkL+7vI8toUTmDKdFqgp -wgscONyfMXdcvyej/Cestyu9dJsXLfKB2l2w4SMXPohKEiPQ6s+d3gMXsUJKoBZM -pG2T6T867jp8nVid9E6P/DsjyG244gXazOvswzH016cpVIDPRFtMbzCe88zdH5RD -nU1/cHAN1DrRN/BsnZvAFJNY781BOHW8EwOVfH/jXOnVDdXifBBiqmvwPXbzP6Po -sMH976pXTayGpxi0KcEsDr9kvimM2AItzVwv8n/vFfQMFawKsPHTDU9qTXeXAaDx -Zre3zu/O7Oyldcqs4+Fj97ihBMi8ez9dLRYiVu1ISf6nL3kwJZu6ay0/nTvEF+cd -Lvvyz6b84xQslpghjLSR6Rlgg/IwKwZzUNWYOwbpx4oMYIwo+FKbbuH2TbsGJJvX -KyY//SovcfXWJL5/MZ4PbeiPT02jP/816t9JXkGPhvnxd3lLG7SjXi/7RgLQZhNe -XoVPzthwiHvOAbWWl9fNff2C+MIkwcoBOU+NosEUQB+cZtUMCUbW8tDRSHZWOkPL -tgoRObqME2wGtZ7P6wIDAQABo0IwQDAdBgNVHQ4EFgQUUTMc7TZArxfTJc1paPKv -TiM+s0EwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN -AQEMBQADggIBAGCmr1tfV9qJ20tQqcQjNSH/0GEwhJG3PxDPJY7Jv0Y02cEhJhxw -GXIeo8mH/qlDZJY6yFMECrZBu8RHANmfGBg7sg7zNOok992vIGCukihfNudd5N7H -PNtQOa27PShNlnx2xlv0wdsUpasZYgcYQF+Xkdycx6u1UQ3maVNVzDl92sURVXLF -O4uJ+DQtpBflF+aZfTCIITfNMBc9uPK8qHWgQ9w+iUuQrm0D4ByjoJYJu32jtyoQ -REtGBzRj7TG5BO6jm5qu5jF49OokYTurWGT/u4cnYiWB39yhL/btp/96j1EuMPik -AdKFOV8BmZZvWltwGUb+hmA+rYAQCd05JS9Yf7vSdPD3Rh9GOUrYU9DzLjtxpdRv -/PNn5AeP3SYZ4Y1b+qOTEZvpyDrDVWiakuFSdjjo4bq9+0/V77PnSIMx8IIh47a+ -p6tv75/fTM8BuGJqIz3nCU2AG3swpMPdB380vqQmsvZB6Akd4yCYqjdP//fx4ilw -MUc/dNAUFvohigLVigmUdy7yWSiLfFCSCmZ4OIN1xLVaqBHG5cGdZlXPU8Sv13WF -qUITVuwhd4GTWgzqltlJyqEI8pc7bZsEGCREjnwB8twl2F6GmrE52/WRMmrRpnCK -ovfepEWFJqgejF0pW8hL2JpqA15w8oVPbEtoL8pU9ozaMv7Da4M/OMZ+ ------END CERTIFICATE----- - -# Issuer: CN=Certainly Root R1 O=Certainly -# Subject: CN=Certainly Root R1 O=Certainly -# Label: "Certainly Root R1" -# Serial: 188833316161142517227353805653483829216 -# MD5 Fingerprint: 07:70:d4:3e:82:87:a0:fa:33:36:13:f4:fa:33:e7:12 -# SHA1 Fingerprint: a0:50:ee:0f:28:71:f4:27:b2:12:6d:6f:50:96:25:ba:cc:86:42:af -# SHA256 Fingerprint: 77:b8:2c:d8:64:4c:43:05:f7:ac:c5:cb:15:6b:45:67:50:04:03:3d:51:c6:0c:62:02:a8:e0:c3:34:67:d3:a0 ------BEGIN CERTIFICATE----- -MIIFRzCCAy+gAwIBAgIRAI4P+UuQcWhlM1T01EQ5t+AwDQYJKoZIhvcNAQELBQAw -PTELMAkGA1UEBhMCVVMxEjAQBgNVBAoTCUNlcnRhaW5seTEaMBgGA1UEAxMRQ2Vy -dGFpbmx5IFJvb3QgUjEwHhcNMjEwNDAxMDAwMDAwWhcNNDYwNDAxMDAwMDAwWjA9 -MQswCQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0 -YWlubHkgUm9vdCBSMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANA2 -1B/q3avk0bbm+yLA3RMNansiExyXPGhjZjKcA7WNpIGD2ngwEc/csiu+kr+O5MQT -vqRoTNoCaBZ0vrLdBORrKt03H2As2/X3oXyVtwxwhi7xOu9S98zTm/mLvg7fMbed -aFySpvXl8wo0tf97ouSHocavFwDvA5HtqRxOcT3Si2yJ9HiG5mpJoM610rCrm/b0 -1C7jcvk2xusVtyWMOvwlDbMicyF0yEqWYZL1LwsYpfSt4u5BvQF5+paMjRcCMLT5 -r3gajLQ2EBAHBXDQ9DGQilHFhiZ5shGIXsXwClTNSaa/ApzSRKft43jvRl5tcdF5 -cBxGX1HpyTfcX35pe0HfNEXgO4T0oYoKNp43zGJS4YkNKPl6I7ENPT2a/Z2B7yyQ -wHtETrtJ4A5KVpK8y7XdeReJkd5hiXSSqOMyhb5OhaRLWcsrxXiOcVTQAjeZjOVJ -6uBUcqQRBi8LjMFbvrWhsFNunLhgkR9Za/kt9JQKl7XsxXYDVBtlUrpMklZRNaBA -2CnbrlJ2Oy0wQJuK0EJWtLeIAaSHO1OWzaMWj/Nmqhexx2DgwUMFDO6bW2BvBlyH -Wyf5QBGenDPBt+U1VwV/J84XIIwc/PH72jEpSe31C4SnT8H2TsIonPru4K8H+zMR -eiFPCyEQtkA6qyI6BJyLm4SGcprSp6XEtHWRqSsjAgMBAAGjQjBAMA4GA1UdDwEB -/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTgqj8ljZ9EXME66C6u -d0yEPmcM9DANBgkqhkiG9w0BAQsFAAOCAgEAuVevuBLaV4OPaAszHQNTVfSVcOQr -PbA56/qJYv331hgELyE03fFo8NWWWt7CgKPBjcZq91l3rhVkz1t5BXdm6ozTaw3d -8VkswTOlMIAVRQdFGjEitpIAq5lNOo93r6kiyi9jyhXWx8bwPWz8HA2YEGGeEaIi -1wrykXprOQ4vMMM2SZ/g6Q8CRFA3lFV96p/2O7qUpUzpvD5RtOjKkjZUbVwlKNrd -rRT90+7iIgXr0PK3aBLXWopBGsaSpVo7Y0VPv+E6dyIvXL9G+VoDhRNCX8reU9di -taY1BMJH/5n9hN9czulegChB8n3nHpDYT3Y+gjwN/KUD+nsa2UUeYNrEjvn8K8l7 -lcUq/6qJ34IxD3L/DCfXCh5WAFAeDJDBlrXYFIW7pw0WwfgHJBu6haEaBQmAupVj -yTrsJZ9/nbqkRxWbRHDxakvWOF5D8xh+UG7pWijmZeZ3Gzr9Hb4DJqPb1OG7fpYn -Kx3upPvaJVQTA945xsMfTZDsjxtK0hzthZU4UHlG1sGQUDGpXJpuHfUzVounmdLy -yCwzk5Iwx06MZTMQZBf9JBeW0Y3COmor6xOLRPIh80oat3df1+2IpHLlOR+Vnb5n -wXARPbv0+Em34yaXOp/SX3z7wJl8OSngex2/DaeP0ik0biQVy96QXr8axGbqwua6 -OV+KmalBWQewLK8= ------END CERTIFICATE----- - -# Issuer: CN=Certainly Root E1 O=Certainly -# Subject: CN=Certainly Root E1 O=Certainly -# Label: "Certainly Root E1" -# Serial: 8168531406727139161245376702891150584 -# MD5 Fingerprint: 0a:9e:ca:cd:3e:52:50:c6:36:f3:4b:a3:ed:a7:53:e9 -# SHA1 Fingerprint: f9:e1:6d:dc:01:89:cf:d5:82:45:63:3e:c5:37:7d:c2:eb:93:6f:2b -# SHA256 Fingerprint: b4:58:5f:22:e4:ac:75:6a:4e:86:12:a1:36:1c:5d:9d:03:1a:93:fd:84:fe:bb:77:8f:a3:06:8b:0f:c4:2d:c2 ------BEGIN CERTIFICATE----- -MIIB9zCCAX2gAwIBAgIQBiUzsUcDMydc+Y2aub/M+DAKBggqhkjOPQQDAzA9MQsw -CQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0YWlu -bHkgUm9vdCBFMTAeFw0yMTA0MDEwMDAwMDBaFw00NjA0MDEwMDAwMDBaMD0xCzAJ -BgNVBAYTAlVTMRIwEAYDVQQKEwlDZXJ0YWlubHkxGjAYBgNVBAMTEUNlcnRhaW5s -eSBSb290IEUxMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3m/4fxzf7flHh4axpMCK -+IKXgOqPyEpeKn2IaKcBYhSRJHpcnqMXfYqGITQYUBsQ3tA3SybHGWCA6TS9YBk2 -QNYphwk8kXr2vBMj3VlOBF7PyAIcGFPBMdjaIOlEjeR2o0IwQDAOBgNVHQ8BAf8E -BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU8ygYy2R17ikq6+2uI1g4 -hevIIgcwCgYIKoZIzj0EAwMDaAAwZQIxALGOWiDDshliTd6wT99u0nCK8Z9+aozm -ut6Dacpps6kFtZaSF4fC0urQe87YQVt8rgIwRt7qy12a7DLCZRawTDBcMPPaTnOG -BtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR ------END CERTIFICATE----- - -# Issuer: CN=Security Communication ECC RootCA1 O=SECOM Trust Systems CO.,LTD. -# Subject: CN=Security Communication ECC RootCA1 O=SECOM Trust Systems CO.,LTD. -# Label: "Security Communication ECC RootCA1" -# Serial: 15446673492073852651 -# MD5 Fingerprint: 7e:43:b0:92:68:ec:05:43:4c:98:ab:5d:35:2e:7e:86 -# SHA1 Fingerprint: b8:0e:26:a9:bf:d2:b2:3b:c0:ef:46:c9:ba:c7:bb:f6:1d:0d:41:41 -# SHA256 Fingerprint: e7:4f:bd:a5:5b:d5:64:c4:73:a3:6b:44:1a:a7:99:c8:a6:8e:07:74:40:e8:28:8b:9f:a1:e5:0e:4b:ba:ca:11 ------BEGIN CERTIFICATE----- -MIICODCCAb6gAwIBAgIJANZdm7N4gS7rMAoGCCqGSM49BAMDMGExCzAJBgNVBAYT -AkpQMSUwIwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMSswKQYD -VQQDEyJTZWN1cml0eSBDb21tdW5pY2F0aW9uIEVDQyBSb290Q0ExMB4XDTE2MDYx -NjA1MTUyOFoXDTM4MDExODA1MTUyOFowYTELMAkGA1UEBhMCSlAxJTAjBgNVBAoT -HFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKzApBgNVBAMTIlNlY3VyaXR5 -IENvbW11bmljYXRpb24gRUNDIFJvb3RDQTEwdjAQBgcqhkjOPQIBBgUrgQQAIgNi -AASkpW9gAwPDvTH00xecK4R1rOX9PVdu12O/5gSJko6BnOPpR27KkBLIE+Cnnfdl -dB9sELLo5OnvbYUymUSxXv3MdhDYW72ixvnWQuRXdtyQwjWpS4g8EkdtXP9JTxpK -ULGjQjBAMB0GA1UdDgQWBBSGHOf+LaVKiwj+KBH6vqNm+GBZLzAOBgNVHQ8BAf8E -BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjAVXUI9/Lbu -9zuxNuie9sRGKEkz0FhDKmMpzE2xtHqiuQ04pV1IKv3LsnNdo4gIxwwCMQDAqy0O -be0YottT6SXbVQjgUMzfRGEWgqtJsLKB7HOHeLRMsmIbEvoWTSVLY70eN9k= ------END CERTIFICATE----- - -# Issuer: CN=BJCA Global Root CA1 O=BEIJING CERTIFICATE AUTHORITY -# Subject: CN=BJCA Global Root CA1 O=BEIJING CERTIFICATE AUTHORITY -# Label: "BJCA Global Root CA1" -# Serial: 113562791157148395269083148143378328608 -# MD5 Fingerprint: 42:32:99:76:43:33:36:24:35:07:82:9b:28:f9:d0:90 -# SHA1 Fingerprint: d5:ec:8d:7b:4c:ba:79:f4:e7:e8:cb:9d:6b:ae:77:83:10:03:21:6a -# SHA256 Fingerprint: f3:89:6f:88:fe:7c:0a:88:27:66:a7:fa:6a:d2:74:9f:b5:7a:7f:3e:98:fb:76:9c:1f:a7:b0:9c:2c:44:d5:ae ------BEGIN CERTIFICATE----- -MIIFdDCCA1ygAwIBAgIQVW9l47TZkGobCdFsPsBsIDANBgkqhkiG9w0BAQsFADBU -MQswCQYDVQQGEwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRI -T1JJVFkxHTAbBgNVBAMMFEJKQ0EgR2xvYmFsIFJvb3QgQ0ExMB4XDTE5MTIxOTAz -MTYxN1oXDTQ0MTIxMjAzMTYxN1owVDELMAkGA1UEBhMCQ04xJjAkBgNVBAoMHUJF -SUpJTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRCSkNBIEdsb2Jh -bCBSb290IENBMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAPFmCL3Z -xRVhy4QEQaVpN3cdwbB7+sN3SJATcmTRuHyQNZ0YeYjjlwE8R4HyDqKYDZ4/N+AZ -spDyRhySsTphzvq3Rp4Dhtczbu33RYx2N95ulpH3134rhxfVizXuhJFyV9xgw8O5 -58dnJCNPYwpj9mZ9S1WnP3hkSWkSl+BMDdMJoDIwOvqfwPKcxRIqLhy1BDPapDgR -at7GGPZHOiJBhyL8xIkoVNiMpTAK+BcWyqw3/XmnkRd4OJmtWO2y3syJfQOcs4ll -5+M7sSKGjwZteAf9kRJ/sGsciQ35uMt0WwfCyPQ10WRjeulumijWML3mG90Vr4Tq -nMfK9Q7q8l0ph49pczm+LiRvRSGsxdRpJQaDrXpIhRMsDQa4bHlW/KNnMoH1V6XK -V0Jp6VwkYe/iMBhORJhVb3rCk9gZtt58R4oRTklH2yiUAguUSiz5EtBP6DF+bHq/ -pj+bOT0CFqMYs2esWz8sgytnOYFcuX6U1WTdno9uruh8W7TXakdI136z1C2OVnZO -z2nxbkRs1CTqjSShGL+9V/6pmTW12xB3uD1IutbB5/EjPtffhZ0nPNRAvQoMvfXn -jSXWgXSHRtQpdaJCbPdzied9v3pKH9MiyRVVz99vfFXQpIsHETdfg6YmV6YBW37+ -WGgHqel62bno/1Afq8K0wM7o6v0PvY1NuLxxAgMBAAGjQjBAMB0GA1UdDgQWBBTF -7+3M2I0hxkjk49cULqcWk+WYATAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE -AwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAUoKsITQfI/Ki2Pm4rzc2IInRNwPWaZ+4 -YRC6ojGYWUfo0Q0lHhVBDOAqVdVXUsv45Mdpox1NcQJeXyFFYEhcCY5JEMEE3Kli -awLwQ8hOnThJdMkycFRtwUf8jrQ2ntScvd0g1lPJGKm1Vrl2i5VnZu69mP6u775u -+2D2/VnGKhs/I0qUJDAnyIm860Qkmss9vk/Ves6OF8tiwdneHg56/0OGNFK8YT88 -X7vZdrRTvJez/opMEi4r89fO4aL/3Xtw+zuhTaRjAv04l5U/BXCga99igUOLtFkN -SoxUnMW7gZ/NfaXvCyUeOiDbHPwfmGcCCtRzRBPbUYQaVQNW4AB+dAb/OMRyHdOo -P2gxXdMJxy6MW2Pg6Nwe0uxhHvLe5e/2mXZgLR6UcnHGCyoyx5JO1UbXHfmpGQrI -+pXObSOYqgs4rZpWDW+N8TEAiMEXnM0ZNjX+VVOg4DwzX5Ze4jLp3zO7Bkqp2IRz -znfSxqxx4VyjHQy7Ct9f4qNx2No3WqB4K/TUfet27fJhcKVlmtOJNBir+3I+17Q9 -eVzYH6Eze9mCUAyTF6ps3MKCuwJXNq+YJyo5UOGwifUll35HaBC07HPKs5fRJNz2 -YqAo07WjuGS3iGJCz51TzZm+ZGiPTx4SSPfSKcOYKMryMguTjClPPGAyzQWWYezy -r/6zcCwupvI= ------END CERTIFICATE----- - -# Issuer: CN=BJCA Global Root CA2 O=BEIJING CERTIFICATE AUTHORITY -# Subject: CN=BJCA Global Root CA2 O=BEIJING CERTIFICATE AUTHORITY -# Label: "BJCA Global Root CA2" -# Serial: 58605626836079930195615843123109055211 -# MD5 Fingerprint: 5e:0a:f6:47:5f:a6:14:e8:11:01:95:3f:4d:01:eb:3c -# SHA1 Fingerprint: f4:27:86:eb:6e:b8:6d:88:31:67:02:fb:ba:66:a4:53:00:aa:7a:a6 -# SHA256 Fingerprint: 57:4d:f6:93:1e:27:80:39:66:7b:72:0a:fd:c1:60:0f:c2:7e:b6:6d:d3:09:29:79:fb:73:85:64:87:21:28:82 ------BEGIN CERTIFICATE----- -MIICJTCCAaugAwIBAgIQLBcIfWQqwP6FGFkGz7RK6zAKBggqhkjOPQQDAzBUMQsw -CQYDVQQGEwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRIT1JJ -VFkxHTAbBgNVBAMMFEJKQ0EgR2xvYmFsIFJvb3QgQ0EyMB4XDTE5MTIxOTAzMTgy -MVoXDTQ0MTIxMjAzMTgyMVowVDELMAkGA1UEBhMCQ04xJjAkBgNVBAoMHUJFSUpJ -TkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRCSkNBIEdsb2JhbCBS -b290IENBMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABJ3LgJGNU2e1uVCxA/jlSR9B -IgmwUVJY1is0j8USRhTFiy8shP8sbqjV8QnjAyEUxEM9fMEsxEtqSs3ph+B99iK+ -+kpRuDCK/eHeGBIK9ke35xe/J4rUQUyWPGCWwf0VHKNCMEAwHQYDVR0OBBYEFNJK -sVF/BvDRgh9Obl+rg/xI1LCRMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD -AgEGMAoGCCqGSM49BAMDA2gAMGUCMBq8W9f+qdJUDkpd0m2xQNz0Q9XSSpkZElaA -94M04TVOSG0ED1cxMDAtsaqdAzjbBgIxAMvMh1PLet8gUXOQwKhbYdDFUDn9hf7B -43j4ptZLvZuHjw/l1lOWqzzIQNph91Oj9w== ------END CERTIFICATE----- - -# Issuer: CN=Sectigo Public Server Authentication Root E46 O=Sectigo Limited -# Subject: CN=Sectigo Public Server Authentication Root E46 O=Sectigo Limited -# Label: "Sectigo Public Server Authentication Root E46" -# Serial: 88989738453351742415770396670917916916 -# MD5 Fingerprint: 28:23:f8:b2:98:5c:37:16:3b:3e:46:13:4e:b0:b3:01 -# SHA1 Fingerprint: ec:8a:39:6c:40:f0:2e:bc:42:75:d4:9f:ab:1c:1a:5b:67:be:d2:9a -# SHA256 Fingerprint: c9:0f:26:f0:fb:1b:40:18:b2:22:27:51:9b:5c:a2:b5:3e:2c:a5:b3:be:5c:f1:8e:fe:1b:ef:47:38:0c:53:83 ------BEGIN CERTIFICATE----- -MIICOjCCAcGgAwIBAgIQQvLM2htpN0RfFf51KBC49DAKBggqhkjOPQQDAzBfMQsw -CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1T -ZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwHhcN -MjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEYMBYG -A1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBT -ZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA -IgNiAAR2+pmpbiDt+dd34wc7qNs9Xzjoq1WmVk/WSOrsfy2qw7LFeeyZYX8QeccC -WvkEN/U0NSt3zn8gj1KjAIns1aeibVvjS5KToID1AZTc8GgHHs3u/iVStSBDHBv+ -6xnOQ6OjQjBAMB0GA1UdDgQWBBTRItpMWfFLXyY4qp3W7usNw/upYTAOBgNVHQ8B -Af8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNnADBkAjAn7qRa -qCG76UeXlImldCBteU/IvZNeWBj7LRoAasm4PdCkT0RHlAFWovgzJQxC36oCMB3q -4S6ILuH5px0CMk7yn2xVdOOurvulGu7t0vzCAxHrRVxgED1cf5kDW21USAGKcw== ------END CERTIFICATE----- - -# Issuer: CN=Sectigo Public Server Authentication Root R46 O=Sectigo Limited -# Subject: CN=Sectigo Public Server Authentication Root R46 O=Sectigo Limited -# Label: "Sectigo Public Server Authentication Root R46" -# Serial: 156256931880233212765902055439220583700 -# MD5 Fingerprint: 32:10:09:52:00:d5:7e:6c:43:df:15:c0:b1:16:93:e5 -# SHA1 Fingerprint: ad:98:f9:f3:e4:7d:75:3b:65:d4:82:b3:a4:52:17:bb:6e:f5:e4:38 -# SHA256 Fingerprint: 7b:b6:47:a6:2a:ee:ac:88:bf:25:7a:a5:22:d0:1f:fe:a3:95:e0:ab:45:c7:3f:93:f6:56:54:ec:38:f2:5a:06 ------BEGIN CERTIFICATE----- -MIIFijCCA3KgAwIBAgIQdY39i658BwD6qSWn4cetFDANBgkqhkiG9w0BAQwFADBf -MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQD -Ey1TZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYw -HhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEY -MBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1Ymxp -YyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB -AQUAA4ICDwAwggIKAoICAQCTvtU2UnXYASOgHEdCSe5jtrch/cSV1UgrJnwUUxDa -ef0rty2k1Cz66jLdScK5vQ9IPXtamFSvnl0xdE8H/FAh3aTPaE8bEmNtJZlMKpnz -SDBh+oF8HqcIStw+KxwfGExxqjWMrfhu6DtK2eWUAtaJhBOqbchPM8xQljeSM9xf -iOefVNlI8JhD1mb9nxc4Q8UBUQvX4yMPFF1bFOdLvt30yNoDN9HWOaEhUTCDsG3X -ME6WW5HwcCSrv0WBZEMNvSE6Lzzpng3LILVCJ8zab5vuZDCQOc2TZYEhMbUjUDM3 -IuM47fgxMMxF/mL50V0yeUKH32rMVhlATc6qu/m1dkmU8Sf4kaWD5QazYw6A3OAS -VYCmO2a0OYctyPDQ0RTp5A1NDvZdV3LFOxxHVp3i1fuBYYzMTYCQNFu31xR13NgE -SJ/AwSiItOkcyqex8Va3e0lMWeUgFaiEAin6OJRpmkkGj80feRQXEgyDet4fsZfu -+Zd4KKTIRJLpfSYFplhym3kT2BFfrsU4YjRosoYwjviQYZ4ybPUHNs2iTG7sijbt -8uaZFURww3y8nDnAtOFr94MlI1fZEoDlSfB1D++N6xybVCi0ITz8fAr/73trdf+L -HaAZBav6+CuBQug4urv7qv094PPK306Xlynt8xhW6aWWrL3DkJiy4Pmi1KZHQ3xt -zwIDAQABo0IwQDAdBgNVHQ4EFgQUVnNYZJX5khqwEioEYnmhQBWIIUkwDgYDVR0P -AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAC9c -mTz8Bl6MlC5w6tIyMY208FHVvArzZJ8HXtXBc2hkeqK5Duj5XYUtqDdFqij0lgVQ -YKlJfp/imTYpE0RHap1VIDzYm/EDMrraQKFz6oOht0SmDpkBm+S8f74TlH7Kph52 -gDY9hAaLMyZlbcp+nv4fjFg4exqDsQ+8FxG75gbMY/qB8oFM2gsQa6H61SilzwZA -Fv97fRheORKkU55+MkIQpiGRqRxOF3yEvJ+M0ejf5lG5Nkc/kLnHvALcWxxPDkjB -JYOcCj+esQMzEhonrPcibCTRAUH4WAP+JWgiH5paPHxsnnVI84HxZmduTILA7rpX -DhjvLpr3Etiga+kFpaHpaPi8TD8SHkXoUsCjvxInebnMMTzD9joiFgOgyY9mpFui -TdaBJQbpdqQACj7LzTWb4OE4y2BThihCQRxEV+ioratF4yUQvNs+ZUH7G6aXD+u5 -dHn5HrwdVw1Hr8Mvn4dGp+smWg9WY7ViYG4A++MnESLn/pmPNPW56MORcr3Ywx65 -LvKRRFHQV80MNNVIIb/bE/FmJUNS0nAiNs2fxBx1IK1jcmMGDw4nztJqDby1ORrp -0XZ60Vzk50lJLVU3aPAaOpg+VBeHVOmmJ1CJeyAvP/+/oYtKR5j/K3tJPsMpRmAY -QqszKbrAKbkTidOIijlBO8n9pu0f9GBj39ItVQGL ------END CERTIFICATE----- - -# Issuer: CN=SSL.com TLS RSA Root CA 2022 O=SSL Corporation -# Subject: CN=SSL.com TLS RSA Root CA 2022 O=SSL Corporation -# Label: "SSL.com TLS RSA Root CA 2022" -# Serial: 148535279242832292258835760425842727825 -# MD5 Fingerprint: d8:4e:c6:59:30:d8:fe:a0:d6:7a:5a:2c:2c:69:78:da -# SHA1 Fingerprint: ec:2c:83:40:72:af:26:95:10:ff:0e:f2:03:ee:31:70:f6:78:9d:ca -# SHA256 Fingerprint: 8f:af:7d:2e:2c:b4:70:9b:b8:e0:b3:36:66:bf:75:a5:dd:45:b5:de:48:0f:8e:a8:d4:bf:e6:be:bc:17:f2:ed ------BEGIN CERTIFICATE----- -MIIFiTCCA3GgAwIBAgIQb77arXO9CEDii02+1PdbkTANBgkqhkiG9w0BAQsFADBO -MQswCQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQD -DBxTU0wuY29tIFRMUyBSU0EgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzQyMloX -DTQ2MDgxOTE2MzQyMVowTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jw -b3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgUlNBIFJvb3QgQ0EgMjAyMjCC -AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANCkCXJPQIgSYT41I57u9nTP -L3tYPc48DRAokC+X94xI2KDYJbFMsBFMF3NQ0CJKY7uB0ylu1bUJPiYYf7ISf5OY -t6/wNr/y7hienDtSxUcZXXTzZGbVXcdotL8bHAajvI9AI7YexoS9UcQbOcGV0ins -S657Lb85/bRi3pZ7QcacoOAGcvvwB5cJOYF0r/c0WRFXCsJbwST0MXMwgsadugL3 -PnxEX4MN8/HdIGkWCVDi1FW24IBydm5MR7d1VVm0U3TZlMZBrViKMWYPHqIbKUBO -L9975hYsLfy/7PO0+r4Y9ptJ1O4Fbtk085zx7AGL0SDGD6C1vBdOSHtRwvzpXGk3 -R2azaPgVKPC506QVzFpPulJwoxJF3ca6TvvC0PeoUidtbnm1jPx7jMEWTO6Af77w -dr5BUxIzrlo4QqvXDz5BjXYHMtWrifZOZ9mxQnUjbvPNQrL8VfVThxc7wDNY8VLS -+YCk8OjwO4s4zKTGkH8PnP2L0aPP2oOnaclQNtVcBdIKQXTbYxE3waWglksejBYS -d66UNHsef8JmAOSqg+qKkK3ONkRN0VHpvB/zagX9wHQfJRlAUW7qglFA35u5CCoG -AtUjHBPW6dvbxrB6y3snm/vg1UYk7RBLY0ulBY+6uB0rpvqR4pJSvezrZ5dtmi2f -gTIFZzL7SAg/2SW4BCUvAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j -BBgwFoAU+y437uOEeicuzRk1sTN8/9REQrkwHQYDVR0OBBYEFPsuN+7jhHonLs0Z -NbEzfP/UREK5MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAjYlt -hEUY8U+zoO9opMAdrDC8Z2awms22qyIZZtM7QbUQnRC6cm4pJCAcAZli05bg4vsM -QtfhWsSWTVTNj8pDU/0quOr4ZcoBwq1gaAafORpR2eCNJvkLTqVTJXojpBzOCBvf -R4iyrT7gJ4eLSYwfqUdYe5byiB0YrrPRpgqU+tvT5TgKa3kSM/tKWTcWQA673vWJ -DPFs0/dRa1419dvAJuoSc06pkZCmF8NsLzjUo3KUQyxi4U5cMj29TH0ZR6LDSeeW -P4+a0zvkEdiLA9z2tmBVGKaBUfPhqBVq6+AL8BQx1rmMRTqoENjwuSfr98t67wVy -lrXEj5ZzxOhWc5y8aVFjvO9nHEMaX3cZHxj4HCUp+UmZKbaSPaKDN7EgkaibMOlq -bLQjk2UEqxHzDh1TJElTHaE/nUiSEeJ9DU/1172iWD54nR4fK/4huxoTtrEoZP2w -AgDHbICivRZQIA9ygV/MlP+7mea6kMvq+cYMwq7FGc4zoWtcu358NFcXrfA/rs3q -r5nsLFR+jM4uElZI7xc7P0peYNLcdDa8pUNjyw9bowJWCZ4kLOGGgYz+qxcs+sji -Mho6/4UIyYOf8kpIEFR3N+2ivEC+5BB09+Rbu7nzifmPQdjH5FCQNYA+HLhNkNPU -98OwoX6EyneSMSy4kLGCenROmxMmtNVQZlR4rmA= ------END CERTIFICATE----- - -# Issuer: CN=SSL.com TLS ECC Root CA 2022 O=SSL Corporation -# Subject: CN=SSL.com TLS ECC Root CA 2022 O=SSL Corporation -# Label: "SSL.com TLS ECC Root CA 2022" -# Serial: 26605119622390491762507526719404364228 -# MD5 Fingerprint: 99:d7:5c:f1:51:36:cc:e9:ce:d9:19:2e:77:71:56:c5 -# SHA1 Fingerprint: 9f:5f:d9:1a:54:6d:f5:0c:71:f0:ee:7a:bd:17:49:98:84:73:e2:39 -# SHA256 Fingerprint: c3:2f:fd:9f:46:f9:36:d1:6c:36:73:99:09:59:43:4b:9a:d6:0a:af:bb:9e:7c:f3:36:54:f1:44:cc:1b:a1:43 ------BEGIN CERTIFICATE----- -MIICOjCCAcCgAwIBAgIQFAP1q/s3ixdAW+JDsqXRxDAKBggqhkjOPQQDAzBOMQsw -CQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxT -U0wuY29tIFRMUyBFQ0MgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzM0OFoXDTQ2 -MDgxOTE2MzM0N1owTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jwb3Jh -dGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgRUNDIFJvb3QgQ0EgMjAyMjB2MBAG -ByqGSM49AgEGBSuBBAAiA2IABEUpNXP6wrgjzhR9qLFNoFs27iosU8NgCTWyJGYm -acCzldZdkkAZDsalE3D07xJRKF3nzL35PIXBz5SQySvOkkJYWWf9lCcQZIxPBLFN -SeR7T5v15wj4A4j3p8OSSxlUgaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSME -GDAWgBSJjy+j6CugFFR781a4Jl9nOAuc0DAdBgNVHQ4EFgQUiY8vo+groBRUe/NW -uCZfZzgLnNAwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2gAMGUCMFXjIlbp -15IkWE8elDIPDAI2wv2sdDJO4fscgIijzPvX6yv/N33w7deedWo1dlJF4AIxAMeN -b0Igj762TVntd00pxCAgRWSGOlDGxK0tk/UYfXLtqc/ErFc2KAhl3zx5Zn6g6g== ------END CERTIFICATE----- - -# Issuer: CN=Atos TrustedRoot Root CA ECC TLS 2021 O=Atos -# Subject: CN=Atos TrustedRoot Root CA ECC TLS 2021 O=Atos -# Label: "Atos TrustedRoot Root CA ECC TLS 2021" -# Serial: 81873346711060652204712539181482831616 -# MD5 Fingerprint: 16:9f:ad:f1:70:ad:79:d6:ed:29:b4:d1:c5:79:70:a8 -# SHA1 Fingerprint: 9e:bc:75:10:42:b3:02:f3:81:f4:f7:30:62:d4:8f:c3:a7:51:b2:dd -# SHA256 Fingerprint: b2:fa:e5:3e:14:cc:d7:ab:92:12:06:47:01:ae:27:9c:1d:89:88:fa:cb:77:5f:a8:a0:08:91:4e:66:39:88:a8 ------BEGIN CERTIFICATE----- -MIICFTCCAZugAwIBAgIQPZg7pmY9kGP3fiZXOATvADAKBggqhkjOPQQDAzBMMS4w -LAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgRUNDIFRMUyAyMDIxMQ0w -CwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTI2MjNaFw00MTA0 -MTcwOTI2MjJaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBDQSBF -Q0MgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMHYwEAYHKoZI -zj0CAQYFK4EEACIDYgAEloZYKDcKZ9Cg3iQZGeHkBQcfl+3oZIK59sRxUM6KDP/X -tXa7oWyTbIOiaG6l2b4siJVBzV3dscqDY4PMwL502eCdpO5KTlbgmClBk1IQ1SQ4 -AjJn8ZQSb+/Xxd4u/RmAo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR2 -KCXWfeBmmnoJsmo7jjPXNtNPojAOBgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwMD -aAAwZQIwW5kp85wxtolrbNa9d+F851F+uDrNozZffPc8dz7kUK2o59JZDCaOMDtu -CCrCp1rIAjEAmeMM56PDr9NJLkaCI2ZdyQAUEv049OGYa3cpetskz2VAv9LcjBHo -9H1/IISpQuQo ------END CERTIFICATE----- - -# Issuer: CN=Atos TrustedRoot Root CA RSA TLS 2021 O=Atos -# Subject: CN=Atos TrustedRoot Root CA RSA TLS 2021 O=Atos -# Label: "Atos TrustedRoot Root CA RSA TLS 2021" -# Serial: 111436099570196163832749341232207667876 -# MD5 Fingerprint: d4:d3:46:b8:9a:c0:9c:76:5d:9e:3a:c3:b9:99:31:d2 -# SHA1 Fingerprint: 18:52:3b:0d:06:37:e4:d6:3a:df:23:e4:98:fb:5b:16:fb:86:74:48 -# SHA256 Fingerprint: 81:a9:08:8e:a5:9f:b3:64:c5:48:a6:f8:55:59:09:9b:6f:04:05:ef:bf:18:e5:32:4e:c9:f4:57:ba:00:11:2f ------BEGIN CERTIFICATE----- -MIIFZDCCA0ygAwIBAgIQU9XP5hmTC/srBRLYwiqipDANBgkqhkiG9w0BAQwFADBM -MS4wLAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgUlNBIFRMUyAyMDIx -MQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTIxMTBaFw00 -MTA0MTcwOTIxMDlaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBD -QSBSU0EgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMIICIjAN -BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtoAOxHm9BYx9sKOdTSJNy/BBl01Z -4NH+VoyX8te9j2y3I49f1cTYQcvyAh5x5en2XssIKl4w8i1mx4QbZFc4nXUtVsYv -Ye+W/CBGvevUez8/fEc4BKkbqlLfEzfTFRVOvV98r61jx3ncCHvVoOX3W3WsgFWZ -kmGbzSoXfduP9LVq6hdKZChmFSlsAvFr1bqjM9xaZ6cF4r9lthawEO3NUDPJcFDs -GY6wx/J0W2tExn2WuZgIWWbeKQGb9Cpt0xU6kGpn8bRrZtkh68rZYnxGEFzedUln -nkL5/nWpo63/dgpnQOPF943HhZpZnmKaau1Fh5hnstVKPNe0OwANwI8f4UDErmwh -3El+fsqyjW22v5MvoVw+j8rtgI5Y4dtXz4U2OLJxpAmMkokIiEjxQGMYsluMWuPD -0xeqqxmjLBvk1cbiZnrXghmmOxYsL3GHX0WelXOTwkKBIROW1527k2gV+p2kHYzy -geBYBr3JtuP2iV2J+axEoctr+hbxx1A9JNr3w+SH1VbxT5Aw+kUJWdo0zuATHAR8 -ANSbhqRAvNncTFd+rrcztl524WWLZt+NyteYr842mIycg5kDcPOvdO3GDjbnvezB -c6eUWsuSZIKmAMFwoW4sKeFYV+xafJlrJaSQOoD0IJ2azsct+bJLKZWD6TWNp0lI -pw9MGZHQ9b8Q4HECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU -dEmZ0f+0emhFdcN+tNzMzjkz2ggwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB -DAUAA4ICAQAjQ1MkYlxt/T7Cz1UAbMVWiLkO3TriJQ2VSpfKgInuKs1l+NsW4AmS -4BjHeJi78+xCUvuppILXTdiK/ORO/auQxDh1MoSf/7OwKwIzNsAQkG8dnK/haZPs -o0UvFJ/1TCplQ3IM98P4lYsU84UgYt1UU90s3BiVaU+DR3BAM1h3Egyi61IxHkzJ -qM7F78PRreBrAwA0JrRUITWXAdxfG/F851X6LWh3e9NpzNMOa7pNdkTWwhWaJuyw -xfW70Xp0wmzNxbVe9kzmWy2B27O3Opee7c9GslA9hGCZcbUztVdF5kJHdWoOsAgM -rr3e97sPWD2PAzHoPYJQyi9eDF20l74gNAf0xBLh7tew2VktafcxBPTy+av5EzH4 -AXcOPUIjJsyacmdRIXrMPIWo6iFqO9taPKU0nprALN+AnCng33eU0aKAQv9qTFsR -0PXNor6uzFFcw9VUewyu1rkGd4Di7wcaaMxZUa1+XGdrudviB0JbuAEFWDlN5LuY -o7Ey7Nmj1m+UI/87tyll5gfp77YZ6ufCOB0yiJA8EytuzO+rdwY0d4RPcuSBhPm5 -dDTedk+SKlOxJTnbPP/lPqYO5Wue/9vsL3SD3460s6neFE3/MaNFcyT6lSnMEpcE -oji2jbDwN/zIIX8/syQbPYtuzE2wFg2WHYMfRsCbvUOZ58SWLs5fyQ== ------END CERTIFICATE----- - -# Issuer: CN=TrustAsia Global Root CA G3 O=TrustAsia Technologies, Inc. -# Subject: CN=TrustAsia Global Root CA G3 O=TrustAsia Technologies, Inc. -# Label: "TrustAsia Global Root CA G3" -# Serial: 576386314500428537169965010905813481816650257167 -# MD5 Fingerprint: 30:42:1b:b7:bb:81:75:35:e4:16:4f:53:d2:94:de:04 -# SHA1 Fingerprint: 63:cf:b6:c1:27:2b:56:e4:88:8e:1c:23:9a:b6:2e:81:47:24:c3:c7 -# SHA256 Fingerprint: e0:d3:22:6a:eb:11:63:c2:e4:8f:f9:be:3b:50:b4:c6:43:1b:e7:bb:1e:ac:c5:c3:6b:5d:5e:c5:09:03:9a:08 ------BEGIN CERTIFICATE----- -MIIFpTCCA42gAwIBAgIUZPYOZXdhaqs7tOqFhLuxibhxkw8wDQYJKoZIhvcNAQEM -BQAwWjELMAkGA1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dp -ZXMsIEluYy4xJDAiBgNVBAMMG1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHMzAe -Fw0yMTA1MjAwMjEwMTlaFw00NjA1MTkwMjEwMTlaMFoxCzAJBgNVBAYTAkNOMSUw -IwYDVQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQwIgYDVQQDDBtU -cnVzdEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzMwggIiMA0GCSqGSIb3DQEBAQUAA4IC -DwAwggIKAoICAQDAMYJhkuSUGwoqZdC+BqmHO1ES6nBBruL7dOoKjbmzTNyPtxNS -T1QY4SxzlZHFZjtqz6xjbYdT8PfxObegQ2OwxANdV6nnRM7EoYNl9lA+sX4WuDqK -AtCWHwDNBSHvBm3dIZwZQ0WhxeiAysKtQGIXBsaqvPPW5vxQfmZCHzyLpnl5hkA1 -nyDvP+uLRx+PjsXUjrYsyUQE49RDdT/VP68czH5GX6zfZBCK70bwkPAPLfSIC7Ep -qq+FqklYqL9joDiR5rPmd2jE+SoZhLsO4fWvieylL1AgdB4SQXMeJNnKziyhWTXA -yB1GJ2Faj/lN03J5Zh6fFZAhLf3ti1ZwA0pJPn9pMRJpxx5cynoTi+jm9WAPzJMs -hH/x/Gr8m0ed262IPfN2dTPXS6TIi/n1Q1hPy8gDVI+lhXgEGvNz8teHHUGf59gX -zhqcD0r83ERoVGjiQTz+LISGNzzNPy+i2+f3VANfWdP3kXjHi3dqFuVJhZBFcnAv -kV34PmVACxmZySYgWmjBNb9Pp1Hx2BErW+Canig7CjoKH8GB5S7wprlppYiU5msT -f9FkPz2ccEblooV7WIQn3MSAPmeamseaMQ4w7OYXQJXZRe0Blqq/DPNL0WP3E1jA -uPP6Z92bfW1K/zJMtSU7/xxnD4UiWQWRkUF3gdCFTIcQcf+eQxuulXUtgQIDAQAB -o2MwYTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEDk5PIj7zjKsK5Xf/Ih -MBY027ySMB0GA1UdDgQWBBRA5OTyI+84yrCuV3/yITAWNNu8kjAOBgNVHQ8BAf8E -BAMCAQYwDQYJKoZIhvcNAQEMBQADggIBACY7UeFNOPMyGLS0XuFlXsSUT9SnYaP4 -wM8zAQLpw6o1D/GUE3d3NZ4tVlFEbuHGLige/9rsR82XRBf34EzC4Xx8MnpmyFq2 -XFNFV1pF1AWZLy4jVe5jaN/TG3inEpQGAHUNcoTpLrxaatXeL1nHo+zSh2bbt1S1 -JKv0Q3jbSwTEb93mPmY+KfJLaHEih6D4sTNjduMNhXJEIlU/HHzp/LgV6FL6qj6j -ITk1dImmasI5+njPtqzn59ZW/yOSLlALqbUHM/Q4X6RJpstlcHboCoWASzY9M/eV -VHUl2qzEc4Jl6VL1XP04lQJqaTDFHApXB64ipCz5xUG3uOyfT0gA+QEEVcys+TIx -xHWVBqB/0Y0n3bOppHKH/lmLmnp0Ft0WpWIp6zqW3IunaFnT63eROfjXy9mPX1on -AX1daBli2MjN9LdyR75bl87yraKZk62Uy5P2EgmVtqvXO9A/EcswFi55gORngS1d -7XB4tmBZrOFdRWOPyN9yaFvqHbgB8X7754qz41SgOAngPN5C8sLtLpvzHzW2Ntjj -gKGLzZlkD8Kqq7HK9W+eQ42EVJmzbsASZthwEPEGNTNDqJwuuhQxzhB/HIbjj9LV -+Hfsm6vxL2PZQl/gZ4FkkfGXL/xuJvYz+NO1+MRiqzFRJQJ6+N1rZdVtTTDIZbpo -FGWsJwt0ivKH ------END CERTIFICATE----- - -# Issuer: CN=TrustAsia Global Root CA G4 O=TrustAsia Technologies, Inc. -# Subject: CN=TrustAsia Global Root CA G4 O=TrustAsia Technologies, Inc. -# Label: "TrustAsia Global Root CA G4" -# Serial: 451799571007117016466790293371524403291602933463 -# MD5 Fingerprint: 54:dd:b2:d7:5f:d8:3e:ed:7c:e0:0b:2e:cc:ed:eb:eb -# SHA1 Fingerprint: 57:73:a5:61:5d:80:b2:e6:ac:38:82:fc:68:07:31:ac:9f:b5:92:5a -# SHA256 Fingerprint: be:4b:56:cb:50:56:c0:13:6a:52:6d:f4:44:50:8d:aa:36:a0:b5:4f:42:e4:ac:38:f7:2a:f4:70:e4:79:65:4c ------BEGIN CERTIFICATE----- -MIICVTCCAdygAwIBAgIUTyNkuI6XY57GU4HBdk7LKnQV1tcwCgYIKoZIzj0EAwMw -WjELMAkGA1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dpZXMs -IEluYy4xJDAiBgNVBAMMG1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHNDAeFw0y -MTA1MjAwMjEwMjJaFw00NjA1MTkwMjEwMjJaMFoxCzAJBgNVBAYTAkNOMSUwIwYD -VQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQwIgYDVQQDDBtUcnVz -dEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATx -s8045CVD5d4ZCbuBeaIVXxVjAd7Cq92zphtnS4CDr5nLrBfbK5bKfFJV4hrhPVbw -LxYI+hW8m7tH5j/uqOFMjPXTNvk4XatwmkcN4oFBButJ+bAp3TPsUKV/eSm4IJij -YzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUpbtKl86zK3+kMd6Xg1mD -pm9xy94wHQYDVR0OBBYEFKW7SpfOsyt/pDHel4NZg6ZvccveMA4GA1UdDwEB/wQE -AwIBBjAKBggqhkjOPQQDAwNnADBkAjBe8usGzEkxn0AAbbd+NvBNEU/zy4k6LHiR -UKNbwMp1JvK/kF0LgoxgKJ/GcJpo5PECMFxYDlZ2z1jD1xCMuo6u47xkdUfFVZDj -/bpV6wfEU6s3qe4hsiFbYI89MvHVI5TWWA== ------END CERTIFICATE----- - -# Issuer: CN=Telekom Security TLS ECC Root 2020 O=Deutsche Telekom Security GmbH -# Subject: CN=Telekom Security TLS ECC Root 2020 O=Deutsche Telekom Security GmbH -# Label: "Telekom Security TLS ECC Root 2020" -# Serial: 72082518505882327255703894282316633856 -# MD5 Fingerprint: c1:ab:fe:6a:10:2c:03:8d:bc:1c:22:32:c0:85:a7:fd -# SHA1 Fingerprint: c0:f8:96:c5:a9:3b:01:06:21:07:da:18:42:48:bc:e9:9d:88:d5:ec -# SHA256 Fingerprint: 57:8a:f4:de:d0:85:3f:4e:59:98:db:4a:ea:f9:cb:ea:8d:94:5f:60:b6:20:a3:8d:1a:3c:13:b2:bc:7b:a8:e1 ------BEGIN CERTIFICATE----- -MIICQjCCAcmgAwIBAgIQNjqWjMlcsljN0AFdxeVXADAKBggqhkjOPQQDAzBjMQsw -CQYDVQQGEwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBH -bWJIMSswKQYDVQQDDCJUZWxla29tIFNlY3VyaXR5IFRMUyBFQ0MgUm9vdCAyMDIw -MB4XDTIwMDgyNTA3NDgyMFoXDTQ1MDgyNTIzNTk1OVowYzELMAkGA1UEBhMCREUx -JzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJpdHkgR21iSDErMCkGA1UE -AwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgRUNDIFJvb3QgMjAyMDB2MBAGByqGSM49 -AgEGBSuBBAAiA2IABM6//leov9Wq9xCazbzREaK9Z0LMkOsVGJDZos0MKiXrPk/O -tdKPD/M12kOLAoC+b1EkHQ9rK8qfwm9QMuU3ILYg/4gND21Ju9sGpIeQkpT0CdDP -f8iAC8GXs7s1J8nCG6NCMEAwHQYDVR0OBBYEFONyzG6VmUex5rNhTNHLq+O6zd6f -MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2cA -MGQCMHVSi7ekEE+uShCLsoRbQuHmKjYC2qBuGT8lv9pZMo7k+5Dck2TOrbRBR2Di -z6fLHgIwN0GMZt9Ba9aDAEH9L1r3ULRn0SyocddDypwnJJGDSA3PzfdUga/sf+Rn -27iQ7t0l ------END CERTIFICATE----- - -# Issuer: CN=Telekom Security TLS RSA Root 2023 O=Deutsche Telekom Security GmbH -# Subject: CN=Telekom Security TLS RSA Root 2023 O=Deutsche Telekom Security GmbH -# Label: "Telekom Security TLS RSA Root 2023" -# Serial: 44676229530606711399881795178081572759 -# MD5 Fingerprint: bf:5b:eb:54:40:cd:48:71:c4:20:8d:7d:de:0a:42:f2 -# SHA1 Fingerprint: 54:d3:ac:b3:bd:57:56:f6:85:9d:ce:e5:c3:21:e2:d4:ad:83:d0:93 -# SHA256 Fingerprint: ef:c6:5c:ad:bb:59:ad:b6:ef:e8:4d:a2:23:11:b3:56:24:b7:1b:3b:1e:a0:da:8b:66:55:17:4e:c8:97:86:46 ------BEGIN CERTIFICATE----- -MIIFszCCA5ugAwIBAgIQIZxULej27HF3+k7ow3BXlzANBgkqhkiG9w0BAQwFADBj -MQswCQYDVQQGEwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0 -eSBHbWJIMSswKQYDVQQDDCJUZWxla29tIFNlY3VyaXR5IFRMUyBSU0EgUm9vdCAy -MDIzMB4XDTIzMDMyODEyMTY0NVoXDTQ4MDMyNzIzNTk1OVowYzELMAkGA1UEBhMC -REUxJzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJpdHkgR21iSDErMCkG -A1UEAwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgUlNBIFJvb3QgMjAyMzCCAiIwDQYJ -KoZIhvcNAQEBBQADggIPADCCAgoCggIBAO01oYGA88tKaVvC+1GDrib94W7zgRJ9 -cUD/h3VCKSHtgVIs3xLBGYSJwb3FKNXVS2xE1kzbB5ZKVXrKNoIENqil/Cf2SfHV -cp6R+SPWcHu79ZvB7JPPGeplfohwoHP89v+1VmLhc2o0mD6CuKyVU/QBoCcHcqMA -U6DksquDOFczJZSfvkgdmOGjup5czQRxUX11eKvzWarE4GC+j4NSuHUaQTXtvPM6 -Y+mpFEXX5lLRbtLevOP1Czvm4MS9Q2QTps70mDdsipWol8hHD/BeEIvnHRz+sTug -BTNoBUGCwQMrAcjnj02r6LX2zWtEtefdi+zqJbQAIldNsLGyMcEWzv/9FIS3R/qy -8XDe24tsNlikfLMR0cN3f1+2JeANxdKz+bi4d9s3cXFH42AYTyS2dTd4uaNir73J -co4vzLuu2+QVUhkHM/tqty1LkCiCc/4YizWN26cEar7qwU02OxY2kTLvtkCJkUPg -8qKrBC7m8kwOFjQgrIfBLX7JZkcXFBGk8/ehJImr2BrIoVyxo/eMbcgByU/J7MT8 -rFEz0ciD0cmfHdRHNCk+y7AO+oMLKFjlKdw/fKifybYKu6boRhYPluV75Gp6SG12 -mAWl3G0eQh5C2hrgUve1g8Aae3g1LDj1H/1Joy7SWWO/gLCMk3PLNaaZlSJhZQNg -+y+TS/qanIA7AgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUtqeX -gj10hZv3PJ+TmpV5dVKMbUcwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS2 -p5eCPXSFm/c8n5OalXl1UoxtRzANBgkqhkiG9w0BAQwFAAOCAgEAqMxhpr51nhVQ -pGv7qHBFfLp+sVr8WyP6Cnf4mHGCDG3gXkaqk/QeoMPhk9tLrbKmXauw1GLLXrtm -9S3ul0A8Yute1hTWjOKWi0FpkzXmuZlrYrShF2Y0pmtjxrlO8iLpWA1WQdH6DErw -M807u20hOq6OcrXDSvvpfeWxm4bu4uB9tPcy/SKE8YXJN3nptT+/XOR0so8RYgDd -GGah2XsjX/GO1WfoVNpbOms2b/mBsTNHM3dA+VKq3dSDz4V4mZqTuXNnQkYRIer+ -CqkbGmVps4+uFrb2S1ayLfmlyOw7YqPta9BO1UAJpB+Y1zqlklkg5LB9zVtzaL1t -xKITDmcZuI1CfmwMmm6gJC3VRRvcxAIU/oVbZZfKTpBQCHpCNfnqwmbU+AGuHrS+ -w6jv/naaoqYfRvaE7fzbzsQCzndILIyy7MMAo+wsVRjBfhnu4S/yrYObnqsZ38aK -L4x35bcF7DvB7L6Gs4a8wPfc5+pbrrLMtTWGS9DiP7bY+A4A7l3j941Y/8+LN+lj -X273CXE2whJdV/LItM3z7gLfEdxquVeEHVlNjM7IDiPCtyaaEBRx/pOyiriA8A4Q -ntOoUAw3gi/q4Iqd4Sw5/7W0cwDk90imc6y/st53BIe0o82bNSQ3+pCTE4FCxpgm -dTdmQRCsu/WU48IxK63nI1bMNSWSs1A= ------END CERTIFICATE----- - -# Issuer: CN=TWCA CYBER Root CA O=TAIWAN-CA OU=Root CA -# Subject: CN=TWCA CYBER Root CA O=TAIWAN-CA OU=Root CA -# Label: "TWCA CYBER Root CA" -# Serial: 85076849864375384482682434040119489222 -# MD5 Fingerprint: 0b:33:a0:97:52:95:d4:a9:fd:bb:db:6e:a3:55:5b:51 -# SHA1 Fingerprint: f6:b1:1c:1a:83:38:e9:7b:db:b3:a8:c8:33:24:e0:2d:9c:7f:26:66 -# SHA256 Fingerprint: 3f:63:bb:28:14:be:17:4e:c8:b6:43:9c:f0:8d:6d:56:f0:b7:c4:05:88:3a:56:48:a3:34:42:4d:6b:3e:c5:58 ------BEGIN CERTIFICATE----- -MIIFjTCCA3WgAwIBAgIQQAE0jMIAAAAAAAAAATzyxjANBgkqhkiG9w0BAQwFADBQ -MQswCQYDVQQGEwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290 -IENBMRswGQYDVQQDExJUV0NBIENZQkVSIFJvb3QgQ0EwHhcNMjIxMTIyMDY1NDI5 -WhcNNDcxMTIyMTU1OTU5WjBQMQswCQYDVQQGEwJUVzESMBAGA1UEChMJVEFJV0FO -LUNBMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJUV0NBIENZQkVSIFJvb3Qg -Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDG+Moe2Qkgfh1sTs6P -40czRJzHyWmqOlt47nDSkvgEs1JSHWdyKKHfi12VCv7qze33Kc7wb3+szT3vsxxF -avcokPFhV8UMxKNQXd7UtcsZyoC5dc4pztKFIuwCY8xEMCDa6pFbVuYdHNWdZsc/ -34bKS1PE2Y2yHer43CdTo0fhYcx9tbD47nORxc5zb87uEB8aBs/pJ2DFTxnk684i -JkXXYJndzk834H/nY62wuFm40AZoNWDTNq5xQwTxaWV4fPMf88oon1oglWa0zbfu -j3ikRRjpJi+NmykosaS3Om251Bw4ckVYsV7r8Cibt4LK/c/WMw+f+5eesRycnupf -Xtuq3VTpMCEobY5583WSjCb+3MX2w7DfRFlDo7YDKPYIMKoNM+HvnKkHIuNZW0CP -2oi3aQiotyMuRAlZN1vH4xfyIutuOVLF3lSnmMlLIJXcRolftBL5hSmO68gnFSDA -S9TMfAxsNAwmmyYxpjyn9tnQS6Jk/zuZQXLB4HCX8SS7K8R0IrGsayIyJNN4KsDA -oS/xUgXJP+92ZuJF2A09rZXIx4kmyA+upwMu+8Ff+iDhcK2wZSA3M2Cw1a/XDBzC -kHDXShi8fgGwsOsVHkQGzaRP6AzRwyAQ4VRlnrZR0Bp2a0JaWHY06rc3Ga4udfmW -5cFZ95RXKSWNOkyrTZpB0F8mAwIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYD -VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBSdhWEUfMFib5do5E83QOGt4A1WNzAd -BgNVHQ4EFgQUnYVhFHzBYm+XaORPN0DhreANVjcwDQYJKoZIhvcNAQEMBQADggIB -AGSPesRiDrWIzLjHhg6hShbNcAu3p4ULs3a2D6f/CIsLJc+o1IN1KriWiLb73y0t -tGlTITVX1olNc79pj3CjYcya2x6a4CD4bLubIp1dhDGaLIrdaqHXKGnK/nZVekZn -68xDiBaiA9a5F/gZbG0jAn/xX9AKKSM70aoK7akXJlQKTcKlTfjF/biBzysseKNn -TKkHmvPfXvt89YnNdJdhEGoHK4Fa0o635yDRIG4kqIQnoVesqlVYL9zZyvpoBJ7t -RCT5dEA7IzOrg1oYJkK2bVS1FmAwbLGg+LhBoF1JSdJlBTrq/p1hvIbZv97Tujqx -f36SNI7JAG7cmL3c7IAFrQI932XtCwP39xaEBDG6k5TY8hL4iuO/Qq+n1M0RFxbI -Qh0UqEL20kCGoE8jypZFVmAGzbdVAaYBlGX+bgUJurSkquLvWL69J1bY73NxW0Qz -8ppy6rBePm6pUlvscG21h483XjyMnM7k8M4MZ0HMzvaAq07MTFb1wWFZk7Q+ptq4 -NxKfKjLji7gh7MMrZQzvIt6IKTtM1/r+t+FHvpw+PoP7UV31aPcuIYXcv/Fa4nzX -xeSDwWrruoBa3lwtcHb4yOWHh8qgnaHlIhInD0Q9HWzq1MKLL295q39QpsQZp6F6 -t5b5wR9iWqJDB0BeJsas7a5wFsWqynKKTbDPAYsDP27X ------END CERTIFICATE----- - -# Issuer: CN=SecureSign Root CA14 O=Cybertrust Japan Co., Ltd. -# Subject: CN=SecureSign Root CA14 O=Cybertrust Japan Co., Ltd. -# Label: "SecureSign Root CA14" -# Serial: 575790784512929437950770173562378038616896959179 -# MD5 Fingerprint: 71:0d:72:fa:92:19:65:5e:89:04:ac:16:33:f0:bc:d5 -# SHA1 Fingerprint: dd:50:c0:f7:79:b3:64:2e:74:a2:b8:9d:9f:d3:40:dd:bb:f0:f2:4f -# SHA256 Fingerprint: 4b:00:9c:10:34:49:4f:9a:b5:6b:ba:3b:a1:d6:27:31:fc:4d:20:d8:95:5a:dc:ec:10:a9:25:60:72:61:e3:38 ------BEGIN CERTIFICATE----- -MIIFcjCCA1qgAwIBAgIUZNtaDCBO6Ncpd8hQJ6JaJ90t8sswDQYJKoZIhvcNAQEM -BQAwUTELMAkGA1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28u -LCBMdGQuMR0wGwYDVQQDExRTZWN1cmVTaWduIFJvb3QgQ0ExNDAeFw0yMDA0MDgw -NzA2MTlaFw00NTA0MDgwNzA2MTlaMFExCzAJBgNVBAYTAkpQMSMwIQYDVQQKExpD -eWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMUU2VjdXJlU2lnbiBS -b290IENBMTQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDF0nqh1oq/ -FjHQmNE6lPxauG4iwWL3pwon71D2LrGeaBLwbCRjOfHw3xDG3rdSINVSW0KZnvOg -vlIfX8xnbacuUKLBl422+JX1sLrcneC+y9/3OPJH9aaakpUqYllQC6KxNedlsmGy -6pJxaeQp8E+BgQQ8sqVb1MWoWWd7VRxJq3qdwudzTe/NCcLEVxLbAQ4jeQkHO6Lo -/IrPj8BGJJw4J+CDnRugv3gVEOuGTgpa/d/aLIJ+7sr2KeH6caH3iGicnPCNvg9J -kdjqOvn90Ghx2+m1K06Ckm9mH+Dw3EzsytHqunQG+bOEkJTRX45zGRBdAuVwpcAQ -0BB8b8VYSbSwbprafZX1zNoCr7gsfXmPvkPx+SgojQlD+Ajda8iLLCSxjVIHvXib -y8posqTdDEx5YMaZ0ZPxMBoH064iwurO8YQJzOAUbn8/ftKChazcqRZOhaBgy/ac -18izju3Gm5h1DVXoX+WViwKkrkMpKBGk5hIwAUt1ax5mnXkvpXYvHUC0bcl9eQjs -0Wq2XSqypWa9a4X0dFbD9ed1Uigspf9mR6XU/v6eVL9lfgHWMI+lNpyiUBzuOIAB -SMbHdPTGrMNASRZhdCyvjG817XsYAFs2PJxQDcqSMxDxJklt33UkN4Ii1+iW/RVL -ApY+B3KVfqs9TC7XyvDf4Fg/LS8EmjijAQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD -AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUBpOjCl4oaTeqYR3r6/wtbyPk -86AwDQYJKoZIhvcNAQEMBQADggIBAJaAcgkGfpzMkwQWu6A6jZJOtxEaCnFxEM0E -rX+lRVAQZk5KQaID2RFPeje5S+LGjzJmdSX7684/AykmjbgWHfYfM25I5uj4V7Ib -ed87hwriZLoAymzvftAj63iP/2SbNDefNWWipAA9EiOWWF3KY4fGoweITedpdopT -zfFP7ELyk+OZpDc8h7hi2/DsHzc/N19DzFGdtfCXwreFamgLRB7lUe6TzktuhsHS -DCRZNhqfLJGP4xjblJUK7ZGqDpncllPjYYPGFrojutzdfhrGe0K22VoF3Jpf1d+4 -2kd92jjbrDnVHmtsKheMYc2xbXIBw8MgAGJoFjHVdqqGuw6qnsb58Nn4DSEC5MUo -FlkRudlpcyqSeLiSV5sI8jrlL5WwWLdrIBRtFO8KvH7YVdiI2i/6GaX7i+B/OfVy -K4XELKzvGUWSTLNhB9xNH27SgRNcmvMSZ4PPmz+Ln52kuaiWA3rF7iDeM9ovnhp6 -dB7h7sxaOgTdsxoEqBRjrLdHEoOabPXm6RUVkRqEGQ6UROcSjiVbgGcZ3GOTEAtl -Lor6CZpO2oYofaphNdgOpygau1LgePhsumywbrmHXumZNTfxPWQrqaA0k89jL9WB -365jJ6UeTo3cKXhZ+PmhIIynJkBugnLNeLLIjzwec+fBH7/PzqUqm9tEZDKgu39c -JRNItX+S ------END CERTIFICATE----- - -# Issuer: CN=SecureSign Root CA15 O=Cybertrust Japan Co., Ltd. -# Subject: CN=SecureSign Root CA15 O=Cybertrust Japan Co., Ltd. -# Label: "SecureSign Root CA15" -# Serial: 126083514594751269499665114766174399806381178503 -# MD5 Fingerprint: 13:30:fc:c4:62:a6:a9:de:b5:c1:68:af:b5:d2:31:47 -# SHA1 Fingerprint: cb:ba:83:c8:c1:5a:5d:f1:f9:73:6f:ca:d7:ef:28:13:06:4a:07:7d -# SHA256 Fingerprint: e7:78:f0:f0:95:fe:84:37:29:cd:1a:00:82:17:9e:53:14:a9:c2:91:44:28:05:e1:fb:1d:8f:b6:b8:88:6c:3a ------BEGIN CERTIFICATE----- -MIICIzCCAamgAwIBAgIUFhXHw9hJp75pDIqI7fBw+d23PocwCgYIKoZIzj0EAwMw -UTELMAkGA1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBM -dGQuMR0wGwYDVQQDExRTZWN1cmVTaWduIFJvb3QgQ0ExNTAeFw0yMDA0MDgwODMy -NTZaFw00NTA0MDgwODMyNTZaMFExCzAJBgNVBAYTAkpQMSMwIQYDVQQKExpDeWJl -cnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMUU2VjdXJlU2lnbiBSb290 -IENBMTUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQLUHSNZDKZmbPSYAi4Io5GdCx4 -wCtELW1fHcmuS1Iggz24FG1Th2CeX2yF2wYUleDHKP+dX+Sq8bOLbe1PL0vJSpSR -ZHX+AezB2Ot6lHhWGENfa4HL9rzatAy2KZMIaY+jQjBAMA8GA1UdEwEB/wQFMAMB -Af8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTrQciu/NWeUUj1vYv0hyCTQSvT -9DAKBggqhkjOPQQDAwNoADBlAjEA2S6Jfl5OpBEHvVnCB96rMjhTKkZEBhd6zlHp -4P9mLQlO4E/0BdGF9jVg3PVys0Z9AjBEmEYagoUeYWmJSwdLZrWeqrqgHkHZAXQ6 -bkU6iYAZezKYVWOr62Nuk22rGwlgMU4= ------END CERTIFICATE----- - -# Issuer: CN=D-TRUST BR Root CA 2 2023 O=D-Trust GmbH -# Subject: CN=D-TRUST BR Root CA 2 2023 O=D-Trust GmbH -# Label: "D-TRUST BR Root CA 2 2023" -# Serial: 153168538924886464690566649552453098598 -# MD5 Fingerprint: e1:09:ed:d3:60:d4:56:1b:47:1f:b7:0c:5f:1b:5f:85 -# SHA1 Fingerprint: 2d:b0:70:ee:71:94:af:69:68:17:db:79:ce:58:9f:a0:6b:96:f7:87 -# SHA256 Fingerprint: 05:52:e6:f8:3f:df:65:e8:fa:96:70:e6:66:df:28:a4:e2:13:40:b5:10:cb:e5:25:66:f9:7c:4f:b9:4b:2b:d1 ------BEGIN CERTIFICATE----- -MIIFqTCCA5GgAwIBAgIQczswBEhb2U14LnNLyaHcZjANBgkqhkiG9w0BAQ0FADBI -MQswCQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlE -LVRSVVNUIEJSIFJvb3QgQ0EgMiAyMDIzMB4XDTIzMDUwOTA4NTYzMVoXDTM4MDUw -OTA4NTYzMFowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEi -MCAGA1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDIgMjAyMzCCAiIwDQYJKoZIhvcN -AQEBBQADggIPADCCAgoCggIBAK7/CVmRgApKaOYkP7in5Mg6CjoWzckjYaCTcfKr -i3OPoGdlYNJUa2NRb0kz4HIHE304zQaSBylSa053bATTlfrdTIzZXcFhfUvnKLNE -gXtRr90zsWh81k5M/itoucpmacTsXld/9w3HnDY25QdgrMBM6ghs7wZ8T1soegj8 -k12b9py0i4a6Ibn08OhZWiihNIQaJZG2tY/vsvmA+vk9PBFy2OMvhnbFeSzBqZCT -Rphny4NqoFAjpzv2gTng7fC5v2Xx2Mt6++9zA84A9H3X4F07ZrjcjrqDy4d2A/wl -2ecjbwb9Z/Pg/4S8R7+1FhhGaRTMBffb00msa8yr5LULQyReS2tNZ9/WtT5PeB+U -cSTq3nD88ZP+npNa5JRal1QMNXtfbO4AHyTsA7oC9Xb0n9Sa7YUsOCIvx9gvdhFP -/Wxc6PWOJ4d/GUohR5AdeY0cW/jPSoXk7bNbjb7EZChdQcRurDhaTyN0dKkSw/bS -uREVMweR2Ds3OmMwBtHFIjYoYiMQ4EbMl6zWK11kJNXuHA7e+whadSr2Y23OC0K+ -0bpwHJwh5Q8xaRfX/Aq03u2AnMuStIv13lmiWAmlY0cL4UEyNEHZmrHZqLAbWt4N -DfTisl01gLmB1IRpkQLLddCNxbU9CZEJjxShFHR5PtbJFR2kWVki3PaKRT08EtY+ -XTIvAgMBAAGjgY4wgYswDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUZ5Dw1t61 -GNVGKX5cq/ieCLxklRAwDgYDVR0PAQH/BAQDAgEGMEkGA1UdHwRCMEAwPqA8oDqG -OGh0dHA6Ly9jcmwuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3RfYnJfcm9vdF9jYV8y -XzIwMjMuY3JsMA0GCSqGSIb3DQEBDQUAA4ICAQA097N3U9swFrktpSHxQCF16+tI -FoE9c+CeJyrrd6kTpGoKWloUMz1oH4Guaf2Mn2VsNELZLdB/eBaxOqwjMa1ef67n -riv6uvw8l5VAk1/DLQOj7aRvU9f6QA4w9QAgLABMjDu0ox+2v5Eyq6+SmNMW5tTR -VFxDWy6u71cqqLRvpO8NVhTaIasgdp4D/Ca4nj8+AybmTNudX0KEPUUDAxxZiMrc -LmEkWqTqJwtzEr5SswrPMhfiHocaFpVIbVrg0M8JkiZmkdijYQ6qgYF/6FKC0ULn -4B0Y+qSFNueG4A3rvNTJ1jxD8V1Jbn6Bm2m1iWKPiFLY1/4nwSPFyysCu7Ff/vtD -hQNGvl3GyiEm/9cCnnRK3PgTFbGBVzbLZVzRHTF36SXDw7IyN9XxmAnkbWOACKsG -koHU6XCPpz+y7YaMgmo1yEJagtFSGkUPFaUA8JR7ZSdXOUPPfH/mvTWze/EZTN46 -ls/pdu4D58JDUjxqgejBWoC9EV2Ta/vH5mQ/u2kc6d0li690yVRAysuTEwrt+2aS -Ecr1wPrYg1UDfNPFIkZ1cGt5SAYqgpq/5usWDiJFAbzdNpQ0qTUmiteXue4Icr80 -knCDgKs4qllo3UCkGJCy89UDyibK79XH4I9TjvAA46jtn/mtd+ArY0+ew+43u3gJ -hJ65bvspmZDogNOfJA== ------END CERTIFICATE----- - -# Issuer: CN=TrustAsia TLS ECC Root CA O=TrustAsia Technologies, Inc. -# Subject: CN=TrustAsia TLS ECC Root CA O=TrustAsia Technologies, Inc. -# Label: "TrustAsia TLS ECC Root CA" -# Serial: 310892014698942880364840003424242768478804666567 -# MD5 Fingerprint: 09:48:04:77:d2:fc:65:93:71:66:b1:11:95:4f:06:8c -# SHA1 Fingerprint: b5:ec:39:f3:a1:66:37:ae:c3:05:94:57:e2:be:11:be:b7:a1:7f:36 -# SHA256 Fingerprint: c0:07:6b:9e:f0:53:1f:b1:a6:56:d6:7c:4e:be:97:cd:5d:ba:a4:1e:f4:45:98:ac:c2:48:98:78:c9:2d:87:11 ------BEGIN CERTIFICATE----- -MIICMTCCAbegAwIBAgIUNnThTXxlE8msg1UloD5Sfi9QaMcwCgYIKoZIzj0EAwMw -WDELMAkGA1UEBhMCQ04xJTAjBgNVBAoTHFRydXN0QXNpYSBUZWNobm9sb2dpZXMs -IEluYy4xIjAgBgNVBAMTGVRydXN0QXNpYSBUTFMgRUNDIFJvb3QgQ0EwHhcNMjQw -NTE1MDU0MTU2WhcNNDQwNTE1MDU0MTU1WjBYMQswCQYDVQQGEwJDTjElMCMGA1UE -ChMcVHJ1c3RBc2lhIFRlY2hub2xvZ2llcywgSW5jLjEiMCAGA1UEAxMZVHJ1c3RB -c2lhIFRMUyBFQ0MgUm9vdCBDQTB2MBAGByqGSM49AgEGBSuBBAAiA2IABLh/pVs/ -AT598IhtrimY4ZtcU5nb9wj/1WrgjstEpvDBjL1P1M7UiFPoXlfXTr4sP/MSpwDp -guMqWzJ8S5sUKZ74LYO1644xST0mYekdcouJtgq7nDM1D9rs3qlKH8kzsaNCMEAw -DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQULIVTu7FDzTLqnqOH/qKYqKaT6RAw -DgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2gAMGUCMFRH18MtYYZI9HlaVQ01 -L18N9mdsd0AaRuf4aFtOJx24mH1/k78ITcTaRTChD15KeAIxAKORh/IRM4PDwYqR -OkwrULG9IpRdNYlzg8WbGf60oenUoWa2AaU2+dhoYSi3dOGiMQ== ------END CERTIFICATE----- - -# Issuer: CN=TrustAsia TLS RSA Root CA O=TrustAsia Technologies, Inc. -# Subject: CN=TrustAsia TLS RSA Root CA O=TrustAsia Technologies, Inc. -# Label: "TrustAsia TLS RSA Root CA" -# Serial: 160405846464868906657516898462547310235378010780 -# MD5 Fingerprint: 3b:9e:c3:86:0f:34:3c:6b:c5:46:c4:8e:1d:e7:19:12 -# SHA1 Fingerprint: a5:46:50:c5:62:ea:95:9a:1a:a7:04:6f:17:58:c7:29:53:3d:03:fa -# SHA256 Fingerprint: 06:c0:8d:7d:af:d8:76:97:1e:b1:12:4f:e6:7f:84:7e:c0:c7:a1:58:d3:ea:53:cb:e9:40:e2:ea:97:91:f4:c3 ------BEGIN CERTIFICATE----- -MIIFgDCCA2igAwIBAgIUHBjYz+VTPyI1RlNUJDxsR9FcSpwwDQYJKoZIhvcNAQEM -BQAwWDELMAkGA1UEBhMCQ04xJTAjBgNVBAoTHFRydXN0QXNpYSBUZWNobm9sb2dp -ZXMsIEluYy4xIjAgBgNVBAMTGVRydXN0QXNpYSBUTFMgUlNBIFJvb3QgQ0EwHhcN -MjQwNTE1MDU0MTU3WhcNNDQwNTE1MDU0MTU2WjBYMQswCQYDVQQGEwJDTjElMCMG -A1UEChMcVHJ1c3RBc2lhIFRlY2hub2xvZ2llcywgSW5jLjEiMCAGA1UEAxMZVHJ1 -c3RBc2lhIFRMUyBSU0EgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC -AgoCggIBAMMWuBtqpERz5dZO9LnPWwvB0ZqB9WOwj0PBuwhaGnrhB3YmH49pVr7+ -NmDQDIPNlOrnxS1cLwUWAp4KqC/lYCZUlviYQB2srp10Zy9U+5RjmOMmSoPGlbYJ -Q1DNDX3eRA5gEk9bNb2/mThtfWza4mhzH/kxpRkQcwUqwzIZheo0qt1CHjCNP561 -HmHVb70AcnKtEj+qpklz8oYVlQwQX1Fkzv93uMltrOXVmPGZLmzjyUT5tUMnCE32 -ft5EebuyjBza00tsLtbDeLdM1aTk2tyKjg7/D8OmYCYozza/+lcK7Fs/6TAWe8Tb -xNRkoDD75f0dcZLdKY9BWN4ArTr9PXwaqLEX8E40eFgl1oUh63kd0Nyrz2I8sMeX -i9bQn9P+PN7F4/w6g3CEIR0JwqH8uyghZVNgepBtljhb//HXeltt08lwSUq6HTrQ -UNoyIBnkiz/r1RYmNzz7dZ6wB3C4FGB33PYPXFIKvF1tjVEK2sUYyJtt3LCDs3+j -TnhMmCWr8n4uIF6CFabW2I+s5c0yhsj55NqJ4js+k8UTav/H9xj8Z7XvGCxUq0DT -bE3txci3OE9kxJRMT6DNrqXGJyV1J23G2pyOsAWZ1SgRxSHUuPzHlqtKZFlhaxP8 -S8ySpg+kUb8OWJDZgoM5pl+z+m6Ss80zDoWo8SnTq1mt1tve1CuBAgMBAAGjQjBA -MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFLgHkXlcBvRG/XtZylomkadFK/hT -MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQwFAAOCAgEAIZtqBSBdGBanEqT3 -Rz/NyjuujsCCztxIJXgXbODgcMTWltnZ9r96nBO7U5WS/8+S4PPFJzVXqDuiGev4 -iqME3mmL5Dw8veWv0BIb5Ylrc5tvJQJLkIKvQMKtuppgJFqBTQUYo+IzeXoLH5Pt -7DlK9RME7I10nYEKqG/odv6LTytpEoYKNDbdgptvT+Bz3Ul/KD7JO6NXBNiT2Twp -2xIQaOHEibgGIOcberyxk2GaGUARtWqFVwHxtlotJnMnlvm5P1vQiJ3koP26TpUJ -g3933FEFlJ0gcXax7PqJtZwuhfG5WyRasQmr2soaB82G39tp27RIGAAtvKLEiUUj -pQ7hRGU+isFqMB3iYPg6qocJQrmBktwliJiJ8Xw18WLK7nn4GS/+X/jbh87qqA8M -pugLoDzga5SYnH+tBuYc6kIQX+ImFTw3OffXvO645e8D7r0i+yiGNFjEWn9hongP -XvPKnbwbPKfILfanIhHKA9jnZwqKDss1jjQ52MjqjZ9k4DewbNfFj8GQYSbbJIwe -SsCI3zWQzj8C9GRh3sfIB5XeMhg6j6JCQCTl1jNdfK7vsU1P1FeQNWrcrgSXSYk0 -ly4wBOeY99sLAZDBHwo/+ML+TvrbmnNzFrwFuHnYWa8G5z9nODmxfKuU4CkUpijy -323imttUQ/hHWKNddBWcwauwxzQ= ------END CERTIFICATE----- - -# Issuer: CN=D-TRUST EV Root CA 2 2023 O=D-Trust GmbH -# Subject: CN=D-TRUST EV Root CA 2 2023 O=D-Trust GmbH -# Label: "D-TRUST EV Root CA 2 2023" -# Serial: 139766439402180512324132425437959641711 -# MD5 Fingerprint: 96:b4:78:09:f0:09:cb:77:eb:bb:1b:4d:6f:36:bc:b6 -# SHA1 Fingerprint: a5:5b:d8:47:6c:8f:19:f7:4c:f4:6d:6b:b6:c2:79:82:22:df:54:8b -# SHA256 Fingerprint: 8e:82:21:b2:e7:d4:00:78:36:a1:67:2f:0d:cc:29:9c:33:bc:07:d3:16:f1:32:fa:1a:20:6d:58:71:50:f1:ce ------BEGIN CERTIFICATE----- -MIIFqTCCA5GgAwIBAgIQaSYJfoBLTKCnjHhiU19abzANBgkqhkiG9w0BAQ0FADBI -MQswCQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlE -LVRSVVNUIEVWIFJvb3QgQ0EgMiAyMDIzMB4XDTIzMDUwOTA5MTAzM1oXDTM4MDUw -OTA5MTAzMlowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEi -MCAGA1UEAxMZRC1UUlVTVCBFViBSb290IENBIDIgMjAyMzCCAiIwDQYJKoZIhvcN -AQEBBQADggIPADCCAgoCggIBANiOo4mAC7JXUtypU0w3uX9jFxPvp1sjW2l1sJkK -F8GLxNuo4MwxusLyzV3pt/gdr2rElYfXR8mV2IIEUD2BCP/kPbOx1sWy/YgJ25yE -7CUXFId/MHibaljJtnMoPDT3mfd/06b4HEV8rSyMlD/YZxBTfiLNTiVR8CUkNRFe -EMbsh2aJgWi6zCudR3Mfvc2RpHJqnKIbGKBv7FD0fUDCqDDPvXPIEysQEx6Lmqg6 -lHPTGGkKSv/BAQP/eX+1SH977ugpbzZMlWGG2Pmic4ruri+W7mjNPU0oQvlFKzIb -RlUWaqZLKfm7lVa/Rh3sHZMdwGWyH6FDrlaeoLGPaxK3YG14C8qKXO0elg6DpkiV -jTujIcSuWMYAsoS0I6SWhjW42J7YrDRJmGOVxcttSEfi8i4YHtAxq9107PncjLgc -jmgjutDzUNzPZY9zOjLHfP7KgiJPvo5iR2blzYfi6NUPGJ/lBHJLRjwQ8kTCZFZx -TnXonMkmdMV9WdEKWw9t/p51HBjGGjp82A0EzM23RWV6sY+4roRIPrN6TagD4uJ+ -ARZZaBhDM7DS3LAaQzXupdqpRlyuhoFBAUp0JuyfBr/CBTdkdXgpaP3F9ev+R/nk -hbDhezGdpn9yo7nELC7MmVcOIQxFAZRl62UJxmMiCzNJkkg8/M3OsD6Onov4/knF -NXJHAgMBAAGjgY4wgYswDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUqvyREBuH -kV8Wub9PS5FeAByxMoAwDgYDVR0PAQH/BAQDAgEGMEkGA1UdHwRCMEAwPqA8oDqG -OGh0dHA6Ly9jcmwuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3RfZXZfcm9vdF9jYV8y -XzIwMjMuY3JsMA0GCSqGSIb3DQEBDQUAA4ICAQCTy6UfmRHsmg1fLBWTxj++EI14 -QvBukEdHjqOSMo1wj/Zbjb6JzkcBahsgIIlbyIIQbODnmaprxiqgYzWRaoUlrRc4 -pZt+UPJ26oUFKidBK7GB0aL2QHWpDsvxVUjY7NHss+jOFKE17MJeNRqrphYBBo7q -3C+jisosketSjl8MmxfPy3MHGcRqwnNU73xDUmPBEcrCRbH0O1P1aa4846XerOhU -t7KR/aypH/KH5BfGSah82ApB9PI+53c0BFLd6IHyTS9URZ0V4U/M5d40VxDJI3IX -cI1QcB9WbMy5/zpaT2N6w25lBx2Eof+pDGOJbbJAiDnXH3dotfyc1dZnaVuodNv8 -ifYbMvekJKZ2t0dT741Jj6m2g1qllpBFYfXeA08mD6iL8AOWsKwV0HFaanuU5nCT -2vFp4LJiTZ6P/4mdm13NRemUAiKN4DV/6PEEeXFsVIP4M7kFMhtYVRFP0OUnR3Hs -7dpn1mKmS00PaaLJvOwiS5THaJQXfuKOKD62xur1NGyfN4gHONuGcfrNlUhDbqNP -gofXNJhuS5N5YHVpD/Aa1VP6IQzCP+k/HxiMkl14p3ZnGbuy6n/pcAlWVqOwDAst -Nl7F6cTVg8uGF5csbBNvh1qvSaYd2804BC5f4ko1Di1L+KIkBI3Y4WNeApI02phh -XBxvWHZks/wCuPWdCg== ------END CERTIFICATE----- - -# Issuer: CN=SwissSign RSA TLS Root CA 2022 - 1 O=SwissSign AG -# Subject: CN=SwissSign RSA TLS Root CA 2022 - 1 O=SwissSign AG -# Label: "SwissSign RSA TLS Root CA 2022 - 1" -# Serial: 388078645722908516278762308316089881486363258315 -# MD5 Fingerprint: 16:2e:e4:19:76:81:85:ba:8e:91:58:f1:15:ef:72:39 -# SHA1 Fingerprint: 81:34:0a:be:4c:cd:ce:cc:e7:7d:cc:8a:d4:57:e2:45:a0:77:5d:ce -# SHA256 Fingerprint: 19:31:44:f4:31:e0:fd:db:74:07:17:d4:de:92:6a:57:11:33:88:4b:43:60:d3:0e:27:29:13:cb:e6:60:ce:41 ------BEGIN CERTIFICATE----- -MIIFkzCCA3ugAwIBAgIUQ/oMX04bgBhE79G0TzUfRPSA7cswDQYJKoZIhvcNAQEL -BQAwUTELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzErMCkGA1UE -AxMiU3dpc3NTaWduIFJTQSBUTFMgUm9vdCBDQSAyMDIyIC0gMTAeFw0yMjA2MDgx -MTA4MjJaFw00NzA2MDgxMTA4MjJaMFExCzAJBgNVBAYTAkNIMRUwEwYDVQQKEwxT -d2lzc1NpZ24gQUcxKzApBgNVBAMTIlN3aXNzU2lnbiBSU0EgVExTIFJvb3QgQ0Eg -MjAyMiAtIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDLKmjiC8NX -vDVjvHClO/OMPE5Xlm7DTjak9gLKHqquuN6orx122ro10JFwB9+zBvKK8i5VUXu7 -LCTLf5ImgKO0lPaCoaTo+nUdWfMHamFk4saMla+ju45vVs9xzF6BYQ1t8qsCLqSX -5XH8irCRIFucdFJtrhUnWXjyCcplDn/L9Ovn3KlMd/YrFgSVrpxxpT8q2kFC5zyE -EPThPYxr4iuRR1VPuFa+Rd4iUU1OKNlfGUEGjw5NBuBwQCMBauTLE5tzrE0USJIt -/m2n+IdreXXhvhCxqohAWVTXz8TQm0SzOGlkjIHRI36qOTw7D59Ke4LKa2/KIj4x -0LDQKhySio/YGZxH5D4MucLNvkEM+KRHBdvBFzA4OmnczcNpI/2aDwLOEGrOyvi5 -KaM2iYauC8BPY7kGWUleDsFpswrzd34unYyzJ5jSmY0lpx+Gs6ZUcDj8fV3oT4MM -0ZPlEuRU2j7yrTrePjxF8CgPBrnh25d7mUWe3f6VWQQvdT/TromZhqwUtKiE+shd -OxtYk8EXlFXIC+OCeYSf8wCENO7cMdWP8vpPlkwGqnj73mSiI80fPsWMvDdUDrta -clXvyFu1cvh43zcgTFeRc5JzrBh3Q4IgaezprClG5QtO+DdziZaKHG29777YtvTK -wP1H8K4LWCDFyB02rpeNUIMmJCn3nTsPBQIDAQABo2MwYTAPBgNVHRMBAf8EBTAD -AQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBRvjmKLk0Ow4UD2p8P98Q+4 -DxU4pTAdBgNVHQ4EFgQUb45ii5NDsOFA9qfD/fEPuA8VOKUwDQYJKoZIhvcNAQEL -BQADggIBAKwsKUF9+lz1GpUYvyypiqkkVHX1uECry6gkUSsYP2OprphWKwVDIqO3 -10aewCoSPY6WlkDfDDOLazeROpW7OSltwAJsipQLBwJNGD77+3v1dj2b9l4wBlgz -Hqp41eZUBDqyggmNzhYzWUUo8aWjlw5DI/0LIICQ/+Mmz7hkkeUFjxOgdg3XNwwQ -iJb0Pr6VvfHDffCjw3lHC1ySFWPtUnWK50Zpy1FVCypM9fJkT6lc/2cyjlUtMoIc -gC9qkfjLvH4YoiaoLqNTKIftV+Vlek4ASltOU8liNr3CjlvrzG4ngRhZi0Rjn9UM -ZfQpZX+RLOV/fuiJz48gy20HQhFRJjKKLjpHE7iNvUcNCfAWpO2Whi4Z2L6MOuhF -LhG6rlrnub+xzI/goP+4s9GFe3lmozm1O2bYQL7Pt2eLSMkZJVX8vY3PXtpOpvJp -zv1/THfQwUY1mFwjmwJFQ5Ra3bxHrSL+ul4vkSkphnsh3m5kt8sNjzdbowhq6/Td -Ao9QAwKxuDdollDruF/UKIqlIgyKhPBZLtU30WHlQnNYKoH3dtvi4k0NX/a3vgW0 -rk4N3hY9A4GzJl5LuEsAz/+MF7psYC0nhzck5npgL7XTgwSqT0N1osGDsieYK7EO -gLrAhV5Cud+xYJHT6xh+cHiudoO+cVrQkOPKwRYlZ0rwtnu64ZzZ ------END CERTIFICATE----- - -# Issuer: CN=OISTE Server Root ECC G1 O=OISTE Foundation -# Subject: CN=OISTE Server Root ECC G1 O=OISTE Foundation -# Label: "OISTE Server Root ECC G1" -# Serial: 47819833811561661340092227008453318557 -# MD5 Fingerprint: 42:a7:d2:35:ae:02:92:db:19:76:08:de:2f:05:b4:d4 -# SHA1 Fingerprint: 3b:f6:8b:09:ae:2a:92:7b:ba:e3:8d:3f:11:95:d9:e6:44:0c:45:e2 -# SHA256 Fingerprint: ee:c9:97:c0:c3:0f:21:6f:7e:3b:8b:30:7d:2b:ae:42:41:2d:75:3f:c8:21:9d:af:d1:52:0b:25:72:85:0f:49 ------BEGIN CERTIFICATE----- -MIICNTCCAbqgAwIBAgIQI/nD1jWvjyhLH/BU6n6XnTAKBggqhkjOPQQDAzBLMQsw -CQYDVQQGEwJDSDEZMBcGA1UECgwQT0lTVEUgRm91bmRhdGlvbjEhMB8GA1UEAwwY -T0lTVEUgU2VydmVyIFJvb3QgRUNDIEcxMB4XDTIzMDUzMTE0NDIyOFoXDTQ4MDUy -NDE0NDIyN1owSzELMAkGA1UEBhMCQ0gxGTAXBgNVBAoMEE9JU1RFIEZvdW5kYXRp -b24xITAfBgNVBAMMGE9JU1RFIFNlcnZlciBSb290IEVDQyBHMTB2MBAGByqGSM49 -AgEGBSuBBAAiA2IABBcv+hK8rBjzCvRE1nZCnrPoH7d5qVi2+GXROiFPqOujvqQy -cvO2Ackr/XeFblPdreqqLiWStukhEaivtUwL85Zgmjvn6hp4LrQ95SjeHIC6XG4N -2xml4z+cKrhAS93mT6NjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBQ3 -TYhlz/w9itWj8UnATgwQb0K0nDAdBgNVHQ4EFgQUN02IZc/8PYrVo/FJwE4MEG9C -tJwwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2kAMGYCMQCpKjAd0MKfkFFR -QD6VVCHNFmb3U2wIFjnQEnx/Yxvf4zgAOdktUyBFCxxgZzFDJe0CMQCSia7pXGKD -YmH5LVerVrkR3SW+ak5KGoJr3M/TvEqzPNcum9v4KGm8ay3sMaE641c= ------END CERTIFICATE----- - -# Issuer: CN=OISTE Server Root RSA G1 O=OISTE Foundation -# Subject: CN=OISTE Server Root RSA G1 O=OISTE Foundation -# Label: "OISTE Server Root RSA G1" -# Serial: 113845518112613905024960613408179309848 -# MD5 Fingerprint: 23:a7:9e:d4:70:b8:b9:14:57:41:8a:7e:44:59:e2:68 -# SHA1 Fingerprint: f7:00:34:25:94:88:68:31:e4:34:87:3f:70:fe:86:b3:86:9f:f0:6e -# SHA256 Fingerprint: 9a:e3:62:32:a5:18:9f:fd:db:35:3d:fd:26:52:0c:01:53:95:d2:27:77:da:c5:9d:b5:7b:98:c0:89:a6:51:e6 ------BEGIN CERTIFICATE----- -MIIFgzCCA2ugAwIBAgIQVaXZZ5Qoxu0M+ifdWwFNGDANBgkqhkiG9w0BAQwFADBL -MQswCQYDVQQGEwJDSDEZMBcGA1UECgwQT0lTVEUgRm91bmRhdGlvbjEhMB8GA1UE -AwwYT0lTVEUgU2VydmVyIFJvb3QgUlNBIEcxMB4XDTIzMDUzMTE0MzcxNloXDTQ4 -MDUyNDE0MzcxNVowSzELMAkGA1UEBhMCQ0gxGTAXBgNVBAoMEE9JU1RFIEZvdW5k -YXRpb24xITAfBgNVBAMMGE9JU1RFIFNlcnZlciBSb290IFJTQSBHMTCCAiIwDQYJ -KoZIhvcNAQEBBQADggIPADCCAgoCggIBAKqu9KuCz/vlNwvn1ZatkOhLKdxVYOPM -vLO8LZK55KN68YG0nnJyQ98/qwsmtO57Gmn7KNByXEptaZnwYx4M0rH/1ow00O7b -rEi56rAUjtgHqSSY3ekJvqgiG1k50SeH3BzN+Puz6+mTeO0Pzjd8JnduodgsIUzk -ik/HEzxux9UTl7Ko2yRpg1bTacuCErudG/L4NPKYKyqOBGf244ehHa1uzjZ0Dl4z -O8vbUZeUapU8zhhabkvG/AePLhq5SvdkNCncpo1Q4Y2LS+VIG24ugBA/5J8bZT8R -tOpXaZ+0AOuFJJkk9SGdl6r7NH8CaxWQrbueWhl/pIzY+m0o/DjH40ytas7ZTpOS -jswMZ78LS5bOZmdTaMsXEY5Z96ycG7mOaES3GK/m5Q9l3JUJsJMStR8+lKXHiHUh -sd4JJCpM4rzsTGdHwimIuQq6+cF0zowYJmXa92/GjHtoXAvuY8BeS/FOzJ8vD+Ho -mnqT8eDI278n5mUpezbgMxVz8p1rhAhoKzYHKyfMeNhqhw5HdPSqoBNdZH702xSu -+zrkL8Fl47l6QGzwBrd7KJvX4V84c5Ss2XCTLdyEr0YconosP4EmQufU2MVshGYR -i3drVByjtdgQ8K4p92cIiBdcuJd5z+orKu5YM+Vt6SmqZQENghPsJQtdLEByFSnT -kCz3GkPVavBpAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU -8snBDw1jALvsRQ5KH7WxszbNDo0wHQYDVR0OBBYEFPLJwQ8NYwC77EUOSh+1sbM2 -zQ6NMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQwFAAOCAgEANGd5sjrG5T33 -I3K5Ce+SrScfoE4KsvXaFwyihdJ+klH9FWXXXGtkFu6KRcoMQzZENdl//nk6HOjG -5D1rd9QhEOP28yBOqb6J8xycqd+8MDoX0TJD0KqKchxRKEzdNsjkLWd9kYccnbz8 -qyiWXmFcuCIzGEgWUOrKL+mlSdx/PKQZvDatkuK59EvV6wit53j+F8Bdh3foZ3dP -AGav9LEDOr4SfEE15fSmG0eLy3n31r8Xbk5l8PjaV8GUgeV6Vg27Rn9vkf195hfk -gSe7BYhW3SCl95gtkRlpMV+bMPKZrXJAlszYd2abtNUOshD+FKrDgHGdPY3ofRRs -YWSGRqbXVMW215AWRqWFyp464+YTFrYVI8ypKVL9AMb2kI5Wj4kI3Zaq5tNqqYY1 -9tVFeEJKRvwDyF7YZvZFZSS0vod7VSCd9521Kvy5YhnLbDuv0204bKt7ph6N/Ome -/msVuduCmsuY33OhkKCgxeDoAaijFJzIwZqsFVAzje18KotzlUBDJvyBpCpfOZC3 -J8tRd/iWkx7P8nd9H0aTolkelUTFLXVksNb54Dxp6gS1HAviRkRNQzuXSXERvSS2 -wq1yVAb+axj5d9spLFKebXd7Yv0PTY6YMjAwcRLWJTXjn/hvnLXrahut6hDTlhZy -BiElxky8j3C7DOReIoMt0r7+hVu05L0= ------END CERTIFICATE----- - -# Issuer: CN=e-Szigno TLS Root CA 2023 O=Microsec Ltd. -# Subject: CN=e-Szigno TLS Root CA 2023 O=Microsec Ltd. -# Label: "e-Szigno TLS Root CA 2023" -# Serial: 71934828665710877219916191754 -# MD5 Fingerprint: 6a:e9:99:74:a5:da:5e:f1:d9:2e:f2:c8:d1:86:8b:71 -# SHA1 Fingerprint: 6f:9a:d5:d5:df:e8:2c:eb:be:37:07:ee:4f:4f:52:58:29:41:d1:fe -# SHA256 Fingerprint: b4:91:41:50:2d:00:66:3d:74:0f:2e:7e:c3:40:c5:28:00:96:26:66:12:1a:36:d0:9c:f7:dd:2b:90:38:4f:b4 ------BEGIN CERTIFICATE----- -MIICzzCCAjGgAwIBAgINAOhvGHvWOWuYSkmYCjAKBggqhkjOPQQDBDB1MQswCQYD -VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0 -ZC4xFzAVBgNVBGEMDlZBVEhVLTIzNTg0NDk3MSIwIAYDVQQDDBllLVN6aWdubyBU -TFMgUm9vdCBDQSAyMDIzMB4XDTIzMDcxNzE0MDAwMFoXDTM4MDcxNzE0MDAwMFow -dTELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRYwFAYDVQQKDA1NaWNy -b3NlYyBMdGQuMRcwFQYDVQRhDA5WQVRIVS0yMzU4NDQ5NzEiMCAGA1UEAwwZZS1T -emlnbm8gVExTIFJvb3QgQ0EgMjAyMzCBmzAQBgcqhkjOPQIBBgUrgQQAIwOBhgAE -AGgP36J8PKp0iGEKjcJMpQEiFNT3YHdCnAo4YKGMZz6zY+n6kbCLS+Y53wLCMAFS -AL/fjO1ZrTJlqwlZULUZwmgcAOAFX9pQJhzDrAQixTpN7+lXWDajwRlTEArRzT/v -SzUaQ49CE0y5LBqcvjC2xN7cS53kpDzLLtmt3999Cd8ukv+ho2MwYTAPBgNVHRMB -Af8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUWYQCYlpGePVd3I8K -ECgj3NXW+0UwHwYDVR0jBBgwFoAUWYQCYlpGePVd3I8KECgj3NXW+0UwCgYIKoZI -zj0EAwQDgYsAMIGHAkIBLdqu9S54tma4n7Zwf2Z0z+yOfP7AAXmazlIC58PRDHpt -y7Ve7hekm9sEdu4pKeiv+62sUvTXK9Z3hBC9xdIoaDQCQTV2WnXzkoYI9bIeCvZl -C9p2x1L/Cx6AcCIwwzPbGO2E14vs7dOoY4G1VnxHx1YwlGhza9IuqbnZLBwpvQy6 -uWWL ------END CERTIFICATE----- diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/certifi/core.py b/venv/lib/python3.11/site-packages/pip/_vendor/certifi/core.py deleted file mode 100755 index 2f2f7e0..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/certifi/core.py +++ /dev/null @@ -1,83 +0,0 @@ -""" -certifi.py -~~~~~~~~~~ - -This module returns the installation location of cacert.pem or its contents. -""" -import sys -import atexit - -def exit_cacert_ctx() -> None: - _CACERT_CTX.__exit__(None, None, None) # type: ignore[union-attr] - - -if sys.version_info >= (3, 11): - - from importlib.resources import as_file, files - - _CACERT_CTX = None - _CACERT_PATH = None - - def where() -> str: - # This is slightly terrible, but we want to delay extracting the file - # in cases where we're inside of a zipimport situation until someone - # actually calls where(), but we don't want to re-extract the file - # on every call of where(), so we'll do it once then store it in a - # global variable. - global _CACERT_CTX - global _CACERT_PATH - if _CACERT_PATH is None: - # This is slightly janky, the importlib.resources API wants you to - # manage the cleanup of this file, so it doesn't actually return a - # path, it returns a context manager that will give you the path - # when you enter it and will do any cleanup when you leave it. In - # the common case of not needing a temporary file, it will just - # return the file system location and the __exit__() is a no-op. - # - # We also have to hold onto the actual context manager, because - # it will do the cleanup whenever it gets garbage collected, so - # we will also store that at the global level as well. - _CACERT_CTX = as_file(files("pip._vendor.certifi").joinpath("cacert.pem")) - _CACERT_PATH = str(_CACERT_CTX.__enter__()) - atexit.register(exit_cacert_ctx) - - return _CACERT_PATH - - def contents() -> str: - return files("pip._vendor.certifi").joinpath("cacert.pem").read_text(encoding="ascii") - -else: - - from importlib.resources import path as get_path, read_text - - _CACERT_CTX = None - _CACERT_PATH = None - - def where() -> str: - # This is slightly terrible, but we want to delay extracting the - # file in cases where we're inside of a zipimport situation until - # someone actually calls where(), but we don't want to re-extract - # the file on every call of where(), so we'll do it once then store - # it in a global variable. - global _CACERT_CTX - global _CACERT_PATH - if _CACERT_PATH is None: - # This is slightly janky, the importlib.resources API wants you - # to manage the cleanup of this file, so it doesn't actually - # return a path, it returns a context manager that will give - # you the path when you enter it and will do any cleanup when - # you leave it. In the common case of not needing a temporary - # file, it will just return the file system location and the - # __exit__() is a no-op. - # - # We also have to hold onto the actual context manager, because - # it will do the cleanup whenever it gets garbage collected, so - # we will also store that at the global level as well. - _CACERT_CTX = get_path("pip._vendor.certifi", "cacert.pem") - _CACERT_PATH = str(_CACERT_CTX.__enter__()) - atexit.register(exit_cacert_ctx) - - return _CACERT_PATH - - def contents() -> str: - return read_text("pip._vendor.certifi", "cacert.pem", encoding="ascii") diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/certifi/py.typed b/venv/lib/python3.11/site-packages/pip/_vendor/certifi/py.typed deleted file mode 100755 index e69de29..0000000 diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/distlib/LICENSE.txt b/venv/lib/python3.11/site-packages/pip/_vendor/distlib/LICENSE.txt deleted file mode 100755 index c31ac56..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/distlib/LICENSE.txt +++ /dev/null @@ -1,284 +0,0 @@ -A. HISTORY OF THE SOFTWARE -========================== - -Python was created in the early 1990s by Guido van Rossum at Stichting -Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands -as a successor of a language called ABC. Guido remains Python's -principal author, although it includes many contributions from others. - -In 1995, Guido continued his work on Python at the Corporation for -National Research Initiatives (CNRI, see http://www.cnri.reston.va.us) -in Reston, Virginia where he released several versions of the -software. - -In May 2000, Guido and the Python core development team moved to -BeOpen.com to form the BeOpen PythonLabs team. In October of the same -year, the PythonLabs team moved to Digital Creations (now Zope -Corporation, see http://www.zope.com). In 2001, the Python Software -Foundation (PSF, see http://www.python.org/psf/) was formed, a -non-profit organization created specifically to own Python-related -Intellectual Property. Zope Corporation is a sponsoring member of -the PSF. - -All Python releases are Open Source (see http://www.opensource.org for -the Open Source Definition). Historically, most, but not all, Python -releases have also been GPL-compatible; the table below summarizes -the various releases. - - Release Derived Year Owner GPL- - from compatible? (1) - - 0.9.0 thru 1.2 1991-1995 CWI yes - 1.3 thru 1.5.2 1.2 1995-1999 CNRI yes - 1.6 1.5.2 2000 CNRI no - 2.0 1.6 2000 BeOpen.com no - 1.6.1 1.6 2001 CNRI yes (2) - 2.1 2.0+1.6.1 2001 PSF no - 2.0.1 2.0+1.6.1 2001 PSF yes - 2.1.1 2.1+2.0.1 2001 PSF yes - 2.2 2.1.1 2001 PSF yes - 2.1.2 2.1.1 2002 PSF yes - 2.1.3 2.1.2 2002 PSF yes - 2.2.1 2.2 2002 PSF yes - 2.2.2 2.2.1 2002 PSF yes - 2.2.3 2.2.2 2003 PSF yes - 2.3 2.2.2 2002-2003 PSF yes - 2.3.1 2.3 2002-2003 PSF yes - 2.3.2 2.3.1 2002-2003 PSF yes - 2.3.3 2.3.2 2002-2003 PSF yes - 2.3.4 2.3.3 2004 PSF yes - 2.3.5 2.3.4 2005 PSF yes - 2.4 2.3 2004 PSF yes - 2.4.1 2.4 2005 PSF yes - 2.4.2 2.4.1 2005 PSF yes - 2.4.3 2.4.2 2006 PSF yes - 2.4.4 2.4.3 2006 PSF yes - 2.5 2.4 2006 PSF yes - 2.5.1 2.5 2007 PSF yes - 2.5.2 2.5.1 2008 PSF yes - 2.5.3 2.5.2 2008 PSF yes - 2.6 2.5 2008 PSF yes - 2.6.1 2.6 2008 PSF yes - 2.6.2 2.6.1 2009 PSF yes - 2.6.3 2.6.2 2009 PSF yes - 2.6.4 2.6.3 2009 PSF yes - 2.6.5 2.6.4 2010 PSF yes - 3.0 2.6 2008 PSF yes - 3.0.1 3.0 2009 PSF yes - 3.1 3.0.1 2009 PSF yes - 3.1.1 3.1 2009 PSF yes - 3.1.2 3.1 2010 PSF yes - 3.2 3.1 2010 PSF yes - -Footnotes: - -(1) GPL-compatible doesn't mean that we're distributing Python under - the GPL. All Python licenses, unlike the GPL, let you distribute - a modified version without making your changes open source. The - GPL-compatible licenses make it possible to combine Python with - other software that is released under the GPL; the others don't. - -(2) According to Richard Stallman, 1.6.1 is not GPL-compatible, - because its license has a choice of law clause. According to - CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1 - is "not incompatible" with the GPL. - -Thanks to the many outside volunteers who have worked under Guido's -direction to make these releases possible. - - -B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON -=============================================================== - -PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 --------------------------------------------- - -1. This LICENSE AGREEMENT is between the Python Software Foundation -("PSF"), and the Individual or Organization ("Licensee") accessing and -otherwise using this software ("Python") in source or binary form and -its associated documentation. - -2. Subject to the terms and conditions of this License Agreement, PSF hereby -grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, -analyze, test, perform and/or display publicly, prepare derivative works, -distribute, and otherwise use Python alone or in any derivative version, -provided, however, that PSF's License Agreement and PSF's notice of copyright, -i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 -Python Software Foundation; All Rights Reserved" are retained in Python alone or -in any derivative version prepared by Licensee. - -3. In the event Licensee prepares a derivative work that is based on -or incorporates Python or any part thereof, and wants to make -the derivative work available to others as provided herein, then -Licensee hereby agrees to include in any such work a brief summary of -the changes made to Python. - -4. PSF is making Python available to Licensee on an "AS IS" -basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR -IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND -DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS -FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT -INFRINGE ANY THIRD PARTY RIGHTS. - -5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON -FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS -A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, -OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. - -6. This License Agreement will automatically terminate upon a material -breach of its terms and conditions. - -7. Nothing in this License Agreement shall be deemed to create any -relationship of agency, partnership, or joint venture between PSF and -Licensee. This License Agreement does not grant permission to use PSF -trademarks or trade name in a trademark sense to endorse or promote -products or services of Licensee, or any third party. - -8. By copying, installing or otherwise using Python, Licensee -agrees to be bound by the terms and conditions of this License -Agreement. - - -BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0 -------------------------------------------- - -BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1 - -1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an -office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the -Individual or Organization ("Licensee") accessing and otherwise using -this software in source or binary form and its associated -documentation ("the Software"). - -2. Subject to the terms and conditions of this BeOpen Python License -Agreement, BeOpen hereby grants Licensee a non-exclusive, -royalty-free, world-wide license to reproduce, analyze, test, perform -and/or display publicly, prepare derivative works, distribute, and -otherwise use the Software alone or in any derivative version, -provided, however, that the BeOpen Python License is retained in the -Software, alone or in any derivative version prepared by Licensee. - -3. BeOpen is making the Software available to Licensee on an "AS IS" -basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR -IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND -DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS -FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT -INFRINGE ANY THIRD PARTY RIGHTS. - -4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE -SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS -AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY -DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. - -5. This License Agreement will automatically terminate upon a material -breach of its terms and conditions. - -6. This License Agreement shall be governed by and interpreted in all -respects by the law of the State of California, excluding conflict of -law provisions. Nothing in this License Agreement shall be deemed to -create any relationship of agency, partnership, or joint venture -between BeOpen and Licensee. This License Agreement does not grant -permission to use BeOpen trademarks or trade names in a trademark -sense to endorse or promote products or services of Licensee, or any -third party. As an exception, the "BeOpen Python" logos available at -http://www.pythonlabs.com/logos.html may be used according to the -permissions granted on that web page. - -7. By copying, installing or otherwise using the software, Licensee -agrees to be bound by the terms and conditions of this License -Agreement. - - -CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1 ---------------------------------------- - -1. This LICENSE AGREEMENT is between the Corporation for National -Research Initiatives, having an office at 1895 Preston White Drive, -Reston, VA 20191 ("CNRI"), and the Individual or Organization -("Licensee") accessing and otherwise using Python 1.6.1 software in -source or binary form and its associated documentation. - -2. Subject to the terms and conditions of this License Agreement, CNRI -hereby grants Licensee a nonexclusive, royalty-free, world-wide -license to reproduce, analyze, test, perform and/or display publicly, -prepare derivative works, distribute, and otherwise use Python 1.6.1 -alone or in any derivative version, provided, however, that CNRI's -License Agreement and CNRI's notice of copyright, i.e., "Copyright (c) -1995-2001 Corporation for National Research Initiatives; All Rights -Reserved" are retained in Python 1.6.1 alone or in any derivative -version prepared by Licensee. Alternately, in lieu of CNRI's License -Agreement, Licensee may substitute the following text (omitting the -quotes): "Python 1.6.1 is made available subject to the terms and -conditions in CNRI's License Agreement. This Agreement together with -Python 1.6.1 may be located on the Internet using the following -unique, persistent identifier (known as a handle): 1895.22/1013. This -Agreement may also be obtained from a proxy server on the Internet -using the following URL: http://hdl.handle.net/1895.22/1013". - -3. In the event Licensee prepares a derivative work that is based on -or incorporates Python 1.6.1 or any part thereof, and wants to make -the derivative work available to others as provided herein, then -Licensee hereby agrees to include in any such work a brief summary of -the changes made to Python 1.6.1. - -4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS" -basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR -IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND -DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS -FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT -INFRINGE ANY THIRD PARTY RIGHTS. - -5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON -1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS -A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, -OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. - -6. This License Agreement will automatically terminate upon a material -breach of its terms and conditions. - -7. This License Agreement shall be governed by the federal -intellectual property law of the United States, including without -limitation the federal copyright law, and, to the extent such -U.S. federal law does not apply, by the law of the Commonwealth of -Virginia, excluding Virginia's conflict of law provisions. -Notwithstanding the foregoing, with regard to derivative works based -on Python 1.6.1 that incorporate non-separable material that was -previously distributed under the GNU General Public License (GPL), the -law of the Commonwealth of Virginia shall govern this License -Agreement only as to issues arising under or with respect to -Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this -License Agreement shall be deemed to create any relationship of -agency, partnership, or joint venture between CNRI and Licensee. This -License Agreement does not grant permission to use CNRI trademarks or -trade name in a trademark sense to endorse or promote products or -services of Licensee, or any third party. - -8. By clicking on the "ACCEPT" button where indicated, or by copying, -installing or otherwise using Python 1.6.1, Licensee agrees to be -bound by the terms and conditions of this License Agreement. - - ACCEPT - - -CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2 --------------------------------------------------- - -Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, -The Netherlands. All rights reserved. - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Stichting Mathematisch -Centrum or CWI not be used in advertising or publicity pertaining to -distribution of the software without specific, written prior -permission. - -STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO -THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE -FOR ANY SPECIAL, 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. diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/distlib/__init__.py b/venv/lib/python3.11/site-packages/pip/_vendor/distlib/__init__.py deleted file mode 100755 index 3ac0c33..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/distlib/__init__.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2012-2024 Vinay Sajip. -# Licensed to the Python Software Foundation under a contributor agreement. -# See LICENSE.txt and CONTRIBUTORS.txt. -# -import logging - -__version__ = '0.4.2' - - -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.11/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-311.pyc deleted file mode 100755 index e79a2da5e979f98b36b6b6229242e02ce54dc3f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1465 zcmah|%}>-o6o0ercDK8LfP$!C*2raJ*!p$gU`$LfiXnU9VBAYn+i|IO+d3^O#KRsu zaPWW$5o2QF2}Aq?{5QZ5-Sl8gJb7EP9*8I3Yqtx6iPQGiH}7-a$9(ATF95DDYi}Pu z&H((NO}dmW(b+*_9W1bz12wQRHI{)}U`a2)l6huB0{DnuvTBk_npp=La!qF7o;?pd zI|*WxL2RXfWIvn<}wfE{7;fsm$MfuS1Xszo-z_?kj?;Z*6|oMWwX&HMrI=gz0H_yt;Qq zGkjlr!rdnty4C!paKUr0R4!f80z2eWzF|Hx>O9bV+t+kdvpk_$$r&_Vw_Q8b^@_hF zWb__G9}>Yagl6w)$@%7tP*aUEi;C4n$GL5|mczxrvoE3c!R%i^O|mkGGPS>!wPY+~ zRuoaq#QEthDj&^6huTcDGY^}rD)PA7%tUg)od=O3xakQiAiGjYP$MH{AwJFW@PU(6 z65c4vJ2VSTX!Q-QB$@m#sG#=6VFeZAuUIl~*x~Zv!AQh8MHa^is8nV;2uR}qce6Ty z1ZDLcbmGU0a*V@aVP(fNAC;LHL`gs%y6F{6!Htm5p>%olVBmfJIGOY#V47p&D>E-= zSMZ6?QY|YYixNRa6;ui_OfW()MnLsVI!x7!+Y$qvH@JbYKMie}sY7k(fzqR59&RT{ zdKeP#)bDaJ$~j)WZoBoUsN+zI051YgyxO}J$vBd7RGe-2o(OLW;fW~Mow-P@^KcG* za1kdKDddogs9;!DSLaYpzw_6Ut94zRL%&qp;2T0)VvMy1fE{ZN(DQv@q*-h$jH#H# z5m;T?CGM|%QNEu|wB++!N8Y_wZnzCahK1;XtY&e06jtkN-Y)Tf{X^K!qW#|9UV9u0 zXI4(`sHfjdZ>y6#>SR-Cf$|lGKEu%Jh1CnMrq-smp|k^~t@I7(I=@yX;N94?^odPN Fe*mOAJ@o(p diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-311.pyc deleted file mode 100755 index 374f021f103a8ca439d1a7ba37d2af56f8c06d43..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52137 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 Tt$&^AlXdR?F6$>7%z*z7wV$rz diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/distlib/compat.py b/venv/lib/python3.11/site-packages/pip/_vendor/distlib/compat.py deleted file mode 100755 index b9c0fec..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/distlib/compat.py +++ /dev/null @@ -1,1107 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2013-2026 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 shutil -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 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 - - # Leaving this around for now, in case it needs resurrecting in some way - # _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 - from urllib.parse import (urlparse, urlunparse, urljoin, 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: %r' % 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 os.curdir not 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 normdir not 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' - - -import sysconfig - -try: - callable = callable -except NameError: # pragma: no cover - from collections.abc 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 - - 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' % 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 - - def cache_from_source(path, debug_override=None, optimization=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[a-z]+)://(?P.*)$') - - 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]] - 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.11/site-packages/pip/_vendor/distlib/resources.py b/venv/lib/python3.11/site-packages/pip/_vendor/distlib/resources.py deleted file mode 100755 index b908308..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/distlib/resources.py +++ /dev/null @@ -1,372 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2013-2026 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 sys -import types -import zipimport - -from . import DistlibException -from .util import cached_property, get_cache_base, 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 _is_in_base(self, path): - base = self._adjust_path(self.base) - if path == base: - return True - if not base.endswith(os.sep): - base = base + os.sep - return path.startswith(base) - - 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) - result = self._adjust_path(result) - # Confine the resolved resource to the package base so a resource - # name containing '..' cannot read files outside the package. - if not self._is_in_base(result): - raise DistlibException('Resource name escapes package: ' - '%r' % resource_name) - return 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 - # See issue #146 - _finder_registry[_fi.SourcelessFileLoader] = 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.11/site-packages/pip/_vendor/distlib/scripts.py b/venv/lib/python3.11/site-packages/pip/_vendor/distlib/scripts.py deleted file mode 100755 index ac9e909..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/distlib/scripts.py +++ /dev/null @@ -1,451 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2013-2026 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 -import time -from zipfile import ZipInfo - -from . import DistlibException -from .compat import sysconfig, detect_encoding, ZipFile -from .resources import finder -from .util import (FileOperator, get_export_entry, convert_path, get_executable, get_platform, in_venv, - is_in_directory) - -logger = logging.getLogger(__name__) - -_DEFAULT_MANIFEST = ''' - - - - - - - - - - - - -'''.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 -*- -import re -import sys -if __name__ == '__main__': - from %(module)s import %(import_name)s - sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) - sys.exit(%(func)s()) -''' - -# Pre-fetch the contents of all executable wrapper stubs. -# This is to address https://github.com/pypa/pip/issues/12666. -# When updating pip, we rename the old pip in place before installing the -# new version. If we try to fetch a wrapper *after* that rename, the finder -# machinery will be confused as the package is no longer available at the -# location where it was imported from. So we load everything into memory in -# advance. - -if os.name == 'nt' or (os.name == 'java' and os._name == 'nt'): - # Issue 31: don't hardcode an absolute package name, but - # determine it relative to the current package - DISTLIB_PACKAGE = __name__.rsplit('.', 1)[0] - - WRAPPERS = { - r.name: r.bytes - for r in finder(DISTLIB_PACKAGE).iterator("") - if r.name.endswith(".exe") - } - - -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 - - -# Keep the old name around (for now), as there is at least one project using it! -_enquote_executable = enquote_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') - self.version_info = sys.version_info - - def _get_alternate_executable(self, executable, options): - if options.get('gui', False) and self._is_nt: # pragma: no cover - 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 - elif getattr(sys, "cross_compiling", False): - # In a cross-compiling environment, the shebang will likely be a - # script; this *must* be invoked with the "safe" version of the - # shebang, or else using os.exec() to run the entry script will - # fail, raising "OSError 8 [Errno 8] Exec format error". - simple_shebang = False - 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"' '''\n" - 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 - if os.name == 'nt': - # for Python builds from source on Windows, no Python executables with - # a version suffix are created, so we use python.exe - executable = os.path.join(sysconfig.get_config_var('BINDIR'), - 'python%s' % (sysconfig.get_config_var('EXE'))) - else: - 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 - COMMENTED OUT - # executable = os.path.normcase(executable) - # N.B. The normalising operation above has been commented out: See - # issue #124. Although paths in Windows are generally case-insensitive, - # they aren't always. For example, a path containing a ẞ (which is a - # LATIN CAPITAL LETTER SHARP S - U+1E9E) is normcased to ß (which is a - # LATIN SMALL LETTER SHARP S' - U+00DF). The two are not considered by - # Windows as equivalent in path names. - - # If the user didn't specify an executable, it may be necessary to - # cater for executable paths with spaces (not uncommon on Windows) - if enquote: - executable = enquote_executable(executable) - # 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, import_name=entry.suffix.split('.')[0], 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 - if not use_launcher: - script_bytes = shebang + 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: - source_date_epoch = os.environ.get('SOURCE_DATE_EPOCH') - if source_date_epoch: - date_time = time.gmtime(int(source_date_epoch))[:6] - zinfo = ZipInfo(filename='__main__.py', date_time=date_time) - zf.writestr(zinfo, script_bytes) - else: - zf.writestr('__main__.py', script_bytes) - zip_data = stream.getvalue() - script_bytes = launcher + shebang + zip_data - for name in names: - outname = os.path.abspath(os.path.join(self.target_dir, name)) - if not is_in_directory(outname, self.target_dir): - raise DistlibException('Attempt to escape script directory') - 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) - - variant_separator = '-' - - def get_script_filenames(self, name): - result = set() - if '' in self.variants: - result.add(name) - if 'X' in self.variants: - result.add('%s%s' % (name, self.version_info[0])) - if 'X.Y' in self.variants: - result.add('%s%s%s.%s' % (name, self.variant_separator, self.version_info[0], self.version_info[1])) - return result - - 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') - scriptnames = self.get_script_filenames(entry.name) - 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 is an empty file (skipping)', 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' - platform_suffix = '-arm' if get_platform() == 'win-arm64' else '' - name = '%s%s%s.exe' % (kind, bits, platform_suffix) - if name not in WRAPPERS: - msg = ('Unable to find resource %s in package %s' % - (name, DISTLIB_PACKAGE)) - raise ValueError(msg) - return WRAPPERS[name] - - # 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.11/site-packages/pip/_vendor/distlib/t32.exe b/venv/lib/python3.11/site-packages/pip/_vendor/distlib/t32.exe deleted file mode 100755 index 52154f0be32cc2bdbf98af131d477900667d0abd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 97792 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

XMwe#*Lv$g8jIpIBEV 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 w+IyK^N3WCD*(>mhAj=irKyR>D9b+D<@QBhV6U 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

qx{CqlSNQ_YhQ()VtG-D; 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 z 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 bB!6W7g#4-b3-g!cLzth+PZapSNrC?c%T_@< diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/distro/LICENSE b/venv/lib/python3.11/site-packages/pip/_vendor/distro/LICENSE deleted file mode 100755 index e06d208..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/distro/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ -Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - 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. - diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/distro/__init__.py b/venv/lib/python3.11/site-packages/pip/_vendor/distro/__init__.py deleted file mode 100755 index 7686fe8..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/distro/__init__.py +++ /dev/null @@ -1,54 +0,0 @@ -from .distro import ( - NORMALIZED_DISTRO_ID, - NORMALIZED_LSB_ID, - NORMALIZED_OS_ID, - LinuxDistribution, - __version__, - build_number, - codename, - distro_release_attr, - distro_release_info, - id, - info, - like, - linux_distribution, - lsb_release_attr, - lsb_release_info, - major_version, - minor_version, - name, - os_release_attr, - os_release_info, - uname_attr, - uname_info, - version, - version_parts, -) - -__all__ = [ - "NORMALIZED_DISTRO_ID", - "NORMALIZED_LSB_ID", - "NORMALIZED_OS_ID", - "LinuxDistribution", - "build_number", - "codename", - "distro_release_attr", - "distro_release_info", - "id", - "info", - "like", - "linux_distribution", - "lsb_release_attr", - "lsb_release_info", - "major_version", - "minor_version", - "name", - "os_release_attr", - "os_release_info", - "uname_attr", - "uname_info", - "version", - "version_parts", -] - -__version__ = __version__ diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/distro/__main__.py b/venv/lib/python3.11/site-packages/pip/_vendor/distro/__main__.py deleted file mode 100755 index 0c01d5b..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/distro/__main__.py +++ /dev/null @@ -1,4 +0,0 @@ -from .distro import main - -if __name__ == "__main__": - main() diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/distro/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/distro/__pycache__/__init__.cpython-311.pyc deleted file mode 100755 index 45ef0286de77f9ffe9c0f1af8a7404742607da96..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1194 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 z 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 diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/distro/distro.py b/venv/lib/python3.11/site-packages/pip/_vendor/distro/distro.py deleted file mode 100755 index 78ccdfa..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/distro/distro.py +++ /dev/null @@ -1,1403 +0,0 @@ -#!/usr/bin/env python -# Copyright 2015-2021 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 the recommended replacement 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.8 removed it altogether. Its -predecessor function :py:func:`platform.dist` was already deprecated since -Python 2.6 and removed in Python 3.8. Still, there are many cases in which -access to OS distribution information is needed. See `Python issue 1322 -`_ for more information. -""" - -import argparse -import json -import logging -import os -import re -import shlex -import subprocess -import sys -import warnings -from typing import ( - Any, - Callable, - Dict, - Iterable, - Optional, - Sequence, - TextIO, - Tuple, - Type, -) - -try: - from typing import TypedDict -except ImportError: - # Python 3.7 - TypedDict = dict - -__version__ = "1.9.0" - - -class VersionDict(TypedDict): - major: str - minor: str - build_number: str - - -class InfoDict(TypedDict): - id: str - version: str - version_parts: VersionDict - like: str - codename: str - - -_UNIXCONFDIR = os.environ.get("UNIXCONFDIR", "/etc") -_UNIXUSRLIBDIR = os.environ.get("UNIXUSRLIBDIR", "/usr/lib") -_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 = { - "ol": "oracle", # Oracle Linux - "opensuse-leap": "opensuse", # Newer versions of OpenSuSE report as opensuse-leap -} - -#: 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 = { - "enterpriseenterpriseas": "oracle", # Oracle Enterprise Linux 4 - "enterpriseenterpriseserver": "oracle", # Oracle Linux 5 - "redhatenterpriseworkstation": "rhel", # RHEL 6, 7 Workstation - "redhatenterpriseserver": "rhel", # RHEL 6, 7 Server - "redhatenterprisecomputenode": "rhel", # RHEL 6 ComputeNode -} - -#: Translation table for normalizing the distro ID derived from the file name -#: 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 looked up for if _UNIXCONFDIR is not readable. -_DISTRO_RELEASE_BASENAMES = [ - "SuSE-release", - "altlinux-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", - "rocky-release", - "sl-release", - "slackware-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", - "plesk-release", - "iredmail-release", - "board-release", - "ec2_version", -) - - -def linux_distribution(full_distribution_name: bool = True) -> Tuple[str, str, str]: - """ - .. deprecated:: 1.6.0 - - :func:`distro.linux_distribution()` is deprecated. It should only be - used as a compatibility shim with Python's - :py:func:`platform.linux_distribution()`. Please use :func:`distro.id`, - :func:`distro.version` and :func:`distro.name` instead. - - 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 extra item (usually in parentheses) after the - os-release version number, or 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. - """ - warnings.warn( - "distro.linux_distribution() is deprecated. It should only be used as a " - "compatibility shim with Python's platform.linux_distribution(). Please use " - "distro.id(), distro.version() and distro.name() instead.", - DeprecationWarning, - stacklevel=2, - ) - return _distro.linux_distribution(full_distribution_name) - - -def id() -> str: - """ - 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 - "amzn" Amazon Linux - "arch" Arch Linux - "buildroot" Buildroot - "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 - "midnightbsd" MidnightBSD - "rocky" Rocky Linux - "aix" AIX - "guix" Guix System - "altlinux" ALT Linux - ============== ========================================= - - 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: bool = False) -> str: - """ - 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 "" 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 "" field of the distro release file, appended - with the value of the pretty version ("" and "" - fields) of the distro release file, if available. - """ - return _distro.name(pretty) - - -def version(pretty: bool = False, best: bool = False) -> str: - """ - 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). - - Some other distributions may not provide this kind of information. In these - cases, an empty string would be returned. This behavior can be observed - with rolling releases distributions (e.g. Arch Linux). - - 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 "" 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: bool = False) -> Tuple[str, str, str]: - """ - 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: bool = False) -> str: - """ - 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: bool = False) -> str: - """ - 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: bool = False) -> str: - """ - 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() -> str: - """ - 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 - `_. - """ - return _distro.like() - - -def codename() -> str: - """ - 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 "" field of the distro release file. - """ - return _distro.codename() - - -def info(pretty: bool = False, best: bool = False) -> InfoDict: - """ - 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() -> Dict[str, str]: - """ - 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() -> Dict[str, str]: - """ - 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() -> Dict[str, str]: - """ - 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() -> Dict[str, str]: - """ - 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: str) -> str: - """ - 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: str) -> str: - """ - 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: str) -> str: - """ - 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: str) -> str: - """ - 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) - - -try: - from functools import cached_property -except ImportError: - # Python < 3.8 - class cached_property: # type: ignore - """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: Callable[[Any], Any]) -> None: - self._fname = f.__name__ - self._f = f - - def __get__(self, obj: Any, owner: Type[Any]) -> Any: - assert obj is not None, f"call {self._fname} on an instance" - ret = obj.__dict__[self._fname] = self._f(obj) - return ret - - -class LinuxDistribution: - """ - 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: Optional[bool] = None, - os_release_file: str = "", - distro_release_file: str = "", - include_uname: Optional[bool] = None, - root_dir: Optional[str] = None, - include_oslevel: Optional[bool] = None, - ) -> None: - """ - 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_uname`` (bool): Controls whether uname command output is - included as a data source. If the uname command is not available in - the program execution path the data source for the uname command will - be empty. - - * ``root_dir`` (string): The absolute path to the root directory to use - to find distro-related information files. Note that ``include_*`` - parameters must not be enabled in combination with ``root_dir``. - - * ``include_oslevel`` (bool): Controls whether (AIX) oslevel command - output is included as a data source. If the oslevel command is not - available in the program execution path the data source 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. - - * ``include_oslevel`` (bool): The result of the ``include_oslevel`` - parameter. This controls whether (AIX) oslevel information will be - loaded. - - * ``root_dir`` (string): The result of the ``root_dir`` parameter. - The absolute path to the root directory to use to find distro-related - information files. - - Raises: - - * :py:exc:`ValueError`: Initialization parameters combination is not - supported. - - * :py:exc:`OSError`: Some I/O issue with an os-release file or distro - release file. - - * :py:exc:`UnicodeError`: A data source has unexpected characters or - uses an unexpected encoding. - """ - self.root_dir = root_dir - self.etc_dir = os.path.join(root_dir, "etc") if root_dir else _UNIXCONFDIR - self.usr_lib_dir = ( - os.path.join(root_dir, "usr/lib") if root_dir else _UNIXUSRLIBDIR - ) - - if os_release_file: - self.os_release_file = os_release_file - else: - etc_dir_os_release_file = os.path.join(self.etc_dir, _OS_RELEASE_BASENAME) - usr_lib_os_release_file = os.path.join( - self.usr_lib_dir, _OS_RELEASE_BASENAME - ) - - # NOTE: The idea is to respect order **and** have it set - # at all times for API backwards compatibility. - if os.path.isfile(etc_dir_os_release_file) or not os.path.isfile( - usr_lib_os_release_file - ): - self.os_release_file = etc_dir_os_release_file - else: - self.os_release_file = usr_lib_os_release_file - - self.distro_release_file = distro_release_file or "" # updated later - - is_root_dir_defined = root_dir is not None - if is_root_dir_defined and (include_lsb or include_uname or include_oslevel): - raise ValueError( - "Including subprocess data sources from specific root_dir is disallowed" - " to prevent false information" - ) - self.include_lsb = ( - include_lsb if include_lsb is not None else not is_root_dir_defined - ) - self.include_uname = ( - include_uname if include_uname is not None else not is_root_dir_defined - ) - self.include_oslevel = ( - include_oslevel if include_oslevel is not None else not is_root_dir_defined - ) - - def __repr__(self) -> str: - """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}, " - "include_oslevel={self.include_oslevel!r}, " - "root_dir={self.root_dir!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}, " - "_oslevel_info={self._oslevel_info!r})".format(self=self) - ) - - def linux_distribution( - self, full_distribution_name: bool = True - ) -> Tuple[str, str, str]: - """ - 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._os_release_info.get("release_codename") or self.codename(), - ) - - def id(self) -> str: - """Return the distro ID of the OS distribution, as a string. - - For details, see :func:`distro.id`. - """ - - def normalize(distro_id: str, table: Dict[str, str]) -> str: - 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: bool = False) -> str: - """ - 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 = f"{name} {version}" - return name or "" - - def version(self, pretty: bool = False, best: bool = False) -> str: - """ - 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"), - ] - if self.uname_attr("id").startswith("aix"): - # On AIX platforms, prefer oslevel command output. - versions.insert(0, self.oslevel_info()) - elif self.id() == "debian" or "debian" in self.like().split(): - # On Debian-like, add debian_version file content to candidates list. - versions.append(self._debian_version) - 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 = f"{version} ({self.codename()})" - return version - - def version_parts(self, best: bool = False) -> Tuple[str, str, str]: - """ - 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: bool = False) -> str: - """ - 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: bool = False) -> str: - """ - 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: bool = False) -> str: - """ - Return the build number of the current distribution. - - For details, see :func:`distro.build_number`. - """ - return self.version_parts(best)[2] - - def like(self) -> str: - """ - 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) -> str: - """ - Return the codename of the OS distribution. - - For details, see :func:`distro.codename`. - """ - try: - # Handle os_release specially since distros might purposefully set - # this to empty string to have no codename - return self._os_release_info["codename"] - except KeyError: - return ( - self.lsb_release_attr("codename") - or self.distro_release_attr("codename") - or "" - ) - - def info(self, pretty: bool = False, best: bool = False) -> InfoDict: - """ - Return certain machine-readable information about the OS - distribution. - - For details, see :func:`distro.info`. - """ - return InfoDict( - id=self.id(), - version=self.version(pretty, best), - version_parts=VersionDict( - 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) -> Dict[str, str]: - """ - 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) -> Dict[str, str]: - """ - 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) -> Dict[str, str]: - """ - 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) -> Dict[str, str]: - """ - 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`. - """ - return self._uname_info - - def oslevel_info(self) -> str: - """ - Return AIX' oslevel command output. - """ - return self._oslevel_info - - def os_release_attr(self, attribute: str) -> str: - """ - 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: str) -> str: - """ - 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: str) -> str: - """ - 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: str) -> str: - """ - Return a single named information item from the uname command - output data source of the OS distribution. - - For details, see :func:`distro.uname_attr`. - """ - return self._uname_info.get(attribute, "") - - @cached_property - def _os_release_info(self) -> Dict[str, str]: - """ - 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, encoding="utf-8") as release_file: - return self._parse_os_release_content(release_file) - return {} - - @staticmethod - def _parse_os_release_content(lines: TextIO) -> Dict[str, str]: - """ - 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 - - 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) - # Ignore any tokens that are not variable assignments - if "=" in token: - k, v = token.split("=", 1) - props[k.lower()] = v - - if "version" in props: - # extract release codename (if any) from version attribute - match = re.search(r"\((\D+)\)|,\s*(\D+)", props["version"]) - if match: - release_codename = match.group(1) or match.group(2) - props["codename"] = props["release_codename"] = release_codename - - if "version_codename" in props: - # os-release added a version_codename field. Use that in - # preference to anything else Note that some distros purposefully - # do not have code names. They should be setting - # version_codename="" - props["codename"] = props["version_codename"] - elif "ubuntu_codename" in props: - # Same as above but a non-standard field name used on older Ubuntus - props["codename"] = props["ubuntu_codename"] - - return props - - @cached_property - def _lsb_release_info(self) -> Dict[str, str]: - """ - Get the information items from the lsb_release command output. - - Returns: - A dictionary containing all information items. - """ - if not self.include_lsb: - return {} - try: - cmd = ("lsb_release", "-a") - stdout = subprocess.check_output(cmd, stderr=subprocess.DEVNULL) - # Command not found or lsb_release returned error - except (OSError, subprocess.CalledProcessError): - return {} - content = self._to_str(stdout).splitlines() - return self._parse_lsb_release_content(content) - - @staticmethod - def _parse_lsb_release_content(lines: Iterable[str]) -> Dict[str, str]: - """ - 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) -> Dict[str, str]: - if not self.include_uname: - return {} - try: - cmd = ("uname", "-rs") - stdout = subprocess.check_output(cmd, stderr=subprocess.DEVNULL) - except OSError: - return {} - content = self._to_str(stdout).splitlines() - return self._parse_uname_content(content) - - @cached_property - def _oslevel_info(self) -> str: - if not self.include_oslevel: - return "" - try: - stdout = subprocess.check_output("oslevel", stderr=subprocess.DEVNULL) - except (OSError, subprocess.CalledProcessError): - return "" - return self._to_str(stdout).strip() - - @cached_property - def _debian_version(self) -> str: - try: - with open( - os.path.join(self.etc_dir, "debian_version"), encoding="ascii" - ) as fp: - return fp.readline().rstrip() - except FileNotFoundError: - return "" - - @staticmethod - def _parse_uname_content(lines: Sequence[str]) -> Dict[str, str]: - if not lines: - return {} - 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 - - @staticmethod - def _to_str(bytestring: bytes) -> str: - encoding = sys.getfilesystemencoding() - return bytestring.decode(encoding) - - @cached_property - def _distro_release_info(self) -> Dict[str, str]: - """ - 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) - else: - try: - basenames = [ - basename - for basename in os.listdir(self.etc_dir) - if basename not in _DISTRO_RELEASE_IGNORE_BASENAMES - and os.path.isfile(os.path.join(self.etc_dir, basename)) - ] - # 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 = _DISTRO_RELEASE_BASENAMES - for basename in basenames: - match = _DISTRO_RELEASE_BASENAME_PATTERN.match(basename) - if match is None: - continue - filepath = os.path.join(self.etc_dir, basename) - distro_info = self._parse_distro_release_file(filepath) - # The name is always present if the pattern matches. - if "name" not in distro_info: - continue - self.distro_release_file = filepath - break - else: # the loop didn't "break": no candidate. - return {} - - if match is not None: - distro_info["id"] = match.group(1) - - # CloudLinux < 7: manually enrich info with proper id. - if "cloudlinux" in distro_info.get("name", "").lower(): - distro_info["id"] = "cloudlinux" - - return distro_info - - def _parse_distro_release_file(self, filepath: str) -> Dict[str, str]: - """ - 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, encoding="utf-8") 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: - # Ignore not being able to read a specific, seemingly version - # related file. - # See https://github.com/python-distro/distro/issues/162 - return {} - - @staticmethod - def _parse_distro_release_content(line: str) -> Dict[str, str]: - """ - 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. - """ - 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() -> None: - 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" - ) - - parser.add_argument( - "--root-dir", - "-r", - type=str, - dest="root_dir", - help="Path to the root filesystem directory (defaults to /)", - ) - - args = parser.parse_args() - - if args.root_dir: - dist = LinuxDistribution( - include_lsb=False, - include_uname=False, - include_oslevel=False, - root_dir=args.root_dir, - ) - else: - dist = _distro - - if args.json: - logger.info(json.dumps(dist.info(), indent=4, sort_keys=True)) - else: - logger.info("Name: %s", dist.name(pretty=True)) - distribution_version = dist.version(pretty=True) - logger.info("Version: %s", distribution_version) - distribution_codename = dist.codename() - logger.info("Codename: %s", distribution_codename) - - -if __name__ == "__main__": - main() diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/distro/py.typed b/venv/lib/python3.11/site-packages/pip/_vendor/distro/py.typed deleted file mode 100755 index e69de29..0000000 diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/idna/LICENSE.md b/venv/lib/python3.11/site-packages/pip/_vendor/idna/LICENSE.md deleted file mode 100755 index f706835..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/idna/LICENSE.md +++ /dev/null @@ -1,31 +0,0 @@ -BSD 3-Clause License - -Copyright (c) 2013-2026, Kim Davies and contributors. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/idna/__init__.py b/venv/lib/python3.11/site-packages/pip/_vendor/idna/__init__.py deleted file mode 100755 index cfdc030..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/idna/__init__.py +++ /dev/null @@ -1,45 +0,0 @@ -from .core import ( - IDNABidiError, - IDNAError, - InvalidCodepoint, - InvalidCodepointContext, - alabel, - check_bidi, - check_hyphen_ok, - check_initial_combiner, - check_label, - check_nfc, - decode, - encode, - ulabel, - uts46_remap, - valid_contextj, - valid_contexto, - valid_label_length, - valid_string_length, -) -from .intranges import intranges_contain -from .package_data import __version__ - -__all__ = [ - "__version__", - "IDNABidiError", - "IDNAError", - "InvalidCodepoint", - "InvalidCodepointContext", - "alabel", - "check_bidi", - "check_hyphen_ok", - "check_initial_combiner", - "check_label", - "check_nfc", - "decode", - "encode", - "intranges_contain", - "ulabel", - "uts46_remap", - "valid_contextj", - "valid_contexto", - "valid_label_length", - "valid_string_length", -] diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/idna/__main__.py b/venv/lib/python3.11/site-packages/pip/_vendor/idna/__main__.py deleted file mode 100755 index dbdd066..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/idna/__main__.py +++ /dev/null @@ -1,6 +0,0 @@ -import sys - -from .cli import main - -if __name__ == "__main__": - sys.exit(main()) diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-311.pyc deleted file mode 100755 index e7d47d17a3551a2e7535e2ed8a87789105d94f89..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1100 zcmdUtJ#P~+7{~3rTwX5kNmB;IhSUu7R24BHBq$7J=mL`$%Q>6G%{}(XcZul6hd@GN zWI=qJP6&BrVvE$R6ZTz-paTmNKI?bS^Y`8JV*7Kq+eU7DegE;CR}uQ|otshF8CM%; zd_Wv=oFKpiLxohJN~%yJHK>z11SEh4X+V=Sp+#EICT$2w2p!UaF6ly#^q^1rFdzdM zk|B)92>W=IWDFBBDeP*p2U9Y|Xn}a`6DIq-{tC^4AJ`?IjcoVy`PtKFlFJvyXk%O6 zEzQBH+OS0O6U{}crONI8ZRJF(T)fR~z!EkWiEYPA5wGang|q$AUS6b2p{QQjX(>o0 zbIB4KYnV$Vj15b@jL<3_^(M9f7qLri1EI?Iy8I+u=h?$Y)Cgdy?G+`uU_~M4w|s3! z<$CcaO@vzHOFJ&LEH_ducH#`%p=;4FwGdemj!EUjkkXAXnbeBX*~CoUrWtph$kaUQ z9)U;0qv_G|@P}_gkB&#zqvx^b(f1g53_V63V~>f$+3b$3#oCB}%JbJ0w)Lykq9EHz zS-fHkK{?A=(WGrq%94cAFX+k@g|1&mOAR6dW?~(^)C+wau{4b~LT#c%&ZG1qUut!H zcyttHG8Yea5wj?jY2@}$acv^W6^khKSAf#P^y0et7&Koe;)%KElK3l`H66EAjPbTI l#+5Dl|8aou>=GUPKEI*+mw(P}Z7+1)-r!xsKjyC6k)N6MAA$e? diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/__main__.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/__main__.cpython-311.pyc deleted file mode 100755 index 6788eabb7f811246298e09e62d3b2bb1b50b2ffe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 399 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 diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/codec.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/codec.cpython-311.pyc deleted file mode 100755 index d5261169d31540571e6e0b082807cbbc819e2879..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7083 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 diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/compat.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/compat.cpython-311.pyc deleted file mode 100755 index 6c538169a4237ba9f8110a3aae86bb6645e86a18..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2040 zcmd5-&2Jk;6yLSicI+g4BvhgWs&_%EMe0qOMryYdDQY;)28>2c$-vIDslI-1s+)R3Wq{Bu>3qin#Q|n^`;kPy|(bVYQx_x9?+S-uu0u ze_C8@Ir#kk-S?k#YmW1m5oV7!U7QSXao3>^bz>)Sdu~$cRa}QwXf>`TUe8Nvy&B3M ztJ4~53_M!@+Uw1sTwx8?98}KFB08wAqrQRq7M)`*tSZR z^P;wwa*;l8%TIO6B0*VEXQ`cQG3m3os7t0tGL4MY?5X0y{7wLeyN-TL_l5H#N5kL%7tvy}b!nR#&gJJ8(ye15Oz=#*8QinUI>N`!XQsYvh?_PjRf9UDI=Q?5$m@~YHiD*>XwW(a~PCQ1ciKgaA~ zx=gm(u54gI?zwUfCuM2?4?psUB4K_)WF-6##J*VfNtXEsEIsgJ-uJUy4@J7(SzGfJ z*X(jeqEE>_Q+~!X|6??xLi#2Xeq<}y$?~Ext&?2DE$a9?c?E|roxfjm7M70Q{^sVl zH^<)VC-}{IA>8aeJ8lrlro8`+oD${#Gvv$;^*qQaea}Kpsi82=B}6;%U4leHa0Jr;bo(B)%LTNle$mRz*la&Lat&tcl4_F5eZC6 z>}fuj@rmUdf^3sy=!m3b8H4K?FG#|bIjzv$B#T+XQqAc5CP)CA@gd1oS*_1k9^IG< z^svd%$fU?|=`?qcNufm~;xtjn8`jbYOheJE^za^GE9w2dCo=J3T#I sFcy2q8$YziZ@hE=+=|uzvi!7}i7>g)bhq83>clbgu~*LjKH5zE18jyaCIA2c diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/core.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/core.cpython-311.pyc deleted file mode 100755 index 8690d65d50b6e55921caa7deed826e8f1b41bc6b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31548 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 bWtWvgbwE!9*?N|%*i)7sPjw|_n%(~kW_)eG diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-311.pyc deleted file mode 100755 index a6e3b2e04da4a2e6ba92c39ccb1d405b6fc3fd50..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22052 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 diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-311.pyc deleted file mode 100755 index 2865a22ff2533da9367b0240ccd78ed5cc268de8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 216 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

qtN0vW;2N&u25#aOzQk?Z!B@D8 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 bool: - """Return True if any label in ``s`` carries the ``xn--`` ACE prefix.""" - prefix = _alabel_prefix.decode("ascii") - return any(label.lower().startswith(prefix) for label in _unicode_dots_re.split(s)) - - -def _build_parser() -> argparse.ArgumentParser: - parser = argparse.ArgumentParser( - prog="python -m idna", - description=( - "Convert a domain name between its Unicode (U-label) and " - "ASCII-compatible (A-label) forms. With no mode flag, the " - "direction is chosen from the first input — if it contains " - "an xn-- label the stream is decoded, otherwise it is " - "encoded — and the same mode is applied to every remaining " - "input. UTS #46 mapping is applied by default; pass " - "--strict to disable it. When no domains are given on the " - "command line and stdin is piped, one domain per line is " - "read from stdin." - ), - ) - mode = parser.add_mutually_exclusive_group() - mode.add_argument( - "-e", - "--encode", - dest="mode", - action="store_const", - const="encode", - help="Encode the input to its ASCII A-label form.", - ) - mode.add_argument( - "-d", - "--decode", - dest="mode", - action="store_const", - const="decode", - help="Decode the input from its ASCII A-label form.", - ) - parser.add_argument( - "--strict", - action="store_true", - help="Disable the default UTS #46 mapping and apply IDNA 2008 rules verbatim.", - ) - parser.add_argument( - "--version", - action="version", - version=f"idna {__version__}", - ) - parser.add_argument( - "domain", - nargs="*", - help="One or more domain names to convert. Omit to read from stdin.", - ) - return parser - - -def _iter_stdin(stream: IO[str]) -> Iterable[str]: - """Yield non-empty stripped lines from ``stream``, ignoring blanks.""" - for line in stream: - stripped = line.strip() - if stripped: - yield stripped - - -def _convert_one(domain: str, mode: str, uts46: bool) -> bool: - """Convert ``domain`` and write the result; return ``False`` on failure.""" - try: - if mode == "decode": - print(decode(domain, uts46=uts46)) - else: - print(encode(domain, uts46=uts46).decode("ascii")) - except IDNAError as err: - print(f"idna: {mode} failed for {domain!r}: {err}", file=sys.stderr) - return False - return True - - -def main(argv: Optional[list[str]] = None) -> int: - """Entry point for ``python -m idna``. - - When more than one domain is supplied (via positional arguments or - piped stdin) and no mode flag is given, the first input determines - the direction and that mode is applied uniformly to the rest. - - :param argv: Argument list excluding the program name. Defaults to - :data:`sys.argv` when ``None``. - :returns: ``0`` on success, ``1`` if any conversion fails. - """ - parser = _build_parser() - args = parser.parse_args(argv) - uts46 = not args.strict - - if args.domain: - domains: Iterable[str] = args.domain - elif not sys.stdin.isatty(): - domains = _iter_stdin(sys.stdin) - else: - parser.error("a domain argument is required when stdin is a terminal") - - iterator = iter(domains) - first = next(iterator, None) - if first is None: - return 0 - - mode = args.mode or ("decode" if _looks_like_alabel(first) else "encode") - - results = [_convert_one(domain, mode, uts46) for domain in chain([first], iterator)] - return 0 if all(results) else 1 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/idna/codec.py b/venv/lib/python3.11/site-packages/pip/_vendor/idna/codec.py deleted file mode 100755 index 83b42fe..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/idna/codec.py +++ /dev/null @@ -1,159 +0,0 @@ -import codecs -from typing import Any, Optional - -from .core import IDNAError, _unicode_dots_re, alabel, decode, encode, ulabel - - -class Codec(codecs.Codec): - """Stateless IDNA 2008 codec. - - Implements the :class:`codecs.Codec` protocol so that the whole-domain - encoder (:func:`idna.encode`) and decoder (:func:`idna.decode`) are - accessible through the standard codec machinery as ``"idna2008"``. - - Only the ``"strict"`` error handler is supported; any other handler - raises :exc:`~idna.IDNAError`. - """ - - def encode(self, data: str, errors: str = "strict") -> tuple[bytes, int]: # ty: ignore[invalid-method-override] - if errors != "strict": - raise IDNAError(f'Unsupported error handling "{errors}"') - - if not data: - return b"", 0 - - return encode(data), len(data) - - def decode(self, data: bytes, errors: str = "strict") -> tuple[str, int]: # ty: ignore[invalid-method-override] - if errors != "strict": - raise IDNAError(f'Unsupported error handling "{errors}"') - - if not data: - return "", 0 - - return decode(data), len(data) - - -class IncrementalEncoder(codecs.BufferedIncrementalEncoder): - """Incremental IDNA 2008 encoder. - - Buffers a partial trailing label across calls until either the next - label separator is seen or ``final=True``, so that streamed input is - encoded one whole label at a time. Any of the four Unicode label - separators (``U+002E``, ``U+3002``, ``U+FF0E``, ``U+FF61``) ends a - label; the result always uses ``U+002E`` as the separator. - - Only the ``"strict"`` error handler is supported. - """ - - def _buffer_encode(self, data: str, errors: str, final: bool) -> tuple[bytes, int]: # ty: ignore[invalid-method-override] - if errors != "strict": - raise IDNAError(f'Unsupported error handling "{errors}"') - - if not data: - return b"", 0 - - labels = _unicode_dots_re.split(data) - trailing_dot = b"" - if labels: - if not labels[-1]: - trailing_dot = b"." - del labels[-1] - elif not final: - # Keep potentially unfinished label until the next call - del labels[-1] - if labels: - trailing_dot = b"." - - result = [] - size = 0 - for label in labels: - result.append(alabel(label)) - if size: - size += 1 - size += len(label) - - # Join with U+002E - result_bytes = b".".join(result) + trailing_dot - size += len(trailing_dot) - return result_bytes, size - - -class IncrementalDecoder(codecs.BufferedIncrementalDecoder): - """Incremental IDNA 2008 decoder. - - Buffers a partial trailing label across calls until either the next - label separator is seen or ``final=True``, so that streamed input is - decoded one whole label at a time. - - Only the ``"strict"`` error handler is supported. - """ - - def _buffer_decode(self, data: Any, errors: str, final: bool) -> tuple[str, int]: # ty: ignore[invalid-method-override] - if errors != "strict": - raise IDNAError(f'Unsupported error handling "{errors}"') - - if not data: - return ("", 0) - - if not isinstance(data, str): - data = str(data, "ascii") - - labels = _unicode_dots_re.split(data) - trailing_dot = "" - 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(ulabel(label)) - if size: - size += 1 - size += len(label) - - result_str = ".".join(result) + trailing_dot - size += len(trailing_dot) - return (result_str, size) - - -class StreamWriter(Codec, codecs.StreamWriter): - pass - - -class StreamReader(Codec, codecs.StreamReader): - pass - - -def search_function(name: str) -> Optional[codecs.CodecInfo]: - """Codec search function registered with :mod:`codecs`. - - Returns a :class:`codecs.CodecInfo` for the ``"idna2008"`` codec name - so that ``str.encode("idna2008")`` and ``bytes.decode("idna2008")`` - invoke the IDNA 2008 codec defined in this module. - - :param name: The codec name being looked up. - :returns: A :class:`codecs.CodecInfo` instance if ``name`` is - ``"idna2008"``, otherwise ``None``. - """ - if name != "idna2008": - return None - return codecs.CodecInfo( - name=name, - encode=Codec().encode, - decode=Codec().decode, # type: ignore - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamwriter=StreamWriter, - streamreader=StreamReader, - ) - - -codecs.register(search_function) diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/idna/compat.py b/venv/lib/python3.11/site-packages/pip/_vendor/idna/compat.py deleted file mode 100755 index 1d01e3d..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/idna/compat.py +++ /dev/null @@ -1,41 +0,0 @@ -from typing import Any, Union - -from .core import decode, encode - - -def ToASCII(label: str) -> bytes: - """Compatibility shim for :rfc:`3490` ``ToASCII``. - - Delegates to :func:`idna.encode` (IDNA 2008). Provided to ease porting - of code written against the legacy :mod:`encodings.idna` API; new code - should call :func:`idna.encode` directly. - - :param label: The label or domain to encode. - :returns: The encoded form as ASCII :class:`bytes`. - """ - return encode(label) - - -def ToUnicode(label: Union[bytes, bytearray]) -> str: - """Compatibility shim for :rfc:`3490` ``ToUnicode``. - - Delegates to :func:`idna.decode` (IDNA 2008). Provided to ease porting - of code written against the legacy :mod:`encodings.idna` API; new code - should call :func:`idna.decode` directly. - - :param label: The label or domain to decode. - :returns: The decoded Unicode form. - """ - return decode(label) - - -def nameprep(s: Any) -> None: - """Stub for :rfc:`3491` Nameprep, which is not used by IDNA 2008. - - IDNA 2008 (:rfc:`5891`) replaces Nameprep with the per-codepoint - validity classes from :rfc:`5892`; this function exists only to - return a clear error if legacy code attempts to call it. - - :raises NotImplementedError: Always. - """ - raise NotImplementedError("IDNA 2008 does not utilise nameprep protocol") diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/idna/core.py b/venv/lib/python3.11/site-packages/pip/_vendor/idna/core.py deleted file mode 100755 index 1ccbd1f..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/idna/core.py +++ /dev/null @@ -1,648 +0,0 @@ -import bisect -import re -import unicodedata -import warnings -from typing import Optional, Union - -from . import idnadata -from .intranges import intranges_contain - -_virama_combining_class = 9 -_alabel_prefix = b"xn--" -_max_input_length = 1024 -_unicode_dots_re = re.compile("[\u002e\u3002\uff0e\uff61]") - - -# Bidi category sets from RFC 5893, hoisted out of the per-codepoint loop -_bidi_rtl_first = frozenset({"R", "AL"}) -_bidi_rtl_categories = frozenset({"R", "AL", "AN"}) -_bidi_rtl_allowed = frozenset({"R", "AL", "AN", "EN", "ES", "CS", "ET", "ON", "BN", "NSM"}) -_bidi_rtl_valid_ending = frozenset({"R", "AL", "EN", "AN"}) -_bidi_rtl_numeric = frozenset({"AN", "EN"}) -_bidi_ltr_allowed = frozenset({"L", "EN", "ES", "CS", "ET", "ON", "BN", "NSM"}) -_bidi_ltr_valid_ending = frozenset({"L", "EN"}) -_bidi_joiner_l_or_d = frozenset({"L", "D"}) -_bidi_joiner_r_or_d = frozenset({"R", "D"}) - - -def _joining_type(cp: int) -> Optional[str]: - for jt, ranges in idnadata.joining_types.items(): - if intranges_contain(cp, ranges): - return jt - return None - - -class IDNAError(UnicodeError): - """Base exception for all IDNA-encoding related problems""" - - -class IDNABidiError(IDNAError): - """Exception when bidirectional requirements are not satisfied""" - - -class InvalidCodepoint(IDNAError): - """Exception when a disallowed or unallocated codepoint is used""" - - -class InvalidCodepointContext(IDNAError): - """Exception when the codepoint is not valid in the context it is used""" - - -def _combining_class(cp: int) -> int: - v = unicodedata.combining(chr(cp)) - if v == 0 and not unicodedata.name(chr(cp)): - raise ValueError("Unknown character in unicodedata") - return v - - -def _is_script(cp: str, script: str) -> bool: - return intranges_contain(ord(cp), idnadata.scripts[script]) - - -def _punycode(s: str) -> bytes: - return s.encode("punycode") - - -def _unot(s: int) -> str: - return f"U+{s:04X}" - - -def valid_label_length(label: Union[bytes, str]) -> bool: - """Check that a label does not exceed the maximum permitted length. - - Per :rfc:`1035` (and :rfc:`5891` §4.2.4) a DNS label must not exceed - 63 octets. The argument may be either a :class:`str` (a U-label, where - length is measured in characters) or :class:`bytes` (an A-label, where - length is measured in octets). - - :param label: The label to check. - :returns: ``True`` if the label is within the length limit, otherwise - ``False``. - """ - return len(label) <= 63 - - -def valid_string_length(domain: Union[bytes, str], trailing_dot: bool) -> bool: - """Check that a full domain name does not exceed the maximum length. - - Per :rfc:`1035`, a domain name is limited to 253 octets when no trailing - dot is present, or 254 octets when one is included. - - :param domain: The full (possibly multi-label) domain name. - :param trailing_dot: ``True`` if ``domain`` includes a trailing ``.``. - :returns: ``True`` if the domain is within the length limit, otherwise - ``False``. - """ - return len(domain) <= (254 if trailing_dot else 253) - - -def check_bidi(label: str, check_ltr: bool = False) -> bool: - """Validate the Bidi Rule from :rfc:`5893` for a single label. - - The Bidi Rule constrains how bidirectional characters (Hebrew, Arabic, - etc.) may appear within a label. By default the check is only applied - when the label contains at least one right-to-left character (Unicode - bidirectional categories ``R``, ``AL``, or ``AN``); set ``check_ltr`` - to ``True`` to apply it to LTR-only labels as well. - - :param label: The label to validate, as a Unicode string. - :param check_ltr: If ``True``, apply the rules even when the label - contains no RTL characters. - :returns: ``True`` if the label satisfies the Bidi Rule. - :raises IDNABidiError: If any of Bidi Rule conditions 1-6 are violated, - or if the directional category of a codepoint cannot be determined. - """ - if len(label) > _max_input_length: - raise IDNAError("Label too long") - # 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(f"Unknown directionality in label {label!r} at position {idx}") - if direction in _bidi_rtl_categories: - bidi_label = True - if not bidi_label and not check_ltr: - return True - - # Bidi rule 1 - direction = unicodedata.bidirectional(label[0]) - if direction in _bidi_rtl_first: - rtl = True - elif direction == "L": - rtl = False - else: - raise IDNABidiError(f"First codepoint in label {label!r} must be directionality L, R or AL") - - valid_ending = False - number_type: Optional[str] = None - for idx, cp in enumerate(label, 1): - direction = unicodedata.bidirectional(cp) - - if rtl: - # Bidi rule 2 - if direction not in _bidi_rtl_allowed: - raise IDNABidiError(f"Invalid direction for codepoint at position {idx} in a right-to-left label") - # Bidi rule 3 - if direction in _bidi_rtl_valid_ending: - valid_ending = True - elif direction != "NSM": - valid_ending = False - # Bidi rule 4 - if direction in _bidi_rtl_numeric: - if not number_type: - number_type = direction - elif number_type != direction: - raise IDNABidiError("Can not mix numeral types in a right-to-left label") - else: - # Bidi rule 5 - if direction not in _bidi_ltr_allowed: - raise IDNABidiError(f"Invalid direction for codepoint at position {idx} in a left-to-right label") - # Bidi rule 6 - if direction in _bidi_ltr_valid_ending: - 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: str) -> bool: - """Reject labels that begin with a combining mark. - - Per :rfc:`5891` §4.2.3.2 a label must not start with a character of - Unicode general category ``M`` (Mark). - - :param label: The label to check. - :returns: ``True`` if the first character is not a combining mark. - :raises IDNAError: If the label begins with a combining character. - """ - if unicodedata.category(label[0])[0] == "M": - raise IDNAError("Label begins with an illegal combining character") - return True - - -def check_hyphen_ok(label: str) -> bool: - """Validate the hyphen restrictions for a label. - - Per :rfc:`5891` §4.2.3.1 a label must not start or end with a hyphen - (``U+002D``), and must not have hyphens in both the third and fourth - positions (the prefix reserved for A-labels). - - :param label: The label to check. - :returns: ``True`` if the hyphen restrictions are satisfied. - :raises IDNAError: If any of the hyphen restrictions are violated. - """ - 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: str) -> None: - """Require that a label is in Unicode Normalization Form C. - - :param label: The label to check. - :raises IDNAError: If ``label`` differs from its NFC normalisation. - """ - if len(label) > _max_input_length: - raise IDNAError("Label too long") - if unicodedata.normalize("NFC", label) != label: - raise IDNAError("Label must be in Normalization Form C") - - -def valid_contextj(label: str, pos: int) -> bool: - """Validate the CONTEXTJ rules from :rfc:`5892` Appendix A. - - These rules govern the contextual use of the joiner codepoints - ``U+200C`` (ZERO WIDTH NON-JOINER, Appendix A.1) and ``U+200D`` - (ZERO WIDTH JOINER, Appendix A.2) within a label. - - :param label: The label containing the codepoint. - :param pos: Index of the joiner codepoint within ``label``. - :returns: ``True`` if the codepoint at ``pos`` satisfies its CONTEXTJ - rule, ``False`` otherwise (including when the codepoint at - ``pos`` is not a recognised joiner). - :raises ValueError: If an adjacent codepoint has no Unicode name when - determining its combining class. - :raises IDNAError: If ``label`` exceeds the defensive input length limit. - """ - if len(label) > _max_input_length: - raise IDNAError("Label too long") - cp_value = ord(label[pos]) - - if cp_value == 0x200C: - if pos > 0 and _combining_class(ord(label[pos - 1])) == _virama_combining_class: - return True - - ok = False - for i in range(pos - 1, -1, -1): - joining_type = _joining_type(ord(label[i])) - if joining_type == "T": - continue - if joining_type in _bidi_joiner_l_or_d: - ok = True - break - break - - if not ok: - return False - - ok = False - for i in range(pos + 1, len(label)): - joining_type = _joining_type(ord(label[i])) - if joining_type == "T": - continue - if joining_type in _bidi_joiner_r_or_d: - ok = True - break - break - return ok - - if cp_value == 0x200D: - return pos > 0 and _combining_class(ord(label[pos - 1])) == _virama_combining_class - - return False - - -def valid_contexto(label: str, pos: int, exception: bool = False) -> bool: - """Validate the CONTEXTO rules from :rfc:`5892` Appendix A. - - Covers the contextual rules for codepoints such as MIDDLE DOT - (``U+00B7``), Greek lower numeral sign, Hebrew punctuation, Katakana - middle dot, and the Arabic-Indic / Extended Arabic-Indic digit ranges. - - :param label: The label containing the codepoint. - :param pos: Index of the codepoint within ``label``. - :param exception: Reserved for forward compatibility; currently unused. - :returns: ``True`` if the codepoint at ``pos`` satisfies its CONTEXTO - rule, ``False`` otherwise (including when the codepoint is not a - recognised CONTEXTO codepoint). - :raises IDNAError: If ``label`` exceeds the defensive input length limit. - """ - if len(label) > _max_input_length: - raise IDNAError("Label too long") - cp_value = ord(label[pos]) - - if cp_value == 0x00B7: - return 0 < pos < len(label) - 1 and ord(label[pos - 1]) == 0x006C and ord(label[pos + 1]) == 0x006C - - if cp_value == 0x0375: - if pos < len(label) - 1 and len(label) > 1: - return _is_script(label[pos + 1], "Greek") - return False - - if cp_value in {0x05F3, 0x05F4}: - if pos > 0: - return _is_script(label[pos - 1], "Hebrew") - return False - - if cp_value == 0x30FB: - for cp in label: - if cp == "\u30fb": - continue - if _is_script(cp, "Hiragana") or _is_script(cp, "Katakana") or _is_script(cp, "Han"): - return True - return False - - if 0x660 <= cp_value <= 0x669: - return not any(0x6F0 <= ord(cp) <= 0x06F9 for cp in label) - - if 0x6F0 <= cp_value <= 0x6F9: - return not any(0x660 <= ord(cp) <= 0x0669 for cp in label) - - return False - - -def check_label(label: Union[str, bytes, bytearray]) -> None: - """Run the full set of IDNA 2008 validity checks on a single label. - - Applies, in order: NFC normalisation (:func:`check_nfc`), hyphen - restrictions (:func:`check_hyphen_ok`), the no-leading-combiner rule - (:func:`check_initial_combiner`), per-codepoint validity (PVALID, - CONTEXTJ, CONTEXTO classes from :rfc:`5892`), and the Bidi Rule - (:func:`check_bidi`). - - :param label: The label to validate. ``bytes`` or ``bytearray`` input - is decoded as UTF-8 first. - :raises IDNAError: If the label is empty or fails a structural rule. - :raises InvalidCodepoint: If the label contains a DISALLOWED or - UNASSIGNED codepoint. - :raises InvalidCodepointContext: If a CONTEXTJ or CONTEXTO codepoint - is not valid in its context. - :raises IDNABidiError: If the Bidi Rule is violated. - """ - if len(label) > _max_input_length: - raise IDNAError("Label too long") - if isinstance(label, (bytes, bytearray)): - label = label.decode("utf-8") - if len(label) == 0: - raise IDNAError("Empty Label") - - # Reject on domain length rather than label length so support some UTS 46 - # use cases, still reducing processing of label contextual rules - if not valid_string_length(label, trailing_dot=True): - raise IDNAError("Label too long") - - 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 - if intranges_contain(cp_value, idnadata.codepoint_classes["CONTEXTJ"]): - try: - if not valid_contextj(label, pos): - raise InvalidCodepointContext(f"Joiner {_unot(cp_value)} not allowed at position {pos + 1} in {label!r}") - except ValueError as err: - raise IDNAError( - f"Unknown codepoint adjacent to joiner {_unot(cp_value)} at position {pos + 1} in {label!r}" - ) from err - elif intranges_contain(cp_value, idnadata.codepoint_classes["CONTEXTO"]): - if not valid_contexto(label, pos): - raise InvalidCodepointContext(f"Codepoint {_unot(cp_value)} not allowed at position {pos + 1} in {label!r}") - else: - raise InvalidCodepoint(f"Codepoint {_unot(cp_value)} at position {pos + 1} of {label!r} not allowed") - - check_bidi(label) - - -def alabel(label: str) -> bytes: - """Convert a single U-label into its A-label form. - - The result is the ASCII-Compatible Encoding (ACE) form per :rfc:`5891` - §4: the label is validated, Punycode-encoded, and prefixed with - ``xn--``. Pure ASCII labels that are already valid IDNA labels are - returned unchanged (as :class:`bytes`). - - :param label: The label to convert, as a Unicode string. - :returns: The A-label as ASCII-encoded :class:`bytes`. - :raises IDNAError: If the label is invalid or the resulting A-label - exceeds 63 octets. - """ - if len(label) > _max_input_length: - raise IDNAError("Label too long") - try: - label_bytes = label.encode("ascii") - except UnicodeEncodeError: - pass - else: - ulabel(label_bytes) - if not valid_label_length(label_bytes): - raise IDNAError("Label too long") - return label_bytes - - check_label(label) - label_bytes = _alabel_prefix + _punycode(label) - - if not valid_label_length(label_bytes): - raise IDNAError("Label too long") - - return label_bytes - - -def ulabel(label: Union[str, bytes, bytearray]) -> str: - """Convert a single A-label into its U-label form. - - Performs the inverse of :func:`alabel`: an ``xn--``-prefixed label is - Punycode-decoded and validated. Labels that are already Unicode (or - plain ASCII without the ACE prefix) are validated and returned as a - Unicode string. - - :param label: The label to convert. ``bytes`` or ``bytearray`` input - is treated as ASCII. - :returns: The U-label as a Unicode string. - :raises IDNAError: If the label is malformed or fails validation. - """ - if len(label) > _max_input_length: - raise IDNAError("Label too long") - if not isinstance(label, (bytes, bytearray)): - try: - label_bytes = label.encode("ascii") - except UnicodeEncodeError: - check_label(label) - return label - else: - label_bytes = bytes(label) - - label_bytes = label_bytes.lower() - if label_bytes.startswith(_alabel_prefix): - label_bytes = label_bytes[len(_alabel_prefix) :] - if not label_bytes: - raise IDNAError("Malformed A-label, no Punycode eligible content found") - if label_bytes.endswith(b"-"): - raise IDNAError("A-label must not end with a hyphen") - else: - check_label(label_bytes) - return label_bytes.decode("ascii") - - try: - label = label_bytes.decode("punycode") - except UnicodeError as err: - raise IDNAError("Invalid A-label") from err - check_label(label) - return label - - -def uts46_remap(domain: str, std3_rules: bool = True, transitional: bool = False) -> str: - """Apply the UTS #46 character mapping to a domain string. - - Implements the mapping table from `UTS #46 §4 - `_: each character is kept, - replaced, or rejected based on its status (``V``, ``M``, ``D``, ``3``, - ``I``). The result is returned in Normalisation Form C. - - :param domain: The full domain name to remap. - :param std3_rules: If ``True``, apply the stricter STD3 ASCII rules - (status ``3`` codepoints raise instead of being kept or mapped). - :param transitional: If ``True``, use transitional processing (status - ``D`` codepoints are mapped instead of kept). Transitional - processing has been removed from UTS #46 and this option is - retained only for backwards compatibility. - :returns: The remapped domain, in Normalisation Form C. - :raises InvalidCodepoint: If the domain contains a disallowed - codepoint under the chosen rules. - :raises IDNAError: If ``domain`` exceeds the defensive input length limit. - """ - if len(domain) > _max_input_length: - raise IDNAError("Domain too long") - from .uts46data import uts46_replacements, uts46_starts, uts46_statuses - - output = "" - - for pos, char in enumerate(domain): - code_point = ord(char) - i = code_point if code_point < 256 else bisect.bisect_right(uts46_starts, code_point) - 1 - status = chr(uts46_statuses[i]) - replacement: Optional[str] = uts46_replacements[i] - - # UTS #46 §4: V is always valid, D is deviation (kept unless transitional), - # 3 is disallowed-STD3 (kept unmapped if std3_rules is off and no mapping). - keep_as_is = ( - status == "V" or (status == "D" and not transitional) or (status == "3" and not std3_rules and replacement is None) - ) - # M is mapped, 3-with-replacement and transitional D fall through to the - # same replacement output path. - use_replacement = replacement is not None and ( - status == "M" or (status == "3" and not std3_rules) or (status == "D" and transitional) - ) - - if keep_as_is: - output += char - elif use_replacement: - assert replacement is not None # narrowed by use_replacement - output += replacement - elif status == "I": - continue - else: - raise InvalidCodepoint(f"Codepoint {_unot(code_point)} not allowed at position {pos + 1} in {domain!r}") - - return unicodedata.normalize("NFC", output) - - -def encode( - s: Union[str, bytes, bytearray], - strict: bool = False, - uts46: bool = False, - std3_rules: bool = False, - transitional: bool = False, -) -> bytes: - """Encode a Unicode domain name into its ASCII (A-label) form. - - Splits the input on label separators (only ``U+002E`` if ``strict`` is - set; otherwise also IDEOGRAPHIC FULL STOP ``U+3002``, FULLWIDTH FULL - STOP ``U+FF0E``, and HALFWIDTH IDEOGRAPHIC FULL STOP ``U+FF61``), - encodes each label with :func:`alabel`, and rejoins them with ``.``. - Optionally pre-processes the input through :func:`uts46_remap`. - - :param s: The domain name to encode. - :param strict: If ``True``, only ``U+002E`` is recognised as a label - separator. - :param uts46: If ``True``, apply UTS #46 mapping before encoding. - :param std3_rules: Forwarded to :func:`uts46_remap` when ``uts46`` is - ``True``. - :param transitional: Forwarded to :func:`uts46_remap` when ``uts46`` - is ``True``. Deprecated: emits a :class:`DeprecationWarning` and - will be removed in a future version. - :returns: The encoded domain as ASCII :class:`bytes`. - :raises IDNAError: If the domain is empty, contains an invalid label, - or exceeds the maximum domain length. - """ - if transitional: - warnings.warn( - "Transitional processing has been removed from UTS #46. " - "The transitional argument will be removed in a future version.", - DeprecationWarning, - stacklevel=2, - ) - if not isinstance(s, str): - try: - s = str(s, "ascii") - except (UnicodeDecodeError, TypeError) as err: - raise IDNAError("should pass a unicode string to the function rather than a byte string.") from err - if len(s) > _max_input_length: - raise IDNAError("Domain too long") - if uts46: - s = uts46_remap(s, std3_rules, transitional) - - # Reject inputs that exceed the maximum DNS domain length up-front - # to avoid expensive computation on long inputs. - if not valid_string_length(s, trailing_dot=True): - raise IDNAError("Domain too long") - - trailing_dot = False - result = [] - labels = s.split(".") if strict else _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: Union[str, bytes, bytearray], - strict: bool = False, - uts46: bool = False, - std3_rules: bool = False, - display: bool = False, -) -> str: - """Decode an A-label-encoded domain name back to Unicode. - - Splits the input on label separators (see :func:`encode` for the - rules), decodes each label with :func:`ulabel`, and rejoins them - with ``.``. Optionally pre-processes the input through - :func:`uts46_remap`. - - :param s: The domain name to decode. - :param strict: If ``True``, only ``U+002E`` is recognised as a label - separator. - :param uts46: If ``True``, apply UTS #46 mapping before decoding. - :param std3_rules: Forwarded to :func:`uts46_remap` when ``uts46`` is - ``True``. - :param display: If ``True``, any ``xn--`` label that fails IDNA - validation is passed through unchanged (lowercased) rather than - aborting the whole call. Intended for "decode for display" - consumers (e.g. URL libraries, HTTP clients) that want to show - the user the label as it appears on the wire when it cannot be - rendered as Unicode. Matches the per-label recovery prescribed - by UTS #46 §4 and the WHATWG URL "domain to Unicode" algorithm. - :returns: The decoded domain as a Unicode string. - :raises IDNAError: If the input is not valid ASCII, contains an - invalid label, or is empty. - """ - if not isinstance(s, str): - try: - s = str(s, "ascii") - except (UnicodeDecodeError, TypeError) as err: - raise IDNAError("Invalid ASCII in A-label") from err - if len(s) > _max_input_length: - raise IDNAError("Domain too long") - if uts46: - s = uts46_remap(s, std3_rules, False) - # Reject inputs that exceed the maximum DNS domain length up-front - # to avoid expensive computation on long inputs. - if not valid_string_length(s, trailing_dot=True): - raise IDNAError("Domain too long") - trailing_dot = False - result = [] - labels = s.split(".") if strict else _unicode_dots_re.split(s) - if not labels or labels == [""]: - raise IDNAError("Empty domain") - if not labels[-1]: - del labels[-1] - trailing_dot = True - for label in labels: - try: - u = ulabel(label) - except IDNAError: - if display and label[:4].lower() == "xn--": - u = label.lower() - else: - raise - if u: - result.append(u) - else: - raise IDNAError("Empty label") - if trailing_dot: - result.append("") - return ".".join(result) diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/idna/idnadata.py b/venv/lib/python3.11/site-packages/pip/_vendor/idna/idnadata.py deleted file mode 100755 index f2ab388..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/idna/idnadata.py +++ /dev/null @@ -1,1897 +0,0 @@ -# This file is automatically generated by tools/idna-data - -__version__ = "17.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, - 0x340000004DC0, - 0x4E000000A000, - 0xF9000000FA6E, - 0xFA700000FADA, - 0x16FE200016FE4, - 0x16FF000016FF7, - 0x200000002A6E0, - 0x2A7000002B81E, - 0x2B8200002CEAE, - 0x2CEB00002EBE1, - 0x2EBF00002EE5E, - 0x2F8000002FA1E, - 0x300000003134B, - 0x313500003347A, - ), - "Hebrew": ( - 0x591000005C8, - 0x5D0000005EB, - 0x5EF000005F5, - 0xFB1D0000FB37, - 0xFB380000FB3D, - 0xFB3E0000FB3F, - 0xFB400000FB42, - 0xFB430000FB45, - 0xFB460000FB50, - ), - "Hiragana": ( - 0x304100003097, - 0x309D000030A0, - 0x1B0010001B120, - 0x1B1320001B133, - 0x1B1500001B153, - 0x1F2000001F201, - ), - "Katakana": ( - 0x30A1000030FB, - 0x30FD00003100, - 0x31F000003200, - 0x32D0000032FF, - 0x330000003358, - 0xFF660000FF70, - 0xFF710000FF9E, - 0x1AFF00001AFF4, - 0x1AFF50001AFFC, - 0x1AFFD0001AFFF, - 0x1B0000001B001, - 0x1B1200001B123, - 0x1B1550001B156, - 0x1B1640001B168, - ), -} - - -joining_types = { - "C": ( - 0x64000000641, - 0x7FA000007FB, - 0x88300000886, - 0x180A0000180B, - 0x200D0000200E, - ), - "D": ( - 0x62000000621, - 0x62600000627, - 0x62800000629, - 0x62A0000062F, - 0x63300000640, - 0x64100000648, - 0x6490000064B, - 0x66E00000670, - 0x67800000688, - 0x69A000006C0, - 0x6C1000006C3, - 0x6CC000006CD, - 0x6CE000006CF, - 0x6D0000006D2, - 0x6FA000006FD, - 0x6FF00000700, - 0x71200000715, - 0x71A0000071E, - 0x71F00000728, - 0x7290000072A, - 0x72B0000072C, - 0x72D0000072F, - 0x74E00000759, - 0x75C0000076B, - 0x76D00000771, - 0x77200000773, - 0x77500000778, - 0x77A00000780, - 0x7CA000007EB, - 0x84100000846, - 0x84800000849, - 0x84A00000854, - 0x85500000856, - 0x86000000861, - 0x86200000866, - 0x86800000869, - 0x88600000887, - 0x8890000088E, - 0x88F00000890, - 0x8A0000008AA, - 0x8AF000008B1, - 0x8B3000008B9, - 0x8BA000008C9, - 0x180700001808, - 0x182000001879, - 0x1887000018A9, - 0x18AA000018AB, - 0xA8400000A872, - 0x10AC000010AC5, - 0x10AD300010AD7, - 0x10AD800010ADD, - 0x10ADE00010AE1, - 0x10AEB00010AEF, - 0x10B8000010B81, - 0x10B8200010B83, - 0x10B8600010B89, - 0x10B8A00010B8C, - 0x10B8D00010B8E, - 0x10B9000010B91, - 0x10BAD00010BAF, - 0x10D0100010D22, - 0x10D2300010D24, - 0x10EC300010EC5, - 0x10EC600010EC8, - 0x10F3000010F33, - 0x10F3400010F45, - 0x10F5100010F54, - 0x10F7000010F74, - 0x10F7600010F82, - 0x10FB000010FB1, - 0x10FB200010FB4, - 0x10FB800010FB9, - 0x10FBB00010FBD, - 0x10FBE00010FC0, - 0x10FC100010FC2, - 0x10FC400010FC5, - 0x10FCA00010FCB, - 0x1E9000001E944, - ), - "L": ( - 0xA8720000A873, - 0x10ACD00010ACE, - 0x10AD700010AD8, - 0x10D0000010D01, - 0x10FCB00010FCC, - ), - "R": ( - 0x62200000626, - 0x62700000628, - 0x6290000062A, - 0x62F00000633, - 0x64800000649, - 0x67100000674, - 0x67500000678, - 0x6880000069A, - 0x6C0000006C1, - 0x6C3000006CC, - 0x6CD000006CE, - 0x6CF000006D0, - 0x6D2000006D4, - 0x6D5000006D6, - 0x6EE000006F0, - 0x71000000711, - 0x7150000071A, - 0x71E0000071F, - 0x72800000729, - 0x72A0000072B, - 0x72C0000072D, - 0x72F00000730, - 0x74D0000074E, - 0x7590000075C, - 0x76B0000076D, - 0x77100000772, - 0x77300000775, - 0x7780000077A, - 0x84000000841, - 0x84600000848, - 0x8490000084A, - 0x85400000855, - 0x85600000859, - 0x86700000868, - 0x8690000086B, - 0x87000000883, - 0x88E0000088F, - 0x8AA000008AD, - 0x8AE000008AF, - 0x8B1000008B3, - 0x8B9000008BA, - 0x10AC500010AC6, - 0x10AC700010AC8, - 0x10AC900010ACB, - 0x10ACE00010AD3, - 0x10ADD00010ADE, - 0x10AE100010AE2, - 0x10AE400010AE5, - 0x10AEF00010AF0, - 0x10B8100010B82, - 0x10B8300010B86, - 0x10B8900010B8A, - 0x10B8C00010B8D, - 0x10B8E00010B90, - 0x10B9100010B92, - 0x10BA900010BAD, - 0x10D2200010D23, - 0x10EC200010EC3, - 0x10F3300010F34, - 0x10F5400010F55, - 0x10F7400010F76, - 0x10FB400010FB7, - 0x10FB900010FBB, - 0x10FBD00010FBE, - 0x10FC200010FC4, - 0x10FC900010FCA, - ), - "T": ( - 0xAD000000AE, - 0x30000000370, - 0x4830000048A, - 0x591000005BE, - 0x5BF000005C0, - 0x5C1000005C3, - 0x5C4000005C6, - 0x5C7000005C8, - 0x6100000061B, - 0x61C0000061D, - 0x64B00000660, - 0x67000000671, - 0x6D6000006DD, - 0x6DF000006E5, - 0x6E7000006E9, - 0x6EA000006EE, - 0x70F00000710, - 0x71100000712, - 0x7300000074B, - 0x7A6000007B1, - 0x7EB000007F4, - 0x7FD000007FE, - 0x8160000081A, - 0x81B00000824, - 0x82500000828, - 0x8290000082E, - 0x8590000085C, - 0x897000008A0, - 0x8CA000008E2, - 0x8E300000903, - 0x93A0000093B, - 0x93C0000093D, - 0x94100000949, - 0x94D0000094E, - 0x95100000958, - 0x96200000964, - 0x98100000982, - 0x9BC000009BD, - 0x9C1000009C5, - 0x9CD000009CE, - 0x9E2000009E4, - 0x9FE000009FF, - 0xA0100000A03, - 0xA3C00000A3D, - 0xA4100000A43, - 0xA4700000A49, - 0xA4B00000A4E, - 0xA5100000A52, - 0xA7000000A72, - 0xA7500000A76, - 0xA8100000A83, - 0xABC00000ABD, - 0xAC100000AC6, - 0xAC700000AC9, - 0xACD00000ACE, - 0xAE200000AE4, - 0xAFA00000B00, - 0xB0100000B02, - 0xB3C00000B3D, - 0xB3F00000B40, - 0xB4100000B45, - 0xB4D00000B4E, - 0xB5500000B57, - 0xB6200000B64, - 0xB8200000B83, - 0xBC000000BC1, - 0xBCD00000BCE, - 0xC0000000C01, - 0xC0400000C05, - 0xC3C00000C3D, - 0xC3E00000C41, - 0xC4600000C49, - 0xC4A00000C4E, - 0xC5500000C57, - 0xC6200000C64, - 0xC8100000C82, - 0xCBC00000CBD, - 0xCBF00000CC0, - 0xCC600000CC7, - 0xCCC00000CCE, - 0xCE200000CE4, - 0xD0000000D02, - 0xD3B00000D3D, - 0xD4100000D45, - 0xD4D00000D4E, - 0xD6200000D64, - 0xD8100000D82, - 0xDCA00000DCB, - 0xDD200000DD5, - 0xDD600000DD7, - 0xE3100000E32, - 0xE3400000E3B, - 0xE4700000E4F, - 0xEB100000EB2, - 0xEB400000EBD, - 0xEC800000ECF, - 0xF1800000F1A, - 0xF3500000F36, - 0xF3700000F38, - 0xF3900000F3A, - 0xF7100000F7F, - 0xF8000000F85, - 0xF8600000F88, - 0xF8D00000F98, - 0xF9900000FBD, - 0xFC600000FC7, - 0x102D00001031, - 0x103200001038, - 0x10390000103B, - 0x103D0000103F, - 0x10580000105A, - 0x105E00001061, - 0x107100001075, - 0x108200001083, - 0x108500001087, - 0x108D0000108E, - 0x109D0000109E, - 0x135D00001360, - 0x171200001715, - 0x173200001734, - 0x175200001754, - 0x177200001774, - 0x17B4000017B6, - 0x17B7000017BE, - 0x17C6000017C7, - 0x17C9000017D4, - 0x17DD000017DE, - 0x180B0000180E, - 0x180F00001810, - 0x188500001887, - 0x18A9000018AA, - 0x192000001923, - 0x192700001929, - 0x193200001933, - 0x19390000193C, - 0x1A1700001A19, - 0x1A1B00001A1C, - 0x1A5600001A57, - 0x1A5800001A5F, - 0x1A6000001A61, - 0x1A6200001A63, - 0x1A6500001A6D, - 0x1A7300001A7D, - 0x1A7F00001A80, - 0x1AB000001ADE, - 0x1AE000001AEC, - 0x1B0000001B04, - 0x1B3400001B35, - 0x1B3600001B3B, - 0x1B3C00001B3D, - 0x1B4200001B43, - 0x1B6B00001B74, - 0x1B8000001B82, - 0x1BA200001BA6, - 0x1BA800001BAA, - 0x1BAB00001BAE, - 0x1BE600001BE7, - 0x1BE800001BEA, - 0x1BED00001BEE, - 0x1BEF00001BF2, - 0x1C2C00001C34, - 0x1C3600001C38, - 0x1CD000001CD3, - 0x1CD400001CE1, - 0x1CE200001CE9, - 0x1CED00001CEE, - 0x1CF400001CF5, - 0x1CF800001CFA, - 0x1DC000001E00, - 0x200B0000200C, - 0x200E00002010, - 0x202A0000202F, - 0x206000002065, - 0x206A00002070, - 0x20D0000020F1, - 0x2CEF00002CF2, - 0x2D7F00002D80, - 0x2DE000002E00, - 0x302A0000302E, - 0x30990000309B, - 0xA66F0000A673, - 0xA6740000A67E, - 0xA69E0000A6A0, - 0xA6F00000A6F2, - 0xA8020000A803, - 0xA8060000A807, - 0xA80B0000A80C, - 0xA8250000A827, - 0xA82C0000A82D, - 0xA8C40000A8C6, - 0xA8E00000A8F2, - 0xA8FF0000A900, - 0xA9260000A92E, - 0xA9470000A952, - 0xA9800000A983, - 0xA9B30000A9B4, - 0xA9B60000A9BA, - 0xA9BC0000A9BE, - 0xA9E50000A9E6, - 0xAA290000AA2F, - 0xAA310000AA33, - 0xAA350000AA37, - 0xAA430000AA44, - 0xAA4C0000AA4D, - 0xAA7C0000AA7D, - 0xAAB00000AAB1, - 0xAAB20000AAB5, - 0xAAB70000AAB9, - 0xAABE0000AAC0, - 0xAAC10000AAC2, - 0xAAEC0000AAEE, - 0xAAF60000AAF7, - 0xABE50000ABE6, - 0xABE80000ABE9, - 0xABED0000ABEE, - 0xFB1E0000FB1F, - 0xFE000000FE10, - 0xFE200000FE30, - 0xFEFF0000FF00, - 0xFFF90000FFFC, - 0x101FD000101FE, - 0x102E0000102E1, - 0x103760001037B, - 0x10A0100010A04, - 0x10A0500010A07, - 0x10A0C00010A10, - 0x10A3800010A3B, - 0x10A3F00010A40, - 0x10AE500010AE7, - 0x10D2400010D28, - 0x10D6900010D6E, - 0x10EAB00010EAD, - 0x10EFA00010F00, - 0x10F4600010F51, - 0x10F8200010F86, - 0x1100100011002, - 0x1103800011047, - 0x1107000011071, - 0x1107300011075, - 0x1107F00011082, - 0x110B3000110B7, - 0x110B9000110BB, - 0x110C2000110C3, - 0x1110000011103, - 0x111270001112C, - 0x1112D00011135, - 0x1117300011174, - 0x1118000011182, - 0x111B6000111BF, - 0x111C9000111CD, - 0x111CF000111D0, - 0x1122F00011232, - 0x1123400011235, - 0x1123600011238, - 0x1123E0001123F, - 0x1124100011242, - 0x112DF000112E0, - 0x112E3000112EB, - 0x1130000011302, - 0x1133B0001133D, - 0x1134000011341, - 0x113660001136D, - 0x1137000011375, - 0x113BB000113C1, - 0x113CE000113CF, - 0x113D0000113D1, - 0x113D2000113D3, - 0x113E1000113E3, - 0x1143800011440, - 0x1144200011445, - 0x1144600011447, - 0x1145E0001145F, - 0x114B3000114B9, - 0x114BA000114BB, - 0x114BF000114C1, - 0x114C2000114C4, - 0x115B2000115B6, - 0x115BC000115BE, - 0x115BF000115C1, - 0x115DC000115DE, - 0x116330001163B, - 0x1163D0001163E, - 0x1163F00011641, - 0x116AB000116AC, - 0x116AD000116AE, - 0x116B0000116B6, - 0x116B7000116B8, - 0x1171D0001171E, - 0x1171F00011720, - 0x1172200011726, - 0x117270001172C, - 0x1182F00011838, - 0x118390001183B, - 0x1193B0001193D, - 0x1193E0001193F, - 0x1194300011944, - 0x119D4000119D8, - 0x119DA000119DC, - 0x119E0000119E1, - 0x11A0100011A0B, - 0x11A3300011A39, - 0x11A3B00011A3F, - 0x11A4700011A48, - 0x11A5100011A57, - 0x11A5900011A5C, - 0x11A8A00011A97, - 0x11A9800011A9A, - 0x11B6000011B61, - 0x11B6200011B65, - 0x11B6600011B67, - 0x11C3000011C37, - 0x11C3800011C3E, - 0x11C3F00011C40, - 0x11C9200011CA8, - 0x11CAA00011CB1, - 0x11CB200011CB4, - 0x11CB500011CB7, - 0x11D3100011D37, - 0x11D3A00011D3B, - 0x11D3C00011D3E, - 0x11D3F00011D46, - 0x11D4700011D48, - 0x11D9000011D92, - 0x11D9500011D96, - 0x11D9700011D98, - 0x11EF300011EF5, - 0x11F0000011F02, - 0x11F3600011F3B, - 0x11F4000011F41, - 0x11F4200011F43, - 0x11F5A00011F5B, - 0x1343000013441, - 0x1344700013456, - 0x1611E0001612A, - 0x1612D00016130, - 0x16AF000016AF5, - 0x16B3000016B37, - 0x16F4F00016F50, - 0x16F8F00016F93, - 0x16FE400016FE5, - 0x1BC9D0001BC9F, - 0x1BCA00001BCA4, - 0x1CF000001CF2E, - 0x1CF300001CF47, - 0x1D1670001D16A, - 0x1D1730001D183, - 0x1D1850001D18C, - 0x1D1AA0001D1AE, - 0x1D2420001D245, - 0x1DA000001DA37, - 0x1DA3B0001DA6D, - 0x1DA750001DA76, - 0x1DA840001DA85, - 0x1DA9B0001DAA0, - 0x1DAA10001DAB0, - 0x1E0000001E007, - 0x1E0080001E019, - 0x1E01B0001E022, - 0x1E0230001E025, - 0x1E0260001E02B, - 0x1E08F0001E090, - 0x1E1300001E137, - 0x1E2AE0001E2AF, - 0x1E2EC0001E2F0, - 0x1E4EC0001E4F0, - 0x1E5EE0001E5F0, - 0x1E6E30001E6E4, - 0x1E6E60001E6E7, - 0x1E6EE0001E6F0, - 0x1E6F50001E6F6, - 0x1E8D00001E8D7, - 0x1E9440001E94C, - 0xE0001000E0002, - 0xE0020000E0080, - 0xE0100000E01F0, - ), -} - - -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, - 0x56000000587, - 0x58800000589, - 0x591000005BE, - 0x5BF000005C0, - 0x5C1000005C3, - 0x5C4000005C6, - 0x5C7000005C8, - 0x5D0000005EB, - 0x5EF000005F3, - 0x6100000061B, - 0x62000000640, - 0x64100000660, - 0x66E00000675, - 0x679000006D4, - 0x6D5000006DD, - 0x6DF000006E9, - 0x6EA000006F0, - 0x6FA00000700, - 0x7100000074B, - 0x74D000007B2, - 0x7C0000007F6, - 0x7FD000007FE, - 0x8000000082E, - 0x8400000085C, - 0x8600000086B, - 0x87000000888, - 0x88900000890, - 0x897000008E2, - 0x8E300000958, - 0x96000000964, - 0x96600000970, - 0x97100000984, - 0x9850000098D, - 0x98F00000991, - 0x993000009A9, - 0x9AA000009B1, - 0x9B2000009B3, - 0x9B6000009BA, - 0x9BC000009C5, - 0x9C7000009C9, - 0x9CB000009CF, - 0x9D7000009D8, - 0x9E0000009E4, - 0x9E6000009F2, - 0x9FC000009FD, - 0x9FE000009FF, - 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, - 0xB5500000B58, - 0xB5F00000B64, - 0xB6600000B70, - 0xB7100000B72, - 0xB8200000B84, - 0xB8500000B8B, - 0xB8E00000B91, - 0xB9200000B96, - 0xB9900000B9B, - 0xB9C00000B9D, - 0xB9E00000BA0, - 0xBA300000BA5, - 0xBA800000BAB, - 0xBAE00000BBA, - 0xBBE00000BC3, - 0xBC600000BC9, - 0xBCA00000BCE, - 0xBD000000BD1, - 0xBD700000BD8, - 0xBE600000BF0, - 0xC0000000C0D, - 0xC0E00000C11, - 0xC1200000C29, - 0xC2A00000C3A, - 0xC3C00000C45, - 0xC4600000C49, - 0xC4A00000C4E, - 0xC5500000C57, - 0xC5800000C5B, - 0xC5C00000C5E, - 0xC6000000C64, - 0xC6600000C70, - 0xC8000000C84, - 0xC8500000C8D, - 0xC8E00000C91, - 0xC9200000CA9, - 0xCAA00000CB4, - 0xCB500000CBA, - 0xCBC00000CC5, - 0xCC600000CC9, - 0xCCA00000CCE, - 0xCD500000CD7, - 0xCDC00000CDF, - 0xCE000000CE4, - 0xCE600000CF0, - 0xCF100000CF4, - 0xD0000000D0D, - 0xD0E00000D11, - 0xD1200000D45, - 0xD4600000D49, - 0xD4A00000D4F, - 0xD5400000D58, - 0xD5F00000D64, - 0xD6600000D70, - 0xD7A00000D80, - 0xD8100000D84, - 0xD8500000D97, - 0xD9A00000DB2, - 0xDB300000DBC, - 0xDBD00000DBE, - 0xDC000000DC7, - 0xDCA00000DCB, - 0xDCF00000DD5, - 0xDD600000DD7, - 0xDD800000DE0, - 0xDE600000DF0, - 0xDF200000DF4, - 0xE0100000E33, - 0xE3400000E3B, - 0xE4000000E4F, - 0xE5000000E5A, - 0xE8100000E83, - 0xE8400000E85, - 0xE8600000E8B, - 0xE8C00000EA4, - 0xEA500000EA6, - 0xEA700000EB3, - 0xEB400000EBE, - 0xEC000000EC5, - 0xEC600000EC7, - 0xEC800000ECF, - 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, - 0x170000001716, - 0x171F00001735, - 0x174000001754, - 0x17600000176D, - 0x176E00001771, - 0x177200001774, - 0x1780000017B4, - 0x17B6000017D4, - 0x17D7000017D8, - 0x17DC000017DE, - 0x17E0000017EA, - 0x18100000181A, - 0x182000001879, - 0x1880000018AB, - 0x18B0000018F6, - 0x19000000191F, - 0x19200000192C, - 0x19300000193C, - 0x19460000196E, - 0x197000001975, - 0x1980000019AC, - 0x19B0000019CA, - 0x19D0000019DA, - 0x1A0000001A1C, - 0x1A2000001A5F, - 0x1A6000001A7D, - 0x1A7F00001A8A, - 0x1A9000001A9A, - 0x1AA700001AA8, - 0x1AB000001ABE, - 0x1ABF00001ADE, - 0x1AE000001AEC, - 0x1B0000001B4D, - 0x1B5000001B5A, - 0x1B6B00001B74, - 0x1B8000001BF4, - 0x1C0000001C38, - 0x1C4000001C4A, - 0x1C4D00001C7E, - 0x1C8A00001C8B, - 0x1CD000001CD3, - 0x1CD400001CFB, - 0x1D0000001D2C, - 0x1D2F00001D30, - 0x1D3B00001D3C, - 0x1D4E00001D4F, - 0x1D6B00001D78, - 0x1D7900001D9B, - 0x1DC000001E00, - 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, - 0x2C3000002C60, - 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, - 0x310500003130, - 0x31A0000031C0, - 0x31F000003200, - 0x340000004DC0, - 0x4E000000A48D, - 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, - 0xA7AF0000A7B0, - 0xA7B50000A7B6, - 0xA7B70000A7B8, - 0xA7B90000A7BA, - 0xA7BB0000A7BC, - 0xA7BD0000A7BE, - 0xA7BF0000A7C0, - 0xA7C10000A7C2, - 0xA7C30000A7C4, - 0xA7C80000A7C9, - 0xA7CA0000A7CB, - 0xA7CD0000A7CE, - 0xA7CF0000A7D0, - 0xA7D10000A7D2, - 0xA7D30000A7D4, - 0xA7D50000A7D6, - 0xA7D70000A7D8, - 0xA7D90000A7DA, - 0xA7DB0000A7DC, - 0xA7F60000A7F8, - 0xA7FA0000A828, - 0xA82C0000A82D, - 0xA8400000A874, - 0xA8800000A8C6, - 0xA8D00000A8DA, - 0xA8E00000A8F8, - 0xA8FB0000A8FC, - 0xA8FD0000A92E, - 0xA9300000A954, - 0xA9800000A9C1, - 0xA9CF0000A9DA, - 0xA9E00000A9FF, - 0xAA000000AA37, - 0xAA400000AA4E, - 0xAA500000AA5A, - 0xAA600000AA77, - 0xAA7A0000AAC3, - 0xAADB0000AADE, - 0xAAE00000AAF0, - 0xAAF20000AAF7, - 0xAB010000AB07, - 0xAB090000AB0F, - 0xAB110000AB17, - 0xAB200000AB27, - 0xAB280000AB2F, - 0xAB300000AB5B, - 0xAB600000AB69, - 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, - 0x10597000105A2, - 0x105A3000105B2, - 0x105B3000105BA, - 0x105BB000105BD, - 0x105C0000105F4, - 0x1060000010737, - 0x1074000010756, - 0x1076000010768, - 0x1078000010781, - 0x1080000010806, - 0x1080800010809, - 0x1080A00010836, - 0x1083700010839, - 0x1083C0001083D, - 0x1083F00010856, - 0x1086000010877, - 0x108800001089F, - 0x108E0000108F3, - 0x108F4000108F6, - 0x1090000010916, - 0x109200001093A, - 0x109400001095A, - 0x10980000109B8, - 0x109BE000109C0, - 0x10A0000010A04, - 0x10A0500010A07, - 0x10A0C00010A14, - 0x10A1500010A18, - 0x10A1900010A36, - 0x10A3800010A3B, - 0x10A3F00010A40, - 0x10A6000010A7D, - 0x10A8000010A9D, - 0x10AC000010AC8, - 0x10AC900010AE7, - 0x10B0000010B36, - 0x10B4000010B56, - 0x10B6000010B73, - 0x10B8000010B92, - 0x10C0000010C49, - 0x10CC000010CF3, - 0x10D0000010D28, - 0x10D3000010D3A, - 0x10D4000010D50, - 0x10D6900010D6E, - 0x10D6F00010D86, - 0x10E8000010EAA, - 0x10EAB00010EAD, - 0x10EB000010EB2, - 0x10EC200010EC8, - 0x10EFA00010F1D, - 0x10F2700010F28, - 0x10F3000010F51, - 0x10F7000010F86, - 0x10FB000010FC5, - 0x10FE000010FF7, - 0x1100000011047, - 0x1106600011076, - 0x1107F000110BB, - 0x110C2000110C3, - 0x110D0000110E9, - 0x110F0000110FA, - 0x1110000011135, - 0x1113600011140, - 0x1114400011148, - 0x1115000011174, - 0x1117600011177, - 0x11180000111C5, - 0x111C9000111CD, - 0x111CE000111DB, - 0x111DC000111DD, - 0x1120000011212, - 0x1121300011238, - 0x1123E00011242, - 0x1128000011287, - 0x1128800011289, - 0x1128A0001128E, - 0x1128F0001129E, - 0x1129F000112A9, - 0x112B0000112EB, - 0x112F0000112FA, - 0x1130000011304, - 0x113050001130D, - 0x1130F00011311, - 0x1131300011329, - 0x1132A00011331, - 0x1133200011334, - 0x113350001133A, - 0x1133B00011345, - 0x1134700011349, - 0x1134B0001134E, - 0x1135000011351, - 0x1135700011358, - 0x1135D00011364, - 0x113660001136D, - 0x1137000011375, - 0x113800001138A, - 0x1138B0001138C, - 0x1138E0001138F, - 0x11390000113B6, - 0x113B7000113C1, - 0x113C2000113C3, - 0x113C5000113C6, - 0x113C7000113CB, - 0x113CC000113D4, - 0x113E1000113E3, - 0x114000001144B, - 0x114500001145A, - 0x1145E00011462, - 0x11480000114C6, - 0x114C7000114C8, - 0x114D0000114DA, - 0x11580000115B6, - 0x115B8000115C1, - 0x115D8000115DE, - 0x1160000011641, - 0x1164400011645, - 0x116500001165A, - 0x11680000116B9, - 0x116C0000116CA, - 0x116D0000116E4, - 0x117000001171B, - 0x1171D0001172C, - 0x117300001173A, - 0x1174000011747, - 0x118000001183B, - 0x118C0000118EA, - 0x118FF00011907, - 0x119090001190A, - 0x1190C00011914, - 0x1191500011917, - 0x1191800011936, - 0x1193700011939, - 0x1193B00011944, - 0x119500001195A, - 0x119A0000119A8, - 0x119AA000119D8, - 0x119DA000119E2, - 0x119E3000119E5, - 0x11A0000011A3F, - 0x11A4700011A48, - 0x11A5000011A9A, - 0x11A9D00011A9E, - 0x11AB000011AF9, - 0x11B6000011B68, - 0x11BC000011BE1, - 0x11BF000011BFA, - 0x11C0000011C09, - 0x11C0A00011C37, - 0x11C3800011C41, - 0x11C5000011C5A, - 0x11C7200011C90, - 0x11C9200011CA8, - 0x11CA900011CB7, - 0x11D0000011D07, - 0x11D0800011D0A, - 0x11D0B00011D37, - 0x11D3A00011D3B, - 0x11D3C00011D3E, - 0x11D3F00011D48, - 0x11D5000011D5A, - 0x11D6000011D66, - 0x11D6700011D69, - 0x11D6A00011D8F, - 0x11D9000011D92, - 0x11D9300011D99, - 0x11DA000011DAA, - 0x11DB000011DDC, - 0x11DE000011DEA, - 0x11EE000011EF7, - 0x11F0000011F11, - 0x11F1200011F3B, - 0x11F3E00011F43, - 0x11F5000011F5B, - 0x11FB000011FB1, - 0x120000001239A, - 0x1248000012544, - 0x12F9000012FF1, - 0x1300000013430, - 0x1344000013456, - 0x13460000143FB, - 0x1440000014647, - 0x161000001613A, - 0x1680000016A39, - 0x16A4000016A5F, - 0x16A6000016A6A, - 0x16A7000016ABF, - 0x16AC000016ACA, - 0x16AD000016AEE, - 0x16AF000016AF5, - 0x16B0000016B37, - 0x16B4000016B44, - 0x16B5000016B5A, - 0x16B6300016B78, - 0x16B7D00016B90, - 0x16D4000016D6D, - 0x16D7000016D7A, - 0x16E6000016E80, - 0x16EBB00016ED4, - 0x16F0000016F4B, - 0x16F4F00016F88, - 0x16F8F00016FA0, - 0x16FE000016FE2, - 0x16FE300016FE5, - 0x16FF000016FF4, - 0x1700000018CD6, - 0x18CFF00018D1F, - 0x18D8000018DF3, - 0x1AFF00001AFF4, - 0x1AFF50001AFFC, - 0x1AFFD0001AFFF, - 0x1B0000001B123, - 0x1B1320001B133, - 0x1B1500001B153, - 0x1B1550001B156, - 0x1B1640001B168, - 0x1B1700001B2FC, - 0x1BC000001BC6B, - 0x1BC700001BC7D, - 0x1BC800001BC89, - 0x1BC900001BC9A, - 0x1BC9D0001BC9F, - 0x1CF000001CF2E, - 0x1CF300001CF47, - 0x1DA000001DA37, - 0x1DA3B0001DA6D, - 0x1DA750001DA76, - 0x1DA840001DA85, - 0x1DA9B0001DAA0, - 0x1DAA10001DAB0, - 0x1DF000001DF1F, - 0x1DF250001DF2B, - 0x1E0000001E007, - 0x1E0080001E019, - 0x1E01B0001E022, - 0x1E0230001E025, - 0x1E0260001E02B, - 0x1E08F0001E090, - 0x1E1000001E12D, - 0x1E1300001E13E, - 0x1E1400001E14A, - 0x1E14E0001E14F, - 0x1E2900001E2AF, - 0x1E2C00001E2FA, - 0x1E4D00001E4FA, - 0x1E5D00001E5FB, - 0x1E6C00001E6DF, - 0x1E6E00001E6F6, - 0x1E6FE0001E700, - 0x1E7E00001E7E7, - 0x1E7E80001E7EC, - 0x1E7ED0001E7EF, - 0x1E7F00001E7FF, - 0x1E8000001E8C5, - 0x1E8D00001E8D7, - 0x1E9220001E94C, - 0x1E9500001E95A, - 0x200000002A6E0, - 0x2A7000002B81E, - 0x2B8200002CEAE, - 0x2CEB00002EBE1, - 0x2EBF00002EE5E, - 0x300000003134B, - 0x313500003347A, - ), - "CONTEXTJ": (0x200C0000200E,), - "CONTEXTO": ( - 0xB7000000B8, - 0x37500000376, - 0x5F3000005F5, - 0x6600000066A, - 0x6F0000006FA, - 0x30FB000030FC, - ), -} diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/idna/intranges.py b/venv/lib/python3.11/site-packages/pip/_vendor/idna/intranges.py deleted file mode 100755 index 19d7781..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/idna/intranges.py +++ /dev/null @@ -1,55 +0,0 @@ -""" -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_: list[int]) -> tuple[int, ...]: - """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) and 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: int, end: int) -> int: - return (start << 32) | end - - -def _decode_range(r: int) -> tuple[int, int]: - return (r >> 32), (r & ((1 << 32) - 1)) - - -def intranges_contain(int_: int, ranges: tuple[int, ...]) -> bool: - """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.11/site-packages/pip/_vendor/idna/package_data.py b/venv/lib/python3.11/site-packages/pip/_vendor/idna/package_data.py deleted file mode 100755 index 94e4039..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/idna/package_data.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = "3.18" diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/idna/py.typed b/venv/lib/python3.11/site-packages/pip/_vendor/idna/py.typed deleted file mode 100755 index e69de29..0000000 diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/idna/uts46data.py b/venv/lib/python3.11/site-packages/pip/_vendor/idna/uts46data.py deleted file mode 100755 index f2d931f..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/idna/uts46data.py +++ /dev/null @@ -1,16896 +0,0 @@ -# This file is automatically generated by tools/idna-data - -from array import array -from typing import Optional - -"""IDNA Mapping Table from UTS46.""" - - -__version__ = "17.0.0" - -uts46_starts: "array[int]" = array( - "I", - ( - 0x0, - 0x1, - 0x2, - 0x3, - 0x4, - 0x5, - 0x6, - 0x7, - 0x8, - 0x9, - 0xA, - 0xB, - 0xC, - 0xD, - 0xE, - 0xF, - 0x10, - 0x11, - 0x12, - 0x13, - 0x14, - 0x15, - 0x16, - 0x17, - 0x18, - 0x19, - 0x1A, - 0x1B, - 0x1C, - 0x1D, - 0x1E, - 0x1F, - 0x20, - 0x21, - 0x22, - 0x23, - 0x24, - 0x25, - 0x26, - 0x27, - 0x28, - 0x29, - 0x2A, - 0x2B, - 0x2C, - 0x2D, - 0x2E, - 0x2F, - 0x30, - 0x31, - 0x32, - 0x33, - 0x34, - 0x35, - 0x36, - 0x37, - 0x38, - 0x39, - 0x3A, - 0x3B, - 0x3C, - 0x3D, - 0x3E, - 0x3F, - 0x40, - 0x41, - 0x42, - 0x43, - 0x44, - 0x45, - 0x46, - 0x47, - 0x48, - 0x49, - 0x4A, - 0x4B, - 0x4C, - 0x4D, - 0x4E, - 0x4F, - 0x50, - 0x51, - 0x52, - 0x53, - 0x54, - 0x55, - 0x56, - 0x57, - 0x58, - 0x59, - 0x5A, - 0x5B, - 0x5C, - 0x5D, - 0x5E, - 0x5F, - 0x60, - 0x61, - 0x62, - 0x63, - 0x64, - 0x65, - 0x66, - 0x67, - 0x68, - 0x69, - 0x6A, - 0x6B, - 0x6C, - 0x6D, - 0x6E, - 0x6F, - 0x70, - 0x71, - 0x72, - 0x73, - 0x74, - 0x75, - 0x76, - 0x77, - 0x78, - 0x79, - 0x7A, - 0x7B, - 0x7C, - 0x7D, - 0x7E, - 0x7F, - 0x80, - 0x81, - 0x82, - 0x83, - 0x84, - 0x85, - 0x86, - 0x87, - 0x88, - 0x89, - 0x8A, - 0x8B, - 0x8C, - 0x8D, - 0x8E, - 0x8F, - 0x90, - 0x91, - 0x92, - 0x93, - 0x94, - 0x95, - 0x96, - 0x97, - 0x98, - 0x99, - 0x9A, - 0x9B, - 0x9C, - 0x9D, - 0x9E, - 0x9F, - 0xA0, - 0xA1, - 0xA2, - 0xA3, - 0xA4, - 0xA5, - 0xA6, - 0xA7, - 0xA8, - 0xA9, - 0xAA, - 0xAB, - 0xAC, - 0xAD, - 0xAE, - 0xAF, - 0xB0, - 0xB1, - 0xB2, - 0xB3, - 0xB4, - 0xB5, - 0xB6, - 0xB7, - 0xB8, - 0xB9, - 0xBA, - 0xBB, - 0xBC, - 0xBD, - 0xBE, - 0xBF, - 0xC0, - 0xC1, - 0xC2, - 0xC3, - 0xC4, - 0xC5, - 0xC6, - 0xC7, - 0xC8, - 0xC9, - 0xCA, - 0xCB, - 0xCC, - 0xCD, - 0xCE, - 0xCF, - 0xD0, - 0xD1, - 0xD2, - 0xD3, - 0xD4, - 0xD5, - 0xD6, - 0xD7, - 0xD8, - 0xD9, - 0xDA, - 0xDB, - 0xDC, - 0xDD, - 0xDE, - 0xDF, - 0xE0, - 0xE1, - 0xE2, - 0xE3, - 0xE4, - 0xE5, - 0xE6, - 0xE7, - 0xE8, - 0xE9, - 0xEA, - 0xEB, - 0xEC, - 0xED, - 0xEE, - 0xEF, - 0xF0, - 0xF1, - 0xF2, - 0xF3, - 0xF4, - 0xF5, - 0xF6, - 0xF7, - 0xF8, - 0xF9, - 0xFA, - 0xFB, - 0xFC, - 0xFD, - 0xFE, - 0xFF, - 0x100, - 0x101, - 0x102, - 0x103, - 0x104, - 0x105, - 0x106, - 0x107, - 0x108, - 0x109, - 0x10A, - 0x10B, - 0x10C, - 0x10D, - 0x10E, - 0x10F, - 0x110, - 0x111, - 0x112, - 0x113, - 0x114, - 0x115, - 0x116, - 0x117, - 0x118, - 0x119, - 0x11A, - 0x11B, - 0x11C, - 0x11D, - 0x11E, - 0x11F, - 0x120, - 0x121, - 0x122, - 0x123, - 0x124, - 0x125, - 0x126, - 0x127, - 0x128, - 0x129, - 0x12A, - 0x12B, - 0x12C, - 0x12D, - 0x12E, - 0x12F, - 0x130, - 0x131, - 0x132, - 0x134, - 0x135, - 0x136, - 0x137, - 0x139, - 0x13A, - 0x13B, - 0x13C, - 0x13D, - 0x13E, - 0x13F, - 0x141, - 0x142, - 0x143, - 0x144, - 0x145, - 0x146, - 0x147, - 0x148, - 0x149, - 0x14A, - 0x14B, - 0x14C, - 0x14D, - 0x14E, - 0x14F, - 0x150, - 0x151, - 0x152, - 0x153, - 0x154, - 0x155, - 0x156, - 0x157, - 0x158, - 0x159, - 0x15A, - 0x15B, - 0x15C, - 0x15D, - 0x15E, - 0x15F, - 0x160, - 0x161, - 0x162, - 0x163, - 0x164, - 0x165, - 0x166, - 0x167, - 0x168, - 0x169, - 0x16A, - 0x16B, - 0x16C, - 0x16D, - 0x16E, - 0x16F, - 0x170, - 0x171, - 0x172, - 0x173, - 0x174, - 0x175, - 0x176, - 0x177, - 0x178, - 0x179, - 0x17A, - 0x17B, - 0x17C, - 0x17D, - 0x17E, - 0x17F, - 0x180, - 0x181, - 0x182, - 0x183, - 0x184, - 0x185, - 0x186, - 0x187, - 0x188, - 0x189, - 0x18A, - 0x18B, - 0x18C, - 0x18E, - 0x18F, - 0x190, - 0x191, - 0x192, - 0x193, - 0x194, - 0x195, - 0x196, - 0x197, - 0x198, - 0x199, - 0x19C, - 0x19D, - 0x19E, - 0x19F, - 0x1A0, - 0x1A1, - 0x1A2, - 0x1A3, - 0x1A4, - 0x1A5, - 0x1A6, - 0x1A7, - 0x1A8, - 0x1A9, - 0x1AA, - 0x1AC, - 0x1AD, - 0x1AE, - 0x1AF, - 0x1B0, - 0x1B1, - 0x1B2, - 0x1B3, - 0x1B4, - 0x1B5, - 0x1B6, - 0x1B7, - 0x1B8, - 0x1B9, - 0x1BC, - 0x1BD, - 0x1C4, - 0x1C7, - 0x1CA, - 0x1CD, - 0x1CE, - 0x1CF, - 0x1D0, - 0x1D1, - 0x1D2, - 0x1D3, - 0x1D4, - 0x1D5, - 0x1D6, - 0x1D7, - 0x1D8, - 0x1D9, - 0x1DA, - 0x1DB, - 0x1DC, - 0x1DE, - 0x1DF, - 0x1E0, - 0x1E1, - 0x1E2, - 0x1E3, - 0x1E4, - 0x1E5, - 0x1E6, - 0x1E7, - 0x1E8, - 0x1E9, - 0x1EA, - 0x1EB, - 0x1EC, - 0x1ED, - 0x1EE, - 0x1EF, - 0x1F1, - 0x1F4, - 0x1F5, - 0x1F6, - 0x1F7, - 0x1F8, - 0x1F9, - 0x1FA, - 0x1FB, - 0x1FC, - 0x1FD, - 0x1FE, - 0x1FF, - 0x200, - 0x201, - 0x202, - 0x203, - 0x204, - 0x205, - 0x206, - 0x207, - 0x208, - 0x209, - 0x20A, - 0x20B, - 0x20C, - 0x20D, - 0x20E, - 0x20F, - 0x210, - 0x211, - 0x212, - 0x213, - 0x214, - 0x215, - 0x216, - 0x217, - 0x218, - 0x219, - 0x21A, - 0x21B, - 0x21C, - 0x21D, - 0x21E, - 0x21F, - 0x220, - 0x221, - 0x222, - 0x223, - 0x224, - 0x225, - 0x226, - 0x227, - 0x228, - 0x229, - 0x22A, - 0x22B, - 0x22C, - 0x22D, - 0x22E, - 0x22F, - 0x230, - 0x231, - 0x232, - 0x233, - 0x23A, - 0x23B, - 0x23C, - 0x23D, - 0x23E, - 0x23F, - 0x241, - 0x242, - 0x243, - 0x244, - 0x245, - 0x246, - 0x247, - 0x248, - 0x249, - 0x24A, - 0x24B, - 0x24C, - 0x24D, - 0x24E, - 0x24F, - 0x2B0, - 0x2B1, - 0x2B2, - 0x2B3, - 0x2B4, - 0x2B5, - 0x2B6, - 0x2B7, - 0x2B8, - 0x2B9, - 0x2D8, - 0x2D9, - 0x2DA, - 0x2DB, - 0x2DC, - 0x2DD, - 0x2DE, - 0x2E0, - 0x2E1, - 0x2E2, - 0x2E3, - 0x2E4, - 0x2E5, - 0x340, - 0x341, - 0x342, - 0x343, - 0x344, - 0x345, - 0x346, - 0x34F, - 0x350, - 0x370, - 0x371, - 0x372, - 0x373, - 0x374, - 0x375, - 0x376, - 0x377, - 0x378, - 0x37A, - 0x37B, - 0x37E, - 0x37F, - 0x380, - 0x384, - 0x385, - 0x386, - 0x387, - 0x388, - 0x389, - 0x38A, - 0x38B, - 0x38C, - 0x38D, - 0x38E, - 0x38F, - 0x390, - 0x391, - 0x392, - 0x393, - 0x394, - 0x395, - 0x396, - 0x397, - 0x398, - 0x399, - 0x39A, - 0x39B, - 0x39C, - 0x39D, - 0x39E, - 0x39F, - 0x3A0, - 0x3A1, - 0x3A2, - 0x3A3, - 0x3A4, - 0x3A5, - 0x3A6, - 0x3A7, - 0x3A8, - 0x3A9, - 0x3AA, - 0x3AB, - 0x3AC, - 0x3C2, - 0x3C3, - 0x3CF, - 0x3D0, - 0x3D1, - 0x3D2, - 0x3D3, - 0x3D4, - 0x3D5, - 0x3D6, - 0x3D7, - 0x3D8, - 0x3D9, - 0x3DA, - 0x3DB, - 0x3DC, - 0x3DD, - 0x3DE, - 0x3DF, - 0x3E0, - 0x3E1, - 0x3E2, - 0x3E3, - 0x3E4, - 0x3E5, - 0x3E6, - 0x3E7, - 0x3E8, - 0x3E9, - 0x3EA, - 0x3EB, - 0x3EC, - 0x3ED, - 0x3EE, - 0x3EF, - 0x3F0, - 0x3F1, - 0x3F2, - 0x3F3, - 0x3F4, - 0x3F5, - 0x3F6, - 0x3F7, - 0x3F8, - 0x3F9, - 0x3FA, - 0x3FB, - 0x3FD, - 0x3FE, - 0x3FF, - 0x400, - 0x401, - 0x402, - 0x403, - 0x404, - 0x405, - 0x406, - 0x407, - 0x408, - 0x409, - 0x40A, - 0x40B, - 0x40C, - 0x40D, - 0x40E, - 0x40F, - 0x410, - 0x411, - 0x412, - 0x413, - 0x414, - 0x415, - 0x416, - 0x417, - 0x418, - 0x419, - 0x41A, - 0x41B, - 0x41C, - 0x41D, - 0x41E, - 0x41F, - 0x420, - 0x421, - 0x422, - 0x423, - 0x424, - 0x425, - 0x426, - 0x427, - 0x428, - 0x429, - 0x42A, - 0x42B, - 0x42C, - 0x42D, - 0x42E, - 0x42F, - 0x430, - 0x460, - 0x461, - 0x462, - 0x463, - 0x464, - 0x465, - 0x466, - 0x467, - 0x468, - 0x469, - 0x46A, - 0x46B, - 0x46C, - 0x46D, - 0x46E, - 0x46F, - 0x470, - 0x471, - 0x472, - 0x473, - 0x474, - 0x475, - 0x476, - 0x477, - 0x478, - 0x479, - 0x47A, - 0x47B, - 0x47C, - 0x47D, - 0x47E, - 0x47F, - 0x480, - 0x481, - 0x48A, - 0x48B, - 0x48C, - 0x48D, - 0x48E, - 0x48F, - 0x490, - 0x491, - 0x492, - 0x493, - 0x494, - 0x495, - 0x496, - 0x497, - 0x498, - 0x499, - 0x49A, - 0x49B, - 0x49C, - 0x49D, - 0x49E, - 0x49F, - 0x4A0, - 0x4A1, - 0x4A2, - 0x4A3, - 0x4A4, - 0x4A5, - 0x4A6, - 0x4A7, - 0x4A8, - 0x4A9, - 0x4AA, - 0x4AB, - 0x4AC, - 0x4AD, - 0x4AE, - 0x4AF, - 0x4B0, - 0x4B1, - 0x4B2, - 0x4B3, - 0x4B4, - 0x4B5, - 0x4B6, - 0x4B7, - 0x4B8, - 0x4B9, - 0x4BA, - 0x4BB, - 0x4BC, - 0x4BD, - 0x4BE, - 0x4BF, - 0x4C0, - 0x4C1, - 0x4C2, - 0x4C3, - 0x4C4, - 0x4C5, - 0x4C6, - 0x4C7, - 0x4C8, - 0x4C9, - 0x4CA, - 0x4CB, - 0x4CC, - 0x4CD, - 0x4CE, - 0x4D0, - 0x4D1, - 0x4D2, - 0x4D3, - 0x4D4, - 0x4D5, - 0x4D6, - 0x4D7, - 0x4D8, - 0x4D9, - 0x4DA, - 0x4DB, - 0x4DC, - 0x4DD, - 0x4DE, - 0x4DF, - 0x4E0, - 0x4E1, - 0x4E2, - 0x4E3, - 0x4E4, - 0x4E5, - 0x4E6, - 0x4E7, - 0x4E8, - 0x4E9, - 0x4EA, - 0x4EB, - 0x4EC, - 0x4ED, - 0x4EE, - 0x4EF, - 0x4F0, - 0x4F1, - 0x4F2, - 0x4F3, - 0x4F4, - 0x4F5, - 0x4F6, - 0x4F7, - 0x4F8, - 0x4F9, - 0x4FA, - 0x4FB, - 0x4FC, - 0x4FD, - 0x4FE, - 0x4FF, - 0x500, - 0x501, - 0x502, - 0x503, - 0x504, - 0x505, - 0x506, - 0x507, - 0x508, - 0x509, - 0x50A, - 0x50B, - 0x50C, - 0x50D, - 0x50E, - 0x50F, - 0x510, - 0x511, - 0x512, - 0x513, - 0x514, - 0x515, - 0x516, - 0x517, - 0x518, - 0x519, - 0x51A, - 0x51B, - 0x51C, - 0x51D, - 0x51E, - 0x51F, - 0x520, - 0x521, - 0x522, - 0x523, - 0x524, - 0x525, - 0x526, - 0x527, - 0x528, - 0x529, - 0x52A, - 0x52B, - 0x52C, - 0x52D, - 0x52E, - 0x52F, - 0x530, - 0x531, - 0x532, - 0x533, - 0x534, - 0x535, - 0x536, - 0x537, - 0x538, - 0x539, - 0x53A, - 0x53B, - 0x53C, - 0x53D, - 0x53E, - 0x53F, - 0x540, - 0x541, - 0x542, - 0x543, - 0x544, - 0x545, - 0x546, - 0x547, - 0x548, - 0x549, - 0x54A, - 0x54B, - 0x54C, - 0x54D, - 0x54E, - 0x54F, - 0x550, - 0x551, - 0x552, - 0x553, - 0x554, - 0x555, - 0x556, - 0x557, - 0x559, - 0x587, - 0x588, - 0x58B, - 0x58D, - 0x590, - 0x591, - 0x5C8, - 0x5D0, - 0x5EB, - 0x5EF, - 0x5F5, - 0x606, - 0x61C, - 0x61D, - 0x675, - 0x676, - 0x677, - 0x678, - 0x679, - 0x6DD, - 0x6DE, - 0x70E, - 0x710, - 0x74B, - 0x74D, - 0x7B2, - 0x7C0, - 0x7FB, - 0x7FD, - 0x82E, - 0x830, - 0x83F, - 0x840, - 0x85C, - 0x85E, - 0x85F, - 0x860, - 0x86B, - 0x870, - 0x890, - 0x897, - 0x8E2, - 0x8E3, - 0x958, - 0x959, - 0x95A, - 0x95B, - 0x95C, - 0x95D, - 0x95E, - 0x95F, - 0x960, - 0x984, - 0x985, - 0x98D, - 0x98F, - 0x991, - 0x993, - 0x9A9, - 0x9AA, - 0x9B1, - 0x9B2, - 0x9B3, - 0x9B6, - 0x9BA, - 0x9BC, - 0x9C5, - 0x9C7, - 0x9C9, - 0x9CB, - 0x9CF, - 0x9D7, - 0x9D8, - 0x9DC, - 0x9DD, - 0x9DE, - 0x9DF, - 0x9E0, - 0x9E4, - 0x9E6, - 0x9FF, - 0xA01, - 0xA04, - 0xA05, - 0xA0B, - 0xA0F, - 0xA11, - 0xA13, - 0xA29, - 0xA2A, - 0xA31, - 0xA32, - 0xA33, - 0xA34, - 0xA35, - 0xA36, - 0xA37, - 0xA38, - 0xA3A, - 0xA3C, - 0xA3D, - 0xA3E, - 0xA43, - 0xA47, - 0xA49, - 0xA4B, - 0xA4E, - 0xA51, - 0xA52, - 0xA59, - 0xA5A, - 0xA5B, - 0xA5C, - 0xA5D, - 0xA5E, - 0xA5F, - 0xA66, - 0xA77, - 0xA81, - 0xA84, - 0xA85, - 0xA8E, - 0xA8F, - 0xA92, - 0xA93, - 0xAA9, - 0xAAA, - 0xAB1, - 0xAB2, - 0xAB4, - 0xAB5, - 0xABA, - 0xABC, - 0xAC6, - 0xAC7, - 0xACA, - 0xACB, - 0xACE, - 0xAD0, - 0xAD1, - 0xAE0, - 0xAE4, - 0xAE6, - 0xAF2, - 0xAF9, - 0xB00, - 0xB01, - 0xB04, - 0xB05, - 0xB0D, - 0xB0F, - 0xB11, - 0xB13, - 0xB29, - 0xB2A, - 0xB31, - 0xB32, - 0xB34, - 0xB35, - 0xB3A, - 0xB3C, - 0xB45, - 0xB47, - 0xB49, - 0xB4B, - 0xB4E, - 0xB55, - 0xB58, - 0xB5C, - 0xB5D, - 0xB5E, - 0xB5F, - 0xB64, - 0xB66, - 0xB78, - 0xB82, - 0xB84, - 0xB85, - 0xB8B, - 0xB8E, - 0xB91, - 0xB92, - 0xB96, - 0xB99, - 0xB9B, - 0xB9C, - 0xB9D, - 0xB9E, - 0xBA0, - 0xBA3, - 0xBA5, - 0xBA8, - 0xBAB, - 0xBAE, - 0xBBA, - 0xBBE, - 0xBC3, - 0xBC6, - 0xBC9, - 0xBCA, - 0xBCE, - 0xBD0, - 0xBD1, - 0xBD7, - 0xBD8, - 0xBE6, - 0xBFB, - 0xC00, - 0xC0D, - 0xC0E, - 0xC11, - 0xC12, - 0xC29, - 0xC2A, - 0xC3A, - 0xC3C, - 0xC45, - 0xC46, - 0xC49, - 0xC4A, - 0xC4E, - 0xC55, - 0xC57, - 0xC58, - 0xC5B, - 0xC5C, - 0xC5E, - 0xC60, - 0xC64, - 0xC66, - 0xC70, - 0xC77, - 0xC8D, - 0xC8E, - 0xC91, - 0xC92, - 0xCA9, - 0xCAA, - 0xCB4, - 0xCB5, - 0xCBA, - 0xCBC, - 0xCC5, - 0xCC6, - 0xCC9, - 0xCCA, - 0xCCE, - 0xCD5, - 0xCD7, - 0xCDC, - 0xCDF, - 0xCE0, - 0xCE4, - 0xCE6, - 0xCF0, - 0xCF1, - 0xCF4, - 0xD00, - 0xD0D, - 0xD0E, - 0xD11, - 0xD12, - 0xD45, - 0xD46, - 0xD49, - 0xD4A, - 0xD50, - 0xD54, - 0xD64, - 0xD66, - 0xD80, - 0xD81, - 0xD84, - 0xD85, - 0xD97, - 0xD9A, - 0xDB2, - 0xDB3, - 0xDBC, - 0xDBD, - 0xDBE, - 0xDC0, - 0xDC7, - 0xDCA, - 0xDCB, - 0xDCF, - 0xDD5, - 0xDD6, - 0xDD7, - 0xDD8, - 0xDE0, - 0xDE6, - 0xDF0, - 0xDF2, - 0xDF5, - 0xE01, - 0xE33, - 0xE34, - 0xE3B, - 0xE3F, - 0xE5C, - 0xE81, - 0xE83, - 0xE84, - 0xE85, - 0xE86, - 0xE8B, - 0xE8C, - 0xEA4, - 0xEA5, - 0xEA6, - 0xEA7, - 0xEB3, - 0xEB4, - 0xEBE, - 0xEC0, - 0xEC5, - 0xEC6, - 0xEC7, - 0xEC8, - 0xECF, - 0xED0, - 0xEDA, - 0xEDC, - 0xEDD, - 0xEDE, - 0xEE0, - 0xF00, - 0xF0C, - 0xF0D, - 0xF43, - 0xF44, - 0xF48, - 0xF49, - 0xF4D, - 0xF4E, - 0xF52, - 0xF53, - 0xF57, - 0xF58, - 0xF5C, - 0xF5D, - 0xF69, - 0xF6A, - 0xF6D, - 0xF71, - 0xF73, - 0xF74, - 0xF75, - 0xF76, - 0xF77, - 0xF78, - 0xF79, - 0xF7A, - 0xF81, - 0xF82, - 0xF93, - 0xF94, - 0xF98, - 0xF99, - 0xF9D, - 0xF9E, - 0xFA2, - 0xFA3, - 0xFA7, - 0xFA8, - 0xFAC, - 0xFAD, - 0xFB9, - 0xFBA, - 0xFBD, - 0xFBE, - 0xFCD, - 0xFCE, - 0xFDB, - 0x1000, - 0x10A0, - 0x10A1, - 0x10A2, - 0x10A3, - 0x10A4, - 0x10A5, - 0x10A6, - 0x10A7, - 0x10A8, - 0x10A9, - 0x10AA, - 0x10AB, - 0x10AC, - 0x10AD, - 0x10AE, - 0x10AF, - 0x10B0, - 0x10B1, - 0x10B2, - 0x10B3, - 0x10B4, - 0x10B5, - 0x10B6, - 0x10B7, - 0x10B8, - 0x10B9, - 0x10BA, - 0x10BB, - 0x10BC, - 0x10BD, - 0x10BE, - 0x10BF, - 0x10C0, - 0x10C1, - 0x10C2, - 0x10C3, - 0x10C4, - 0x10C5, - 0x10C6, - 0x10C7, - 0x10C8, - 0x10CD, - 0x10CE, - 0x10D0, - 0x10FC, - 0x10FD, - 0x115F, - 0x1161, - 0x1249, - 0x124A, - 0x124E, - 0x1250, - 0x1257, - 0x1258, - 0x1259, - 0x125A, - 0x125E, - 0x1260, - 0x1289, - 0x128A, - 0x128E, - 0x1290, - 0x12B1, - 0x12B2, - 0x12B6, - 0x12B8, - 0x12BF, - 0x12C0, - 0x12C1, - 0x12C2, - 0x12C6, - 0x12C8, - 0x12D7, - 0x12D8, - 0x1311, - 0x1312, - 0x1316, - 0x1318, - 0x135B, - 0x135D, - 0x137D, - 0x1380, - 0x139A, - 0x13A0, - 0x13F6, - 0x13F8, - 0x13F9, - 0x13FA, - 0x13FB, - 0x13FC, - 0x13FD, - 0x13FE, - 0x1400, - 0x1680, - 0x1681, - 0x169D, - 0x16A0, - 0x16F9, - 0x1700, - 0x1716, - 0x171F, - 0x1737, - 0x1740, - 0x1754, - 0x1760, - 0x176D, - 0x176E, - 0x1771, - 0x1772, - 0x1774, - 0x1780, - 0x17B4, - 0x17B6, - 0x17DE, - 0x17E0, - 0x17EA, - 0x17F0, - 0x17FA, - 0x1800, - 0x180B, - 0x1810, - 0x181A, - 0x1820, - 0x1879, - 0x1880, - 0x18AB, - 0x18B0, - 0x18F6, - 0x1900, - 0x191F, - 0x1920, - 0x192C, - 0x1930, - 0x193C, - 0x1940, - 0x1941, - 0x1944, - 0x196E, - 0x1970, - 0x1975, - 0x1980, - 0x19AC, - 0x19B0, - 0x19CA, - 0x19D0, - 0x19DB, - 0x19DE, - 0x1A1C, - 0x1A1E, - 0x1A5F, - 0x1A60, - 0x1A7D, - 0x1A7F, - 0x1A8A, - 0x1A90, - 0x1A9A, - 0x1AA0, - 0x1AAE, - 0x1AB0, - 0x1ADE, - 0x1AE0, - 0x1AEC, - 0x1B00, - 0x1B4D, - 0x1B4E, - 0x1BF4, - 0x1BFC, - 0x1C38, - 0x1C3B, - 0x1C4A, - 0x1C4D, - 0x1C80, - 0x1C81, - 0x1C82, - 0x1C83, - 0x1C84, - 0x1C86, - 0x1C87, - 0x1C88, - 0x1C89, - 0x1C8A, - 0x1C8B, - 0x1C90, - 0x1C91, - 0x1C92, - 0x1C93, - 0x1C94, - 0x1C95, - 0x1C96, - 0x1C97, - 0x1C98, - 0x1C99, - 0x1C9A, - 0x1C9B, - 0x1C9C, - 0x1C9D, - 0x1C9E, - 0x1C9F, - 0x1CA0, - 0x1CA1, - 0x1CA2, - 0x1CA3, - 0x1CA4, - 0x1CA5, - 0x1CA6, - 0x1CA7, - 0x1CA8, - 0x1CA9, - 0x1CAA, - 0x1CAB, - 0x1CAC, - 0x1CAD, - 0x1CAE, - 0x1CAF, - 0x1CB0, - 0x1CB1, - 0x1CB2, - 0x1CB3, - 0x1CB4, - 0x1CB5, - 0x1CB6, - 0x1CB7, - 0x1CB8, - 0x1CB9, - 0x1CBA, - 0x1CBB, - 0x1CBD, - 0x1CBE, - 0x1CBF, - 0x1CC0, - 0x1CC8, - 0x1CD0, - 0x1CFB, - 0x1D00, - 0x1D2C, - 0x1D2D, - 0x1D2E, - 0x1D2F, - 0x1D30, - 0x1D31, - 0x1D32, - 0x1D33, - 0x1D34, - 0x1D35, - 0x1D36, - 0x1D37, - 0x1D38, - 0x1D39, - 0x1D3A, - 0x1D3B, - 0x1D3C, - 0x1D3D, - 0x1D3E, - 0x1D3F, - 0x1D40, - 0x1D41, - 0x1D42, - 0x1D43, - 0x1D44, - 0x1D45, - 0x1D46, - 0x1D47, - 0x1D48, - 0x1D49, - 0x1D4A, - 0x1D4B, - 0x1D4C, - 0x1D4D, - 0x1D4E, - 0x1D4F, - 0x1D50, - 0x1D51, - 0x1D52, - 0x1D53, - 0x1D54, - 0x1D55, - 0x1D56, - 0x1D57, - 0x1D58, - 0x1D59, - 0x1D5A, - 0x1D5B, - 0x1D5C, - 0x1D5D, - 0x1D5E, - 0x1D5F, - 0x1D60, - 0x1D61, - 0x1D62, - 0x1D63, - 0x1D64, - 0x1D65, - 0x1D66, - 0x1D67, - 0x1D68, - 0x1D69, - 0x1D6A, - 0x1D6B, - 0x1D78, - 0x1D79, - 0x1D9B, - 0x1D9C, - 0x1D9D, - 0x1D9E, - 0x1D9F, - 0x1DA0, - 0x1DA1, - 0x1DA2, - 0x1DA3, - 0x1DA4, - 0x1DA5, - 0x1DA6, - 0x1DA7, - 0x1DA8, - 0x1DA9, - 0x1DAA, - 0x1DAB, - 0x1DAC, - 0x1DAD, - 0x1DAE, - 0x1DAF, - 0x1DB0, - 0x1DB1, - 0x1DB2, - 0x1DB3, - 0x1DB4, - 0x1DB5, - 0x1DB6, - 0x1DB7, - 0x1DB8, - 0x1DB9, - 0x1DBA, - 0x1DBB, - 0x1DBC, - 0x1DBD, - 0x1DBE, - 0x1DBF, - 0x1DC0, - 0x1E00, - 0x1E01, - 0x1E02, - 0x1E03, - 0x1E04, - 0x1E05, - 0x1E06, - 0x1E07, - 0x1E08, - 0x1E09, - 0x1E0A, - 0x1E0B, - 0x1E0C, - 0x1E0D, - 0x1E0E, - 0x1E0F, - 0x1E10, - 0x1E11, - 0x1E12, - 0x1E13, - 0x1E14, - 0x1E15, - 0x1E16, - 0x1E17, - 0x1E18, - 0x1E19, - 0x1E1A, - 0x1E1B, - 0x1E1C, - 0x1E1D, - 0x1E1E, - 0x1E1F, - 0x1E20, - 0x1E21, - 0x1E22, - 0x1E23, - 0x1E24, - 0x1E25, - 0x1E26, - 0x1E27, - 0x1E28, - 0x1E29, - 0x1E2A, - 0x1E2B, - 0x1E2C, - 0x1E2D, - 0x1E2E, - 0x1E2F, - 0x1E30, - 0x1E31, - 0x1E32, - 0x1E33, - 0x1E34, - 0x1E35, - 0x1E36, - 0x1E37, - 0x1E38, - 0x1E39, - 0x1E3A, - 0x1E3B, - 0x1E3C, - 0x1E3D, - 0x1E3E, - 0x1E3F, - 0x1E40, - 0x1E41, - 0x1E42, - 0x1E43, - 0x1E44, - 0x1E45, - 0x1E46, - 0x1E47, - 0x1E48, - 0x1E49, - 0x1E4A, - 0x1E4B, - 0x1E4C, - 0x1E4D, - 0x1E4E, - 0x1E4F, - 0x1E50, - 0x1E51, - 0x1E52, - 0x1E53, - 0x1E54, - 0x1E55, - 0x1E56, - 0x1E57, - 0x1E58, - 0x1E59, - 0x1E5A, - 0x1E5B, - 0x1E5C, - 0x1E5D, - 0x1E5E, - 0x1E5F, - 0x1E60, - 0x1E61, - 0x1E62, - 0x1E63, - 0x1E64, - 0x1E65, - 0x1E66, - 0x1E67, - 0x1E68, - 0x1E69, - 0x1E6A, - 0x1E6B, - 0x1E6C, - 0x1E6D, - 0x1E6E, - 0x1E6F, - 0x1E70, - 0x1E71, - 0x1E72, - 0x1E73, - 0x1E74, - 0x1E75, - 0x1E76, - 0x1E77, - 0x1E78, - 0x1E79, - 0x1E7A, - 0x1E7B, - 0x1E7C, - 0x1E7D, - 0x1E7E, - 0x1E7F, - 0x1E80, - 0x1E81, - 0x1E82, - 0x1E83, - 0x1E84, - 0x1E85, - 0x1E86, - 0x1E87, - 0x1E88, - 0x1E89, - 0x1E8A, - 0x1E8B, - 0x1E8C, - 0x1E8D, - 0x1E8E, - 0x1E8F, - 0x1E90, - 0x1E91, - 0x1E92, - 0x1E93, - 0x1E94, - 0x1E95, - 0x1E9A, - 0x1E9B, - 0x1E9C, - 0x1E9E, - 0x1E9F, - 0x1EA0, - 0x1EA1, - 0x1EA2, - 0x1EA3, - 0x1EA4, - 0x1EA5, - 0x1EA6, - 0x1EA7, - 0x1EA8, - 0x1EA9, - 0x1EAA, - 0x1EAB, - 0x1EAC, - 0x1EAD, - 0x1EAE, - 0x1EAF, - 0x1EB0, - 0x1EB1, - 0x1EB2, - 0x1EB3, - 0x1EB4, - 0x1EB5, - 0x1EB6, - 0x1EB7, - 0x1EB8, - 0x1EB9, - 0x1EBA, - 0x1EBB, - 0x1EBC, - 0x1EBD, - 0x1EBE, - 0x1EBF, - 0x1EC0, - 0x1EC1, - 0x1EC2, - 0x1EC3, - 0x1EC4, - 0x1EC5, - 0x1EC6, - 0x1EC7, - 0x1EC8, - 0x1EC9, - 0x1ECA, - 0x1ECB, - 0x1ECC, - 0x1ECD, - 0x1ECE, - 0x1ECF, - 0x1ED0, - 0x1ED1, - 0x1ED2, - 0x1ED3, - 0x1ED4, - 0x1ED5, - 0x1ED6, - 0x1ED7, - 0x1ED8, - 0x1ED9, - 0x1EDA, - 0x1EDB, - 0x1EDC, - 0x1EDD, - 0x1EDE, - 0x1EDF, - 0x1EE0, - 0x1EE1, - 0x1EE2, - 0x1EE3, - 0x1EE4, - 0x1EE5, - 0x1EE6, - 0x1EE7, - 0x1EE8, - 0x1EE9, - 0x1EEA, - 0x1EEB, - 0x1EEC, - 0x1EED, - 0x1EEE, - 0x1EEF, - 0x1EF0, - 0x1EF1, - 0x1EF2, - 0x1EF3, - 0x1EF4, - 0x1EF5, - 0x1EF6, - 0x1EF7, - 0x1EF8, - 0x1EF9, - 0x1EFA, - 0x1EFB, - 0x1EFC, - 0x1EFD, - 0x1EFE, - 0x1EFF, - 0x1F08, - 0x1F09, - 0x1F0A, - 0x1F0B, - 0x1F0C, - 0x1F0D, - 0x1F0E, - 0x1F0F, - 0x1F10, - 0x1F16, - 0x1F18, - 0x1F19, - 0x1F1A, - 0x1F1B, - 0x1F1C, - 0x1F1D, - 0x1F1E, - 0x1F20, - 0x1F28, - 0x1F29, - 0x1F2A, - 0x1F2B, - 0x1F2C, - 0x1F2D, - 0x1F2E, - 0x1F2F, - 0x1F30, - 0x1F38, - 0x1F39, - 0x1F3A, - 0x1F3B, - 0x1F3C, - 0x1F3D, - 0x1F3E, - 0x1F3F, - 0x1F40, - 0x1F46, - 0x1F48, - 0x1F49, - 0x1F4A, - 0x1F4B, - 0x1F4C, - 0x1F4D, - 0x1F4E, - 0x1F50, - 0x1F58, - 0x1F59, - 0x1F5A, - 0x1F5B, - 0x1F5C, - 0x1F5D, - 0x1F5E, - 0x1F5F, - 0x1F60, - 0x1F68, - 0x1F69, - 0x1F6A, - 0x1F6B, - 0x1F6C, - 0x1F6D, - 0x1F6E, - 0x1F6F, - 0x1F70, - 0x1F71, - 0x1F72, - 0x1F73, - 0x1F74, - 0x1F75, - 0x1F76, - 0x1F77, - 0x1F78, - 0x1F79, - 0x1F7A, - 0x1F7B, - 0x1F7C, - 0x1F7D, - 0x1F7E, - 0x1F80, - 0x1F81, - 0x1F82, - 0x1F83, - 0x1F84, - 0x1F85, - 0x1F86, - 0x1F87, - 0x1F88, - 0x1F89, - 0x1F8A, - 0x1F8B, - 0x1F8C, - 0x1F8D, - 0x1F8E, - 0x1F8F, - 0x1F90, - 0x1F91, - 0x1F92, - 0x1F93, - 0x1F94, - 0x1F95, - 0x1F96, - 0x1F97, - 0x1F98, - 0x1F99, - 0x1F9A, - 0x1F9B, - 0x1F9C, - 0x1F9D, - 0x1F9E, - 0x1F9F, - 0x1FA0, - 0x1FA1, - 0x1FA2, - 0x1FA3, - 0x1FA4, - 0x1FA5, - 0x1FA6, - 0x1FA7, - 0x1FA8, - 0x1FA9, - 0x1FAA, - 0x1FAB, - 0x1FAC, - 0x1FAD, - 0x1FAE, - 0x1FAF, - 0x1FB0, - 0x1FB2, - 0x1FB3, - 0x1FB4, - 0x1FB5, - 0x1FB6, - 0x1FB7, - 0x1FB8, - 0x1FB9, - 0x1FBA, - 0x1FBB, - 0x1FBC, - 0x1FBD, - 0x1FBE, - 0x1FBF, - 0x1FC0, - 0x1FC1, - 0x1FC2, - 0x1FC3, - 0x1FC4, - 0x1FC5, - 0x1FC6, - 0x1FC7, - 0x1FC8, - 0x1FC9, - 0x1FCA, - 0x1FCB, - 0x1FCC, - 0x1FCD, - 0x1FCE, - 0x1FCF, - 0x1FD0, - 0x1FD3, - 0x1FD4, - 0x1FD6, - 0x1FD8, - 0x1FD9, - 0x1FDA, - 0x1FDB, - 0x1FDC, - 0x1FDD, - 0x1FDE, - 0x1FDF, - 0x1FE0, - 0x1FE3, - 0x1FE4, - 0x1FE8, - 0x1FE9, - 0x1FEA, - 0x1FEB, - 0x1FEC, - 0x1FED, - 0x1FEE, - 0x1FEF, - 0x1FF0, - 0x1FF2, - 0x1FF3, - 0x1FF4, - 0x1FF5, - 0x1FF6, - 0x1FF7, - 0x1FF8, - 0x1FF9, - 0x1FFA, - 0x1FFB, - 0x1FFC, - 0x1FFD, - 0x1FFE, - 0x1FFF, - 0x2000, - 0x200B, - 0x200C, - 0x200E, - 0x2010, - 0x2011, - 0x2012, - 0x2017, - 0x2018, - 0x2024, - 0x2027, - 0x2028, - 0x202F, - 0x2030, - 0x2033, - 0x2034, - 0x2035, - 0x2036, - 0x2037, - 0x2038, - 0x203C, - 0x203D, - 0x203E, - 0x203F, - 0x2047, - 0x2048, - 0x2049, - 0x204A, - 0x2057, - 0x2058, - 0x205F, - 0x2060, - 0x2065, - 0x206A, - 0x2070, - 0x2071, - 0x2072, - 0x2074, - 0x2075, - 0x2076, - 0x2077, - 0x2078, - 0x2079, - 0x207A, - 0x207B, - 0x207C, - 0x207D, - 0x207E, - 0x207F, - 0x2080, - 0x2081, - 0x2082, - 0x2083, - 0x2084, - 0x2085, - 0x2086, - 0x2087, - 0x2088, - 0x2089, - 0x208A, - 0x208B, - 0x208C, - 0x208D, - 0x208E, - 0x208F, - 0x2090, - 0x2091, - 0x2092, - 0x2093, - 0x2094, - 0x2095, - 0x2096, - 0x2097, - 0x2098, - 0x2099, - 0x209A, - 0x209B, - 0x209C, - 0x209D, - 0x20A0, - 0x20A8, - 0x20A9, - 0x20C2, - 0x20D0, - 0x20F1, - 0x2100, - 0x2101, - 0x2102, - 0x2103, - 0x2104, - 0x2105, - 0x2106, - 0x2107, - 0x2108, - 0x2109, - 0x210A, - 0x210B, - 0x210F, - 0x2110, - 0x2112, - 0x2114, - 0x2115, - 0x2116, - 0x2117, - 0x2119, - 0x211A, - 0x211B, - 0x211E, - 0x2120, - 0x2121, - 0x2122, - 0x2123, - 0x2124, - 0x2125, - 0x2126, - 0x2127, - 0x2128, - 0x2129, - 0x212A, - 0x212B, - 0x212C, - 0x212D, - 0x212E, - 0x212F, - 0x2131, - 0x2132, - 0x2133, - 0x2134, - 0x2135, - 0x2136, - 0x2137, - 0x2138, - 0x2139, - 0x213A, - 0x213B, - 0x213C, - 0x213D, - 0x213F, - 0x2140, - 0x2141, - 0x2145, - 0x2147, - 0x2148, - 0x2149, - 0x214A, - 0x2150, - 0x2151, - 0x2152, - 0x2153, - 0x2154, - 0x2155, - 0x2156, - 0x2157, - 0x2158, - 0x2159, - 0x215A, - 0x215B, - 0x215C, - 0x215D, - 0x215E, - 0x215F, - 0x2160, - 0x2161, - 0x2162, - 0x2163, - 0x2164, - 0x2165, - 0x2166, - 0x2167, - 0x2168, - 0x2169, - 0x216A, - 0x216B, - 0x216C, - 0x216D, - 0x216E, - 0x216F, - 0x2170, - 0x2171, - 0x2172, - 0x2173, - 0x2174, - 0x2175, - 0x2176, - 0x2177, - 0x2178, - 0x2179, - 0x217A, - 0x217B, - 0x217C, - 0x217D, - 0x217E, - 0x217F, - 0x2180, - 0x2183, - 0x2184, - 0x2189, - 0x218A, - 0x218C, - 0x2190, - 0x222C, - 0x222D, - 0x222E, - 0x222F, - 0x2230, - 0x2231, - 0x2329, - 0x232A, - 0x232B, - 0x242A, - 0x2440, - 0x244B, - 0x2460, - 0x2461, - 0x2462, - 0x2463, - 0x2464, - 0x2465, - 0x2466, - 0x2467, - 0x2468, - 0x2469, - 0x246A, - 0x246B, - 0x246C, - 0x246D, - 0x246E, - 0x246F, - 0x2470, - 0x2471, - 0x2472, - 0x2473, - 0x2474, - 0x2475, - 0x2476, - 0x2477, - 0x2478, - 0x2479, - 0x247A, - 0x247B, - 0x247C, - 0x247D, - 0x247E, - 0x247F, - 0x2480, - 0x2481, - 0x2482, - 0x2483, - 0x2484, - 0x2485, - 0x2486, - 0x2487, - 0x2488, - 0x249C, - 0x249D, - 0x249E, - 0x249F, - 0x24A0, - 0x24A1, - 0x24A2, - 0x24A3, - 0x24A4, - 0x24A5, - 0x24A6, - 0x24A7, - 0x24A8, - 0x24A9, - 0x24AA, - 0x24AB, - 0x24AC, - 0x24AD, - 0x24AE, - 0x24AF, - 0x24B0, - 0x24B1, - 0x24B2, - 0x24B3, - 0x24B4, - 0x24B5, - 0x24B6, - 0x24B7, - 0x24B8, - 0x24B9, - 0x24BA, - 0x24BB, - 0x24BC, - 0x24BD, - 0x24BE, - 0x24BF, - 0x24C0, - 0x24C1, - 0x24C2, - 0x24C3, - 0x24C4, - 0x24C5, - 0x24C6, - 0x24C7, - 0x24C8, - 0x24C9, - 0x24CA, - 0x24CB, - 0x24CC, - 0x24CD, - 0x24CE, - 0x24CF, - 0x24D0, - 0x24D1, - 0x24D2, - 0x24D3, - 0x24D4, - 0x24D5, - 0x24D6, - 0x24D7, - 0x24D8, - 0x24D9, - 0x24DA, - 0x24DB, - 0x24DC, - 0x24DD, - 0x24DE, - 0x24DF, - 0x24E0, - 0x24E1, - 0x24E2, - 0x24E3, - 0x24E4, - 0x24E5, - 0x24E6, - 0x24E7, - 0x24E8, - 0x24E9, - 0x24EA, - 0x24EB, - 0x2A0C, - 0x2A0D, - 0x2A74, - 0x2A75, - 0x2A76, - 0x2A77, - 0x2ADC, - 0x2ADD, - 0x2B74, - 0x2B76, - 0x2C00, - 0x2C01, - 0x2C02, - 0x2C03, - 0x2C04, - 0x2C05, - 0x2C06, - 0x2C07, - 0x2C08, - 0x2C09, - 0x2C0A, - 0x2C0B, - 0x2C0C, - 0x2C0D, - 0x2C0E, - 0x2C0F, - 0x2C10, - 0x2C11, - 0x2C12, - 0x2C13, - 0x2C14, - 0x2C15, - 0x2C16, - 0x2C17, - 0x2C18, - 0x2C19, - 0x2C1A, - 0x2C1B, - 0x2C1C, - 0x2C1D, - 0x2C1E, - 0x2C1F, - 0x2C20, - 0x2C21, - 0x2C22, - 0x2C23, - 0x2C24, - 0x2C25, - 0x2C26, - 0x2C27, - 0x2C28, - 0x2C29, - 0x2C2A, - 0x2C2B, - 0x2C2C, - 0x2C2D, - 0x2C2E, - 0x2C2F, - 0x2C30, - 0x2C60, - 0x2C61, - 0x2C62, - 0x2C63, - 0x2C64, - 0x2C65, - 0x2C67, - 0x2C68, - 0x2C69, - 0x2C6A, - 0x2C6B, - 0x2C6C, - 0x2C6D, - 0x2C6E, - 0x2C6F, - 0x2C70, - 0x2C71, - 0x2C72, - 0x2C73, - 0x2C75, - 0x2C76, - 0x2C7C, - 0x2C7D, - 0x2C7E, - 0x2C7F, - 0x2C80, - 0x2C81, - 0x2C82, - 0x2C83, - 0x2C84, - 0x2C85, - 0x2C86, - 0x2C87, - 0x2C88, - 0x2C89, - 0x2C8A, - 0x2C8B, - 0x2C8C, - 0x2C8D, - 0x2C8E, - 0x2C8F, - 0x2C90, - 0x2C91, - 0x2C92, - 0x2C93, - 0x2C94, - 0x2C95, - 0x2C96, - 0x2C97, - 0x2C98, - 0x2C99, - 0x2C9A, - 0x2C9B, - 0x2C9C, - 0x2C9D, - 0x2C9E, - 0x2C9F, - 0x2CA0, - 0x2CA1, - 0x2CA2, - 0x2CA3, - 0x2CA4, - 0x2CA5, - 0x2CA6, - 0x2CA7, - 0x2CA8, - 0x2CA9, - 0x2CAA, - 0x2CAB, - 0x2CAC, - 0x2CAD, - 0x2CAE, - 0x2CAF, - 0x2CB0, - 0x2CB1, - 0x2CB2, - 0x2CB3, - 0x2CB4, - 0x2CB5, - 0x2CB6, - 0x2CB7, - 0x2CB8, - 0x2CB9, - 0x2CBA, - 0x2CBB, - 0x2CBC, - 0x2CBD, - 0x2CBE, - 0x2CBF, - 0x2CC0, - 0x2CC1, - 0x2CC2, - 0x2CC3, - 0x2CC4, - 0x2CC5, - 0x2CC6, - 0x2CC7, - 0x2CC8, - 0x2CC9, - 0x2CCA, - 0x2CCB, - 0x2CCC, - 0x2CCD, - 0x2CCE, - 0x2CCF, - 0x2CD0, - 0x2CD1, - 0x2CD2, - 0x2CD3, - 0x2CD4, - 0x2CD5, - 0x2CD6, - 0x2CD7, - 0x2CD8, - 0x2CD9, - 0x2CDA, - 0x2CDB, - 0x2CDC, - 0x2CDD, - 0x2CDE, - 0x2CDF, - 0x2CE0, - 0x2CE1, - 0x2CE2, - 0x2CE3, - 0x2CEB, - 0x2CEC, - 0x2CED, - 0x2CEE, - 0x2CF2, - 0x2CF3, - 0x2CF4, - 0x2CF9, - 0x2D26, - 0x2D27, - 0x2D28, - 0x2D2D, - 0x2D2E, - 0x2D30, - 0x2D68, - 0x2D6F, - 0x2D70, - 0x2D71, - 0x2D7F, - 0x2D97, - 0x2DA0, - 0x2DA7, - 0x2DA8, - 0x2DAF, - 0x2DB0, - 0x2DB7, - 0x2DB8, - 0x2DBF, - 0x2DC0, - 0x2DC7, - 0x2DC8, - 0x2DCF, - 0x2DD0, - 0x2DD7, - 0x2DD8, - 0x2DDF, - 0x2DE0, - 0x2E5E, - 0x2E80, - 0x2E9A, - 0x2E9B, - 0x2E9F, - 0x2EA0, - 0x2EF3, - 0x2EF4, - 0x2F00, - 0x2F01, - 0x2F02, - 0x2F03, - 0x2F04, - 0x2F05, - 0x2F06, - 0x2F07, - 0x2F08, - 0x2F09, - 0x2F0A, - 0x2F0B, - 0x2F0C, - 0x2F0D, - 0x2F0E, - 0x2F0F, - 0x2F10, - 0x2F11, - 0x2F12, - 0x2F13, - 0x2F14, - 0x2F15, - 0x2F16, - 0x2F17, - 0x2F18, - 0x2F19, - 0x2F1A, - 0x2F1B, - 0x2F1C, - 0x2F1D, - 0x2F1E, - 0x2F1F, - 0x2F20, - 0x2F21, - 0x2F22, - 0x2F23, - 0x2F24, - 0x2F25, - 0x2F26, - 0x2F27, - 0x2F28, - 0x2F29, - 0x2F2A, - 0x2F2B, - 0x2F2C, - 0x2F2D, - 0x2F2E, - 0x2F2F, - 0x2F30, - 0x2F31, - 0x2F32, - 0x2F33, - 0x2F34, - 0x2F35, - 0x2F36, - 0x2F37, - 0x2F38, - 0x2F39, - 0x2F3A, - 0x2F3B, - 0x2F3C, - 0x2F3D, - 0x2F3E, - 0x2F3F, - 0x2F40, - 0x2F41, - 0x2F42, - 0x2F43, - 0x2F44, - 0x2F45, - 0x2F46, - 0x2F47, - 0x2F48, - 0x2F49, - 0x2F4A, - 0x2F4B, - 0x2F4C, - 0x2F4D, - 0x2F4E, - 0x2F4F, - 0x2F50, - 0x2F51, - 0x2F52, - 0x2F53, - 0x2F54, - 0x2F55, - 0x2F56, - 0x2F57, - 0x2F58, - 0x2F59, - 0x2F5A, - 0x2F5B, - 0x2F5C, - 0x2F5D, - 0x2F5E, - 0x2F5F, - 0x2F60, - 0x2F61, - 0x2F62, - 0x2F63, - 0x2F64, - 0x2F65, - 0x2F66, - 0x2F67, - 0x2F68, - 0x2F69, - 0x2F6A, - 0x2F6B, - 0x2F6C, - 0x2F6D, - 0x2F6E, - 0x2F6F, - 0x2F70, - 0x2F71, - 0x2F72, - 0x2F73, - 0x2F74, - 0x2F75, - 0x2F76, - 0x2F77, - 0x2F78, - 0x2F79, - 0x2F7A, - 0x2F7B, - 0x2F7C, - 0x2F7D, - 0x2F7E, - 0x2F7F, - 0x2F80, - 0x2F81, - 0x2F82, - 0x2F83, - 0x2F84, - 0x2F85, - 0x2F86, - 0x2F87, - 0x2F88, - 0x2F89, - 0x2F8A, - 0x2F8B, - 0x2F8C, - 0x2F8D, - 0x2F8E, - 0x2F8F, - 0x2F90, - 0x2F91, - 0x2F92, - 0x2F93, - 0x2F94, - 0x2F95, - 0x2F96, - 0x2F97, - 0x2F98, - 0x2F99, - 0x2F9A, - 0x2F9B, - 0x2F9C, - 0x2F9D, - 0x2F9E, - 0x2F9F, - 0x2FA0, - 0x2FA1, - 0x2FA2, - 0x2FA3, - 0x2FA4, - 0x2FA5, - 0x2FA6, - 0x2FA7, - 0x2FA8, - 0x2FA9, - 0x2FAA, - 0x2FAB, - 0x2FAC, - 0x2FAD, - 0x2FAE, - 0x2FAF, - 0x2FB0, - 0x2FB1, - 0x2FB2, - 0x2FB3, - 0x2FB4, - 0x2FB5, - 0x2FB6, - 0x2FB7, - 0x2FB8, - 0x2FB9, - 0x2FBA, - 0x2FBB, - 0x2FBC, - 0x2FBD, - 0x2FBE, - 0x2FBF, - 0x2FC0, - 0x2FC1, - 0x2FC2, - 0x2FC3, - 0x2FC4, - 0x2FC5, - 0x2FC6, - 0x2FC7, - 0x2FC8, - 0x2FC9, - 0x2FCA, - 0x2FCB, - 0x2FCC, - 0x2FCD, - 0x2FCE, - 0x2FCF, - 0x2FD0, - 0x2FD1, - 0x2FD2, - 0x2FD3, - 0x2FD4, - 0x2FD5, - 0x2FD6, - 0x3000, - 0x3001, - 0x3002, - 0x3003, - 0x3036, - 0x3037, - 0x3038, - 0x3039, - 0x303A, - 0x303B, - 0x3040, - 0x3041, - 0x3097, - 0x3099, - 0x309B, - 0x309C, - 0x309D, - 0x309F, - 0x30A0, - 0x30FF, - 0x3100, - 0x3105, - 0x3130, - 0x3131, - 0x3132, - 0x3133, - 0x3134, - 0x3135, - 0x3136, - 0x3137, - 0x3138, - 0x3139, - 0x313A, - 0x313B, - 0x313C, - 0x313D, - 0x313E, - 0x313F, - 0x3140, - 0x3141, - 0x3142, - 0x3143, - 0x3144, - 0x3145, - 0x3146, - 0x3147, - 0x3148, - 0x3149, - 0x314A, - 0x314B, - 0x314C, - 0x314D, - 0x314E, - 0x314F, - 0x3150, - 0x3151, - 0x3152, - 0x3153, - 0x3154, - 0x3155, - 0x3156, - 0x3157, - 0x3158, - 0x3159, - 0x315A, - 0x315B, - 0x315C, - 0x315D, - 0x315E, - 0x315F, - 0x3160, - 0x3161, - 0x3162, - 0x3163, - 0x3164, - 0x3165, - 0x3166, - 0x3167, - 0x3168, - 0x3169, - 0x316A, - 0x316B, - 0x316C, - 0x316D, - 0x316E, - 0x316F, - 0x3170, - 0x3171, - 0x3172, - 0x3173, - 0x3174, - 0x3175, - 0x3176, - 0x3177, - 0x3178, - 0x3179, - 0x317A, - 0x317B, - 0x317C, - 0x317D, - 0x317E, - 0x317F, - 0x3180, - 0x3181, - 0x3182, - 0x3183, - 0x3184, - 0x3185, - 0x3186, - 0x3187, - 0x3188, - 0x3189, - 0x318A, - 0x318B, - 0x318C, - 0x318D, - 0x318E, - 0x318F, - 0x3190, - 0x3192, - 0x3193, - 0x3194, - 0x3195, - 0x3196, - 0x3197, - 0x3198, - 0x3199, - 0x319A, - 0x319B, - 0x319C, - 0x319D, - 0x319E, - 0x319F, - 0x31A0, - 0x31E6, - 0x31F0, - 0x3200, - 0x3201, - 0x3202, - 0x3203, - 0x3204, - 0x3205, - 0x3206, - 0x3207, - 0x3208, - 0x3209, - 0x320A, - 0x320B, - 0x320C, - 0x320D, - 0x320E, - 0x320F, - 0x3210, - 0x3211, - 0x3212, - 0x3213, - 0x3214, - 0x3215, - 0x3216, - 0x3217, - 0x3218, - 0x3219, - 0x321A, - 0x321B, - 0x321C, - 0x321D, - 0x321E, - 0x321F, - 0x3220, - 0x3221, - 0x3222, - 0x3223, - 0x3224, - 0x3225, - 0x3226, - 0x3227, - 0x3228, - 0x3229, - 0x322A, - 0x322B, - 0x322C, - 0x322D, - 0x322E, - 0x322F, - 0x3230, - 0x3231, - 0x3232, - 0x3233, - 0x3234, - 0x3235, - 0x3236, - 0x3237, - 0x3238, - 0x3239, - 0x323A, - 0x323B, - 0x323C, - 0x323D, - 0x323E, - 0x323F, - 0x3240, - 0x3241, - 0x3242, - 0x3243, - 0x3244, - 0x3245, - 0x3246, - 0x3247, - 0x3248, - 0x3250, - 0x3251, - 0x3252, - 0x3253, - 0x3254, - 0x3255, - 0x3256, - 0x3257, - 0x3258, - 0x3259, - 0x325A, - 0x325B, - 0x325C, - 0x325D, - 0x325E, - 0x325F, - 0x3260, - 0x3261, - 0x3262, - 0x3263, - 0x3264, - 0x3265, - 0x3266, - 0x3267, - 0x3268, - 0x3269, - 0x326A, - 0x326B, - 0x326C, - 0x326D, - 0x326E, - 0x326F, - 0x3270, - 0x3271, - 0x3272, - 0x3273, - 0x3274, - 0x3275, - 0x3276, - 0x3277, - 0x3278, - 0x3279, - 0x327A, - 0x327B, - 0x327C, - 0x327D, - 0x327E, - 0x327F, - 0x3280, - 0x3281, - 0x3282, - 0x3283, - 0x3284, - 0x3285, - 0x3286, - 0x3287, - 0x3288, - 0x3289, - 0x328A, - 0x328B, - 0x328C, - 0x328D, - 0x328E, - 0x328F, - 0x3290, - 0x3291, - 0x3292, - 0x3293, - 0x3294, - 0x3295, - 0x3296, - 0x3297, - 0x3298, - 0x3299, - 0x329A, - 0x329B, - 0x329C, - 0x329D, - 0x329E, - 0x329F, - 0x32A0, - 0x32A1, - 0x32A2, - 0x32A3, - 0x32A4, - 0x32A5, - 0x32A6, - 0x32A7, - 0x32A8, - 0x32A9, - 0x32AA, - 0x32AB, - 0x32AC, - 0x32AD, - 0x32AE, - 0x32AF, - 0x32B0, - 0x32B1, - 0x32B2, - 0x32B3, - 0x32B4, - 0x32B5, - 0x32B6, - 0x32B7, - 0x32B8, - 0x32B9, - 0x32BA, - 0x32BB, - 0x32BC, - 0x32BD, - 0x32BE, - 0x32BF, - 0x32C0, - 0x32C1, - 0x32C2, - 0x32C3, - 0x32C4, - 0x32C5, - 0x32C6, - 0x32C7, - 0x32C8, - 0x32C9, - 0x32CA, - 0x32CB, - 0x32CC, - 0x32CD, - 0x32CE, - 0x32CF, - 0x32D0, - 0x32D1, - 0x32D2, - 0x32D3, - 0x32D4, - 0x32D5, - 0x32D6, - 0x32D7, - 0x32D8, - 0x32D9, - 0x32DA, - 0x32DB, - 0x32DC, - 0x32DD, - 0x32DE, - 0x32DF, - 0x32E0, - 0x32E1, - 0x32E2, - 0x32E3, - 0x32E4, - 0x32E5, - 0x32E6, - 0x32E7, - 0x32E8, - 0x32E9, - 0x32EA, - 0x32EB, - 0x32EC, - 0x32ED, - 0x32EE, - 0x32EF, - 0x32F0, - 0x32F1, - 0x32F2, - 0x32F3, - 0x32F4, - 0x32F5, - 0x32F6, - 0x32F7, - 0x32F8, - 0x32F9, - 0x32FA, - 0x32FB, - 0x32FC, - 0x32FD, - 0x32FE, - 0x32FF, - 0x3300, - 0x3301, - 0x3302, - 0x3303, - 0x3304, - 0x3305, - 0x3306, - 0x3307, - 0x3308, - 0x3309, - 0x330A, - 0x330B, - 0x330C, - 0x330D, - 0x330E, - 0x330F, - 0x3310, - 0x3311, - 0x3312, - 0x3313, - 0x3314, - 0x3315, - 0x3316, - 0x3317, - 0x3318, - 0x3319, - 0x331A, - 0x331B, - 0x331C, - 0x331D, - 0x331E, - 0x331F, - 0x3320, - 0x3321, - 0x3322, - 0x3323, - 0x3324, - 0x3325, - 0x3326, - 0x3327, - 0x3328, - 0x3329, - 0x332A, - 0x332B, - 0x332C, - 0x332D, - 0x332E, - 0x332F, - 0x3330, - 0x3331, - 0x3332, - 0x3333, - 0x3334, - 0x3335, - 0x3336, - 0x3337, - 0x3338, - 0x3339, - 0x333A, - 0x333B, - 0x333C, - 0x333D, - 0x333E, - 0x333F, - 0x3340, - 0x3341, - 0x3342, - 0x3343, - 0x3344, - 0x3345, - 0x3346, - 0x3347, - 0x3348, - 0x3349, - 0x334A, - 0x334B, - 0x334C, - 0x334D, - 0x334E, - 0x334F, - 0x3350, - 0x3351, - 0x3352, - 0x3353, - 0x3354, - 0x3355, - 0x3356, - 0x3357, - 0x3358, - 0x3359, - 0x335A, - 0x335B, - 0x335C, - 0x335D, - 0x335E, - 0x335F, - 0x3360, - 0x3361, - 0x3362, - 0x3363, - 0x3364, - 0x3365, - 0x3366, - 0x3367, - 0x3368, - 0x3369, - 0x336A, - 0x336B, - 0x336C, - 0x336D, - 0x336E, - 0x336F, - 0x3370, - 0x3371, - 0x3372, - 0x3373, - 0x3374, - 0x3375, - 0x3376, - 0x3377, - 0x3378, - 0x3379, - 0x337A, - 0x337B, - 0x337C, - 0x337D, - 0x337E, - 0x337F, - 0x3380, - 0x3381, - 0x3382, - 0x3383, - 0x3384, - 0x3385, - 0x3386, - 0x3387, - 0x3388, - 0x3389, - 0x338A, - 0x338B, - 0x338C, - 0x338D, - 0x338E, - 0x338F, - 0x3390, - 0x3391, - 0x3392, - 0x3393, - 0x3394, - 0x3395, - 0x3396, - 0x3397, - 0x3398, - 0x3399, - 0x339A, - 0x339B, - 0x339C, - 0x339D, - 0x339E, - 0x339F, - 0x33A0, - 0x33A1, - 0x33A2, - 0x33A3, - 0x33A4, - 0x33A5, - 0x33A6, - 0x33A7, - 0x33A8, - 0x33A9, - 0x33AA, - 0x33AB, - 0x33AC, - 0x33AD, - 0x33AE, - 0x33AF, - 0x33B0, - 0x33B1, - 0x33B2, - 0x33B3, - 0x33B4, - 0x33B5, - 0x33B6, - 0x33B7, - 0x33B8, - 0x33B9, - 0x33BA, - 0x33BB, - 0x33BC, - 0x33BD, - 0x33BE, - 0x33BF, - 0x33C0, - 0x33C1, - 0x33C2, - 0x33C3, - 0x33C4, - 0x33C5, - 0x33C6, - 0x33C7, - 0x33C8, - 0x33C9, - 0x33CA, - 0x33CB, - 0x33CC, - 0x33CD, - 0x33CE, - 0x33CF, - 0x33D0, - 0x33D1, - 0x33D2, - 0x33D3, - 0x33D4, - 0x33D5, - 0x33D6, - 0x33D7, - 0x33D8, - 0x33D9, - 0x33DA, - 0x33DB, - 0x33DC, - 0x33DD, - 0x33DE, - 0x33DF, - 0x33E0, - 0x33E1, - 0x33E2, - 0x33E3, - 0x33E4, - 0x33E5, - 0x33E6, - 0x33E7, - 0x33E8, - 0x33E9, - 0x33EA, - 0x33EB, - 0x33EC, - 0x33ED, - 0x33EE, - 0x33EF, - 0x33F0, - 0x33F1, - 0x33F2, - 0x33F3, - 0x33F4, - 0x33F5, - 0x33F6, - 0x33F7, - 0x33F8, - 0x33F9, - 0x33FA, - 0x33FB, - 0x33FC, - 0x33FD, - 0x33FE, - 0x33FF, - 0x3400, - 0xA48D, - 0xA490, - 0xA4C7, - 0xA4D0, - 0xA62C, - 0xA640, - 0xA641, - 0xA642, - 0xA643, - 0xA644, - 0xA645, - 0xA646, - 0xA647, - 0xA648, - 0xA649, - 0xA64A, - 0xA64B, - 0xA64C, - 0xA64D, - 0xA64E, - 0xA64F, - 0xA650, - 0xA651, - 0xA652, - 0xA653, - 0xA654, - 0xA655, - 0xA656, - 0xA657, - 0xA658, - 0xA659, - 0xA65A, - 0xA65B, - 0xA65C, - 0xA65D, - 0xA65E, - 0xA65F, - 0xA660, - 0xA661, - 0xA662, - 0xA663, - 0xA664, - 0xA665, - 0xA666, - 0xA667, - 0xA668, - 0xA669, - 0xA66A, - 0xA66B, - 0xA66C, - 0xA66D, - 0xA680, - 0xA681, - 0xA682, - 0xA683, - 0xA684, - 0xA685, - 0xA686, - 0xA687, - 0xA688, - 0xA689, - 0xA68A, - 0xA68B, - 0xA68C, - 0xA68D, - 0xA68E, - 0xA68F, - 0xA690, - 0xA691, - 0xA692, - 0xA693, - 0xA694, - 0xA695, - 0xA696, - 0xA697, - 0xA698, - 0xA699, - 0xA69A, - 0xA69B, - 0xA69C, - 0xA69D, - 0xA69E, - 0xA6F8, - 0xA700, - 0xA722, - 0xA723, - 0xA724, - 0xA725, - 0xA726, - 0xA727, - 0xA728, - 0xA729, - 0xA72A, - 0xA72B, - 0xA72C, - 0xA72D, - 0xA72E, - 0xA72F, - 0xA732, - 0xA733, - 0xA734, - 0xA735, - 0xA736, - 0xA737, - 0xA738, - 0xA739, - 0xA73A, - 0xA73B, - 0xA73C, - 0xA73D, - 0xA73E, - 0xA73F, - 0xA740, - 0xA741, - 0xA742, - 0xA743, - 0xA744, - 0xA745, - 0xA746, - 0xA747, - 0xA748, - 0xA749, - 0xA74A, - 0xA74B, - 0xA74C, - 0xA74D, - 0xA74E, - 0xA74F, - 0xA750, - 0xA751, - 0xA752, - 0xA753, - 0xA754, - 0xA755, - 0xA756, - 0xA757, - 0xA758, - 0xA759, - 0xA75A, - 0xA75B, - 0xA75C, - 0xA75D, - 0xA75E, - 0xA75F, - 0xA760, - 0xA761, - 0xA762, - 0xA763, - 0xA764, - 0xA765, - 0xA766, - 0xA767, - 0xA768, - 0xA769, - 0xA76A, - 0xA76B, - 0xA76C, - 0xA76D, - 0xA76E, - 0xA76F, - 0xA770, - 0xA771, - 0xA779, - 0xA77A, - 0xA77B, - 0xA77C, - 0xA77D, - 0xA77E, - 0xA77F, - 0xA780, - 0xA781, - 0xA782, - 0xA783, - 0xA784, - 0xA785, - 0xA786, - 0xA787, - 0xA78B, - 0xA78C, - 0xA78D, - 0xA78E, - 0xA790, - 0xA791, - 0xA792, - 0xA793, - 0xA796, - 0xA797, - 0xA798, - 0xA799, - 0xA79A, - 0xA79B, - 0xA79C, - 0xA79D, - 0xA79E, - 0xA79F, - 0xA7A0, - 0xA7A1, - 0xA7A2, - 0xA7A3, - 0xA7A4, - 0xA7A5, - 0xA7A6, - 0xA7A7, - 0xA7A8, - 0xA7A9, - 0xA7AA, - 0xA7AB, - 0xA7AC, - 0xA7AD, - 0xA7AE, - 0xA7AF, - 0xA7B0, - 0xA7B1, - 0xA7B2, - 0xA7B3, - 0xA7B4, - 0xA7B5, - 0xA7B6, - 0xA7B7, - 0xA7B8, - 0xA7B9, - 0xA7BA, - 0xA7BB, - 0xA7BC, - 0xA7BD, - 0xA7BE, - 0xA7BF, - 0xA7C0, - 0xA7C1, - 0xA7C2, - 0xA7C3, - 0xA7C4, - 0xA7C5, - 0xA7C6, - 0xA7C7, - 0xA7C8, - 0xA7C9, - 0xA7CA, - 0xA7CB, - 0xA7CC, - 0xA7CD, - 0xA7CE, - 0xA7CF, - 0xA7D0, - 0xA7D1, - 0xA7D2, - 0xA7D3, - 0xA7D4, - 0xA7D5, - 0xA7D6, - 0xA7D7, - 0xA7D8, - 0xA7D9, - 0xA7DA, - 0xA7DB, - 0xA7DC, - 0xA7DD, - 0xA7F1, - 0xA7F2, - 0xA7F3, - 0xA7F4, - 0xA7F5, - 0xA7F6, - 0xA7F8, - 0xA7F9, - 0xA7FA, - 0xA82D, - 0xA830, - 0xA83A, - 0xA840, - 0xA878, - 0xA880, - 0xA8C6, - 0xA8CE, - 0xA8DA, - 0xA8E0, - 0xA954, - 0xA95F, - 0xA97D, - 0xA980, - 0xA9CE, - 0xA9CF, - 0xA9DA, - 0xA9DE, - 0xA9FF, - 0xAA00, - 0xAA37, - 0xAA40, - 0xAA4E, - 0xAA50, - 0xAA5A, - 0xAA5C, - 0xAAC3, - 0xAADB, - 0xAAF7, - 0xAB01, - 0xAB07, - 0xAB09, - 0xAB0F, - 0xAB11, - 0xAB17, - 0xAB20, - 0xAB27, - 0xAB28, - 0xAB2F, - 0xAB30, - 0xAB5C, - 0xAB5D, - 0xAB5E, - 0xAB5F, - 0xAB60, - 0xAB69, - 0xAB6A, - 0xAB6C, - 0xAB70, - 0xAB71, - 0xAB72, - 0xAB73, - 0xAB74, - 0xAB75, - 0xAB76, - 0xAB77, - 0xAB78, - 0xAB79, - 0xAB7A, - 0xAB7B, - 0xAB7C, - 0xAB7D, - 0xAB7E, - 0xAB7F, - 0xAB80, - 0xAB81, - 0xAB82, - 0xAB83, - 0xAB84, - 0xAB85, - 0xAB86, - 0xAB87, - 0xAB88, - 0xAB89, - 0xAB8A, - 0xAB8B, - 0xAB8C, - 0xAB8D, - 0xAB8E, - 0xAB8F, - 0xAB90, - 0xAB91, - 0xAB92, - 0xAB93, - 0xAB94, - 0xAB95, - 0xAB96, - 0xAB97, - 0xAB98, - 0xAB99, - 0xAB9A, - 0xAB9B, - 0xAB9C, - 0xAB9D, - 0xAB9E, - 0xAB9F, - 0xABA0, - 0xABA1, - 0xABA2, - 0xABA3, - 0xABA4, - 0xABA5, - 0xABA6, - 0xABA7, - 0xABA8, - 0xABA9, - 0xABAA, - 0xABAB, - 0xABAC, - 0xABAD, - 0xABAE, - 0xABAF, - 0xABB0, - 0xABB1, - 0xABB2, - 0xABB3, - 0xABB4, - 0xABB5, - 0xABB6, - 0xABB7, - 0xABB8, - 0xABB9, - 0xABBA, - 0xABBB, - 0xABBC, - 0xABBD, - 0xABBE, - 0xABBF, - 0xABC0, - 0xABEE, - 0xABF0, - 0xABFA, - 0xAC00, - 0xD7A4, - 0xD7B0, - 0xD7C7, - 0xD7CB, - 0xD7FC, - 0xF900, - 0xF901, - 0xF902, - 0xF903, - 0xF904, - 0xF905, - 0xF906, - 0xF907, - 0xF909, - 0xF90A, - 0xF90B, - 0xF90C, - 0xF90D, - 0xF90E, - 0xF90F, - 0xF910, - 0xF911, - 0xF912, - 0xF913, - 0xF914, - 0xF915, - 0xF916, - 0xF917, - 0xF918, - 0xF919, - 0xF91A, - 0xF91B, - 0xF91C, - 0xF91D, - 0xF91E, - 0xF91F, - 0xF920, - 0xF921, - 0xF922, - 0xF923, - 0xF924, - 0xF925, - 0xF926, - 0xF927, - 0xF928, - 0xF929, - 0xF92A, - 0xF92B, - 0xF92C, - 0xF92D, - 0xF92E, - 0xF92F, - 0xF930, - 0xF931, - 0xF932, - 0xF933, - 0xF934, - 0xF935, - 0xF936, - 0xF937, - 0xF938, - 0xF939, - 0xF93A, - 0xF93B, - 0xF93C, - 0xF93D, - 0xF93E, - 0xF93F, - 0xF940, - 0xF941, - 0xF942, - 0xF943, - 0xF944, - 0xF945, - 0xF946, - 0xF947, - 0xF948, - 0xF949, - 0xF94A, - 0xF94B, - 0xF94C, - 0xF94D, - 0xF94E, - 0xF94F, - 0xF950, - 0xF951, - 0xF952, - 0xF953, - 0xF954, - 0xF955, - 0xF956, - 0xF957, - 0xF958, - 0xF959, - 0xF95A, - 0xF95B, - 0xF95C, - 0xF95D, - 0xF95E, - 0xF95F, - 0xF960, - 0xF961, - 0xF962, - 0xF963, - 0xF964, - 0xF965, - 0xF966, - 0xF967, - 0xF968, - 0xF969, - 0xF96A, - 0xF96B, - 0xF96C, - 0xF96D, - 0xF96E, - 0xF96F, - 0xF970, - 0xF971, - 0xF972, - 0xF973, - 0xF974, - 0xF975, - 0xF976, - 0xF977, - 0xF978, - 0xF979, - 0xF97A, - 0xF97B, - 0xF97C, - 0xF97D, - 0xF97E, - 0xF97F, - 0xF980, - 0xF981, - 0xF982, - 0xF983, - 0xF984, - 0xF985, - 0xF986, - 0xF987, - 0xF988, - 0xF989, - 0xF98A, - 0xF98B, - 0xF98C, - 0xF98D, - 0xF98E, - 0xF98F, - 0xF990, - 0xF991, - 0xF992, - 0xF993, - 0xF994, - 0xF995, - 0xF996, - 0xF997, - 0xF998, - 0xF999, - 0xF99A, - 0xF99B, - 0xF99C, - 0xF99D, - 0xF99E, - 0xF99F, - 0xF9A0, - 0xF9A1, - 0xF9A2, - 0xF9A3, - 0xF9A4, - 0xF9A5, - 0xF9A6, - 0xF9A7, - 0xF9A8, - 0xF9A9, - 0xF9AA, - 0xF9AB, - 0xF9AC, - 0xF9AD, - 0xF9AE, - 0xF9AF, - 0xF9B0, - 0xF9B1, - 0xF9B2, - 0xF9B3, - 0xF9B4, - 0xF9B5, - 0xF9B6, - 0xF9B7, - 0xF9B8, - 0xF9B9, - 0xF9BA, - 0xF9BB, - 0xF9BC, - 0xF9BD, - 0xF9BE, - 0xF9BF, - 0xF9C0, - 0xF9C1, - 0xF9C2, - 0xF9C3, - 0xF9C4, - 0xF9C5, - 0xF9C6, - 0xF9C7, - 0xF9C8, - 0xF9C9, - 0xF9CA, - 0xF9CB, - 0xF9CC, - 0xF9CD, - 0xF9CE, - 0xF9CF, - 0xF9D0, - 0xF9D1, - 0xF9D2, - 0xF9D3, - 0xF9D4, - 0xF9D5, - 0xF9D6, - 0xF9D7, - 0xF9D8, - 0xF9D9, - 0xF9DA, - 0xF9DB, - 0xF9DC, - 0xF9DD, - 0xF9DE, - 0xF9DF, - 0xF9E0, - 0xF9E1, - 0xF9E2, - 0xF9E3, - 0xF9E4, - 0xF9E5, - 0xF9E6, - 0xF9E7, - 0xF9E8, - 0xF9E9, - 0xF9EA, - 0xF9EB, - 0xF9EC, - 0xF9ED, - 0xF9EE, - 0xF9EF, - 0xF9F0, - 0xF9F1, - 0xF9F2, - 0xF9F3, - 0xF9F4, - 0xF9F5, - 0xF9F6, - 0xF9F7, - 0xF9F8, - 0xF9F9, - 0xF9FA, - 0xF9FB, - 0xF9FC, - 0xF9FD, - 0xF9FE, - 0xF9FF, - 0xFA00, - 0xFA01, - 0xFA02, - 0xFA03, - 0xFA04, - 0xFA05, - 0xFA06, - 0xFA07, - 0xFA08, - 0xFA09, - 0xFA0A, - 0xFA0B, - 0xFA0C, - 0xFA0D, - 0xFA0E, - 0xFA10, - 0xFA11, - 0xFA12, - 0xFA13, - 0xFA15, - 0xFA16, - 0xFA17, - 0xFA18, - 0xFA19, - 0xFA1A, - 0xFA1B, - 0xFA1C, - 0xFA1D, - 0xFA1E, - 0xFA1F, - 0xFA20, - 0xFA21, - 0xFA22, - 0xFA23, - 0xFA25, - 0xFA26, - 0xFA27, - 0xFA2A, - 0xFA2B, - 0xFA2C, - 0xFA2D, - 0xFA2E, - 0xFA2F, - 0xFA30, - 0xFA31, - 0xFA32, - 0xFA33, - 0xFA34, - 0xFA35, - 0xFA36, - 0xFA37, - 0xFA38, - 0xFA39, - 0xFA3A, - 0xFA3B, - 0xFA3C, - 0xFA3D, - 0xFA3E, - 0xFA3F, - 0xFA40, - 0xFA41, - 0xFA42, - 0xFA43, - 0xFA44, - 0xFA45, - 0xFA46, - 0xFA47, - 0xFA48, - 0xFA49, - 0xFA4A, - 0xFA4B, - 0xFA4C, - 0xFA4D, - 0xFA4E, - 0xFA4F, - 0xFA50, - 0xFA51, - 0xFA52, - 0xFA53, - 0xFA54, - 0xFA55, - 0xFA56, - 0xFA57, - 0xFA58, - 0xFA59, - 0xFA5A, - 0xFA5B, - 0xFA5C, - 0xFA5D, - 0xFA5F, - 0xFA60, - 0xFA61, - 0xFA62, - 0xFA63, - 0xFA64, - 0xFA65, - 0xFA66, - 0xFA67, - 0xFA68, - 0xFA69, - 0xFA6A, - 0xFA6B, - 0xFA6C, - 0xFA6D, - 0xFA6E, - 0xFA70, - 0xFA71, - 0xFA72, - 0xFA73, - 0xFA74, - 0xFA75, - 0xFA76, - 0xFA77, - 0xFA78, - 0xFA79, - 0xFA7A, - 0xFA7B, - 0xFA7C, - 0xFA7D, - 0xFA7E, - 0xFA7F, - 0xFA80, - 0xFA81, - 0xFA82, - 0xFA83, - 0xFA84, - 0xFA85, - 0xFA86, - 0xFA87, - 0xFA88, - 0xFA89, - 0xFA8A, - 0xFA8B, - 0xFA8C, - 0xFA8D, - 0xFA8E, - 0xFA8F, - 0xFA90, - 0xFA91, - 0xFA92, - 0xFA93, - 0xFA94, - 0xFA95, - 0xFA96, - 0xFA97, - 0xFA98, - 0xFA99, - 0xFA9A, - 0xFA9B, - 0xFA9C, - 0xFA9D, - 0xFA9E, - 0xFA9F, - 0xFAA0, - 0xFAA1, - 0xFAA2, - 0xFAA3, - 0xFAA4, - 0xFAA5, - 0xFAA6, - 0xFAA7, - 0xFAA8, - 0xFAA9, - 0xFAAA, - 0xFAAB, - 0xFAAC, - 0xFAAD, - 0xFAAE, - 0xFAAF, - 0xFAB0, - 0xFAB1, - 0xFAB2, - 0xFAB3, - 0xFAB4, - 0xFAB5, - 0xFAB6, - 0xFAB7, - 0xFAB8, - 0xFAB9, - 0xFABA, - 0xFABB, - 0xFABC, - 0xFABD, - 0xFABE, - 0xFABF, - 0xFAC0, - 0xFAC1, - 0xFAC2, - 0xFAC3, - 0xFAC4, - 0xFAC5, - 0xFAC6, - 0xFAC7, - 0xFAC8, - 0xFAC9, - 0xFACA, - 0xFACB, - 0xFACC, - 0xFACD, - 0xFACE, - 0xFACF, - 0xFAD0, - 0xFAD1, - 0xFAD2, - 0xFAD3, - 0xFAD4, - 0xFAD5, - 0xFAD6, - 0xFAD7, - 0xFAD8, - 0xFAD9, - 0xFADA, - 0xFB00, - 0xFB01, - 0xFB02, - 0xFB03, - 0xFB04, - 0xFB05, - 0xFB07, - 0xFB13, - 0xFB14, - 0xFB15, - 0xFB16, - 0xFB17, - 0xFB18, - 0xFB1D, - 0xFB1E, - 0xFB1F, - 0xFB20, - 0xFB21, - 0xFB22, - 0xFB23, - 0xFB24, - 0xFB25, - 0xFB26, - 0xFB27, - 0xFB28, - 0xFB29, - 0xFB2A, - 0xFB2B, - 0xFB2C, - 0xFB2D, - 0xFB2E, - 0xFB2F, - 0xFB30, - 0xFB31, - 0xFB32, - 0xFB33, - 0xFB34, - 0xFB35, - 0xFB36, - 0xFB37, - 0xFB38, - 0xFB39, - 0xFB3A, - 0xFB3B, - 0xFB3C, - 0xFB3D, - 0xFB3E, - 0xFB3F, - 0xFB40, - 0xFB41, - 0xFB42, - 0xFB43, - 0xFB44, - 0xFB45, - 0xFB46, - 0xFB47, - 0xFB48, - 0xFB49, - 0xFB4A, - 0xFB4B, - 0xFB4C, - 0xFB4D, - 0xFB4E, - 0xFB4F, - 0xFB50, - 0xFB52, - 0xFB56, - 0xFB5A, - 0xFB5E, - 0xFB62, - 0xFB66, - 0xFB6A, - 0xFB6E, - 0xFB72, - 0xFB76, - 0xFB7A, - 0xFB7E, - 0xFB82, - 0xFB84, - 0xFB86, - 0xFB88, - 0xFB8A, - 0xFB8C, - 0xFB8E, - 0xFB92, - 0xFB96, - 0xFB9A, - 0xFB9E, - 0xFBA0, - 0xFBA4, - 0xFBA6, - 0xFBAA, - 0xFBAE, - 0xFBB0, - 0xFBB2, - 0xFBD3, - 0xFBD7, - 0xFBD9, - 0xFBDB, - 0xFBDD, - 0xFBDE, - 0xFBE0, - 0xFBE2, - 0xFBE4, - 0xFBE8, - 0xFBEA, - 0xFBEC, - 0xFBEE, - 0xFBF0, - 0xFBF2, - 0xFBF4, - 0xFBF6, - 0xFBF9, - 0xFBFC, - 0xFC00, - 0xFC01, - 0xFC02, - 0xFC03, - 0xFC04, - 0xFC05, - 0xFC06, - 0xFC07, - 0xFC08, - 0xFC09, - 0xFC0A, - 0xFC0B, - 0xFC0C, - 0xFC0D, - 0xFC0E, - 0xFC0F, - 0xFC10, - 0xFC11, - 0xFC12, - 0xFC13, - 0xFC14, - 0xFC15, - 0xFC16, - 0xFC17, - 0xFC18, - 0xFC19, - 0xFC1A, - 0xFC1B, - 0xFC1C, - 0xFC1D, - 0xFC1E, - 0xFC1F, - 0xFC20, - 0xFC21, - 0xFC22, - 0xFC23, - 0xFC24, - 0xFC25, - 0xFC26, - 0xFC27, - 0xFC28, - 0xFC29, - 0xFC2A, - 0xFC2B, - 0xFC2C, - 0xFC2D, - 0xFC2E, - 0xFC2F, - 0xFC30, - 0xFC31, - 0xFC32, - 0xFC33, - 0xFC34, - 0xFC35, - 0xFC36, - 0xFC37, - 0xFC38, - 0xFC39, - 0xFC3A, - 0xFC3B, - 0xFC3C, - 0xFC3D, - 0xFC3E, - 0xFC3F, - 0xFC40, - 0xFC41, - 0xFC42, - 0xFC43, - 0xFC44, - 0xFC45, - 0xFC46, - 0xFC47, - 0xFC48, - 0xFC49, - 0xFC4A, - 0xFC4B, - 0xFC4C, - 0xFC4D, - 0xFC4E, - 0xFC4F, - 0xFC50, - 0xFC51, - 0xFC52, - 0xFC53, - 0xFC54, - 0xFC55, - 0xFC56, - 0xFC57, - 0xFC58, - 0xFC59, - 0xFC5A, - 0xFC5B, - 0xFC5C, - 0xFC5D, - 0xFC5E, - 0xFC5F, - 0xFC60, - 0xFC61, - 0xFC62, - 0xFC63, - 0xFC64, - 0xFC65, - 0xFC66, - 0xFC67, - 0xFC68, - 0xFC69, - 0xFC6A, - 0xFC6B, - 0xFC6C, - 0xFC6D, - 0xFC6E, - 0xFC6F, - 0xFC70, - 0xFC71, - 0xFC72, - 0xFC73, - 0xFC74, - 0xFC75, - 0xFC76, - 0xFC77, - 0xFC78, - 0xFC79, - 0xFC7A, - 0xFC7B, - 0xFC7C, - 0xFC7D, - 0xFC7E, - 0xFC7F, - 0xFC80, - 0xFC81, - 0xFC82, - 0xFC83, - 0xFC84, - 0xFC85, - 0xFC86, - 0xFC87, - 0xFC88, - 0xFC89, - 0xFC8A, - 0xFC8B, - 0xFC8C, - 0xFC8D, - 0xFC8E, - 0xFC8F, - 0xFC90, - 0xFC91, - 0xFC92, - 0xFC93, - 0xFC94, - 0xFC95, - 0xFC96, - 0xFC97, - 0xFC98, - 0xFC99, - 0xFC9A, - 0xFC9B, - 0xFC9C, - 0xFC9D, - 0xFC9E, - 0xFC9F, - 0xFCA0, - 0xFCA1, - 0xFCA2, - 0xFCA3, - 0xFCA4, - 0xFCA5, - 0xFCA6, - 0xFCA7, - 0xFCA8, - 0xFCA9, - 0xFCAA, - 0xFCAB, - 0xFCAC, - 0xFCAD, - 0xFCAE, - 0xFCAF, - 0xFCB0, - 0xFCB1, - 0xFCB2, - 0xFCB3, - 0xFCB4, - 0xFCB5, - 0xFCB6, - 0xFCB7, - 0xFCB8, - 0xFCB9, - 0xFCBA, - 0xFCBB, - 0xFCBC, - 0xFCBD, - 0xFCBE, - 0xFCBF, - 0xFCC0, - 0xFCC1, - 0xFCC2, - 0xFCC3, - 0xFCC4, - 0xFCC5, - 0xFCC6, - 0xFCC7, - 0xFCC8, - 0xFCC9, - 0xFCCA, - 0xFCCB, - 0xFCCC, - 0xFCCD, - 0xFCCE, - 0xFCCF, - 0xFCD0, - 0xFCD1, - 0xFCD2, - 0xFCD3, - 0xFCD4, - 0xFCD5, - 0xFCD6, - 0xFCD7, - 0xFCD8, - 0xFCD9, - 0xFCDA, - 0xFCDB, - 0xFCDC, - 0xFCDD, - 0xFCDE, - 0xFCDF, - 0xFCE0, - 0xFCE1, - 0xFCE2, - 0xFCE3, - 0xFCE4, - 0xFCE5, - 0xFCE6, - 0xFCE7, - 0xFCE8, - 0xFCE9, - 0xFCEA, - 0xFCEB, - 0xFCEC, - 0xFCED, - 0xFCEE, - 0xFCEF, - 0xFCF0, - 0xFCF1, - 0xFCF2, - 0xFCF3, - 0xFCF4, - 0xFCF5, - 0xFCF6, - 0xFCF7, - 0xFCF8, - 0xFCF9, - 0xFCFA, - 0xFCFB, - 0xFCFC, - 0xFCFD, - 0xFCFE, - 0xFCFF, - 0xFD00, - 0xFD01, - 0xFD02, - 0xFD03, - 0xFD04, - 0xFD05, - 0xFD06, - 0xFD07, - 0xFD08, - 0xFD09, - 0xFD0A, - 0xFD0B, - 0xFD0C, - 0xFD0D, - 0xFD0E, - 0xFD0F, - 0xFD10, - 0xFD11, - 0xFD12, - 0xFD13, - 0xFD14, - 0xFD15, - 0xFD16, - 0xFD17, - 0xFD18, - 0xFD19, - 0xFD1A, - 0xFD1B, - 0xFD1C, - 0xFD1D, - 0xFD1E, - 0xFD1F, - 0xFD20, - 0xFD21, - 0xFD22, - 0xFD23, - 0xFD24, - 0xFD25, - 0xFD26, - 0xFD27, - 0xFD28, - 0xFD29, - 0xFD2A, - 0xFD2B, - 0xFD2C, - 0xFD2D, - 0xFD2E, - 0xFD2F, - 0xFD30, - 0xFD31, - 0xFD32, - 0xFD33, - 0xFD34, - 0xFD35, - 0xFD36, - 0xFD37, - 0xFD38, - 0xFD39, - 0xFD3A, - 0xFD3B, - 0xFD3C, - 0xFD3E, - 0xFD50, - 0xFD51, - 0xFD53, - 0xFD54, - 0xFD55, - 0xFD56, - 0xFD57, - 0xFD58, - 0xFD5A, - 0xFD5B, - 0xFD5C, - 0xFD5D, - 0xFD5E, - 0xFD5F, - 0xFD61, - 0xFD62, - 0xFD64, - 0xFD66, - 0xFD67, - 0xFD69, - 0xFD6A, - 0xFD6C, - 0xFD6E, - 0xFD6F, - 0xFD71, - 0xFD73, - 0xFD74, - 0xFD75, - 0xFD76, - 0xFD78, - 0xFD79, - 0xFD7A, - 0xFD7B, - 0xFD7C, - 0xFD7E, - 0xFD7F, - 0xFD80, - 0xFD81, - 0xFD82, - 0xFD83, - 0xFD85, - 0xFD87, - 0xFD89, - 0xFD8A, - 0xFD8B, - 0xFD8C, - 0xFD8D, - 0xFD8E, - 0xFD8F, - 0xFD90, - 0xFD92, - 0xFD93, - 0xFD94, - 0xFD95, - 0xFD96, - 0xFD97, - 0xFD99, - 0xFD9A, - 0xFD9B, - 0xFD9C, - 0xFD9E, - 0xFD9F, - 0xFDA0, - 0xFDA1, - 0xFDA2, - 0xFDA3, - 0xFDA4, - 0xFDA5, - 0xFDA6, - 0xFDA7, - 0xFDA8, - 0xFDA9, - 0xFDAA, - 0xFDAB, - 0xFDAC, - 0xFDAD, - 0xFDAE, - 0xFDAF, - 0xFDB0, - 0xFDB1, - 0xFDB2, - 0xFDB3, - 0xFDB4, - 0xFDB5, - 0xFDB6, - 0xFDB7, - 0xFDB8, - 0xFDB9, - 0xFDBA, - 0xFDBB, - 0xFDBC, - 0xFDBD, - 0xFDBE, - 0xFDBF, - 0xFDC0, - 0xFDC1, - 0xFDC2, - 0xFDC3, - 0xFDC4, - 0xFDC5, - 0xFDC6, - 0xFDC7, - 0xFDC8, - 0xFDD0, - 0xFDF0, - 0xFDF1, - 0xFDF2, - 0xFDF3, - 0xFDF4, - 0xFDF5, - 0xFDF6, - 0xFDF7, - 0xFDF8, - 0xFDF9, - 0xFDFA, - 0xFDFB, - 0xFDFC, - 0xFDFD, - 0xFE00, - 0xFE10, - 0xFE11, - 0xFE12, - 0xFE13, - 0xFE14, - 0xFE15, - 0xFE16, - 0xFE17, - 0xFE18, - 0xFE19, - 0xFE20, - 0xFE30, - 0xFE31, - 0xFE32, - 0xFE33, - 0xFE35, - 0xFE36, - 0xFE37, - 0xFE38, - 0xFE39, - 0xFE3A, - 0xFE3B, - 0xFE3C, - 0xFE3D, - 0xFE3E, - 0xFE3F, - 0xFE40, - 0xFE41, - 0xFE42, - 0xFE43, - 0xFE44, - 0xFE45, - 0xFE47, - 0xFE48, - 0xFE49, - 0xFE4D, - 0xFE50, - 0xFE51, - 0xFE52, - 0xFE54, - 0xFE55, - 0xFE56, - 0xFE57, - 0xFE58, - 0xFE59, - 0xFE5A, - 0xFE5B, - 0xFE5C, - 0xFE5D, - 0xFE5E, - 0xFE5F, - 0xFE60, - 0xFE61, - 0xFE62, - 0xFE63, - 0xFE64, - 0xFE65, - 0xFE66, - 0xFE67, - 0xFE68, - 0xFE69, - 0xFE6A, - 0xFE6B, - 0xFE6C, - 0xFE70, - 0xFE71, - 0xFE72, - 0xFE73, - 0xFE74, - 0xFE75, - 0xFE76, - 0xFE77, - 0xFE78, - 0xFE79, - 0xFE7A, - 0xFE7B, - 0xFE7C, - 0xFE7D, - 0xFE7E, - 0xFE7F, - 0xFE80, - 0xFE81, - 0xFE83, - 0xFE85, - 0xFE87, - 0xFE89, - 0xFE8D, - 0xFE8F, - 0xFE93, - 0xFE95, - 0xFE99, - 0xFE9D, - 0xFEA1, - 0xFEA5, - 0xFEA9, - 0xFEAB, - 0xFEAD, - 0xFEAF, - 0xFEB1, - 0xFEB5, - 0xFEB9, - 0xFEBD, - 0xFEC1, - 0xFEC5, - 0xFEC9, - 0xFECD, - 0xFED1, - 0xFED5, - 0xFED9, - 0xFEDD, - 0xFEE1, - 0xFEE5, - 0xFEE9, - 0xFEED, - 0xFEEF, - 0xFEF1, - 0xFEF5, - 0xFEF7, - 0xFEF9, - 0xFEFB, - 0xFEFD, - 0xFEFF, - 0xFF00, - 0xFF01, - 0xFF02, - 0xFF03, - 0xFF04, - 0xFF05, - 0xFF06, - 0xFF07, - 0xFF08, - 0xFF09, - 0xFF0A, - 0xFF0B, - 0xFF0C, - 0xFF0D, - 0xFF0E, - 0xFF0F, - 0xFF10, - 0xFF11, - 0xFF12, - 0xFF13, - 0xFF14, - 0xFF15, - 0xFF16, - 0xFF17, - 0xFF18, - 0xFF19, - 0xFF1A, - 0xFF1B, - 0xFF1C, - 0xFF1D, - 0xFF1E, - 0xFF1F, - 0xFF20, - 0xFF21, - 0xFF22, - 0xFF23, - 0xFF24, - 0xFF25, - 0xFF26, - 0xFF27, - 0xFF28, - 0xFF29, - 0xFF2A, - 0xFF2B, - 0xFF2C, - 0xFF2D, - 0xFF2E, - 0xFF2F, - 0xFF30, - 0xFF31, - 0xFF32, - 0xFF33, - 0xFF34, - 0xFF35, - 0xFF36, - 0xFF37, - 0xFF38, - 0xFF39, - 0xFF3A, - 0xFF3B, - 0xFF3C, - 0xFF3D, - 0xFF3E, - 0xFF3F, - 0xFF40, - 0xFF41, - 0xFF42, - 0xFF43, - 0xFF44, - 0xFF45, - 0xFF46, - 0xFF47, - 0xFF48, - 0xFF49, - 0xFF4A, - 0xFF4B, - 0xFF4C, - 0xFF4D, - 0xFF4E, - 0xFF4F, - 0xFF50, - 0xFF51, - 0xFF52, - 0xFF53, - 0xFF54, - 0xFF55, - 0xFF56, - 0xFF57, - 0xFF58, - 0xFF59, - 0xFF5A, - 0xFF5B, - 0xFF5C, - 0xFF5D, - 0xFF5E, - 0xFF5F, - 0xFF60, - 0xFF61, - 0xFF62, - 0xFF63, - 0xFF64, - 0xFF65, - 0xFF66, - 0xFF67, - 0xFF68, - 0xFF69, - 0xFF6A, - 0xFF6B, - 0xFF6C, - 0xFF6D, - 0xFF6E, - 0xFF6F, - 0xFF70, - 0xFF71, - 0xFF72, - 0xFF73, - 0xFF74, - 0xFF75, - 0xFF76, - 0xFF77, - 0xFF78, - 0xFF79, - 0xFF7A, - 0xFF7B, - 0xFF7C, - 0xFF7D, - 0xFF7E, - 0xFF7F, - 0xFF80, - 0xFF81, - 0xFF82, - 0xFF83, - 0xFF84, - 0xFF85, - 0xFF86, - 0xFF87, - 0xFF88, - 0xFF89, - 0xFF8A, - 0xFF8B, - 0xFF8C, - 0xFF8D, - 0xFF8E, - 0xFF8F, - 0xFF90, - 0xFF91, - 0xFF92, - 0xFF93, - 0xFF94, - 0xFF95, - 0xFF96, - 0xFF97, - 0xFF98, - 0xFF99, - 0xFF9A, - 0xFF9B, - 0xFF9C, - 0xFF9D, - 0xFF9E, - 0xFF9F, - 0xFFA0, - 0xFFA1, - 0xFFA2, - 0xFFA3, - 0xFFA4, - 0xFFA5, - 0xFFA6, - 0xFFA7, - 0xFFA8, - 0xFFA9, - 0xFFAA, - 0xFFAB, - 0xFFAC, - 0xFFAD, - 0xFFAE, - 0xFFAF, - 0xFFB0, - 0xFFB1, - 0xFFB2, - 0xFFB3, - 0xFFB4, - 0xFFB5, - 0xFFB6, - 0xFFB7, - 0xFFB8, - 0xFFB9, - 0xFFBA, - 0xFFBB, - 0xFFBC, - 0xFFBD, - 0xFFBE, - 0xFFBF, - 0xFFC2, - 0xFFC3, - 0xFFC4, - 0xFFC5, - 0xFFC6, - 0xFFC7, - 0xFFC8, - 0xFFCA, - 0xFFCB, - 0xFFCC, - 0xFFCD, - 0xFFCE, - 0xFFCF, - 0xFFD0, - 0xFFD2, - 0xFFD3, - 0xFFD4, - 0xFFD5, - 0xFFD6, - 0xFFD7, - 0xFFD8, - 0xFFDA, - 0xFFDB, - 0xFFDC, - 0xFFDD, - 0xFFE0, - 0xFFE1, - 0xFFE2, - 0xFFE3, - 0xFFE4, - 0xFFE5, - 0xFFE6, - 0xFFE7, - 0xFFE8, - 0xFFE9, - 0xFFEA, - 0xFFEB, - 0xFFEC, - 0xFFED, - 0xFFEE, - 0xFFEF, - 0x10000, - 0x1000C, - 0x1000D, - 0x10027, - 0x10028, - 0x1003B, - 0x1003C, - 0x1003E, - 0x1003F, - 0x1004E, - 0x10050, - 0x1005E, - 0x10080, - 0x100FB, - 0x10100, - 0x10103, - 0x10107, - 0x10134, - 0x10137, - 0x1018F, - 0x10190, - 0x1019D, - 0x101A0, - 0x101A1, - 0x101D0, - 0x101FE, - 0x10280, - 0x1029D, - 0x102A0, - 0x102D1, - 0x102E0, - 0x102FC, - 0x10300, - 0x10324, - 0x1032D, - 0x1034B, - 0x10350, - 0x1037B, - 0x10380, - 0x1039E, - 0x1039F, - 0x103C4, - 0x103C8, - 0x103D6, - 0x10400, - 0x10401, - 0x10402, - 0x10403, - 0x10404, - 0x10405, - 0x10406, - 0x10407, - 0x10408, - 0x10409, - 0x1040A, - 0x1040B, - 0x1040C, - 0x1040D, - 0x1040E, - 0x1040F, - 0x10410, - 0x10411, - 0x10412, - 0x10413, - 0x10414, - 0x10415, - 0x10416, - 0x10417, - 0x10418, - 0x10419, - 0x1041A, - 0x1041B, - 0x1041C, - 0x1041D, - 0x1041E, - 0x1041F, - 0x10420, - 0x10421, - 0x10422, - 0x10423, - 0x10424, - 0x10425, - 0x10426, - 0x10427, - 0x10428, - 0x1049E, - 0x104A0, - 0x104AA, - 0x104B0, - 0x104B1, - 0x104B2, - 0x104B3, - 0x104B4, - 0x104B5, - 0x104B6, - 0x104B7, - 0x104B8, - 0x104B9, - 0x104BA, - 0x104BB, - 0x104BC, - 0x104BD, - 0x104BE, - 0x104BF, - 0x104C0, - 0x104C1, - 0x104C2, - 0x104C3, - 0x104C4, - 0x104C5, - 0x104C6, - 0x104C7, - 0x104C8, - 0x104C9, - 0x104CA, - 0x104CB, - 0x104CC, - 0x104CD, - 0x104CE, - 0x104CF, - 0x104D0, - 0x104D1, - 0x104D2, - 0x104D3, - 0x104D4, - 0x104D8, - 0x104FC, - 0x10500, - 0x10528, - 0x10530, - 0x10564, - 0x1056F, - 0x10570, - 0x10571, - 0x10572, - 0x10573, - 0x10574, - 0x10575, - 0x10576, - 0x10577, - 0x10578, - 0x10579, - 0x1057A, - 0x1057B, - 0x1057C, - 0x1057D, - 0x1057E, - 0x1057F, - 0x10580, - 0x10581, - 0x10582, - 0x10583, - 0x10584, - 0x10585, - 0x10586, - 0x10587, - 0x10588, - 0x10589, - 0x1058A, - 0x1058B, - 0x1058C, - 0x1058D, - 0x1058E, - 0x1058F, - 0x10590, - 0x10591, - 0x10592, - 0x10593, - 0x10594, - 0x10595, - 0x10596, - 0x10597, - 0x105A2, - 0x105A3, - 0x105B2, - 0x105B3, - 0x105BA, - 0x105BB, - 0x105BD, - 0x105C0, - 0x105F4, - 0x10600, - 0x10737, - 0x10740, - 0x10756, - 0x10760, - 0x10768, - 0x10780, - 0x10781, - 0x10782, - 0x10783, - 0x10784, - 0x10785, - 0x10786, - 0x10787, - 0x10788, - 0x10789, - 0x1078A, - 0x1078B, - 0x1078C, - 0x1078D, - 0x1078E, - 0x1078F, - 0x10790, - 0x10791, - 0x10792, - 0x10793, - 0x10794, - 0x10795, - 0x10796, - 0x10797, - 0x10798, - 0x10799, - 0x1079A, - 0x1079B, - 0x1079C, - 0x1079D, - 0x1079E, - 0x1079F, - 0x107A0, - 0x107A1, - 0x107A2, - 0x107A3, - 0x107A4, - 0x107A5, - 0x107A6, - 0x107A7, - 0x107A8, - 0x107A9, - 0x107AA, - 0x107AB, - 0x107AC, - 0x107AD, - 0x107AE, - 0x107AF, - 0x107B0, - 0x107B1, - 0x107B2, - 0x107B3, - 0x107B4, - 0x107B5, - 0x107B6, - 0x107B7, - 0x107B8, - 0x107B9, - 0x107BA, - 0x107BB, - 0x10800, - 0x10806, - 0x10808, - 0x10809, - 0x1080A, - 0x10836, - 0x10837, - 0x10839, - 0x1083C, - 0x1083D, - 0x1083F, - 0x10856, - 0x10857, - 0x1089F, - 0x108A7, - 0x108B0, - 0x108E0, - 0x108F3, - 0x108F4, - 0x108F6, - 0x108FB, - 0x1091C, - 0x1091F, - 0x1093A, - 0x1093F, - 0x1095A, - 0x10980, - 0x109B8, - 0x109BC, - 0x109D0, - 0x109D2, - 0x10A04, - 0x10A05, - 0x10A07, - 0x10A0C, - 0x10A14, - 0x10A15, - 0x10A18, - 0x10A19, - 0x10A36, - 0x10A38, - 0x10A3B, - 0x10A3F, - 0x10A49, - 0x10A50, - 0x10A59, - 0x10A60, - 0x10AA0, - 0x10AC0, - 0x10AE7, - 0x10AEB, - 0x10AF7, - 0x10B00, - 0x10B36, - 0x10B39, - 0x10B56, - 0x10B58, - 0x10B73, - 0x10B78, - 0x10B92, - 0x10B99, - 0x10B9D, - 0x10BA9, - 0x10BB0, - 0x10C00, - 0x10C49, - 0x10C80, - 0x10C81, - 0x10C82, - 0x10C83, - 0x10C84, - 0x10C85, - 0x10C86, - 0x10C87, - 0x10C88, - 0x10C89, - 0x10C8A, - 0x10C8B, - 0x10C8C, - 0x10C8D, - 0x10C8E, - 0x10C8F, - 0x10C90, - 0x10C91, - 0x10C92, - 0x10C93, - 0x10C94, - 0x10C95, - 0x10C96, - 0x10C97, - 0x10C98, - 0x10C99, - 0x10C9A, - 0x10C9B, - 0x10C9C, - 0x10C9D, - 0x10C9E, - 0x10C9F, - 0x10CA0, - 0x10CA1, - 0x10CA2, - 0x10CA3, - 0x10CA4, - 0x10CA5, - 0x10CA6, - 0x10CA7, - 0x10CA8, - 0x10CA9, - 0x10CAA, - 0x10CAB, - 0x10CAC, - 0x10CAD, - 0x10CAE, - 0x10CAF, - 0x10CB0, - 0x10CB1, - 0x10CB2, - 0x10CB3, - 0x10CC0, - 0x10CF3, - 0x10CFA, - 0x10D28, - 0x10D30, - 0x10D3A, - 0x10D40, - 0x10D50, - 0x10D51, - 0x10D52, - 0x10D53, - 0x10D54, - 0x10D55, - 0x10D56, - 0x10D57, - 0x10D58, - 0x10D59, - 0x10D5A, - 0x10D5B, - 0x10D5C, - 0x10D5D, - 0x10D5E, - 0x10D5F, - 0x10D60, - 0x10D61, - 0x10D62, - 0x10D63, - 0x10D64, - 0x10D65, - 0x10D66, - 0x10D69, - 0x10D86, - 0x10D8E, - 0x10D90, - 0x10E60, - 0x10E7F, - 0x10E80, - 0x10EAA, - 0x10EAB, - 0x10EAE, - 0x10EB0, - 0x10EB2, - 0x10EC2, - 0x10EC8, - 0x10ED0, - 0x10ED9, - 0x10EFA, - 0x10F28, - 0x10F30, - 0x10F5A, - 0x10F70, - 0x10F8A, - 0x10FB0, - 0x10FCC, - 0x10FE0, - 0x10FF7, - 0x11000, - 0x1104E, - 0x11052, - 0x11076, - 0x1107F, - 0x110BD, - 0x110BE, - 0x110C3, - 0x110D0, - 0x110E9, - 0x110F0, - 0x110FA, - 0x11100, - 0x11135, - 0x11136, - 0x11148, - 0x11150, - 0x11177, - 0x11180, - 0x111E0, - 0x111E1, - 0x111F5, - 0x11200, - 0x11212, - 0x11213, - 0x11242, - 0x11280, - 0x11287, - 0x11288, - 0x11289, - 0x1128A, - 0x1128E, - 0x1128F, - 0x1129E, - 0x1129F, - 0x112AA, - 0x112B0, - 0x112EB, - 0x112F0, - 0x112FA, - 0x11300, - 0x11304, - 0x11305, - 0x1130D, - 0x1130F, - 0x11311, - 0x11313, - 0x11329, - 0x1132A, - 0x11331, - 0x11332, - 0x11334, - 0x11335, - 0x1133A, - 0x1133B, - 0x11345, - 0x11347, - 0x11349, - 0x1134B, - 0x1134E, - 0x11350, - 0x11351, - 0x11357, - 0x11358, - 0x1135D, - 0x11364, - 0x11366, - 0x1136D, - 0x11370, - 0x11375, - 0x11380, - 0x1138A, - 0x1138B, - 0x1138C, - 0x1138E, - 0x1138F, - 0x11390, - 0x113B6, - 0x113B7, - 0x113C1, - 0x113C2, - 0x113C3, - 0x113C5, - 0x113C6, - 0x113C7, - 0x113CB, - 0x113CC, - 0x113D6, - 0x113D7, - 0x113D9, - 0x113E1, - 0x113E3, - 0x11400, - 0x1145C, - 0x1145D, - 0x11462, - 0x11480, - 0x114C8, - 0x114D0, - 0x114DA, - 0x11580, - 0x115B6, - 0x115B8, - 0x115DE, - 0x11600, - 0x11645, - 0x11650, - 0x1165A, - 0x11660, - 0x1166D, - 0x11680, - 0x116BA, - 0x116C0, - 0x116CA, - 0x116D0, - 0x116E4, - 0x11700, - 0x1171B, - 0x1171D, - 0x1172C, - 0x11730, - 0x11747, - 0x11800, - 0x1183C, - 0x118A0, - 0x118A1, - 0x118A2, - 0x118A3, - 0x118A4, - 0x118A5, - 0x118A6, - 0x118A7, - 0x118A8, - 0x118A9, - 0x118AA, - 0x118AB, - 0x118AC, - 0x118AD, - 0x118AE, - 0x118AF, - 0x118B0, - 0x118B1, - 0x118B2, - 0x118B3, - 0x118B4, - 0x118B5, - 0x118B6, - 0x118B7, - 0x118B8, - 0x118B9, - 0x118BA, - 0x118BB, - 0x118BC, - 0x118BD, - 0x118BE, - 0x118BF, - 0x118C0, - 0x118F3, - 0x118FF, - 0x11907, - 0x11909, - 0x1190A, - 0x1190C, - 0x11914, - 0x11915, - 0x11917, - 0x11918, - 0x11936, - 0x11937, - 0x11939, - 0x1193B, - 0x11947, - 0x11950, - 0x1195A, - 0x119A0, - 0x119A8, - 0x119AA, - 0x119D8, - 0x119DA, - 0x119E5, - 0x11A00, - 0x11A48, - 0x11A50, - 0x11AA3, - 0x11AB0, - 0x11AF9, - 0x11B00, - 0x11B0A, - 0x11B60, - 0x11B68, - 0x11BC0, - 0x11BE2, - 0x11BF0, - 0x11BFA, - 0x11C00, - 0x11C09, - 0x11C0A, - 0x11C37, - 0x11C38, - 0x11C46, - 0x11C50, - 0x11C6D, - 0x11C70, - 0x11C90, - 0x11C92, - 0x11CA8, - 0x11CA9, - 0x11CB7, - 0x11D00, - 0x11D07, - 0x11D08, - 0x11D0A, - 0x11D0B, - 0x11D37, - 0x11D3A, - 0x11D3B, - 0x11D3C, - 0x11D3E, - 0x11D3F, - 0x11D48, - 0x11D50, - 0x11D5A, - 0x11D60, - 0x11D66, - 0x11D67, - 0x11D69, - 0x11D6A, - 0x11D8F, - 0x11D90, - 0x11D92, - 0x11D93, - 0x11D99, - 0x11DA0, - 0x11DAA, - 0x11DB0, - 0x11DDC, - 0x11DE0, - 0x11DEA, - 0x11EE0, - 0x11EF9, - 0x11F00, - 0x11F11, - 0x11F12, - 0x11F3B, - 0x11F3E, - 0x11F5B, - 0x11FB0, - 0x11FB1, - 0x11FC0, - 0x11FF2, - 0x11FFF, - 0x1239A, - 0x12400, - 0x1246F, - 0x12470, - 0x12475, - 0x12480, - 0x12544, - 0x12F90, - 0x12FF3, - 0x13000, - 0x13430, - 0x13440, - 0x13456, - 0x13460, - 0x143FB, - 0x14400, - 0x14647, - 0x16100, - 0x1613A, - 0x16800, - 0x16A39, - 0x16A40, - 0x16A5F, - 0x16A60, - 0x16A6A, - 0x16A6E, - 0x16ABF, - 0x16AC0, - 0x16ACA, - 0x16AD0, - 0x16AEE, - 0x16AF0, - 0x16AF6, - 0x16B00, - 0x16B46, - 0x16B50, - 0x16B5A, - 0x16B5B, - 0x16B62, - 0x16B63, - 0x16B78, - 0x16B7D, - 0x16B90, - 0x16D40, - 0x16D7A, - 0x16E40, - 0x16E41, - 0x16E42, - 0x16E43, - 0x16E44, - 0x16E45, - 0x16E46, - 0x16E47, - 0x16E48, - 0x16E49, - 0x16E4A, - 0x16E4B, - 0x16E4C, - 0x16E4D, - 0x16E4E, - 0x16E4F, - 0x16E50, - 0x16E51, - 0x16E52, - 0x16E53, - 0x16E54, - 0x16E55, - 0x16E56, - 0x16E57, - 0x16E58, - 0x16E59, - 0x16E5A, - 0x16E5B, - 0x16E5C, - 0x16E5D, - 0x16E5E, - 0x16E5F, - 0x16E60, - 0x16E9B, - 0x16EA0, - 0x16EA1, - 0x16EA2, - 0x16EA3, - 0x16EA4, - 0x16EA5, - 0x16EA6, - 0x16EA7, - 0x16EA8, - 0x16EA9, - 0x16EAA, - 0x16EAB, - 0x16EAC, - 0x16EAD, - 0x16EAE, - 0x16EAF, - 0x16EB0, - 0x16EB1, - 0x16EB2, - 0x16EB3, - 0x16EB4, - 0x16EB5, - 0x16EB6, - 0x16EB7, - 0x16EB8, - 0x16EB9, - 0x16EBB, - 0x16ED4, - 0x16F00, - 0x16F4B, - 0x16F4F, - 0x16F88, - 0x16F8F, - 0x16FA0, - 0x16FE0, - 0x16FE5, - 0x16FF0, - 0x16FF7, - 0x17000, - 0x18CD6, - 0x18CFF, - 0x18D1F, - 0x18D80, - 0x18DF3, - 0x1AFF0, - 0x1AFF4, - 0x1AFF5, - 0x1AFFC, - 0x1AFFD, - 0x1AFFF, - 0x1B000, - 0x1B123, - 0x1B132, - 0x1B133, - 0x1B150, - 0x1B153, - 0x1B155, - 0x1B156, - 0x1B164, - 0x1B168, - 0x1B170, - 0x1B2FC, - 0x1BC00, - 0x1BC6B, - 0x1BC70, - 0x1BC7D, - 0x1BC80, - 0x1BC89, - 0x1BC90, - 0x1BC9A, - 0x1BC9C, - 0x1BCA0, - 0x1BCA4, - 0x1CC00, - 0x1CCD6, - 0x1CCD7, - 0x1CCD8, - 0x1CCD9, - 0x1CCDA, - 0x1CCDB, - 0x1CCDC, - 0x1CCDD, - 0x1CCDE, - 0x1CCDF, - 0x1CCE0, - 0x1CCE1, - 0x1CCE2, - 0x1CCE3, - 0x1CCE4, - 0x1CCE5, - 0x1CCE6, - 0x1CCE7, - 0x1CCE8, - 0x1CCE9, - 0x1CCEA, - 0x1CCEB, - 0x1CCEC, - 0x1CCED, - 0x1CCEE, - 0x1CCEF, - 0x1CCF0, - 0x1CCF1, - 0x1CCF2, - 0x1CCF3, - 0x1CCF4, - 0x1CCF5, - 0x1CCF6, - 0x1CCF7, - 0x1CCF8, - 0x1CCF9, - 0x1CCFA, - 0x1CCFD, - 0x1CD00, - 0x1CEB4, - 0x1CEBA, - 0x1CED1, - 0x1CEE0, - 0x1CEF1, - 0x1CF00, - 0x1CF2E, - 0x1CF30, - 0x1CF47, - 0x1CF50, - 0x1CFC4, - 0x1D000, - 0x1D0F6, - 0x1D100, - 0x1D127, - 0x1D129, - 0x1D15E, - 0x1D15F, - 0x1D160, - 0x1D161, - 0x1D162, - 0x1D163, - 0x1D164, - 0x1D165, - 0x1D173, - 0x1D17B, - 0x1D1BB, - 0x1D1BC, - 0x1D1BD, - 0x1D1BE, - 0x1D1BF, - 0x1D1C0, - 0x1D1C1, - 0x1D1EB, - 0x1D200, - 0x1D246, - 0x1D2C0, - 0x1D2D4, - 0x1D2E0, - 0x1D2F4, - 0x1D300, - 0x1D357, - 0x1D360, - 0x1D379, - 0x1D400, - 0x1D401, - 0x1D402, - 0x1D403, - 0x1D404, - 0x1D405, - 0x1D406, - 0x1D407, - 0x1D408, - 0x1D409, - 0x1D40A, - 0x1D40B, - 0x1D40C, - 0x1D40D, - 0x1D40E, - 0x1D40F, - 0x1D410, - 0x1D411, - 0x1D412, - 0x1D413, - 0x1D414, - 0x1D415, - 0x1D416, - 0x1D417, - 0x1D418, - 0x1D419, - 0x1D41A, - 0x1D41B, - 0x1D41C, - 0x1D41D, - 0x1D41E, - 0x1D41F, - 0x1D420, - 0x1D421, - 0x1D422, - 0x1D423, - 0x1D424, - 0x1D425, - 0x1D426, - 0x1D427, - 0x1D428, - 0x1D429, - 0x1D42A, - 0x1D42B, - 0x1D42C, - 0x1D42D, - 0x1D42E, - 0x1D42F, - 0x1D430, - 0x1D431, - 0x1D432, - 0x1D433, - 0x1D434, - 0x1D435, - 0x1D436, - 0x1D437, - 0x1D438, - 0x1D439, - 0x1D43A, - 0x1D43B, - 0x1D43C, - 0x1D43D, - 0x1D43E, - 0x1D43F, - 0x1D440, - 0x1D441, - 0x1D442, - 0x1D443, - 0x1D444, - 0x1D445, - 0x1D446, - 0x1D447, - 0x1D448, - 0x1D449, - 0x1D44A, - 0x1D44B, - 0x1D44C, - 0x1D44D, - 0x1D44E, - 0x1D44F, - 0x1D450, - 0x1D451, - 0x1D452, - 0x1D453, - 0x1D454, - 0x1D455, - 0x1D456, - 0x1D457, - 0x1D458, - 0x1D459, - 0x1D45A, - 0x1D45B, - 0x1D45C, - 0x1D45D, - 0x1D45E, - 0x1D45F, - 0x1D460, - 0x1D461, - 0x1D462, - 0x1D463, - 0x1D464, - 0x1D465, - 0x1D466, - 0x1D467, - 0x1D468, - 0x1D469, - 0x1D46A, - 0x1D46B, - 0x1D46C, - 0x1D46D, - 0x1D46E, - 0x1D46F, - 0x1D470, - 0x1D471, - 0x1D472, - 0x1D473, - 0x1D474, - 0x1D475, - 0x1D476, - 0x1D477, - 0x1D478, - 0x1D479, - 0x1D47A, - 0x1D47B, - 0x1D47C, - 0x1D47D, - 0x1D47E, - 0x1D47F, - 0x1D480, - 0x1D481, - 0x1D482, - 0x1D483, - 0x1D484, - 0x1D485, - 0x1D486, - 0x1D487, - 0x1D488, - 0x1D489, - 0x1D48A, - 0x1D48B, - 0x1D48C, - 0x1D48D, - 0x1D48E, - 0x1D48F, - 0x1D490, - 0x1D491, - 0x1D492, - 0x1D493, - 0x1D494, - 0x1D495, - 0x1D496, - 0x1D497, - 0x1D498, - 0x1D499, - 0x1D49A, - 0x1D49B, - 0x1D49C, - 0x1D49D, - 0x1D49E, - 0x1D49F, - 0x1D4A0, - 0x1D4A2, - 0x1D4A3, - 0x1D4A5, - 0x1D4A6, - 0x1D4A7, - 0x1D4A9, - 0x1D4AA, - 0x1D4AB, - 0x1D4AC, - 0x1D4AD, - 0x1D4AE, - 0x1D4AF, - 0x1D4B0, - 0x1D4B1, - 0x1D4B2, - 0x1D4B3, - 0x1D4B4, - 0x1D4B5, - 0x1D4B6, - 0x1D4B7, - 0x1D4B8, - 0x1D4B9, - 0x1D4BA, - 0x1D4BB, - 0x1D4BC, - 0x1D4BD, - 0x1D4BE, - 0x1D4BF, - 0x1D4C0, - 0x1D4C1, - 0x1D4C2, - 0x1D4C3, - 0x1D4C4, - 0x1D4C5, - 0x1D4C6, - 0x1D4C7, - 0x1D4C8, - 0x1D4C9, - 0x1D4CA, - 0x1D4CB, - 0x1D4CC, - 0x1D4CD, - 0x1D4CE, - 0x1D4CF, - 0x1D4D0, - 0x1D4D1, - 0x1D4D2, - 0x1D4D3, - 0x1D4D4, - 0x1D4D5, - 0x1D4D6, - 0x1D4D7, - 0x1D4D8, - 0x1D4D9, - 0x1D4DA, - 0x1D4DB, - 0x1D4DC, - 0x1D4DD, - 0x1D4DE, - 0x1D4DF, - 0x1D4E0, - 0x1D4E1, - 0x1D4E2, - 0x1D4E3, - 0x1D4E4, - 0x1D4E5, - 0x1D4E6, - 0x1D4E7, - 0x1D4E8, - 0x1D4E9, - 0x1D4EA, - 0x1D4EB, - 0x1D4EC, - 0x1D4ED, - 0x1D4EE, - 0x1D4EF, - 0x1D4F0, - 0x1D4F1, - 0x1D4F2, - 0x1D4F3, - 0x1D4F4, - 0x1D4F5, - 0x1D4F6, - 0x1D4F7, - 0x1D4F8, - 0x1D4F9, - 0x1D4FA, - 0x1D4FB, - 0x1D4FC, - 0x1D4FD, - 0x1D4FE, - 0x1D4FF, - 0x1D500, - 0x1D501, - 0x1D502, - 0x1D503, - 0x1D504, - 0x1D505, - 0x1D506, - 0x1D507, - 0x1D508, - 0x1D509, - 0x1D50A, - 0x1D50B, - 0x1D50D, - 0x1D50E, - 0x1D50F, - 0x1D510, - 0x1D511, - 0x1D512, - 0x1D513, - 0x1D514, - 0x1D515, - 0x1D516, - 0x1D517, - 0x1D518, - 0x1D519, - 0x1D51A, - 0x1D51B, - 0x1D51C, - 0x1D51D, - 0x1D51E, - 0x1D51F, - 0x1D520, - 0x1D521, - 0x1D522, - 0x1D523, - 0x1D524, - 0x1D525, - 0x1D526, - 0x1D527, - 0x1D528, - 0x1D529, - 0x1D52A, - 0x1D52B, - 0x1D52C, - 0x1D52D, - 0x1D52E, - 0x1D52F, - 0x1D530, - 0x1D531, - 0x1D532, - 0x1D533, - 0x1D534, - 0x1D535, - 0x1D536, - 0x1D537, - 0x1D538, - 0x1D539, - 0x1D53A, - 0x1D53B, - 0x1D53C, - 0x1D53D, - 0x1D53E, - 0x1D53F, - 0x1D540, - 0x1D541, - 0x1D542, - 0x1D543, - 0x1D544, - 0x1D545, - 0x1D546, - 0x1D547, - 0x1D54A, - 0x1D54B, - 0x1D54C, - 0x1D54D, - 0x1D54E, - 0x1D54F, - 0x1D550, - 0x1D551, - 0x1D552, - 0x1D553, - 0x1D554, - 0x1D555, - 0x1D556, - 0x1D557, - 0x1D558, - 0x1D559, - 0x1D55A, - 0x1D55B, - 0x1D55C, - 0x1D55D, - 0x1D55E, - 0x1D55F, - 0x1D560, - 0x1D561, - 0x1D562, - 0x1D563, - 0x1D564, - 0x1D565, - 0x1D566, - 0x1D567, - 0x1D568, - 0x1D569, - 0x1D56A, - 0x1D56B, - 0x1D56C, - 0x1D56D, - 0x1D56E, - 0x1D56F, - 0x1D570, - 0x1D571, - 0x1D572, - 0x1D573, - 0x1D574, - 0x1D575, - 0x1D576, - 0x1D577, - 0x1D578, - 0x1D579, - 0x1D57A, - 0x1D57B, - 0x1D57C, - 0x1D57D, - 0x1D57E, - 0x1D57F, - 0x1D580, - 0x1D581, - 0x1D582, - 0x1D583, - 0x1D584, - 0x1D585, - 0x1D586, - 0x1D587, - 0x1D588, - 0x1D589, - 0x1D58A, - 0x1D58B, - 0x1D58C, - 0x1D58D, - 0x1D58E, - 0x1D58F, - 0x1D590, - 0x1D591, - 0x1D592, - 0x1D593, - 0x1D594, - 0x1D595, - 0x1D596, - 0x1D597, - 0x1D598, - 0x1D599, - 0x1D59A, - 0x1D59B, - 0x1D59C, - 0x1D59D, - 0x1D59E, - 0x1D59F, - 0x1D5A0, - 0x1D5A1, - 0x1D5A2, - 0x1D5A3, - 0x1D5A4, - 0x1D5A5, - 0x1D5A6, - 0x1D5A7, - 0x1D5A8, - 0x1D5A9, - 0x1D5AA, - 0x1D5AB, - 0x1D5AC, - 0x1D5AD, - 0x1D5AE, - 0x1D5AF, - 0x1D5B0, - 0x1D5B1, - 0x1D5B2, - 0x1D5B3, - 0x1D5B4, - 0x1D5B5, - 0x1D5B6, - 0x1D5B7, - 0x1D5B8, - 0x1D5B9, - 0x1D5BA, - 0x1D5BB, - 0x1D5BC, - 0x1D5BD, - 0x1D5BE, - 0x1D5BF, - 0x1D5C0, - 0x1D5C1, - 0x1D5C2, - 0x1D5C3, - 0x1D5C4, - 0x1D5C5, - 0x1D5C6, - 0x1D5C7, - 0x1D5C8, - 0x1D5C9, - 0x1D5CA, - 0x1D5CB, - 0x1D5CC, - 0x1D5CD, - 0x1D5CE, - 0x1D5CF, - 0x1D5D0, - 0x1D5D1, - 0x1D5D2, - 0x1D5D3, - 0x1D5D4, - 0x1D5D5, - 0x1D5D6, - 0x1D5D7, - 0x1D5D8, - 0x1D5D9, - 0x1D5DA, - 0x1D5DB, - 0x1D5DC, - 0x1D5DD, - 0x1D5DE, - 0x1D5DF, - 0x1D5E0, - 0x1D5E1, - 0x1D5E2, - 0x1D5E3, - 0x1D5E4, - 0x1D5E5, - 0x1D5E6, - 0x1D5E7, - 0x1D5E8, - 0x1D5E9, - 0x1D5EA, - 0x1D5EB, - 0x1D5EC, - 0x1D5ED, - 0x1D5EE, - 0x1D5EF, - 0x1D5F0, - 0x1D5F1, - 0x1D5F2, - 0x1D5F3, - 0x1D5F4, - 0x1D5F5, - 0x1D5F6, - 0x1D5F7, - 0x1D5F8, - 0x1D5F9, - 0x1D5FA, - 0x1D5FB, - 0x1D5FC, - 0x1D5FD, - 0x1D5FE, - 0x1D5FF, - 0x1D600, - 0x1D601, - 0x1D602, - 0x1D603, - 0x1D604, - 0x1D605, - 0x1D606, - 0x1D607, - 0x1D608, - 0x1D609, - 0x1D60A, - 0x1D60B, - 0x1D60C, - 0x1D60D, - 0x1D60E, - 0x1D60F, - 0x1D610, - 0x1D611, - 0x1D612, - 0x1D613, - 0x1D614, - 0x1D615, - 0x1D616, - 0x1D617, - 0x1D618, - 0x1D619, - 0x1D61A, - 0x1D61B, - 0x1D61C, - 0x1D61D, - 0x1D61E, - 0x1D61F, - 0x1D620, - 0x1D621, - 0x1D622, - 0x1D623, - 0x1D624, - 0x1D625, - 0x1D626, - 0x1D627, - 0x1D628, - 0x1D629, - 0x1D62A, - 0x1D62B, - 0x1D62C, - 0x1D62D, - 0x1D62E, - 0x1D62F, - 0x1D630, - 0x1D631, - 0x1D632, - 0x1D633, - 0x1D634, - 0x1D635, - 0x1D636, - 0x1D637, - 0x1D638, - 0x1D639, - 0x1D63A, - 0x1D63B, - 0x1D63C, - 0x1D63D, - 0x1D63E, - 0x1D63F, - 0x1D640, - 0x1D641, - 0x1D642, - 0x1D643, - 0x1D644, - 0x1D645, - 0x1D646, - 0x1D647, - 0x1D648, - 0x1D649, - 0x1D64A, - 0x1D64B, - 0x1D64C, - 0x1D64D, - 0x1D64E, - 0x1D64F, - 0x1D650, - 0x1D651, - 0x1D652, - 0x1D653, - 0x1D654, - 0x1D655, - 0x1D656, - 0x1D657, - 0x1D658, - 0x1D659, - 0x1D65A, - 0x1D65B, - 0x1D65C, - 0x1D65D, - 0x1D65E, - 0x1D65F, - 0x1D660, - 0x1D661, - 0x1D662, - 0x1D663, - 0x1D664, - 0x1D665, - 0x1D666, - 0x1D667, - 0x1D668, - 0x1D669, - 0x1D66A, - 0x1D66B, - 0x1D66C, - 0x1D66D, - 0x1D66E, - 0x1D66F, - 0x1D670, - 0x1D671, - 0x1D672, - 0x1D673, - 0x1D674, - 0x1D675, - 0x1D676, - 0x1D677, - 0x1D678, - 0x1D679, - 0x1D67A, - 0x1D67B, - 0x1D67C, - 0x1D67D, - 0x1D67E, - 0x1D67F, - 0x1D680, - 0x1D681, - 0x1D682, - 0x1D683, - 0x1D684, - 0x1D685, - 0x1D686, - 0x1D687, - 0x1D688, - 0x1D689, - 0x1D68A, - 0x1D68B, - 0x1D68C, - 0x1D68D, - 0x1D68E, - 0x1D68F, - 0x1D690, - 0x1D691, - 0x1D692, - 0x1D693, - 0x1D694, - 0x1D695, - 0x1D696, - 0x1D697, - 0x1D698, - 0x1D699, - 0x1D69A, - 0x1D69B, - 0x1D69C, - 0x1D69D, - 0x1D69E, - 0x1D69F, - 0x1D6A0, - 0x1D6A1, - 0x1D6A2, - 0x1D6A3, - 0x1D6A4, - 0x1D6A5, - 0x1D6A6, - 0x1D6A8, - 0x1D6A9, - 0x1D6AA, - 0x1D6AB, - 0x1D6AC, - 0x1D6AD, - 0x1D6AE, - 0x1D6AF, - 0x1D6B0, - 0x1D6B1, - 0x1D6B2, - 0x1D6B3, - 0x1D6B4, - 0x1D6B5, - 0x1D6B6, - 0x1D6B7, - 0x1D6B8, - 0x1D6B9, - 0x1D6BA, - 0x1D6BB, - 0x1D6BC, - 0x1D6BD, - 0x1D6BE, - 0x1D6BF, - 0x1D6C0, - 0x1D6C1, - 0x1D6C2, - 0x1D6C3, - 0x1D6C4, - 0x1D6C5, - 0x1D6C6, - 0x1D6C7, - 0x1D6C8, - 0x1D6C9, - 0x1D6CA, - 0x1D6CB, - 0x1D6CC, - 0x1D6CD, - 0x1D6CE, - 0x1D6CF, - 0x1D6D0, - 0x1D6D1, - 0x1D6D2, - 0x1D6D3, - 0x1D6D5, - 0x1D6D6, - 0x1D6D7, - 0x1D6D8, - 0x1D6D9, - 0x1D6DA, - 0x1D6DB, - 0x1D6DC, - 0x1D6DD, - 0x1D6DE, - 0x1D6DF, - 0x1D6E0, - 0x1D6E1, - 0x1D6E2, - 0x1D6E3, - 0x1D6E4, - 0x1D6E5, - 0x1D6E6, - 0x1D6E7, - 0x1D6E8, - 0x1D6E9, - 0x1D6EA, - 0x1D6EB, - 0x1D6EC, - 0x1D6ED, - 0x1D6EE, - 0x1D6EF, - 0x1D6F0, - 0x1D6F1, - 0x1D6F2, - 0x1D6F3, - 0x1D6F4, - 0x1D6F5, - 0x1D6F6, - 0x1D6F7, - 0x1D6F8, - 0x1D6F9, - 0x1D6FA, - 0x1D6FB, - 0x1D6FC, - 0x1D6FD, - 0x1D6FE, - 0x1D6FF, - 0x1D700, - 0x1D701, - 0x1D702, - 0x1D703, - 0x1D704, - 0x1D705, - 0x1D706, - 0x1D707, - 0x1D708, - 0x1D709, - 0x1D70A, - 0x1D70B, - 0x1D70C, - 0x1D70D, - 0x1D70F, - 0x1D710, - 0x1D711, - 0x1D712, - 0x1D713, - 0x1D714, - 0x1D715, - 0x1D716, - 0x1D717, - 0x1D718, - 0x1D719, - 0x1D71A, - 0x1D71B, - 0x1D71C, - 0x1D71D, - 0x1D71E, - 0x1D71F, - 0x1D720, - 0x1D721, - 0x1D722, - 0x1D723, - 0x1D724, - 0x1D725, - 0x1D726, - 0x1D727, - 0x1D728, - 0x1D729, - 0x1D72A, - 0x1D72B, - 0x1D72C, - 0x1D72D, - 0x1D72E, - 0x1D72F, - 0x1D730, - 0x1D731, - 0x1D732, - 0x1D733, - 0x1D734, - 0x1D735, - 0x1D736, - 0x1D737, - 0x1D738, - 0x1D739, - 0x1D73A, - 0x1D73B, - 0x1D73C, - 0x1D73D, - 0x1D73E, - 0x1D73F, - 0x1D740, - 0x1D741, - 0x1D742, - 0x1D743, - 0x1D744, - 0x1D745, - 0x1D746, - 0x1D747, - 0x1D749, - 0x1D74A, - 0x1D74B, - 0x1D74C, - 0x1D74D, - 0x1D74E, - 0x1D74F, - 0x1D750, - 0x1D751, - 0x1D752, - 0x1D753, - 0x1D754, - 0x1D755, - 0x1D756, - 0x1D757, - 0x1D758, - 0x1D759, - 0x1D75A, - 0x1D75B, - 0x1D75C, - 0x1D75D, - 0x1D75E, - 0x1D75F, - 0x1D760, - 0x1D761, - 0x1D762, - 0x1D763, - 0x1D764, - 0x1D765, - 0x1D766, - 0x1D767, - 0x1D768, - 0x1D769, - 0x1D76A, - 0x1D76B, - 0x1D76C, - 0x1D76D, - 0x1D76E, - 0x1D76F, - 0x1D770, - 0x1D771, - 0x1D772, - 0x1D773, - 0x1D774, - 0x1D775, - 0x1D776, - 0x1D777, - 0x1D778, - 0x1D779, - 0x1D77A, - 0x1D77B, - 0x1D77C, - 0x1D77D, - 0x1D77E, - 0x1D77F, - 0x1D780, - 0x1D781, - 0x1D783, - 0x1D784, - 0x1D785, - 0x1D786, - 0x1D787, - 0x1D788, - 0x1D789, - 0x1D78A, - 0x1D78B, - 0x1D78C, - 0x1D78D, - 0x1D78E, - 0x1D78F, - 0x1D790, - 0x1D791, - 0x1D792, - 0x1D793, - 0x1D794, - 0x1D795, - 0x1D796, - 0x1D797, - 0x1D798, - 0x1D799, - 0x1D79A, - 0x1D79B, - 0x1D79C, - 0x1D79D, - 0x1D79E, - 0x1D79F, - 0x1D7A0, - 0x1D7A1, - 0x1D7A2, - 0x1D7A3, - 0x1D7A4, - 0x1D7A5, - 0x1D7A6, - 0x1D7A7, - 0x1D7A8, - 0x1D7A9, - 0x1D7AA, - 0x1D7AB, - 0x1D7AC, - 0x1D7AD, - 0x1D7AE, - 0x1D7AF, - 0x1D7B0, - 0x1D7B1, - 0x1D7B2, - 0x1D7B3, - 0x1D7B4, - 0x1D7B5, - 0x1D7B6, - 0x1D7B7, - 0x1D7B8, - 0x1D7B9, - 0x1D7BA, - 0x1D7BB, - 0x1D7BD, - 0x1D7BE, - 0x1D7BF, - 0x1D7C0, - 0x1D7C1, - 0x1D7C2, - 0x1D7C3, - 0x1D7C4, - 0x1D7C5, - 0x1D7C6, - 0x1D7C7, - 0x1D7C8, - 0x1D7C9, - 0x1D7CA, - 0x1D7CC, - 0x1D7CE, - 0x1D7CF, - 0x1D7D0, - 0x1D7D1, - 0x1D7D2, - 0x1D7D3, - 0x1D7D4, - 0x1D7D5, - 0x1D7D6, - 0x1D7D7, - 0x1D7D8, - 0x1D7D9, - 0x1D7DA, - 0x1D7DB, - 0x1D7DC, - 0x1D7DD, - 0x1D7DE, - 0x1D7DF, - 0x1D7E0, - 0x1D7E1, - 0x1D7E2, - 0x1D7E3, - 0x1D7E4, - 0x1D7E5, - 0x1D7E6, - 0x1D7E7, - 0x1D7E8, - 0x1D7E9, - 0x1D7EA, - 0x1D7EB, - 0x1D7EC, - 0x1D7ED, - 0x1D7EE, - 0x1D7EF, - 0x1D7F0, - 0x1D7F1, - 0x1D7F2, - 0x1D7F3, - 0x1D7F4, - 0x1D7F5, - 0x1D7F6, - 0x1D7F7, - 0x1D7F8, - 0x1D7F9, - 0x1D7FA, - 0x1D7FB, - 0x1D7FC, - 0x1D7FD, - 0x1D7FE, - 0x1D7FF, - 0x1D800, - 0x1DA8C, - 0x1DA9B, - 0x1DAA0, - 0x1DAA1, - 0x1DAB0, - 0x1DF00, - 0x1DF1F, - 0x1DF25, - 0x1DF2B, - 0x1E000, - 0x1E007, - 0x1E008, - 0x1E019, - 0x1E01B, - 0x1E022, - 0x1E023, - 0x1E025, - 0x1E026, - 0x1E02B, - 0x1E030, - 0x1E031, - 0x1E032, - 0x1E033, - 0x1E034, - 0x1E035, - 0x1E036, - 0x1E037, - 0x1E038, - 0x1E039, - 0x1E03A, - 0x1E03B, - 0x1E03C, - 0x1E03D, - 0x1E03E, - 0x1E03F, - 0x1E040, - 0x1E041, - 0x1E042, - 0x1E043, - 0x1E044, - 0x1E045, - 0x1E046, - 0x1E047, - 0x1E048, - 0x1E049, - 0x1E04A, - 0x1E04B, - 0x1E04C, - 0x1E04D, - 0x1E04E, - 0x1E04F, - 0x1E050, - 0x1E051, - 0x1E052, - 0x1E053, - 0x1E054, - 0x1E055, - 0x1E056, - 0x1E057, - 0x1E058, - 0x1E059, - 0x1E05A, - 0x1E05B, - 0x1E05C, - 0x1E05D, - 0x1E05E, - 0x1E05F, - 0x1E060, - 0x1E061, - 0x1E062, - 0x1E063, - 0x1E064, - 0x1E065, - 0x1E066, - 0x1E067, - 0x1E068, - 0x1E069, - 0x1E06A, - 0x1E06B, - 0x1E06C, - 0x1E06D, - 0x1E06E, - 0x1E08F, - 0x1E090, - 0x1E100, - 0x1E12D, - 0x1E130, - 0x1E13E, - 0x1E140, - 0x1E14A, - 0x1E14E, - 0x1E150, - 0x1E290, - 0x1E2AF, - 0x1E2C0, - 0x1E2FA, - 0x1E2FF, - 0x1E300, - 0x1E4D0, - 0x1E4FA, - 0x1E5D0, - 0x1E5FB, - 0x1E5FF, - 0x1E600, - 0x1E6C0, - 0x1E6DF, - 0x1E6E0, - 0x1E6F6, - 0x1E6FE, - 0x1E700, - 0x1E7E0, - 0x1E7E7, - 0x1E7E8, - 0x1E7EC, - 0x1E7ED, - 0x1E7EF, - 0x1E7F0, - 0x1E7FF, - 0x1E800, - 0x1E8C5, - 0x1E8C7, - 0x1E8D7, - 0x1E900, - 0x1E901, - 0x1E902, - 0x1E903, - 0x1E904, - 0x1E905, - 0x1E906, - 0x1E907, - 0x1E908, - 0x1E909, - 0x1E90A, - 0x1E90B, - 0x1E90C, - 0x1E90D, - 0x1E90E, - 0x1E90F, - 0x1E910, - 0x1E911, - 0x1E912, - 0x1E913, - 0x1E914, - 0x1E915, - 0x1E916, - 0x1E917, - 0x1E918, - 0x1E919, - 0x1E91A, - 0x1E91B, - 0x1E91C, - 0x1E91D, - 0x1E91E, - 0x1E91F, - 0x1E920, - 0x1E921, - 0x1E922, - 0x1E94C, - 0x1E950, - 0x1E95A, - 0x1E95E, - 0x1E960, - 0x1EC71, - 0x1ECB5, - 0x1ED01, - 0x1ED3E, - 0x1EE00, - 0x1EE01, - 0x1EE02, - 0x1EE03, - 0x1EE04, - 0x1EE05, - 0x1EE06, - 0x1EE07, - 0x1EE08, - 0x1EE09, - 0x1EE0A, - 0x1EE0B, - 0x1EE0C, - 0x1EE0D, - 0x1EE0E, - 0x1EE0F, - 0x1EE10, - 0x1EE11, - 0x1EE12, - 0x1EE13, - 0x1EE14, - 0x1EE15, - 0x1EE16, - 0x1EE17, - 0x1EE18, - 0x1EE19, - 0x1EE1A, - 0x1EE1B, - 0x1EE1C, - 0x1EE1D, - 0x1EE1E, - 0x1EE1F, - 0x1EE20, - 0x1EE21, - 0x1EE22, - 0x1EE23, - 0x1EE24, - 0x1EE25, - 0x1EE27, - 0x1EE28, - 0x1EE29, - 0x1EE2A, - 0x1EE2B, - 0x1EE2C, - 0x1EE2D, - 0x1EE2E, - 0x1EE2F, - 0x1EE30, - 0x1EE31, - 0x1EE32, - 0x1EE33, - 0x1EE34, - 0x1EE35, - 0x1EE36, - 0x1EE37, - 0x1EE38, - 0x1EE39, - 0x1EE3A, - 0x1EE3B, - 0x1EE3C, - 0x1EE42, - 0x1EE43, - 0x1EE47, - 0x1EE48, - 0x1EE49, - 0x1EE4A, - 0x1EE4B, - 0x1EE4C, - 0x1EE4D, - 0x1EE4E, - 0x1EE4F, - 0x1EE50, - 0x1EE51, - 0x1EE52, - 0x1EE53, - 0x1EE54, - 0x1EE55, - 0x1EE57, - 0x1EE58, - 0x1EE59, - 0x1EE5A, - 0x1EE5B, - 0x1EE5C, - 0x1EE5D, - 0x1EE5E, - 0x1EE5F, - 0x1EE60, - 0x1EE61, - 0x1EE62, - 0x1EE63, - 0x1EE64, - 0x1EE65, - 0x1EE67, - 0x1EE68, - 0x1EE69, - 0x1EE6A, - 0x1EE6B, - 0x1EE6C, - 0x1EE6D, - 0x1EE6E, - 0x1EE6F, - 0x1EE70, - 0x1EE71, - 0x1EE72, - 0x1EE73, - 0x1EE74, - 0x1EE75, - 0x1EE76, - 0x1EE77, - 0x1EE78, - 0x1EE79, - 0x1EE7A, - 0x1EE7B, - 0x1EE7C, - 0x1EE7D, - 0x1EE7E, - 0x1EE7F, - 0x1EE80, - 0x1EE81, - 0x1EE82, - 0x1EE83, - 0x1EE84, - 0x1EE85, - 0x1EE86, - 0x1EE87, - 0x1EE88, - 0x1EE89, - 0x1EE8A, - 0x1EE8B, - 0x1EE8C, - 0x1EE8D, - 0x1EE8E, - 0x1EE8F, - 0x1EE90, - 0x1EE91, - 0x1EE92, - 0x1EE93, - 0x1EE94, - 0x1EE95, - 0x1EE96, - 0x1EE97, - 0x1EE98, - 0x1EE99, - 0x1EE9A, - 0x1EE9B, - 0x1EE9C, - 0x1EEA1, - 0x1EEA2, - 0x1EEA3, - 0x1EEA4, - 0x1EEA5, - 0x1EEA6, - 0x1EEA7, - 0x1EEA8, - 0x1EEA9, - 0x1EEAA, - 0x1EEAB, - 0x1EEAC, - 0x1EEAD, - 0x1EEAE, - 0x1EEAF, - 0x1EEB0, - 0x1EEB1, - 0x1EEB2, - 0x1EEB3, - 0x1EEB4, - 0x1EEB5, - 0x1EEB6, - 0x1EEB7, - 0x1EEB8, - 0x1EEB9, - 0x1EEBA, - 0x1EEBB, - 0x1EEBC, - 0x1EEF0, - 0x1EEF2, - 0x1F000, - 0x1F02C, - 0x1F030, - 0x1F094, - 0x1F0A0, - 0x1F0AF, - 0x1F0B1, - 0x1F0C0, - 0x1F0C1, - 0x1F0D0, - 0x1F0D1, - 0x1F0F6, - 0x1F101, - 0x1F102, - 0x1F103, - 0x1F104, - 0x1F105, - 0x1F106, - 0x1F107, - 0x1F108, - 0x1F109, - 0x1F10A, - 0x1F10B, - 0x1F110, - 0x1F111, - 0x1F112, - 0x1F113, - 0x1F114, - 0x1F115, - 0x1F116, - 0x1F117, - 0x1F118, - 0x1F119, - 0x1F11A, - 0x1F11B, - 0x1F11C, - 0x1F11D, - 0x1F11E, - 0x1F11F, - 0x1F120, - 0x1F121, - 0x1F122, - 0x1F123, - 0x1F124, - 0x1F125, - 0x1F126, - 0x1F127, - 0x1F128, - 0x1F129, - 0x1F12A, - 0x1F12B, - 0x1F12C, - 0x1F12D, - 0x1F12E, - 0x1F12F, - 0x1F130, - 0x1F131, - 0x1F132, - 0x1F133, - 0x1F134, - 0x1F135, - 0x1F136, - 0x1F137, - 0x1F138, - 0x1F139, - 0x1F13A, - 0x1F13B, - 0x1F13C, - 0x1F13D, - 0x1F13E, - 0x1F13F, - 0x1F140, - 0x1F141, - 0x1F142, - 0x1F143, - 0x1F144, - 0x1F145, - 0x1F146, - 0x1F147, - 0x1F148, - 0x1F149, - 0x1F14A, - 0x1F14B, - 0x1F14C, - 0x1F14D, - 0x1F14E, - 0x1F14F, - 0x1F150, - 0x1F16A, - 0x1F16B, - 0x1F16C, - 0x1F16D, - 0x1F190, - 0x1F191, - 0x1F1AE, - 0x1F1E6, - 0x1F200, - 0x1F201, - 0x1F202, - 0x1F203, - 0x1F210, - 0x1F211, - 0x1F212, - 0x1F213, - 0x1F214, - 0x1F215, - 0x1F216, - 0x1F217, - 0x1F218, - 0x1F219, - 0x1F21A, - 0x1F21B, - 0x1F21C, - 0x1F21D, - 0x1F21E, - 0x1F21F, - 0x1F220, - 0x1F221, - 0x1F222, - 0x1F223, - 0x1F224, - 0x1F225, - 0x1F226, - 0x1F227, - 0x1F228, - 0x1F229, - 0x1F22A, - 0x1F22B, - 0x1F22C, - 0x1F22D, - 0x1F22E, - 0x1F22F, - 0x1F230, - 0x1F231, - 0x1F232, - 0x1F233, - 0x1F234, - 0x1F235, - 0x1F236, - 0x1F237, - 0x1F238, - 0x1F239, - 0x1F23A, - 0x1F23B, - 0x1F23C, - 0x1F240, - 0x1F241, - 0x1F242, - 0x1F243, - 0x1F244, - 0x1F245, - 0x1F246, - 0x1F247, - 0x1F248, - 0x1F249, - 0x1F250, - 0x1F251, - 0x1F252, - 0x1F260, - 0x1F266, - 0x1F300, - 0x1F6D9, - 0x1F6DC, - 0x1F6ED, - 0x1F6F0, - 0x1F6FD, - 0x1F700, - 0x1F7DA, - 0x1F7E0, - 0x1F7EC, - 0x1F7F0, - 0x1F7F1, - 0x1F800, - 0x1F80C, - 0x1F810, - 0x1F848, - 0x1F850, - 0x1F85A, - 0x1F860, - 0x1F888, - 0x1F890, - 0x1F8AE, - 0x1F8B0, - 0x1F8BC, - 0x1F8C0, - 0x1F8C2, - 0x1F8D0, - 0x1F8D9, - 0x1F900, - 0x1FA58, - 0x1FA60, - 0x1FA6E, - 0x1FA70, - 0x1FA7D, - 0x1FA80, - 0x1FA8B, - 0x1FA8E, - 0x1FAC7, - 0x1FAC8, - 0x1FAC9, - 0x1FACD, - 0x1FADD, - 0x1FADF, - 0x1FAEB, - 0x1FAEF, - 0x1FAF9, - 0x1FB00, - 0x1FB93, - 0x1FB94, - 0x1FBF0, - 0x1FBF1, - 0x1FBF2, - 0x1FBF3, - 0x1FBF4, - 0x1FBF5, - 0x1FBF6, - 0x1FBF7, - 0x1FBF8, - 0x1FBF9, - 0x1FBFA, - 0x1FBFB, - 0x20000, - 0x2A6E0, - 0x2A700, - 0x2B81E, - 0x2B820, - 0x2CEAE, - 0x2CEB0, - 0x2EBE1, - 0x2EBF0, - 0x2EE5E, - 0x2F800, - 0x2F801, - 0x2F802, - 0x2F803, - 0x2F804, - 0x2F805, - 0x2F806, - 0x2F807, - 0x2F808, - 0x2F809, - 0x2F80A, - 0x2F80B, - 0x2F80C, - 0x2F80D, - 0x2F80E, - 0x2F80F, - 0x2F810, - 0x2F811, - 0x2F812, - 0x2F813, - 0x2F814, - 0x2F815, - 0x2F816, - 0x2F817, - 0x2F818, - 0x2F819, - 0x2F81A, - 0x2F81B, - 0x2F81C, - 0x2F81D, - 0x2F81E, - 0x2F81F, - 0x2F820, - 0x2F821, - 0x2F822, - 0x2F823, - 0x2F824, - 0x2F825, - 0x2F826, - 0x2F827, - 0x2F828, - 0x2F829, - 0x2F82A, - 0x2F82B, - 0x2F82C, - 0x2F82D, - 0x2F82E, - 0x2F82F, - 0x2F830, - 0x2F831, - 0x2F834, - 0x2F835, - 0x2F836, - 0x2F837, - 0x2F838, - 0x2F839, - 0x2F83A, - 0x2F83B, - 0x2F83C, - 0x2F83D, - 0x2F83E, - 0x2F83F, - 0x2F840, - 0x2F841, - 0x2F842, - 0x2F843, - 0x2F844, - 0x2F845, - 0x2F847, - 0x2F848, - 0x2F849, - 0x2F84A, - 0x2F84B, - 0x2F84C, - 0x2F84D, - 0x2F84E, - 0x2F84F, - 0x2F850, - 0x2F851, - 0x2F852, - 0x2F853, - 0x2F854, - 0x2F855, - 0x2F856, - 0x2F857, - 0x2F858, - 0x2F859, - 0x2F85A, - 0x2F85B, - 0x2F85C, - 0x2F85D, - 0x2F85E, - 0x2F85F, - 0x2F860, - 0x2F861, - 0x2F862, - 0x2F863, - 0x2F864, - 0x2F865, - 0x2F866, - 0x2F867, - 0x2F868, - 0x2F869, - 0x2F86A, - 0x2F86C, - 0x2F86D, - 0x2F86E, - 0x2F86F, - 0x2F870, - 0x2F871, - 0x2F872, - 0x2F873, - 0x2F874, - 0x2F875, - 0x2F876, - 0x2F877, - 0x2F878, - 0x2F879, - 0x2F87A, - 0x2F87B, - 0x2F87C, - 0x2F87D, - 0x2F87E, - 0x2F87F, - 0x2F880, - 0x2F881, - 0x2F882, - 0x2F883, - 0x2F884, - 0x2F885, - 0x2F886, - 0x2F887, - 0x2F888, - 0x2F889, - 0x2F88A, - 0x2F88B, - 0x2F88C, - 0x2F88D, - 0x2F88E, - 0x2F88F, - 0x2F890, - 0x2F891, - 0x2F893, - 0x2F894, - 0x2F896, - 0x2F897, - 0x2F898, - 0x2F899, - 0x2F89A, - 0x2F89B, - 0x2F89C, - 0x2F89D, - 0x2F89E, - 0x2F89F, - 0x2F8A0, - 0x2F8A1, - 0x2F8A2, - 0x2F8A3, - 0x2F8A4, - 0x2F8A5, - 0x2F8A6, - 0x2F8A7, - 0x2F8A8, - 0x2F8A9, - 0x2F8AA, - 0x2F8AB, - 0x2F8AC, - 0x2F8AD, - 0x2F8AE, - 0x2F8AF, - 0x2F8B0, - 0x2F8B1, - 0x2F8B2, - 0x2F8B3, - 0x2F8B4, - 0x2F8B5, - 0x2F8B6, - 0x2F8B7, - 0x2F8B8, - 0x2F8B9, - 0x2F8BA, - 0x2F8BB, - 0x2F8BC, - 0x2F8BD, - 0x2F8BE, - 0x2F8BF, - 0x2F8C0, - 0x2F8C1, - 0x2F8C2, - 0x2F8C3, - 0x2F8C4, - 0x2F8C5, - 0x2F8C6, - 0x2F8C7, - 0x2F8C8, - 0x2F8C9, - 0x2F8CA, - 0x2F8CB, - 0x2F8CC, - 0x2F8CD, - 0x2F8CE, - 0x2F8CF, - 0x2F8D0, - 0x2F8D1, - 0x2F8D2, - 0x2F8D3, - 0x2F8D4, - 0x2F8D5, - 0x2F8D6, - 0x2F8D7, - 0x2F8D8, - 0x2F8D9, - 0x2F8DA, - 0x2F8DB, - 0x2F8DC, - 0x2F8DD, - 0x2F8DE, - 0x2F8DF, - 0x2F8E0, - 0x2F8E1, - 0x2F8E2, - 0x2F8E3, - 0x2F8E4, - 0x2F8E5, - 0x2F8E6, - 0x2F8E7, - 0x2F8E8, - 0x2F8E9, - 0x2F8EA, - 0x2F8EB, - 0x2F8EC, - 0x2F8ED, - 0x2F8EE, - 0x2F8EF, - 0x2F8F0, - 0x2F8F1, - 0x2F8F2, - 0x2F8F3, - 0x2F8F4, - 0x2F8F5, - 0x2F8F6, - 0x2F8F7, - 0x2F8F8, - 0x2F8F9, - 0x2F8FA, - 0x2F8FB, - 0x2F8FC, - 0x2F8FD, - 0x2F8FE, - 0x2F8FF, - 0x2F900, - 0x2F901, - 0x2F902, - 0x2F903, - 0x2F904, - 0x2F905, - 0x2F906, - 0x2F907, - 0x2F908, - 0x2F909, - 0x2F90A, - 0x2F90B, - 0x2F90C, - 0x2F90D, - 0x2F90E, - 0x2F90F, - 0x2F910, - 0x2F911, - 0x2F912, - 0x2F913, - 0x2F914, - 0x2F915, - 0x2F916, - 0x2F917, - 0x2F918, - 0x2F919, - 0x2F91A, - 0x2F91B, - 0x2F91C, - 0x2F91D, - 0x2F91E, - 0x2F91F, - 0x2F920, - 0x2F921, - 0x2F922, - 0x2F923, - 0x2F924, - 0x2F925, - 0x2F926, - 0x2F927, - 0x2F928, - 0x2F929, - 0x2F92A, - 0x2F92B, - 0x2F92C, - 0x2F92E, - 0x2F92F, - 0x2F930, - 0x2F931, - 0x2F932, - 0x2F933, - 0x2F934, - 0x2F935, - 0x2F936, - 0x2F937, - 0x2F938, - 0x2F939, - 0x2F93A, - 0x2F93B, - 0x2F93C, - 0x2F93D, - 0x2F93E, - 0x2F93F, - 0x2F940, - 0x2F941, - 0x2F942, - 0x2F943, - 0x2F944, - 0x2F945, - 0x2F946, - 0x2F948, - 0x2F949, - 0x2F94A, - 0x2F94B, - 0x2F94C, - 0x2F94D, - 0x2F94E, - 0x2F94F, - 0x2F950, - 0x2F951, - 0x2F952, - 0x2F953, - 0x2F954, - 0x2F955, - 0x2F956, - 0x2F957, - 0x2F958, - 0x2F959, - 0x2F95A, - 0x2F95B, - 0x2F95C, - 0x2F95D, - 0x2F95F, - 0x2F960, - 0x2F961, - 0x2F962, - 0x2F963, - 0x2F964, - 0x2F965, - 0x2F966, - 0x2F967, - 0x2F968, - 0x2F969, - 0x2F96A, - 0x2F96B, - 0x2F96C, - 0x2F96D, - 0x2F96E, - 0x2F96F, - 0x2F970, - 0x2F971, - 0x2F972, - 0x2F973, - 0x2F974, - 0x2F975, - 0x2F976, - 0x2F977, - 0x2F978, - 0x2F979, - 0x2F97A, - 0x2F97B, - 0x2F97C, - 0x2F97D, - 0x2F97E, - 0x2F97F, - 0x2F980, - 0x2F981, - 0x2F982, - 0x2F983, - 0x2F984, - 0x2F985, - 0x2F986, - 0x2F987, - 0x2F988, - 0x2F989, - 0x2F98A, - 0x2F98B, - 0x2F98C, - 0x2F98D, - 0x2F98E, - 0x2F98F, - 0x2F990, - 0x2F991, - 0x2F992, - 0x2F993, - 0x2F994, - 0x2F995, - 0x2F996, - 0x2F997, - 0x2F998, - 0x2F999, - 0x2F99A, - 0x2F99B, - 0x2F99C, - 0x2F99D, - 0x2F99E, - 0x2F99F, - 0x2F9A0, - 0x2F9A1, - 0x2F9A2, - 0x2F9A3, - 0x2F9A4, - 0x2F9A5, - 0x2F9A6, - 0x2F9A7, - 0x2F9A8, - 0x2F9A9, - 0x2F9AA, - 0x2F9AB, - 0x2F9AC, - 0x2F9AD, - 0x2F9AE, - 0x2F9AF, - 0x2F9B0, - 0x2F9B1, - 0x2F9B2, - 0x2F9B3, - 0x2F9B4, - 0x2F9B5, - 0x2F9B6, - 0x2F9B7, - 0x2F9B8, - 0x2F9B9, - 0x2F9BA, - 0x2F9BB, - 0x2F9BC, - 0x2F9BD, - 0x2F9BE, - 0x2F9BF, - 0x2F9C0, - 0x2F9C1, - 0x2F9C2, - 0x2F9C3, - 0x2F9C4, - 0x2F9C5, - 0x2F9C6, - 0x2F9C7, - 0x2F9C8, - 0x2F9C9, - 0x2F9CA, - 0x2F9CB, - 0x2F9CC, - 0x2F9CD, - 0x2F9CE, - 0x2F9CF, - 0x2F9D0, - 0x2F9D1, - 0x2F9D2, - 0x2F9D3, - 0x2F9D4, - 0x2F9D5, - 0x2F9D6, - 0x2F9D7, - 0x2F9D8, - 0x2F9D9, - 0x2F9DA, - 0x2F9DB, - 0x2F9DC, - 0x2F9DD, - 0x2F9DE, - 0x2F9DF, - 0x2F9E0, - 0x2F9E1, - 0x2F9E2, - 0x2F9E3, - 0x2F9E4, - 0x2F9E5, - 0x2F9E6, - 0x2F9E7, - 0x2F9E8, - 0x2F9E9, - 0x2F9EA, - 0x2F9EB, - 0x2F9EC, - 0x2F9ED, - 0x2F9EE, - 0x2F9EF, - 0x2F9F0, - 0x2F9F1, - 0x2F9F2, - 0x2F9F3, - 0x2F9F4, - 0x2F9F5, - 0x2F9F6, - 0x2F9F7, - 0x2F9F8, - 0x2F9F9, - 0x2F9FA, - 0x2F9FB, - 0x2F9FC, - 0x2F9FD, - 0x2F9FE, - 0x2FA00, - 0x2FA01, - 0x2FA02, - 0x2FA03, - 0x2FA04, - 0x2FA05, - 0x2FA06, - 0x2FA07, - 0x2FA08, - 0x2FA09, - 0x2FA0A, - 0x2FA0B, - 0x2FA0C, - 0x2FA0D, - 0x2FA0E, - 0x2FA0F, - 0x2FA10, - 0x2FA11, - 0x2FA12, - 0x2FA13, - 0x2FA14, - 0x2FA15, - 0x2FA16, - 0x2FA17, - 0x2FA18, - 0x2FA19, - 0x2FA1A, - 0x2FA1B, - 0x2FA1C, - 0x2FA1D, - 0x2FA1E, - 0x30000, - 0x3134B, - 0x31350, - 0x3347A, - 0xE0100, - 0xE01F0, - ), -) - -uts46_statuses: bytes = ( - b"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV" - b"VMMMMMMMMMMMMMMMMMMMMMMMMMMVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV" - b"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXMVVVVVVVMVMVVIVMVVMMMMVVMMMVMMMV" - b"MMMMMMMMMMMMMMMMMMMMMMMVMMMMMMMDVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV" - b"MVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMMVMVMVMVMVMMV" - b"MVMVMVMMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMMVMVMVMVMM" - b"VMVMMVMMMVMMMMVMMVMMMVMMVMMVMVMVMMVMVMVMMVMMMVMVMMVMVMMMMVMVMVMV" - b"MVMVMVMVMVMVMVMVMVMVMVMVMVMMVMMMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVM" - b"VMVMVMVMVMVMVMVMVMVMVMVMVMVMMVMMVMVMMMMVMVMVMVMVMMMMMMMMMVMMMMMM" - b"VMMMMMVMMVMMMVIVMVMVMVMVXMVMMXMMMMMMMXMXMMVMMMMMMMMMMMMMMMMMXMMM" - b"MMMMMMVDVMMMMMMMMVMVMVMVMVMVMVMVMVMVMVMVMVMMMVMMVMVMMVMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMVMVMVMVMVMVMVMVMVMVMV" - b"MVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMV" - b"MVMMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVM" - b"VMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVXMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMXVMVXVXVXVXVXVXVMMMMVXVXVXVXVXVXVXVXVXVX" - b"VXVXVMMMMMMMMVXVXVXVXVXVXVXVXVXVXVXMMXMVXVXVXVXVXVXVXVMXVMXVXVXV" - b"XVXVXVXMMMVXMXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVX" - b"VXMMXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXV" - b"XVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXV" - b"XVMVXVXVXVXVXVXVXVMVXVXVXVXVXMMVXVMVMVXVMVMVMVMVMVXVMVMMMMMVMVMV" - b"XVMVMVMVMVMVXVXVXVMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMXMXVMV" - b"IVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXMMMMMMXVXVXVXVXVXVXVXVXVX" - b"VIVXVXVXVIVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVMMM" - b"MMMMMMVXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMVXVXVMMMV" - b"MMMMMMMMMMMVMMMMMMMMMMMMMMMMMMVMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMVMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMVMVMVMVMVMVMVMVMVMVMVMVMVMV" - b"MVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMV" - b"MVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMMVMVM" - b"VMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVM" - b"VMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMMMMMMMMVXMMMMMMXVMMMMMMMMVMMMMMM" - b"MMVXMMMMMMXVXMXMXMXMVMMMMMMMMVMVMVMVMVMVMVMXMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMVMMMXVMMMMMMMMMMMMMMXVMMMMMMMMMVMXVM" - b"MMMXMMMVMVMMMMMMMMXMMMXVMMMMMMMMXMIDXVMVMVXVXMVMMVMMVMVMVMMMVMVM" - b"IXIMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMMMMMMMMMMMXVMVXVXMMMMVMMMVM" - b"MMMMMVMMVMMMVMMMVMVMVMVMMMMVMMMMMMMMMMVMMMMMVMMMMVMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMVMVXVMMVMMVMMVXVXMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMVMMMVMVXVMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMVMMMVMVMVMVMMMMVMVMVMM" - b"MMMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMV" - b"MVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVXVXVXVXVXMVXVXVXVXVX" - b"VXVXVXVXVXVXVXVMVMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMVMVMVMMMVXVXVMMVMVMXV" - b"XMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMIMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXVMMMMMMMMMMMMMMVXVMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMMXMMMMMMMMMMMMM" - b"MMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVXVXVXMVMVMVMVMVMVMVM" - b"VMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMMVXV" - b"MVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMV" - b"MVMVMVMVMVMVMVMVMVMMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMMMMMVM" - b"MMMMVMVMVMVMVMVMVMVMMMMVMVMMVMVMVMVMVMVMVMVMXMMMMMVMMVXVXVXVXVXV" - b"XVXVXVXVXVXVXVXVXVXVXVXVXVXVXVMMMMVMVXMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVXVXVXVXVX" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMVMVMVMMMMMMMMMMVMVMVMMVMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMXMMMMMMXMMMMMXMVMMMMMMMMMMMMMMMMMMMMMMMMXMMMMM" - b"XMXMMXMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMVMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVXMMMMMMMMMMMMMVIMMXMMM" - b"MMMXVXMMMMMMMMMMMMMMMMMMMVMMMMMMXMMMMMMMMMMMMMMMMMMMXMMMMXMMMVMX" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXIXMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMIMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMMMMXMMMMM" - b"MXMMMMMMXMMMXMMMMMMMXMMMMMMMXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXV" - b"XVXVXVXVXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVXVXMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMXVXVXVXVMMMMMMMMMMMXMMMMMMMMMMMMMMMXMMM" - b"MMMMXMMXVXVXVXVXVXVXVXVXVMMMMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMXMMMMMMMMMXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVX" - b"VXVXVXVXVXVXVXVXVXVXVXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMXVXVXVXVMMMMMMMMMMMMMMMMMMMMMMXVXVXVXVXVXVXVXVXVXVXVXVX" - b"VXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVX" - b"VXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVX" - b"VXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVX" - b"VXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMVXMMMMMMMMMMMMMMMMMMMMMMMMMXVXVXVXVXVXVXVXVXVXVXVXVXVX" - b"VXVXVXVXVXVXVXVXVXVIXVMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVXVXVX" - b"VXVXVXVXVXVXVMMMMMMMVIVMMMMMMVXVXVXVXVXVXMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMXMMXMXMMXMMMMXMMMMMMMMMMMMXMXMMMMMMMXMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMMXMMMMMMMMXMMMMM" - b"MMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMMXMMMMMXMXMMMMMMMXMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMVXVXVXVXVXVXVXVXVXVXMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXVXVXVXVXVXVXVXVXVX" - b"VXVXVXVXVXVXVXVXVXVXVXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVXVXVXVX" - b"VXMMMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMXMXMXMMMMMMMMMMXMMMMXMXMXMX" - b"MXMXMXMMMXMMXMXMXMXMXMXMXMMXMXMMMMXMMMMMMMXMMMMXMMMMXMXMMMMMMMMM" - b"MXMMMMMMMMMMMMMMMMMXMMMXMMMMMXMMMMMMMMMMMMMMMMMXVXVXVXVXVXVXVXMM" - b"MMMMMMMMVMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMVMMMVMVXVMMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMXMMMMMMMMMXMMXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVX" - b"VXVMMMMMMMMMMVXVXVXVXVXVXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXVXVXIX" -) - -uts46_replacements: tuple[Optional[str], ...] = ( - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "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", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - " ", - None, - None, - None, - None, - None, - None, - None, - " ̈", - None, - "a", - None, - None, - None, - None, - " ̄", - None, - None, - "2", - "3", - " ́", - "μ", - None, - None, - " ̧", - "1", - "o", - None, - "1⁄4", - "1⁄2", - "3⁄4", - None, - "à", - "á", - "â", - "ã", - "ä", - "å", - "æ", - "ç", - "è", - "é", - "ê", - "ë", - "ì", - "í", - "î", - "ï", - "ð", - "ñ", - "ò", - "ó", - "ô", - "õ", - "ö", - None, - "ø", - "ù", - "ú", - "û", - "ü", - "ý", - "þ", - "ss", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "ā", - None, - "ă", - None, - "ą", - None, - "ć", - None, - "ĉ", - None, - "ċ", - None, - "č", - None, - "ď", - None, - "đ", - None, - "ē", - None, - "ĕ", - None, - "ė", - None, - "ę", - None, - "ě", - None, - "ĝ", - None, - "ğ", - None, - "ġ", - None, - "ģ", - None, - "ĥ", - None, - "ħ", - None, - "ĩ", - None, - "ī", - None, - "ĭ", - None, - "į", - None, - "i̇", - None, - "ij", - "ĵ", - None, - "ķ", - None, - "ĺ", - None, - "ļ", - None, - "ľ", - None, - "l·", - "ł", - None, - "ń", - None, - "ņ", - None, - "ň", - None, - "ʼn", - "ŋ", - None, - "ō", - None, - "ŏ", - None, - "ő", - None, - "œ", - None, - "ŕ", - None, - "ŗ", - None, - "ř", - None, - "ś", - None, - "ŝ", - None, - "ş", - None, - "š", - None, - "ţ", - None, - "ť", - None, - "ŧ", - None, - "ũ", - None, - "ū", - None, - "ŭ", - None, - "ů", - None, - "ű", - None, - "ų", - None, - "ŵ", - None, - "ŷ", - None, - "ÿ", - "ź", - None, - "ż", - None, - "ž", - None, - "s", - None, - "ɓ", - "ƃ", - None, - "ƅ", - None, - "ɔ", - "ƈ", - None, - "ɖ", - "ɗ", - "ƌ", - None, - "ǝ", - "ə", - "ɛ", - "ƒ", - None, - "ɠ", - "ɣ", - None, - "ɩ", - "ɨ", - "ƙ", - None, - "ɯ", - "ɲ", - None, - "ɵ", - "ơ", - None, - "ƣ", - None, - "ƥ", - None, - "ʀ", - "ƨ", - None, - "ʃ", - None, - "ƭ", - None, - "ʈ", - "ư", - None, - "ʊ", - "ʋ", - "ƴ", - None, - "ƶ", - None, - "ʒ", - "ƹ", - None, - "ƽ", - None, - "dž", - "lj", - "nj", - "ǎ", - None, - "ǐ", - None, - "ǒ", - None, - "ǔ", - None, - "ǖ", - None, - "ǘ", - None, - "ǚ", - None, - "ǜ", - None, - "ǟ", - None, - "ǡ", - None, - "ǣ", - None, - "ǥ", - None, - "ǧ", - None, - "ǩ", - None, - "ǫ", - None, - "ǭ", - None, - "ǯ", - None, - "dz", - "ǵ", - None, - "ƕ", - "ƿ", - "ǹ", - None, - "ǻ", - None, - "ǽ", - None, - "ǿ", - None, - "ȁ", - None, - "ȃ", - None, - "ȅ", - None, - "ȇ", - None, - "ȉ", - None, - "ȋ", - None, - "ȍ", - None, - "ȏ", - None, - "ȑ", - None, - "ȓ", - None, - "ȕ", - None, - "ȗ", - None, - "ș", - None, - "ț", - None, - "ȝ", - None, - "ȟ", - None, - "ƞ", - None, - "ȣ", - None, - "ȥ", - None, - "ȧ", - None, - "ȩ", - None, - "ȫ", - None, - "ȭ", - None, - "ȯ", - None, - "ȱ", - None, - "ȳ", - None, - "ⱥ", - "ȼ", - None, - "ƚ", - "ⱦ", - None, - "ɂ", - None, - "ƀ", - "ʉ", - "ʌ", - "ɇ", - None, - "ɉ", - None, - "ɋ", - None, - "ɍ", - None, - "ɏ", - None, - "h", - "ɦ", - "j", - "r", - "ɹ", - "ɻ", - "ʁ", - "w", - "y", - None, - " ̆", - " ̇", - " ̊", - " ̨", - " ̃", - " ̋", - None, - "ɣ", - "l", - "s", - "x", - "ʕ", - None, - "̀", - "́", - None, - "̓", - "̈́", - "ι", - None, - None, - None, - "ͱ", - None, - "ͳ", - None, - "ʹ", - None, - "ͷ", - None, - None, - " ι", - None, - ";", - "ϳ", - None, - " ́", - " ̈́", - "ά", - "·", - "έ", - "ή", - "ί", - None, - "ό", - None, - "ύ", - "ώ", - None, - "α", - "β", - "γ", - "δ", - "ε", - "ζ", - "η", - "θ", - "ι", - "κ", - "λ", - "μ", - "ν", - "ξ", - "ο", - "π", - "ρ", - None, - "σ", - "τ", - "υ", - "φ", - "χ", - "ψ", - "ω", - "ϊ", - "ϋ", - None, - "σ", - None, - "ϗ", - "β", - "θ", - "υ", - "ύ", - "ϋ", - "φ", - "π", - None, - "ϙ", - None, - "ϛ", - None, - "ϝ", - None, - "ϟ", - None, - "ϡ", - None, - "ϣ", - None, - "ϥ", - None, - "ϧ", - None, - "ϩ", - None, - "ϫ", - None, - "ϭ", - None, - "ϯ", - None, - "κ", - "ρ", - "σ", - None, - "θ", - "ε", - None, - "ϸ", - None, - "σ", - "ϻ", - None, - "ͻ", - "ͼ", - "ͽ", - "ѐ", - "ё", - "ђ", - "ѓ", - "є", - "ѕ", - "і", - "ї", - "ј", - "љ", - "њ", - "ћ", - "ќ", - "ѝ", - "ў", - "џ", - "а", - "б", - "в", - "г", - "д", - "е", - "ж", - "з", - "и", - "й", - "к", - "л", - "м", - "н", - "о", - "п", - "р", - "с", - "т", - "у", - "ф", - "х", - "ц", - "ч", - "ш", - "щ", - "ъ", - "ы", - "ь", - "э", - "ю", - "я", - None, - "ѡ", - None, - "ѣ", - None, - "ѥ", - None, - "ѧ", - None, - "ѩ", - None, - "ѫ", - None, - "ѭ", - None, - "ѯ", - None, - "ѱ", - None, - "ѳ", - None, - "ѵ", - None, - "ѷ", - None, - "ѹ", - None, - "ѻ", - None, - "ѽ", - None, - "ѿ", - None, - "ҁ", - None, - "ҋ", - None, - "ҍ", - None, - "ҏ", - None, - "ґ", - None, - "ғ", - None, - "ҕ", - None, - "җ", - None, - "ҙ", - None, - "қ", - None, - "ҝ", - None, - "ҟ", - None, - "ҡ", - None, - "ң", - None, - "ҥ", - None, - "ҧ", - None, - "ҩ", - None, - "ҫ", - None, - "ҭ", - None, - "ү", - None, - "ұ", - None, - "ҳ", - None, - "ҵ", - None, - "ҷ", - None, - "ҹ", - None, - "һ", - None, - "ҽ", - None, - "ҿ", - None, - "ӏ", - "ӂ", - None, - "ӄ", - None, - "ӆ", - None, - "ӈ", - None, - "ӊ", - None, - "ӌ", - None, - "ӎ", - None, - "ӑ", - None, - "ӓ", - None, - "ӕ", - None, - "ӗ", - None, - "ә", - None, - "ӛ", - None, - "ӝ", - None, - "ӟ", - None, - "ӡ", - None, - "ӣ", - None, - "ӥ", - None, - "ӧ", - None, - "ө", - None, - "ӫ", - None, - "ӭ", - None, - "ӯ", - None, - "ӱ", - None, - "ӳ", - None, - "ӵ", - None, - "ӷ", - None, - "ӹ", - None, - "ӻ", - None, - "ӽ", - None, - "ӿ", - None, - "ԁ", - None, - "ԃ", - None, - "ԅ", - None, - "ԇ", - None, - "ԉ", - None, - "ԋ", - None, - "ԍ", - None, - "ԏ", - None, - "ԑ", - None, - "ԓ", - None, - "ԕ", - None, - "ԗ", - None, - "ԙ", - None, - "ԛ", - None, - "ԝ", - None, - "ԟ", - None, - "ԡ", - None, - "ԣ", - None, - "ԥ", - None, - "ԧ", - None, - "ԩ", - None, - "ԫ", - None, - "ԭ", - None, - "ԯ", - None, - None, - "ա", - "բ", - "գ", - "դ", - "ե", - "զ", - "է", - "ը", - "թ", - "ժ", - "ի", - "լ", - "խ", - "ծ", - "կ", - "հ", - "ձ", - "ղ", - "ճ", - "մ", - "յ", - "ն", - "շ", - "ո", - "չ", - "պ", - "ջ", - "ռ", - "ս", - "վ", - "տ", - "ր", - "ց", - "ւ", - "փ", - "ք", - "օ", - "ֆ", - None, - None, - "եւ", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "اٴ", - "وٴ", - "ۇٴ", - "يٴ", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "क़", - "ख़", - "ग़", - "ज़", - "ड़", - "ढ़", - "फ़", - "य़", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "ড়", - "ঢ়", - None, - "য়", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "ਲ਼", - None, - None, - "ਸ਼", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "ਖ਼", - "ਗ਼", - "ਜ਼", - None, - None, - "ਫ਼", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "ଡ଼", - "ଢ଼", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "ํา", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "ໍາ", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "ຫນ", - "ຫມ", - None, - None, - None, - "་", - None, - "གྷ", - None, - None, - None, - "ཌྷ", - None, - "དྷ", - None, - "བྷ", - None, - "ཛྷ", - None, - "ཀྵ", - None, - None, - None, - "ཱི", - None, - "ཱུ", - "ྲྀ", - "ྲཱྀ", - "ླྀ", - "ླཱྀ", - None, - "ཱྀ", - None, - "ྒྷ", - None, - None, - None, - "ྜྷ", - None, - "ྡྷ", - None, - "ྦྷ", - None, - "ྫྷ", - None, - "ྐྵ", - None, - None, - None, - None, - None, - None, - None, - "ⴀ", - "ⴁ", - "ⴂ", - "ⴃ", - "ⴄ", - "ⴅ", - "ⴆ", - "ⴇ", - "ⴈ", - "ⴉ", - "ⴊ", - "ⴋ", - "ⴌ", - "ⴍ", - "ⴎ", - "ⴏ", - "ⴐ", - "ⴑ", - "ⴒ", - "ⴓ", - "ⴔ", - "ⴕ", - "ⴖ", - "ⴗ", - "ⴘ", - "ⴙ", - "ⴚ", - "ⴛ", - "ⴜ", - "ⴝ", - "ⴞ", - "ⴟ", - "ⴠ", - "ⴡ", - "ⴢ", - "ⴣ", - "ⴤ", - "ⴥ", - None, - "ⴧ", - None, - "ⴭ", - None, - None, - "ნ", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "Ᏸ", - "Ᏹ", - "Ᏺ", - "Ᏻ", - "Ᏼ", - "Ᏽ", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "в", - "д", - "о", - "с", - "т", - "ъ", - "ѣ", - "ꙋ", - "\u1c8a", - None, - None, - "ა", - "ბ", - "გ", - "დ", - "ე", - "ვ", - "ზ", - "თ", - "ი", - "კ", - "ლ", - "მ", - "ნ", - "ო", - "პ", - "ჟ", - "რ", - "ს", - "ტ", - "უ", - "ფ", - "ქ", - "ღ", - "ყ", - "შ", - "ჩ", - "ც", - "ძ", - "წ", - "ჭ", - "ხ", - "ჯ", - "ჰ", - "ჱ", - "ჲ", - "ჳ", - "ჴ", - "ჵ", - "ჶ", - "ჷ", - "ჸ", - "ჹ", - "ჺ", - None, - "ჽ", - "ჾ", - "ჿ", - None, - None, - None, - None, - None, - "a", - "æ", - "b", - None, - "d", - "e", - "ǝ", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - None, - "o", - "ȣ", - "p", - "r", - "t", - "u", - "w", - "a", - "ɐ", - "ɑ", - "ᴂ", - "b", - "d", - "e", - "ə", - "ɛ", - "ɜ", - "g", - None, - "k", - "m", - "ŋ", - "o", - "ɔ", - "ᴖ", - "ᴗ", - "p", - "t", - "u", - "ᴝ", - "ɯ", - "v", - "ᴥ", - "β", - "γ", - "δ", - "φ", - "χ", - "i", - "r", - "u", - "v", - "β", - "γ", - "ρ", - "φ", - "χ", - None, - "н", - None, - "ɒ", - "c", - "ɕ", - "ð", - "ɜ", - "f", - "ɟ", - "ɡ", - "ɥ", - "ɨ", - "ɩ", - "ɪ", - "ᵻ", - "ʝ", - "ɭ", - "ᶅ", - "ʟ", - "ɱ", - "ɰ", - "ɲ", - "ɳ", - "ɴ", - "ɵ", - "ɸ", - "ʂ", - "ʃ", - "ƫ", - "ʉ", - "ʊ", - "ᴜ", - "ʋ", - "ʌ", - "z", - "ʐ", - "ʑ", - "ʒ", - "θ", - None, - "ḁ", - None, - "ḃ", - None, - "ḅ", - None, - "ḇ", - None, - "ḉ", - None, - "ḋ", - None, - "ḍ", - None, - "ḏ", - None, - "ḑ", - None, - "ḓ", - None, - "ḕ", - None, - "ḗ", - None, - "ḙ", - None, - "ḛ", - None, - "ḝ", - None, - "ḟ", - None, - "ḡ", - None, - "ḣ", - None, - "ḥ", - None, - "ḧ", - None, - "ḩ", - None, - "ḫ", - None, - "ḭ", - None, - "ḯ", - None, - "ḱ", - None, - "ḳ", - None, - "ḵ", - None, - "ḷ", - None, - "ḹ", - None, - "ḻ", - None, - "ḽ", - None, - "ḿ", - None, - "ṁ", - None, - "ṃ", - None, - "ṅ", - None, - "ṇ", - None, - "ṉ", - None, - "ṋ", - None, - "ṍ", - None, - "ṏ", - None, - "ṑ", - None, - "ṓ", - None, - "ṕ", - None, - "ṗ", - None, - "ṙ", - None, - "ṛ", - None, - "ṝ", - None, - "ṟ", - None, - "ṡ", - None, - "ṣ", - None, - "ṥ", - None, - "ṧ", - None, - "ṩ", - None, - "ṫ", - None, - "ṭ", - None, - "ṯ", - None, - "ṱ", - None, - "ṳ", - None, - "ṵ", - None, - "ṷ", - None, - "ṹ", - None, - "ṻ", - None, - "ṽ", - None, - "ṿ", - None, - "ẁ", - None, - "ẃ", - None, - "ẅ", - None, - "ẇ", - None, - "ẉ", - None, - "ẋ", - None, - "ẍ", - None, - "ẏ", - None, - "ẑ", - None, - "ẓ", - None, - "ẕ", - None, - "aʾ", - "ṡ", - None, - "ß", - None, - "ạ", - None, - "ả", - None, - "ấ", - None, - "ầ", - None, - "ẩ", - None, - "ẫ", - None, - "ậ", - None, - "ắ", - None, - "ằ", - None, - "ẳ", - None, - "ẵ", - None, - "ặ", - None, - "ẹ", - None, - "ẻ", - None, - "ẽ", - None, - "ế", - None, - "ề", - None, - "ể", - None, - "ễ", - None, - "ệ", - None, - "ỉ", - None, - "ị", - None, - "ọ", - None, - "ỏ", - None, - "ố", - None, - "ồ", - None, - "ổ", - None, - "ỗ", - None, - "ộ", - None, - "ớ", - None, - "ờ", - None, - "ở", - None, - "ỡ", - None, - "ợ", - None, - "ụ", - None, - "ủ", - None, - "ứ", - None, - "ừ", - None, - "ử", - None, - "ữ", - None, - "ự", - None, - "ỳ", - None, - "ỵ", - None, - "ỷ", - None, - "ỹ", - None, - "ỻ", - None, - "ỽ", - None, - "ỿ", - None, - "ἀ", - "ἁ", - "ἂ", - "ἃ", - "ἄ", - "ἅ", - "ἆ", - "ἇ", - None, - None, - "ἐ", - "ἑ", - "ἒ", - "ἓ", - "ἔ", - "ἕ", - None, - None, - "ἠ", - "ἡ", - "ἢ", - "ἣ", - "ἤ", - "ἥ", - "ἦ", - "ἧ", - None, - "ἰ", - "ἱ", - "ἲ", - "ἳ", - "ἴ", - "ἵ", - "ἶ", - "ἷ", - None, - None, - "ὀ", - "ὁ", - "ὂ", - "ὃ", - "ὄ", - "ὅ", - None, - None, - None, - "ὑ", - None, - "ὓ", - None, - "ὕ", - None, - "ὗ", - None, - "ὠ", - "ὡ", - "ὢ", - "ὣ", - "ὤ", - "ὥ", - "ὦ", - "ὧ", - None, - "ά", - None, - "έ", - None, - "ή", - None, - "ί", - None, - "ό", - None, - "ύ", - None, - "ώ", - None, - "ἀι", - "ἁι", - "ἂι", - "ἃι", - "ἄι", - "ἅι", - "ἆι", - "ἇι", - "ἀι", - "ἁι", - "ἂι", - "ἃι", - "ἄι", - "ἅι", - "ἆι", - "ἇι", - "ἠι", - "ἡι", - "ἢι", - "ἣι", - "ἤι", - "ἥι", - "ἦι", - "ἧι", - "ἠι", - "ἡι", - "ἢι", - "ἣι", - "ἤι", - "ἥι", - "ἦι", - "ἧι", - "ὠι", - "ὡι", - "ὢι", - "ὣι", - "ὤι", - "ὥι", - "ὦι", - "ὧι", - "ὠι", - "ὡι", - "ὢι", - "ὣι", - "ὤι", - "ὥι", - "ὦι", - "ὧι", - None, - "ὰι", - "αι", - "άι", - None, - None, - "ᾶι", - "ᾰ", - "ᾱ", - "ὰ", - "ά", - "αι", - " ̓", - "ι", - " ̓", - " ͂", - " ̈͂", - "ὴι", - "ηι", - "ήι", - None, - None, - "ῆι", - "ὲ", - "έ", - "ὴ", - "ή", - "ηι", - " ̓̀", - " ̓́", - " ̓͂", - None, - "ΐ", - None, - None, - "ῐ", - "ῑ", - "ὶ", - "ί", - None, - " ̔̀", - " ̔́", - " ̔͂", - None, - "ΰ", - None, - "ῠ", - "ῡ", - "ὺ", - "ύ", - "ῥ", - " ̈̀", - " ̈́", - "`", - None, - "ὼι", - "ωι", - "ώι", - None, - None, - "ῶι", - "ὸ", - "ό", - "ὼ", - "ώ", - "ωι", - " ́", - " ̔", - None, - " ", - None, - "", - None, - None, - "‐", - None, - " ̳", - None, - None, - None, - None, - " ", - None, - "′′", - "′′′", - None, - "‵‵", - "‵‵‵", - None, - "!!", - None, - " ̅", - None, - "??", - "?!", - "!?", - None, - "′′′′", - None, - " ", - None, - None, - None, - "0", - "i", - None, - "4", - "5", - "6", - "7", - "8", - "9", - "+", - "−", - "=", - "(", - ")", - "n", - "0", - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - "+", - "−", - "=", - "(", - ")", - None, - "a", - "e", - "o", - "x", - "ə", - "h", - "k", - "l", - "m", - "n", - "p", - "s", - "t", - None, - None, - "rs", - None, - None, - None, - None, - "a/c", - "a/s", - "c", - "°c", - None, - "c/o", - "c/u", - "ɛ", - None, - "°f", - "g", - "h", - "ħ", - "i", - "l", - None, - "n", - "no", - None, - "p", - "q", - "r", - None, - "sm", - "tel", - "tm", - None, - "z", - None, - "ω", - None, - "z", - None, - "k", - "å", - "b", - "c", - None, - "e", - "f", - "ⅎ", - "m", - "o", - "א", - "ב", - "ג", - "ד", - "i", - None, - "fax", - "π", - "γ", - "π", - "∑", - None, - "d", - "e", - "i", - "j", - None, - "1⁄7", - "1⁄9", - "1⁄10", - "1⁄3", - "2⁄3", - "1⁄5", - "2⁄5", - "3⁄5", - "4⁄5", - "1⁄6", - "5⁄6", - "1⁄8", - "3⁄8", - "5⁄8", - "7⁄8", - "1⁄", - "i", - "ii", - "iii", - "iv", - "v", - "vi", - "vii", - "viii", - "ix", - "x", - "xi", - "xii", - "l", - "c", - "d", - "m", - "i", - "ii", - "iii", - "iv", - "v", - "vi", - "vii", - "viii", - "ix", - "x", - "xi", - "xii", - "l", - "c", - "d", - "m", - None, - "ↄ", - None, - "0⁄3", - None, - None, - None, - "∫∫", - "∫∫∫", - None, - "∮∮", - "∮∮∮", - None, - "〈", - "〉", - None, - None, - None, - None, - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - "10", - "11", - "12", - "13", - "14", - "15", - "16", - "17", - "18", - "19", - "20", - "(1)", - "(2)", - "(3)", - "(4)", - "(5)", - "(6)", - "(7)", - "(8)", - "(9)", - "(10)", - "(11)", - "(12)", - "(13)", - "(14)", - "(15)", - "(16)", - "(17)", - "(18)", - "(19)", - "(20)", - None, - "(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", - "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", - "0", - None, - "∫∫∫∫", - None, - "::=", - "==", - "===", - None, - "⫝̸", - None, - None, - None, - "ⰰ", - "ⰱ", - "ⰲ", - "ⰳ", - "ⰴ", - "ⰵ", - "ⰶ", - "ⰷ", - "ⰸ", - "ⰹ", - "ⰺ", - "ⰻ", - "ⰼ", - "ⰽ", - "ⰾ", - "ⰿ", - "ⱀ", - "ⱁ", - "ⱂ", - "ⱃ", - "ⱄ", - "ⱅ", - "ⱆ", - "ⱇ", - "ⱈ", - "ⱉ", - "ⱊ", - "ⱋ", - "ⱌ", - "ⱍ", - "ⱎ", - "ⱏ", - "ⱐ", - "ⱑ", - "ⱒ", - "ⱓ", - "ⱔ", - "ⱕ", - "ⱖ", - "ⱗ", - "ⱘ", - "ⱙ", - "ⱚ", - "ⱛ", - "ⱜ", - "ⱝ", - "ⱞ", - "ⱟ", - None, - "ⱡ", - None, - "ɫ", - "ᵽ", - "ɽ", - None, - "ⱨ", - None, - "ⱪ", - None, - "ⱬ", - None, - "ɑ", - "ɱ", - "ɐ", - "ɒ", - None, - "ⱳ", - None, - "ⱶ", - None, - "j", - "v", - "ȿ", - "ɀ", - "ⲁ", - None, - "ⲃ", - None, - "ⲅ", - None, - "ⲇ", - None, - "ⲉ", - None, - "ⲋ", - None, - "ⲍ", - None, - "ⲏ", - None, - "ⲑ", - None, - "ⲓ", - None, - "ⲕ", - None, - "ⲗ", - None, - "ⲙ", - None, - "ⲛ", - None, - "ⲝ", - None, - "ⲟ", - None, - "ⲡ", - None, - "ⲣ", - None, - "ⲥ", - None, - "ⲧ", - None, - "ⲩ", - None, - "ⲫ", - None, - "ⲭ", - None, - "ⲯ", - None, - "ⲱ", - None, - "ⲳ", - None, - "ⲵ", - None, - "ⲷ", - None, - "ⲹ", - None, - "ⲻ", - None, - "ⲽ", - None, - "ⲿ", - None, - "ⳁ", - None, - "ⳃ", - None, - "ⳅ", - None, - "ⳇ", - None, - "ⳉ", - None, - "ⳋ", - None, - "ⳍ", - None, - "ⳏ", - None, - "ⳑ", - None, - "ⳓ", - None, - "ⳕ", - None, - "ⳗ", - None, - "ⳙ", - None, - "ⳛ", - None, - "ⳝ", - None, - "ⳟ", - None, - "ⳡ", - None, - "ⳣ", - None, - "ⳬ", - None, - "ⳮ", - None, - "ⳳ", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "ⵡ", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "母", - None, - "龟", - None, - "一", - "丨", - "丶", - "丿", - "乙", - "亅", - "二", - "亠", - "人", - "儿", - "入", - "八", - "冂", - "冖", - "冫", - "几", - "凵", - "刀", - "力", - "勹", - "匕", - "匚", - "匸", - "十", - "卜", - "卩", - "厂", - "厶", - "又", - "口", - "囗", - "土", - "士", - "夂", - "夊", - "夕", - "大", - "女", - "子", - "宀", - "寸", - "小", - "尢", - "尸", - "屮", - "山", - "巛", - "工", - "己", - "巾", - "干", - "幺", - "广", - "廴", - "廾", - "弋", - "弓", - "彐", - "彡", - "彳", - "心", - "戈", - "戶", - "手", - "支", - "攴", - "文", - "斗", - "斤", - "方", - "无", - "日", - "曰", - "月", - "木", - "欠", - "止", - "歹", - "殳", - "毋", - "比", - "毛", - "氏", - "气", - "水", - "火", - "爪", - "父", - "爻", - "爿", - "片", - "牙", - "牛", - "犬", - "玄", - "玉", - "瓜", - "瓦", - "甘", - "生", - "用", - "田", - "疋", - "疒", - "癶", - "白", - "皮", - "皿", - "目", - "矛", - "矢", - "石", - "示", - "禸", - "禾", - "穴", - "立", - "竹", - "米", - "糸", - "缶", - "网", - "羊", - "羽", - "老", - "而", - "耒", - "耳", - "聿", - "肉", - "臣", - "自", - "至", - "臼", - "舌", - "舛", - "舟", - "艮", - "色", - "艸", - "虍", - "虫", - "血", - "行", - "衣", - "襾", - "見", - "角", - "言", - "谷", - "豆", - "豕", - "豸", - "貝", - "赤", - "走", - "足", - "身", - "車", - "辛", - "辰", - "辵", - "邑", - "酉", - "釆", - "里", - "金", - "長", - "門", - "阜", - "隶", - "隹", - "雨", - "靑", - "非", - "面", - "革", - "韋", - "韭", - "音", - "頁", - "風", - "飛", - "食", - "首", - "香", - "馬", - "骨", - "高", - "髟", - "鬥", - "鬯", - "鬲", - "鬼", - "魚", - "鳥", - "鹵", - "鹿", - "麥", - "麻", - "黃", - "黍", - "黑", - "黹", - "黽", - "鼎", - "鼓", - "鼠", - "鼻", - "齊", - "齒", - "龍", - "龜", - "龠", - None, - " ", - None, - ".", - None, - "〒", - None, - "十", - "卄", - "卅", - None, - None, - None, - None, - None, - " ゙", - " ゚", - None, - "より", - None, - "コト", - None, - None, - None, - "ᄀ", - "ᄁ", - "ᆪ", - "ᄂ", - "ᆬ", - "ᆭ", - "ᄃ", - "ᄄ", - "ᄅ", - "ᆰ", - "ᆱ", - "ᆲ", - "ᆳ", - "ᆴ", - "ᆵ", - "ᄚ", - "ᄆ", - "ᄇ", - "ᄈ", - "ᄡ", - "ᄉ", - "ᄊ", - "ᄋ", - "ᄌ", - "ᄍ", - "ᄎ", - "ᄏ", - "ᄐ", - "ᄑ", - "ᄒ", - "ᅡ", - "ᅢ", - "ᅣ", - "ᅤ", - "ᅥ", - "ᅦ", - "ᅧ", - "ᅨ", - "ᅩ", - "ᅪ", - "ᅫ", - "ᅬ", - "ᅭ", - "ᅮ", - "ᅯ", - "ᅰ", - "ᅱ", - "ᅲ", - "ᅳ", - "ᅴ", - "ᅵ", - None, - "ᄔ", - "ᄕ", - "ᇇ", - "ᇈ", - "ᇌ", - "ᇎ", - "ᇓ", - "ᇗ", - "ᇙ", - "ᄜ", - "ᇝ", - "ᇟ", - "ᄝ", - "ᄞ", - "ᄠ", - "ᄢ", - "ᄣ", - "ᄧ", - "ᄩ", - "ᄫ", - "ᄬ", - "ᄭ", - "ᄮ", - "ᄯ", - "ᄲ", - "ᄶ", - "ᅀ", - "ᅇ", - "ᅌ", - "ᇱ", - "ᇲ", - "ᅗ", - "ᅘ", - "ᅙ", - "ᆄ", - "ᆅ", - "ᆈ", - "ᆑ", - "ᆒ", - "ᆔ", - "ᆞ", - "ᆡ", - None, - None, - "一", - "二", - "三", - "四", - "上", - "中", - "下", - "甲", - "乙", - "丙", - "丁", - "天", - "地", - "人", - None, - None, - None, - "(ᄀ)", - "(ᄂ)", - "(ᄃ)", - "(ᄅ)", - "(ᄆ)", - "(ᄇ)", - "(ᄉ)", - "(ᄋ)", - "(ᄌ)", - "(ᄎ)", - "(ᄏ)", - "(ᄐ)", - "(ᄑ)", - "(ᄒ)", - "(가)", - "(나)", - "(다)", - "(라)", - "(마)", - "(바)", - "(사)", - "(아)", - "(자)", - "(차)", - "(카)", - "(타)", - "(파)", - "(하)", - "(주)", - "(오전)", - "(오후)", - None, - "(一)", - "(二)", - "(三)", - "(四)", - "(五)", - "(六)", - "(七)", - "(八)", - "(九)", - "(十)", - "(月)", - "(火)", - "(水)", - "(木)", - "(金)", - "(土)", - "(日)", - "(株)", - "(有)", - "(社)", - "(名)", - "(特)", - "(財)", - "(祝)", - "(労)", - "(代)", - "(呼)", - "(学)", - "(監)", - "(企)", - "(資)", - "(協)", - "(祭)", - "(休)", - "(自)", - "(至)", - "問", - "幼", - "文", - "箏", - None, - "pte", - "21", - "22", - "23", - "24", - "25", - "26", - "27", - "28", - "29", - "30", - "31", - "32", - "33", - "34", - "35", - "ᄀ", - "ᄂ", - "ᄃ", - "ᄅ", - "ᄆ", - "ᄇ", - "ᄉ", - "ᄋ", - "ᄌ", - "ᄎ", - "ᄏ", - "ᄐ", - "ᄑ", - "ᄒ", - "가", - "나", - "다", - "라", - "마", - "바", - "사", - "아", - "자", - "차", - "카", - "타", - "파", - "하", - "참고", - "주의", - "우", - None, - "一", - "二", - "三", - "四", - "五", - "六", - "七", - "八", - "九", - "十", - "月", - "火", - "水", - "木", - "金", - "土", - "日", - "株", - "有", - "社", - "名", - "特", - "財", - "祝", - "労", - "秘", - "男", - "女", - "適", - "優", - "印", - "注", - "項", - "休", - "写", - "正", - "上", - "中", - "下", - "左", - "右", - "医", - "宗", - "学", - "監", - "企", - "資", - "協", - "夜", - "36", - "37", - "38", - "39", - "40", - "41", - "42", - "43", - "44", - "45", - "46", - "47", - "48", - "49", - "50", - "1月", - "2月", - "3月", - "4月", - "5月", - "6月", - "7月", - "8月", - "9月", - "10月", - "11月", - "12月", - "hg", - "erg", - "ev", - "ltd", - "ア", - "イ", - "ウ", - "エ", - "オ", - "カ", - "キ", - "ク", - "ケ", - "コ", - "サ", - "シ", - "ス", - "セ", - "ソ", - "タ", - "チ", - "ツ", - "テ", - "ト", - "ナ", - "ニ", - "ヌ", - "ネ", - "ノ", - "ハ", - "ヒ", - "フ", - "ヘ", - "ホ", - "マ", - "ミ", - "ム", - "メ", - "モ", - "ヤ", - "ユ", - "ヨ", - "ラ", - "リ", - "ル", - "レ", - "ロ", - "ワ", - "ヰ", - "ヱ", - "ヲ", - "令和", - "アパート", - "アルファ", - "アンペア", - "アール", - "イニング", - "インチ", - "ウォン", - "エスクード", - "エーカー", - "オンス", - "オーム", - "カイリ", - "カラット", - "カロリー", - "ガロン", - "ガンマ", - "ギガ", - "ギニー", - "キュリー", - "ギルダー", - "キロ", - "キログラム", - "キロメートル", - "キロワット", - "グラム", - "グラムトン", - "クルゼイロ", - "クローネ", - "ケース", - "コルナ", - "コーポ", - "サイクル", - "サンチーム", - "シリング", - "センチ", - "セント", - "ダース", - "デシ", - "ドル", - "トン", - "ナノ", - "ノット", - "ハイツ", - "パーセント", - "パーツ", - "バーレル", - "ピアストル", - "ピクル", - "ピコ", - "ビル", - "ファラッド", - "フィート", - "ブッシェル", - "フラン", - "ヘクタール", - "ペソ", - "ペニヒ", - "ヘルツ", - "ペンス", - "ページ", - "ベータ", - "ポイント", - "ボルト", - "ホン", - "ポンド", - "ホール", - "ホーン", - "マイクロ", - "マイル", - "マッハ", - "マルク", - "マンション", - "ミクロン", - "ミリ", - "ミリバール", - "メガ", - "メガトン", - "メートル", - "ヤード", - "ヤール", - "ユアン", - "リットル", - "リラ", - "ルピー", - "ルーブル", - "レム", - "レントゲン", - "ワット", - "0点", - "1点", - "2点", - "3点", - "4点", - "5点", - "6点", - "7点", - "8点", - "9点", - "10点", - "11点", - "12点", - "13点", - "14点", - "15点", - "16点", - "17点", - "18点", - "19点", - "20点", - "21点", - "22点", - "23点", - "24点", - "hpa", - "da", - "au", - "bar", - "ov", - "pc", - "dm", - "dm2", - "dm3", - "iu", - "平成", - "昭和", - "大正", - "明治", - "株式会社", - "pa", - "na", - "μa", - "ma", - "ka", - "kb", - "mb", - "gb", - "cal", - "kcal", - "pf", - "nf", - "μf", - "μg", - "mg", - "kg", - "hz", - "khz", - "mhz", - "ghz", - "thz", - "μl", - "ml", - "dl", - "kl", - "fm", - "nm", - "μm", - "mm", - "cm", - "km", - "mm2", - "cm2", - "m2", - "km2", - "mm3", - "cm3", - "m3", - "km3", - "m∕s", - "m∕s2", - "pa", - "kpa", - "mpa", - "gpa", - "rad", - "rad∕s", - "rad∕s2", - "ps", - "ns", - "μs", - "ms", - "pv", - "nv", - "μv", - "mv", - "kv", - "mv", - "pw", - "nw", - "μw", - "mw", - "kw", - "mw", - "kω", - "mω", - None, - "bq", - "cc", - "cd", - "c∕kg", - None, - "db", - "gy", - "ha", - "hp", - "in", - "kk", - "km", - "kt", - "lm", - "ln", - "log", - "lx", - "mb", - "mil", - "mol", - "ph", - None, - "ppm", - "pr", - "sr", - "sv", - "wb", - "v∕m", - "a∕m", - "1日", - "2日", - "3日", - "4日", - "5日", - "6日", - "7日", - "8日", - "9日", - "10日", - "11日", - "12日", - "13日", - "14日", - "15日", - "16日", - "17日", - "18日", - "19日", - "20日", - "21日", - "22日", - "23日", - "24日", - "25日", - "26日", - "27日", - "28日", - "29日", - "30日", - "31日", - "gal", - None, - None, - None, - None, - None, - None, - "ꙁ", - None, - "ꙃ", - None, - "ꙅ", - None, - "ꙇ", - None, - "ꙉ", - None, - "ꙋ", - None, - "ꙍ", - None, - "ꙏ", - None, - "ꙑ", - None, - "ꙓ", - None, - "ꙕ", - None, - "ꙗ", - None, - "ꙙ", - None, - "ꙛ", - None, - "ꙝ", - None, - "ꙟ", - None, - "ꙡ", - None, - "ꙣ", - None, - "ꙥ", - None, - "ꙧ", - None, - "ꙩ", - None, - "ꙫ", - None, - "ꙭ", - None, - "ꚁ", - None, - "ꚃ", - None, - "ꚅ", - None, - "ꚇ", - None, - "ꚉ", - None, - "ꚋ", - None, - "ꚍ", - None, - "ꚏ", - None, - "ꚑ", - None, - "ꚓ", - None, - "ꚕ", - None, - "ꚗ", - None, - "ꚙ", - None, - "ꚛ", - None, - "ъ", - "ь", - None, - None, - None, - "ꜣ", - None, - "ꜥ", - None, - "ꜧ", - None, - "ꜩ", - None, - "ꜫ", - None, - "ꜭ", - None, - "ꜯ", - None, - "ꜳ", - None, - "ꜵ", - None, - "ꜷ", - None, - "ꜹ", - None, - "ꜻ", - None, - "ꜽ", - None, - "ꜿ", - None, - "ꝁ", - None, - "ꝃ", - None, - "ꝅ", - None, - "ꝇ", - None, - "ꝉ", - None, - "ꝋ", - None, - "ꝍ", - None, - "ꝏ", - None, - "ꝑ", - None, - "ꝓ", - None, - "ꝕ", - None, - "ꝗ", - None, - "ꝙ", - None, - "ꝛ", - None, - "ꝝ", - None, - "ꝟ", - None, - "ꝡ", - None, - "ꝣ", - None, - "ꝥ", - None, - "ꝧ", - None, - "ꝩ", - None, - "ꝫ", - None, - "ꝭ", - None, - "ꝯ", - None, - "ꝯ", - None, - "ꝺ", - None, - "ꝼ", - None, - "ᵹ", - "ꝿ", - None, - "ꞁ", - None, - "ꞃ", - None, - "ꞅ", - None, - "ꞇ", - None, - "ꞌ", - None, - "ɥ", - None, - "ꞑ", - None, - "ꞓ", - None, - "ꞗ", - None, - "ꞙ", - None, - "ꞛ", - None, - "ꞝ", - None, - "ꞟ", - None, - "ꞡ", - None, - "ꞣ", - None, - "ꞥ", - None, - "ꞧ", - None, - "ꞩ", - None, - "ɦ", - "ɜ", - "ɡ", - "ɬ", - "ɪ", - None, - "ʞ", - "ʇ", - "ʝ", - "ꭓ", - "ꞵ", - None, - "ꞷ", - None, - "ꞹ", - None, - "ꞻ", - None, - "ꞽ", - None, - "ꞿ", - None, - "ꟁ", - None, - "ꟃ", - None, - "ꞔ", - "ʂ", - "ᶎ", - "ꟈ", - None, - "ꟊ", - None, - "ɤ", - "\ua7cd", - None, - "\ua7cf", - None, - "ꟑ", - None, - "ꟓ", - None, - "ꟕ", - None, - "ꟗ", - None, - "ꟙ", - None, - "\ua7db", - None, - "ƛ", - None, - "s", - "c", - "f", - "q", - "ꟶ", - None, - "ħ", - "œ", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "ꜧ", - "ꬷ", - "ɫ", - "ꭒ", - None, - "ʍ", - None, - None, - "Ꭰ", - "Ꭱ", - "Ꭲ", - "Ꭳ", - "Ꭴ", - "Ꭵ", - "Ꭶ", - "Ꭷ", - "Ꭸ", - "Ꭹ", - "Ꭺ", - "Ꭻ", - "Ꭼ", - "Ꭽ", - "Ꭾ", - "Ꭿ", - "Ꮀ", - "Ꮁ", - "Ꮂ", - "Ꮃ", - "Ꮄ", - "Ꮅ", - "Ꮆ", - "Ꮇ", - "Ꮈ", - "Ꮉ", - "Ꮊ", - "Ꮋ", - "Ꮌ", - "Ꮍ", - "Ꮎ", - "Ꮏ", - "Ꮐ", - "Ꮑ", - "Ꮒ", - "Ꮓ", - "Ꮔ", - "Ꮕ", - "Ꮖ", - "Ꮗ", - "Ꮘ", - "Ꮙ", - "Ꮚ", - "Ꮛ", - "Ꮜ", - "Ꮝ", - "Ꮞ", - "Ꮟ", - "Ꮠ", - "Ꮡ", - "Ꮢ", - "Ꮣ", - "Ꮤ", - "Ꮥ", - "Ꮦ", - "Ꮧ", - "Ꮨ", - "Ꮩ", - "Ꮪ", - "Ꮫ", - "Ꮬ", - "Ꮭ", - "Ꮮ", - "Ꮯ", - "Ꮰ", - "Ꮱ", - "Ꮲ", - "Ꮳ", - "Ꮴ", - "Ꮵ", - "Ꮶ", - "Ꮷ", - "Ꮸ", - "Ꮹ", - "Ꮺ", - "Ꮻ", - "Ꮼ", - "Ꮽ", - "Ꮾ", - "Ꮿ", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "豈", - "更", - "車", - "賈", - "滑", - "串", - "句", - "龜", - "契", - "金", - "喇", - "奈", - "懶", - "癩", - "羅", - "蘿", - "螺", - "裸", - "邏", - "樂", - "洛", - "烙", - "珞", - "落", - "酪", - "駱", - "亂", - "卵", - "欄", - "爛", - "蘭", - "鸞", - "嵐", - "濫", - "藍", - "襤", - "拉", - "臘", - "蠟", - "廊", - "朗", - "浪", - "狼", - "郎", - "來", - "冷", - "勞", - "擄", - "櫓", - "爐", - "盧", - "老", - "蘆", - "虜", - "路", - "露", - "魯", - "鷺", - "碌", - "祿", - "綠", - "菉", - "錄", - "鹿", - "論", - "壟", - "弄", - "籠", - "聾", - "牢", - "磊", - "賂", - "雷", - "壘", - "屢", - "樓", - "淚", - "漏", - "累", - "縷", - "陋", - "勒", - "肋", - "凜", - "凌", - "稜", - "綾", - "菱", - "陵", - "讀", - "拏", - "樂", - "諾", - "丹", - "寧", - "怒", - "率", - "異", - "北", - "磻", - "便", - "復", - "不", - "泌", - "數", - "索", - "參", - "塞", - "省", - "葉", - "說", - "殺", - "辰", - "沈", - "拾", - "若", - "掠", - "略", - "亮", - "兩", - "凉", - "梁", - "糧", - "良", - "諒", - "量", - "勵", - "呂", - "女", - "廬", - "旅", - "濾", - "礪", - "閭", - "驪", - "麗", - "黎", - "力", - "曆", - "歷", - "轢", - "年", - "憐", - "戀", - "撚", - "漣", - "煉", - "璉", - "秊", - "練", - "聯", - "輦", - "蓮", - "連", - "鍊", - "列", - "劣", - "咽", - "烈", - "裂", - "說", - "廉", - "念", - "捻", - "殮", - "簾", - "獵", - "令", - "囹", - "寧", - "嶺", - "怜", - "玲", - "瑩", - "羚", - "聆", - "鈴", - "零", - "靈", - "領", - "例", - "禮", - "醴", - "隸", - "惡", - "了", - "僚", - "寮", - "尿", - "料", - "樂", - "燎", - "療", - "蓼", - "遼", - "龍", - "暈", - "阮", - "劉", - "杻", - "柳", - "流", - "溜", - "琉", - "留", - "硫", - "紐", - "類", - "六", - "戮", - "陸", - "倫", - "崙", - "淪", - "輪", - "律", - "慄", - "栗", - "率", - "隆", - "利", - "吏", - "履", - "易", - "李", - "梨", - "泥", - "理", - "痢", - "罹", - "裏", - "裡", - "里", - "離", - "匿", - "溺", - "吝", - "燐", - "璘", - "藺", - "隣", - "鱗", - "麟", - "林", - "淋", - "臨", - "立", - "笠", - "粒", - "狀", - "炙", - "識", - "什", - "茶", - "刺", - "切", - "度", - "拓", - "糖", - "宅", - "洞", - "暴", - "輻", - "行", - "降", - "見", - "廓", - "兀", - "嗀", - None, - "塚", - None, - "晴", - None, - "凞", - "猪", - "益", - "礼", - "神", - "祥", - "福", - "靖", - "精", - "羽", - None, - "蘒", - None, - "諸", - None, - "逸", - "都", - None, - "飯", - "飼", - "館", - "鶴", - "郞", - "隷", - "侮", - "僧", - "免", - "勉", - "勤", - "卑", - "喝", - "嘆", - "器", - "塀", - "墨", - "層", - "屮", - "悔", - "慨", - "憎", - "懲", - "敏", - "既", - "暑", - "梅", - "海", - "渚", - "漢", - "煮", - "爫", - "琢", - "碑", - "社", - "祉", - "祈", - "祐", - "祖", - "祝", - "禍", - "禎", - "穀", - "突", - "節", - "練", - "縉", - "繁", - "署", - "者", - "臭", - "艹", - "著", - "褐", - "視", - "謁", - "謹", - "賓", - "贈", - "辶", - "逸", - "難", - "響", - "頻", - "恵", - "𤋮", - "舘", - None, - "並", - "况", - "全", - "侀", - "充", - "冀", - "勇", - "勺", - "喝", - "啕", - "喙", - "嗢", - "塚", - "墳", - "奄", - "奔", - "婢", - "嬨", - "廒", - "廙", - "彩", - "徭", - "惘", - "慎", - "愈", - "憎", - "慠", - "懲", - "戴", - "揄", - "搜", - "摒", - "敖", - "晴", - "朗", - "望", - "杖", - "歹", - "殺", - "流", - "滛", - "滋", - "漢", - "瀞", - "煮", - "瞧", - "爵", - "犯", - "猪", - "瑱", - "甆", - "画", - "瘝", - "瘟", - "益", - "盛", - "直", - "睊", - "着", - "磌", - "窱", - "節", - "类", - "絛", - "練", - "缾", - "者", - "荒", - "華", - "蝹", - "襁", - "覆", - "視", - "調", - "諸", - "請", - "謁", - "諾", - "諭", - "謹", - "變", - "贈", - "輸", - "遲", - "醙", - "鉶", - "陼", - "難", - "靖", - "韛", - "響", - "頋", - "頻", - "鬒", - "龜", - "𢡊", - "𢡄", - "𣏕", - "㮝", - "䀘", - "䀹", - "𥉉", - "𥳐", - "𧻓", - "齃", - "龎", - None, - "ff", - "fi", - "fl", - "ffi", - "ffl", - "st", - None, - "մն", - "մե", - "մի", - "վն", - "մխ", - None, - "יִ", - None, - "ײַ", - "ע", - "א", - "ד", - "ה", - "כ", - "ל", - "ם", - "ר", - "ת", - "+", - "שׁ", - "שׂ", - "שּׁ", - "שּׂ", - "אַ", - "אָ", - "אּ", - "בּ", - "גּ", - "דּ", - "הּ", - "וּ", - "זּ", - None, - "טּ", - "יּ", - "ךּ", - "כּ", - "לּ", - None, - "מּ", - None, - "נּ", - "סּ", - None, - "ףּ", - "פּ", - None, - "צּ", - "קּ", - "רּ", - "שּ", - "תּ", - "וֹ", - "בֿ", - "כֿ", - "פֿ", - "אל", - "ٱ", - "ٻ", - "پ", - "ڀ", - "ٺ", - "ٿ", - "ٹ", - "ڤ", - "ڦ", - "ڄ", - "ڃ", - "چ", - "ڇ", - "ڍ", - "ڌ", - "ڎ", - "ڈ", - "ژ", - "ڑ", - "ک", - "گ", - "ڳ", - "ڱ", - "ں", - "ڻ", - "ۀ", - "ہ", - "ھ", - "ے", - "ۓ", - None, - "ڭ", - "ۇ", - "ۆ", - "ۈ", - "ۇٴ", - "ۋ", - "ۅ", - "ۉ", - "ې", - "ى", - "ئا", - "ئە", - "ئو", - "ئۇ", - "ئۆ", - "ئۈ", - "ئې", - "ئى", - "ی", - "ئج", - "ئح", - "ئم", - "ئى", - "ئي", - "بج", - "بح", - "بخ", - "بم", - "بى", - "بي", - "تج", - "تح", - "تخ", - "تم", - "تى", - "تي", - "ثج", - "ثم", - "ثى", - "ثي", - "جح", - "جم", - "حج", - "حم", - "خج", - "خح", - "خم", - "سج", - "سح", - "سخ", - "سم", - "صح", - "صم", - "ضج", - "ضح", - "ضخ", - "ضم", - "طح", - "طم", - "ظم", - "عج", - "عم", - "غج", - "غم", - "فج", - "فح", - "فخ", - "فم", - "فى", - "في", - "قح", - "قم", - "قى", - "قي", - "كا", - "كج", - "كح", - "كخ", - "كل", - "كم", - "كى", - "كي", - "لج", - "لح", - "لخ", - "لم", - "لى", - "لي", - "مج", - "مح", - "مخ", - "مم", - "مى", - "مي", - "نج", - "نح", - "نخ", - "نم", - "نى", - "ني", - "هج", - "هم", - "هى", - "هي", - "يج", - "يح", - "يخ", - "يم", - "يى", - "يي", - "ذٰ", - "رٰ", - "ىٰ", - " ٌّ", - " ٍّ", - " َّ", - " ُّ", - " ِّ", - " ّٰ", - "ئر", - "ئز", - "ئم", - "ئن", - "ئى", - "ئي", - "بر", - "بز", - "بم", - "بن", - "بى", - "بي", - "تر", - "تز", - "تم", - "تن", - "تى", - "تي", - "ثر", - "ثز", - "ثم", - "ثن", - "ثى", - "ثي", - "فى", - "في", - "قى", - "قي", - "كا", - "كل", - "كم", - "كى", - "كي", - "لم", - "لى", - "لي", - "ما", - "مم", - "نر", - "نز", - "نم", - "نن", - "نى", - "ني", - "ىٰ", - "ير", - "يز", - "يم", - "ين", - "يى", - "يي", - "ئج", - "ئح", - "ئخ", - "ئم", - "ئه", - "بج", - "بح", - "بخ", - "بم", - "به", - "تج", - "تح", - "تخ", - "تم", - "ته", - "ثم", - "جح", - "جم", - "حج", - "حم", - "خج", - "خم", - "سج", - "سح", - "سخ", - "سم", - "صح", - "صخ", - "صم", - "ضج", - "ضح", - "ضخ", - "ضم", - "طح", - "ظم", - "عج", - "عم", - "غج", - "غم", - "فج", - "فح", - "فخ", - "فم", - "قح", - "قم", - "كج", - "كح", - "كخ", - "كل", - "كم", - "لج", - "لح", - "لخ", - "لم", - "له", - "مج", - "مح", - "مخ", - "مم", - "نج", - "نح", - "نخ", - "نم", - "نه", - "هج", - "هم", - "هٰ", - "يج", - "يح", - "يخ", - "يم", - "يه", - "ئم", - "ئه", - "بم", - "به", - "تم", - "ته", - "ثم", - "ثه", - "سم", - "سه", - "شم", - "شه", - "كل", - "كم", - "لم", - "نم", - "نه", - "يم", - "يه", - "ـَّ", - "ـُّ", - "ـِّ", - "طى", - "طي", - "عى", - "عي", - "غى", - "غي", - "سى", - "سي", - "شى", - "شي", - "حى", - "حي", - "جى", - "جي", - "خى", - "خي", - "صى", - "صي", - "ضى", - "ضي", - "شج", - "شح", - "شخ", - "شم", - "شر", - "سر", - "صر", - "ضر", - "طى", - "طي", - "عى", - "عي", - "غى", - "غي", - "سى", - "سي", - "شى", - "شي", - "حى", - "حي", - "جى", - "جي", - "خى", - "خي", - "صى", - "صي", - "ضى", - "ضي", - "شج", - "شح", - "شخ", - "شم", - "شر", - "سر", - "صر", - "ضر", - "شج", - "شح", - "شخ", - "شم", - "سه", - "شه", - "طم", - "سج", - "سح", - "سخ", - "شج", - "شح", - "شخ", - "طم", - "ظم", - "اً", - None, - "تجم", - "تحج", - "تحم", - "تخم", - "تمج", - "تمح", - "تمخ", - "جمح", - "حمي", - "حمى", - "سحج", - "سجح", - "سجى", - "سمح", - "سمج", - "سمم", - "صحح", - "صمم", - "شحم", - "شجي", - "شمخ", - "شمم", - "ضحى", - "ضخم", - "طمح", - "طمم", - "طمي", - "عجم", - "عمم", - "عمى", - "غمم", - "غمي", - "غمى", - "فخم", - "قمح", - "قمم", - "لحم", - "لحي", - "لحى", - "لجج", - "لخم", - "لمح", - "محج", - "محم", - "محي", - "مجح", - "مجم", - "مخج", - "مخم", - None, - "مجخ", - "همج", - "همم", - "نحم", - "نحى", - "نجم", - "نجى", - "نمي", - "نمى", - "يمم", - "بخي", - "تجي", - "تجى", - "تخي", - "تخى", - "تمي", - "تمى", - "جمي", - "جحى", - "جمى", - "سخى", - "صحي", - "شحي", - "ضحي", - "لجي", - "لمي", - "يحي", - "يجي", - "يمي", - "ممي", - "قمي", - "نحي", - "قمح", - "لحم", - "عمي", - "كمي", - "نجح", - "مخي", - "لجم", - "كمم", - "لجم", - "نجح", - "جحي", - "حجي", - "مجي", - "فمي", - "بحي", - "كمم", - "عجم", - "صمم", - "سخي", - "نجي", - None, - None, - "صلے", - "قلے", - "الله", - "اكبر", - "محمد", - "صلعم", - "رسول", - "عليه", - "وسلم", - "صلى", - "صلى الله عليه وسلم", - "جل جلاله", - "ریال", - None, - None, - ",", - "、", - None, - ":", - ";", - "!", - "?", - "〖", - "〗", - None, - None, - None, - "—", - "–", - "_", - "(", - ")", - "{", - "}", - "〔", - "〕", - "【", - "】", - "《", - "》", - "〈", - "〉", - "「", - "」", - "『", - "』", - None, - "[", - "]", - " ̅", - "_", - ",", - "、", - None, - ";", - ":", - "?", - "!", - "—", - "(", - ")", - "{", - "}", - "〔", - "〕", - "#", - "&", - "*", - "+", - "-", - "<", - ">", - "=", - None, - "\\", - "$", - "%", - "@", - None, - " ً", - "ـً", - " ٌ", - None, - " ٍ", - None, - " َ", - "ـَ", - " ُ", - "ـُ", - " ِ", - "ـِ", - " ّ", - "ـّ", - " ْ", - "ـْ", - "ء", - "آ", - "أ", - "ؤ", - "إ", - "ئ", - "ا", - "ب", - "ة", - "ت", - "ث", - "ج", - "ح", - "خ", - "د", - "ذ", - "ر", - "ز", - "س", - "ش", - "ص", - "ض", - "ط", - "ظ", - "ع", - "غ", - "ف", - "ق", - "ك", - "ل", - "م", - "ن", - "ه", - "و", - "ى", - "ي", - "لآ", - "لأ", - "لإ", - "لا", - None, - None, - None, - "!", - '"', - "#", - "$", - "%", - "&", - "'", - "(", - ")", - "*", - "+", - ",", - "-", - ".", - "/", - "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", - "{", - "|", - "}", - "~", - "⦅", - "⦆", - ".", - "「", - "」", - "、", - "・", - "ヲ", - "ァ", - "ィ", - "ゥ", - "ェ", - "ォ", - "ャ", - "ュ", - "ョ", - "ッ", - "ー", - "ア", - "イ", - "ウ", - "エ", - "オ", - "カ", - "キ", - "ク", - "ケ", - "コ", - "サ", - "シ", - "ス", - "セ", - "ソ", - "タ", - "チ", - "ツ", - "テ", - "ト", - "ナ", - "ニ", - "ヌ", - "ネ", - "ノ", - "ハ", - "ヒ", - "フ", - "ヘ", - "ホ", - "マ", - "ミ", - "ム", - "メ", - "モ", - "ヤ", - "ユ", - "ヨ", - "ラ", - "リ", - "ル", - "レ", - "ロ", - "ワ", - "ン", - "゙", - "゚", - None, - "ᄀ", - "ᄁ", - "ᆪ", - "ᄂ", - "ᆬ", - "ᆭ", - "ᄃ", - "ᄄ", - "ᄅ", - "ᆰ", - "ᆱ", - "ᆲ", - "ᆳ", - "ᆴ", - "ᆵ", - "ᄚ", - "ᄆ", - "ᄇ", - "ᄈ", - "ᄡ", - "ᄉ", - "ᄊ", - "ᄋ", - "ᄌ", - "ᄍ", - "ᄎ", - "ᄏ", - "ᄐ", - "ᄑ", - "ᄒ", - None, - "ᅡ", - "ᅢ", - "ᅣ", - "ᅤ", - "ᅥ", - "ᅦ", - None, - "ᅧ", - "ᅨ", - "ᅩ", - "ᅪ", - "ᅫ", - "ᅬ", - None, - "ᅭ", - "ᅮ", - "ᅯ", - "ᅰ", - "ᅱ", - "ᅲ", - None, - "ᅳ", - "ᅴ", - "ᅵ", - None, - "¢", - "£", - "¬", - " ̄", - "¦", - "¥", - "₩", - None, - "│", - "←", - "↑", - "→", - "↓", - "■", - "○", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "𐐨", - "𐐩", - "𐐪", - "𐐫", - "𐐬", - "𐐭", - "𐐮", - "𐐯", - "𐐰", - "𐐱", - "𐐲", - "𐐳", - "𐐴", - "𐐵", - "𐐶", - "𐐷", - "𐐸", - "𐐹", - "𐐺", - "𐐻", - "𐐼", - "𐐽", - "𐐾", - "𐐿", - "𐑀", - "𐑁", - "𐑂", - "𐑃", - "𐑄", - "𐑅", - "𐑆", - "𐑇", - "𐑈", - "𐑉", - "𐑊", - "𐑋", - "𐑌", - "𐑍", - "𐑎", - "𐑏", - None, - None, - None, - None, - "𐓘", - "𐓙", - "𐓚", - "𐓛", - "𐓜", - "𐓝", - "𐓞", - "𐓟", - "𐓠", - "𐓡", - "𐓢", - "𐓣", - "𐓤", - "𐓥", - "𐓦", - "𐓧", - "𐓨", - "𐓩", - "𐓪", - "𐓫", - "𐓬", - "𐓭", - "𐓮", - "𐓯", - "𐓰", - "𐓱", - "𐓲", - "𐓳", - "𐓴", - "𐓵", - "𐓶", - "𐓷", - "𐓸", - "𐓹", - "𐓺", - "𐓻", - None, - None, - None, - None, - None, - None, - None, - None, - "𐖗", - "𐖘", - "𐖙", - "𐖚", - "𐖛", - "𐖜", - "𐖝", - "𐖞", - "𐖟", - "𐖠", - "𐖡", - None, - "𐖣", - "𐖤", - "𐖥", - "𐖦", - "𐖧", - "𐖨", - "𐖩", - "𐖪", - "𐖫", - "𐖬", - "𐖭", - "𐖮", - "𐖯", - "𐖰", - "𐖱", - None, - "𐖳", - "𐖴", - "𐖵", - "𐖶", - "𐖷", - "𐖸", - "𐖹", - None, - "𐖻", - "𐖼", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "ː", - "ˑ", - "æ", - "ʙ", - "ɓ", - None, - "ʣ", - "ꭦ", - "ʥ", - "ʤ", - "ɖ", - "ɗ", - "ᶑ", - "ɘ", - "ɞ", - "ʩ", - "ɤ", - "ɢ", - "ɠ", - "ʛ", - "ħ", - "ʜ", - "ɧ", - "ʄ", - "ʪ", - "ʫ", - "ɬ", - "𝼄", - "ꞎ", - "ɮ", - "𝼅", - "ʎ", - "𝼆", - "ø", - "ɶ", - "ɷ", - "q", - "ɺ", - "𝼈", - "ɽ", - "ɾ", - "ʀ", - "ʨ", - "ʦ", - "ꭧ", - "ʧ", - "ʈ", - "ⱱ", - None, - "ʏ", - "ʡ", - "ʢ", - "ʘ", - "ǀ", - "ǁ", - "ǂ", - "𝼊", - "𝼞", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "𐳀", - "𐳁", - "𐳂", - "𐳃", - "𐳄", - "𐳅", - "𐳆", - "𐳇", - "𐳈", - "𐳉", - "𐳊", - "𐳋", - "𐳌", - "𐳍", - "𐳎", - "𐳏", - "𐳐", - "𐳑", - "𐳒", - "𐳓", - "𐳔", - "𐳕", - "𐳖", - "𐳗", - "𐳘", - "𐳙", - "𐳚", - "𐳛", - "𐳜", - "𐳝", - "𐳞", - "𐳟", - "𐳠", - "𐳡", - "𐳢", - "𐳣", - "𐳤", - "𐳥", - "𐳦", - "𐳧", - "𐳨", - "𐳩", - "𐳪", - "𐳫", - "𐳬", - "𐳭", - "𐳮", - "𐳯", - "𐳰", - "𐳱", - "𐳲", - None, - None, - None, - None, - None, - None, - None, - None, - "\U00010d70", - "\U00010d71", - "\U00010d72", - "\U00010d73", - "\U00010d74", - "\U00010d75", - "\U00010d76", - "\U00010d77", - "\U00010d78", - "\U00010d79", - "\U00010d7a", - "\U00010d7b", - "\U00010d7c", - "\U00010d7d", - "\U00010d7e", - "\U00010d7f", - "\U00010d80", - "\U00010d81", - "\U00010d82", - "\U00010d83", - "\U00010d84", - "\U00010d85", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "𑣀", - "𑣁", - "𑣂", - "𑣃", - "𑣄", - "𑣅", - "𑣆", - "𑣇", - "𑣈", - "𑣉", - "𑣊", - "𑣋", - "𑣌", - "𑣍", - "𑣎", - "𑣏", - "𑣐", - "𑣑", - "𑣒", - "𑣓", - "𑣔", - "𑣕", - "𑣖", - "𑣗", - "𑣘", - "𑣙", - "𑣚", - "𑣛", - "𑣜", - "𑣝", - "𑣞", - "𑣟", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "𖹠", - "𖹡", - "𖹢", - "𖹣", - "𖹤", - "𖹥", - "𖹦", - "𖹧", - "𖹨", - "𖹩", - "𖹪", - "𖹫", - "𖹬", - "𖹭", - "𖹮", - "𖹯", - "𖹰", - "𖹱", - "𖹲", - "𖹳", - "𖹴", - "𖹵", - "𖹶", - "𖹷", - "𖹸", - "𖹹", - "𖹺", - "𖹻", - "𖹼", - "𖹽", - "𖹾", - "𖹿", - None, - None, - "\U00016ebb", - "\U00016ebc", - "\U00016ebd", - "\U00016ebe", - "\U00016ebf", - "\U00016ec0", - "\U00016ec1", - "\U00016ec2", - "\U00016ec3", - "\U00016ec4", - "\U00016ec5", - "\U00016ec6", - "\U00016ec7", - "\U00016ec8", - "\U00016ec9", - "\U00016eca", - "\U00016ecb", - "\U00016ecc", - "\U00016ecd", - "\U00016ece", - "\U00016ecf", - "\U00016ed0", - "\U00016ed1", - "\U00016ed2", - "\U00016ed3", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "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", - "0", - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "𝅗𝅥", - "𝅘𝅥", - "𝅘𝅥𝅮", - "𝅘𝅥𝅯", - "𝅘𝅥𝅰", - "𝅘𝅥𝅱", - "𝅘𝅥𝅲", - None, - None, - None, - "𝆹𝅥", - "𝆺𝅥", - "𝆹𝅥𝅮", - "𝆺𝅥𝅮", - "𝆹𝅥𝅯", - "𝆺𝅥𝅯", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "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", - "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", - None, - "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", - "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", - None, - "c", - "d", - None, - "g", - None, - "j", - "k", - None, - "n", - "o", - "p", - "q", - None, - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "a", - "b", - "c", - "d", - None, - "f", - None, - "h", - "i", - "j", - "k", - "l", - "m", - "n", - None, - "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", - "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", - None, - "d", - "e", - "f", - "g", - None, - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - None, - "s", - "t", - "u", - "v", - "w", - "x", - "y", - None, - "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", - None, - "d", - "e", - "f", - "g", - None, - "i", - "j", - "k", - "l", - "m", - None, - "o", - None, - "s", - "t", - "u", - "v", - "w", - "x", - "y", - None, - "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", - "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", - "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", - "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", - "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", - "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", - "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", - "ı", - "ȷ", - None, - "α", - "β", - "γ", - "δ", - "ε", - "ζ", - "η", - "θ", - "ι", - "κ", - "λ", - "μ", - "ν", - "ξ", - "ο", - "π", - "ρ", - "θ", - "σ", - "τ", - "υ", - "φ", - "χ", - "ψ", - "ω", - "∇", - "α", - "β", - "γ", - "δ", - "ε", - "ζ", - "η", - "θ", - "ι", - "κ", - "λ", - "μ", - "ν", - "ξ", - "ο", - "π", - "ρ", - "σ", - "τ", - "υ", - "φ", - "χ", - "ψ", - "ω", - "∂", - "ε", - "θ", - "κ", - "φ", - "ρ", - "π", - "α", - "β", - "γ", - "δ", - "ε", - "ζ", - "η", - "θ", - "ι", - "κ", - "λ", - "μ", - "ν", - "ξ", - "ο", - "π", - "ρ", - "θ", - "σ", - "τ", - "υ", - "φ", - "χ", - "ψ", - "ω", - "∇", - "α", - "β", - "γ", - "δ", - "ε", - "ζ", - "η", - "θ", - "ι", - "κ", - "λ", - "μ", - "ν", - "ξ", - "ο", - "π", - "ρ", - "σ", - "τ", - "υ", - "φ", - "χ", - "ψ", - "ω", - "∂", - "ε", - "θ", - "κ", - "φ", - "ρ", - "π", - "α", - "β", - "γ", - "δ", - "ε", - "ζ", - "η", - "θ", - "ι", - "κ", - "λ", - "μ", - "ν", - "ξ", - "ο", - "π", - "ρ", - "θ", - "σ", - "τ", - "υ", - "φ", - "χ", - "ψ", - "ω", - "∇", - "α", - "β", - "γ", - "δ", - "ε", - "ζ", - "η", - "θ", - "ι", - "κ", - "λ", - "μ", - "ν", - "ξ", - "ο", - "π", - "ρ", - "σ", - "τ", - "υ", - "φ", - "χ", - "ψ", - "ω", - "∂", - "ε", - "θ", - "κ", - "φ", - "ρ", - "π", - "α", - "β", - "γ", - "δ", - "ε", - "ζ", - "η", - "θ", - "ι", - "κ", - "λ", - "μ", - "ν", - "ξ", - "ο", - "π", - "ρ", - "θ", - "σ", - "τ", - "υ", - "φ", - "χ", - "ψ", - "ω", - "∇", - "α", - "β", - "γ", - "δ", - "ε", - "ζ", - "η", - "θ", - "ι", - "κ", - "λ", - "μ", - "ν", - "ξ", - "ο", - "π", - "ρ", - "σ", - "τ", - "υ", - "φ", - "χ", - "ψ", - "ω", - "∂", - "ε", - "θ", - "κ", - "φ", - "ρ", - "π", - "α", - "β", - "γ", - "δ", - "ε", - "ζ", - "η", - "θ", - "ι", - "κ", - "λ", - "μ", - "ν", - "ξ", - "ο", - "π", - "ρ", - "θ", - "σ", - "τ", - "υ", - "φ", - "χ", - "ψ", - "ω", - "∇", - "α", - "β", - "γ", - "δ", - "ε", - "ζ", - "η", - "θ", - "ι", - "κ", - "λ", - "μ", - "ν", - "ξ", - "ο", - "π", - "ρ", - "σ", - "τ", - "υ", - "φ", - "χ", - "ψ", - "ω", - "∂", - "ε", - "θ", - "κ", - "φ", - "ρ", - "π", - "ϝ", - None, - "0", - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - "0", - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - "0", - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - "0", - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - "0", - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "а", - "б", - "в", - "г", - "д", - "е", - "ж", - "з", - "и", - "к", - "л", - "м", - "о", - "п", - "р", - "с", - "т", - "у", - "ф", - "х", - "ц", - "ч", - "ш", - "ы", - "э", - "ю", - "ꚉ", - "ә", - "і", - "ј", - "ө", - "ү", - "ӏ", - "а", - "б", - "в", - "г", - "д", - "е", - "ж", - "з", - "и", - "к", - "л", - "о", - "п", - "с", - "у", - "ф", - "х", - "ц", - "ч", - "ш", - "ъ", - "ы", - "ґ", - "і", - "ѕ", - "џ", - "ҫ", - "ꙑ", - "ұ", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "𞤢", - "𞤣", - "𞤤", - "𞤥", - "𞤦", - "𞤧", - "𞤨", - "𞤩", - "𞤪", - "𞤫", - "𞤬", - "𞤭", - "𞤮", - "𞤯", - "𞤰", - "𞤱", - "𞤲", - "𞤳", - "𞤴", - "𞤵", - "𞤶", - "𞤷", - "𞤸", - "𞤹", - "𞤺", - "𞤻", - "𞤼", - "𞤽", - "𞤾", - "𞤿", - "𞥀", - "𞥁", - "𞥂", - "𞥃", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "ا", - "ب", - "ج", - "د", - None, - "و", - "ز", - "ح", - "ط", - "ي", - "ك", - "ل", - "م", - "ن", - "س", - "ع", - "ف", - "ص", - "ق", - "ر", - "ش", - "ت", - "ث", - "خ", - "ذ", - "ض", - "ظ", - "غ", - "ٮ", - "ں", - "ڡ", - "ٯ", - None, - "ب", - "ج", - None, - "ه", - None, - "ح", - None, - "ي", - "ك", - "ل", - "م", - "ن", - "س", - "ع", - "ف", - "ص", - "ق", - None, - "ش", - "ت", - "ث", - "خ", - None, - "ض", - None, - "غ", - None, - "ج", - None, - "ح", - None, - "ي", - None, - "ل", - None, - "ن", - "س", - "ع", - None, - "ص", - "ق", - None, - "ش", - None, - "خ", - None, - "ض", - None, - "غ", - None, - "ں", - None, - "ٯ", - None, - "ب", - "ج", - None, - "ه", - None, - "ح", - "ط", - "ي", - "ك", - None, - "م", - "ن", - "س", - "ع", - "ف", - "ص", - "ق", - None, - "ش", - "ت", - "ث", - "خ", - None, - "ض", - "ظ", - "غ", - "ٮ", - None, - "ڡ", - None, - "ا", - "ب", - "ج", - "د", - "ه", - "و", - "ز", - "ح", - "ط", - "ي", - None, - "ل", - "م", - "ن", - "س", - "ع", - "ف", - "ص", - "ق", - "ر", - "ش", - "ت", - "ث", - "خ", - "ذ", - "ض", - "ظ", - "غ", - None, - "ب", - "ج", - "د", - None, - "و", - "ز", - "ح", - "ط", - "ي", - None, - "ل", - "م", - "ن", - "س", - "ع", - "ف", - "ص", - "ق", - "ر", - "ش", - "ت", - "ث", - "خ", - "ذ", - "ض", - "ظ", - "غ", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "0,", - "1,", - "2,", - "3,", - "4,", - "5,", - "6,", - "7,", - "8,", - "9,", - None, - "(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)", - "〔s〕", - "c", - "r", - "cd", - "wz", - None, - "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", - "hv", - "mv", - "sd", - "ss", - "ppv", - "wc", - None, - "mc", - "md", - "mr", - None, - "dj", - None, - None, - None, - "ほか", - "ココ", - "サ", - None, - "手", - "字", - "双", - "デ", - "二", - "多", - "解", - "天", - "交", - "映", - "無", - "料", - "前", - "後", - "再", - "新", - "初", - "終", - "生", - "販", - "声", - "吹", - "演", - "投", - "捕", - "一", - "三", - "遊", - "左", - "中", - "右", - "指", - "走", - "打", - "禁", - "空", - "合", - "満", - "有", - "月", - "申", - "割", - "営", - "配", - None, - "〔本〕", - "〔三〕", - "〔二〕", - "〔安〕", - "〔点〕", - "〔打〕", - "〔盗〕", - "〔勝〕", - "〔敗〕", - None, - "得", - "可", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "0", - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "丽", - "丸", - "乁", - "𠄢", - "你", - "侮", - "侻", - "倂", - "偺", - "備", - "僧", - "像", - "㒞", - "𠘺", - "免", - "兔", - "兤", - "具", - "𠔜", - "㒹", - "內", - "再", - "𠕋", - "冗", - "冤", - "仌", - "冬", - "况", - "𩇟", - "凵", - "刃", - "㓟", - "刻", - "剆", - "割", - "剷", - "㔕", - "勇", - "勉", - "勤", - "勺", - "包", - "匆", - "北", - "卉", - "卑", - "博", - "即", - "卽", - "卿", - "𠨬", - "灰", - "及", - "叟", - "𠭣", - "叫", - "叱", - "吆", - "咞", - "吸", - "呈", - "周", - "咢", - "哶", - "唐", - "啓", - "啣", - "善", - "喙", - "喫", - "喳", - "嗂", - "圖", - "嘆", - "圗", - "噑", - "噴", - "切", - "壮", - "城", - "埴", - "堍", - "型", - "堲", - "報", - "墬", - "𡓤", - "売", - "壷", - "夆", - "多", - "夢", - "奢", - "𡚨", - "𡛪", - "姬", - "娛", - "娧", - "姘", - "婦", - "㛮", - "㛼", - "嬈", - "嬾", - "𡧈", - "寃", - "寘", - "寧", - "寳", - "𡬘", - "寿", - "将", - "当", - "尢", - "㞁", - "屠", - "屮", - "峀", - "岍", - "𡷤", - "嵃", - "𡷦", - "嵮", - "嵫", - "嵼", - "巡", - "巢", - "㠯", - "巽", - "帨", - "帽", - "幩", - "㡢", - "𢆃", - "㡼", - "庰", - "庳", - "庶", - "廊", - "𪎒", - "廾", - "𢌱", - "舁", - "弢", - "㣇", - "𣊸", - "𦇚", - "形", - "彫", - "㣣", - "徚", - "忍", - "志", - "忹", - "悁", - "㤺", - "㤜", - "悔", - "𢛔", - "惇", - "慈", - "慌", - "慎", - "慌", - "慺", - "憎", - "憲", - "憤", - "憯", - "懞", - "懲", - "懶", - "成", - "戛", - "扝", - "抱", - "拔", - "捐", - "𢬌", - "挽", - "拼", - "捨", - "掃", - "揤", - "𢯱", - "搢", - "揅", - "掩", - "㨮", - "摩", - "摾", - "撝", - "摷", - "㩬", - "敏", - "敬", - "𣀊", - "旣", - "書", - "晉", - "㬙", - "暑", - "㬈", - "㫤", - "冒", - "冕", - "最", - "暜", - "肭", - "䏙", - "朗", - "望", - "朡", - "杞", - "杓", - "𣏃", - "㭉", - "柺", - "枅", - "桒", - "梅", - "𣑭", - "梎", - "栟", - "椔", - "㮝", - "楂", - "榣", - "槪", - "檨", - "𣚣", - "櫛", - "㰘", - "次", - "𣢧", - "歔", - "㱎", - "歲", - "殟", - "殺", - "殻", - "𣪍", - "𡴋", - "𣫺", - "汎", - "𣲼", - "沿", - "泍", - "汧", - "洖", - "派", - "海", - "流", - "浩", - "浸", - "涅", - "𣴞", - "洴", - "港", - "湮", - "㴳", - "滋", - "滇", - "𣻑", - "淹", - "潮", - "𣽞", - "𣾎", - "濆", - "瀹", - "瀞", - "瀛", - "㶖", - "灊", - "災", - "灷", - "炭", - "𠔥", - "煅", - "𤉣", - "熜", - "𤎫", - "爨", - "爵", - "牐", - "𤘈", - "犀", - "犕", - "𤜵", - "𤠔", - "獺", - "王", - "㺬", - "玥", - "㺸", - "瑇", - "瑜", - "瑱", - "璅", - "瓊", - "㼛", - "甤", - "𤰶", - "甾", - "𤲒", - "異", - "𢆟", - "瘐", - "𤾡", - "𤾸", - "𥁄", - "㿼", - "䀈", - "直", - "𥃳", - "𥃲", - "𥄙", - "𥄳", - "眞", - "真", - "睊", - "䀹", - "瞋", - "䁆", - "䂖", - "𥐝", - "硎", - "碌", - "磌", - "䃣", - "𥘦", - "祖", - "𥚚", - "𥛅", - "福", - "秫", - "䄯", - "穀", - "穊", - "穏", - "𥥼", - "𥪧", - "竮", - "䈂", - "𥮫", - "篆", - "築", - "䈧", - "𥲀", - "糒", - "䊠", - "糨", - "糣", - "紀", - "𥾆", - "絣", - "䌁", - "緇", - "縂", - "繅", - "䌴", - "𦈨", - "𦉇", - "䍙", - "𦋙", - "罺", - "𦌾", - "羕", - "翺", - "者", - "𦓚", - "𦔣", - "聠", - "𦖨", - "聰", - "𣍟", - "䏕", - "育", - "脃", - "䐋", - "脾", - "媵", - "𦞧", - "𦞵", - "𣎓", - "𣎜", - "舁", - "舄", - "辞", - "䑫", - "芑", - "芋", - "芝", - "劳", - "花", - "芳", - "芽", - "苦", - "𦬼", - "若", - "茝", - "荣", - "莭", - "茣", - "莽", - "菧", - "著", - "荓", - "菊", - "菌", - "菜", - "𦰶", - "𦵫", - "𦳕", - "䔫", - "蓱", - "蓳", - "蔖", - "𧏊", - "蕤", - "𦼬", - "䕝", - "䕡", - "𦾱", - "𧃒", - "䕫", - "虐", - "虜", - "虧", - "虩", - "蚩", - "蚈", - "蜎", - "蛢", - "蝹", - "蜨", - "蝫", - "螆", - "䗗", - "蟡", - "蠁", - "䗹", - "衠", - "衣", - "𧙧", - "裗", - "裞", - "䘵", - "裺", - "㒻", - "𧢮", - "𧥦", - "䚾", - "䛇", - "誠", - "諭", - "變", - "豕", - "𧲨", - "貫", - "賁", - "贛", - "起", - "𧼯", - "𠠄", - "跋", - "趼", - "跰", - "𠣞", - "軔", - "輸", - "𨗒", - "𨗭", - "邔", - "郱", - "鄑", - "𨜮", - "鄛", - "鈸", - "鋗", - "鋘", - "鉼", - "鏹", - "鐕", - "𨯺", - "開", - "䦕", - "閷", - "𨵷", - "䧦", - "雃", - "嶲", - "霣", - "𩅅", - "𩈚", - "䩮", - "䩶", - "韠", - "𩐊", - "䪲", - "𩒖", - "頋", - "頩", - "𩖶", - "飢", - "䬳", - "餩", - "馧", - "駂", - "駾", - "䯎", - "𩬰", - "鬒", - "鱀", - "鳽", - "䳎", - "䳭", - "鵧", - "𪃎", - "䳸", - "𪄅", - "𪈎", - "𪊑", - "麻", - "䵖", - "黹", - "黾", - "鼅", - "鼏", - "鼖", - "鼻", - "𪘀", - None, - None, - None, - None, - None, - None, - None, -) diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/msgpack/COPYING b/venv/lib/python3.11/site-packages/pip/_vendor/msgpack/COPYING deleted file mode 100755 index f067af3..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/msgpack/COPYING +++ /dev/null @@ -1,14 +0,0 @@ -Copyright (C) 2008-2011 INADA Naoki - - 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. - diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/msgpack/__init__.py b/venv/lib/python3.11/site-packages/pip/_vendor/msgpack/__init__.py deleted file mode 100755 index f3266b7..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/msgpack/__init__.py +++ /dev/null @@ -1,55 +0,0 @@ -# ruff: noqa: F401 -import os - -from .exceptions import * # noqa: F403 -from .ext import ExtType, Timestamp - -version = (1, 1, 2) -__version__ = "1.1.2" - - -if os.environ.get("MSGPACK_PUREPYTHON"): - from .fallback import Packer, Unpacker, unpackb -else: - try: - from ._cmsgpack import Packer, Unpacker, unpackb - except ImportError: - from .fallback import Packer, Unpacker, unpackb - - -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.11/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-311.pyc deleted file mode 100755 index a76a346d0c8bac9bc563af01232e954f2698a4fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1978 zcmb7FTWcFf6rRyuw9-nxD7KSgYBpAgQJ`8}m)3O}Q&T&=rLG&>q}~^4tsUEPw7X(< zeMJEg0-+_eZV5Q_$qyx=!kGP>^EoUdgeRl ztezy3aRl<~!ylGsMTGw3FHM2>Kn{P0W*b?^!X;!ND`E*HJi}YD6tM+Euth_}$dU}n zk`0-l<>>KBw4*ewldTnfj1hVYPbgG{y_8bSjvH}XHB>ucBrtL=#`qaZDS4{DJB>)& zB}9{O<{9hekRz_4bzu&zVJmhI8SPdau)|UTJ4vUJA_?OhX*aq^htX}}X_QGEa7QK& zxJMbx@Rdx2MJLw%nT;}Gv6-SxJm0j-8G#BgBY=YlSew#db};)UOMN!|;ndg%pXR1! zZ%$0j&3yFvWJX}}lv%hFTMeF{NlpqmvIe*d#btf%cS6Ic{i__j-{>9qEED< zulcT)_k2oBJ0A~bPZOez6iTM&jpV~S=CuWvYHrytx{j9(CQbeX+tV2M!=zvL%LZm>#M|B)l0>By}aQs zxz12_a8UQa%{TaZbCGy@xmeb7FwJtQZhMQoU(e-=PSMZhvgHlh4krZA1%~%7Ko$L! zKy6*M6_AuL9PlR;^P@_iUN z6-o@D#5|NQ3FE17L2x3Qw_X|?O8gb-XaQ}OHoxH$?|;OGCc(cIoFFFg6Xxl8u>1JfWq^RNM5?Ctf^J<8+uu~}7ggKo+*Q+iYPu$-X*Wzgo1JkO z*+vz#1MR=%F?2m`b>E5jyylLj5?N^R2n^xP2LVH2fkDR+S(FvTGO-c8T@if9`grtVKd@|vi#e7D}!&gIuGO;KxXGs1|XaY)^ zXu)|NzX&9E$gCWG3urHN4#4AasG>$2N~FHM`t{YXu06O`9sfg3ZM{`f`#~SQ9kw;G zKj1dg!y>N7;$*!*!op($_napol>u0El~4~VlBqc;iNMU|SQKigNTF9)BtBCX%u;C{ zf*d9T|2GKSXR%!2xPF-Wv0ZklKS8NW!vf;@5O~hSl51K_;^@IOSL`yAIC?>j1&#*y zeXhJ`yVgpHjM6Kxm{*P057-be#``E%4SxIRwOUi_C|x^C_v7cP(Ry2VRc**fl<$q) zAH6$TOI_X-2KI!329oh`T^y>tQX8Tm4cC?7+AH;_uJ$w#mWKa6kP diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-311.pyc deleted file mode 100755 index 138b099f935a04599c86dee9341b99fc8831fe5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2375 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 Sq1|o%^VF>S{sm3gHvShi#V=9- diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-311.pyc deleted file mode 100755 index 5b219cc73195c056e627227d53ee6f74a36a195e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44768 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 diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/msgpack/exceptions.py b/venv/lib/python3.11/site-packages/pip/_vendor/msgpack/exceptions.py deleted file mode 100755 index d6d2615..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/msgpack/exceptions.py +++ /dev/null @@ -1,48 +0,0 @@ -class UnpackException(Exception): - """Base class for some exceptions raised while unpacking. - - NOTE: unpack may raise exception other than subclass of - UnpackException. If you want to catch all error, catch - Exception instead. - """ - - -class BufferFull(UnpackException): - pass - - -class OutOfData(UnpackException): - pass - - -class FormatError(ValueError, UnpackException): - """Invalid msgpack format""" - - -class StackError(ValueError, UnpackException): - """Too nested""" - - -# Deprecated. Use ValueError instead -UnpackValueError = ValueError - - -class ExtraData(UnpackValueError): - """ExtraData is raised when there is trailing data. - - This exception is raised while only one-shot (not streaming) - unpack. - """ - - def __init__(self, unpacked, extra): - self.unpacked = unpacked - self.extra = extra - - def __str__(self): - return "unpack(b) received extra data." - - -# Deprecated. Use Exception instead to catch all exception during packing. -PackException = Exception -PackValueError = ValueError -PackOverflowError = OverflowError diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/msgpack/ext.py b/venv/lib/python3.11/site-packages/pip/_vendor/msgpack/ext.py deleted file mode 100755 index 9694819..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/msgpack/ext.py +++ /dev/null @@ -1,170 +0,0 @@ -import datetime -import struct -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().__new__(cls, code, data) - - -class Timestamp: - """Timestamp represents the Timestamp extension type in msgpack. - - When built with Cython, msgpack uses C methods to pack and unpack `Timestamp`. - When using pure-Python msgpack, :func:`to_bytes` and :func:`from_bytes` are used to pack and - unpack `Timestamp`. - - This class is immutable: Do not override seconds and nanoseconds. - """ - - __slots__ = ["seconds", "nanoseconds"] - - def __init__(self, seconds, nanoseconds=0): - """Initialize a Timestamp object. - - :param int seconds: - Number of seconds since the UNIX epoch (00:00:00 UTC Jan 1 1970, minus leap seconds). - May be negative. - - :param int nanoseconds: - Number of nanoseconds to add to `seconds` to get fractional time. - Maximum is 999_999_999. Default is 0. - - Note: Negative times (before the UNIX epoch) are represented as neg. seconds + pos. ns. - """ - if not isinstance(seconds, int): - raise TypeError("seconds must be an integer") - if not isinstance(nanoseconds, int): - raise TypeError("nanoseconds must be an integer") - if not (0 <= nanoseconds < 10**9): - raise ValueError("nanoseconds must be a non-negative integer less than 999999999.") - self.seconds = seconds - self.nanoseconds = nanoseconds - - def __repr__(self): - """String representation of Timestamp.""" - return f"Timestamp(seconds={self.seconds}, nanoseconds={self.nanoseconds})" - - def __eq__(self, other): - """Check for equality with another Timestamp object""" - if type(other) is self.__class__: - return self.seconds == other.seconds and self.nanoseconds == other.nanoseconds - return False - - def __ne__(self, other): - """not-equals method (see :func:`__eq__()`)""" - return not self.__eq__(other) - - def __hash__(self): - return hash((self.seconds, self.nanoseconds)) - - @staticmethod - def from_bytes(b): - """Unpack bytes into a `Timestamp` object. - - Used for pure-Python msgpack unpacking. - - :param b: Payload from msgpack ext message with code -1 - :type b: bytes - - :returns: Timestamp object unpacked from msgpack ext payload - :rtype: Timestamp - """ - if len(b) == 4: - seconds = struct.unpack("!L", b)[0] - nanoseconds = 0 - elif len(b) == 8: - data64 = struct.unpack("!Q", b)[0] - seconds = data64 & 0x00000003FFFFFFFF - nanoseconds = data64 >> 34 - elif len(b) == 12: - nanoseconds, seconds = struct.unpack("!Iq", b) - else: - raise ValueError( - "Timestamp type can only be created from 32, 64, or 96-bit byte objects" - ) - return Timestamp(seconds, nanoseconds) - - def to_bytes(self): - """Pack this Timestamp object into bytes. - - Used for pure-Python msgpack packing. - - :returns data: Payload for EXT message with code -1 (timestamp type) - :rtype: bytes - """ - if (self.seconds >> 34) == 0: # seconds is non-negative and fits in 34 bits - data64 = self.nanoseconds << 34 | self.seconds - if data64 & 0xFFFFFFFF00000000 == 0: - # nanoseconds is zero and seconds < 2**32, so timestamp 32 - data = struct.pack("!L", data64) - else: - # timestamp 64 - data = struct.pack("!Q", data64) - else: - # timestamp 96 - data = struct.pack("!Iq", self.nanoseconds, self.seconds) - return data - - @staticmethod - def from_unix(unix_sec): - """Create a Timestamp from posix timestamp in seconds. - - :param unix_float: Posix timestamp in seconds. - :type unix_float: int or float - """ - seconds = int(unix_sec // 1) - nanoseconds = int((unix_sec % 1) * 10**9) - return Timestamp(seconds, nanoseconds) - - def to_unix(self): - """Get the timestamp as a floating-point value. - - :returns: posix timestamp - :rtype: float - """ - return self.seconds + self.nanoseconds / 1e9 - - @staticmethod - def from_unix_nano(unix_ns): - """Create a Timestamp from posix timestamp in nanoseconds. - - :param int unix_ns: Posix timestamp in nanoseconds. - :rtype: Timestamp - """ - return Timestamp(*divmod(unix_ns, 10**9)) - - def to_unix_nano(self): - """Get the timestamp as a unixtime in nanoseconds. - - :returns: posix timestamp in nanoseconds - :rtype: int - """ - return self.seconds * 10**9 + self.nanoseconds - - def to_datetime(self): - """Get the timestamp as a UTC datetime. - - :rtype: `datetime.datetime` - """ - utc = datetime.timezone.utc - return datetime.datetime.fromtimestamp(0, utc) + datetime.timedelta( - seconds=self.seconds, microseconds=self.nanoseconds // 1000 - ) - - @staticmethod - def from_datetime(dt): - """Create a Timestamp from datetime with tzinfo. - - :rtype: Timestamp - """ - return Timestamp(seconds=int(dt.timestamp()), nanoseconds=dt.microsecond * 1000) diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/msgpack/fallback.py b/venv/lib/python3.11/site-packages/pip/_vendor/msgpack/fallback.py deleted file mode 100755 index b02e47c..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/msgpack/fallback.py +++ /dev/null @@ -1,929 +0,0 @@ -"""Fallback pure Python implementation of msgpack""" - -import struct -import sys -from datetime import datetime as _DateTime - -if hasattr(sys, "pypy_version_info"): - from __pypy__ import newlist_hint - from __pypy__.builders import BytesBuilder - - _USING_STRINGBUILDER = True - - class BytesIO: - def __init__(self, s=b""): - if s: - self.builder = BytesBuilder(len(s)) - self.builder.append(s) - else: - self.builder = BytesBuilder() - - 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: - from io import BytesIO - - _USING_STRINGBUILDER = False - - def newlist_hint(size): - return [] - - -from .exceptions import BufferFull, ExtraData, FormatError, OutOfData, StackError -from .ext import ExtType, Timestamp - -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): - view = memoryview(obj) - if view.itemsize != 1: - raise ValueError("cannot unpack from multi-byte object") - return view - - -def unpackb(packed, **kwargs): - """ - Unpack an object from `packed`. - - Raises ``ExtraData`` when *packed* contains extra bytes. - Raises ``ValueError`` when *packed* is incomplete. - Raises ``FormatError`` when *packed* is not valid msgpack. - Raises ``StackError`` when *packed* contains too nested. - Other exceptions can be raised during unpacking. - - See :class:`Unpacker` for options. - """ - unpacker = Unpacker(None, max_buffer_size=len(packed), **kwargs) - unpacker.feed(packed) - try: - ret = unpacker._unpack() - except OutOfData: - raise ValueError("Unpack failed: incomplete input") - except RecursionError: - raise StackError - if unpacker._got_extradata(): - raise ExtraData(ret, unpacker._get_extradata()) - return ret - - -_NO_FORMAT_USED = "" -_MSGPACK_HEADERS = { - 0xC4: (1, _NO_FORMAT_USED, TYPE_BIN), - 0xC5: (2, ">H", TYPE_BIN), - 0xC6: (4, ">I", TYPE_BIN), - 0xC7: (2, "Bb", TYPE_EXT), - 0xC8: (3, ">Hb", TYPE_EXT), - 0xC9: (5, ">Ib", TYPE_EXT), - 0xCA: (4, ">f"), - 0xCB: (8, ">d"), - 0xCC: (1, _NO_FORMAT_USED), - 0xCD: (2, ">H"), - 0xCE: (4, ">I"), - 0xCF: (8, ">Q"), - 0xD0: (1, "b"), - 0xD1: (2, ">h"), - 0xD2: (4, ">i"), - 0xD3: (8, ">q"), - 0xD4: (1, "b1s", TYPE_EXT), - 0xD5: (2, "b2s", TYPE_EXT), - 0xD6: (4, "b4s", TYPE_EXT), - 0xD7: (8, "b8s", TYPE_EXT), - 0xD8: (16, "b16s", TYPE_EXT), - 0xD9: (1, _NO_FORMAT_USED, TYPE_RAW), - 0xDA: (2, ">H", TYPE_RAW), - 0xDB: (4, ">I", TYPE_RAW), - 0xDC: (2, ">H", TYPE_ARRAY), - 0xDD: (4, ">I", TYPE_ARRAY), - 0xDE: (2, ">H", TYPE_MAP), - 0xDF: (4, ">I", TYPE_MAP), -} - - -class Unpacker: - """Streaming unpacker. - - Arguments: - - :param file_like: - File-like object having `.read(n)` method. - If specified, unpacker reads serialized data from it and `.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. - Otherwise, unpack to Python str by decoding with UTF-8 encoding (default). - - :param int timestamp: - Control how timestamp type is unpacked: - - 0 - Timestamp - 1 - float (Seconds from the EPOCH) - 2 - int (Nanoseconds from the EPOCH) - 3 - datetime.datetime (UTC). - - :param bool strict_map_key: - If true (default), only str or bytes are accepted for map (dict) keys. - - :param object_hook: - When specified, it should be callable. - Unpacker calls it with a dict argument after unpacking msgpack map. - (See also simplejson) - - :param 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 unicode_errors: - The error handler for decoding unicode. (default: 'strict') - This option should be used only when you have msgpack data which - contains invalid UTF-8 string. - - :param int max_buffer_size: - Limits size of data waiting unpacked. 0 means 2**32-1. - The default value is 100*1024*1024 (100MiB). - Raises `BufferFull` exception when it is insufficient. - You should set this parameter when unpacking data from untrusted source. - - :param int max_str_len: - Deprecated, use *max_buffer_size* instead. - Limits max length of str. (default: max_buffer_size) - - :param int max_bin_len: - Deprecated, use *max_buffer_size* instead. - Limits max length of bin. (default: max_buffer_size) - - :param int max_array_len: - Limits max length of array. - (default: max_buffer_size) - - :param int max_map_len: - Limits max length of map. - (default: max_buffer_size//2) - - :param int max_ext_len: - Deprecated, use *max_buffer_size* instead. - Limits max size of ext type. (default: max_buffer_size) - - Example of streaming deserialize from file-like object:: - - unpacker = Unpacker(file_like) - for o in unpacker: - process(o) - - Example of streaming deserialize from socket:: - - unpacker = Unpacker() - while True: - buf = sock.recv(1024**2) - if not buf: - break - unpacker.feed(buf) - for o in unpacker: - process(o) - - Raises ``ExtraData`` when *packed* contains extra bytes. - Raises ``OutOfData`` when *packed* is incomplete. - Raises ``FormatError`` when *packed* is not valid msgpack. - Raises ``StackError`` when *packed* contains too nested. - Other exceptions can be raised during unpacking. - """ - - def __init__( - self, - file_like=None, - *, - read_size=0, - use_list=True, - raw=False, - timestamp=0, - strict_map_key=True, - object_hook=None, - object_pairs_hook=None, - list_hook=None, - unicode_errors=None, - max_buffer_size=100 * 1024 * 1024, - ext_hook=ExtType, - max_str_len=-1, - max_bin_len=-1, - max_array_len=-1, - max_map_len=-1, - max_ext_len=-1, - ): - if unicode_errors is None: - unicode_errors = "strict" - - 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() - #: 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 - - if not max_buffer_size: - max_buffer_size = 2**31 - 1 - if max_str_len == -1: - max_str_len = max_buffer_size - if max_bin_len == -1: - max_bin_len = max_buffer_size - if max_array_len == -1: - max_array_len = max_buffer_size - if max_map_len == -1: - max_map_len = max_buffer_size // 2 - if max_ext_len == -1: - max_ext_len = max_buffer_size - - self._max_buffer_size = max_buffer_size - if read_size > self._max_buffer_size: - raise ValueError("read_size must be smaller than max_buffer_size") - self._read_size = read_size or min(self._max_buffer_size, 16 * 1024) - self._raw = bool(raw) - self._strict_map_key = bool(strict_map_key) - self._unicode_errors = unicode_errors - self._use_list = use_list - if not (0 <= timestamp <= 3): - raise ValueError("timestamp must be 0..3") - self._timestamp = timestamp - self._list_hook = list_hook - self._object_hook = object_hook - self._object_pairs_hook = object_pairs_hook - 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 - - # Use extend here: INPLACE_ADD += doesn't reliably typecast memoryview in jython - self._buffer.extend(view) - view.release() - - 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): - ret = self._read(n, raise_outofdata=False) - self._consume() - return ret - - def _read(self, n, raise_outofdata=True): - # (int) -> bytearray - self._reserve(n, raise_outofdata=raise_outofdata) - i = self._buff_i - ret = self._buffer[i : i + n] - self._buff_i = i + len(ret) - return ret - - def _reserve(self, n, raise_outofdata=True): - 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 - if remain_bytes + len(self._buffer) > self._max_buffer_size: - raise BufferFull - 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 and raise_outofdata: - self._buff_i = 0 # rollback - raise OutOfData - - def _read_header(self): - 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 ValueError(f"{n} exceeds max_str_len({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 ValueError(f"{n} exceeds max_array_len({self._max_array_len})") - elif b & 0b11110000 == 0b10000000: - n = b & 0b00001111 - typ = TYPE_MAP - if n > self._max_map_len: - raise ValueError(f"{n} exceeds max_map_len({self._max_map_len})") - elif b == 0xC0: - obj = None - elif b == 0xC2: - obj = False - elif b == 0xC3: - obj = True - elif 0xC4 <= b <= 0xC6: - size, fmt, typ = _MSGPACK_HEADERS[b] - self._reserve(size) - if len(fmt) > 0: - n = struct.unpack_from(fmt, self._buffer, self._buff_i)[0] - else: - n = self._buffer[self._buff_i] - self._buff_i += size - if n > self._max_bin_len: - raise ValueError(f"{n} exceeds max_bin_len({self._max_bin_len})") - obj = self._read(n) - elif 0xC7 <= b <= 0xC9: - size, fmt, typ = _MSGPACK_HEADERS[b] - self._reserve(size) - L, n = struct.unpack_from(fmt, self._buffer, self._buff_i) - self._buff_i += size - if L > self._max_ext_len: - raise ValueError(f"{L} exceeds max_ext_len({self._max_ext_len})") - obj = self._read(L) - elif 0xCA <= b <= 0xD3: - size, fmt = _MSGPACK_HEADERS[b] - self._reserve(size) - if len(fmt) > 0: - obj = struct.unpack_from(fmt, self._buffer, self._buff_i)[0] - else: - obj = self._buffer[self._buff_i] - self._buff_i += size - elif 0xD4 <= b <= 0xD8: - size, fmt, typ = _MSGPACK_HEADERS[b] - if self._max_ext_len < size: - raise ValueError(f"{size} exceeds max_ext_len({self._max_ext_len})") - self._reserve(size + 1) - n, obj = struct.unpack_from(fmt, self._buffer, self._buff_i) - self._buff_i += size + 1 - elif 0xD9 <= b <= 0xDB: - size, fmt, typ = _MSGPACK_HEADERS[b] - self._reserve(size) - if len(fmt) > 0: - (n,) = struct.unpack_from(fmt, self._buffer, self._buff_i) - else: - n = self._buffer[self._buff_i] - self._buff_i += size - if n > self._max_str_len: - raise ValueError(f"{n} exceeds max_str_len({self._max_str_len})") - obj = self._read(n) - elif 0xDC <= b <= 0xDD: - size, fmt, typ = _MSGPACK_HEADERS[b] - self._reserve(size) - (n,) = struct.unpack_from(fmt, self._buffer, self._buff_i) - self._buff_i += size - if n > self._max_array_len: - raise ValueError(f"{n} exceeds max_array_len({self._max_array_len})") - elif 0xDE <= b <= 0xDF: - size, fmt, typ = _MSGPACK_HEADERS[b] - self._reserve(size) - (n,) = struct.unpack_from(fmt, self._buffer, self._buff_i) - self._buff_i += size - if n > self._max_map_len: - raise ValueError(f"{n} exceeds max_map_len({self._max_map_len})") - else: - raise FormatError("Unknown header: 0x%x" % b) - return typ, n, obj - - def _unpack(self, execute=EX_CONSTRUCT): - typ, n, obj = self._read_header() - - if execute == EX_READ_ARRAY_HEADER: - if typ != TYPE_ARRAY: - raise ValueError("Expected array") - return n - if execute == EX_READ_MAP_HEADER: - if typ != TYPE_MAP: - raise ValueError("Expected map") - return n - # TODO should we eliminate the recursion? - if typ == TYPE_ARRAY: - if execute == EX_SKIP: - for i in range(n): - # TODO check whether we need to call `list_hook` - self._unpack(EX_SKIP) - return - ret = newlist_hint(n) - for i in range(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 range(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 range(n) - ) - else: - ret = {} - for _ in range(n): - key = self._unpack(EX_CONSTRUCT) - if self._strict_map_key and type(key) not in (str, bytes): - raise ValueError("%s is not allowed for map key" % str(type(key))) - if isinstance(key, str): - key = sys.intern(key) - 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._raw: - obj = bytes(obj) - else: - obj = obj.decode("utf_8", self._unicode_errors) - return obj - if typ == TYPE_BIN: - return bytes(obj) - if typ == TYPE_EXT: - if n == -1: # timestamp - ts = Timestamp.from_bytes(bytes(obj)) - if self._timestamp == 1: - return ts.to_unix() - elif self._timestamp == 2: - return ts.to_unix_nano() - elif self._timestamp == 3: - return ts.to_datetime() - else: - return ts - else: - return self._ext_hook(n, bytes(obj)) - assert typ == TYPE_IMMEDIATE - return obj - - def __iter__(self): - return self - - def __next__(self): - try: - ret = self._unpack(EX_CONSTRUCT) - self._consume() - return ret - except OutOfData: - self._consume() - raise StopIteration - except RecursionError: - raise StackError - - next = __next__ - - def skip(self): - self._unpack(EX_SKIP) - self._consume() - - def unpack(self): - try: - ret = self._unpack(EX_CONSTRUCT) - except RecursionError: - raise StackError - self._consume() - return ret - - def read_array_header(self): - ret = self._unpack(EX_READ_ARRAY_HEADER) - self._consume() - return ret - - def read_map_header(self): - ret = self._unpack(EX_READ_MAP_HEADER) - self._consume() - return ret - - def tell(self): - return self._stream_offset - - -class Packer: - """ - MessagePack Packer - - Usage:: - - packer = Packer() - astream.write(packer.pack(a)) - astream.write(packer.pack(b)) - - Packer's constructor has some keyword arguments: - - :param default: - When specified, it should be callable. - 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. (default: True) - - :param bool strict_types: - If set to true, types will be checked to be exact. Derived classes - from serializable types will not be serialized and will be - treated as unsupported type and forwarded to default. - Additionally tuples will not be serialized as lists. - This is useful when trying to implement accurate serialization - for python types. - - :param bool datetime: - If set to true, datetime with tzinfo is packed into Timestamp type. - Note that the tzinfo is stripped in the timestamp. - You can get UTC datetime with `timestamp=3` option of the Unpacker. - - :param str unicode_errors: - The error handler for encoding unicode. (default: 'strict') - DO NOT USE THIS!! This option is kept for very specific usage. - - :param int buf_size: - Internal buffer size. This option is used only for C implementation. - """ - - def __init__( - self, - *, - default=None, - use_single_float=False, - autoreset=True, - use_bin_type=True, - strict_types=False, - datetime=False, - unicode_errors=None, - buf_size=None, - ): - self._strict_types = strict_types - self._use_float = use_single_float - self._autoreset = autoreset - self._use_bin_type = use_bin_type - self._buffer = BytesIO() - self._datetime = bool(datetime) - self._unicode_errors = unicode_errors or "strict" - if default is not None and 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 ValueError("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): - 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 OverflowError("Integer value out of range") - if check(obj, (bytes, bytearray)): - n = len(obj) - if n >= 2**32: - raise ValueError("%s is too large" % type(obj).__name__) - self._pack_bin_header(n) - return self._buffer.write(obj) - if check(obj, str): - obj = obj.encode("utf-8", self._unicode_errors) - n = len(obj) - if n >= 2**32: - raise ValueError("String is too large") - self._pack_raw_header(n) - return self._buffer.write(obj) - if check(obj, memoryview): - n = obj.nbytes - if n >= 2**32: - raise ValueError("Memoryview is too large") - self._pack_bin_header(n) - return self._buffer.write(obj) - if check(obj, float): - if self._use_float: - return self._buffer.write(struct.pack(">Bf", 0xCA, obj)) - return self._buffer.write(struct.pack(">Bd", 0xCB, obj)) - if check(obj, (ExtType, Timestamp)): - if check(obj, Timestamp): - code = -1 - data = obj.to_bytes() - else: - code = obj.code - data = obj.data - assert isinstance(code, int) - assert isinstance(data, bytes) - L = len(data) - if L == 1: - self._buffer.write(b"\xd4") - 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 range(n): - self._pack(obj[i], nest_limit - 1) - return - if check(obj, dict): - return self._pack_map_pairs(len(obj), obj.items(), nest_limit - 1) - - if self._datetime and check(obj, _DateTime) and obj.tzinfo is not None: - obj = Timestamp.from_datetime(obj) - default_used = 1 - continue - - if not default_used and self._default is not None: - obj = self._default(obj) - default_used = 1 - continue - - if self._datetime and check(obj, _DateTime): - raise ValueError(f"Cannot serialize {obj!r} where tzinfo=None") - - raise TypeError(f"Cannot serialize {obj!r}") - - def pack(self, obj): - try: - self._pack(obj) - except: - self._buffer = BytesIO() # force reset - raise - if self._autoreset: - ret = self._buffer.getvalue() - self._buffer = BytesIO() - return ret - - def pack_map_pairs(self, pairs): - self._pack_map_pairs(len(pairs), pairs) - if self._autoreset: - ret = self._buffer.getvalue() - self._buffer = BytesIO() - return ret - - def pack_array_header(self, n): - if n >= 2**32: - raise ValueError - self._pack_array_header(n) - if self._autoreset: - ret = self._buffer.getvalue() - self._buffer = BytesIO() - return ret - - def pack_map_header(self, n): - if n >= 2**32: - raise ValueError - self._pack_map_header(n) - if self._autoreset: - ret = self._buffer.getvalue() - self._buffer = BytesIO() - 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 ValueError("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 ValueError("Array is too large") - - def _pack_map_header(self, n): - if n <= 0x0F: - return self._buffer.write(struct.pack("B", 0x80 + n)) - if n <= 0xFFFF: - return self._buffer.write(struct.pack(">BH", 0xDE, n)) - if n <= 0xFFFFFFFF: - return self._buffer.write(struct.pack(">BI", 0xDF, n)) - raise ValueError("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 ValueError("Raw is too large") - - def _pack_bin_header(self, n): - if not self._use_bin_type: - return self._pack_raw_header(n) - elif n <= 0xFF: - return self._buffer.write(struct.pack(">BB", 0xC4, n)) - elif n <= 0xFFFF: - return self._buffer.write(struct.pack(">BH", 0xC5, n)) - elif n <= 0xFFFFFFFF: - return self._buffer.write(struct.pack(">BI", 0xC6, n)) - else: - raise ValueError("Bin is too large") - - def bytes(self): - """Return internal buffer contents as bytes object""" - return self._buffer.getvalue() - - def reset(self): - """Reset internal buffer. - - This method is useful only when autoreset=False. - """ - self._buffer = BytesIO() - - def getbuffer(self): - """Return view of internal buffer.""" - if _USING_STRINGBUILDER: - return memoryview(self.bytes()) - else: - return self._buffer.getbuffer() diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/LICENSE b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/LICENSE deleted file mode 100755 index 6f62d44..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/LICENSE +++ /dev/null @@ -1,3 +0,0 @@ -This software is made available under the terms of *either* of the licenses -found in LICENSE.APACHE or LICENSE.BSD. Contributions to this software is made -under the terms of *both* these licenses. diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/LICENSE.APACHE b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/LICENSE.APACHE deleted file mode 100755 index f433b1a..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/LICENSE.APACHE +++ /dev/null @@ -1,177 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/LICENSE.BSD b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/LICENSE.BSD deleted file mode 100755 index 42ce7b7..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/LICENSE.BSD +++ /dev/null @@ -1,23 +0,0 @@ -Copyright (c) Donald Stufft and individual contributors. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/__init__.py b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/__init__.py deleted file mode 100755 index a6bdf59..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# 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. - -__title__ = "packaging" -__summary__ = "Core utilities for Python packages" -__uri__ = "https://github.com/pypa/packaging" - -__version__ = "26.2" - -__author__ = "Donald Stufft and individual contributors" -__email__ = "donald@stufft.io" - -__license__ = "BSD-2-Clause or Apache-2.0" -__copyright__ = f"2014 {__author__}" diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-311.pyc deleted file mode 100755 index f6ca3a927f36463d45ad6716fd90845657acd5ed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 558 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 diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/_manylinux.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/_manylinux.cpython-311.pyc deleted file mode 100755 index 3c4cf6664edd214ca4a0e43856430061c0fcf2fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11142 zcmbtaYiu0Xb-uGR`{q8lKIkirV-KrwSuC^&s}0%FQz3Rpb%Q2e^!tU2>R2W zb7x;eO19h1&YroCbDwkWx!*Z={?g@g5V-#3#`|+;S_%1gj1(`M9$=pQjv?ed@&*xz zz{E(L2{8cia>5#JwSJygF1J_l10rZVA;0)=;fr3;Ab>VE+pyR41}?^~FvK-GciX zcN?M~6_ZG)LFf^xuW_L*@btm6QRo%?@Z4%5qG@hhkx{6-MsCB{K7zk~g_?wVal6nk z3{evqC&HF%L}(PNZnMAz{{mOD&?jtz`U3E5g69r+ZinYiph#l%`!T1m{)j6m>e66BJ1ceJ~A6kh_S*neV-*!C}fTjj*x>^ z2x{i}`N&|uW|sS2>b{~`t_%%^A!_A$DKd)znhkYXrKlXa1S!r~GMShuWOMVpGOMw& zB54*$R2HPfv)0l8-YWDXkP1vC6JmP>Jr^mxUg(4c{<{cap8OL8juHk0+fI}UjuZ&F zadHR95~Gw}J|QW_C^VY7c)#jZHab+YS7awgf=#m~=oT@n+Qx?<4_UGrC! z*<_-xv!|y^jw)iuJRiBp&xmr@e007m3~WMD>e3UViJ7i&oKIYhMH35GI_Ixyj_^D$ z$zoWHO-li2uNnUGKLYtr_@zmn1pCc)!y)g9j>C+eH(Tt}Lt7_go`wK_Lxewyznlj0`eanvW4|-v) zf$HRT7{fL12q8Coee7)~1pb!WZ~ZL`f!{Ivt^a_5`(*1#GkbqK15|T}SH#GI!e0O> z=Po3Zu}!iGa>hIvW>Dc8rP3&KD3d8hAPY<~kz(e6U%x8lX|5!*7pY=No(0a5yeU-i z>!s#Ol2_n744k-R>7{s!AwuTt#c+YM3ph(PDRsqMLKdMHha{UL8H2K0t9JMP)vi4@x-kc{k zvtzaAL6vLe)bg=BF}o(1oVWUh>DNHgWZhm<7A=cGv{=_ZqhvvXQLrGPELZ2&ylo&rC?`-)o*2kujDBuR z+rUDjR89;fH*gi?gd5qx-rvEEv|8`)Wq@jC1O@UlR}rAR1+d^;q=cVftoUZBGEGC^ zJ=oM!%q1duzD%i}1Wa4tDydG`?l)k>lSDB?m4!=SuK^%9Om0KGj6jXb8Za0)rCDIL zU)mqjID9V#LC416Juy%473-KJMb5cU!z+bm@NucI|6g|_s?ddo(cIyY$;snqMh}CM zI`rzvph+`zc557+AANJDYUi1Kcm~kkm3isl;-2sPEWiK&8&nbYV{H{Z z(rTaA4e49JHiE3jfuu>!>RB1cSR3G8_iVqpnDw-&p0mq->Wsj@bfKo8Qi3}mN(sCx)6}D0i2agC zhu}fW=u>DLj`8se0)J3C3>j1Km$6uyeDX?K=Ua3O(TMU^G@-NyfSl8+!;>Q?Pld-P zCtf)eJ~lCR{Dh%-Xc{l(Nej^Th)6=Pr-w{nYB3@!m?)IT5KBWGbk3}~ptk6RL#IVa z1|YAo(2iz~^K*dq%<*UFluW&pmEWk?+YgOU!cNh3rA;%LAR~Q80 z@P^?^&Bk3bQI8q8=RG%#@`OE=JvH-^oW5y|iaWhZuLSQ5M zE~{=p;qY?Grr8oK#I)%M`5}`ctCb5KYSFLT@F*|AZv)Q~vt&xN>>@8h)|D7YL9JT2 zra3^|93pizpo&O4g~k-Sc*GHa>oq9~VEJkw8V5ruE+%xdDv+EG%m7}F03@cbCk&GS zKqIgqBTdSkkz`^T(mH7+TFs%8;qj?A!c;r}Oq`rJJ~b7zYNn*DSqrRS?a1@7sG_+? zWLcEZdeZ^DdqjcCFDxiJsF$`v@1-UnK~{4c+t-+|W-TPiD0DCa9gQ@FpVwc|4YZq5 z2zXD!UycC*sP46zYah1m`7o5}9?iCnsjXwn?wqG718a}oIsdND{B3LgwyeKh^|$}n zvCJ&*U*7+8y{hrn)W_q$31yt$$`g~hwoD#)YL=B{C2xjQ+z%|IswO=pd!WG|cJ-29 zH;vS=_k9ddgBWp;PsL~m#014iV8A0mmPn!+UU-FoJnvQ7L71K|M1pC9*fF#|6xzb| zg8C}31PC4Wp#+Nwd0v?mDZ}oRDQqp)Zz3s^QIwZhrMj34`w^=kcq&{*SS}o~3 zMK16Nup7q3rdZsU7RRY1j`6YB1+eMUk*{5oMWbJsA+cD4oZ2XT>^@QDi{y3zEO>1(Hw4B+URX`Y+`F z0s?|>W6iZWn}6A*|DLWp>(D*~IWCf1L5{&Vq;ed<65DqE?CASP?{L{|9qP7@jBN|t zP}Wy2MnfCRTFg+kxm#@>&DgfV4Mn!(2~=1?EW}$&7mgLuap6>vmbMSSnc*5#E|9C= zm#N>Et?y9lJJLrVI{hmbf6rv}^mYolrbs4Ts zZiDgukh78>IsEJm#?St_zl;2};~VVnnQyT78S99h+_yVM>e>5s3{b<8LL<|w%BR8e38^9^0(dIPT1N*YM&$zQEO^7j1g$KZ2mox3 z%!)$SbW*w~3dJIFY4;E86+34-1C!ANFD3WLMTSy7tq1yC&e0`X4#c7t#lX(q&fe~h z-tL}$@VD&@b_Pz0Fh8>$eFH;7y0Tqt+564chAHSf_*QqvOXv0lzuifba16zy#g|8~ z%!?5Px=0sCsUMf4%50z)$3G9w(u4w|MEuxEXP`YWlT;1_9-*j$(->eJ>o)Io zSFY;JANOUd&cF@GBUj&$w{mvJV*=!JBzYuXIEc6D=808b*3+VTS~9klb!Wq^nwzix z?9BUTR?lRcI@G3)?3PY-OXqLcyCc6H|MmF2@ofKLwf}IodsGDgC zHO}s3$o?4qat{ztfWAFhUr_Z0(?@ewU&h+F?%B3snwnRgS!cWIY|n7*x?V&BMLG+_ zV1%QgOs8QOr0Gki!IT2i`y#MIH6}E}0MLQwFUBmf6infS7OoPQ0svFQ=1PS^OR)lH zRE5$Yz@my8iZ!7s6ii!6QHYrssA2Mz@26IksP%2u!lR%35; z&!*I}q0crWmsD$Li7h*zHnzE`J-e}{7qsUva&2l4H#T~GWqVFzO)qG#%E+~;J^PE= z!#NGQrp743Jf+o^&K4>>7!vkYLiu@wGN<`VOg$A`kErLYp_B(Iw!1PLQMP8t?ytxO z4;`))u&7HFNZ-K(>ntzxV2eptAtvoaGLGbXNS2Vi4J2rmN{d9Z%U5L`jYw(8!xJre zA*RUKd4#Bi)k?j2Wj~E{4YL0p{_^Xvq`{l#-I?{asNR`ZP3txFH!bfB-x$tRHB&5`v%25ySY=jwvc6W;*ScnH%~)GM-gCDt zbMTF9+iA7!G{o0E;EYsj`?H<_)iaQ>4HQfDW_`O=-|jW*?u>Q!$NO_OU#7P6F>7kK zd`^Hs;una1vGD$^XGrx7Wo$$Lzrs$>a=(n?ag%Ezw;cP}zhd^WRG_5qL#pN~y>r}` zrPQXhZfOzI93{S<#RlpOGPrBn5xATKBsw`dK62=6_}IwQ*~y8iH{OKMYtLN8Q&`=d ziE6uep?=$iUX!1LCe?j}l~A+N;GM&rn_e41r%W|#rQQJ@%No}uoOPB~;%4V39@Ed7 z@T^AiZm7qysh$d*T&c^9c>gD433UGq==n;mnKG62onT!AlUA?_Hlsd1OwRQ#ah0c2 zDXy%&m&~B^D@IbB6F8Ns=vRtMZGg>2ZO4%7eJKJhy}M*dvG813vZk!%zEvI!6!e}A z(n==yk}Y8pY)dx7*sSIJl=1RV; z8IrR9oJm>UVNQ^r6#U5w+C7D9)m;o#KA~24;~$me@d~r#knAbPPl@12S-@0b^^@uA z-?{$I^*^IdR44z>z+O0?2W(wD4-P1Brbdyc?s`VJj^I18AW48k1M@Ln0azU`SO5nA z4f62-^=2Oc9IStifIzye6=^OUN=M+EfTA}7Rp=?Gb~-A_N&rA^K%NB`2N(-_Yq2Dt zZ)z)G<2)4QV}^Rbb`Xl(&C7*Z4LIm+nz@6~%+HNFM;tzrtVs8(0teLCP0(q$=JO%;)~$}^fgdbhTU>eb=A}&S?yPk; zI!-$tZrQ#1-8(z7TiVqv?aS`<+8v+n8p!V2ukPBPsU1om%hl~#38$yNaFd3no9EP~ z?z=tNrvAJ9JzutdSgjw%O2!$TE<4xj_S|u*b^XiEoUQINThp4Y=~n#C(R*97+eg*y zqq>Eav5mo<^ZN6|Z62UxnagbfcaqBvQ6S3`IZwm&w^uvWor7zh!Hj1xx2;Xx*1ck1 zv4dB)sd>e|-rTZ!_QUYq=qJ8x^I^65aGqFQP#VaJb3M>;C;F@8z3*iMN7ca571w&r zj@6bsu58VqS_5-rt{%uW4rCfTRisDnE&=&O08+SXk7no%*kJd|pS2!bYdv^xDcgEX zZ9SH$Ken<6v+N(p?bw&u-VgU3L4Rf%`t|#1-h+K{;c(dE5UFtkPDcD(hB_XlIt-!C zh14C!R78G3OGPTms5F3tmZJG4J&dPYPy?F474_oM0K=Ga)38OyjDBQ0iv&|EYUAiS zsA%KISVIs`eWn*sAHuN?7+~NCjU;0+P?7lUm*xQXz9L>x!1b!xrxy|tSVl2fI)Qa3 zko*afc`RoEcPM@-L03DXQ^|tFig`BtqGuYu{?gB@anqxpAJGG9sU4#oNIH=m0HV1I z4TG+LuZJZ4#Jd}_@tj&$6iz{$<^c;Mc#=>dNO;nw4?KjS86;68Xya=3n6wa%z}Fih z)hASAP)$LX-Uc7wGuyC!8g@`Z7=k;Rd3%?bnc|%z)tTa*Bi>B$ z&JlZ>{we~FH2vj>Cry7jGMxFU`vDoseAWG+dTZL9^KDCeat+X3f1b1XOz;gxfu!B} zMq;W`nZ~@y%)mEHMe>*>rmdx9ZxsVh5F^=c#WW+SH8U?^9hIb!v<|NxRa;)ZcjVrY zY|FUXGEQd&DBf8zp0}774``Q7WaY?XOa&BQ%yM|KlSZ;T$kgY-c~ME;WK7I4)L0uS zRDhan6WvWrPL-+6n>eNe44DGKS@4&Vy$y^vPmJUMG5gZTR(7nM$f75`;bzwZuKM{2 muV=Y>m8-wG4ZfG@GvT{{*@JgcB#&vRb{_*8?gfPEm;V7y7$ffh diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/_musllinux.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/_musllinux.cpython-311.pyc deleted file mode 100755 index d0ecd6b6794553f77da82862e7a87e3cb8f7b234..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5321 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 M(HfEU@>}%(HwwS>(f|Me diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/_tokenizer.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/_tokenizer.cpython-311.pyc deleted file mode 100755 index cd8099343cbc7aff0be47def1a44b82aa5772b2b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8894 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 diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/dependency_groups.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/dependency_groups.cpython-311.pyc deleted file mode 100755 index 3c94acb8092b089973ac63f398842f33cde60f38..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12593 zcmd5?TWlLwdY<8RBuXMFQnF-A%1D-M)0V0D?kHI&jwL5fY$Yo@*{l+mra2><4n=Bb zMs`e4ShWZcZD8zrgDmW3>n^)!5(Oy=qd;j&ADgX$ahKZlxNO6<7IJAN|h_cR49Ox1M zR*wNz5<*G1p(H46m$qU)oeoZRTnSZLNZUTaia*D{)k9bsmikezOB#^|@!Ksq&T^3* zf1u(BZ}{TrbViG7$xK?EiZ~4KnfUyCGJVMq&dNVpkkbkI57ZZG`eT!dl2J}%QYks1 zWfW>WjXFt1o|DsB#A9@wxSmKQ6BF{hoR-k^`U^^CVczI&$T*cwq!uLE*wT3e-8^@&T;IT_Ix@ve7SzA!j z8!f4%s=cXd%K3!3H72Ch;RN{y0Yq+bT3y*$?lXQ0%k;)#@l+}n`;2=)r5hK=E@$TC zvAMXC$c(*|xs*9DhD{s0DyOfGrIHuN=C5m)GwB1-ef!4Lq$cm3k0;)aUy{|a`Q-dq z4ArEJGG=CCr^lM69G$;TV@gRS7E`uhL^@s73$Vo9^K~vwDP4#+tpa(#cfebm%+2r; z2OQ^Tob0@vN*fBY=UYXDbC+dN#iok2kwtT}#A~ub*|W*CEQ#8+WI`SluO+q1qLiGS zMOj)C)0y<%bVixOVPsJ$O{WuO{Z4)6GK5%+a$+%~H5Qx8NDC>7x5Z*VT8O8t5?Wg( zfwhG(C$<))n_@IY2Ko?D2LP6;e`SZmEtEMMFq={<+g{)_Dew=50pDxfjh1C@mY0Ng z+h$zL+&lb?8`RLMw4iGCP<3}2H%3gFIID`YSh*M%6To!YT(#j>h*DHdmQ0j0oIokIF2}XCvvFJ*-=bVT;SPp8iICAcI7hM{SW`$4i`*|h7YwXERl+DblIf~eWk9g%dQ)(rT*QN+`8`Txjnh+8!Y$+ zOFjLCt}*jlKDm5yy=SD*HHB~GkokLe()|5m(fnOLc~5BniT8$gP3Tz_ddd#IeNV|h zP1=8Jh651Vzg@tixJ)_+W{gTWh=$E5gUX=fJw>JeFFd0 zV4?hDxLP~vW@SdV$Hh5$?xL)SnOP8M69r$3t6~yTNlVTq!M2b>rDQ@I6)!GmB9%f8 z0wIyj(IYGX#M{hA1RiGUCPS zC`jT=OwMZVF%3VZL@~>VL)nENwltOIFN$@P`@|;Gs*vuBXrPiPT;j@Y+`t}2tOa2! zK6U_!Dl5O5VGhX%=B=#)Frin9z0UF6u_@n+9Cz*#Vz0l^>=w zkD96g_>BfV6k7DCh(=-tNUyMwK^`iJG*S{QRauP^eL&HQ<3E#5ffBA|#QBAbPl zQ<_RX=BkSGO6DpUqaM&TNRmcfrSA(D-mG=8m(j6$o(3UWHG;J=tNV>H%Yq

(2wGi`ptJ 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 o6Q=Gw3hqNpXEPfu!60&EMvO=0sqfjC;$Ke diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/errors.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/errors.cpython-311.pyc deleted file mode 100755 index 058803c381efc0f507d387da1d38740aed12f6b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4781 zcma)ATWl1`6|H{E(=#^MJPm6K8(2>;9s@#IvFvKm2GH&%P6&b(gV4B{F57MQbWf^# z@IxlDB0ii5CHp}F$|{jR5+XztCMT)}T5U-+@zjAN&V;*Lc zRQKGzU3I%2x6VCPHNVSd(*)Ar?*DRb5wySKOPFH5B5i&K$^)VkT{1~oDo7IQvMCp2 z@l*g5TrO`554x{#KL)hm-rL{Hr% zy25%MDTF+MpPve8rp#r+H({3syPiifSi#RvkKpknd?AIbE?*(J>`TnaNnVd;S+=XW zhHW{MUhjp)606|LC2m(MUYs+x%B`)GX*li;$K^LmQB9yo@Ppn+n>#>xK-{*nE99{> z3H2w6Ma?ve#m8h5OSeAG&)Q{{FKfJH=RdS(?9+LzQpw+D*6qA$+{#y$+*#W?J$~|J z-Z5NuqN0`NwHfB*D@G+>1T)>{c|X&zX7Y@4n>*u`C2UAHc(KT{&`b~foCJtf^1P>i zb&_L7PJW55dnt5@tDtv`1`8ocn{R=9Ko}`VIw{CkVRm62Wv1%NIVjOp&|*UC(UUNX zF__I1JmY#AJu50+{_A;KHY}s8nbas(Ojc%=?`3LF)3a>RW!%zCP)cW~I-Nd6r@39G z-xH3Y=!x-kng;2E|M{`uP|f5_)0e2urVWef^wv^Xo8daloF0p+b7wV|-e%l^8K>}N z)d6$Ea$NX+JhJi>n0YTzW{v|>vDGKQ5Ow;dmxfXJsBt(#*i$EMie3YUtfK?oRqQmcj0v#rE@buGM zWcMjR14^P$`&8CpD09)k;a&Mv96+H?Zb_rd@)+HcayivY6^kWPbDUxkJ8o%Z2DojF zRpNW0B?p^n4Ue-5p!+q$^9v5+7vBH@!`m}>->UC9Q5(1h_aD{IGQRftkw52s4Q1w< z81!T=?zg-Xz7?+K1E}FV^4%a{7KD!FxdcZydg)@ZZ0l7My6t6(#UE5P(;tM0Lc0Xn zeGvC8W`W`D!wQE`Ag_wH#ng##5dzzF7>L!jt0}9gOp~Co zNK=(lxhClpNh$TQ)Fl5+`cn?AMM?EFY4aDLbjQC;fUD6FBC)tG|6b|j*+K%CAsH~k zZaoc*kYedMWE+w6J$mM@+Qr714vW3|j%^lMeV;x6b@l4I07(16u@{i@-nUJYm0X)^ z{{ozdPz|!E&xsJmu1!0G!3mh;Du%gf%rolF8qV1ky_CXQ={vNmozYyx2P5>nu2YRV zz`!P>QS?U!Q8nYDFQeBqv&uxbM~8tKhI6@AlOyy>wNkOU>rjh1E>t-NT`!qc9aLJf z%eNq~LF*bx)YgLG&VpIsjqyMm&7F-bkUF_$IE=RU!(Fh4TSID90FJI4B><&*4_!BiIX}_pXr#k_69n$lIP)q(=~}PmtI}g6*R3x5Wso z?*nq27H+_AmQAZxfKLe9Ai5XOnHA0)*jKde53X*vM2`#j>rfSk4T-tbTH0ZY#*af^ zI4&I>K2HSTTi)B{k@2A5J^UgE;-7G>l4dXI8(2%@)ktQ3miEt- zy~S|D2gE{6+paicRCB0pnM)wT&q|twW-ScDrctA=QD*HxihHSOF8xIv0~?44_PUlX zwiaF-_WJOWQ~f~Cqd`_6+TRc{$BX#@M{fgf2m7By(DrsP1_d92x$_4Q5g7N=+P?g6 zKUhDvmTk(h)Uifp=h}tv`s#V#8^{7DTcVNKaqpuqGDFWYLl3La9IAl>c1)%bD8H<&B}s^`XnF7i;Qe|K3n9H&rDDt5>H;llYE$Y^W(GVh5Te6t5H# zKNMy6hc=lQAT|^&8_YQviw!r)*9b8^VjSUl01rsHUOWm+SK&VbJi#Dy@^?@mB;nM! ziiX@bNCc0M-a~ z=ieY8rX;CBhHIVo3$n8o-VM@U3-1O=uZpWdva8~H(Q}}dKDe4_#wBS0;<`g5iJGV@ z1D`BBQ-*5FP(yvQw(V}l`(k+Pc)fhM|CK2Dvc3EWk+XGaPg8zN0_SfRuQ2aR6fjxx K-tDGhV*Ueuc$P2# diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-311.pyc deleted file mode 100755 index 7875f50c31fe60af962c302d47eda130f956ea0e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19944 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�RZ8qb0olC^xG6IUkZ zN7<}d_}z}8fyoD{z7YZpXUT`qF$yTr2=evvr+~z#DS|9c*nJ!MW%99%jC52O=CI_K zsp+Nr2=W#Byh?z@vOJ8K1Z;VpqxkhwUPlCKFOe=rOnyMgOC@=jDUJLG#ZcBJle9Hb z2_9q6OZmvxyNCXHg`v*_opB>b4_KEgn1W~sjp3jx2kbhpTtmJ;13&|^nM+a{|5rw4YAU^=#Eux2|0G)0 zy))S))Ey0!uaiJG0XCpCmU_UtA7W6~H!1cSMO2)j|53p#?hFlB3q`dOpn+j`QJK!n zxLDTx6d86}aF$`zw?}D(2Z=fqO~){h#~X0rl%W1#XAxdU;{^PIbMfz->~U&#EU7a^d>D3FiH)4Lpy{!U+OgxNdQLY4fss`I~p5+U6%!;YqFe zDYb6*-8!{ypBCCbA1KsrP@4~EwZrofY%RQJwU*m}3ldMNjZdju9qwkdp&kpU+=kU^ zFOU6eEm$1=oI<}SMOFJKYgSq7+rj^QWBl0YhA7c8+#>)(#{UDQ{!Tam diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/metadata.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/metadata.cpython-311.pyc deleted file mode 100755 index 5768d8bc7ab244723cc368d4ddbe03d677250744..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35859 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 diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/pylock.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/pylock.cpython-311.pyc deleted file mode 100755 index 3ca4093f0535a7f75f225eb7c802bc2b84300646..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41845 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 MM*sdLT(-gg1z`5cg8%>k diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-311.pyc deleted file mode 100755 index ef84e25f205c5a516210ba94e18da6c5429b7e65..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 81011 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 SJcVgu+jYKjV~*=Qf&U+PQT&Mj diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/tags.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/tags.cpython-311.pyc deleted file mode 100755 index f18539a3ab016664e39aa9bd75d5e318507de924..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41179 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 diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-311.pyc deleted file mode 100755 index 3ea8a46b55ed18692d0720cae4ab1e89f4759ca7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12046 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 diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-311.pyc deleted file mode 100755 index 8fb582aec2e1206aa0a063897e05ea403b35d4b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43901 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 G>Hh`UBuFFx diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/_elffile.py b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/_elffile.py deleted file mode 100755 index 497b064..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/_elffile.py +++ /dev/null @@ -1,108 +0,0 @@ -""" -ELF file parser. - -This provides a class ``ELFFile`` that parses an ELF executable in a similar -interface to ``ZipFile``. Only the read interface is implemented. - -ELF header: https://refspecs.linuxfoundation.org/elf/gabi4+/ch4.eheader.html -""" - -from __future__ import annotations - -import enum -import os -import struct -from typing import IO - - -class ELFInvalid(ValueError): - pass - - -class EIClass(enum.IntEnum): - C32 = 1 - C64 = 2 - - -class EIData(enum.IntEnum): - Lsb = 1 - Msb = 2 - - -class EMachine(enum.IntEnum): - I386 = 3 - S390 = 22 - Arm = 40 - X8664 = 62 - AArc64 = 183 - - -class ELFFile: - """ - Representation of an ELF executable. - """ - - def __init__(self, f: IO[bytes]) -> None: - self._f = f - - try: - ident = self._read("16B") - except struct.error as e: - raise ELFInvalid("unable to parse identification") from e - magic = bytes(ident[:4]) - if magic != b"\x7fELF": - raise ELFInvalid(f"invalid magic: {magic!r}") - - self.capacity = ident[4] # Format for program header (bitness). - self.encoding = ident[5] # Data structure encoding (endianness). - - try: - # e_fmt: Format for program header. - # p_fmt: Format for section header. - # p_idx: Indexes to find p_type, p_offset, and p_filesz. - e_fmt, self._p_fmt, self._p_idx = { - (1, 1): ("HHIIIIIHHH", ">IIIIIIII", (0, 1, 4)), # 32-bit MSB. - (2, 1): ("HHIQQQIHHH", ">IIQQQQQQ", (0, 2, 5)), # 64-bit MSB. - }[(self.capacity, self.encoding)] - except KeyError as e: - raise ELFInvalid( - f"unrecognized capacity ({self.capacity}) or encoding ({self.encoding})" - ) from e - - try: - ( - _, - self.machine, # Architecture type. - _, - _, - self._e_phoff, # Offset of program header. - _, - self.flags, # Processor-specific flags. - _, - self._e_phentsize, # Size of section. - self._e_phnum, # Number of sections. - ) = self._read(e_fmt) - except struct.error as e: - raise ELFInvalid("unable to parse machine and section information") from e - - def _read(self, fmt: str) -> tuple[int, ...]: - return struct.unpack(fmt, self._f.read(struct.calcsize(fmt))) - - @property - def interpreter(self) -> str | None: - """ - The path recorded in the ``PT_INTERP`` section header. - """ - for index in range(self._e_phnum): - self._f.seek(self._e_phoff + self._e_phentsize * index) - try: - data = self._read(self._p_fmt) - except struct.error: - continue - if data[self._p_idx[0]] != 3: # Not PT_INTERP. - continue - self._f.seek(data[self._p_idx[1]]) - return os.fsdecode(self._f.read(data[self._p_idx[2]])).strip("\0") - return None diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/_manylinux.py b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/_manylinux.py deleted file mode 100755 index 0e79e8a..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/_manylinux.py +++ /dev/null @@ -1,262 +0,0 @@ -from __future__ import annotations - -import collections -import contextlib -import functools -import os -import re -import sys -import warnings -from typing import Generator, Iterator, NamedTuple, Sequence - -from ._elffile import EIClass, EIData, ELFFile, EMachine - -EF_ARM_ABIMASK = 0xFF000000 -EF_ARM_ABI_VER5 = 0x05000000 -EF_ARM_ABI_FLOAT_HARD = 0x00000400 - -_ALLOWED_ARCHS = { - "x86_64", - "aarch64", - "ppc64", - "ppc64le", - "s390x", - "loongarch64", - "riscv64", -} - - -# `os.PathLike` not a generic type until Python 3.9, so sticking with `str` -# as the type for `path` until then. -@contextlib.contextmanager -def _parse_elf(path: str) -> Generator[ELFFile | None, None, None]: - try: - with open(path, "rb") as f: - yield ELFFile(f) - except (OSError, TypeError, ValueError): - yield None - - -def _is_linux_armhf(executable: str) -> bool: - # hard-float ABI can be detected from the ELF header of the running - # process - # https://static.docs.arm.com/ihi0044/g/aaelf32.pdf - with _parse_elf(executable) as f: - return ( - f is not None - and f.capacity == EIClass.C32 - and f.encoding == EIData.Lsb - and f.machine == EMachine.Arm - and f.flags & EF_ARM_ABIMASK == EF_ARM_ABI_VER5 - and f.flags & EF_ARM_ABI_FLOAT_HARD == EF_ARM_ABI_FLOAT_HARD - ) - - -def _is_linux_i686(executable: str) -> bool: - with _parse_elf(executable) as f: - return ( - f is not None - and f.capacity == EIClass.C32 - and f.encoding == EIData.Lsb - and f.machine == EMachine.I386 - ) - - -def _have_compatible_abi(executable: str, archs: Sequence[str]) -> bool: - if "armv7l" in archs: - return _is_linux_armhf(executable) - if "i686" in archs: - return _is_linux_i686(executable) - return any(arch in _ALLOWED_ARCHS for arch in archs) - - -# If glibc ever changes its major version, we need to know what the last -# minor version was, so we can build the complete list of all versions. -# For now, guess what the highest minor version might be, assume it will -# be 50 for testing. Once this actually happens, update the dictionary -# with the actual value. -_LAST_GLIBC_MINOR: dict[int, int] = collections.defaultdict(lambda: 50) - - -class _GLibCVersion(NamedTuple): - major: int - minor: int - - -def _glibc_version_string_confstr() -> str | None: - """ - Primary implementation of glibc_version_string using os.confstr. - """ - # os.confstr is quite a bit faster than ctypes.DLL. It's also less likely - # to be broken or missing. This strategy is used in the standard library - # platform module. - # https://github.com/python/cpython/blob/fcf1d003bf4f0100c/Lib/platform.py#L175-L183 - try: - # Should be a string like "glibc 2.17". - version_string: str | None = os.confstr("CS_GNU_LIBC_VERSION") - assert version_string is not None - _, version = version_string.rsplit() - except (AssertionError, AttributeError, OSError, ValueError): - # os.confstr() or CS_GNU_LIBC_VERSION not available (or a bad value)... - return None - return version - - -def _glibc_version_string_ctypes() -> str | None: - """ - Fallback implementation of glibc_version_string using ctypes. - """ - try: - import ctypes # noqa: PLC0415 - except ImportError: - return None - - # ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen - # manpage says, "If filename is NULL, then the returned handle is for the - # main program". This way we can let the linker do the work to figure out - # which libc our process is actually using. - # - # We must also handle the special case where the executable is not a - # dynamically linked executable. This can occur when using musl libc, - # for example. In this situation, dlopen() will error, leading to an - # OSError. Interestingly, at least in the case of musl, there is no - # errno set on the OSError. The single string argument used to construct - # OSError comes from libc itself and is therefore not portable to - # hard code here. In any case, failure to call dlopen() means we - # can proceed, so we bail on our attempt. - try: - process_namespace = ctypes.CDLL(None) - except OSError: - return None - - try: - gnu_get_libc_version = process_namespace.gnu_get_libc_version - except AttributeError: - # Symbol doesn't exist -> therefore, we are not linked to - # glibc. - return None - - # Call gnu_get_libc_version, which returns a string like "2.5" - gnu_get_libc_version.restype = ctypes.c_char_p - version_str: str = gnu_get_libc_version() - # py2 / py3 compatibility: - if not isinstance(version_str, str): - version_str = version_str.decode("ascii") - - return version_str - - -def _glibc_version_string() -> str | None: - """Returns glibc version string, or None if not using glibc.""" - return _glibc_version_string_confstr() or _glibc_version_string_ctypes() - - -def _parse_glibc_version(version_str: str) -> _GLibCVersion: - """Parse glibc version. - - We use a regexp instead of str.split because we want to discard any - random junk that might come after the minor version -- this might happen - in patched/forked versions of glibc (e.g. Linaro's version of glibc - uses version strings like "2.20-2014.11"). See gh-3588. - """ - m = re.match(r"(?P[0-9]+)\.(?P[0-9]+)", version_str) - if not m: - warnings.warn( - f"Expected glibc version with 2 components major.minor, got: {version_str}", - RuntimeWarning, - stacklevel=2, - ) - return _GLibCVersion(-1, -1) - return _GLibCVersion(int(m.group("major")), int(m.group("minor"))) - - -@functools.lru_cache -def _get_glibc_version() -> _GLibCVersion: - version_str = _glibc_version_string() - if version_str is None: - return _GLibCVersion(-1, -1) - return _parse_glibc_version(version_str) - - -# From PEP 513, PEP 600 -def _is_compatible(arch: str, version: _GLibCVersion) -> bool: - sys_glibc = _get_glibc_version() - if sys_glibc < version: - return False - # Check for presence of _manylinux module. - try: - import _manylinux # noqa: PLC0415 - except ImportError: - return True - if hasattr(_manylinux, "manylinux_compatible"): - result = _manylinux.manylinux_compatible(version[0], version[1], arch) - if result is not None: - return bool(result) - return True - if version == _GLibCVersion(2, 5) and hasattr(_manylinux, "manylinux1_compatible"): - return bool(_manylinux.manylinux1_compatible) - if version == _GLibCVersion(2, 12) and hasattr( - _manylinux, "manylinux2010_compatible" - ): - return bool(_manylinux.manylinux2010_compatible) - if version == _GLibCVersion(2, 17) and hasattr( - _manylinux, "manylinux2014_compatible" - ): - return bool(_manylinux.manylinux2014_compatible) - return True - - -_LEGACY_MANYLINUX_MAP: dict[_GLibCVersion, str] = { - # CentOS 7 w/ glibc 2.17 (PEP 599) - _GLibCVersion(2, 17): "manylinux2014", - # CentOS 6 w/ glibc 2.12 (PEP 571) - _GLibCVersion(2, 12): "manylinux2010", - # CentOS 5 w/ glibc 2.5 (PEP 513) - _GLibCVersion(2, 5): "manylinux1", -} - - -def platform_tags(archs: Sequence[str]) -> Iterator[str]: - """Generate manylinux tags compatible to the current platform. - - :param archs: Sequence of compatible architectures. - The first one shall be the closest to the actual architecture and be the part of - platform tag after the ``linux_`` prefix, e.g. ``x86_64``. - The ``linux_`` prefix is assumed as a prerequisite for the current platform to - be manylinux-compatible. - - :returns: An iterator of compatible manylinux tags. - """ - if not _have_compatible_abi(sys.executable, archs): - return - # Oldest glibc to be supported regardless of architecture is (2, 17). - too_old_glibc2 = _GLibCVersion(2, 16) - if set(archs) & {"x86_64", "i686"}: - # On x86/i686 also oldest glibc to be supported is (2, 5). - too_old_glibc2 = _GLibCVersion(2, 4) - current_glibc = _GLibCVersion(*_get_glibc_version()) - glibc_max_list = [current_glibc] - # We can assume compatibility across glibc major versions. - # https://sourceware.org/bugzilla/show_bug.cgi?id=24636 - # - # Build a list of maximum glibc versions so that we can - # output the canonical list of all glibc from current_glibc - # down to too_old_glibc2, including all intermediary versions. - for glibc_major in range(current_glibc.major - 1, 1, -1): - glibc_minor = _LAST_GLIBC_MINOR[glibc_major] - glibc_max_list.append(_GLibCVersion(glibc_major, glibc_minor)) - for arch in archs: - for glibc_max in glibc_max_list: - if glibc_max.major == too_old_glibc2.major: - min_minor = too_old_glibc2.minor - else: - # For other glibc major versions oldest supported is (x, 0). - min_minor = -1 - for glibc_minor in range(glibc_max.minor, min_minor, -1): - glibc_version = _GLibCVersion(glibc_max.major, glibc_minor) - if _is_compatible(arch, glibc_version): - yield "manylinux_{}_{}_{}".format(*glibc_version, arch) - - # Handle the legacy manylinux1, manylinux2010, manylinux2014 tags. - if legacy_tag := _LEGACY_MANYLINUX_MAP.get(glibc_version): - yield f"{legacy_tag}_{arch}" diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/_musllinux.py b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/_musllinux.py deleted file mode 100755 index 4e8116a..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/_musllinux.py +++ /dev/null @@ -1,85 +0,0 @@ -"""PEP 656 support. - -This module implements logic to detect if the currently running Python is -linked against musl, and what musl version is used. -""" - -from __future__ import annotations - -import functools -import re -import subprocess -import sys -from typing import Iterator, NamedTuple, Sequence - -from ._elffile import ELFFile - - -class _MuslVersion(NamedTuple): - major: int - minor: int - - -def _parse_musl_version(output: str) -> _MuslVersion | None: - lines = [n for n in (n.strip() for n in output.splitlines()) if n] - if len(lines) < 2 or lines[0][:4] != "musl": - return None - m = re.match(r"Version (\d+)\.(\d+)", lines[1]) - if not m: - return None - return _MuslVersion(major=int(m.group(1)), minor=int(m.group(2))) - - -@functools.lru_cache -def _get_musl_version(executable: str) -> _MuslVersion | None: - """Detect currently-running musl runtime version. - - This is done by checking the specified executable's dynamic linking - information, and invoking the loader to parse its output for a version - string. If the loader is musl, the output would be something like:: - - musl libc (x86_64) - Version 1.2.2 - Dynamic Program Loader - """ - try: - with open(executable, "rb") as f: - ld = ELFFile(f).interpreter - except (OSError, TypeError, ValueError): - return None - if ld is None or "musl" not in ld: - return None - proc = subprocess.run([ld], check=False, stderr=subprocess.PIPE, text=True) - return _parse_musl_version(proc.stderr) - - -def platform_tags(archs: Sequence[str]) -> Iterator[str]: - """Generate musllinux tags compatible to the current platform. - - :param archs: Sequence of compatible architectures. - The first one shall be the closest to the actual architecture and be the part of - platform tag after the ``linux_`` prefix, e.g. ``x86_64``. - The ``linux_`` prefix is assumed as a prerequisite for the current platform to - be musllinux-compatible. - - :returns: An iterator of compatible musllinux tags. - """ - sys_musl = _get_musl_version(sys.executable) - if sys_musl is None: # Python not dynamically linked against musl. - return - for arch in archs: - for minor in range(sys_musl.minor, -1, -1): - yield f"musllinux_{sys_musl.major}_{minor}_{arch}" - - -if __name__ == "__main__": # pragma: no cover - import sysconfig - - plat = sysconfig.get_platform() - assert plat.startswith("linux-"), "not linux" - - print("plat:", plat) - print("musl:", _get_musl_version(sys.executable)) - print("tags:", end=" ") - for t in platform_tags(re.sub(r"[.-]", "_", plat.split("-", 1)[-1])): - print(t, end="\n ") diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/_parser.py b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/_parser.py deleted file mode 100755 index d320269..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/_parser.py +++ /dev/null @@ -1,393 +0,0 @@ -"""Handwritten parser of dependency specifiers. - -The docstring for each __parse_* function contains EBNF-inspired grammar representing -the implementation. -""" - -from __future__ import annotations - -import ast -from typing import List, Literal, NamedTuple, Sequence, Tuple, Union - -from ._tokenizer import DEFAULT_RULES, Tokenizer - - -class Node: - __slots__ = ("value",) - - def __init__(self, value: str) -> None: - self.value = value - - def __str__(self) -> str: - return self.value - - def __repr__(self) -> str: - return f"<{self.__class__.__name__}({self.value!r})>" - - def serialize(self) -> str: - raise NotImplementedError - - def __getstate__(self) -> str: - # Return just the value string for compactness and stability. - return self.value - - def _restore_value(self, value: object) -> None: - if not isinstance(value, str): - raise TypeError( - f"Cannot restore {self.__class__.__name__} value from {value!r}" - ) - self.value = value - - def __setstate__(self, state: object) -> None: - if isinstance(state, str): - # New format (26.2+): just the value string. - self._restore_value(state) - return - if isinstance(state, tuple) and len(state) == 2: - # Old format (packaging <= 26.0, __slots__): (None, {slot: value}). - _, slot_dict = state - if isinstance(slot_dict, dict) and "value" in slot_dict: - self._restore_value(slot_dict["value"]) - return - if isinstance(state, dict) and "value" in state: - # Old format (packaging <= 25.0, no __slots__): plain __dict__. - self._restore_value(state["value"]) - return - raise TypeError(f"Cannot restore {self.__class__.__name__} from {state!r}") - - -class Variable(Node): - __slots__ = () - - def serialize(self) -> str: - return str(self) - - -class Value(Node): - __slots__ = () - - def serialize(self) -> str: - return f'"{self}"' - - -class Op(Node): - __slots__ = () - - def serialize(self) -> str: - return str(self) - - -MarkerLogical = Literal["and", "or"] -MarkerVar = Union[Variable, Value] -MarkerItem = Tuple[MarkerVar, Op, MarkerVar] -MarkerAtom = Union[MarkerItem, Sequence["MarkerAtom"]] -MarkerList = List[Union["MarkerList", MarkerAtom, MarkerLogical]] - - -class ParsedRequirement(NamedTuple): - name: str - url: str - extras: list[str] - specifier: str - marker: MarkerList | None - - -# -------------------------------------------------------------------------------------- -# Recursive descent parser for dependency specifier -# -------------------------------------------------------------------------------------- -def parse_requirement(source: str) -> ParsedRequirement: - return _parse_requirement(Tokenizer(source, rules=DEFAULT_RULES)) - - -def _parse_requirement(tokenizer: Tokenizer) -> ParsedRequirement: - """ - requirement = WS? IDENTIFIER WS? extras WS? requirement_details - """ - tokenizer.consume("WS") - - name_token = tokenizer.expect( - "IDENTIFIER", expected="package name at the start of dependency specifier" - ) - name = name_token.text - tokenizer.consume("WS") - - extras = _parse_extras(tokenizer) - tokenizer.consume("WS") - - url, specifier, marker = _parse_requirement_details(tokenizer) - tokenizer.expect("END", expected="end of dependency specifier") - - return ParsedRequirement(name, url, extras, specifier, marker) - - -def _parse_requirement_details( - tokenizer: Tokenizer, -) -> tuple[str, str, MarkerList | None]: - """ - requirement_details = AT URL (WS requirement_marker?)? - | specifier WS? (requirement_marker)? - """ - - specifier = "" - url = "" - marker = None - - if tokenizer.check("AT"): - tokenizer.read() - tokenizer.consume("WS") - - url_start = tokenizer.position - url = tokenizer.expect("URL", expected="URL after @").text - if tokenizer.check("END", peek=True): - return (url, specifier, marker) - - tokenizer.expect("WS", expected="whitespace after URL") - - # The input might end after whitespace. - if tokenizer.check("END", peek=True): - return (url, specifier, marker) - - marker = _parse_requirement_marker( - tokenizer, - span_start=url_start, - expected="semicolon (after URL and whitespace)", - ) - else: - specifier_start = tokenizer.position - specifier = _parse_specifier(tokenizer) - tokenizer.consume("WS") - - if tokenizer.check("END", peek=True): - return (url, specifier, marker) - - marker = _parse_requirement_marker( - tokenizer, - span_start=specifier_start, - expected=( - "comma (within version specifier), semicolon (after version specifier)" - if specifier - else "semicolon (after name with no version specifier)" - ), - ) - - return (url, specifier, marker) - - -def _parse_requirement_marker( - tokenizer: Tokenizer, *, span_start: int, expected: str -) -> MarkerList: - """ - requirement_marker = SEMICOLON marker WS? - """ - - if not tokenizer.check("SEMICOLON"): - tokenizer.raise_syntax_error( - f"Expected {expected} or end", - span_start=span_start, - span_end=None, - ) - tokenizer.read() - - marker = _parse_marker(tokenizer) - tokenizer.consume("WS") - - return marker - - -def _parse_extras(tokenizer: Tokenizer) -> list[str]: - """ - extras = (LEFT_BRACKET wsp* extras_list? wsp* RIGHT_BRACKET)? - """ - if not tokenizer.check("LEFT_BRACKET", peek=True): - return [] - - with tokenizer.enclosing_tokens( - "LEFT_BRACKET", - "RIGHT_BRACKET", - around="extras", - ): - tokenizer.consume("WS") - extras = _parse_extras_list(tokenizer) - tokenizer.consume("WS") - - return extras - - -def _parse_extras_list(tokenizer: Tokenizer) -> list[str]: - """ - extras_list = identifier (wsp* ',' wsp* identifier)* - """ - extras: list[str] = [] - - if not tokenizer.check("IDENTIFIER"): - return extras - - extras.append(tokenizer.read().text) - - while True: - tokenizer.consume("WS") - if tokenizer.check("IDENTIFIER", peek=True): - tokenizer.raise_syntax_error("Expected comma between extra names") - elif not tokenizer.check("COMMA"): - break - - tokenizer.read() - tokenizer.consume("WS") - - extra_token = tokenizer.expect("IDENTIFIER", expected="extra name after comma") - extras.append(extra_token.text) - - return extras - - -def _parse_specifier(tokenizer: Tokenizer) -> str: - """ - specifier = LEFT_PARENTHESIS WS? version_many WS? RIGHT_PARENTHESIS - | WS? version_many WS? - """ - with tokenizer.enclosing_tokens( - "LEFT_PARENTHESIS", - "RIGHT_PARENTHESIS", - around="version specifier", - ): - tokenizer.consume("WS") - parsed_specifiers = _parse_version_many(tokenizer) - tokenizer.consume("WS") - - return parsed_specifiers - - -def _parse_version_many(tokenizer: Tokenizer) -> str: - """ - version_many = (SPECIFIER (WS? COMMA WS? SPECIFIER)*)? - """ - parsed_specifiers = "" - while tokenizer.check("SPECIFIER"): - span_start = tokenizer.position - parsed_specifiers += tokenizer.read().text - if tokenizer.check("VERSION_PREFIX_TRAIL", peek=True): - tokenizer.raise_syntax_error( - ".* suffix can only be used with `==` or `!=` operators", - span_start=span_start, - span_end=tokenizer.position + 1, - ) - if tokenizer.check("VERSION_LOCAL_LABEL_TRAIL", peek=True): - tokenizer.raise_syntax_error( - "Local version label can only be used with `==` or `!=` operators", - span_start=span_start, - span_end=tokenizer.position, - ) - tokenizer.consume("WS") - if not tokenizer.check("COMMA"): - break - parsed_specifiers += tokenizer.read().text - tokenizer.consume("WS") - - return parsed_specifiers - - -# -------------------------------------------------------------------------------------- -# Recursive descent parser for marker expression -# -------------------------------------------------------------------------------------- -def parse_marker(source: str) -> MarkerList: - return _parse_full_marker(Tokenizer(source, rules=DEFAULT_RULES)) - - -def _parse_full_marker(tokenizer: Tokenizer) -> MarkerList: - retval = _parse_marker(tokenizer) - tokenizer.expect("END", expected="end of marker expression") - return retval - - -def _parse_marker(tokenizer: Tokenizer) -> MarkerList: - """ - marker = marker_atom (BOOLOP marker_atom)+ - """ - expression = [_parse_marker_atom(tokenizer)] - while tokenizer.check("BOOLOP"): - token = tokenizer.read() - expr_right = _parse_marker_atom(tokenizer) - expression.extend((token.text, expr_right)) - return expression - - -def _parse_marker_atom(tokenizer: Tokenizer) -> MarkerAtom: - """ - marker_atom = WS? LEFT_PARENTHESIS WS? marker WS? RIGHT_PARENTHESIS WS? - | WS? marker_item WS? - """ - - tokenizer.consume("WS") - if tokenizer.check("LEFT_PARENTHESIS", peek=True): - with tokenizer.enclosing_tokens( - "LEFT_PARENTHESIS", - "RIGHT_PARENTHESIS", - around="marker expression", - ): - tokenizer.consume("WS") - marker: MarkerAtom = _parse_marker(tokenizer) - tokenizer.consume("WS") - else: - marker = _parse_marker_item(tokenizer) - tokenizer.consume("WS") - return marker - - -def _parse_marker_item(tokenizer: Tokenizer) -> MarkerItem: - """ - marker_item = WS? marker_var WS? marker_op WS? marker_var WS? - """ - tokenizer.consume("WS") - marker_var_left = _parse_marker_var(tokenizer) - tokenizer.consume("WS") - marker_op = _parse_marker_op(tokenizer) - tokenizer.consume("WS") - marker_var_right = _parse_marker_var(tokenizer) - tokenizer.consume("WS") - return (marker_var_left, marker_op, marker_var_right) - - -def _parse_marker_var(tokenizer: Tokenizer) -> MarkerVar: # noqa: RET503 - """ - marker_var = VARIABLE | QUOTED_STRING - """ - if tokenizer.check("VARIABLE"): - return process_env_var(tokenizer.read().text.replace(".", "_")) - elif tokenizer.check("QUOTED_STRING"): - return process_python_str(tokenizer.read().text) - else: - tokenizer.raise_syntax_error( - message="Expected a marker variable or quoted string" - ) - - -def process_env_var(env_var: str) -> Variable: - if env_var in ("platform_python_implementation", "python_implementation"): - return Variable("platform_python_implementation") - else: - return Variable(env_var) - - -def process_python_str(python_str: str) -> Value: - value = ast.literal_eval(python_str) - return Value(str(value)) - - -def _parse_marker_op(tokenizer: Tokenizer) -> Op: - """ - marker_op = IN | NOT IN | OP - """ - if tokenizer.check("IN"): - tokenizer.read() - return Op("in") - elif tokenizer.check("NOT"): - tokenizer.read() - tokenizer.expect("WS", expected="whitespace after 'not'") - tokenizer.expect("IN", expected="'in' after 'not'") - return Op("not in") - elif tokenizer.check("OP"): - return Op(tokenizer.read().text) - else: - return tokenizer.raise_syntax_error( - "Expected marker operator, one of <=, <, !=, ==, >=, >, ~=, ===, in, not in" - ) diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/_structures.py b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/_structures.py deleted file mode 100755 index 4306784..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/_structures.py +++ /dev/null @@ -1,33 +0,0 @@ -# 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. - -"""Backward-compatibility shim for unpickling Version objects serialized before -packaging 26.1. - -Old pickles reference ``packaging._structures.InfinityType`` and -``packaging._structures.NegativeInfinityType``. This module provides minimal -stand-in classes so that ``pickle.loads()`` can resolve those references. -The deserialized objects are not used for comparisons — ``Version.__setstate__`` -discards the stale ``_key`` cache and recomputes it from the core version fields. -""" - -from __future__ import annotations - - -class InfinityType: - """Stand-in for the removed ``InfinityType`` used in old comparison keys.""" - - def __repr__(self) -> str: - return "Infinity" - - -class NegativeInfinityType: - """Stand-in for the removed ``NegativeInfinityType`` used in old comparison keys.""" - - def __repr__(self) -> str: - return "-Infinity" - - -Infinity = InfinityType() -NegativeInfinity = NegativeInfinityType() diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/_tokenizer.py b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/_tokenizer.py deleted file mode 100755 index 5ab891c..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/_tokenizer.py +++ /dev/null @@ -1,193 +0,0 @@ -from __future__ import annotations - -import contextlib -import re -from dataclasses import dataclass -from typing import Generator, Mapping, NoReturn - -from .specifiers import Specifier - - -@dataclass -class Token: - name: str - text: str - position: int - - -class ParserSyntaxError(Exception): - """The provided source text could not be parsed correctly.""" - - def __init__( - self, - message: str, - *, - source: str, - span: tuple[int, int], - ) -> None: - self.span = span - self.message = message - self.source = source - - super().__init__() - - def __str__(self) -> str: - marker = " " * self.span[0] + "~" * (self.span[1] - self.span[0]) + "^" - return f"{self.message}\n {self.source}\n {marker}" - - -DEFAULT_RULES: dict[str, re.Pattern[str]] = { - "LEFT_PARENTHESIS": re.compile(r"\("), - "RIGHT_PARENTHESIS": re.compile(r"\)"), - "LEFT_BRACKET": re.compile(r"\["), - "RIGHT_BRACKET": re.compile(r"\]"), - "SEMICOLON": re.compile(r";"), - "COMMA": re.compile(r","), - "QUOTED_STRING": re.compile( - r""" - ( - ('[^']*') - | - ("[^"]*") - ) - """, - re.VERBOSE, - ), - "OP": re.compile(r"(===|==|~=|!=|<=|>=|<|>)"), - "BOOLOP": re.compile(r"\b(or|and)\b"), - "IN": re.compile(r"\bin\b"), - "NOT": re.compile(r"\bnot\b"), - "VARIABLE": re.compile( - r""" - \b( - python_version - |python_full_version - |os[._]name - |sys[._]platform - |platform_(release|system) - |platform[._](version|machine|python_implementation) - |python_implementation - |implementation_(name|version) - |extras? - |dependency_groups - )\b - """, - re.VERBOSE, - ), - "SPECIFIER": re.compile( - Specifier._specifier_regex_str, - re.VERBOSE | re.IGNORECASE, - ), - "AT": re.compile(r"\@"), - "URL": re.compile(r"[^ \t]+"), - "IDENTIFIER": re.compile(r"\b[a-zA-Z0-9][a-zA-Z0-9._-]*\b"), - "VERSION_PREFIX_TRAIL": re.compile(r"\.\*"), - "VERSION_LOCAL_LABEL_TRAIL": re.compile(r"\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*"), - "WS": re.compile(r"[ \t]+"), - "END": re.compile(r"$"), -} - - -class Tokenizer: - """Context-sensitive token parsing. - - Provides methods to examine the input stream to check whether the next token - matches. - """ - - def __init__( - self, - source: str, - *, - rules: Mapping[str, re.Pattern[str]], - ) -> None: - self.source = source - self.rules = rules - self.next_token: Token | None = None - self.position = 0 - - def consume(self, name: str) -> None: - """Move beyond provided token name, if at current position.""" - if self.check(name): - self.read() - - def check(self, name: str, *, peek: bool = False) -> bool: - """Check whether the next token has the provided name. - - By default, if the check succeeds, the token *must* be read before - another check. If `peek` is set to `True`, the token is not loaded and - would need to be checked again. - """ - assert self.next_token is None, ( - f"Cannot check for {name!r}, already have {self.next_token!r}" - ) - assert name in self.rules, f"Unknown token name: {name!r}" - - expression = self.rules[name] - - match = expression.match(self.source, self.position) - if match is None: - return False - if not peek: - self.next_token = Token(name, match[0], self.position) - return True - - def expect(self, name: str, *, expected: str) -> Token: - """Expect a certain token name next, failing with a syntax error otherwise. - - The token is *not* read. - """ - if not self.check(name): - raise self.raise_syntax_error(f"Expected {expected}") - return self.read() - - def read(self) -> Token: - """Consume the next token and return it.""" - token = self.next_token - assert token is not None - - self.position += len(token.text) - self.next_token = None - - return token - - def raise_syntax_error( - self, - message: str, - *, - span_start: int | None = None, - span_end: int | None = None, - ) -> NoReturn: - """Raise ParserSyntaxError at the given position.""" - span = ( - self.position if span_start is None else span_start, - self.position if span_end is None else span_end, - ) - raise ParserSyntaxError( - message, - source=self.source, - span=span, - ) - - @contextlib.contextmanager - def enclosing_tokens( - self, open_token: str, close_token: str, *, around: str - ) -> Generator[None, None, None]: - if self.check(open_token): - open_position = self.position - self.read() - else: - open_position = None - - yield - - if open_position is None: - return - - if not self.check(close_token): - self.raise_syntax_error( - f"Expected matching {close_token} for {open_token}, after {around}", - span_start=open_position, - ) - - self.read() diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/dependency_groups.py b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/dependency_groups.py deleted file mode 100755 index 413e5cb..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/dependency_groups.py +++ /dev/null @@ -1,302 +0,0 @@ -from __future__ import annotations - -import re -from collections.abc import Mapping, Sequence - -from .errors import _ErrorCollector -from .requirements import Requirement - -__all__ = [ - "CyclicDependencyGroup", - "DependencyGroupInclude", - "DependencyGroupResolver", - "DuplicateGroupNames", - "InvalidDependencyGroupObject", - "resolve_dependency_groups", -] - - -def __dir__() -> list[str]: - return __all__ - - -# ----------- -# Error Types -# ----------- - - -class DuplicateGroupNames(ValueError): - """ - The same dependency groups were defined twice, with different non-normalized names. - """ - - -class CyclicDependencyGroup(ValueError): - """ - The dependency group includes form a cycle. - """ - - def __init__(self, requested_group: str, group: str, include_group: str) -> None: - self.requested_group = requested_group - self.group = group - self.include_group = include_group - - if include_group == group: - reason = f"{group} includes itself" - else: - reason = f"{include_group} -> {group}, {group} -> {include_group}" - super().__init__( - "Cyclic dependency group include while resolving " - f"{requested_group}: {reason}" - ) - - -# in the PEP 735 spec, the tables in dependency group lists were described as -# "Dependency Object Specifiers", but the only defined type of object was a -# "Dependency Group Include" -- hence the naming of this error as "Object" -class InvalidDependencyGroupObject(ValueError): - """ - A member of a dependency group was identified as a dict, but was not in a valid - format. - """ - - -# ------------------------ -# Object Model & Interface -# ------------------------ - - -class DependencyGroupInclude: - __slots__ = ("include_group",) - - def __init__(self, include_group: str) -> None: - """ - Initialize a DependencyGroupInclude. - - :param include_group: The name of the group referred to by this include. - """ - self.include_group = include_group - - def __repr__(self) -> str: - return f"{self.__class__.__name__}({self.include_group!r})" - - -class DependencyGroupResolver: - """ - A resolver for Dependency Group data. - - This class handles caching, name normalization, cycle detection, and other - parsing requirements. There are only two public methods for exploring the data: - ``lookup()`` and ``resolve()``. - - :param dependency_groups: A mapping, as provided via pyproject - ``[dependency-groups]``. - """ - - def __init__( - self, - dependency_groups: Mapping[str, Sequence[str | Mapping[str, str]]], - ) -> None: - errors = _ErrorCollector() - - self.dependency_groups = _normalize_group_names(dependency_groups, errors) - - # a map of group names to parsed data - self._parsed_groups: dict[ - str, tuple[Requirement | DependencyGroupInclude, ...] - ] = {} - # a map of group names to their ancestors, used for cycle detection - self._include_graph_ancestors: dict[str, tuple[str, ...]] = {} - # a cache of completed resolutions to Requirement lists - self._resolve_cache: dict[str, tuple[Requirement, ...]] = {} - - errors.finalize("[dependency-groups] data was invalid") - - def lookup(self, group: str) -> tuple[Requirement | DependencyGroupInclude, ...]: - """ - Lookup a group name, returning the parsed dependency data for that group. - This will not resolve includes. - - :param group: the name of the group to lookup - """ - group = _normalize_name(group) - - with _ErrorCollector().on_exit( - f"[dependency-groups] data for {group!r} was malformed" - ) as errors: - return self._parse_group(group, errors) - - def resolve(self, group: str) -> tuple[Requirement, ...]: - """ - Resolve a dependency group to a list of requirements. - - :param group: the name of the group to resolve - """ - group = _normalize_name(group) - - with _ErrorCollector().on_exit( - f"[dependency-groups] data for {group!r} was malformed" - ) as errors: - return self._resolve(group, group, errors) - - def _resolve( - self, group: str, requested_group: str, errors: _ErrorCollector - ) -> tuple[Requirement, ...]: - """ - This is a helper for cached resolution to strings. It preserves the name of the - group which the user initially requested in order to present a clearer error in - the event that a cycle is detected. - - :param group: The normalized name of the group to resolve. - :param requested_group: The group which was used in the original, user-facing - request. - """ - if group in self._resolve_cache: - return self._resolve_cache[group] - - parsed = self._parse_group(group, errors) - - resolved_group = [] - - for item in parsed: - if isinstance(item, Requirement): - resolved_group.append(item) - elif isinstance(item, DependencyGroupInclude): - include_group = _normalize_name(item.include_group) - - # if a group is cyclic, record the error - # otherwise, follow the include_group reference - # - # this allows us to examine all includes in a group, even in the - # presence of errors - if include_group in self._include_graph_ancestors.get(group, ()): - errors.error( - CyclicDependencyGroup( - requested_group, group, item.include_group - ) - ) - else: - self._include_graph_ancestors[include_group] = ( - *self._include_graph_ancestors.get(group, ()), - group, - ) - resolved_group.extend( - self._resolve(include_group, requested_group, errors) - ) - else: # pragma: no cover - raise NotImplementedError( - f"Invalid dependency group item after parse: {item}" - ) - - # in the event that errors were detected, present the group as empty and do not - # cache the result - # this ensures that repeated access to a cyclic group will raise multiple errors - if errors.errors: - return () - - self._resolve_cache[group] = tuple(resolved_group) - return self._resolve_cache[group] - - def _parse_group( - self, group: str, errors: _ErrorCollector - ) -> tuple[Requirement | DependencyGroupInclude, ...]: - # short circuit -- never do the work twice - if group in self._parsed_groups: - return self._parsed_groups[group] - - if group not in self.dependency_groups: - errors.error(LookupError(f"Dependency group '{group}' not found")) - return () - - raw_group = self.dependency_groups[group] - if isinstance(raw_group, str): - errors.error( - TypeError( - f"Dependency group {group!r} contained a string rather than a list." - ) - ) - return () - - if not isinstance(raw_group, Sequence): - errors.error( - TypeError(f"Dependency group {group!r} is not a sequence type.") - ) - return () - - elements: list[Requirement | DependencyGroupInclude] = [] - for item in raw_group: - if isinstance(item, str): - # packaging.requirements.Requirement parsing ensures that this is a - # valid PEP 508 Dependency Specifier - # raises InvalidRequirement on failure - elements.append(Requirement(item)) - elif isinstance(item, Mapping): - if tuple(item.keys()) != ("include-group",): - errors.error( - InvalidDependencyGroupObject( - f"Invalid dependency group item: {item!r}" - ) - ) - else: - include_group = item["include-group"] - elements.append(DependencyGroupInclude(include_group=include_group)) - else: - errors.error(TypeError(f"Invalid dependency group item: {item!r}")) - - self._parsed_groups[group] = tuple(elements) - return self._parsed_groups[group] - - -# -------------------- -# Functional Interface -# -------------------- - - -def resolve_dependency_groups( - dependency_groups: Mapping[str, Sequence[str | Mapping[str, str]]], /, *groups: str -) -> tuple[str, ...]: - """ - Resolve a dependency group to a tuple of requirements, as strings. - - :param dependency_groups: the parsed contents of the ``[dependency-groups]`` table - from ``pyproject.toml`` - :param groups: the name of the group(s) to resolve - """ - resolver = DependencyGroupResolver(dependency_groups) - return tuple(str(r) for group in groups for r in resolver.resolve(group)) - - -# ---------------- -# internal helpers -# ---------------- - - -_NORMALIZE_PATTERN = re.compile(r"[-_.]+") - - -def _normalize_name(name: str) -> str: - return _NORMALIZE_PATTERN.sub("-", name).lower() - - -def _normalize_group_names( - dependency_groups: Mapping[str, Sequence[str | Mapping[str, str]]], - errors: _ErrorCollector, -) -> dict[str, Sequence[str | Mapping[str, str]]]: - original_names: dict[str, list[str]] = {} - normalized_groups: dict[str, Sequence[str | Mapping[str, str]]] = {} - - for group_name, value in dependency_groups.items(): - normed_group_name = _normalize_name(group_name) - original_names.setdefault(normed_group_name, []).append(group_name) - normalized_groups[normed_group_name] = value - - for normed_name, names in original_names.items(): - if len(names) > 1: - errors.error( - DuplicateGroupNames( - "Duplicate dependency group names: " - f"{normed_name} ({', '.join(names)})" - ) - ) - - return normalized_groups diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/direct_url.py b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/direct_url.py deleted file mode 100755 index 5d1c56c..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/direct_url.py +++ /dev/null @@ -1,325 +0,0 @@ -from __future__ import annotations - -import dataclasses -import re -import urllib.parse -from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, Protocol, TypeVar - -if TYPE_CHECKING: # pragma: no cover - import sys - from collections.abc import Collection - - if sys.version_info >= (3, 11): - from typing import Self - else: - from typing_extensions import Self - -__all__ = [ - "ArchiveInfo", - "DirInfo", - "DirectUrl", - "DirectUrlValidationError", - "VcsInfo", -] - - -def __dir__() -> list[str]: - return __all__ - - -_T = TypeVar("_T") - - -class _FromMappingProtocol(Protocol): # pragma: no cover - @classmethod - def _from_dict(cls, d: Mapping[str, Any]) -> Self: ... - - -_FromMappingProtocolT = TypeVar("_FromMappingProtocolT", bound=_FromMappingProtocol) - - -def _json_dict_factory(data: list[tuple[str, Any]]) -> dict[str, Any]: - return {key: value for key, value in data if value is not None} - - -def _get(d: Mapping[str, Any], expected_type: type[_T], key: str) -> _T | None: - """Get a value from the dictionary and verify it's the expected type.""" - if (value := d.get(key)) is None: - return None - if not isinstance(value, expected_type): - raise DirectUrlValidationError( - f"Unexpected type {type(value).__name__} " - f"(expected {expected_type.__name__})", - context=key, - ) - return value - - -def _get_required(d: Mapping[str, Any], expected_type: type[_T], key: str) -> _T: - """Get a required value from the dictionary and verify it's the expected type.""" - if (value := _get(d, expected_type, key)) is None: - raise _DirectUrlRequiredKeyError(key) - return value - - -def _get_object( - d: Mapping[str, Any], target_type: type[_FromMappingProtocolT], key: str -) -> _FromMappingProtocolT | None: - """Get a dictionary value from the dictionary and convert it to a dataclass.""" - if (value := _get(d, Mapping, key)) is None: # type: ignore[type-abstract] - return None - try: - return target_type._from_dict(value) - except Exception as e: - raise DirectUrlValidationError(e, context=key) from e - - -_PEP610_USER_PASS_ENV_VARS_REGEX = re.compile( - r"^\$\{[A-Za-z0-9-_]+\}(:\$\{[A-Za-z0-9-_]+\})?$" -) - - -def _strip_auth_from_netloc(netloc: str, safe_user_passwords: Collection[str]) -> str: - if "@" not in netloc: - return netloc - user_pass, netloc_no_user_pass = netloc.split("@", 1) - if user_pass in safe_user_passwords: - return netloc - if _PEP610_USER_PASS_ENV_VARS_REGEX.match(user_pass): - return netloc - return netloc_no_user_pass - - -def _strip_url(url: str, safe_user_passwords: Collection[str]) -> str: - """url with user:password part removed unless it is formed with - environment variables as specified in PEP 610, or it is a safe user:password - such as `git`. - """ - parsed_url = urllib.parse.urlsplit(url) - netloc = _strip_auth_from_netloc(parsed_url.netloc, safe_user_passwords) - return urllib.parse.urlunsplit( - ( - parsed_url.scheme, - netloc, - parsed_url.path, - parsed_url.query, - parsed_url.fragment, - ) - ) - - -class DirectUrlValidationError(Exception): - """Raised when when input data is not spec-compliant.""" - - context: str | None = None - message: str - - def __init__( - self, - cause: str | Exception, - *, - context: str | None = None, - ) -> None: - if isinstance(cause, DirectUrlValidationError): - if cause.context: - self.context = ( - f"{context}.{cause.context}" if context else cause.context - ) - else: - self.context = context # pragma: no cover - self.message = cause.message - else: - self.context = context - self.message = str(cause) - - def __str__(self) -> str: - if self.context: - return f"{self.message} in {self.context!r}" - return self.message - - -class _DirectUrlRequiredKeyError(DirectUrlValidationError): - def __init__(self, key: str) -> None: - super().__init__("Missing required value", context=key) - - -@dataclasses.dataclass(frozen=True, init=False) -class VcsInfo: - vcs: str - commit_id: str - requested_revision: str | None = None - - def __init__( - self, - *, - vcs: str, - commit_id: str, - requested_revision: str | None = None, - ) -> None: - object.__setattr__(self, "vcs", vcs) - object.__setattr__(self, "commit_id", commit_id) - object.__setattr__(self, "requested_revision", requested_revision) - - @classmethod - def _from_dict(cls, d: Mapping[str, Any]) -> Self: - # We can't validate vcs value because is not closed. - return cls( - vcs=_get_required(d, str, "vcs"), - requested_revision=_get(d, str, "requested_revision"), - commit_id=_get_required(d, str, "commit_id"), - ) - - -@dataclasses.dataclass(frozen=True, init=False) -class ArchiveInfo: - hashes: Mapping[str, str] | None = None - - def __init__( - self, - *, - hashes: Mapping[str, str] | None = None, - ) -> None: - object.__setattr__(self, "hashes", hashes) - - @classmethod - def _from_dict(cls, d: Mapping[str, Any]) -> Self: - hashes = _get(d, Mapping, "hashes") # type: ignore[type-abstract] - if hashes is not None and not all(isinstance(h, str) for h in hashes.values()): - raise DirectUrlValidationError( - "Hash values must be strings", context="hashes" - ) - legacy_hash = _get(d, str, "hash") - if legacy_hash is not None: - if "=" not in legacy_hash: - raise DirectUrlValidationError( - "Invalid hash format (expected '=')", - context="hash", - ) - hash_algorithm, hash_value = legacy_hash.split("=", 1) - if hashes is None: - # if `hashes` are not present, we can derive it from the legacy `hash` - hashes = {hash_algorithm: hash_value} - else: - # if `hashes` are present, the legacy `hash` must match one of them - if hash_algorithm not in hashes: - raise DirectUrlValidationError( - f"Algorithm {hash_algorithm!r} used in hash field " - f"is not present in hashes field", - context="hashes", - ) - if hashes[hash_algorithm] != hash_value: - raise DirectUrlValidationError( - f"Algorithm {hash_algorithm!r} used in hash field " - f"has different value in hashes field", - context="hash", - ) - return cls(hashes=hashes) - - -@dataclasses.dataclass(frozen=True, init=False) -class DirInfo: - editable: bool | None = None - - def __init__( - self, - *, - editable: bool | None = None, - ) -> None: - object.__setattr__(self, "editable", editable) - - @classmethod - def _from_dict(cls, d: Mapping[str, Any]) -> Self: - return cls( - editable=_get(d, bool, "editable"), - ) - - -@dataclasses.dataclass(frozen=True, init=False) -class DirectUrl: - """A class representing a direct URL.""" - - url: str - archive_info: ArchiveInfo | None = None - vcs_info: VcsInfo | None = None - dir_info: DirInfo | None = None - subdirectory: str | None = None # XXX Path or str? - - def __init__( - self, - *, - url: str, - archive_info: ArchiveInfo | None = None, - vcs_info: VcsInfo | None = None, - dir_info: DirInfo | None = None, - subdirectory: str | None = None, - ) -> None: - object.__setattr__(self, "url", url) - object.__setattr__(self, "archive_info", archive_info) - object.__setattr__(self, "vcs_info", vcs_info) - object.__setattr__(self, "dir_info", dir_info) - object.__setattr__(self, "subdirectory", subdirectory) - - @classmethod - def _from_dict(cls, d: Mapping[str, Any]) -> Self: - direct_url = cls( - url=_get_required(d, str, "url"), - archive_info=_get_object(d, ArchiveInfo, "archive_info"), - vcs_info=_get_object(d, VcsInfo, "vcs_info"), - dir_info=_get_object(d, DirInfo, "dir_info"), - subdirectory=_get(d, str, "subdirectory"), - ) - if ( - bool(direct_url.vcs_info) - + bool(direct_url.archive_info) - + bool(direct_url.dir_info) - ) != 1: - raise DirectUrlValidationError( - "Exactly one of vcs_info, archive_info, dir_info must be present" - ) - if direct_url.dir_info is not None and not direct_url.url.startswith("file://"): - raise DirectUrlValidationError( - "URL scheme must be file:// when dir_info is present", - context="url", - ) - # XXX subdirectory must be relative, can we, should we validate that here? - return direct_url - - @classmethod - def from_dict(cls, d: Mapping[str, Any], /) -> Self: - """Create and validate a DirectUrl instance from a JSON dictionary.""" - return cls._from_dict(d) - - def to_dict( - self, - *, - generate_legacy_hash: bool = False, - strip_user_password: bool = True, - safe_user_passwords: Collection[str] = ("git",), - ) -> Mapping[str, Any]: - """Convert the DirectUrl instance to a JSON dictionary. - - :param generate_legacy_hash: If True, include a legacy `hash` field in - `archive_info` for backward compatibility with tools that don't - support the `hashes` field. - :param strip_user_password: If True, strip user:password from the URL - unless it is formed with environment variables as specified in PEP - 610, or it is a safe user:password such as `git`. - :param safe_user_passwords: A collection of user:password strings that - should not be stripped from the URL even if `strip_user_password` is - True. - """ - res = dataclasses.asdict(self, dict_factory=_json_dict_factory) - if generate_legacy_hash and self.archive_info and self.archive_info.hashes: - hash_algorithm, hash_value = next(iter(self.archive_info.hashes.items())) - res["archive_info"]["hash"] = f"{hash_algorithm}={hash_value}" - if strip_user_password: - res["url"] = _strip_url(self.url, safe_user_passwords) - return res - - def validate(self) -> None: - """Validate the DirectUrl instance against the specification. - - Raises :class:`DirectUrlValidationError` if invalid. - """ - self.from_dict(self.to_dict()) diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/errors.py b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/errors.py deleted file mode 100755 index d1d47cf..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/errors.py +++ /dev/null @@ -1,94 +0,0 @@ -from __future__ import annotations - -import contextlib -import dataclasses -import sys -import typing - -__all__ = ["ExceptionGroup"] - - -def __dir__() -> list[str]: - return __all__ - - -if sys.version_info >= (3, 11): # pragma: no cover - from builtins import ExceptionGroup -else: # pragma: no cover - - class ExceptionGroup(Exception): - """A minimal implementation of :external:exc:`ExceptionGroup` from Python 3.11. - - If :external:exc:`ExceptionGroup` is already defined by Python itself, - that version is used instead. - """ - - message: str - exceptions: list[Exception] - - def __init__(self, message: str, exceptions: list[Exception]) -> None: - self.message = message - self.exceptions = exceptions - - def __repr__(self) -> str: - return f"{self.__class__.__name__}({self.message!r}, {self.exceptions!r})" - - -@dataclasses.dataclass -class _ErrorCollector: - """ - Collect errors into ExceptionGroups. - - Used like this: - - collector = _ErrorCollector() - # Add a single exception - collector.error(ValueError("one")) - - # Supports nesting, including combining ExceptionGroups - with collector.collect(): - raise ValueError("two") - collector.finalize("Found some errors") - - Since making a collector and then calling finalize later is a common pattern, - a convenience method ``on_exit`` is provided. - """ - - errors: list[Exception] = dataclasses.field(default_factory=list, init=False) - - def finalize(self, msg: str) -> None: - """Raise a group exception if there are any errors.""" - if self.errors: - raise ExceptionGroup(msg, self.errors) - - @contextlib.contextmanager - def on_exit(self, msg: str) -> typing.Generator[_ErrorCollector, None, None]: - """ - Calls finalize if no uncollected errors were present. - - Uncollected errors are raised normally. - """ - yield self - self.finalize(msg) - - @contextlib.contextmanager - def collect(self, *err_cls: type[Exception]) -> typing.Generator[None, None, None]: - """ - Context manager to collect errors into the error list. - - Must be inside loops, as only one error can be collected at a time. - """ - error_classes = err_cls or (Exception,) - try: - yield - except ExceptionGroup as error: - self.errors.extend(error.exceptions) - except error_classes as error: - self.errors.append(error) - - def error( - self, - error: Exception, - ) -> None: - """Add an error to the list.""" - self.errors.append(error) diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/licenses/__init__.py b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/licenses/__init__.py deleted file mode 100755 index 36e46ed..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/licenses/__init__.py +++ /dev/null @@ -1,186 +0,0 @@ -####################################################################################### -# -# Adapted from: -# https://github.com/pypa/hatch/blob/5352e44/backend/src/hatchling/licenses/parse.py -# -# MIT License -# -# Copyright (c) 2017-present Ofek Lev -# -# 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. -# -# -# With additional allowance of arbitrary `LicenseRef-` identifiers, not just -# `LicenseRef-Public-Domain` and `LicenseRef-Proprietary`. -# -####################################################################################### -from __future__ import annotations - -import re -from typing import NewType, cast - -from ._spdx import EXCEPTIONS, LICENSES - -__all__ = [ - "InvalidLicenseExpression", - "NormalizedLicenseExpression", - "canonicalize_license_expression", -] - - -# Simple __dir__ implementation since there are no public submodules -def __dir__() -> list[str]: - return __all__ - - -license_ref_allowed = re.compile("^[A-Za-z0-9.-]*$") - -NormalizedLicenseExpression = NewType("NormalizedLicenseExpression", str) -""" -A :class:`typing.NewType` of :class:`str`, representing a normalized -License-Expression. -""" - - -class InvalidLicenseExpression(ValueError): - """Raised when a license-expression string is invalid - - >>> from packaging.licenses import canonicalize_license_expression - >>> canonicalize_license_expression("invalid") - Traceback (most recent call last): - ... - packaging.licenses.InvalidLicenseExpression: Invalid license expression: 'invalid' - """ - - -def canonicalize_license_expression( - raw_license_expression: str, -) -> NormalizedLicenseExpression: - """ - This function takes a valid License-Expression, and returns the normalized - form of it. - - The return type is typed as :class:`NormalizedLicenseExpression`. This - allows type checkers to help require that a string has passed through this - function before use. - - :param str raw_license_expression: The License-Expression to canonicalize. - :raises InvalidLicenseExpression: If the License-Expression is invalid due to an - invalid/unknown license identifier or invalid syntax. - - .. doctest:: - - >>> from packaging.licenses import canonicalize_license_expression - >>> canonicalize_license_expression("mit") - 'MIT' - >>> canonicalize_license_expression("mit and (apache-2.0 or bsd-2-clause)") - 'MIT AND (Apache-2.0 OR BSD-2-Clause)' - >>> canonicalize_license_expression("(mit") - Traceback (most recent call last): - ... - InvalidLicenseExpression: Invalid license expression: '(mit' - >>> canonicalize_license_expression("Use-it-after-midnight") - Traceback (most recent call last): - ... - InvalidLicenseExpression: Unknown license: 'Use-it-after-midnight' - """ - if not raw_license_expression: - message = f"Invalid license expression: {raw_license_expression!r}" - raise InvalidLicenseExpression(message) - - # Pad any parentheses so tokenization can be achieved by merely splitting on - # whitespace. - license_expression = raw_license_expression.replace("(", " ( ").replace(")", " ) ") - licenseref_prefix = "LicenseRef-" - license_refs = { - ref.lower(): "LicenseRef-" + ref[len(licenseref_prefix) :] - for ref in license_expression.split() - if ref.lower().startswith(licenseref_prefix.lower()) - } - - # Normalize to lower case so we can look up licenses/exceptions - # and so boolean operators are Python-compatible. - license_expression = license_expression.lower() - - tokens = license_expression.split() - - # Rather than implementing a parenthesis/boolean logic parser, create an - # expression that Python can parse. Everything that is not involved with the - # grammar itself is replaced with the placeholder `False` and the resultant - # expression should become a valid Python expression. - python_tokens = [] - for token in tokens: - if token not in {"or", "and", "with", "(", ")"}: - python_tokens.append("False") - elif token == "with": - python_tokens.append("or") - elif ( - token == "(" - and python_tokens - and python_tokens[-1] not in {"or", "and", "("} - ) or (token == ")" and python_tokens and python_tokens[-1] == "("): - message = f"Invalid license expression: {raw_license_expression!r}" - raise InvalidLicenseExpression(message) - else: - python_tokens.append(token) - - python_expression = " ".join(python_tokens) - try: - compile(python_expression, "", "eval") - except SyntaxError: - message = f"Invalid license expression: {raw_license_expression!r}" - raise InvalidLicenseExpression(message) from None - - # Take a final pass to check for unknown licenses/exceptions. - normalized_tokens = [] - for token in tokens: - if token in {"or", "and", "with", "(", ")"}: - normalized_tokens.append(token.upper()) - continue - - if normalized_tokens and normalized_tokens[-1] == "WITH": - if token not in EXCEPTIONS: - message = f"Unknown license exception: {token!r}" - raise InvalidLicenseExpression(message) - - normalized_tokens.append(EXCEPTIONS[token]["id"]) - else: - if token.endswith("+"): - final_token = token[:-1] - suffix = "+" - else: - final_token = token - suffix = "" - - if final_token.startswith("licenseref-"): - if not license_ref_allowed.match(final_token): - message = f"Invalid licenseref: {final_token!r}" - raise InvalidLicenseExpression(message) - normalized_tokens.append(license_refs[final_token] + suffix) - else: - if final_token not in LICENSES: - message = f"Unknown license: {final_token!r}" - raise InvalidLicenseExpression(message) - normalized_tokens.append(LICENSES[final_token]["id"] + suffix) - - normalized_expression = " ".join(normalized_tokens) - - return cast( - "NormalizedLicenseExpression", - normalized_expression.replace("( ", "(").replace(" )", ")"), - ) diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/licenses/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/licenses/__pycache__/__init__.cpython-311.pyc deleted file mode 100755 index 4e45cc135318ac9c56103e0cd1ea24ef8ecfba1b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6397 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 diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/licenses/__pycache__/_spdx.cpython-311.pyc b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/licenses/__pycache__/_spdx.cpython-311.pyc deleted file mode 100755 index 43772928565863f515a97f76c091e45d398e2930..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52906 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 diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/licenses/_spdx.py b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/licenses/_spdx.py deleted file mode 100755 index a277af2..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/licenses/_spdx.py +++ /dev/null @@ -1,799 +0,0 @@ - -from __future__ import annotations - -from typing import TypedDict - -class SPDXLicense(TypedDict): - id: str - deprecated: bool - -class SPDXException(TypedDict): - id: str - deprecated: bool - - -VERSION = '3.27.0' - -LICENSES: dict[str, SPDXLicense] = { - '0bsd': {'id': '0BSD', 'deprecated': False}, - '3d-slicer-1.0': {'id': '3D-Slicer-1.0', 'deprecated': False}, - 'aal': {'id': 'AAL', 'deprecated': False}, - 'abstyles': {'id': 'Abstyles', 'deprecated': False}, - 'adacore-doc': {'id': 'AdaCore-doc', 'deprecated': False}, - 'adobe-2006': {'id': 'Adobe-2006', 'deprecated': False}, - 'adobe-display-postscript': {'id': 'Adobe-Display-PostScript', 'deprecated': False}, - 'adobe-glyph': {'id': 'Adobe-Glyph', 'deprecated': False}, - 'adobe-utopia': {'id': 'Adobe-Utopia', 'deprecated': False}, - 'adsl': {'id': 'ADSL', 'deprecated': False}, - 'afl-1.1': {'id': 'AFL-1.1', 'deprecated': False}, - 'afl-1.2': {'id': 'AFL-1.2', 'deprecated': False}, - 'afl-2.0': {'id': 'AFL-2.0', 'deprecated': False}, - 'afl-2.1': {'id': 'AFL-2.1', 'deprecated': False}, - 'afl-3.0': {'id': 'AFL-3.0', 'deprecated': False}, - 'afmparse': {'id': 'Afmparse', 'deprecated': False}, - 'agpl-1.0': {'id': 'AGPL-1.0', 'deprecated': True}, - 'agpl-1.0-only': {'id': 'AGPL-1.0-only', 'deprecated': False}, - 'agpl-1.0-or-later': {'id': 'AGPL-1.0-or-later', 'deprecated': False}, - 'agpl-3.0': {'id': 'AGPL-3.0', 'deprecated': True}, - 'agpl-3.0-only': {'id': 'AGPL-3.0-only', 'deprecated': False}, - 'agpl-3.0-or-later': {'id': 'AGPL-3.0-or-later', 'deprecated': False}, - 'aladdin': {'id': 'Aladdin', 'deprecated': False}, - 'amd-newlib': {'id': 'AMD-newlib', 'deprecated': False}, - 'amdplpa': {'id': 'AMDPLPA', 'deprecated': False}, - 'aml': {'id': 'AML', 'deprecated': False}, - 'aml-glslang': {'id': 'AML-glslang', 'deprecated': False}, - 'ampas': {'id': 'AMPAS', 'deprecated': False}, - 'antlr-pd': {'id': 'ANTLR-PD', 'deprecated': False}, - 'antlr-pd-fallback': {'id': 'ANTLR-PD-fallback', 'deprecated': False}, - 'any-osi': {'id': 'any-OSI', 'deprecated': False}, - 'any-osi-perl-modules': {'id': 'any-OSI-perl-modules', 'deprecated': False}, - 'apache-1.0': {'id': 'Apache-1.0', 'deprecated': False}, - 'apache-1.1': {'id': 'Apache-1.1', 'deprecated': False}, - 'apache-2.0': {'id': 'Apache-2.0', 'deprecated': False}, - 'apafml': {'id': 'APAFML', 'deprecated': False}, - 'apl-1.0': {'id': 'APL-1.0', 'deprecated': False}, - 'app-s2p': {'id': 'App-s2p', 'deprecated': False}, - 'apsl-1.0': {'id': 'APSL-1.0', 'deprecated': False}, - 'apsl-1.1': {'id': 'APSL-1.1', 'deprecated': False}, - 'apsl-1.2': {'id': 'APSL-1.2', 'deprecated': False}, - 'apsl-2.0': {'id': 'APSL-2.0', 'deprecated': False}, - 'arphic-1999': {'id': 'Arphic-1999', 'deprecated': False}, - 'artistic-1.0': {'id': 'Artistic-1.0', 'deprecated': False}, - 'artistic-1.0-cl8': {'id': 'Artistic-1.0-cl8', 'deprecated': False}, - 'artistic-1.0-perl': {'id': 'Artistic-1.0-Perl', 'deprecated': False}, - 'artistic-2.0': {'id': 'Artistic-2.0', 'deprecated': False}, - 'artistic-dist': {'id': 'Artistic-dist', 'deprecated': False}, - 'aspell-ru': {'id': 'Aspell-RU', 'deprecated': False}, - 'aswf-digital-assets-1.0': {'id': 'ASWF-Digital-Assets-1.0', 'deprecated': False}, - 'aswf-digital-assets-1.1': {'id': 'ASWF-Digital-Assets-1.1', 'deprecated': False}, - 'baekmuk': {'id': 'Baekmuk', 'deprecated': False}, - 'bahyph': {'id': 'Bahyph', 'deprecated': False}, - 'barr': {'id': 'Barr', 'deprecated': False}, - 'bcrypt-solar-designer': {'id': 'bcrypt-Solar-Designer', 'deprecated': False}, - 'beerware': {'id': 'Beerware', 'deprecated': False}, - 'bitstream-charter': {'id': 'Bitstream-Charter', 'deprecated': False}, - 'bitstream-vera': {'id': 'Bitstream-Vera', 'deprecated': False}, - 'bittorrent-1.0': {'id': 'BitTorrent-1.0', 'deprecated': False}, - 'bittorrent-1.1': {'id': 'BitTorrent-1.1', 'deprecated': False}, - 'blessing': {'id': 'blessing', 'deprecated': False}, - 'blueoak-1.0.0': {'id': 'BlueOak-1.0.0', 'deprecated': False}, - 'boehm-gc': {'id': 'Boehm-GC', 'deprecated': False}, - 'boehm-gc-without-fee': {'id': 'Boehm-GC-without-fee', 'deprecated': False}, - 'borceux': {'id': 'Borceux', 'deprecated': False}, - 'brian-gladman-2-clause': {'id': 'Brian-Gladman-2-Clause', 'deprecated': False}, - 'brian-gladman-3-clause': {'id': 'Brian-Gladman-3-Clause', 'deprecated': False}, - 'bsd-1-clause': {'id': 'BSD-1-Clause', 'deprecated': False}, - 'bsd-2-clause': {'id': 'BSD-2-Clause', 'deprecated': False}, - 'bsd-2-clause-darwin': {'id': 'BSD-2-Clause-Darwin', 'deprecated': False}, - 'bsd-2-clause-first-lines': {'id': 'BSD-2-Clause-first-lines', 'deprecated': False}, - 'bsd-2-clause-freebsd': {'id': 'BSD-2-Clause-FreeBSD', 'deprecated': True}, - 'bsd-2-clause-netbsd': {'id': 'BSD-2-Clause-NetBSD', 'deprecated': True}, - 'bsd-2-clause-patent': {'id': 'BSD-2-Clause-Patent', 'deprecated': False}, - 'bsd-2-clause-pkgconf-disclaimer': {'id': 'BSD-2-Clause-pkgconf-disclaimer', 'deprecated': False}, - 'bsd-2-clause-views': {'id': 'BSD-2-Clause-Views', 'deprecated': False}, - 'bsd-3-clause': {'id': 'BSD-3-Clause', 'deprecated': False}, - 'bsd-3-clause-acpica': {'id': 'BSD-3-Clause-acpica', 'deprecated': False}, - 'bsd-3-clause-attribution': {'id': 'BSD-3-Clause-Attribution', 'deprecated': False}, - 'bsd-3-clause-clear': {'id': 'BSD-3-Clause-Clear', 'deprecated': False}, - 'bsd-3-clause-flex': {'id': 'BSD-3-Clause-flex', 'deprecated': False}, - 'bsd-3-clause-hp': {'id': 'BSD-3-Clause-HP', 'deprecated': False}, - 'bsd-3-clause-lbnl': {'id': 'BSD-3-Clause-LBNL', 'deprecated': False}, - 'bsd-3-clause-modification': {'id': 'BSD-3-Clause-Modification', 'deprecated': False}, - 'bsd-3-clause-no-military-license': {'id': 'BSD-3-Clause-No-Military-License', 'deprecated': False}, - 'bsd-3-clause-no-nuclear-license': {'id': 'BSD-3-Clause-No-Nuclear-License', 'deprecated': False}, - 'bsd-3-clause-no-nuclear-license-2014': {'id': 'BSD-3-Clause-No-Nuclear-License-2014', 'deprecated': False}, - 'bsd-3-clause-no-nuclear-warranty': {'id': 'BSD-3-Clause-No-Nuclear-Warranty', 'deprecated': False}, - 'bsd-3-clause-open-mpi': {'id': 'BSD-3-Clause-Open-MPI', 'deprecated': False}, - 'bsd-3-clause-sun': {'id': 'BSD-3-Clause-Sun', 'deprecated': False}, - 'bsd-4-clause': {'id': 'BSD-4-Clause', 'deprecated': False}, - 'bsd-4-clause-shortened': {'id': 'BSD-4-Clause-Shortened', 'deprecated': False}, - 'bsd-4-clause-uc': {'id': 'BSD-4-Clause-UC', 'deprecated': False}, - 'bsd-4.3reno': {'id': 'BSD-4.3RENO', 'deprecated': False}, - 'bsd-4.3tahoe': {'id': 'BSD-4.3TAHOE', 'deprecated': False}, - 'bsd-advertising-acknowledgement': {'id': 'BSD-Advertising-Acknowledgement', 'deprecated': False}, - 'bsd-attribution-hpnd-disclaimer': {'id': 'BSD-Attribution-HPND-disclaimer', 'deprecated': False}, - 'bsd-inferno-nettverk': {'id': 'BSD-Inferno-Nettverk', 'deprecated': False}, - 'bsd-protection': {'id': 'BSD-Protection', 'deprecated': False}, - 'bsd-source-beginning-file': {'id': 'BSD-Source-beginning-file', 'deprecated': False}, - 'bsd-source-code': {'id': 'BSD-Source-Code', 'deprecated': False}, - 'bsd-systemics': {'id': 'BSD-Systemics', 'deprecated': False}, - 'bsd-systemics-w3works': {'id': 'BSD-Systemics-W3Works', 'deprecated': False}, - 'bsl-1.0': {'id': 'BSL-1.0', 'deprecated': False}, - 'busl-1.1': {'id': 'BUSL-1.1', 'deprecated': False}, - 'bzip2-1.0.5': {'id': 'bzip2-1.0.5', 'deprecated': True}, - 'bzip2-1.0.6': {'id': 'bzip2-1.0.6', 'deprecated': False}, - 'c-uda-1.0': {'id': 'C-UDA-1.0', 'deprecated': False}, - 'cal-1.0': {'id': 'CAL-1.0', 'deprecated': False}, - 'cal-1.0-combined-work-exception': {'id': 'CAL-1.0-Combined-Work-Exception', 'deprecated': False}, - 'caldera': {'id': 'Caldera', 'deprecated': False}, - 'caldera-no-preamble': {'id': 'Caldera-no-preamble', 'deprecated': False}, - 'catharon': {'id': 'Catharon', 'deprecated': False}, - 'catosl-1.1': {'id': 'CATOSL-1.1', 'deprecated': False}, - 'cc-by-1.0': {'id': 'CC-BY-1.0', 'deprecated': False}, - 'cc-by-2.0': {'id': 'CC-BY-2.0', 'deprecated': False}, - 'cc-by-2.5': {'id': 'CC-BY-2.5', 'deprecated': False}, - 'cc-by-2.5-au': {'id': 'CC-BY-2.5-AU', 'deprecated': False}, - 'cc-by-3.0': {'id': 'CC-BY-3.0', 'deprecated': False}, - 'cc-by-3.0-at': {'id': 'CC-BY-3.0-AT', 'deprecated': False}, - 'cc-by-3.0-au': {'id': 'CC-BY-3.0-AU', 'deprecated': False}, - 'cc-by-3.0-de': {'id': 'CC-BY-3.0-DE', 'deprecated': False}, - 'cc-by-3.0-igo': {'id': 'CC-BY-3.0-IGO', 'deprecated': False}, - 'cc-by-3.0-nl': {'id': 'CC-BY-3.0-NL', 'deprecated': False}, - 'cc-by-3.0-us': {'id': 'CC-BY-3.0-US', 'deprecated': False}, - 'cc-by-4.0': {'id': 'CC-BY-4.0', 'deprecated': False}, - 'cc-by-nc-1.0': {'id': 'CC-BY-NC-1.0', 'deprecated': False}, - 'cc-by-nc-2.0': {'id': 'CC-BY-NC-2.0', 'deprecated': False}, - 'cc-by-nc-2.5': {'id': 'CC-BY-NC-2.5', 'deprecated': False}, - 'cc-by-nc-3.0': {'id': 'CC-BY-NC-3.0', 'deprecated': False}, - 'cc-by-nc-3.0-de': {'id': 'CC-BY-NC-3.0-DE', 'deprecated': False}, - 'cc-by-nc-4.0': {'id': 'CC-BY-NC-4.0', 'deprecated': False}, - 'cc-by-nc-nd-1.0': {'id': 'CC-BY-NC-ND-1.0', 'deprecated': False}, - 'cc-by-nc-nd-2.0': {'id': 'CC-BY-NC-ND-2.0', 'deprecated': False}, - 'cc-by-nc-nd-2.5': {'id': 'CC-BY-NC-ND-2.5', 'deprecated': False}, - 'cc-by-nc-nd-3.0': {'id': 'CC-BY-NC-ND-3.0', 'deprecated': False}, - 'cc-by-nc-nd-3.0-de': {'id': 'CC-BY-NC-ND-3.0-DE', 'deprecated': False}, - 'cc-by-nc-nd-3.0-igo': {'id': 'CC-BY-NC-ND-3.0-IGO', 'deprecated': False}, - 'cc-by-nc-nd-4.0': {'id': 'CC-BY-NC-ND-4.0', 'deprecated': False}, - 'cc-by-nc-sa-1.0': {'id': 'CC-BY-NC-SA-1.0', 'deprecated': False}, - 'cc-by-nc-sa-2.0': {'id': 'CC-BY-NC-SA-2.0', 'deprecated': False}, - 'cc-by-nc-sa-2.0-de': {'id': 'CC-BY-NC-SA-2.0-DE', 'deprecated': False}, - 'cc-by-nc-sa-2.0-fr': {'id': 'CC-BY-NC-SA-2.0-FR', 'deprecated': False}, - 'cc-by-nc-sa-2.0-uk': {'id': 'CC-BY-NC-SA-2.0-UK', 'deprecated': False}, - 'cc-by-nc-sa-2.5': {'id': 'CC-BY-NC-SA-2.5', 'deprecated': False}, - 'cc-by-nc-sa-3.0': {'id': 'CC-BY-NC-SA-3.0', 'deprecated': False}, - 'cc-by-nc-sa-3.0-de': {'id': 'CC-BY-NC-SA-3.0-DE', 'deprecated': False}, - 'cc-by-nc-sa-3.0-igo': {'id': 'CC-BY-NC-SA-3.0-IGO', 'deprecated': False}, - 'cc-by-nc-sa-4.0': {'id': 'CC-BY-NC-SA-4.0', 'deprecated': False}, - 'cc-by-nd-1.0': {'id': 'CC-BY-ND-1.0', 'deprecated': False}, - 'cc-by-nd-2.0': {'id': 'CC-BY-ND-2.0', 'deprecated': False}, - 'cc-by-nd-2.5': {'id': 'CC-BY-ND-2.5', 'deprecated': False}, - 'cc-by-nd-3.0': {'id': 'CC-BY-ND-3.0', 'deprecated': False}, - 'cc-by-nd-3.0-de': {'id': 'CC-BY-ND-3.0-DE', 'deprecated': False}, - 'cc-by-nd-4.0': {'id': 'CC-BY-ND-4.0', 'deprecated': False}, - 'cc-by-sa-1.0': {'id': 'CC-BY-SA-1.0', 'deprecated': False}, - 'cc-by-sa-2.0': {'id': 'CC-BY-SA-2.0', 'deprecated': False}, - 'cc-by-sa-2.0-uk': {'id': 'CC-BY-SA-2.0-UK', 'deprecated': False}, - 'cc-by-sa-2.1-jp': {'id': 'CC-BY-SA-2.1-JP', 'deprecated': False}, - 'cc-by-sa-2.5': {'id': 'CC-BY-SA-2.5', 'deprecated': False}, - 'cc-by-sa-3.0': {'id': 'CC-BY-SA-3.0', 'deprecated': False}, - 'cc-by-sa-3.0-at': {'id': 'CC-BY-SA-3.0-AT', 'deprecated': False}, - 'cc-by-sa-3.0-de': {'id': 'CC-BY-SA-3.0-DE', 'deprecated': False}, - 'cc-by-sa-3.0-igo': {'id': 'CC-BY-SA-3.0-IGO', 'deprecated': False}, - 'cc-by-sa-4.0': {'id': 'CC-BY-SA-4.0', 'deprecated': False}, - 'cc-pddc': {'id': 'CC-PDDC', 'deprecated': False}, - 'cc-pdm-1.0': {'id': 'CC-PDM-1.0', 'deprecated': False}, - 'cc-sa-1.0': {'id': 'CC-SA-1.0', 'deprecated': False}, - 'cc0-1.0': {'id': 'CC0-1.0', 'deprecated': False}, - 'cddl-1.0': {'id': 'CDDL-1.0', 'deprecated': False}, - 'cddl-1.1': {'id': 'CDDL-1.1', 'deprecated': False}, - 'cdl-1.0': {'id': 'CDL-1.0', 'deprecated': False}, - 'cdla-permissive-1.0': {'id': 'CDLA-Permissive-1.0', 'deprecated': False}, - 'cdla-permissive-2.0': {'id': 'CDLA-Permissive-2.0', 'deprecated': False}, - 'cdla-sharing-1.0': {'id': 'CDLA-Sharing-1.0', 'deprecated': False}, - 'cecill-1.0': {'id': 'CECILL-1.0', 'deprecated': False}, - 'cecill-1.1': {'id': 'CECILL-1.1', 'deprecated': False}, - 'cecill-2.0': {'id': 'CECILL-2.0', 'deprecated': False}, - 'cecill-2.1': {'id': 'CECILL-2.1', 'deprecated': False}, - 'cecill-b': {'id': 'CECILL-B', 'deprecated': False}, - 'cecill-c': {'id': 'CECILL-C', 'deprecated': False}, - 'cern-ohl-1.1': {'id': 'CERN-OHL-1.1', 'deprecated': False}, - 'cern-ohl-1.2': {'id': 'CERN-OHL-1.2', 'deprecated': False}, - 'cern-ohl-p-2.0': {'id': 'CERN-OHL-P-2.0', 'deprecated': False}, - 'cern-ohl-s-2.0': {'id': 'CERN-OHL-S-2.0', 'deprecated': False}, - 'cern-ohl-w-2.0': {'id': 'CERN-OHL-W-2.0', 'deprecated': False}, - 'cfitsio': {'id': 'CFITSIO', 'deprecated': False}, - 'check-cvs': {'id': 'check-cvs', 'deprecated': False}, - 'checkmk': {'id': 'checkmk', 'deprecated': False}, - 'clartistic': {'id': 'ClArtistic', 'deprecated': False}, - 'clips': {'id': 'Clips', 'deprecated': False}, - 'cmu-mach': {'id': 'CMU-Mach', 'deprecated': False}, - 'cmu-mach-nodoc': {'id': 'CMU-Mach-nodoc', 'deprecated': False}, - 'cnri-jython': {'id': 'CNRI-Jython', 'deprecated': False}, - 'cnri-python': {'id': 'CNRI-Python', 'deprecated': False}, - 'cnri-python-gpl-compatible': {'id': 'CNRI-Python-GPL-Compatible', 'deprecated': False}, - 'coil-1.0': {'id': 'COIL-1.0', 'deprecated': False}, - 'community-spec-1.0': {'id': 'Community-Spec-1.0', 'deprecated': False}, - 'condor-1.1': {'id': 'Condor-1.1', 'deprecated': False}, - 'copyleft-next-0.3.0': {'id': 'copyleft-next-0.3.0', 'deprecated': False}, - 'copyleft-next-0.3.1': {'id': 'copyleft-next-0.3.1', 'deprecated': False}, - 'cornell-lossless-jpeg': {'id': 'Cornell-Lossless-JPEG', 'deprecated': False}, - 'cpal-1.0': {'id': 'CPAL-1.0', 'deprecated': False}, - 'cpl-1.0': {'id': 'CPL-1.0', 'deprecated': False}, - 'cpol-1.02': {'id': 'CPOL-1.02', 'deprecated': False}, - 'cronyx': {'id': 'Cronyx', 'deprecated': False}, - 'crossword': {'id': 'Crossword', 'deprecated': False}, - 'cryptoswift': {'id': 'CryptoSwift', 'deprecated': False}, - 'crystalstacker': {'id': 'CrystalStacker', 'deprecated': False}, - 'cua-opl-1.0': {'id': 'CUA-OPL-1.0', 'deprecated': False}, - 'cube': {'id': 'Cube', 'deprecated': False}, - 'curl': {'id': 'curl', 'deprecated': False}, - 'cve-tou': {'id': 'cve-tou', 'deprecated': False}, - 'd-fsl-1.0': {'id': 'D-FSL-1.0', 'deprecated': False}, - 'dec-3-clause': {'id': 'DEC-3-Clause', 'deprecated': False}, - 'diffmark': {'id': 'diffmark', 'deprecated': False}, - 'dl-de-by-2.0': {'id': 'DL-DE-BY-2.0', 'deprecated': False}, - 'dl-de-zero-2.0': {'id': 'DL-DE-ZERO-2.0', 'deprecated': False}, - 'doc': {'id': 'DOC', 'deprecated': False}, - 'docbook-dtd': {'id': 'DocBook-DTD', 'deprecated': False}, - 'docbook-schema': {'id': 'DocBook-Schema', 'deprecated': False}, - 'docbook-stylesheet': {'id': 'DocBook-Stylesheet', 'deprecated': False}, - 'docbook-xml': {'id': 'DocBook-XML', 'deprecated': False}, - 'dotseqn': {'id': 'Dotseqn', 'deprecated': False}, - 'drl-1.0': {'id': 'DRL-1.0', 'deprecated': False}, - 'drl-1.1': {'id': 'DRL-1.1', 'deprecated': False}, - 'dsdp': {'id': 'DSDP', 'deprecated': False}, - 'dtoa': {'id': 'dtoa', 'deprecated': False}, - 'dvipdfm': {'id': 'dvipdfm', 'deprecated': False}, - 'ecl-1.0': {'id': 'ECL-1.0', 'deprecated': False}, - 'ecl-2.0': {'id': 'ECL-2.0', 'deprecated': False}, - 'ecos-2.0': {'id': 'eCos-2.0', 'deprecated': True}, - 'efl-1.0': {'id': 'EFL-1.0', 'deprecated': False}, - 'efl-2.0': {'id': 'EFL-2.0', 'deprecated': False}, - 'egenix': {'id': 'eGenix', 'deprecated': False}, - 'elastic-2.0': {'id': 'Elastic-2.0', 'deprecated': False}, - 'entessa': {'id': 'Entessa', 'deprecated': False}, - 'epics': {'id': 'EPICS', 'deprecated': False}, - 'epl-1.0': {'id': 'EPL-1.0', 'deprecated': False}, - 'epl-2.0': {'id': 'EPL-2.0', 'deprecated': False}, - 'erlpl-1.1': {'id': 'ErlPL-1.1', 'deprecated': False}, - 'etalab-2.0': {'id': 'etalab-2.0', 'deprecated': False}, - 'eudatagrid': {'id': 'EUDatagrid', 'deprecated': False}, - 'eupl-1.0': {'id': 'EUPL-1.0', 'deprecated': False}, - 'eupl-1.1': {'id': 'EUPL-1.1', 'deprecated': False}, - 'eupl-1.2': {'id': 'EUPL-1.2', 'deprecated': False}, - 'eurosym': {'id': 'Eurosym', 'deprecated': False}, - 'fair': {'id': 'Fair', 'deprecated': False}, - 'fbm': {'id': 'FBM', 'deprecated': False}, - 'fdk-aac': {'id': 'FDK-AAC', 'deprecated': False}, - 'ferguson-twofish': {'id': 'Ferguson-Twofish', 'deprecated': False}, - 'frameworx-1.0': {'id': 'Frameworx-1.0', 'deprecated': False}, - 'freebsd-doc': {'id': 'FreeBSD-DOC', 'deprecated': False}, - 'freeimage': {'id': 'FreeImage', 'deprecated': False}, - 'fsfap': {'id': 'FSFAP', 'deprecated': False}, - 'fsfap-no-warranty-disclaimer': {'id': 'FSFAP-no-warranty-disclaimer', 'deprecated': False}, - 'fsful': {'id': 'FSFUL', 'deprecated': False}, - 'fsfullr': {'id': 'FSFULLR', 'deprecated': False}, - 'fsfullrsd': {'id': 'FSFULLRSD', 'deprecated': False}, - 'fsfullrwd': {'id': 'FSFULLRWD', 'deprecated': False}, - 'fsl-1.1-alv2': {'id': 'FSL-1.1-ALv2', 'deprecated': False}, - 'fsl-1.1-mit': {'id': 'FSL-1.1-MIT', 'deprecated': False}, - 'ftl': {'id': 'FTL', 'deprecated': False}, - 'furuseth': {'id': 'Furuseth', 'deprecated': False}, - 'fwlw': {'id': 'fwlw', 'deprecated': False}, - 'game-programming-gems': {'id': 'Game-Programming-Gems', 'deprecated': False}, - 'gcr-docs': {'id': 'GCR-docs', 'deprecated': False}, - 'gd': {'id': 'GD', 'deprecated': False}, - 'generic-xts': {'id': 'generic-xts', 'deprecated': False}, - 'gfdl-1.1': {'id': 'GFDL-1.1', 'deprecated': True}, - 'gfdl-1.1-invariants-only': {'id': 'GFDL-1.1-invariants-only', 'deprecated': False}, - 'gfdl-1.1-invariants-or-later': {'id': 'GFDL-1.1-invariants-or-later', 'deprecated': False}, - 'gfdl-1.1-no-invariants-only': {'id': 'GFDL-1.1-no-invariants-only', 'deprecated': False}, - 'gfdl-1.1-no-invariants-or-later': {'id': 'GFDL-1.1-no-invariants-or-later', 'deprecated': False}, - 'gfdl-1.1-only': {'id': 'GFDL-1.1-only', 'deprecated': False}, - 'gfdl-1.1-or-later': {'id': 'GFDL-1.1-or-later', 'deprecated': False}, - 'gfdl-1.2': {'id': 'GFDL-1.2', 'deprecated': True}, - 'gfdl-1.2-invariants-only': {'id': 'GFDL-1.2-invariants-only', 'deprecated': False}, - 'gfdl-1.2-invariants-or-later': {'id': 'GFDL-1.2-invariants-or-later', 'deprecated': False}, - 'gfdl-1.2-no-invariants-only': {'id': 'GFDL-1.2-no-invariants-only', 'deprecated': False}, - 'gfdl-1.2-no-invariants-or-later': {'id': 'GFDL-1.2-no-invariants-or-later', 'deprecated': False}, - 'gfdl-1.2-only': {'id': 'GFDL-1.2-only', 'deprecated': False}, - 'gfdl-1.2-or-later': {'id': 'GFDL-1.2-or-later', 'deprecated': False}, - 'gfdl-1.3': {'id': 'GFDL-1.3', 'deprecated': True}, - 'gfdl-1.3-invariants-only': {'id': 'GFDL-1.3-invariants-only', 'deprecated': False}, - 'gfdl-1.3-invariants-or-later': {'id': 'GFDL-1.3-invariants-or-later', 'deprecated': False}, - 'gfdl-1.3-no-invariants-only': {'id': 'GFDL-1.3-no-invariants-only', 'deprecated': False}, - 'gfdl-1.3-no-invariants-or-later': {'id': 'GFDL-1.3-no-invariants-or-later', 'deprecated': False}, - 'gfdl-1.3-only': {'id': 'GFDL-1.3-only', 'deprecated': False}, - 'gfdl-1.3-or-later': {'id': 'GFDL-1.3-or-later', 'deprecated': False}, - 'giftware': {'id': 'Giftware', 'deprecated': False}, - 'gl2ps': {'id': 'GL2PS', 'deprecated': False}, - 'glide': {'id': 'Glide', 'deprecated': False}, - 'glulxe': {'id': 'Glulxe', 'deprecated': False}, - 'glwtpl': {'id': 'GLWTPL', 'deprecated': False}, - 'gnuplot': {'id': 'gnuplot', 'deprecated': False}, - 'gpl-1.0': {'id': 'GPL-1.0', 'deprecated': True}, - 'gpl-1.0+': {'id': 'GPL-1.0+', 'deprecated': True}, - 'gpl-1.0-only': {'id': 'GPL-1.0-only', 'deprecated': False}, - 'gpl-1.0-or-later': {'id': 'GPL-1.0-or-later', 'deprecated': False}, - 'gpl-2.0': {'id': 'GPL-2.0', 'deprecated': True}, - 'gpl-2.0+': {'id': 'GPL-2.0+', 'deprecated': True}, - 'gpl-2.0-only': {'id': 'GPL-2.0-only', 'deprecated': False}, - 'gpl-2.0-or-later': {'id': 'GPL-2.0-or-later', 'deprecated': False}, - 'gpl-2.0-with-autoconf-exception': {'id': 'GPL-2.0-with-autoconf-exception', 'deprecated': True}, - 'gpl-2.0-with-bison-exception': {'id': 'GPL-2.0-with-bison-exception', 'deprecated': True}, - 'gpl-2.0-with-classpath-exception': {'id': 'GPL-2.0-with-classpath-exception', 'deprecated': True}, - 'gpl-2.0-with-font-exception': {'id': 'GPL-2.0-with-font-exception', 'deprecated': True}, - 'gpl-2.0-with-gcc-exception': {'id': 'GPL-2.0-with-GCC-exception', 'deprecated': True}, - 'gpl-3.0': {'id': 'GPL-3.0', 'deprecated': True}, - 'gpl-3.0+': {'id': 'GPL-3.0+', 'deprecated': True}, - 'gpl-3.0-only': {'id': 'GPL-3.0-only', 'deprecated': False}, - 'gpl-3.0-or-later': {'id': 'GPL-3.0-or-later', 'deprecated': False}, - 'gpl-3.0-with-autoconf-exception': {'id': 'GPL-3.0-with-autoconf-exception', 'deprecated': True}, - 'gpl-3.0-with-gcc-exception': {'id': 'GPL-3.0-with-GCC-exception', 'deprecated': True}, - 'graphics-gems': {'id': 'Graphics-Gems', 'deprecated': False}, - 'gsoap-1.3b': {'id': 'gSOAP-1.3b', 'deprecated': False}, - 'gtkbook': {'id': 'gtkbook', 'deprecated': False}, - 'gutmann': {'id': 'Gutmann', 'deprecated': False}, - 'haskellreport': {'id': 'HaskellReport', 'deprecated': False}, - 'hdf5': {'id': 'HDF5', 'deprecated': False}, - 'hdparm': {'id': 'hdparm', 'deprecated': False}, - 'hidapi': {'id': 'HIDAPI', 'deprecated': False}, - 'hippocratic-2.1': {'id': 'Hippocratic-2.1', 'deprecated': False}, - 'hp-1986': {'id': 'HP-1986', 'deprecated': False}, - 'hp-1989': {'id': 'HP-1989', 'deprecated': False}, - 'hpnd': {'id': 'HPND', 'deprecated': False}, - 'hpnd-dec': {'id': 'HPND-DEC', 'deprecated': False}, - 'hpnd-doc': {'id': 'HPND-doc', 'deprecated': False}, - 'hpnd-doc-sell': {'id': 'HPND-doc-sell', 'deprecated': False}, - 'hpnd-export-us': {'id': 'HPND-export-US', 'deprecated': False}, - 'hpnd-export-us-acknowledgement': {'id': 'HPND-export-US-acknowledgement', 'deprecated': False}, - 'hpnd-export-us-modify': {'id': 'HPND-export-US-modify', 'deprecated': False}, - 'hpnd-export2-us': {'id': 'HPND-export2-US', 'deprecated': False}, - 'hpnd-fenneberg-livingston': {'id': 'HPND-Fenneberg-Livingston', 'deprecated': False}, - 'hpnd-inria-imag': {'id': 'HPND-INRIA-IMAG', 'deprecated': False}, - 'hpnd-intel': {'id': 'HPND-Intel', 'deprecated': False}, - 'hpnd-kevlin-henney': {'id': 'HPND-Kevlin-Henney', 'deprecated': False}, - 'hpnd-markus-kuhn': {'id': 'HPND-Markus-Kuhn', 'deprecated': False}, - 'hpnd-merchantability-variant': {'id': 'HPND-merchantability-variant', 'deprecated': False}, - 'hpnd-mit-disclaimer': {'id': 'HPND-MIT-disclaimer', 'deprecated': False}, - 'hpnd-netrek': {'id': 'HPND-Netrek', 'deprecated': False}, - 'hpnd-pbmplus': {'id': 'HPND-Pbmplus', 'deprecated': False}, - 'hpnd-sell-mit-disclaimer-xserver': {'id': 'HPND-sell-MIT-disclaimer-xserver', 'deprecated': False}, - 'hpnd-sell-regexpr': {'id': 'HPND-sell-regexpr', 'deprecated': False}, - 'hpnd-sell-variant': {'id': 'HPND-sell-variant', 'deprecated': False}, - 'hpnd-sell-variant-mit-disclaimer': {'id': 'HPND-sell-variant-MIT-disclaimer', 'deprecated': False}, - 'hpnd-sell-variant-mit-disclaimer-rev': {'id': 'HPND-sell-variant-MIT-disclaimer-rev', 'deprecated': False}, - 'hpnd-uc': {'id': 'HPND-UC', 'deprecated': False}, - 'hpnd-uc-export-us': {'id': 'HPND-UC-export-US', 'deprecated': False}, - 'htmltidy': {'id': 'HTMLTIDY', 'deprecated': False}, - 'ibm-pibs': {'id': 'IBM-pibs', 'deprecated': False}, - 'icu': {'id': 'ICU', 'deprecated': False}, - 'iec-code-components-eula': {'id': 'IEC-Code-Components-EULA', 'deprecated': False}, - 'ijg': {'id': 'IJG', 'deprecated': False}, - 'ijg-short': {'id': 'IJG-short', 'deprecated': False}, - 'imagemagick': {'id': 'ImageMagick', 'deprecated': False}, - 'imatix': {'id': 'iMatix', 'deprecated': False}, - 'imlib2': {'id': 'Imlib2', 'deprecated': False}, - 'info-zip': {'id': 'Info-ZIP', 'deprecated': False}, - 'inner-net-2.0': {'id': 'Inner-Net-2.0', 'deprecated': False}, - 'innosetup': {'id': 'InnoSetup', 'deprecated': False}, - 'intel': {'id': 'Intel', 'deprecated': False}, - 'intel-acpi': {'id': 'Intel-ACPI', 'deprecated': False}, - 'interbase-1.0': {'id': 'Interbase-1.0', 'deprecated': False}, - 'ipa': {'id': 'IPA', 'deprecated': False}, - 'ipl-1.0': {'id': 'IPL-1.0', 'deprecated': False}, - 'isc': {'id': 'ISC', 'deprecated': False}, - 'isc-veillard': {'id': 'ISC-Veillard', 'deprecated': False}, - 'jam': {'id': 'Jam', 'deprecated': False}, - 'jasper-2.0': {'id': 'JasPer-2.0', 'deprecated': False}, - 'jove': {'id': 'jove', 'deprecated': False}, - 'jpl-image': {'id': 'JPL-image', 'deprecated': False}, - 'jpnic': {'id': 'JPNIC', 'deprecated': False}, - 'json': {'id': 'JSON', 'deprecated': False}, - 'kastrup': {'id': 'Kastrup', 'deprecated': False}, - 'kazlib': {'id': 'Kazlib', 'deprecated': False}, - 'knuth-ctan': {'id': 'Knuth-CTAN', 'deprecated': False}, - 'lal-1.2': {'id': 'LAL-1.2', 'deprecated': False}, - 'lal-1.3': {'id': 'LAL-1.3', 'deprecated': False}, - 'latex2e': {'id': 'Latex2e', 'deprecated': False}, - 'latex2e-translated-notice': {'id': 'Latex2e-translated-notice', 'deprecated': False}, - 'leptonica': {'id': 'Leptonica', 'deprecated': False}, - 'lgpl-2.0': {'id': 'LGPL-2.0', 'deprecated': True}, - 'lgpl-2.0+': {'id': 'LGPL-2.0+', 'deprecated': True}, - 'lgpl-2.0-only': {'id': 'LGPL-2.0-only', 'deprecated': False}, - 'lgpl-2.0-or-later': {'id': 'LGPL-2.0-or-later', 'deprecated': False}, - 'lgpl-2.1': {'id': 'LGPL-2.1', 'deprecated': True}, - 'lgpl-2.1+': {'id': 'LGPL-2.1+', 'deprecated': True}, - 'lgpl-2.1-only': {'id': 'LGPL-2.1-only', 'deprecated': False}, - 'lgpl-2.1-or-later': {'id': 'LGPL-2.1-or-later', 'deprecated': False}, - 'lgpl-3.0': {'id': 'LGPL-3.0', 'deprecated': True}, - 'lgpl-3.0+': {'id': 'LGPL-3.0+', 'deprecated': True}, - 'lgpl-3.0-only': {'id': 'LGPL-3.0-only', 'deprecated': False}, - 'lgpl-3.0-or-later': {'id': 'LGPL-3.0-or-later', 'deprecated': False}, - 'lgpllr': {'id': 'LGPLLR', 'deprecated': False}, - 'libpng': {'id': 'Libpng', 'deprecated': False}, - 'libpng-1.6.35': {'id': 'libpng-1.6.35', 'deprecated': False}, - 'libpng-2.0': {'id': 'libpng-2.0', 'deprecated': False}, - 'libselinux-1.0': {'id': 'libselinux-1.0', 'deprecated': False}, - 'libtiff': {'id': 'libtiff', 'deprecated': False}, - 'libutil-david-nugent': {'id': 'libutil-David-Nugent', 'deprecated': False}, - 'liliq-p-1.1': {'id': 'LiLiQ-P-1.1', 'deprecated': False}, - 'liliq-r-1.1': {'id': 'LiLiQ-R-1.1', 'deprecated': False}, - 'liliq-rplus-1.1': {'id': 'LiLiQ-Rplus-1.1', 'deprecated': False}, - 'linux-man-pages-1-para': {'id': 'Linux-man-pages-1-para', 'deprecated': False}, - 'linux-man-pages-copyleft': {'id': 'Linux-man-pages-copyleft', 'deprecated': False}, - 'linux-man-pages-copyleft-2-para': {'id': 'Linux-man-pages-copyleft-2-para', 'deprecated': False}, - 'linux-man-pages-copyleft-var': {'id': 'Linux-man-pages-copyleft-var', 'deprecated': False}, - 'linux-openib': {'id': 'Linux-OpenIB', 'deprecated': False}, - 'loop': {'id': 'LOOP', 'deprecated': False}, - 'lpd-document': {'id': 'LPD-document', 'deprecated': False}, - 'lpl-1.0': {'id': 'LPL-1.0', 'deprecated': False}, - 'lpl-1.02': {'id': 'LPL-1.02', 'deprecated': False}, - 'lppl-1.0': {'id': 'LPPL-1.0', 'deprecated': False}, - 'lppl-1.1': {'id': 'LPPL-1.1', 'deprecated': False}, - 'lppl-1.2': {'id': 'LPPL-1.2', 'deprecated': False}, - 'lppl-1.3a': {'id': 'LPPL-1.3a', 'deprecated': False}, - 'lppl-1.3c': {'id': 'LPPL-1.3c', 'deprecated': False}, - 'lsof': {'id': 'lsof', 'deprecated': False}, - 'lucida-bitmap-fonts': {'id': 'Lucida-Bitmap-Fonts', 'deprecated': False}, - 'lzma-sdk-9.11-to-9.20': {'id': 'LZMA-SDK-9.11-to-9.20', 'deprecated': False}, - 'lzma-sdk-9.22': {'id': 'LZMA-SDK-9.22', 'deprecated': False}, - 'mackerras-3-clause': {'id': 'Mackerras-3-Clause', 'deprecated': False}, - 'mackerras-3-clause-acknowledgment': {'id': 'Mackerras-3-Clause-acknowledgment', 'deprecated': False}, - 'magaz': {'id': 'magaz', 'deprecated': False}, - 'mailprio': {'id': 'mailprio', 'deprecated': False}, - 'makeindex': {'id': 'MakeIndex', 'deprecated': False}, - 'man2html': {'id': 'man2html', 'deprecated': False}, - 'martin-birgmeier': {'id': 'Martin-Birgmeier', 'deprecated': False}, - 'mcphee-slideshow': {'id': 'McPhee-slideshow', 'deprecated': False}, - 'metamail': {'id': 'metamail', 'deprecated': False}, - 'minpack': {'id': 'Minpack', 'deprecated': False}, - 'mips': {'id': 'MIPS', 'deprecated': False}, - 'miros': {'id': 'MirOS', 'deprecated': False}, - 'mit': {'id': 'MIT', 'deprecated': False}, - 'mit-0': {'id': 'MIT-0', 'deprecated': False}, - 'mit-advertising': {'id': 'MIT-advertising', 'deprecated': False}, - 'mit-click': {'id': 'MIT-Click', 'deprecated': False}, - 'mit-cmu': {'id': 'MIT-CMU', 'deprecated': False}, - 'mit-enna': {'id': 'MIT-enna', 'deprecated': False}, - 'mit-feh': {'id': 'MIT-feh', 'deprecated': False}, - 'mit-festival': {'id': 'MIT-Festival', 'deprecated': False}, - 'mit-khronos-old': {'id': 'MIT-Khronos-old', 'deprecated': False}, - 'mit-modern-variant': {'id': 'MIT-Modern-Variant', 'deprecated': False}, - 'mit-open-group': {'id': 'MIT-open-group', 'deprecated': False}, - 'mit-testregex': {'id': 'MIT-testregex', 'deprecated': False}, - 'mit-wu': {'id': 'MIT-Wu', 'deprecated': False}, - 'mitnfa': {'id': 'MITNFA', 'deprecated': False}, - 'mmixware': {'id': 'MMIXware', 'deprecated': False}, - 'motosoto': {'id': 'Motosoto', 'deprecated': False}, - 'mpeg-ssg': {'id': 'MPEG-SSG', 'deprecated': False}, - 'mpi-permissive': {'id': 'mpi-permissive', 'deprecated': False}, - 'mpich2': {'id': 'mpich2', 'deprecated': False}, - 'mpl-1.0': {'id': 'MPL-1.0', 'deprecated': False}, - 'mpl-1.1': {'id': 'MPL-1.1', 'deprecated': False}, - 'mpl-2.0': {'id': 'MPL-2.0', 'deprecated': False}, - 'mpl-2.0-no-copyleft-exception': {'id': 'MPL-2.0-no-copyleft-exception', 'deprecated': False}, - 'mplus': {'id': 'mplus', 'deprecated': False}, - 'ms-lpl': {'id': 'MS-LPL', 'deprecated': False}, - 'ms-pl': {'id': 'MS-PL', 'deprecated': False}, - 'ms-rl': {'id': 'MS-RL', 'deprecated': False}, - 'mtll': {'id': 'MTLL', 'deprecated': False}, - 'mulanpsl-1.0': {'id': 'MulanPSL-1.0', 'deprecated': False}, - 'mulanpsl-2.0': {'id': 'MulanPSL-2.0', 'deprecated': False}, - 'multics': {'id': 'Multics', 'deprecated': False}, - 'mup': {'id': 'Mup', 'deprecated': False}, - 'naist-2003': {'id': 'NAIST-2003', 'deprecated': False}, - 'nasa-1.3': {'id': 'NASA-1.3', 'deprecated': False}, - 'naumen': {'id': 'Naumen', 'deprecated': False}, - 'nbpl-1.0': {'id': 'NBPL-1.0', 'deprecated': False}, - 'ncbi-pd': {'id': 'NCBI-PD', 'deprecated': False}, - 'ncgl-uk-2.0': {'id': 'NCGL-UK-2.0', 'deprecated': False}, - 'ncl': {'id': 'NCL', 'deprecated': False}, - 'ncsa': {'id': 'NCSA', 'deprecated': False}, - 'net-snmp': {'id': 'Net-SNMP', 'deprecated': True}, - 'netcdf': {'id': 'NetCDF', 'deprecated': False}, - 'newsletr': {'id': 'Newsletr', 'deprecated': False}, - 'ngpl': {'id': 'NGPL', 'deprecated': False}, - 'ngrep': {'id': 'ngrep', 'deprecated': False}, - 'nicta-1.0': {'id': 'NICTA-1.0', 'deprecated': False}, - 'nist-pd': {'id': 'NIST-PD', 'deprecated': False}, - 'nist-pd-fallback': {'id': 'NIST-PD-fallback', 'deprecated': False}, - 'nist-software': {'id': 'NIST-Software', 'deprecated': False}, - 'nlod-1.0': {'id': 'NLOD-1.0', 'deprecated': False}, - 'nlod-2.0': {'id': 'NLOD-2.0', 'deprecated': False}, - 'nlpl': {'id': 'NLPL', 'deprecated': False}, - 'nokia': {'id': 'Nokia', 'deprecated': False}, - 'nosl': {'id': 'NOSL', 'deprecated': False}, - 'noweb': {'id': 'Noweb', 'deprecated': False}, - 'npl-1.0': {'id': 'NPL-1.0', 'deprecated': False}, - 'npl-1.1': {'id': 'NPL-1.1', 'deprecated': False}, - 'nposl-3.0': {'id': 'NPOSL-3.0', 'deprecated': False}, - 'nrl': {'id': 'NRL', 'deprecated': False}, - 'ntia-pd': {'id': 'NTIA-PD', 'deprecated': False}, - 'ntp': {'id': 'NTP', 'deprecated': False}, - 'ntp-0': {'id': 'NTP-0', 'deprecated': False}, - 'nunit': {'id': 'Nunit', 'deprecated': True}, - 'o-uda-1.0': {'id': 'O-UDA-1.0', 'deprecated': False}, - 'oar': {'id': 'OAR', 'deprecated': False}, - 'occt-pl': {'id': 'OCCT-PL', 'deprecated': False}, - 'oclc-2.0': {'id': 'OCLC-2.0', 'deprecated': False}, - 'odbl-1.0': {'id': 'ODbL-1.0', 'deprecated': False}, - 'odc-by-1.0': {'id': 'ODC-By-1.0', 'deprecated': False}, - 'offis': {'id': 'OFFIS', 'deprecated': False}, - 'ofl-1.0': {'id': 'OFL-1.0', 'deprecated': False}, - 'ofl-1.0-no-rfn': {'id': 'OFL-1.0-no-RFN', 'deprecated': False}, - 'ofl-1.0-rfn': {'id': 'OFL-1.0-RFN', 'deprecated': False}, - 'ofl-1.1': {'id': 'OFL-1.1', 'deprecated': False}, - 'ofl-1.1-no-rfn': {'id': 'OFL-1.1-no-RFN', 'deprecated': False}, - 'ofl-1.1-rfn': {'id': 'OFL-1.1-RFN', 'deprecated': False}, - 'ogc-1.0': {'id': 'OGC-1.0', 'deprecated': False}, - 'ogdl-taiwan-1.0': {'id': 'OGDL-Taiwan-1.0', 'deprecated': False}, - 'ogl-canada-2.0': {'id': 'OGL-Canada-2.0', 'deprecated': False}, - 'ogl-uk-1.0': {'id': 'OGL-UK-1.0', 'deprecated': False}, - 'ogl-uk-2.0': {'id': 'OGL-UK-2.0', 'deprecated': False}, - 'ogl-uk-3.0': {'id': 'OGL-UK-3.0', 'deprecated': False}, - 'ogtsl': {'id': 'OGTSL', 'deprecated': False}, - 'oldap-1.1': {'id': 'OLDAP-1.1', 'deprecated': False}, - 'oldap-1.2': {'id': 'OLDAP-1.2', 'deprecated': False}, - 'oldap-1.3': {'id': 'OLDAP-1.3', 'deprecated': False}, - 'oldap-1.4': {'id': 'OLDAP-1.4', 'deprecated': False}, - 'oldap-2.0': {'id': 'OLDAP-2.0', 'deprecated': False}, - 'oldap-2.0.1': {'id': 'OLDAP-2.0.1', 'deprecated': False}, - 'oldap-2.1': {'id': 'OLDAP-2.1', 'deprecated': False}, - 'oldap-2.2': {'id': 'OLDAP-2.2', 'deprecated': False}, - 'oldap-2.2.1': {'id': 'OLDAP-2.2.1', 'deprecated': False}, - 'oldap-2.2.2': {'id': 'OLDAP-2.2.2', 'deprecated': False}, - 'oldap-2.3': {'id': 'OLDAP-2.3', 'deprecated': False}, - 'oldap-2.4': {'id': 'OLDAP-2.4', 'deprecated': False}, - 'oldap-2.5': {'id': 'OLDAP-2.5', 'deprecated': False}, - 'oldap-2.6': {'id': 'OLDAP-2.6', 'deprecated': False}, - 'oldap-2.7': {'id': 'OLDAP-2.7', 'deprecated': False}, - 'oldap-2.8': {'id': 'OLDAP-2.8', 'deprecated': False}, - 'olfl-1.3': {'id': 'OLFL-1.3', 'deprecated': False}, - 'oml': {'id': 'OML', 'deprecated': False}, - 'openpbs-2.3': {'id': 'OpenPBS-2.3', 'deprecated': False}, - 'openssl': {'id': 'OpenSSL', 'deprecated': False}, - 'openssl-standalone': {'id': 'OpenSSL-standalone', 'deprecated': False}, - 'openvision': {'id': 'OpenVision', 'deprecated': False}, - 'opl-1.0': {'id': 'OPL-1.0', 'deprecated': False}, - 'opl-uk-3.0': {'id': 'OPL-UK-3.0', 'deprecated': False}, - 'opubl-1.0': {'id': 'OPUBL-1.0', 'deprecated': False}, - 'oset-pl-2.1': {'id': 'OSET-PL-2.1', 'deprecated': False}, - 'osl-1.0': {'id': 'OSL-1.0', 'deprecated': False}, - 'osl-1.1': {'id': 'OSL-1.1', 'deprecated': False}, - 'osl-2.0': {'id': 'OSL-2.0', 'deprecated': False}, - 'osl-2.1': {'id': 'OSL-2.1', 'deprecated': False}, - 'osl-3.0': {'id': 'OSL-3.0', 'deprecated': False}, - 'padl': {'id': 'PADL', 'deprecated': False}, - 'parity-6.0.0': {'id': 'Parity-6.0.0', 'deprecated': False}, - 'parity-7.0.0': {'id': 'Parity-7.0.0', 'deprecated': False}, - 'pddl-1.0': {'id': 'PDDL-1.0', 'deprecated': False}, - 'php-3.0': {'id': 'PHP-3.0', 'deprecated': False}, - 'php-3.01': {'id': 'PHP-3.01', 'deprecated': False}, - 'pixar': {'id': 'Pixar', 'deprecated': False}, - 'pkgconf': {'id': 'pkgconf', 'deprecated': False}, - 'plexus': {'id': 'Plexus', 'deprecated': False}, - 'pnmstitch': {'id': 'pnmstitch', 'deprecated': False}, - 'polyform-noncommercial-1.0.0': {'id': 'PolyForm-Noncommercial-1.0.0', 'deprecated': False}, - 'polyform-small-business-1.0.0': {'id': 'PolyForm-Small-Business-1.0.0', 'deprecated': False}, - 'postgresql': {'id': 'PostgreSQL', 'deprecated': False}, - 'ppl': {'id': 'PPL', 'deprecated': False}, - 'psf-2.0': {'id': 'PSF-2.0', 'deprecated': False}, - 'psfrag': {'id': 'psfrag', 'deprecated': False}, - 'psutils': {'id': 'psutils', 'deprecated': False}, - 'python-2.0': {'id': 'Python-2.0', 'deprecated': False}, - 'python-2.0.1': {'id': 'Python-2.0.1', 'deprecated': False}, - 'python-ldap': {'id': 'python-ldap', 'deprecated': False}, - 'qhull': {'id': 'Qhull', 'deprecated': False}, - 'qpl-1.0': {'id': 'QPL-1.0', 'deprecated': False}, - 'qpl-1.0-inria-2004': {'id': 'QPL-1.0-INRIA-2004', 'deprecated': False}, - 'radvd': {'id': 'radvd', 'deprecated': False}, - 'rdisc': {'id': 'Rdisc', 'deprecated': False}, - 'rhecos-1.1': {'id': 'RHeCos-1.1', 'deprecated': False}, - 'rpl-1.1': {'id': 'RPL-1.1', 'deprecated': False}, - 'rpl-1.5': {'id': 'RPL-1.5', 'deprecated': False}, - 'rpsl-1.0': {'id': 'RPSL-1.0', 'deprecated': False}, - 'rsa-md': {'id': 'RSA-MD', 'deprecated': False}, - 'rscpl': {'id': 'RSCPL', 'deprecated': False}, - 'ruby': {'id': 'Ruby', 'deprecated': False}, - 'ruby-pty': {'id': 'Ruby-pty', 'deprecated': False}, - 'sax-pd': {'id': 'SAX-PD', 'deprecated': False}, - 'sax-pd-2.0': {'id': 'SAX-PD-2.0', 'deprecated': False}, - 'saxpath': {'id': 'Saxpath', 'deprecated': False}, - 'scea': {'id': 'SCEA', 'deprecated': False}, - 'schemereport': {'id': 'SchemeReport', 'deprecated': False}, - 'sendmail': {'id': 'Sendmail', 'deprecated': False}, - 'sendmail-8.23': {'id': 'Sendmail-8.23', 'deprecated': False}, - 'sendmail-open-source-1.1': {'id': 'Sendmail-Open-Source-1.1', 'deprecated': False}, - 'sgi-b-1.0': {'id': 'SGI-B-1.0', 'deprecated': False}, - 'sgi-b-1.1': {'id': 'SGI-B-1.1', 'deprecated': False}, - 'sgi-b-2.0': {'id': 'SGI-B-2.0', 'deprecated': False}, - 'sgi-opengl': {'id': 'SGI-OpenGL', 'deprecated': False}, - 'sgp4': {'id': 'SGP4', 'deprecated': False}, - 'shl-0.5': {'id': 'SHL-0.5', 'deprecated': False}, - 'shl-0.51': {'id': 'SHL-0.51', 'deprecated': False}, - 'simpl-2.0': {'id': 'SimPL-2.0', 'deprecated': False}, - 'sissl': {'id': 'SISSL', 'deprecated': False}, - 'sissl-1.2': {'id': 'SISSL-1.2', 'deprecated': False}, - 'sl': {'id': 'SL', 'deprecated': False}, - 'sleepycat': {'id': 'Sleepycat', 'deprecated': False}, - 'smail-gpl': {'id': 'SMAIL-GPL', 'deprecated': False}, - 'smlnj': {'id': 'SMLNJ', 'deprecated': False}, - 'smppl': {'id': 'SMPPL', 'deprecated': False}, - 'snia': {'id': 'SNIA', 'deprecated': False}, - 'snprintf': {'id': 'snprintf', 'deprecated': False}, - 'sofa': {'id': 'SOFA', 'deprecated': False}, - 'softsurfer': {'id': 'softSurfer', 'deprecated': False}, - 'soundex': {'id': 'Soundex', 'deprecated': False}, - 'spencer-86': {'id': 'Spencer-86', 'deprecated': False}, - 'spencer-94': {'id': 'Spencer-94', 'deprecated': False}, - 'spencer-99': {'id': 'Spencer-99', 'deprecated': False}, - 'spl-1.0': {'id': 'SPL-1.0', 'deprecated': False}, - 'ssh-keyscan': {'id': 'ssh-keyscan', 'deprecated': False}, - 'ssh-openssh': {'id': 'SSH-OpenSSH', 'deprecated': False}, - 'ssh-short': {'id': 'SSH-short', 'deprecated': False}, - 'ssleay-standalone': {'id': 'SSLeay-standalone', 'deprecated': False}, - 'sspl-1.0': {'id': 'SSPL-1.0', 'deprecated': False}, - 'standardml-nj': {'id': 'StandardML-NJ', 'deprecated': True}, - 'sugarcrm-1.1.3': {'id': 'SugarCRM-1.1.3', 'deprecated': False}, - 'sul-1.0': {'id': 'SUL-1.0', 'deprecated': False}, - 'sun-ppp': {'id': 'Sun-PPP', 'deprecated': False}, - 'sun-ppp-2000': {'id': 'Sun-PPP-2000', 'deprecated': False}, - 'sunpro': {'id': 'SunPro', 'deprecated': False}, - 'swl': {'id': 'SWL', 'deprecated': False}, - 'swrule': {'id': 'swrule', 'deprecated': False}, - 'symlinks': {'id': 'Symlinks', 'deprecated': False}, - 'tapr-ohl-1.0': {'id': 'TAPR-OHL-1.0', 'deprecated': False}, - 'tcl': {'id': 'TCL', 'deprecated': False}, - 'tcp-wrappers': {'id': 'TCP-wrappers', 'deprecated': False}, - 'termreadkey': {'id': 'TermReadKey', 'deprecated': False}, - 'tgppl-1.0': {'id': 'TGPPL-1.0', 'deprecated': False}, - 'thirdeye': {'id': 'ThirdEye', 'deprecated': False}, - 'threeparttable': {'id': 'threeparttable', 'deprecated': False}, - 'tmate': {'id': 'TMate', 'deprecated': False}, - 'torque-1.1': {'id': 'TORQUE-1.1', 'deprecated': False}, - 'tosl': {'id': 'TOSL', 'deprecated': False}, - 'tpdl': {'id': 'TPDL', 'deprecated': False}, - 'tpl-1.0': {'id': 'TPL-1.0', 'deprecated': False}, - 'trustedqsl': {'id': 'TrustedQSL', 'deprecated': False}, - 'ttwl': {'id': 'TTWL', 'deprecated': False}, - 'ttyp0': {'id': 'TTYP0', 'deprecated': False}, - 'tu-berlin-1.0': {'id': 'TU-Berlin-1.0', 'deprecated': False}, - 'tu-berlin-2.0': {'id': 'TU-Berlin-2.0', 'deprecated': False}, - 'ubuntu-font-1.0': {'id': 'Ubuntu-font-1.0', 'deprecated': False}, - 'ucar': {'id': 'UCAR', 'deprecated': False}, - 'ucl-1.0': {'id': 'UCL-1.0', 'deprecated': False}, - 'ulem': {'id': 'ulem', 'deprecated': False}, - 'umich-merit': {'id': 'UMich-Merit', 'deprecated': False}, - 'unicode-3.0': {'id': 'Unicode-3.0', 'deprecated': False}, - 'unicode-dfs-2015': {'id': 'Unicode-DFS-2015', 'deprecated': False}, - 'unicode-dfs-2016': {'id': 'Unicode-DFS-2016', 'deprecated': False}, - 'unicode-tou': {'id': 'Unicode-TOU', 'deprecated': False}, - 'unixcrypt': {'id': 'UnixCrypt', 'deprecated': False}, - 'unlicense': {'id': 'Unlicense', 'deprecated': False}, - 'unlicense-libtelnet': {'id': 'Unlicense-libtelnet', 'deprecated': False}, - 'unlicense-libwhirlpool': {'id': 'Unlicense-libwhirlpool', 'deprecated': False}, - 'upl-1.0': {'id': 'UPL-1.0', 'deprecated': False}, - 'urt-rle': {'id': 'URT-RLE', 'deprecated': False}, - 'vim': {'id': 'Vim', 'deprecated': False}, - 'vostrom': {'id': 'VOSTROM', 'deprecated': False}, - 'vsl-1.0': {'id': 'VSL-1.0', 'deprecated': False}, - 'w3c': {'id': 'W3C', 'deprecated': False}, - 'w3c-19980720': {'id': 'W3C-19980720', 'deprecated': False}, - 'w3c-20150513': {'id': 'W3C-20150513', 'deprecated': False}, - 'w3m': {'id': 'w3m', 'deprecated': False}, - 'watcom-1.0': {'id': 'Watcom-1.0', 'deprecated': False}, - 'widget-workshop': {'id': 'Widget-Workshop', 'deprecated': False}, - 'wsuipa': {'id': 'Wsuipa', 'deprecated': False}, - 'wtfpl': {'id': 'WTFPL', 'deprecated': False}, - 'wwl': {'id': 'wwl', 'deprecated': False}, - 'wxwindows': {'id': 'wxWindows', 'deprecated': True}, - 'x11': {'id': 'X11', 'deprecated': False}, - 'x11-distribute-modifications-variant': {'id': 'X11-distribute-modifications-variant', 'deprecated': False}, - 'x11-swapped': {'id': 'X11-swapped', 'deprecated': False}, - 'xdebug-1.03': {'id': 'Xdebug-1.03', 'deprecated': False}, - 'xerox': {'id': 'Xerox', 'deprecated': False}, - 'xfig': {'id': 'Xfig', 'deprecated': False}, - 'xfree86-1.1': {'id': 'XFree86-1.1', 'deprecated': False}, - 'xinetd': {'id': 'xinetd', 'deprecated': False}, - 'xkeyboard-config-zinoviev': {'id': 'xkeyboard-config-Zinoviev', 'deprecated': False}, - 'xlock': {'id': 'xlock', 'deprecated': False}, - 'xnet': {'id': 'Xnet', 'deprecated': False}, - 'xpp': {'id': 'xpp', 'deprecated': False}, - 'xskat': {'id': 'XSkat', 'deprecated': False}, - 'xzoom': {'id': 'xzoom', 'deprecated': False}, - 'ypl-1.0': {'id': 'YPL-1.0', 'deprecated': False}, - 'ypl-1.1': {'id': 'YPL-1.1', 'deprecated': False}, - 'zed': {'id': 'Zed', 'deprecated': False}, - 'zeeff': {'id': 'Zeeff', 'deprecated': False}, - 'zend-2.0': {'id': 'Zend-2.0', 'deprecated': False}, - 'zimbra-1.3': {'id': 'Zimbra-1.3', 'deprecated': False}, - 'zimbra-1.4': {'id': 'Zimbra-1.4', 'deprecated': False}, - 'zlib': {'id': 'Zlib', 'deprecated': False}, - 'zlib-acknowledgement': {'id': 'zlib-acknowledgement', 'deprecated': False}, - 'zpl-1.1': {'id': 'ZPL-1.1', 'deprecated': False}, - 'zpl-2.0': {'id': 'ZPL-2.0', 'deprecated': False}, - 'zpl-2.1': {'id': 'ZPL-2.1', 'deprecated': False}, -} - -EXCEPTIONS: dict[str, SPDXException] = { - '389-exception': {'id': '389-exception', 'deprecated': False}, - 'asterisk-exception': {'id': 'Asterisk-exception', 'deprecated': False}, - 'asterisk-linking-protocols-exception': {'id': 'Asterisk-linking-protocols-exception', 'deprecated': False}, - 'autoconf-exception-2.0': {'id': 'Autoconf-exception-2.0', 'deprecated': False}, - 'autoconf-exception-3.0': {'id': 'Autoconf-exception-3.0', 'deprecated': False}, - 'autoconf-exception-generic': {'id': 'Autoconf-exception-generic', 'deprecated': False}, - 'autoconf-exception-generic-3.0': {'id': 'Autoconf-exception-generic-3.0', 'deprecated': False}, - 'autoconf-exception-macro': {'id': 'Autoconf-exception-macro', 'deprecated': False}, - 'bison-exception-1.24': {'id': 'Bison-exception-1.24', 'deprecated': False}, - 'bison-exception-2.2': {'id': 'Bison-exception-2.2', 'deprecated': False}, - 'bootloader-exception': {'id': 'Bootloader-exception', 'deprecated': False}, - 'cgal-linking-exception': {'id': 'CGAL-linking-exception', 'deprecated': False}, - 'classpath-exception-2.0': {'id': 'Classpath-exception-2.0', 'deprecated': False}, - 'clisp-exception-2.0': {'id': 'CLISP-exception-2.0', 'deprecated': False}, - 'cryptsetup-openssl-exception': {'id': 'cryptsetup-OpenSSL-exception', 'deprecated': False}, - 'digia-qt-lgpl-exception-1.1': {'id': 'Digia-Qt-LGPL-exception-1.1', 'deprecated': False}, - 'digirule-foss-exception': {'id': 'DigiRule-FOSS-exception', 'deprecated': False}, - 'ecos-exception-2.0': {'id': 'eCos-exception-2.0', 'deprecated': False}, - 'erlang-otp-linking-exception': {'id': 'erlang-otp-linking-exception', 'deprecated': False}, - 'fawkes-runtime-exception': {'id': 'Fawkes-Runtime-exception', 'deprecated': False}, - 'fltk-exception': {'id': 'FLTK-exception', 'deprecated': False}, - 'fmt-exception': {'id': 'fmt-exception', 'deprecated': False}, - 'font-exception-2.0': {'id': 'Font-exception-2.0', 'deprecated': False}, - 'freertos-exception-2.0': {'id': 'freertos-exception-2.0', 'deprecated': False}, - 'gcc-exception-2.0': {'id': 'GCC-exception-2.0', 'deprecated': False}, - 'gcc-exception-2.0-note': {'id': 'GCC-exception-2.0-note', 'deprecated': False}, - 'gcc-exception-3.1': {'id': 'GCC-exception-3.1', 'deprecated': False}, - 'gmsh-exception': {'id': 'Gmsh-exception', 'deprecated': False}, - 'gnat-exception': {'id': 'GNAT-exception', 'deprecated': False}, - 'gnome-examples-exception': {'id': 'GNOME-examples-exception', 'deprecated': False}, - 'gnu-compiler-exception': {'id': 'GNU-compiler-exception', 'deprecated': False}, - 'gnu-javamail-exception': {'id': 'gnu-javamail-exception', 'deprecated': False}, - 'gpl-3.0-389-ds-base-exception': {'id': 'GPL-3.0-389-ds-base-exception', 'deprecated': False}, - 'gpl-3.0-interface-exception': {'id': 'GPL-3.0-interface-exception', 'deprecated': False}, - 'gpl-3.0-linking-exception': {'id': 'GPL-3.0-linking-exception', 'deprecated': False}, - 'gpl-3.0-linking-source-exception': {'id': 'GPL-3.0-linking-source-exception', 'deprecated': False}, - 'gpl-cc-1.0': {'id': 'GPL-CC-1.0', 'deprecated': False}, - 'gstreamer-exception-2005': {'id': 'GStreamer-exception-2005', 'deprecated': False}, - 'gstreamer-exception-2008': {'id': 'GStreamer-exception-2008', 'deprecated': False}, - 'harbour-exception': {'id': 'harbour-exception', 'deprecated': False}, - 'i2p-gpl-java-exception': {'id': 'i2p-gpl-java-exception', 'deprecated': False}, - 'independent-modules-exception': {'id': 'Independent-modules-exception', 'deprecated': False}, - 'kicad-libraries-exception': {'id': 'KiCad-libraries-exception', 'deprecated': False}, - 'lgpl-3.0-linking-exception': {'id': 'LGPL-3.0-linking-exception', 'deprecated': False}, - 'libpri-openh323-exception': {'id': 'libpri-OpenH323-exception', 'deprecated': False}, - 'libtool-exception': {'id': 'Libtool-exception', 'deprecated': False}, - 'linux-syscall-note': {'id': 'Linux-syscall-note', 'deprecated': False}, - 'llgpl': {'id': 'LLGPL', 'deprecated': False}, - 'llvm-exception': {'id': 'LLVM-exception', 'deprecated': False}, - 'lzma-exception': {'id': 'LZMA-exception', 'deprecated': False}, - 'mif-exception': {'id': 'mif-exception', 'deprecated': False}, - 'mxml-exception': {'id': 'mxml-exception', 'deprecated': False}, - 'nokia-qt-exception-1.1': {'id': 'Nokia-Qt-exception-1.1', 'deprecated': True}, - 'ocaml-lgpl-linking-exception': {'id': 'OCaml-LGPL-linking-exception', 'deprecated': False}, - 'occt-exception-1.0': {'id': 'OCCT-exception-1.0', 'deprecated': False}, - 'openjdk-assembly-exception-1.0': {'id': 'OpenJDK-assembly-exception-1.0', 'deprecated': False}, - 'openvpn-openssl-exception': {'id': 'openvpn-openssl-exception', 'deprecated': False}, - 'pcre2-exception': {'id': 'PCRE2-exception', 'deprecated': False}, - 'polyparse-exception': {'id': 'polyparse-exception', 'deprecated': False}, - 'ps-or-pdf-font-exception-20170817': {'id': 'PS-or-PDF-font-exception-20170817', 'deprecated': False}, - 'qpl-1.0-inria-2004-exception': {'id': 'QPL-1.0-INRIA-2004-exception', 'deprecated': False}, - 'qt-gpl-exception-1.0': {'id': 'Qt-GPL-exception-1.0', 'deprecated': False}, - 'qt-lgpl-exception-1.1': {'id': 'Qt-LGPL-exception-1.1', 'deprecated': False}, - 'qwt-exception-1.0': {'id': 'Qwt-exception-1.0', 'deprecated': False}, - 'romic-exception': {'id': 'romic-exception', 'deprecated': False}, - 'rrdtool-floss-exception-2.0': {'id': 'RRDtool-FLOSS-exception-2.0', 'deprecated': False}, - 'sane-exception': {'id': 'SANE-exception', 'deprecated': False}, - 'shl-2.0': {'id': 'SHL-2.0', 'deprecated': False}, - 'shl-2.1': {'id': 'SHL-2.1', 'deprecated': False}, - 'stunnel-exception': {'id': 'stunnel-exception', 'deprecated': False}, - 'swi-exception': {'id': 'SWI-exception', 'deprecated': False}, - 'swift-exception': {'id': 'Swift-exception', 'deprecated': False}, - 'texinfo-exception': {'id': 'Texinfo-exception', 'deprecated': False}, - 'u-boot-exception-2.0': {'id': 'u-boot-exception-2.0', 'deprecated': False}, - 'ubdl-exception': {'id': 'UBDL-exception', 'deprecated': False}, - 'universal-foss-exception-1.0': {'id': 'Universal-FOSS-exception-1.0', 'deprecated': False}, - 'vsftpd-openssl-exception': {'id': 'vsftpd-openssl-exception', 'deprecated': False}, - 'wxwindows-exception-3.1': {'id': 'WxWindows-exception-3.1', 'deprecated': False}, - 'x11vnc-openssl-exception': {'id': 'x11vnc-openssl-exception', 'deprecated': False}, -} diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/markers.py b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/markers.py deleted file mode 100755 index 6284645..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/markers.py +++ /dev/null @@ -1,492 +0,0 @@ -# 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 annotations - -import operator -import os -import platform -import sys -from typing import AbstractSet, Callable, Literal, Mapping, TypedDict, Union, cast - -from ._parser import MarkerAtom, MarkerList, Op, Value, Variable -from ._parser import parse_marker as _parse_marker -from ._tokenizer import ParserSyntaxError -from .specifiers import InvalidSpecifier, Specifier -from .utils import canonicalize_name - -__all__ = [ - "Environment", - "EvaluateContext", - "InvalidMarker", - "Marker", - "UndefinedComparison", - "UndefinedEnvironmentName", - "default_environment", -] - - -def __dir__() -> list[str]: - return __all__ - - -Operator = Callable[[str, Union[str, AbstractSet[str]]], bool] -EvaluateContext = Literal["metadata", "lock_file", "requirement"] -"""A ``typing.Literal`` enumerating valid marker evaluation contexts. - -Valid values for the ``context`` passed to :meth:`Marker.evaluate` are: - -* ``"metadata"`` (for core metadata; default) -* ``"lock_file"`` (for lock files) -* ``"requirement"`` (i.e. all other situations) -""" - -MARKERS_ALLOWING_SET = {"extras", "dependency_groups"} -MARKERS_REQUIRING_VERSION = { - "implementation_version", - "platform_release", - "python_full_version", - "python_version", -} - - -class InvalidMarker(ValueError): - """Raised when attempting to create a :class:`Marker` from invalid input. - - This error indicates that the given marker string does not conform to the - :ref:`specification of dependency specifiers `. - """ - - -class UndefinedComparison(ValueError): - """Raised when evaluating an unsupported marker comparison. - - This can happen when marker values are compared as versions but do not - conform to the :ref:`specification of version specifiers - `. - """ - - -class UndefinedEnvironmentName(ValueError): - """Raised when evaluating a marker that references a missing environment key.""" - - -class Environment(TypedDict): - """ - A dictionary that represents a Python environment as captured by - :func:`default_environment`. All fields are required. - """ - - implementation_name: str - """The implementation's identifier, e.g. ``'cpython'``.""" - - implementation_version: str - """ - The implementation's version, e.g. ``'3.13.0a2'`` for CPython 3.13.0a2, or - ``'7.3.13'`` for PyPy3.10 v7.3.13. - """ - - os_name: str - """ - The value of :py:data:`os.name`. The name of the operating system dependent module - imported, e.g. ``'posix'``. - """ - - platform_machine: str - """ - Returns the machine type, e.g. ``'i386'``. - - An empty string if the value cannot be determined. - """ - - platform_release: str - """ - The system's release, e.g. ``'2.2.0'`` or ``'NT'``. - - An empty string if the value cannot be determined. - """ - - platform_system: str - """ - The system/OS name, e.g. ``'Linux'``, ``'Windows'`` or ``'Java'``. - - An empty string if the value cannot be determined. - """ - - platform_version: str - """ - The system's release version, e.g. ``'#3 on degas'``. - - An empty string if the value cannot be determined. - """ - - python_full_version: str - """ - The Python version as string ``'major.minor.patchlevel'``. - - Note that unlike the Python :py:data:`sys.version`, this value will always include - the patchlevel (it defaults to 0). - """ - - platform_python_implementation: str - """ - A string identifying the Python implementation, e.g. ``'CPython'``. - """ - - python_version: str - """The Python version as string ``'major.minor'``.""" - - sys_platform: str - """ - This string contains a platform identifier that can be used to append - platform-specific components to :py:data:`sys.path`, for instance. - - For Unix systems, except on Linux and AIX, this is the lowercased OS name as - returned by ``uname -s`` with the first part of the version as returned by - ``uname -r`` appended, e.g. ``'sunos5'`` or ``'freebsd8'``, at the time when Python - was built. - """ - - -def _normalize_extras( - result: MarkerList | MarkerAtom | str, -) -> MarkerList | MarkerAtom | str: - if not isinstance(result, tuple): - return result - - lhs, op, rhs = result - if isinstance(lhs, Variable) and lhs.value == "extra": - normalized_extra = canonicalize_name(rhs.value) - rhs = Value(normalized_extra) - elif isinstance(rhs, Variable) and rhs.value == "extra": - normalized_extra = canonicalize_name(lhs.value) - lhs = Value(normalized_extra) - return lhs, op, rhs - - -def _normalize_extra_values(results: MarkerList) -> MarkerList: - """ - Normalize extra values. - """ - - return [_normalize_extras(r) for r in results] - - -def _format_marker( - marker: list[str] | MarkerAtom | str, first: bool | None = True -) -> str: - assert isinstance(marker, (list, tuple, str)) - - # 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: dict[str, Operator] = { - "in": lambda lhs, rhs: lhs in rhs, - "not in": lambda lhs, rhs: lhs not in rhs, - "<": lambda _lhs, _rhs: False, - "<=": operator.eq, - "==": operator.eq, - "!=": operator.ne, - ">=": operator.eq, - ">": lambda _lhs, _rhs: False, -} - - -def _eval_op(lhs: str, op: Op, rhs: str | AbstractSet[str], *, key: str) -> bool: - op_str = op.serialize() - if key in MARKERS_REQUIRING_VERSION: - try: - spec = Specifier(f"{op_str}{rhs}") - except InvalidSpecifier: - pass - else: - return spec.contains(lhs, prereleases=True) - - oper: Operator | None = _operators.get(op_str) - if oper is None: - raise UndefinedComparison(f"Undefined {op!r} on {lhs!r} and {rhs!r}.") - - return oper(lhs, rhs) - - -def _normalize( - lhs: str, rhs: str | AbstractSet[str], key: str -) -> tuple[str, str | AbstractSet[str]]: - # PEP 685 - Comparison of extra names for optional distribution dependencies - # https://peps.python.org/pep-0685/ - # > When comparing extra names, tools MUST normalize the names being - # > compared using the semantics outlined in PEP 503 for names - if key == "extra": - assert isinstance(rhs, str), "extra value must be a string" - # Both sides are normalized at this point already - return (lhs, rhs) - if key in MARKERS_ALLOWING_SET: - if isinstance(rhs, str): # pragma: no cover - return (canonicalize_name(lhs), canonicalize_name(rhs)) - else: - return (canonicalize_name(lhs), {canonicalize_name(v) for v in rhs}) - - # other environment markers don't have such standards - return lhs, rhs - - -def _evaluate_markers( - markers: MarkerList, environment: dict[str, str | AbstractSet[str]] -) -> bool: - groups: list[list[bool]] = [[]] - - for marker in markers: - if isinstance(marker, list): - groups[-1].append(_evaluate_markers(marker, environment)) - elif isinstance(marker, tuple): - lhs, op, rhs = marker - - if isinstance(lhs, Variable): - environment_key = lhs.value - lhs_value = environment[environment_key] - rhs_value = rhs.value - else: - lhs_value = lhs.value - environment_key = rhs.value - rhs_value = environment[environment_key] - - assert isinstance(lhs_value, str), "lhs must be a string" - lhs_value, rhs_value = _normalize(lhs_value, rhs_value, key=environment_key) - groups[-1].append(_eval_op(lhs_value, op, rhs_value, key=environment_key)) - elif marker == "or": - groups.append([]) - elif marker == "and": - pass - else: # pragma: nocover - raise TypeError(f"Unexpected marker {marker!r}") - - return any(all(item) for item in groups) - - -def _format_full_version(info: sys._version_info) -> str: - version = f"{info.major}.{info.minor}.{info.micro}" - kind = info.releaselevel - if kind != "final": - version += kind[0] + str(info.serial) - return version - - -def default_environment() -> Environment: - """Return the default marker environment for the current Python process. - - This is the base environment used by :meth:`Marker.evaluate`. - """ - iver = _format_full_version(sys.implementation.version) - implementation_name = sys.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": ".".join(platform.python_version_tuple()[:2]), - "sys_platform": sys.platform, - } - - -class Marker: - """Represents a parsed dependency marker expression. - - Marker expressions are parsed according to the - :ref:`specification of dependency specifiers `. - - :param marker: The string representation of a marker expression. - :raises InvalidMarker: If ``marker`` cannot be parsed. - - Instances are safe to serialize with :mod:`pickle`. They use a stable - format so the same pickle can be loaded in future packaging releases. - - .. versionchanged:: 26.2 - - Added a stable pickle format. Pickles created with packaging 26.2+ can - be unpickled with future releases. Backward compatibility with pickles - from pip._vendor.packaging < 26.2 is supported but may be removed in a future - release. - """ - - __slots__ = ("_markers",) - - def __init__(self, marker: str) -> None: - # Note: We create a Marker object without calling this constructor in - # packaging.requirements.Requirement. If any additional logic is - # added here, make sure to mirror/adapt Requirement. - - # If this fails and throws an error, the repr still expects _markers to - # be defined. - self._markers: MarkerList = [] - - try: - self._markers = _normalize_extra_values(_parse_marker(marker)) - # The attribute `_markers` can be described in terms of a recursive type: - # MarkerList = List[Union[Tuple[Node, ...], str, MarkerList]] - # - # For example, the following expression: - # python_version > "3.6" or (python_version == "3.6" and os_name == "unix") - # - # is parsed into: - # [ - # (, ')>, ), - # 'and', - # [ - # (, , ), - # 'or', - # (, , ) - # ] - # ] - except ParserSyntaxError as e: - raise InvalidMarker(str(e)) from e - - @classmethod - def _from_markers(cls, markers: MarkerList) -> Marker: - """Create a Marker instance from a pre-parsed marker tree. - - This avoids re-parsing serialised marker strings when combining markers. - """ - new = cls.__new__(cls) - new._markers = markers - return new - - def __str__(self) -> str: - return _format_marker(self._markers) - - def __repr__(self) -> str: - return f"<{self.__class__.__name__}({str(self)!r})>" - - def __hash__(self) -> int: - return hash(str(self)) - - def __eq__(self, other: object) -> bool: - if not isinstance(other, Marker): - return NotImplemented - - return str(self) == str(other) - - def __getstate__(self) -> str: - # Return the marker expression string for compactness and stability. - # Internal Node objects are excluded; the string is re-parsed on load. - return str(self) - - def __setstate__(self, state: object) -> None: - if isinstance(state, str): - # New format (26.2+): just the marker expression string. - try: - self._markers = _normalize_extra_values(_parse_marker(state)) - except ParserSyntaxError as exc: - raise TypeError(f"Cannot restore Marker from {state!r}") from exc - return - if isinstance(state, dict) and "_markers" in state: - # Old format (packaging <= 26.1, no __slots__): plain __dict__. - markers = state["_markers"] - if isinstance(markers, list): - self._markers = markers - return - if isinstance(state, tuple) and len(state) == 2: - # Old format (packaging <= 26.1, __slots__): (None, {slot: value}). - _, slot_dict = state - if isinstance(slot_dict, dict) and "_markers" in slot_dict: - markers = slot_dict["_markers"] - if isinstance(markers, list): - self._markers = markers - return - raise TypeError(f"Cannot restore Marker from {state!r}") - - def __and__(self, other: Marker) -> Marker: - if not isinstance(other, Marker): - return NotImplemented - return self._from_markers([self._markers, "and", other._markers]) - - def __or__(self, other: Marker) -> Marker: - if not isinstance(other, Marker): - return NotImplemented - return self._from_markers([self._markers, "or", other._markers]) - - def evaluate( - self, - environment: Mapping[str, str | AbstractSet[str]] | None = None, - context: EvaluateContext = "metadata", - ) -> bool: - """Evaluate a marker. - - Return the boolean from evaluating this marker against the environment. - The environment is determined from the current Python process unless - passed in explicitly. - - :param environment: Mapping containing keys and values to override the - detected environment. - :param EvaluateContext context: The context in which the marker is - evaluated, which influences what marker names are considered valid. - Accepted values are ``"metadata"`` (for core metadata; default), - ``"lock_file"``, and ``"requirement"`` (i.e. all other situations). - :raises UndefinedComparison: If the marker uses a comparison on values - that are not valid versions per the :ref:`specification of version - specifiers `. - :raises UndefinedEnvironmentName: If the marker references a value that - is missing from the evaluation environment. - :returns: ``True`` if the marker matches, otherwise ``False``. - - """ - current_environment = cast( - "dict[str, str | AbstractSet[str]]", default_environment() - ) - if context == "lock_file": - current_environment.update( - extras=frozenset(), dependency_groups=frozenset() - ) - elif context == "metadata": - current_environment["extra"] = "" - - if environment is not None: - current_environment.update(environment) - if "extra" in current_environment: - # The API used to allow setting extra to None. We need to handle - # this case for backwards compatibility. Also skip running - # normalize name if extra is empty. - extra = cast("str | None", current_environment["extra"]) - current_environment["extra"] = canonicalize_name(extra) if extra else "" - - return _evaluate_markers( - self._markers, _repair_python_full_version(current_environment) - ) - - -def _repair_python_full_version( - env: dict[str, str | AbstractSet[str]], -) -> dict[str, str | AbstractSet[str]]: - """ - Work around platform.python_version() returning something that is not PEP 440 - compliant for non-tagged Python builds. - """ - python_full_version = cast("str", env["python_full_version"]) - if python_full_version.endswith("+"): - env["python_full_version"] = f"{python_full_version}local" - return env diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/metadata.py b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/metadata.py deleted file mode 100755 index dccb627..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/metadata.py +++ /dev/null @@ -1,964 +0,0 @@ -from __future__ import annotations - -import email.header -import email.message -import email.parser -import email.policy -import keyword -import pathlib -import typing -from typing import ( - Any, - Callable, - Generic, - Literal, - TypedDict, - cast, -) - -from . import licenses, requirements, specifiers, utils -from . import version as version_module -from .errors import ExceptionGroup, _ErrorCollector - -if typing.TYPE_CHECKING: - from .licenses import NormalizedLicenseExpression - -T = typing.TypeVar("T") - - -__all__ = [ - "ExceptionGroup", # Keep this for a bit (makes mypy happy w/ 26.0 compat) - "InvalidMetadata", - "Metadata", - "RFC822Message", - "RFC822Policy", - "RawMetadata", - "parse_email", -] - - -def __dir__() -> list[str]: - return __all__ - - -class InvalidMetadata(ValueError): - """A metadata field contains invalid data.""" - - field: str - """The name of the field that contains invalid data.""" - - def __init__(self, field: str, message: str) -> None: - self.field = field - super().__init__(message) - - -# The RawMetadata class attempts to make as few assumptions about the underlying -# serialization formats as possible. The idea is that as long as a serialization -# formats offer some very basic primitives in *some* way then we can support -# serializing to and from that format. -class RawMetadata(TypedDict, total=False): - """A dictionary of raw core metadata. - - Each field in core metadata maps to a key of this dictionary (when data is - provided). The key is lower-case and underscores are used instead of dashes - compared to the equivalent core metadata field. Any core metadata field that - can be specified multiple times or can hold multiple values in a single - field have a key with a plural name. See :class:`Metadata` whose attributes - match the keys of this dictionary. - - Core metadata fields that can be specified multiple times are stored as a - list or dict depending on which is appropriate for the field. Any fields - which hold multiple values in a single field are stored as a list. All fields - are considered optional. - """ - - # Metadata 1.0 - PEP 241 - metadata_version: str - name: str - version: str - platforms: list[str] - summary: str - description: str - keywords: list[str] - home_page: str - author: str - author_email: str - license: str - - # Metadata 1.1 - PEP 314 - supported_platforms: list[str] - download_url: str - classifiers: list[str] - requires: list[str] - provides: list[str] - obsoletes: list[str] - - # Metadata 1.2 - PEP 345 - maintainer: str - maintainer_email: str - requires_dist: list[str] - provides_dist: list[str] - obsoletes_dist: list[str] - requires_python: str - requires_external: list[str] - project_urls: dict[str, str] - - # Metadata 2.0 - # PEP 426 attempted to completely revamp the metadata format - # but got stuck without ever being able to build consensus on - # it and ultimately ended up withdrawn. - # - # However, a number of tools had started emitting METADATA with - # `2.0` Metadata-Version, so for historical reasons, this version - # was skipped. - - # Metadata 2.1 - PEP 566 - description_content_type: str - provides_extra: list[str] - - # Metadata 2.2 - PEP 643 - dynamic: list[str] - - # Metadata 2.3 - PEP 685 - # No new fields were added in PEP 685, just some edge case were - # tightened up to provide better interoperability. - - # Metadata 2.4 - PEP 639 - license_expression: str - license_files: list[str] - - # Metadata 2.5 - PEP 794 - import_names: list[str] - import_namespaces: list[str] - - -# 'keywords' is special as it's a string in the core metadata spec, but we -# represent it as a list. -_STRING_FIELDS = { - "author", - "author_email", - "description", - "description_content_type", - "download_url", - "home_page", - "license", - "license_expression", - "maintainer", - "maintainer_email", - "metadata_version", - "name", - "requires_python", - "summary", - "version", -} - -_LIST_FIELDS = { - "classifiers", - "dynamic", - "license_files", - "obsoletes", - "obsoletes_dist", - "platforms", - "provides", - "provides_dist", - "provides_extra", - "requires", - "requires_dist", - "requires_external", - "supported_platforms", - "import_names", - "import_namespaces", -} - -_DICT_FIELDS = { - "project_urls", -} - - -def _parse_keywords(data: str) -> list[str]: - """Split a string of comma-separated keywords into a list of keywords.""" - return [k.strip() for k in data.split(",")] - - -def _parse_project_urls(data: list[str]) -> dict[str, str]: - """Parse a list of label/URL string pairings separated by a comma.""" - urls = {} - for pair in data: - # Our logic is slightly tricky here as we want to try and do - # *something* reasonable with malformed data. - # - # The main thing that we have to worry about, is data that does - # not have a ',' at all to split the label from the Value. There - # isn't a singular right answer here, and we will fail validation - # later on (if the caller is validating) so it doesn't *really* - # matter, but since the missing value has to be an empty str - # and our return value is dict[str, str], if we let the key - # be the missing value, then they'd have multiple '' values that - # overwrite each other in a accumulating dict. - # - # The other potential issue is that it's possible to have the - # same label multiple times in the metadata, with no solid "right" - # answer with what to do in that case. As such, we'll do the only - # thing we can, which is treat the field as unparsable and add it - # to our list of unparsed fields. - # - # TODO: The spec doesn't say anything about if the keys should be - # considered case sensitive or not... logically they should - # be case-preserving and case-insensitive, but doing that - # would open up more cases where we might have duplicate - # entries. - label, _, url = (s.strip() for s in pair.partition(",")) - - if label in urls: - # The label already exists in our set of urls, so this field - # is unparsable, and we can just add the whole thing to our - # unparsable data and stop processing it. - raise KeyError("duplicate labels in project urls") - urls[label] = url - - return urls - - -def _get_payload(msg: email.message.Message, source: bytes | str) -> str: - """Get the body of the message.""" - # If our source is a str, then our caller has managed encodings for us, - # and we don't need to deal with it. - if isinstance(source, str): - payload = msg.get_payload() - assert isinstance(payload, str) - return payload - # If our source is a bytes, then we're managing the encoding and we need - # to deal with it. - else: - bpayload = msg.get_payload(decode=True) - assert isinstance(bpayload, bytes) - try: - return bpayload.decode("utf8", "strict") - except UnicodeDecodeError as exc: - raise ValueError("payload in an invalid encoding") from exc - - -# The various parse_FORMAT functions here are intended to be as lenient as -# possible in their parsing, while still returning a correctly typed -# RawMetadata. -# -# To aid in this, we also generally want to do as little touching of the -# data as possible, except where there are possibly some historic holdovers -# that make valid data awkward to work with. -# -# While this is a lower level, intermediate format than our ``Metadata`` -# class, some light touch ups can make a massive difference in usability. - -# Map METADATA fields to RawMetadata. -_EMAIL_TO_RAW_MAPPING = { - "author": "author", - "author-email": "author_email", - "classifier": "classifiers", - "description": "description", - "description-content-type": "description_content_type", - "download-url": "download_url", - "dynamic": "dynamic", - "home-page": "home_page", - "import-name": "import_names", - "import-namespace": "import_namespaces", - "keywords": "keywords", - "license": "license", - "license-expression": "license_expression", - "license-file": "license_files", - "maintainer": "maintainer", - "maintainer-email": "maintainer_email", - "metadata-version": "metadata_version", - "name": "name", - "obsoletes": "obsoletes", - "obsoletes-dist": "obsoletes_dist", - "platform": "platforms", - "project-url": "project_urls", - "provides": "provides", - "provides-dist": "provides_dist", - "provides-extra": "provides_extra", - "requires": "requires", - "requires-dist": "requires_dist", - "requires-external": "requires_external", - "requires-python": "requires_python", - "summary": "summary", - "supported-platform": "supported_platforms", - "version": "version", -} -_RAW_TO_EMAIL_MAPPING = {raw: email for email, raw in _EMAIL_TO_RAW_MAPPING.items()} - - -# This class is for writing RFC822 messages -class RFC822Policy(email.policy.EmailPolicy): - """ - This is :class:`email.policy.EmailPolicy`, but with a simple ``header_store_parse`` - implementation that handles multi-line values, and some nice defaults. - """ - - utf8 = True - mangle_from_ = False - max_line_length = 0 - - def header_store_parse(self, name: str, value: str) -> tuple[str, str]: - size = len(name) + 2 - value = value.replace("\n", "\n" + " " * size) - return (name, value) - - -# This class is for writing RFC822 messages -class RFC822Message(email.message.EmailMessage): - """ - This is :class:`email.message.EmailMessage` with two small changes: it defaults to - our `RFC822Policy`, and it correctly writes unicode when being called - with `bytes()`. - """ - - def __init__(self) -> None: - super().__init__(policy=RFC822Policy()) - - def as_bytes( - self, unixfrom: bool = False, policy: email.policy.Policy | None = None - ) -> bytes: - """ - Return the bytes representation of the message. - - This handles unicode encoding. - """ - return self.as_string(unixfrom, policy=policy).encode("utf-8") - - -def parse_email(data: bytes | str) -> tuple[RawMetadata, dict[str, list[str]]]: - """Parse a distribution's metadata stored as email headers (e.g. from ``METADATA``). - - This function returns a two-item tuple of dicts. The first dict is of - recognized fields from the core metadata specification. Fields that can be - parsed and translated into Python's built-in types are converted - appropriately. All other fields are left as-is. Fields that are allowed to - appear multiple times are stored as lists. - - The second dict contains all other fields from the metadata. This includes - any unrecognized fields. It also includes any fields which are expected to - be parsed into a built-in type but were not formatted appropriately. Finally, - any fields that are expected to appear only once but are repeated are - included in this dict. - - """ - raw: dict[str, str | list[str] | dict[str, str]] = {} - unparsed: dict[str, list[str]] = {} - - if isinstance(data, str): - parsed = email.parser.Parser(policy=email.policy.compat32).parsestr(data) - else: - parsed = email.parser.BytesParser(policy=email.policy.compat32).parsebytes(data) - - # We have to wrap parsed.keys() in a set, because in the case of multiple - # values for a key (a list), the key will appear multiple times in the - # list of keys, but we're avoiding that by using get_all(). - for name_with_case in frozenset(parsed.keys()): - # Header names in RFC are case insensitive, so we'll normalize to all - # lower case to make comparisons easier. - name = name_with_case.lower() - - # We use get_all() here, even for fields that aren't multiple use, - # because otherwise someone could have e.g. two Name fields, and we - # would just silently ignore it rather than doing something about it. - headers = parsed.get_all(name) or [] - - # The way the email module works when parsing bytes is that it - # unconditionally decodes the bytes as ascii using the surrogateescape - # handler. When you pull that data back out (such as with get_all() ), - # it looks to see if the str has any surrogate escapes, and if it does - # it wraps it in a Header object instead of returning the string. - # - # As such, we'll look for those Header objects, and fix up the encoding. - value = [] - # Flag if we have run into any issues processing the headers, thus - # signalling that the data belongs in 'unparsed'. - valid_encoding = True - for h in headers: - # It's unclear if this can return more types than just a Header or - # a str, so we'll just assert here to make sure. - assert isinstance(h, (email.header.Header, str)) - - # If it's a header object, we need to do our little dance to get - # the real data out of it. In cases where there is invalid data - # we're going to end up with mojibake, but there's no obvious, good - # way around that without reimplementing parts of the Header object - # ourselves. - # - # That should be fine since, if mojibacked happens, this key is - # going into the unparsed dict anyways. - if isinstance(h, email.header.Header): - # The Header object stores it's data as chunks, and each chunk - # can be independently encoded, so we'll need to check each - # of them. - chunks: list[tuple[bytes, str | None]] = [] - for binary, _encoding in email.header.decode_header(h): - try: - binary.decode("utf8", "strict") - except UnicodeDecodeError: - # Enable mojibake. - encoding = "latin1" - valid_encoding = False - else: - encoding = "utf8" - chunks.append((binary, encoding)) - - # Turn our chunks back into a Header object, then let that - # Header object do the right thing to turn them into a - # string for us. - value.append(str(email.header.make_header(chunks))) - # This is already a string, so just add it. - else: - value.append(h) - - # We've processed all of our values to get them into a list of str, - # but we may have mojibake data, in which case this is an unparsed - # field. - if not valid_encoding: - unparsed[name] = value - continue - - raw_name = _EMAIL_TO_RAW_MAPPING.get(name) - if raw_name is None: - # This is a bit of a weird situation, we've encountered a key that - # we don't know what it means, so we don't know whether it's meant - # to be a list or not. - # - # Since we can't really tell one way or another, we'll just leave it - # as a list, even though it may be a single item list, because that's - # what makes the most sense for email headers. - unparsed[name] = value - continue - - # If this is one of our string fields, then we'll check to see if our - # value is a list of a single item. If it is then we'll assume that - # it was emitted as a single string, and unwrap the str from inside - # the list. - # - # If it's any other kind of data, then we haven't the faintest clue - # what we should parse it as, and we have to just add it to our list - # of unparsed stuff. - if raw_name in _STRING_FIELDS and len(value) == 1: - raw[raw_name] = value[0] - # If this is import_names, we need to special case the empty field - # case, which converts to an empty list instead of None. We can't let - # the empty case slip through, as it will fail validation. - elif raw_name == "import_names" and value == [""]: - raw[raw_name] = [] - # If this is one of our list of string fields, then we can just assign - # the value, since email *only* has strings, and our get_all() call - # above ensures that this is a list. - elif raw_name in _LIST_FIELDS: - raw[raw_name] = value - # Special Case: Keywords - # The keywords field is implemented in the metadata spec as a str, - # but it conceptually is a list of strings, and is serialized using - # ", ".join(keywords), so we'll do some light data massaging to turn - # this into what it logically is. - elif raw_name == "keywords" and len(value) == 1: - raw[raw_name] = _parse_keywords(value[0]) - # Special Case: Project-URL - # The project urls is implemented in the metadata spec as a list of - # specially-formatted strings that represent a key and a value, which - # is fundamentally a mapping, however the email format doesn't support - # mappings in a sane way, so it was crammed into a list of strings - # instead. - # - # We will do a little light data massaging to turn this into a map as - # it logically should be. - elif raw_name == "project_urls": - try: - raw[raw_name] = _parse_project_urls(value) - except KeyError: - unparsed[name] = value - # Nothing that we've done has managed to parse this, so it'll just - # throw it in our unparsable data and move on. - else: - unparsed[name] = value - - # We need to support getting the Description from the message payload in - # addition to getting it from the the headers. This does mean, though, there - # is the possibility of it being set both ways, in which case we put both - # in 'unparsed' since we don't know which is right. - try: - payload = _get_payload(parsed, data) - except ValueError: - unparsed.setdefault("description", []).append( - parsed.get_payload(decode=isinstance(data, bytes)) # type: ignore[call-overload] - ) - else: - if payload: - # Check to see if we've already got a description, if so then both - # it, and this body move to unparsable. - if "description" in raw: - description_header = cast("str", raw.pop("description")) - unparsed.setdefault("description", []).extend( - [description_header, payload] - ) - elif "description" in unparsed: - unparsed["description"].append(payload) - else: - raw["description"] = payload - - # We need to cast our `raw` to a metadata, because a TypedDict only support - # literal key names, but we're computing our key names on purpose, but the - # way this function is implemented, our `TypedDict` can only have valid key - # names. - return cast("RawMetadata", raw), unparsed - - -_NOT_FOUND = object() - - -# Keep the two values in sync. -_VALID_METADATA_VERSIONS = ["1.0", "1.1", "1.2", "2.1", "2.2", "2.3", "2.4", "2.5"] -_MetadataVersion = Literal["1.0", "1.1", "1.2", "2.1", "2.2", "2.3", "2.4", "2.5"] - -_REQUIRED_ATTRS = frozenset(["metadata_version", "name", "version"]) - - -class _Validator(Generic[T]): - """Validate a metadata field. - - All _process_*() methods correspond to a core metadata field. The method is - called with the field's raw value. If the raw value is valid it is returned - in its "enriched" form (e.g. ``version.Version`` for the ``Version`` field). - If the raw value is invalid, :exc:`InvalidMetadata` is raised (with a cause - as appropriate). - """ - - name: str - raw_name: str - added: _MetadataVersion - - def __init__( - self, - *, - added: _MetadataVersion = "1.0", - ) -> None: - self.added = added - - def __set_name__(self, _owner: Metadata, name: str) -> None: - self.name = name - self.raw_name = _RAW_TO_EMAIL_MAPPING[name] - - def __get__(self, instance: Metadata, _owner: type[Metadata]) -> T: - # With Python 3.8, the caching can be replaced with functools.cached_property(). - # No need to check the cache as attribute lookup will resolve into the - # instance's __dict__ before __get__ is called. - cache = instance.__dict__ - value = instance._raw.get(self.name) - - # To make the _process_* methods easier, we'll check if the value is None - # and if this field is NOT a required attribute, and if both of those - # things are true, we'll skip the the converter. This will mean that the - # converters never have to deal with the None union. - if self.name in _REQUIRED_ATTRS or value is not None: - try: - converter: Callable[[Any], T] = getattr(self, f"_process_{self.name}") - except AttributeError: - pass - else: - value = converter(value) - - cache[self.name] = value - try: - del instance._raw[self.name] # type: ignore[misc] - except KeyError: - pass - - return cast("T", value) - - def _invalid_metadata( - self, msg: str, cause: Exception | None = None - ) -> InvalidMetadata: - exc = InvalidMetadata( - self.raw_name, msg.format_map({"field": repr(self.raw_name)}) - ) - exc.__cause__ = cause - return exc - - def _process_metadata_version(self, value: str) -> _MetadataVersion: - # Implicitly makes Metadata-Version required. - if value not in _VALID_METADATA_VERSIONS: - raise self._invalid_metadata(f"{value!r} is not a valid metadata version") - return cast("_MetadataVersion", value) - - def _process_name(self, value: str) -> str: - if not value: - raise self._invalid_metadata("{field} is a required field") - # Validate the name as a side-effect. - try: - utils.canonicalize_name(value, validate=True) - except utils.InvalidName as exc: - raise self._invalid_metadata( - f"{value!r} is invalid for {{field}}", cause=exc - ) from exc - else: - return value - - def _process_version(self, value: str) -> version_module.Version: - if not value: - raise self._invalid_metadata("{field} is a required field") - try: - return version_module.parse(value) - except version_module.InvalidVersion as exc: - raise self._invalid_metadata( - f"{value!r} is invalid for {{field}}", cause=exc - ) from exc - - def _process_summary(self, value: str) -> str: - """Check the field contains no newlines.""" - if "\n" in value: - raise self._invalid_metadata("{field} must be a single line") - return value - - def _process_description_content_type(self, value: str) -> str: - content_types = {"text/plain", "text/x-rst", "text/markdown"} - message = email.message.EmailMessage() - message["content-type"] = value - - content_type, parameters = ( - # Defaults to `text/plain` if parsing failed. - message.get_content_type().lower(), - message["content-type"].params, - ) - # Check if content-type is valid or defaulted to `text/plain` and thus was - # not parseable. - if content_type not in content_types or content_type not in value.lower(): - raise self._invalid_metadata( - f"{{field}} must be one of {list(content_types)}, not {value!r}" - ) - - charset = parameters.get("charset", "UTF-8") - if charset != "UTF-8": - raise self._invalid_metadata( - f"{{field}} can only specify the UTF-8 charset, not {charset!r}" - ) - - markdown_variants = {"GFM", "CommonMark"} - variant = parameters.get("variant", "GFM") # Use an acceptable default. - if content_type == "text/markdown" and variant not in markdown_variants: - raise self._invalid_metadata( - f"valid Markdown variants for {{field}} are {list(markdown_variants)}, " - f"not {variant!r}", - ) - return value - - def _process_dynamic(self, value: list[str]) -> list[str]: - for dynamic_field in map(str.lower, value): - if dynamic_field in {"name", "version", "metadata-version"}: - raise self._invalid_metadata( - f"{dynamic_field!r} is not allowed as a dynamic field" - ) - elif dynamic_field not in _EMAIL_TO_RAW_MAPPING: - raise self._invalid_metadata( - f"{dynamic_field!r} is not a valid dynamic field" - ) - return list(map(str.lower, value)) - - def _process_provides_extra( - self, - value: list[str], - ) -> list[utils.NormalizedName]: - normalized_names = [] - try: - for name in value: - normalized_names.append(utils.canonicalize_name(name, validate=True)) - except utils.InvalidName as exc: - raise self._invalid_metadata( - f"{name!r} is invalid for {{field}}", cause=exc - ) from exc - else: - return normalized_names - - def _process_requires_python(self, value: str) -> specifiers.SpecifierSet: - try: - return specifiers.SpecifierSet(value) - except specifiers.InvalidSpecifier as exc: - raise self._invalid_metadata( - f"{value!r} is invalid for {{field}}", cause=exc - ) from exc - - def _process_requires_dist( - self, - value: list[str], - ) -> list[requirements.Requirement]: - reqs = [] - try: - for req in value: - reqs.append(requirements.Requirement(req)) - except requirements.InvalidRequirement as exc: - raise self._invalid_metadata( - f"{req!r} is invalid for {{field}}", cause=exc - ) from exc - else: - return reqs - - def _process_license_expression(self, value: str) -> NormalizedLicenseExpression: - try: - return licenses.canonicalize_license_expression(value) - except ValueError as exc: - raise self._invalid_metadata( - f"{value!r} is invalid for {{field}}", cause=exc - ) from exc - - def _process_license_files(self, value: list[str]) -> list[str]: - paths = [] - for path in value: - if ".." in path: - raise self._invalid_metadata( - f"{path!r} is invalid for {{field}}, " - "parent directory indicators are not allowed" - ) - if "*" in path: - raise self._invalid_metadata( - f"{path!r} is invalid for {{field}}, paths must be resolved" - ) - if ( - pathlib.PurePosixPath(path).is_absolute() - or pathlib.PureWindowsPath(path).is_absolute() - ): - raise self._invalid_metadata( - f"{path!r} is invalid for {{field}}, paths must be relative" - ) - if pathlib.PureWindowsPath(path).as_posix() != path: - raise self._invalid_metadata( - f"{path!r} is invalid for {{field}}, paths must use '/' delimiter" - ) - paths.append(path) - return paths - - def _process_import_names(self, value: list[str]) -> list[str]: - for import_name in value: - name, semicolon, private = import_name.partition(";") - name = name.rstrip() - for identifier in name.split("."): - if not identifier.isidentifier(): - raise self._invalid_metadata( - f"{name!r} is invalid for {{field}}; " - f"{identifier!r} is not a valid identifier" - ) - elif keyword.iskeyword(identifier): - raise self._invalid_metadata( - f"{name!r} is invalid for {{field}}; " - f"{identifier!r} is a keyword" - ) - if semicolon and private.lstrip() != "private": - raise self._invalid_metadata( - f"{import_name!r} is invalid for {{field}}; " - "the only valid option is 'private'" - ) - return value - - _process_import_namespaces = _process_import_names - - -class Metadata: - """Representation of distribution metadata. - - Compared to :class:`RawMetadata`, this class provides objects representing - metadata fields instead of only using built-in types. Any invalid metadata - will cause :exc:`InvalidMetadata` to be raised (with a - :py:attr:`~BaseException.__cause__` attribute as appropriate). - """ - - _raw: RawMetadata - - @classmethod - def from_raw(cls, data: RawMetadata, *, validate: bool = True) -> Metadata: - """Create an instance from :class:`RawMetadata`. - - If *validate* is true, all metadata will be validated. All exceptions - related to validation will be gathered and raised as an :class:`ExceptionGroup`. - """ - ins = cls() - ins._raw = data.copy() # Mutations occur due to caching enriched values. - - if validate: - collector = _ErrorCollector() - metadata_version = None - with collector.collect(InvalidMetadata): - metadata_version = ins.metadata_version - metadata_age = _VALID_METADATA_VERSIONS.index(metadata_version) - - # Make sure to check for the fields that are present, the required - # fields (so their absence can be reported). - fields_to_check = frozenset(ins._raw) | _REQUIRED_ATTRS - # Remove fields that have already been checked. - fields_to_check -= {"metadata_version"} - - for key in fields_to_check: - try: - if metadata_version: - # Can't use getattr() as that triggers descriptor protocol which - # will fail due to no value for the instance argument. - try: - field_metadata_version = cls.__dict__[key].added - except KeyError: - exc = InvalidMetadata(key, f"unrecognized field: {key!r}") - collector.error(exc) - continue - field_age = _VALID_METADATA_VERSIONS.index( - field_metadata_version - ) - if field_age > metadata_age: - field = _RAW_TO_EMAIL_MAPPING[key] - exc = InvalidMetadata( - field, - f"{field} introduced in metadata version " - f"{field_metadata_version}, not {metadata_version}", - ) - collector.error(exc) - continue - getattr(ins, key) - except InvalidMetadata as exc: - collector.error(exc) - - collector.finalize("invalid metadata") - - return ins - - @classmethod - def from_email(cls, data: bytes | str, *, validate: bool = True) -> Metadata: - """Parse metadata from email headers. - - If *validate* is true, the metadata will be validated. All exceptions - related to validation will be gathered and raised as an :class:`ExceptionGroup`. - """ - raw, unparsed = parse_email(data) - - if validate: - with _ErrorCollector().on_exit("unparsed") as collector: - for unparsed_key in unparsed: - if unparsed_key in _EMAIL_TO_RAW_MAPPING: - message = f"{unparsed_key!r} has invalid data" - else: - message = f"unrecognized field: {unparsed_key!r}" - collector.error(InvalidMetadata(unparsed_key, message)) - - try: - return cls.from_raw(raw, validate=validate) - except ExceptionGroup as exc_group: - raise ExceptionGroup( - "invalid or unparsed metadata", exc_group.exceptions - ) from None - - metadata_version: _Validator[_MetadataVersion] = _Validator() - """:external:ref:`core-metadata-metadata-version` - (required; validated to be a valid metadata version)""" - # `name` is not normalized/typed to NormalizedName so as to provide access to - # the original/raw name. - name: _Validator[str] = _Validator() - """:external:ref:`core-metadata-name` - (required; validated using :func:`~packaging.utils.canonicalize_name` and its - *validate* parameter)""" - version: _Validator[version_module.Version] = _Validator() - """:external:ref:`core-metadata-version` (required)""" - dynamic: _Validator[list[str] | None] = _Validator( - added="2.2", - ) - """:external:ref:`core-metadata-dynamic` - (validated against core metadata field names and lowercased)""" - platforms: _Validator[list[str] | None] = _Validator() - """:external:ref:`core-metadata-platform`""" - supported_platforms: _Validator[list[str] | None] = _Validator(added="1.1") - """:external:ref:`core-metadata-supported-platform`""" - summary: _Validator[str | None] = _Validator() - """:external:ref:`core-metadata-summary` (validated to contain no newlines)""" - description: _Validator[str | None] = _Validator() # TODO 2.1: can be in body - """:external:ref:`core-metadata-description`""" - description_content_type: _Validator[str | None] = _Validator(added="2.1") - """:external:ref:`core-metadata-description-content-type` (validated)""" - keywords: _Validator[list[str] | None] = _Validator() - """:external:ref:`core-metadata-keywords`""" - home_page: _Validator[str | None] = _Validator() - """:external:ref:`core-metadata-home-page`""" - download_url: _Validator[str | None] = _Validator(added="1.1") - """:external:ref:`core-metadata-download-url`""" - author: _Validator[str | None] = _Validator() - """:external:ref:`core-metadata-author`""" - author_email: _Validator[str | None] = _Validator() - """:external:ref:`core-metadata-author-email`""" - maintainer: _Validator[str | None] = _Validator(added="1.2") - """:external:ref:`core-metadata-maintainer`""" - maintainer_email: _Validator[str | None] = _Validator(added="1.2") - """:external:ref:`core-metadata-maintainer-email`""" - license: _Validator[str | None] = _Validator() - """:external:ref:`core-metadata-license`""" - license_expression: _Validator[NormalizedLicenseExpression | None] = _Validator( - added="2.4" - ) - """:external:ref:`core-metadata-license-expression`""" - license_files: _Validator[list[str] | None] = _Validator(added="2.4") - """:external:ref:`core-metadata-license-file`""" - classifiers: _Validator[list[str] | None] = _Validator(added="1.1") - """:external:ref:`core-metadata-classifier`""" - requires_dist: _Validator[list[requirements.Requirement] | None] = _Validator( - added="1.2" - ) - """:external:ref:`core-metadata-requires-dist`""" - requires_python: _Validator[specifiers.SpecifierSet | None] = _Validator( - added="1.2" - ) - """:external:ref:`core-metadata-requires-python`""" - # Because `Requires-External` allows for non-PEP 440 version specifiers, we - # don't do any processing on the values. - requires_external: _Validator[list[str] | None] = _Validator(added="1.2") - """:external:ref:`core-metadata-requires-external`""" - project_urls: _Validator[dict[str, str] | None] = _Validator(added="1.2") - """:external:ref:`core-metadata-project-url`""" - # PEP 685 lets us raise an error if an extra doesn't pass `Name` validation - # regardless of metadata version. - provides_extra: _Validator[list[utils.NormalizedName] | None] = _Validator( - added="2.1", - ) - """:external:ref:`core-metadata-provides-extra`""" - provides_dist: _Validator[list[str] | None] = _Validator(added="1.2") - """:external:ref:`core-metadata-provides-dist`""" - obsoletes_dist: _Validator[list[str] | None] = _Validator(added="1.2") - """:external:ref:`core-metadata-obsoletes-dist`""" - import_names: _Validator[list[str] | None] = _Validator(added="2.5") - """:external:ref:`core-metadata-import-name`""" - import_namespaces: _Validator[list[str] | None] = _Validator(added="2.5") - """:external:ref:`core-metadata-import-namespace`""" - requires: _Validator[list[str] | None] = _Validator(added="1.1") - """``Requires`` (deprecated)""" - provides: _Validator[list[str] | None] = _Validator(added="1.1") - """``Provides`` (deprecated)""" - obsoletes: _Validator[list[str] | None] = _Validator(added="1.1") - """``Obsoletes`` (deprecated)""" - - def as_rfc822(self) -> RFC822Message: - """ - Return an RFC822 message with the metadata. - """ - message = RFC822Message() - self._write_metadata(message) - return message - - def _write_metadata(self, message: RFC822Message) -> None: - """ - Return an RFC822 message with the metadata. - """ - for name, validator in self.__class__.__dict__.items(): - if isinstance(validator, _Validator) and name != "description": - value = getattr(self, name) - email_name = _RAW_TO_EMAIL_MAPPING[name] - if value is not None: - if email_name == "project-url": - for label, url in value.items(): - message[email_name] = f"{label}, {url}" - elif email_name == "keywords": - message[email_name] = ",".join(value) - elif email_name == "import-name" and value == []: - message[email_name] = "" - elif isinstance(value, list): - for item in value: - message[email_name] = str(item) - else: - message[email_name] = str(value) - - # The description is a special case because it is in the body of the message. - if self.description is not None: - message.set_payload(self.description) diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/py.typed b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/py.typed deleted file mode 100755 index e69de29..0000000 diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/pylock.py b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/pylock.py deleted file mode 100755 index 84e2537..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/pylock.py +++ /dev/null @@ -1,905 +0,0 @@ -from __future__ import annotations - -import dataclasses -import logging -import re -from collections.abc import Mapping, Sequence -from dataclasses import dataclass -from datetime import datetime -from typing import ( - TYPE_CHECKING, - Any, - Callable, - Protocol, - TypeVar, - cast, -) -from urllib.parse import urlparse - -from .markers import Environment, Marker, default_environment -from .specifiers import SpecifierSet -from .tags import create_compatible_tags_selector, sys_tags -from .utils import ( - NormalizedName, - is_normalized_name, - parse_sdist_filename, - parse_wheel_filename, -) -from .version import Version - -if TYPE_CHECKING: # pragma: no cover - from collections.abc import Collection, Iterator - from pathlib import Path - - from typing_extensions import Self - - from .tags import Tag - -_logger = logging.getLogger(__name__) - -__all__ = [ - "Package", - "PackageArchive", - "PackageDirectory", - "PackageSdist", - "PackageVcs", - "PackageWheel", - "Pylock", - "PylockUnsupportedVersionError", - "PylockValidationError", - "is_valid_pylock_path", -] - - -def __dir__() -> list[str]: - return __all__ - - -_T = TypeVar("_T") -_T2 = TypeVar("_T2") - - -class _FromMappingProtocol(Protocol): # pragma: no cover - @classmethod - def _from_dict(cls, d: Mapping[str, Any]) -> Self: ... - - -_FromMappingProtocolT = TypeVar("_FromMappingProtocolT", bound=_FromMappingProtocol) - - -_PYLOCK_FILE_NAME_RE = re.compile(r"^pylock\.([^.]+)\.toml$") - - -def is_valid_pylock_path(path: Path) -> bool: - """Check if the given path is a valid pylock file path.""" - return path.name == "pylock.toml" or bool(_PYLOCK_FILE_NAME_RE.match(path.name)) - - -def _toml_key(key: str) -> str: - return key.replace("_", "-") - - -def _toml_value(key: str, value: Any) -> Any: # noqa: ANN401 - if isinstance(value, (Version, Marker, SpecifierSet)): - return str(value) - if isinstance(value, Sequence) and key == "environments": - return [str(v) for v in value] - return value - - -def _toml_dict_factory(data: list[tuple[str, Any]]) -> dict[str, Any]: - return { - _toml_key(key): _toml_value(key, value) - for key, value in data - if value is not None - } - - -def _get(d: Mapping[str, Any], expected_type: type[_T], key: str) -> _T | None: - """Get a value from the dictionary and verify it's the expected type.""" - if (value := d.get(key)) is None: - return None - if not isinstance(value, expected_type): - raise PylockValidationError( - f"Unexpected type {type(value).__name__} " - f"(expected {expected_type.__name__})", - context=key, - ) - return value - - -def _get_required(d: Mapping[str, Any], expected_type: type[_T], key: str) -> _T: - """Get a required value from the dictionary and verify it's the expected type.""" - if (value := _get(d, expected_type, key)) is None: - raise _PylockRequiredKeyError(key) - return value - - -def _get_sequence( - d: Mapping[str, Any], expected_item_type: type[_T], key: str -) -> Sequence[_T] | None: - """Get a list value from the dictionary and verify it's the expected items type.""" - if (value := _get(d, Sequence, key)) is None: # type: ignore[type-abstract] - return None - if isinstance(value, (str, bytes)): - # special case: str and bytes are Sequences, but we want to reject it - raise PylockValidationError( - f"Unexpected type {type(value).__name__} (expected Sequence)", - context=key, - ) - for i, item in enumerate(value): - if not isinstance(item, expected_item_type): - raise PylockValidationError( - f"Unexpected type {type(item).__name__} " - f"(expected {expected_item_type.__name__})", - context=f"{key}[{i}]", - ) - return value - - -def _get_as( - d: Mapping[str, Any], - expected_type: type[_T], - target_type: Callable[[_T], _T2], - key: str, -) -> _T2 | None: - """Get a value from the dictionary, verify it's the expected type, - and convert to the target type. - - This assumes the target_type constructor accepts the value. - """ - if (value := _get(d, expected_type, key)) is None: - return None - try: - return target_type(value) - except Exception as e: - raise PylockValidationError(e, context=key) from e - - -def _get_required_as( - d: Mapping[str, Any], - expected_type: type[_T], - target_type: Callable[[_T], _T2], - key: str, -) -> _T2: - """Get a required value from the dict, verify it's the expected type, - and convert to the target type.""" - if (value := _get_as(d, expected_type, target_type, key)) is None: - raise _PylockRequiredKeyError(key) - return value - - -def _get_sequence_as( - d: Mapping[str, Any], - expected_item_type: type[_T], - target_item_type: Callable[[_T], _T2], - key: str, -) -> list[_T2] | None: - """Get list value from dictionary and verify expected items type.""" - if (value := _get_sequence(d, expected_item_type, key)) is None: - return None - result = [] - try: - for item in value: - typed_item = target_item_type(item) - result.append(typed_item) - except Exception as e: - raise PylockValidationError(e, context=f"{key}[{len(result)}]") from e - return result - - -def _get_object( - d: Mapping[str, Any], target_type: type[_FromMappingProtocolT], key: str -) -> _FromMappingProtocolT | None: - """Get a dictionary value from the dictionary and convert it to a dataclass.""" - if (value := _get(d, Mapping, key)) is None: # type: ignore[type-abstract] - return None - try: - return target_type._from_dict(value) - except Exception as e: - raise PylockValidationError(e, context=key) from e - - -def _get_sequence_of_objects( - d: Mapping[str, Any], target_item_type: type[_FromMappingProtocolT], key: str -) -> list[_FromMappingProtocolT] | None: - """Get a list value from the dictionary and convert its items to a dataclass.""" - if (value := _get_sequence(d, Mapping, key)) is None: # type: ignore[type-abstract] - return None - result: list[_FromMappingProtocolT] = [] - try: - for item in value: - typed_item = target_item_type._from_dict(item) - result.append(typed_item) - except Exception as e: - raise PylockValidationError(e, context=f"{key}[{len(result)}]") from e - return result - - -def _get_required_sequence_of_objects( - d: Mapping[str, Any], target_item_type: type[_FromMappingProtocolT], key: str -) -> Sequence[_FromMappingProtocolT]: - """Get a required list value from the dictionary and convert its items to a - dataclass.""" - if (result := _get_sequence_of_objects(d, target_item_type, key)) is None: - raise _PylockRequiredKeyError(key) - return result - - -def _validate_normalized_name(name: str) -> NormalizedName: - """Validate that a string is a NormalizedName.""" - if not is_normalized_name(name): - raise PylockValidationError(f"Name {name!r} is not normalized") - return NormalizedName(name) - - -def _validate_path_url(path: str | None, url: str | None) -> None: - if not path and not url: - raise PylockValidationError("path or url must be provided") - - -def _path_name(path: str | None) -> str | None: - if not path: - return None - # If the path is relative it MAY use POSIX-style path separators explicitly - # for portability - if "/" in path: - return path.rsplit("/", 1)[-1] - elif "\\" in path: - return path.rsplit("\\", 1)[-1] - else: - return path - - -def _url_name(url: str | None) -> str | None: - if not url: - return None - url_path = urlparse(url).path - return url_path.rsplit("/", 1)[-1] - - -def _validate_hashes(hashes: Mapping[str, Any]) -> Mapping[str, Any]: - if not hashes: - raise PylockValidationError("At least one hash must be provided") - if not all(isinstance(hash_val, str) for hash_val in hashes.values()): - raise PylockValidationError("Hash values must be strings") - return hashes - - -class PylockValidationError(Exception): - """Raised when when input data is not spec-compliant.""" - - context: str | None = None - message: str - - def __init__( - self, - cause: str | Exception, - *, - context: str | None = None, - ) -> None: - if isinstance(cause, PylockValidationError): - if cause.context: - self.context = ( - f"{context}.{cause.context}" if context else cause.context - ) - else: - self.context = context - self.message = cause.message - else: - self.context = context - self.message = str(cause) - - def __str__(self) -> str: - if self.context: - return f"{self.message} in {self.context!r}" - return self.message - - -class _PylockRequiredKeyError(PylockValidationError): - def __init__(self, key: str) -> None: - super().__init__("Missing required value", context=key) - - -class PylockUnsupportedVersionError(PylockValidationError): - """Raised when encountering an unsupported `lock_version`.""" - - -class PylockSelectError(Exception): - """Base exception for errors raised by :meth:`Pylock.select`.""" - - -@dataclass(frozen=True, init=False) -class PackageVcs: - type: str - url: str | None = None - path: str | None = None - requested_revision: str | None = None - commit_id: str # type: ignore[misc] - subdirectory: str | None = None - - def __init__( - self, - *, - type: str, - url: str | None = None, - path: str | None = None, - requested_revision: str | None = None, - commit_id: str, - subdirectory: str | None = None, - ) -> None: - # In Python 3.10+ make dataclass kw_only=True and remove __init__ - object.__setattr__(self, "type", type) - object.__setattr__(self, "url", url) - object.__setattr__(self, "path", path) - object.__setattr__(self, "requested_revision", requested_revision) - object.__setattr__(self, "commit_id", commit_id) - object.__setattr__(self, "subdirectory", subdirectory) - - @classmethod - def _from_dict(cls, d: Mapping[str, Any]) -> Self: - package_vcs = cls( - type=_get_required(d, str, "type"), - url=_get(d, str, "url"), - path=_get(d, str, "path"), - requested_revision=_get(d, str, "requested-revision"), - commit_id=_get_required(d, str, "commit-id"), - subdirectory=_get(d, str, "subdirectory"), - ) - _validate_path_url(package_vcs.path, package_vcs.url) - return package_vcs - - -@dataclass(frozen=True, init=False) -class PackageDirectory: - path: str - editable: bool | None = None - subdirectory: str | None = None - - def __init__( - self, - *, - path: str, - editable: bool | None = None, - subdirectory: str | None = None, - ) -> None: - # In Python 3.10+ make dataclass kw_only=True and remove __init__ - object.__setattr__(self, "path", path) - object.__setattr__(self, "editable", editable) - object.__setattr__(self, "subdirectory", subdirectory) - - @classmethod - def _from_dict(cls, d: Mapping[str, Any]) -> Self: - return cls( - path=_get_required(d, str, "path"), - editable=_get(d, bool, "editable"), - subdirectory=_get(d, str, "subdirectory"), - ) - - -@dataclass(frozen=True, init=False) -class PackageArchive: - url: str | None = None - path: str | None = None - size: int | None = None - upload_time: datetime | None = None - hashes: Mapping[str, str] # type: ignore[misc] - subdirectory: str | None = None - - def __init__( - self, - *, - url: str | None = None, - path: str | None = None, - size: int | None = None, - upload_time: datetime | None = None, - hashes: Mapping[str, str], - subdirectory: str | None = None, - ) -> None: - # In Python 3.10+ make dataclass kw_only=True and remove __init__ - object.__setattr__(self, "url", url) - object.__setattr__(self, "path", path) - object.__setattr__(self, "size", size) - object.__setattr__(self, "upload_time", upload_time) - object.__setattr__(self, "hashes", hashes) - object.__setattr__(self, "subdirectory", subdirectory) - - @classmethod - def _from_dict(cls, d: Mapping[str, Any]) -> Self: - package_archive = cls( - url=_get(d, str, "url"), - path=_get(d, str, "path"), - size=_get(d, int, "size"), - upload_time=_get(d, datetime, "upload-time"), - hashes=_get_required_as(d, Mapping, _validate_hashes, "hashes"), # type: ignore[type-abstract] - subdirectory=_get(d, str, "subdirectory"), - ) - _validate_path_url(package_archive.path, package_archive.url) - return package_archive - - -@dataclass(frozen=True, init=False) -class PackageSdist: - name: str | None = None - upload_time: datetime | None = None - url: str | None = None - path: str | None = None - size: int | None = None - hashes: Mapping[str, str] # type: ignore[misc] - - def __init__( - self, - *, - name: str | None = None, - upload_time: datetime | None = None, - url: str | None = None, - path: str | None = None, - size: int | None = None, - hashes: Mapping[str, str], - ) -> None: - # In Python 3.10+ make dataclass kw_only=True and remove __init__ - object.__setattr__(self, "name", name) - object.__setattr__(self, "upload_time", upload_time) - object.__setattr__(self, "url", url) - object.__setattr__(self, "path", path) - object.__setattr__(self, "size", size) - object.__setattr__(self, "hashes", hashes) - - @classmethod - def _from_dict(cls, d: Mapping[str, Any]) -> Self: - package_sdist = cls( - name=_get(d, str, "name"), - upload_time=_get(d, datetime, "upload-time"), - url=_get(d, str, "url"), - path=_get(d, str, "path"), - size=_get(d, int, "size"), - hashes=_get_required_as(d, Mapping, _validate_hashes, "hashes"), # type: ignore[type-abstract] - ) - _validate_path_url(package_sdist.path, package_sdist.url) - return package_sdist - - @property - def filename(self) -> str: - """Get the filename of the sdist.""" - filename = self.name or _path_name(self.path) or _url_name(self.url) - if not filename: - raise PylockValidationError("Cannot determine sdist filename") - return filename - - -@dataclass(frozen=True, init=False) -class PackageWheel: - name: str | None = None - upload_time: datetime | None = None - url: str | None = None - path: str | None = None - size: int | None = None - hashes: Mapping[str, str] # type: ignore[misc] - - def __init__( - self, - *, - name: str | None = None, - upload_time: datetime | None = None, - url: str | None = None, - path: str | None = None, - size: int | None = None, - hashes: Mapping[str, str], - ) -> None: - # In Python 3.10+ make dataclass kw_only=True and remove __init__ - object.__setattr__(self, "name", name) - object.__setattr__(self, "upload_time", upload_time) - object.__setattr__(self, "url", url) - object.__setattr__(self, "path", path) - object.__setattr__(self, "size", size) - object.__setattr__(self, "hashes", hashes) - - @classmethod - def _from_dict(cls, d: Mapping[str, Any]) -> Self: - package_wheel = cls( - name=_get(d, str, "name"), - upload_time=_get(d, datetime, "upload-time"), - url=_get(d, str, "url"), - path=_get(d, str, "path"), - size=_get(d, int, "size"), - hashes=_get_required_as(d, Mapping, _validate_hashes, "hashes"), # type: ignore[type-abstract] - ) - _validate_path_url(package_wheel.path, package_wheel.url) - return package_wheel - - @property - def filename(self) -> str: - """Get the filename of the wheel.""" - filename = self.name or _path_name(self.path) or _url_name(self.url) - if not filename: - raise PylockValidationError("Cannot determine wheel filename") - return filename - - -@dataclass(frozen=True, init=False) -class Package: - name: NormalizedName - version: Version | None = None - marker: Marker | None = None - requires_python: SpecifierSet | None = None - dependencies: Sequence[Mapping[str, Any]] | None = None - vcs: PackageVcs | None = None - directory: PackageDirectory | None = None - archive: PackageArchive | None = None - index: str | None = None - sdist: PackageSdist | None = None - wheels: Sequence[PackageWheel] | None = None - attestation_identities: Sequence[Mapping[str, Any]] | None = None - tool: Mapping[str, Any] | None = None - - def __init__( - self, - *, - name: NormalizedName, - version: Version | None = None, - marker: Marker | None = None, - requires_python: SpecifierSet | None = None, - dependencies: Sequence[Mapping[str, Any]] | None = None, - vcs: PackageVcs | None = None, - directory: PackageDirectory | None = None, - archive: PackageArchive | None = None, - index: str | None = None, - sdist: PackageSdist | None = None, - wheels: Sequence[PackageWheel] | None = None, - attestation_identities: Sequence[Mapping[str, Any]] | None = None, - tool: Mapping[str, Any] | None = None, - ) -> None: - # In Python 3.10+ make dataclass kw_only=True and remove __init__ - object.__setattr__(self, "name", name) - object.__setattr__(self, "version", version) - object.__setattr__(self, "marker", marker) - object.__setattr__(self, "requires_python", requires_python) - object.__setattr__(self, "dependencies", dependencies) - object.__setattr__(self, "vcs", vcs) - object.__setattr__(self, "directory", directory) - object.__setattr__(self, "archive", archive) - object.__setattr__(self, "index", index) - object.__setattr__(self, "sdist", sdist) - object.__setattr__(self, "wheels", wheels) - object.__setattr__(self, "attestation_identities", attestation_identities) - object.__setattr__(self, "tool", tool) - - @classmethod - def _from_dict(cls, d: Mapping[str, Any]) -> Self: - package = cls( - name=_get_required_as(d, str, _validate_normalized_name, "name"), - version=_get_as(d, str, Version, "version"), - requires_python=_get_as(d, str, SpecifierSet, "requires-python"), - dependencies=_get_sequence(d, Mapping, "dependencies"), # type: ignore[type-abstract] - marker=_get_as(d, str, Marker, "marker"), - vcs=_get_object(d, PackageVcs, "vcs"), - directory=_get_object(d, PackageDirectory, "directory"), - archive=_get_object(d, PackageArchive, "archive"), - index=_get(d, str, "index"), - sdist=_get_object(d, PackageSdist, "sdist"), - wheels=_get_sequence_of_objects(d, PackageWheel, "wheels"), - attestation_identities=_get_sequence(d, Mapping, "attestation-identities"), # type: ignore[type-abstract] - tool=_get(d, Mapping, "tool"), # type: ignore[type-abstract] - ) - distributions = bool(package.sdist) + len(package.wheels or []) - direct_urls = ( - bool(package.vcs) + bool(package.directory) + bool(package.archive) - ) - if distributions > 0 and direct_urls > 0: - raise PylockValidationError( - "None of vcs, directory, archive must be set if sdist or wheels are set" - ) - if distributions == 0 and direct_urls != 1: - raise PylockValidationError( - "Exactly one of vcs, directory, archive must be set " - "if sdist and wheels are not set" - ) - for i, wheel in enumerate(package.wheels or []): - try: - (name, version, _, _) = parse_wheel_filename(wheel.filename) - except Exception as e: - raise PylockValidationError( - f"Invalid wheel filename {wheel.filename!r}", - context=f"wheels[{i}]", - ) from e - if name != package.name: - raise PylockValidationError( - f"Name in {wheel.filename!r} is not consistent with " - f"package name {package.name!r}", - context=f"wheels[{i}]", - ) - if package.version and version != package.version: - raise PylockValidationError( - f"Version in {wheel.filename!r} is not consistent with " - f"package version {str(package.version)!r}", - context=f"wheels[{i}]", - ) - if package.sdist: - try: - name, version = parse_sdist_filename(package.sdist.filename) - except Exception as e: - raise PylockValidationError( - f"Invalid sdist filename {package.sdist.filename!r}", - context="sdist", - ) from e - if name != package.name: - raise PylockValidationError( - f"Name in {package.sdist.filename!r} is not consistent with " - f"package name {package.name!r}", - context="sdist", - ) - if package.version and version != package.version: - raise PylockValidationError( - f"Version in {package.sdist.filename!r} is not consistent with " - f"package version {str(package.version)!r}", - context="sdist", - ) - try: - for i, attestation_identity in enumerate( # noqa: B007 - package.attestation_identities or [] - ): - _get_required(attestation_identity, str, "kind") - except Exception as e: - raise PylockValidationError( - e, context=f"attestation-identities[{i}]" - ) from e - return package - - @property - def is_direct(self) -> bool: - return not (self.sdist or self.wheels) - - -@dataclass(frozen=True, init=False) -class Pylock: - """A class representing a pylock file.""" - - lock_version: Version - environments: Sequence[Marker] | None = None - requires_python: SpecifierSet | None = None - extras: Sequence[NormalizedName] | None = None - dependency_groups: Sequence[str] | None = None - default_groups: Sequence[str] | None = None - created_by: str # type: ignore[misc] - packages: Sequence[Package] # type: ignore[misc] - tool: Mapping[str, Any] | None = None - - def __init__( - self, - *, - lock_version: Version, - environments: Sequence[Marker] | None = None, - requires_python: SpecifierSet | None = None, - extras: Sequence[NormalizedName] | None = None, - dependency_groups: Sequence[str] | None = None, - default_groups: Sequence[str] | None = None, - created_by: str, - packages: Sequence[Package], - tool: Mapping[str, Any] | None = None, - ) -> None: - # In Python 3.10+ make dataclass kw_only=True and remove __init__ - object.__setattr__(self, "lock_version", lock_version) - object.__setattr__(self, "environments", environments) - object.__setattr__(self, "requires_python", requires_python) - object.__setattr__(self, "extras", extras) - object.__setattr__(self, "dependency_groups", dependency_groups) - object.__setattr__(self, "default_groups", default_groups) - object.__setattr__(self, "created_by", created_by) - object.__setattr__(self, "packages", packages) - object.__setattr__(self, "tool", tool) - - @classmethod - def _from_dict(cls, d: Mapping[str, Any]) -> Self: - pylock = cls( - lock_version=_get_required_as(d, str, Version, "lock-version"), - environments=_get_sequence_as(d, str, Marker, "environments"), - extras=_get_sequence_as(d, str, _validate_normalized_name, "extras"), - dependency_groups=_get_sequence(d, str, "dependency-groups"), - default_groups=_get_sequence(d, str, "default-groups"), - created_by=_get_required(d, str, "created-by"), - requires_python=_get_as(d, str, SpecifierSet, "requires-python"), - packages=_get_required_sequence_of_objects(d, Package, "packages"), - tool=_get(d, Mapping, "tool"), # type: ignore[type-abstract] - ) - if not Version("1") <= pylock.lock_version < Version("2"): - raise PylockUnsupportedVersionError( - f"pylock version {pylock.lock_version} is not supported" - ) - if pylock.lock_version > Version("1.0"): - _logger.warning( - "pylock minor version %s is not supported", pylock.lock_version - ) - return pylock - - @classmethod - def from_dict(cls, d: Mapping[str, Any], /) -> Self: - """Create and validate a Pylock instance from a TOML dictionary. - - Raises :class:`PylockValidationError` if the input data is not - spec-compliant. - """ - return cls._from_dict(d) - - def to_dict(self) -> Mapping[str, Any]: - """Convert the Pylock instance to a TOML dictionary.""" - return dataclasses.asdict(self, dict_factory=_toml_dict_factory) - - def validate(self) -> None: - """Validate the Pylock instance against the specification. - - Raises :class:`PylockValidationError` otherwise.""" - self.from_dict(self.to_dict()) - - def select( - self, - *, - environment: Environment | None = None, - tags: Sequence[Tag] | None = None, - extras: Collection[str] | None = None, - dependency_groups: Collection[str] | None = None, - ) -> Iterator[ - tuple[ - Package, - PackageVcs - | PackageDirectory - | PackageArchive - | PackageWheel - | PackageSdist, - ] - ]: - """Select what to install from the lock file. - - The *environment* and *tags* parameters represent the environment being - selected for. If unspecified, ``packaging.markers.default_environment()`` and - ``packaging.tags.sys_tags()`` are used. - - The *extras* parameter represents the extras to install. - - The *dependency_groups* parameter represents the groups to install. If - unspecified, the default groups are used. - - This method must be used on valid Pylock instances (i.e. one obtained - from :meth:`Pylock.from_dict` or if constructed manually, after calling - :meth:`Pylock.validate`). - """ - compatible_tags_selector = create_compatible_tags_selector(tags or sys_tags()) - - # #. Gather the extras and dependency groups to install and set ``extras`` and - # ``dependency_groups`` for marker evaluation, respectively. - # - # #. ``extras`` SHOULD be set to the empty set by default. - # #. ``dependency_groups`` SHOULD be the set created from - # :ref:`pylock-default-groups` by default. - env = cast( - "dict[str, str | frozenset[str]]", - dict( - environment or {}, # Marker.evaluate will fill-up - extras=frozenset(extras or []), - dependency_groups=frozenset( - (self.default_groups or []) - if dependency_groups is None # to allow selecting no group - else dependency_groups - ), - ), - ) - env_python_full_version = ( - environment["python_full_version"] - if environment - else default_environment()["python_full_version"] - ) - - # #. Check if the metadata version specified by :ref:`pylock-lock-version` is - # supported; an error or warning MUST be raised as appropriate. - # Covered by lock.validate() which is a precondition for this method. - - # #. If :ref:`pylock-requires-python` is specified, check that the environment - # being installed for meets the requirement; an error MUST be raised if it is - # not met. - if self.requires_python and not self.requires_python.contains( - env_python_full_version, - ): - raise PylockSelectError( - f"python_full_version {env_python_full_version!r} " - f"in provided environment does not satisfy the Python version " - f"requirement {str(self.requires_python)!r}" - ) - - # #. If :ref:`pylock-environments` is specified, check that at least one of the - # environment marker expressions is satisfied; an error MUST be raised if no - # expression is satisfied. - if self.environments: - for env_marker in self.environments: - if env_marker.evaluate( - cast("dict[str, str]", environment or {}), context="requirement" - ): - break - else: - raise PylockSelectError( - "Provided environment does not satisfy any of the " - "environments specified in the lock file" - ) - - # #. For each package listed in :ref:`pylock-packages`: - selected_packages_by_name: dict[str, tuple[int, Package]] = {} - for package_index, package in enumerate(self.packages): - # #. If :ref:`pylock-packages-marker` is specified, check if it is - # satisfied;if it isn't, skip to the next package. - if package.marker and not package.marker.evaluate(env, context="lock_file"): - continue - - # #. If :ref:`pylock-packages-requires-python` is specified, check if it is - # satisfied; an error MUST be raised if it isn't. - if package.requires_python and not package.requires_python.contains( - env_python_full_version, - ): - raise PylockSelectError( - f"python_full_version {env_python_full_version!r} " - f"in provided environment does not satisfy the Python version " - f"requirement {str(package.requires_python)!r} for package " - f"{package.name!r} at packages[{package_index}]" - ) - - # #. Check that no other conflicting instance of the package has been slated - # to be installed; an error about the ambiguity MUST be raised otherwise. - if package.name in selected_packages_by_name: - raise PylockSelectError( - f"Multiple packages with the name {package.name!r} are " - f"selected at packages[{package_index}] and " - f"packages[{selected_packages_by_name[package.name][0]}]" - ) - - # #. Check that the source of the package is specified appropriately (i.e. - # there are no conflicting sources in the package entry); - # an error MUST be raised if any issues are found. - # Covered by lock.validate() which is a precondition for this method. - - # #. Add the package to the set of packages to install. - selected_packages_by_name[package.name] = (package_index, package) - - # #. For each package to be installed: - for package_index, package in selected_packages_by_name.values(): - # - If :ref:`pylock-packages-vcs` is set: - if package.vcs is not None: - yield package, package.vcs - - # - Else if :ref:`pylock-packages-directory` is set: - elif package.directory is not None: - yield package, package.directory - - # - Else if :ref:`pylock-packages-archive` is set: - elif package.archive is not None: - yield package, package.archive - - # - Else if there are entries for :ref:`pylock-packages-wheels`: - elif package.wheels: - # #. Look for the appropriate wheel file based on - # :ref:`pylock-packages-wheels-name`; if one is not found then move - # on to :ref:`pylock-packages-sdist` or an error MUST be raised about - # a lack of source for the project. - best_wheel = next( - compatible_tags_selector( - (wheel, parse_wheel_filename(wheel.filename)[-1]) - for wheel in package.wheels - ), - None, - ) - if best_wheel: - yield package, best_wheel - elif package.sdist is not None: - yield package, package.sdist - else: - raise PylockSelectError( - f"No wheel found matching the provided tags " - f"for package {package.name!r} " - f"at packages[{package_index}], " - f"and no sdist available as a fallback" - ) - - # - Else if no :ref:`pylock-packages-wheels` file is found or - # :ref:`pylock-packages-sdist` is solely set: - elif package.sdist is not None: - yield package, package.sdist - - else: - # Covered by lock.validate() which is a precondition for this method. - raise NotImplementedError # pragma: no cover diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/requirements.py b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/requirements.py deleted file mode 100755 index d5c786d..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/requirements.py +++ /dev/null @@ -1,129 +0,0 @@ -# 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 annotations - -from typing import Iterator - -from ._parser import parse_requirement as _parse_requirement -from ._tokenizer import ParserSyntaxError -from .markers import Marker, _normalize_extra_values -from .specifiers import SpecifierSet -from .utils import canonicalize_name - -__all__ = [ - "InvalidRequirement", - "Requirement", -] - - -def __dir__() -> list[str]: - return __all__ - - -class InvalidRequirement(ValueError): - """ - An invalid requirement was found, users should refer to PEP 508. - """ - - -class Requirement: - """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. - - Instances are safe to serialize with :mod:`pickle`. They use a stable - format so the same pickle can be loaded in future packaging releases. - - .. versionchanged:: 26.2 - - Added a stable pickle format. Pickles created with packaging 26.2+ can - be unpickled with future releases. Backward compatibility with pickles - from pip._vendor.packaging < 26.2 is supported but may be removed in a future - release. - """ - - # 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: str) -> None: - try: - parsed = _parse_requirement(requirement_string) - except ParserSyntaxError as e: - raise InvalidRequirement(str(e)) from e - - self.name: str = parsed.name - self.url: str | None = parsed.url or None - self.extras: set[str] = set(parsed.extras or []) - self.specifier: SpecifierSet = SpecifierSet(parsed.specifier) - self.marker: Marker | None = None - if parsed.marker is not None: - self.marker = Marker.__new__(Marker) - self.marker._markers = _normalize_extra_values(parsed.marker) - - def _iter_parts(self, name: str) -> Iterator[str]: - yield name - - if self.extras: - formatted_extras = ",".join(sorted(self.extras)) - yield f"[{formatted_extras}]" - - if self.specifier: - yield str(self.specifier) - - if self.url: - yield f" @ {self.url}" - if self.marker: - yield " " - - if self.marker: - yield f"; {self.marker}" - - def __getstate__(self) -> str: - # Return the requirement string for compactness and stability. - # Re-parsed on load to reconstruct all fields. - return str(self) - - def __setstate__(self, state: object) -> None: - if isinstance(state, str): - # New format (26.2+): just the requirement string. - try: - tmp = Requirement(state) - except InvalidRequirement as exc: - raise TypeError(f"Cannot restore Requirement from {state!r}") from exc - self.name = tmp.name - self.url = tmp.url - self.extras = tmp.extras - self.specifier = tmp.specifier - self.marker = tmp.marker - return - if isinstance(state, dict): - # Old format (packaging <= 26.1, no __slots__): plain __dict__. - self.__dict__.update(state) - return - raise TypeError(f"Cannot restore Requirement from {state!r}") - - def __str__(self) -> str: - return "".join(self._iter_parts(self.name)) - - def __repr__(self) -> str: - return f"<{self.__class__.__name__}({str(self)!r})>" - - def __hash__(self) -> int: - return hash(tuple(self._iter_parts(canonicalize_name(self.name)))) - - def __eq__(self, other: object) -> bool: - if not isinstance(other, Requirement): - return NotImplemented - - return ( - canonicalize_name(self.name) == canonicalize_name(other.name) - and self.extras == other.extras - and self.specifier == other.specifier - and self.url == other.url - and self.marker == other.marker - ) diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/specifiers.py b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/specifiers.py deleted file mode 100755 index 83e0015..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/specifiers.py +++ /dev/null @@ -1,1943 +0,0 @@ -# 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. -""" -.. testsetup:: - - from pip._vendor.packaging.specifiers import Specifier, SpecifierSet, InvalidSpecifier - from pip._vendor.packaging.version import Version -""" - -from __future__ import annotations - -import abc -import enum -import functools -import itertools -import re -import sys -import typing -from typing import ( - TYPE_CHECKING, - Any, - Callable, - Final, - Iterable, - Iterator, - Sequence, - TypeVar, - Union, -) - -from .utils import canonicalize_version -from .version import InvalidVersion, Version - -if sys.version_info >= (3, 10): - from typing import TypeGuard # pragma: no cover -elif TYPE_CHECKING: - from typing_extensions import TypeGuard - -__all__ = [ - "BaseSpecifier", - "InvalidSpecifier", - "Specifier", - "SpecifierSet", -] - - -def __dir__() -> list[str]: - return __all__ - - -def _validate_spec(spec: object, /) -> TypeGuard[tuple[str, str]]: - return ( - isinstance(spec, tuple) - and len(spec) == 2 - and isinstance(spec[0], str) - and isinstance(spec[1], str) - ) - - -def _validate_pre(pre: object, /) -> TypeGuard[bool | None]: - return pre is None or isinstance(pre, bool) - - -T = TypeVar("T") -UnparsedVersion = Union[Version, str] -UnparsedVersionVar = TypeVar("UnparsedVersionVar", bound=UnparsedVersion) -CallableOperator = Callable[[Version, str], bool] - -# The smallest possible PEP 440 version. No valid version is less than this. -_MIN_VERSION: Final[Version] = Version("0.dev0") - - -def _trim_release(release: tuple[int, ...]) -> tuple[int, ...]: - """Strip trailing zeros from a release tuple for normalized comparison.""" - end = len(release) - while end > 1 and release[end - 1] == 0: - end -= 1 - return release if end == len(release) else release[:end] - - -class _BoundaryKind(enum.Enum): - """Where a boundary marker sits in the version ordering.""" - - AFTER_LOCALS = enum.auto() # after V+local, before V.post0 - AFTER_POSTS = enum.auto() # after V.postN, before next release - - -@functools.total_ordering -class _BoundaryVersion: - """A point on the version line between two real PEP 440 versions. - - Some specifier semantics imply boundaries between real versions: - ``<=1.0`` includes ``1.0+local`` and ``>1.0`` excludes - ``1.0.post0``. No real :class:`Version` falls on those boundaries, - so this class creates values that sort between the real versions - on either side. - - Two kinds exist, shown relative to a base version V:: - - V < V+local < AFTER_LOCALS(V) < V.post0 < AFTER_POSTS(V) - - ``AFTER_LOCALS`` sits after V and every V+local, but before - V.post0. Upper bound of ``<=V``, ``==V``, ``!=V``. - - ``AFTER_POSTS`` sits after every V.postN, but before the next - release segment. Lower bound of ``>V`` (final or pre-release V) - to exclude post-releases per PEP 440. - """ - - __slots__ = ("_kind", "_trimmed_release", "version") - - def __init__(self, version: Version, kind: _BoundaryKind) -> None: - self.version = version - self._kind = kind - self._trimmed_release = _trim_release(version.release) - - def _is_family(self, other: Version) -> bool: - """Is ``other`` a version that this boundary sorts above?""" - v = self.version - if not ( - other.epoch == v.epoch - and _trim_release(other.release) == self._trimmed_release - and other.pre == v.pre - ): - return False - if self._kind == _BoundaryKind.AFTER_LOCALS: - # Local family: exact same public version (any local label). - return other.post == v.post and other.dev == v.dev - # Post family: same base + any post-release (or identical). - return other.dev == v.dev or other.post is not None - - def __eq__(self, other: object) -> bool: - if isinstance(other, _BoundaryVersion): - return self.version == other.version and self._kind == other._kind - return NotImplemented - - def __lt__(self, other: _BoundaryVersion | Version) -> bool: - if isinstance(other, _BoundaryVersion): - if self.version != other.version: - return self.version < other.version - return self._kind.value < other._kind.value - return not self._is_family(other) and self.version < other - - def __hash__(self) -> int: - return hash((self.version, self._kind)) - - def __repr__(self) -> str: - return f"{self.__class__.__name__}({self.version!r}, {self._kind.name})" - - -@functools.total_ordering -class _LowerBound: - """Lower bound of a version range. - - A version *v* of ``None`` means unbounded below (-inf). - At equal versions, ``[v`` sorts before ``(v`` because an inclusive - bound starts earlier. - """ - - __slots__ = ("inclusive", "version") - - def __init__(self, version: _VersionOrBoundary, inclusive: bool) -> None: - self.version = version - self.inclusive = inclusive - - def __eq__(self, other: object) -> bool: - if not isinstance(other, _LowerBound): - return NotImplemented # pragma: no cover - return self.version == other.version and self.inclusive == other.inclusive - - def __lt__(self, other: _LowerBound) -> bool: - if not isinstance(other, _LowerBound): # pragma: no cover - return NotImplemented - # -inf < anything (except -inf). - if self.version is None: - return other.version is not None - if other.version is None: - return False - if self.version != other.version: - return self.version < other.version - # [v < (v: inclusive starts earlier. - return self.inclusive and not other.inclusive - - def __hash__(self) -> int: - return hash((self.version, self.inclusive)) - - def __repr__(self) -> str: - bracket = "[" if self.inclusive else "(" - return f"<{self.__class__.__name__} {bracket}{self.version!r}>" - - -@functools.total_ordering -class _UpperBound: - """Upper bound of a version range. - - A version *v* of ``None`` means unbounded above (+inf). - At equal versions, ``v)`` sorts before ``v]`` because an exclusive - bound ends earlier. - """ - - __slots__ = ("inclusive", "version") - - def __init__(self, version: _VersionOrBoundary, inclusive: bool) -> None: - self.version = version - self.inclusive = inclusive - - def __eq__(self, other: object) -> bool: - if not isinstance(other, _UpperBound): - return NotImplemented # pragma: no cover - return self.version == other.version and self.inclusive == other.inclusive - - def __lt__(self, other: _UpperBound) -> bool: - if not isinstance(other, _UpperBound): # pragma: no cover - return NotImplemented - # Nothing < +inf (except +inf itself). - if self.version is None: - return False - if other.version is None: - return True - if self.version != other.version: - return self.version < other.version - # v) < v]: exclusive ends earlier. - return not self.inclusive and other.inclusive - - def __hash__(self) -> int: - return hash((self.version, self.inclusive)) - - def __repr__(self) -> str: - bracket = "]" if self.inclusive else ")" - return f"<{self.__class__.__name__} {self.version!r}{bracket}>" - - -if typing.TYPE_CHECKING: - _VersionOrBoundary = Union[Version, _BoundaryVersion, None] - - #: A single contiguous version range, represented as a - #: (lower bound, upper bound) pair. - _VersionRange = tuple[_LowerBound, _UpperBound] - -_NEG_INF = _LowerBound(None, False) -_POS_INF = _UpperBound(None, False) -_FULL_RANGE: tuple[_VersionRange] = ((_NEG_INF, _POS_INF),) - - -def _range_is_empty(lower: _LowerBound, upper: _UpperBound) -> bool: - """True when the range defined by *lower* and *upper* contains no versions.""" - if lower.version is None or upper.version is None: - return False - if lower.version == upper.version: - return not (lower.inclusive and upper.inclusive) - return lower.version > upper.version - - -def _intersect_ranges( - left: Sequence[_VersionRange], - right: Sequence[_VersionRange], -) -> list[_VersionRange]: - """Intersect two sorted, non-overlapping range lists (two-pointer merge).""" - result: list[_VersionRange] = [] - left_index = right_index = 0 - while left_index < len(left) and right_index < len(right): - left_lower, left_upper = left[left_index] - right_lower, right_upper = right[right_index] - - lower = max(left_lower, right_lower) - upper = min(left_upper, right_upper) - - if not _range_is_empty(lower, upper): - result.append((lower, upper)) - - # Advance whichever side has the smaller upper bound. - if left_upper < right_upper: - left_index += 1 - else: - right_index += 1 - - return result - - -def _next_prefix_dev0(version: Version) -> Version: - """Smallest version in the next prefix: 1.2 -> 1.3.dev0.""" - release = (*version.release[:-1], version.release[-1] + 1) - return Version.from_parts(epoch=version.epoch, release=release, dev=0) - - -def _base_dev0(version: Version) -> Version: - """The .dev0 of a version's base release: 1.2 -> 1.2.dev0.""" - return Version.from_parts(epoch=version.epoch, release=version.release, dev=0) - - -def _coerce_version(version: UnparsedVersion) -> Version | None: - if not isinstance(version, Version): - try: - version = Version(version) - except InvalidVersion: - return None - return version - - -def _public_version(version: Version) -> Version: - if version.local is None: - return version - return version.__replace__(local=None) - - -def _post_base(version: Version) -> Version: - """The version that *version* is a post-release of. - - 1.0.post1 -> 1.0, 1.0a1.post0 -> 1.0a1, 1.0.post0.dev1 -> 1.0. - """ - return version.__replace__(post=None, dev=None, local=None) - - -def _earliest_prerelease(version: Version) -> Version: - """Earliest pre-release of *version*. - - 1.2 -> 1.2.dev0, 1.2.post1 -> 1.2.post1.dev0. - """ - return version.__replace__(dev=0, local=None) - - -def _nearest_non_prerelease( - v: _VersionOrBoundary, -) -> Version | None: - """Smallest non-pre-release version at or above *v*, or None.""" - if v is None: - return None - if isinstance(v, _BoundaryVersion): - inner = v.version - if inner.is_prerelease: - # AFTER_LOCALS(1.0a1) -> nearest non-pre is 1.0 - return inner.__replace__(pre=None, dev=None, local=None) - # AFTER_LOCALS(1.0) -> nearest non-pre is 1.0.post0 - # AFTER_LOCALS(1.0.post0) -> nearest non-pre is 1.0.post1 - k = (inner.post + 1) if inner.post is not None else 0 - return inner.__replace__(post=k, local=None) - if not v.is_prerelease: - return v - # Strip pre/dev to get the final or post-release form. - return v.__replace__(pre=None, dev=None, local=None) - - -class InvalidSpecifier(ValueError): - """ - Raised when attempting to create a :class:`Specifier` with a specifier - string that is invalid. - - >>> Specifier("lolwat") - Traceback (most recent call last): - ... - packaging.specifiers.InvalidSpecifier: Invalid specifier: 'lolwat' - """ - - -class BaseSpecifier(metaclass=abc.ABCMeta): - __slots__ = () - __match_args__ = ("_str",) - - @property - def _str(self) -> str: - """Internal property for match_args""" - return str(self) - - @abc.abstractmethod - def __str__(self) -> str: - """ - Returns the str representation of this Specifier-like object. This - should be representative of the Specifier itself. - """ - - @abc.abstractmethod - def __hash__(self) -> int: - """ - Returns a hash value for this Specifier-like object. - """ - - @abc.abstractmethod - def __eq__(self, other: object) -> bool: - """ - Returns a boolean representing whether or not the two Specifier-like - objects are equal. - - :param other: The other object to check against. - """ - - @property - @abc.abstractmethod - def prereleases(self) -> bool | None: - """Whether or not pre-releases as a whole are allowed. - - This can be set to either ``True`` or ``False`` to explicitly enable or disable - prereleases or it can be set to ``None`` (the default) to use default semantics. - """ - - @prereleases.setter # noqa: B027 - def prereleases(self, value: bool) -> None: - """Setter for :attr:`prereleases`. - - :param value: The value to set. - """ - - @abc.abstractmethod - def contains(self, item: str, prereleases: bool | None = None) -> bool: - """ - Determines if the given item is contained within this specifier. - """ - - @typing.overload - def filter( - self, - iterable: Iterable[UnparsedVersionVar], - prereleases: bool | None = None, - key: None = ..., - ) -> Iterator[UnparsedVersionVar]: ... - - @typing.overload - def filter( - self, - iterable: Iterable[T], - prereleases: bool | None = None, - key: Callable[[T], UnparsedVersion] = ..., - ) -> Iterator[T]: ... - - @abc.abstractmethod - def filter( - self, - iterable: Iterable[Any], - prereleases: bool | None = None, - key: Callable[[Any], UnparsedVersion] | None = None, - ) -> Iterator[Any]: - """ - Takes an iterable of items and filters them so that only items which - are contained within this specifier are allowed in it. - """ - - -class Specifier(BaseSpecifier): - """This class abstracts handling of version specifiers. - - .. tip:: - - It is generally not required to instantiate this manually. You should instead - prefer to work with :class:`SpecifierSet` instead, which can parse - comma-separated version specifiers (which is what package metadata contains). - - Instances are safe to serialize with :mod:`pickle`. They use a stable - format so the same pickle can be loaded in future packaging releases. - - .. versionchanged:: 26.2 - - Added a stable pickle format. Pickles created with packaging 26.2+ can - be unpickled with future releases. Backward compatibility with pickles - from pip._vendor.packaging < 26.2 is supported but may be removed in a future - release. - """ - - __slots__ = ( - "_prereleases", - "_ranges", - "_spec", - "_spec_version", - "_wildcard_split", - ) - - _specifier_regex_str = r""" - (?: - (?: - # 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;)]* # The arbitrary version can be just about anything, - # we match everything except for whitespace, a - # semi-colon for marker support, and a closing paren - # since versions can be enclosed in them. - ) - | - (?: - # 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 - - # You cannot use a wild card and a pre-release, post-release, a dev or - # local version together so group them with a | and make them optional. - (?: - \.\* # Wild card syntax of .* - | - (?a: # pre release - [-_\.]? - (alpha|beta|preview|pre|a|b|c|rc) - [-_\.]? - [0-9]* - )? - (?a: # post release - (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) - )? - (?a:[-_\.]?dev[-_\.]?[0-9]*)? # dev release - (?a:\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*)? # local - )? - ) - | - (?: - # 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 - [-_\.]? - (alpha|beta|preview|pre|a|b|c|rc) - [-_\.]? - [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. - (?:<=|>=|<|>) - - \s* - v? - (?:[0-9]+!)? # epoch - [0-9]+(?:\.[0-9]+)* # release - (?a: # pre release - [-_\.]? - (alpha|beta|preview|pre|a|b|c|rc) - [-_\.]? - [0-9]* - )? - (?a: # post release - (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) - )? - (?a:[-_\.]?dev[-_\.]?[0-9]*)? # dev release - ) - ) - """ - - _regex = re.compile( - r"\s*" + _specifier_regex_str + r"\s*", re.VERBOSE | re.IGNORECASE - ) - - _operators: Final = { - "~=": "compatible", - "==": "equal", - "!=": "not_equal", - "<=": "less_than_equal", - ">=": "greater_than_equal", - "<": "less_than", - ">": "greater_than", - "===": "arbitrary", - } - - def __init__(self, spec: str = "", prereleases: bool | None = None) -> None: - """Initialize a Specifier instance. - - :param spec: - The string representation of a specifier which will be parsed and - normalized before use. - :param prereleases: - This tells the specifier if it should accept prerelease versions if - applicable or not. The default of ``None`` will autodetect it from the - given specifiers. - :raises InvalidSpecifier: - If the given specifier is invalid (i.e. bad syntax). - """ - if not self._regex.fullmatch(spec): - raise InvalidSpecifier(f"Invalid specifier: {spec!r}") - - spec = spec.strip() - if spec.startswith("==="): - operator, version = spec[:3], spec[3:].strip() - elif spec.startswith(("~=", "==", "!=", "<=", ">=")): - operator, version = spec[:2], spec[2:].strip() - else: - operator, version = spec[:1], spec[1:].strip() - - self._spec: tuple[str, str] = (operator, version) - - # Store whether or not this Specifier should accept prereleases - self._prereleases = prereleases - - # Specifier version cache - self._spec_version: tuple[str, Version] | None = None - - # Populated on first wildcard (==X.*) comparison - self._wildcard_split: tuple[list[str], int] | None = None - - # Version range cache (populated by _to_ranges) - self._ranges: Sequence[_VersionRange] | None = None - - def _get_spec_version(self, version: str) -> Version | None: - """One element cache, as only one spec Version is needed per Specifier.""" - if self._spec_version is not None and self._spec_version[0] == version: - return self._spec_version[1] - - version_specifier = _coerce_version(version) - if version_specifier is None: - return None - - self._spec_version = (version, version_specifier) - return version_specifier - - def _require_spec_version(self, version: str) -> Version: - """Get spec version, asserting it's valid (not for === operator). - - This method should only be called for operators where version - strings are guaranteed to be valid PEP 440 versions (not ===). - """ - spec_version = self._get_spec_version(version) - assert spec_version is not None - return spec_version - - def _to_ranges(self) -> Sequence[_VersionRange]: - """Convert this specifier to sorted, non-overlapping version ranges. - - Each standard operator maps to one or two ranges. ``===`` is - modeled as full range (actual check done separately). Cached. - """ - if self._ranges is not None: - return self._ranges - - op = self.operator - ver_str = self.version - - if op == "===": - self._ranges = _FULL_RANGE - return _FULL_RANGE - - if ver_str.endswith(".*"): - result = self._wildcard_ranges(op, ver_str) - else: - result = self._standard_ranges(op, ver_str) - - self._ranges = result - return result - - def _wildcard_ranges(self, op: str, ver_str: str) -> list[_VersionRange]: - # ==1.2.* -> [1.2.dev0, 1.3.dev0); !=1.2.* -> complement. - base = self._require_spec_version(ver_str[:-2]) - lower = _base_dev0(base) - upper = _next_prefix_dev0(base) - if op == "==": - return [(_LowerBound(lower, True), _UpperBound(upper, False))] - # != - return [ - (_NEG_INF, _UpperBound(lower, False)), - (_LowerBound(upper, True), _POS_INF), - ] - - def _standard_ranges(self, op: str, ver_str: str) -> list[_VersionRange]: - v = self._require_spec_version(ver_str) - - if op == ">=": - return [(_LowerBound(v, True), _POS_INF)] - - if op == "<=": - return [ - ( - _NEG_INF, - _UpperBound(_BoundaryVersion(v, _BoundaryKind.AFTER_LOCALS), True), - ) - ] - - if op == ">": - if v.dev is not None: - # >V.devN: dev versions have no post-releases, so the - # next real version is V.dev(N+1). - lower_ver = v.__replace__(dev=v.dev + 1, local=None) - return [(_LowerBound(lower_ver, True), _POS_INF)] - if v.post is not None: - # >V.postN: next real version is V.post(N+1).dev0. - lower_ver = v.__replace__(post=v.post + 1, dev=0, local=None) - return [(_LowerBound(lower_ver, True), _POS_INF)] - # >V (final or pre-release): skip V+local and all V.postN. - return [ - ( - _LowerBound(_BoundaryVersion(v, _BoundaryKind.AFTER_POSTS), False), - _POS_INF, - ) - ] - - if op == "<": - # bool | None: - # 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 - - # Only the "!=" operator does not imply prereleases when - # the version in the specifier is a prerelease. - operator, version_str = self._spec - if operator == "!=": - return False - - # The == specifier with trailing .* cannot include prereleases - # e.g. "==1.0a1.*" is not valid. - if operator == "==" and version_str.endswith(".*"): - return False - - # "===" can have arbitrary string versions, so we cannot parse - # those, we take prereleases as unknown (None) for those. - version = self._get_spec_version(version_str) - if version is None: - return None - - # For all other operators, use the check if spec Version - # object implies pre-releases. - return version.is_prerelease - - @prereleases.setter - def prereleases(self, value: bool | None) -> None: - self._prereleases = value - - def __getstate__(self) -> tuple[tuple[str, str], bool | None]: - # Return state as a 2-item tuple for compactness: - # ((operator, version), prereleases) - # Cache members are excluded and will be recomputed on demand. - return (self._spec, self._prereleases) - - def __setstate__(self, state: object) -> None: - # Always discard cached values - they will be recomputed on demand. - self._spec_version = None - self._wildcard_split = None - self._ranges = None - - if isinstance(state, tuple): - if len(state) == 2: - # New format (26.2+): ((operator, version), prereleases) - spec, prereleases = state - if _validate_spec(spec) and _validate_pre(prereleases): - self._spec = spec - self._prereleases = prereleases - return - if len(state) == 2 and isinstance(state[1], dict): - # Format (packaging 26.0-26.1): (None, {slot: value}). - _, slot_dict = state - spec = slot_dict.get("_spec") - prereleases = slot_dict.get("_prereleases", "invalid") - if _validate_spec(spec) and _validate_pre(prereleases): - self._spec = spec - self._prereleases = prereleases - return - if isinstance(state, dict): - # Old format (packaging <= 25.x, no __slots__): state is a plain dict. - spec = state.get("_spec") - prereleases = state.get("_prereleases", "invalid") - if _validate_spec(spec) and _validate_pre(prereleases): - self._spec = spec - self._prereleases = prereleases - return - - raise TypeError(f"Cannot restore Specifier from {state!r}") - - @property - def operator(self) -> str: - """The operator of this specifier. - - >>> Specifier("==1.2.3").operator - '==' - """ - return self._spec[0] - - @property - def version(self) -> str: - """The version of this specifier. - - >>> Specifier("==1.2.3").version - '1.2.3' - """ - return self._spec[1] - - def __repr__(self) -> str: - """A representation of the Specifier that shows all internal state. - - >>> Specifier('>=1.0.0') - =1.0.0')> - >>> Specifier('>=1.0.0', prereleases=False) - =1.0.0', prereleases=False)> - >>> Specifier('>=1.0.0', prereleases=True) - =1.0.0', prereleases=True)> - """ - pre = ( - f", prereleases={self.prereleases!r}" - if self._prereleases is not None - else "" - ) - - return f"<{self.__class__.__name__}({str(self)!r}{pre})>" - - def __str__(self) -> str: - """A string representation of the Specifier that can be round-tripped. - - >>> str(Specifier('>=1.0.0')) - '>=1.0.0' - >>> str(Specifier('>=1.0.0', prereleases=False)) - '>=1.0.0' - """ - return "{}{}".format(*self._spec) - - @property - def _canonical_spec(self) -> tuple[str, str]: - operator, version = self._spec - if operator == "===" or version.endswith(".*"): - return operator, version - - spec_version = self._require_spec_version(version) - - canonical_version = canonicalize_version( - spec_version, strip_trailing_zero=(operator != "~=") - ) - - return operator, canonical_version - - def __hash__(self) -> int: - return hash(self._canonical_spec) - - def __eq__(self, other: object) -> bool: - """Whether or not the two Specifier-like objects are equal. - - :param other: The other object to check against. - - The value of :attr:`prereleases` is ignored. - - >>> Specifier("==1.2.3") == Specifier("== 1.2.3.0") - True - >>> (Specifier("==1.2.3", prereleases=False) == - ... Specifier("==1.2.3", prereleases=True)) - True - >>> Specifier("==1.2.3") == "==1.2.3" - True - >>> Specifier("==1.2.3") == Specifier("==1.2.4") - False - >>> Specifier("==1.2.3") == Specifier("~=1.2.3") - False - """ - if isinstance(other, str): - try: - other = self.__class__(str(other)) - except InvalidSpecifier: - return NotImplemented - elif not isinstance(other, self.__class__): - return NotImplemented - - return self._canonical_spec == other._canonical_spec - - def _get_operator(self, op: str) -> CallableOperator: - operator_callable: CallableOperator = getattr( - self, f"_compare_{self._operators[op]}" - ) - return operator_callable - - def _compare_compatible(self, prospective: Version, spec: str) -> bool: - # Compatible releases have an equivalent combination of >= and ==. That - # is that ~=2.2 is equivalent to >=2.2,==2.*. This allows us to - # implement this in terms of the other specifiers instead of - # 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 suffix segments. - prefix = _version_join( - list(itertools.takewhile(_is_not_suffix, _version_split(spec)))[:-1] - ) - - # Add the prefix notation to the end of our string - prefix += ".*" - - return (self._compare_greater_than_equal(prospective, spec)) and ( - self._compare_equal(prospective, prefix) - ) - - def _get_wildcard_split(self, spec: str) -> tuple[list[str], int]: - """Cached split of a wildcard spec into components and numeric length. - - >>> Specifier("==1.*")._get_wildcard_split("1.*") - (['0', '1'], 2) - >>> Specifier("==3.10.*")._get_wildcard_split("3.10.*") - (['0', '3', '10'], 3) - """ - wildcard_split = self._wildcard_split - if wildcard_split is None: - normalized = canonicalize_version(spec[:-2], strip_trailing_zero=False) - split_spec = _version_split(normalized) - wildcard_split = (split_spec, _numeric_prefix_len(split_spec)) - self._wildcard_split = wildcard_split - return wildcard_split - - def _compare_equal(self, prospective: Version, spec: str) -> bool: - # We need special logic to handle prefix matching - if spec.endswith(".*"): - split_spec, spec_numeric_len = self._get_wildcard_split(spec) - - # In the case of prefix matching we want to ignore local segment. - normalized_prospective = canonicalize_version( - _public_version(prospective), strip_trailing_zero=False - ) - # Split the prospective version out by bangs and dots, and pretend - # that there is an implicit dot in between a release segment and - # a pre-release segment. - split_prospective = _version_split(normalized_prospective) - - # 0-pad the prospective version before shortening it to get the correct - # shortened version. - padded_prospective = _left_pad(split_prospective, spec_numeric_len) - - # 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. - shortened_prospective = padded_prospective[: len(split_spec)] - - return shortened_prospective == split_spec - else: - # Convert our spec string into a Version - spec_version = self._require_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_version.local: - prospective = _public_version(prospective) - - return prospective == spec_version - - def _compare_not_equal(self, prospective: Version, spec: str) -> bool: - return not self._compare_equal(prospective, spec) - - def _compare_less_than_equal(self, prospective: Version, spec: str) -> bool: - # NB: Local version identifiers are NOT permitted in the version - # specifier, so local version labels can be universally removed from - # the prospective version. - return _public_version(prospective) <= self._require_spec_version(spec) - - def _compare_greater_than_equal(self, prospective: Version, spec: str) -> bool: - # NB: Local version identifiers are NOT permitted in the version - # specifier, so local version labels can be universally removed from - # the prospective version. - return _public_version(prospective) >= self._require_spec_version(spec) - - def _compare_less_than(self, prospective: Version, spec_str: str) -> bool: - # Convert our spec to a Version instance, since we'll want to work with - # it as a version. - spec = self._require_spec_version(spec_str) - - # Check to see if the prospective version is less than the spec - # version. If it's not we can short circuit and just return False now - # instead of doing extra unneeded work. - if not prospective < spec: - return False - - # The spec says: "= _earliest_prerelease(spec) - ): - 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 - - def _compare_greater_than(self, prospective: Version, spec_str: str) -> bool: - # Convert our spec to a Version instance, since we'll want to work with - # it as a version. - spec = self._require_spec_version(spec_str) - - # Check to see if the prospective version is greater than the spec - # version. If it's not we can short circuit and just return False now - # instead of doing extra unneeded work. - if not prospective > spec: - return False - - # The spec says: ">V MUST NOT allow a post-release of the specified - # version unless the specified version is itself a post-release." - if ( - not spec.is_postrelease - and prospective.is_postrelease - and _post_base(prospective) == spec - ): - return False - - # Per the spec: ">V MUST NOT match a local version of the specified - # version". A "local version of V" is any version whose public part - # equals V. So >1.0a1 must not match 1.0a1+local, but must still - # match 1.0a2+local. - if prospective.local is not None and _public_version(prospective) == spec: - 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: Version | str, spec: str) -> bool: - return str(prospective).lower() == str(spec).lower() - - def __contains__(self, item: str | Version) -> bool: - """Return whether or not the item is contained in this specifier. - - :param item: The item to check for. - - This is used for the ``in`` operator and behaves the same as - :meth:`contains` with no ``prereleases`` argument passed. - - >>> "1.2.3" in Specifier(">=1.2.3") - True - >>> Version("1.2.3") in Specifier(">=1.2.3") - True - >>> "1.0.0" in Specifier(">=1.2.3") - False - >>> "1.3.0a1" in Specifier(">=1.2.3") - True - >>> "1.3.0a1" in Specifier(">=1.2.3", prereleases=True) - True - """ - return self.contains(item) - - def contains(self, item: UnparsedVersion, prereleases: bool | None = None) -> bool: - """Return whether or not the item is contained in this specifier. - - :param item: - The item to check for, which can be a version string or a - :class:`Version` instance. - :param prereleases: - Whether or not to match prereleases with this Specifier. If set to - ``None`` (the default), it will follow the recommendation from - :pep:`440` and match prereleases, as there are no other versions. - - >>> Specifier(">=1.2.3").contains("1.2.3") - True - >>> Specifier(">=1.2.3").contains(Version("1.2.3")) - True - >>> Specifier(">=1.2.3").contains("1.0.0") - False - >>> Specifier(">=1.2.3").contains("1.3.0a1") - True - >>> Specifier(">=1.2.3", prereleases=False).contains("1.3.0a1") - False - >>> Specifier(">=1.2.3").contains("1.3.0a1") - True - """ - - return bool(list(self.filter([item], prereleases=prereleases))) - - @typing.overload - def filter( - self, - iterable: Iterable[UnparsedVersionVar], - prereleases: bool | None = None, - key: None = ..., - ) -> Iterator[UnparsedVersionVar]: ... - - @typing.overload - def filter( - self, - iterable: Iterable[T], - prereleases: bool | None = None, - key: Callable[[T], UnparsedVersion] = ..., - ) -> Iterator[T]: ... - - def filter( - self, - iterable: Iterable[Any], - prereleases: bool | None = None, - key: Callable[[Any], UnparsedVersion] | None = None, - ) -> Iterator[Any]: - """Filter items in the given iterable, that match the specifier. - - :param iterable: - An iterable that can contain version strings and :class:`Version` instances. - The items in the iterable will be filtered according to the specifier. - :param prereleases: - Whether or not to allow prereleases in the returned iterator. If set to - ``None`` (the default), it will follow the recommendation from :pep:`440` - and match prereleases if there are no other versions. - :param key: - A callable that takes a single argument (an item from the iterable) and - returns a version string or :class:`Version` instance to be used for - filtering. - - >>> list(Specifier(">=1.2.3").filter(["1.2", "1.3", "1.5a1"])) - ['1.3'] - >>> list(Specifier(">=1.2.3").filter(["1.2", "1.2.3", "1.3", Version("1.4")])) - ['1.2.3', '1.3', ] - >>> list(Specifier(">=1.2.3").filter(["1.2", "1.5a1"])) - ['1.5a1'] - >>> list(Specifier(">=1.2.3").filter(["1.3", "1.5a1"], prereleases=True)) - ['1.3', '1.5a1'] - >>> list(Specifier(">=1.2.3", prereleases=True).filter(["1.3", "1.5a1"])) - ['1.3', '1.5a1'] - >>> list(Specifier(">=1.2.3").filter( - ... [{"ver": "1.2"}, {"ver": "1.3"}], - ... key=lambda x: x["ver"])) - [{'ver': '1.3'}] - """ - prereleases_versions = [] - found_non_prereleases = False - - # Determine if to include prereleases by default - include_prereleases = ( - prereleases if prereleases is not None else self.prereleases - ) - - # Get the matching operator - operator_callable = self._get_operator(self.operator) - - # Filter versions - for version in iterable: - parsed_version = _coerce_version(version if key is None else key(version)) - match = False - if parsed_version is None: - # === operator can match arbitrary (non-version) strings - if self.operator == "===" and self._compare_arbitrary( - version, self.version - ): - yield version - elif self.operator == "===": - match = self._compare_arbitrary( - version if key is None else key(version), self.version - ) - else: - match = operator_callable(parsed_version, self.version) - - if match and parsed_version is not None: - # If it's not a prerelease or prereleases are allowed, yield it directly - if not parsed_version.is_prerelease or include_prereleases: - found_non_prereleases = True - yield version - # Otherwise collect prereleases for potential later use - elif prereleases is None and self._prereleases is not False: - prereleases_versions.append(version) - - # If no non-prereleases were found and prereleases weren't - # explicitly forbidden, yield the collected prereleases - if ( - not found_non_prereleases - and prereleases is None - and self._prereleases is not False - ): - yield from prereleases_versions - - -_prefix_regex = re.compile(r"([0-9]+)((?:a|b|c|rc)[0-9]+)") - - -def _pep440_filter_prereleases( - iterable: Iterable[Any], key: Callable[[Any], UnparsedVersion] | None -) -> Iterator[Any]: - """Filter per PEP 440: exclude prereleases unless no finals exist.""" - # Two lists used: - # * all_nonfinal to preserve order if no finals exist - # * arbitrary_strings for streaming when first final found - all_nonfinal: list[Any] = [] - arbitrary_strings: list[Any] = [] - - found_final = False - for item in iterable: - parsed = _coerce_version(item if key is None else key(item)) - - if parsed is None: - # Arbitrary strings are always included as it is not - # possible to determine if they are prereleases, - # and they have already passed all specifiers. - if found_final: - yield item - else: - arbitrary_strings.append(item) - all_nonfinal.append(item) - continue - - if not parsed.is_prerelease: - # Final release found - flush arbitrary strings, then yield - if not found_final: - yield from arbitrary_strings - found_final = True - yield item - continue - - # Prerelease - buffer if no finals yet, otherwise skip - if not found_final: - all_nonfinal.append(item) - - # No finals found - yield all buffered items - if not found_final: - yield from all_nonfinal - - -def _version_split(version: str) -> list[str]: - """Split version into components. - - The split components are intended for version comparison. The logic does - not attempt to retain the original version string, so joining the - components back with :func:`_version_join` may not produce the original - version string. - """ - result: list[str] = [] - - epoch, _, rest = version.rpartition("!") - result.append(epoch or "0") - - for item in rest.split("."): - match = _prefix_regex.fullmatch(item) - if match: - result.extend(match.groups()) - else: - result.append(item) - return result - - -def _version_join(components: list[str]) -> str: - """Join split version components into a version string. - - This function assumes the input came from :func:`_version_split`, where the - first component must be the epoch (either empty or numeric), and all other - components numeric. - """ - epoch, *rest = components - return f"{epoch}!{'.'.join(rest)}" - - -def _is_not_suffix(segment: str) -> bool: - return not any( - segment.startswith(prefix) for prefix in ("dev", "a", "b", "rc", "post") - ) - - -def _numeric_prefix_len(split: list[str]) -> int: - """Count leading numeric components in a :func:`_version_split` result. - - >>> _numeric_prefix_len(["0", "1", "2", "a1"]) - 3 - """ - count = 0 - for segment in split: - if not segment.isdigit(): - break - count += 1 - return count - - -def _left_pad(split: list[str], target_numeric_len: int) -> list[str]: - """Pad a :func:`_version_split` result with ``"0"`` segments to reach - ``target_numeric_len`` numeric components. Suffix segments are preserved. - - >>> _left_pad(["0", "1", "a1"], 4) - ['0', '1', '0', '0', 'a1'] - """ - numeric_len = _numeric_prefix_len(split) - pad_needed = target_numeric_len - numeric_len - if pad_needed <= 0: - return split - return [*split[:numeric_len], *(["0"] * pad_needed), *split[numeric_len:]] - - -def _operator_cost(op_entry: tuple[CallableOperator, str, str]) -> int: - """Sort key for Cost Based Ordering of specifier operators in _filter_versions. - - Operators run sequentially on a shrinking candidate set, so operators that - reject the most versions should run first to minimize work for later ones. - - Tier 0: Exact equality (==, ===), likely to narrow candidates to one version - Tier 1: Range checks (>=, <=, >, <), cheap and usually reject a large portion - Tier 2: Wildcard equality (==.*) and compatible release (~=), more expensive - Tier 3: Exact !=, cheap but rarely rejects - Tier 4: Wildcard !=.*, expensive and rarely rejects - """ - _, ver, op = op_entry - if op == "==": - return 0 if not ver.endswith(".*") else 2 - if op in (">=", "<=", ">", "<"): - return 1 - if op == "~=": - return 2 - if op == "!=": - return 3 if not ver.endswith(".*") else 4 - if op == "===": - return 0 - - raise ValueError(f"Unknown operator: {op!r}") # pragma: no cover - - -class SpecifierSet(BaseSpecifier): - """This class abstracts handling of a set of version specifiers. - - It can be passed a single specifier (``>=3.0``), a comma-separated list of - specifiers (``>=3.0,!=3.1``), or no specifier at all. - - Instances are safe to serialize with :mod:`pickle`. They use a stable - format so the same pickle can be loaded in future packaging - releases. - - .. versionchanged:: 26.2 - - Added a stable pickle format. Pickles created with - packaging 26.2+ can be unpickled with future releases. - Backward compatibility with pickles from - packaging < 26.2 is supported but may be removed in a future - release. - """ - - __slots__ = ( - "_canonicalized", - "_has_arbitrary", - "_is_unsatisfiable", - "_prereleases", - "_resolved_ops", - "_specs", - ) - - def __init__( - self, - specifiers: str | Iterable[Specifier] = "", - prereleases: bool | None = None, - ) -> None: - """Initialize a SpecifierSet instance. - - :param specifiers: - The string representation of a specifier or a comma-separated list of - specifiers which will be parsed and normalized before use. - May also be an iterable of ``Specifier`` instances, which will be used - as is. - :param prereleases: - This tells the SpecifierSet if it should accept prerelease versions if - applicable or not. The default of ``None`` will autodetect it from the - given specifiers. - - :raises InvalidSpecifier: - If the given ``specifiers`` are not parseable than this exception will be - raised. - """ - - if isinstance(specifiers, str): - # Split on `,` to break each individual specifier into its own item, and - # strip each item to remove leading/trailing whitespace. - split_specifiers = [s.strip() for s in specifiers.split(",") if s.strip()] - - self._specs: tuple[Specifier, ...] = tuple(map(Specifier, split_specifiers)) - # Fast substring check; avoids iterating parsed specs. - self._has_arbitrary = "===" in specifiers - else: - self._specs = tuple(specifiers) - # Substring check works for both Specifier objects and plain - # strings (setuptools passes lists of strings). - self._has_arbitrary = any("===" in str(s) for s in self._specs) - - self._canonicalized = len(self._specs) <= 1 - self._resolved_ops: list[tuple[CallableOperator, str, str]] | None = None - - # Store our prereleases value so we can use it later to determine if - # we accept prereleases or not. - self._prereleases = prereleases - - self._is_unsatisfiable: bool | None = None - - def _canonical_specs(self) -> tuple[Specifier, ...]: - """Deduplicate, sort, and cache specs for order-sensitive operations.""" - if not self._canonicalized: - self._specs = tuple(dict.fromkeys(sorted(self._specs, key=str))) - self._canonicalized = True - self._resolved_ops = None - self._is_unsatisfiable = None - return self._specs - - @property - def prereleases(self) -> bool | None: - # 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. - if any(s.prereleases for s in self._specs): - return True - - return None - - @prereleases.setter - def prereleases(self, value: bool | None) -> None: - self._prereleases = value - self._is_unsatisfiable = None - - def __getstate__(self) -> tuple[tuple[Specifier, ...], bool | None]: - # Return state as a 2-item tuple for compactness: - # (specs, prereleases) - # Cache members are excluded and will be recomputed on demand. - return (self._specs, self._prereleases) - - def __setstate__(self, state: object) -> None: - # Always discard cached values - they will be recomputed on demand. - self._resolved_ops = None - self._is_unsatisfiable = None - - if isinstance(state, tuple): - if len(state) == 2: - # New format (26.2+): (specs, prereleases) - specs, prereleases = state - if ( - isinstance(specs, tuple) - and all(isinstance(s, Specifier) for s in specs) - and _validate_pre(prereleases) - ): - self._specs = specs - self._prereleases = prereleases - self._canonicalized = len(specs) <= 1 - self._has_arbitrary = any("===" in str(s) for s in specs) - return - if len(state) == 2 and isinstance(state[1], dict): - # Format (packaging 26.0-26.1): (None, {slot: value}). - _, slot_dict = state - specs = slot_dict.get("_specs", ()) - prereleases = slot_dict.get("_prereleases") - # Convert frozenset to tuple (26.0 stored as frozenset) - if isinstance(specs, frozenset): - specs = tuple(sorted(specs, key=str)) - if ( - isinstance(specs, tuple) - and all(isinstance(s, Specifier) for s in specs) - and _validate_pre(prereleases) - ): - self._specs = specs - self._prereleases = prereleases - self._canonicalized = len(self._specs) <= 1 - self._has_arbitrary = any("===" in str(s) for s in self._specs) - return - if isinstance(state, dict): - # Old format (packaging <= 25.x, no __slots__): state is a plain dict. - specs = state.get("_specs", ()) - prereleases = state.get("_prereleases") - # Convert frozenset to tuple (26.0 stored as frozenset) - if isinstance(specs, frozenset): - specs = tuple(sorted(specs, key=str)) - if ( - isinstance(specs, tuple) - and all(isinstance(s, Specifier) for s in specs) - and _validate_pre(prereleases) - ): - self._specs = specs - self._prereleases = prereleases - self._canonicalized = len(self._specs) <= 1 - self._has_arbitrary = any("===" in str(s) for s in self._specs) - return - - raise TypeError(f"Cannot restore SpecifierSet from {state!r}") - - def __repr__(self) -> str: - """A representation of the specifier set that shows all internal state. - - Note that the ordering of the individual specifiers within the set may not - match the input string. - - >>> SpecifierSet('>=1.0.0,!=2.0.0') - =1.0.0')> - >>> SpecifierSet('>=1.0.0,!=2.0.0', prereleases=False) - =1.0.0', prereleases=False)> - >>> SpecifierSet('>=1.0.0,!=2.0.0', prereleases=True) - =1.0.0', prereleases=True)> - """ - pre = ( - f", prereleases={self.prereleases!r}" - if self._prereleases is not None - else "" - ) - - return f"<{self.__class__.__name__}({str(self)!r}{pre})>" - - def __str__(self) -> str: - """A string representation of the specifier set that can be round-tripped. - - Note that the ordering of the individual specifiers within the set may not - match the input string. - - >>> str(SpecifierSet(">=1.0.0,!=1.0.1")) - '!=1.0.1,>=1.0.0' - >>> str(SpecifierSet(">=1.0.0,!=1.0.1", prereleases=False)) - '!=1.0.1,>=1.0.0' - """ - return ",".join(str(s) for s in self._canonical_specs()) - - def __hash__(self) -> int: - return hash(self._canonical_specs()) - - def __and__(self, other: SpecifierSet | str) -> SpecifierSet: - """Return a SpecifierSet which is a combination of the two sets. - - :param other: The other object to combine with. - - >>> SpecifierSet(">=1.0.0,!=1.0.1") & '<=2.0.0,!=2.0.1' - =1.0.0')> - >>> SpecifierSet(">=1.0.0,!=1.0.1") & SpecifierSet('<=2.0.0,!=2.0.1') - =1.0.0')> - """ - if isinstance(other, str): - other = SpecifierSet(other) - elif not isinstance(other, SpecifierSet): - return NotImplemented - - specifier = SpecifierSet() - specifier._specs = self._specs + other._specs - specifier._canonicalized = len(specifier._specs) <= 1 - specifier._has_arbitrary = self._has_arbitrary or other._has_arbitrary - specifier._resolved_ops = None - - # Combine prerelease settings: use common or non-None value - if self._prereleases is None or self._prereleases == other._prereleases: - specifier._prereleases = other._prereleases - elif other._prereleases is None: - specifier._prereleases = self._prereleases - else: - raise ValueError( - "Cannot combine SpecifierSets with True and False prerelease overrides." - ) - - return specifier - - def __eq__(self, other: object) -> bool: - """Whether or not the two SpecifierSet-like objects are equal. - - :param other: The other object to check against. - - The value of :attr:`prereleases` is ignored. - - >>> SpecifierSet(">=1.0.0,!=1.0.1") == SpecifierSet(">=1.0.0,!=1.0.1") - True - >>> (SpecifierSet(">=1.0.0,!=1.0.1", prereleases=False) == - ... SpecifierSet(">=1.0.0,!=1.0.1", prereleases=True)) - True - >>> SpecifierSet(">=1.0.0,!=1.0.1") == ">=1.0.0,!=1.0.1" - True - >>> SpecifierSet(">=1.0.0,!=1.0.1") == SpecifierSet(">=1.0.0") - False - >>> SpecifierSet(">=1.0.0,!=1.0.1") == SpecifierSet(">=1.0.0,!=1.0.2") - False - """ - if isinstance(other, (str, Specifier)): - other = SpecifierSet(str(other)) - elif not isinstance(other, SpecifierSet): - return NotImplemented - - return self._canonical_specs() == other._canonical_specs() - - def __len__(self) -> int: - """Returns the number of specifiers in this specifier set.""" - return len(self._specs) - - def __iter__(self) -> Iterator[Specifier]: - """ - Returns an iterator over all the underlying :class:`Specifier` instances - in this specifier set. - - >>> sorted(SpecifierSet(">=1.0.0,!=1.0.1"), key=str) - [, =1.0.0')>] - """ - return iter(self._specs) - - def _get_ranges(self) -> Sequence[_VersionRange]: - """Intersect all specifiers into a single list of version ranges. - - Returns an empty list when unsatisfiable. ``===`` specs are - modeled as full range; string matching is checked separately - by :meth:`_check_arbitrary_unsatisfiable`. - """ - specs = self._specs - - result: Sequence[_VersionRange] | None = None - for s in specs: - if result is None: - result = s._to_ranges() - else: - result = _intersect_ranges(result, s._to_ranges()) - if not result: - break - - if result is None: # pragma: no cover - raise RuntimeError("_get_ranges called with no specs") - return result - - def is_unsatisfiable(self) -> bool: - """Check whether this specifier set can never be satisfied. - - Returns True if no version can satisfy all specifiers simultaneously. - - >>> SpecifierSet(">=2.0,<1.0").is_unsatisfiable() - True - >>> SpecifierSet(">=1.0,<2.0").is_unsatisfiable() - False - >>> SpecifierSet("").is_unsatisfiable() - False - >>> SpecifierSet("==1.0,!=1.0").is_unsatisfiable() - True - """ - cached = self._is_unsatisfiable - if cached is not None: - return cached - - if not self._specs: - self._is_unsatisfiable = False - return False - - result = not self._get_ranges() - - if not result: - result = self._check_arbitrary_unsatisfiable() - - if not result and self.prereleases is False: - result = self._check_prerelease_only_ranges() - - self._is_unsatisfiable = result - return result - - def _check_prerelease_only_ranges(self) -> bool: - """With prereleases=False, check if every range contains only - pre-release versions (which would be excluded from matching).""" - for lower, upper in self._get_ranges(): - nearest = _nearest_non_prerelease(lower.version) - if nearest is None: - return False - if upper.version is None or nearest < upper.version: - return False - if nearest == upper.version and upper.inclusive: - return False - return True - - def _check_arbitrary_unsatisfiable(self) -> bool: - """Check === (arbitrary equality) specs for unsatisfiability. - - === uses case-insensitive string comparison, so the only candidate - that can match ``===V`` is the literal string V. This method - checks whether that candidate is excluded by other specifiers. - """ - arbitrary = [s for s in self._specs if s.operator == "==="] - if not arbitrary: - return False - - # Multiple === must agree on the same string (case-insensitive). - first = arbitrary[0].version.lower() - if any(s.version.lower() != first for s in arbitrary[1:]): - return True - - # The sole candidate is the === version string. Check whether - # it can satisfy every standard spec. - candidate = _coerce_version(arbitrary[0].version) - - # With prereleases=False, a prerelease candidate is excluded - # by contains() before the === string check even runs. - if ( - self.prereleases is False - and candidate is not None - and candidate.is_prerelease - ): - return True - - standard = [s for s in self._specs if s.operator != "==="] - if not standard: - return False - - if candidate is None: - # Unparsable string cannot satisfy any standard spec. - return True - - return not all(s.contains(candidate) for s in standard) - - def __contains__(self, item: UnparsedVersion) -> bool: - """Return whether or not the item is contained in this specifier. - - :param item: The item to check for. - - This is used for the ``in`` operator and behaves the same as - :meth:`contains` with no ``prereleases`` argument passed. - - >>> "1.2.3" in SpecifierSet(">=1.0.0,!=1.0.1") - True - >>> Version("1.2.3") in SpecifierSet(">=1.0.0,!=1.0.1") - True - >>> "1.0.1" in SpecifierSet(">=1.0.0,!=1.0.1") - False - >>> "1.3.0a1" in SpecifierSet(">=1.0.0,!=1.0.1") - True - >>> "1.3.0a1" in SpecifierSet(">=1.0.0,!=1.0.1", prereleases=True) - True - """ - return self.contains(item) - - def contains( - self, - item: UnparsedVersion, - prereleases: bool | None = None, - installed: bool | None = None, - ) -> bool: - """Return whether or not the item is contained in this SpecifierSet. - - :param item: - The item to check for, which can be a version string or a - :class:`Version` instance. - :param prereleases: - Whether or not to match prereleases with this SpecifierSet. If set to - ``None`` (the default), it will follow the recommendation from :pep:`440` - and match prereleases, as there are no other versions. - :param installed: - Whether or not the item is installed. If set to ``True``, it will - accept prerelease versions even if the specifier does not allow them. - - >>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.2.3") - True - >>> SpecifierSet(">=1.0.0,!=1.0.1").contains(Version("1.2.3")) - True - >>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.0.1") - False - >>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.3.0a1") - True - >>> SpecifierSet(">=1.0.0,!=1.0.1", prereleases=False).contains("1.3.0a1") - False - >>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.3.0a1", prereleases=True) - True - """ - version = _coerce_version(item) - - if version is not None and installed and version.is_prerelease: - prereleases = True - - # When item is a string and === is involved, keep it as-is - # so the comparison isn't done against the normalized form. - if version is None or (self._has_arbitrary and not isinstance(item, Version)): - check_item = item - else: - check_item = version - return bool(list(self.filter([check_item], prereleases=prereleases))) - - @typing.overload - def filter( - self, - iterable: Iterable[UnparsedVersionVar], - prereleases: bool | None = None, - key: None = ..., - ) -> Iterator[UnparsedVersionVar]: ... - - @typing.overload - def filter( - self, - iterable: Iterable[T], - prereleases: bool | None = None, - key: Callable[[T], UnparsedVersion] = ..., - ) -> Iterator[T]: ... - - def filter( - self, - iterable: Iterable[Any], - prereleases: bool | None = None, - key: Callable[[Any], UnparsedVersion] | None = None, - ) -> Iterator[Any]: - """Filter items in the given iterable, that match the specifiers in this set. - - :param iterable: - An iterable that can contain version strings and :class:`Version` instances. - The items in the iterable will be filtered according to the specifier. - :param prereleases: - Whether or not to allow prereleases in the returned iterator. If set to - ``None`` (the default), it will follow the recommendation from :pep:`440` - and match prereleases if there are no other versions. - :param key: - A callable that takes a single argument (an item from the iterable) and - returns a version string or :class:`Version` instance to be used for - filtering. - - >>> list(SpecifierSet(">=1.2.3").filter(["1.2", "1.3", "1.5a1"])) - ['1.3'] - >>> list(SpecifierSet(">=1.2.3").filter(["1.2", "1.3", Version("1.4")])) - ['1.3', ] - >>> list(SpecifierSet(">=1.2.3").filter(["1.2", "1.5a1"])) - ['1.5a1'] - >>> list(SpecifierSet(">=1.2.3").filter(["1.3", "1.5a1"], prereleases=True)) - ['1.3', '1.5a1'] - >>> list(SpecifierSet(">=1.2.3", prereleases=True).filter(["1.3", "1.5a1"])) - ['1.3', '1.5a1'] - >>> list(SpecifierSet(">=1.2.3").filter( - ... [{"ver": "1.2"}, {"ver": "1.3"}], - ... key=lambda x: x["ver"])) - [{'ver': '1.3'}] - - An "empty" SpecifierSet will filter items based on the presence of prerelease - versions in the set. - - >>> list(SpecifierSet("").filter(["1.3", "1.5a1"])) - ['1.3'] - >>> list(SpecifierSet("").filter(["1.5a1"])) - ['1.5a1'] - >>> list(SpecifierSet("", prereleases=True).filter(["1.3", "1.5a1"])) - ['1.3', '1.5a1'] - >>> list(SpecifierSet("").filter(["1.3", "1.5a1"], prereleases=True)) - ['1.3', '1.5a1'] - """ - # 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 and self.prereleases is not None: - prereleases = self.prereleases - - # Filter versions that match all specifiers using Cost Based Ordering. - if self._specs: - # When prereleases is None, we need to let all versions through - # the individual filters, then decide about prereleases at the end - # based on whether any non-prereleases matched ALL specs. - - # Fast path: single specifier, delegate directly. - if len(self._specs) == 1: - filtered = self._specs[0].filter( - iterable, - prereleases=True if prereleases is None else prereleases, - key=key, - ) - else: - filtered = self._filter_versions( - iterable, - key, - prereleases=True if prereleases is None else prereleases, - ) - - if prereleases is not None: - return filtered - - return _pep440_filter_prereleases(filtered, key) - - # Handle Empty SpecifierSet. - if prereleases is True: - return iter(iterable) - - if prereleases is False: - return ( - item - for item in iterable - if ( - (version := _coerce_version(item if key is None else key(item))) - is None - or not version.is_prerelease - ) - ) - - # PEP 440: exclude prereleases unless no final releases matched - return _pep440_filter_prereleases(iterable, key) - - def _filter_versions( - self, - iterable: Iterable[Any], - key: Callable[[Any], UnparsedVersion] | None, - prereleases: bool | None = None, - ) -> Iterator[Any]: - """Filter versions against all specifiers in a single pass. - - Uses Cost Based Ordering: specifiers are sorted by _operator_cost so - that cheap range operators reject versions early, avoiding expensive - wildcard or compatible operators on versions that would have been - rejected anyway. - """ - # Pre-resolve operators and sort (cached after first call). - if self._resolved_ops is None: - self._resolved_ops = sorted( - ( - (spec._get_operator(spec.operator), spec.version, spec.operator) - for spec in self._specs - ), - key=_operator_cost, - ) - ops = self._resolved_ops - exclude_prereleases = prereleases is False - - for item in iterable: - parsed = _coerce_version(item if key is None else key(item)) - - if parsed is None: - # Only === can match non-parseable versions. - if all( - op == "===" and str(item).lower() == ver.lower() - for _, ver, op in ops - ): - yield item - elif exclude_prereleases and parsed.is_prerelease: - pass - elif all( - str(item if key is None else key(item)).lower() == ver.lower() - if op == "===" - else op_fn(parsed, ver) - for op_fn, ver, op in ops - ): - # Short-circuits on the first failing operator. - yield item diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/tags.py b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/tags.py deleted file mode 100755 index 979fbd2..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/tags.py +++ /dev/null @@ -1,932 +0,0 @@ -# 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 annotations - -import logging -import operator -import platform -import re -import struct -import subprocess -import sys -import sysconfig -from importlib.machinery import EXTENSION_SUFFIXES -from typing import ( - TYPE_CHECKING, - Iterable, - Iterator, - Sequence, - Tuple, - TypeVar, - cast, -) - -from . import _manylinux, _musllinux - -if TYPE_CHECKING: - from collections.abc import Callable, Iterable - from typing import AbstractSet - - -__all__ = [ - "INTERPRETER_SHORT_NAMES", - "AppleVersion", - "PythonVersion", - "Tag", - "UnsortedTagsError", - "android_platforms", - "compatible_tags", - "cpython_tags", - "create_compatible_tags_selector", - "generic_tags", - "interpreter_name", - "interpreter_version", - "ios_platforms", - "mac_platforms", - "parse_tag", - "platform_tags", - "sys_tags", -] - - -def __dir__() -> list[str]: - return __all__ - - -logger = logging.getLogger(__name__) - -PythonVersion = Sequence[int] -AppleVersion = Tuple[int, int] -_T = TypeVar("_T") - -INTERPRETER_SHORT_NAMES: dict[str, str] = { - "python": "py", # Generic. - "cpython": "cp", - "pypy": "pp", - "ironpython": "ip", - "jython": "jy", -} - - -# This function can be unit tested without reloading the module -# (Unlike _32_BIT_INTERPRETER) -def _compute_32_bit_interpreter() -> bool: - return struct.calcsize("P") == 4 - - -_32_BIT_INTERPRETER = _compute_32_bit_interpreter() - - -class UnsortedTagsError(ValueError): - """ - Raised when a tag component is not in sorted order per PEP 425. - """ - - -class Tag: - """ - A representation of the tag triple for a wheel. - - Instances are considered immutable and thus are hashable. Equality checking - is also supported. - - Instances are safe to serialize with :mod:`pickle`. They use a stable - format so the same pickle can be loaded in future packaging releases. - - .. versionchanged:: 26.2 - - Added a stable pickle format. Pickles created with packaging 26.2+ can - be unpickled with future releases. Backward compatibility with pickles - from pip._vendor.packaging < 26.2 is supported but may be removed in a future - release. - """ - - __slots__ = ["_abi", "_hash", "_interpreter", "_platform"] - - def __init__(self, interpreter: str, abi: str, platform: str) -> None: - """ - :param str interpreter: The interpreter name, e.g. ``"py"`` - (see :attr:`INTERPRETER_SHORT_NAMES` for mapping - well-known interpreter names to their short names). - :param str abi: The ABI that a wheel supports, e.g. ``"cp37m"``. - :param str platform: The OS/platform the wheel supports, - e.g. ``"win_amd64"``. - """ - self._interpreter = interpreter.lower() - self._abi = abi.lower() - self._platform = platform.lower() - # The __hash__ of every single element in a Set[Tag] will be evaluated each time - # that a set calls its `.disjoint()` method, which may be called hundreds of - # times when scanning a page of links for packages with tags matching that - # Set[Tag]. Pre-computing the value here produces significant speedups for - # downstream consumers. - self._hash = hash((self._interpreter, self._abi, self._platform)) - - @property - def interpreter(self) -> str: - """ - The interpreter name, e.g. ``"py"`` (see - :attr:`INTERPRETER_SHORT_NAMES` for mapping well-known interpreter - names to their short names). - """ - return self._interpreter - - @property - def abi(self) -> str: - """ - The supported ABI. - """ - return self._abi - - @property - def platform(self) -> str: - """ - The OS/platform. - """ - return self._platform - - def __eq__(self, other: object) -> bool: - if not isinstance(other, Tag): - return NotImplemented - - return ( - (self._hash == other._hash) # Short-circuit ASAP for perf reasons. - and (self._platform == other._platform) - and (self._abi == other._abi) - and (self._interpreter == other._interpreter) - ) - - def __hash__(self) -> int: - return self._hash - - def __str__(self) -> str: - return f"{self._interpreter}-{self._abi}-{self._platform}" - - def __repr__(self) -> str: - return f"<{self} @ {id(self)}>" - - def __getstate__(self) -> tuple[str, str, str]: - # Return state as a 3-item tuple: (interpreter, abi, platform). - # Cache member _hash is excluded and will be recomputed. - return (self._interpreter, self._abi, self._platform) - - def __setstate__(self, state: object) -> None: - if isinstance(state, tuple): - if len(state) == 3 and all(isinstance(s, str) for s in state): - # New format (26.2+): (interpreter, abi, platform) - self._interpreter, self._abi, self._platform = state - self._hash = hash((self._interpreter, self._abi, self._platform)) - return - if len(state) == 2 and isinstance(state[1], dict): - # Old format (packaging <= 26.1, __slots__): (None, {slot: value}). - _, slots = state - try: - interpreter = slots["_interpreter"] - abi = slots["_abi"] - platform = slots["_platform"] - except KeyError: - raise TypeError(f"Cannot restore Tag from {state!r}") from None - if not all( - isinstance(value, str) for value in (interpreter, abi, platform) - ): - raise TypeError(f"Cannot restore Tag from {state!r}") - self._interpreter = interpreter.lower() - self._abi = abi.lower() - self._platform = platform.lower() - self._hash = hash((self._interpreter, self._abi, self._platform)) - return - raise TypeError(f"Cannot restore Tag from {state!r}") - - -def parse_tag(tag: str, *, validate_order: bool = False) -> frozenset[Tag]: - """ - Parses the provided tag (e.g. `py3-none-any`) into a frozenset of - :class:`Tag` instances. - - Returning a set is required due to the possibility that the tag is a - `compressed tag set`_, e.g. ``"py2.py3-none-any"`` which supports both - Python 2 and Python 3. - - If **validate_order** is true, compressed tag set components are checked - to be in sorted order as required by PEP 425. - - :param str tag: The tag to parse, e.g. ``"py3-none-any"``. - :param bool validate_order: Check whether compressed tag set components - are in sorted order. - :raises UnsortedTagsError: If **validate_order** is true and any compressed tag - set component is not in sorted order. - - .. versionadded:: 26.1 - The *validate_order* parameter. - """ - tags = set() - interpreters, abis, platforms = tag.split("-") - if validate_order: - for component in (interpreters, abis, platforms): - parts = component.split(".") - if parts != sorted(parts): - raise UnsortedTagsError( - f"Tag component {component!r} is not in sorted order per PEP 425" - ) - for interpreter in interpreters.split("."): - for abi in abis.split("."): - for platform_ in platforms.split("."): - tags.add(Tag(interpreter, abi, platform_)) - return frozenset(tags) - - -def _get_config_var(name: str, warn: bool = False) -> int | str | None: - value: int | str | None = sysconfig.get_config_var(name) - if value is None and warn: - logger.debug( - "Config variable '%s' is unset, Python ABI tag may be incorrect", name - ) - return value - - -def _normalize_string(string: str) -> str: - return string.replace(".", "_").replace("-", "_").replace(" ", "_") - - -def _is_threaded_cpython(abis: list[str]) -> bool: - """ - Determine if the ABI corresponds to a threaded (`--disable-gil`) build. - - The threaded builds are indicated by a "t" in the abiflags. - """ - if len(abis) == 0: - return False - # expect e.g., cp313 - m = re.match(r"cp\d+(.*)", abis[0]) - if not m: - return False - abiflags = m.group(1) - return "t" in abiflags - - -def _abi3_applies(python_version: PythonVersion, threading: bool) -> bool: - """ - Determine if the Python version supports abi3. - - PEP 384 was first implemented in Python 3.2. The free-threaded - builds do not support abi3. - """ - return len(python_version) > 1 and tuple(python_version) >= (3, 2) and not threading - - -def _abi3t_applies(python_version: PythonVersion, threading: bool) -> bool: - """ - Determine if the Python version supports abi3t. - - PEP 803 was first implemented in Python 3.15 but, per PEP 803, this - returns tags going back to Python 3.2 to mirror the abi3 - implementation and leave open the possibility of abi3t wheels - supporting older Python versions. - - """ - return len(python_version) > 1 and tuple(python_version) >= (3, 2) and threading - - -def _cpython_abis(py_version: PythonVersion, warn: bool = False) -> list[str]: - py_version = tuple(py_version) # To allow for version comparison. - abis = [] - version = _version_nodot(py_version[:2]) - threading = debug = pymalloc = ucs4 = "" - with_debug = _get_config_var("Py_DEBUG", warn) - has_refcount = hasattr(sys, "gettotalrefcount") - # Windows doesn't set Py_DEBUG, so checking for support of debug-compiled - # extension modules is the best option. - # https://github.com/pypa/pip/issues/3383#issuecomment-173267692 - has_ext = "_d.pyd" in EXTENSION_SUFFIXES - if with_debug or (with_debug is None and (has_refcount or has_ext)): - debug = "d" - if py_version >= (3, 13) and _get_config_var("Py_GIL_DISABLED", warn): - threading = "t" - if py_version < (3, 8): - with_pymalloc = _get_config_var("WITH_PYMALLOC", warn) - if with_pymalloc or with_pymalloc is None: - pymalloc = "m" - if py_version < (3, 3): - unicode_size = _get_config_var("Py_UNICODE_SIZE", warn) - if unicode_size == 4 or ( - unicode_size is None and sys.maxunicode == 0x10FFFF - ): - ucs4 = "u" - elif debug: - # Debug builds can also load "normal" extension modules. - # We can also assume no UCS-4 or pymalloc requirement. - abis.append(f"cp{version}{threading}") - abis.insert(0, f"cp{version}{threading}{debug}{pymalloc}{ucs4}") - return abis - - -def cpython_tags( - python_version: PythonVersion | None = None, - abis: Iterable[str] | None = None, - platforms: Iterable[str] | None = None, - *, - warn: bool = False, -) -> Iterator[Tag]: - """ - Yields the tags for the CPython interpreter. - - The specific tags generated are: - - - ``cp--`` - - ``cp--`` - - ``cp-none-`` - - ``cp--`` where "older version" is all older - minor versions down to Python 3.2 (when ``abi3`` was introduced) - - If ``python_version`` only provides a major-only version then only - user-provided ABIs via ``abis`` and the ``none`` ABI will be used. - - The ``stable_abi`` will be either ``abi3`` or ``abi3t`` if `abi` is a - GIL-enabled ABI like `"cp315"` or a free-threaded ABI like `"cp315t"`, - respectively. - - :param Sequence python_version: A one- or two-item sequence representing the - targeted Python version. Defaults to - ``sys.version_info[:2]``. - :param Iterable abis: Iterable of compatible ABIs. Defaults to the ABIs - compatible with the current system. - :param Iterable platforms: Iterable of compatible platforms. Defaults to the - platforms compatible with the current system. - :param bool warn: Whether warnings should be logged. Defaults to ``False``. - """ - if not python_version: - python_version = sys.version_info[:2] - - interpreter = f"cp{_version_nodot(python_version[:2])}" - - if abis is None: - abis = _cpython_abis(python_version, warn) if len(python_version) > 1 else [] - abis = list(abis) - # 'abi3' and 'none' are explicitly handled later. - for explicit_abi in ("abi3", "none"): - try: - abis.remove(explicit_abi) - except ValueError: # noqa: PERF203 - pass - - platforms = list(platforms or platform_tags()) - for abi in abis: - for platform_ in platforms: - yield Tag(interpreter, abi, platform_) - - threading = _is_threaded_cpython(abis) - use_abi3 = _abi3_applies(python_version, threading) - use_abi3t = _abi3t_applies(python_version, threading) - - if use_abi3: - yield from (Tag(interpreter, "abi3", platform_) for platform_ in platforms) - if use_abi3t: - yield from (Tag(interpreter, "abi3t", platform_) for platform_ in platforms) - - yield from (Tag(interpreter, "none", platform_) for platform_ in platforms) - - if use_abi3 or use_abi3t: - for minor_version in range(python_version[1] - 1, 1, -1): - for platform_ in platforms: - version = _version_nodot((python_version[0], minor_version)) - interpreter = f"cp{version}" - if use_abi3: - yield Tag(interpreter, "abi3", platform_) - if use_abi3t: - # Support for abi3t was introduced in Python 3.15, but in - # principle abi3t wheels are possible for older limited API - # versions, so allow things like ("cp37", "abi3t", "platform") - yield Tag(interpreter, "abi3t", platform_) - - -def _generic_abi() -> list[str]: - """ - Return the ABI tag based on EXT_SUFFIX. - """ - # The following are examples of `EXT_SUFFIX`. - # We want to keep the parts which are related to the ABI and remove the - # parts which are related to the platform: - # - linux: '.cpython-310-x86_64-linux-gnu.so' => cp310 - # - mac: '.cpython-310-darwin.so' => cp310 - # - win: '.cp310-win_amd64.pyd' => cp310 - # - win: '.pyd' => cp37 (uses _cpython_abis()) - # - pypy: '.pypy38-pp73-x86_64-linux-gnu.so' => pypy38_pp73 - # - graalpy: '.graalpy-38-native-x86_64-darwin.dylib' - # => graalpy_38_native - - ext_suffix = _get_config_var("EXT_SUFFIX", warn=True) - if not isinstance(ext_suffix, str) or ext_suffix[0] != ".": - raise SystemError("invalid sysconfig.get_config_var('EXT_SUFFIX')") - parts = ext_suffix.split(".") - if len(parts) < 3: - # CPython3.7 and earlier uses ".pyd" on Windows. - return _cpython_abis(sys.version_info[:2]) - soabi = parts[1] - if soabi.startswith("cpython"): - # non-windows - abi = "cp" + soabi.split("-")[1] - elif soabi.startswith("cp"): - # windows - abi = soabi.split("-")[0] - elif soabi.startswith("pypy"): - abi = "-".join(soabi.split("-")[:2]) - elif soabi.startswith("graalpy"): - abi = "-".join(soabi.split("-")[:3]) - elif soabi: - # pyston, ironpython, others? - abi = soabi - else: - return [] - return [_normalize_string(abi)] - - -def generic_tags( - interpreter: str | None = None, - abis: Iterable[str] | None = None, - platforms: Iterable[str] | None = None, - *, - warn: bool = False, -) -> Iterator[Tag]: - """ - Yields the tags for an interpreter which requires no specialization. - - This function should be used if one of the other interpreter-specific - functions provided by this module is not appropriate (i.e. not calculating - tags for a CPython interpreter). - - The specific tags generated are: - - - ``--`` - - The ``"none"`` ABI will be added if it was not explicitly provided. - - :param str interpreter: The name of the interpreter. Defaults to being - calculated. - :param Iterable abis: Iterable of compatible ABIs. Defaults to the ABIs - compatible with the current system. - :param Iterable platforms: Iterable of compatible platforms. Defaults to the - platforms compatible with the current system. - :param bool warn: Whether warnings should be logged. Defaults to ``False``. - """ - if not interpreter: - interp_name = interpreter_name() - interp_version = interpreter_version(warn=warn) - interpreter = f"{interp_name}{interp_version}" - abis = _generic_abi() if abis is None else list(abis) - platforms = list(platforms or platform_tags()) - if "none" not in abis: - abis.append("none") - for abi in abis: - for platform_ in platforms: - yield Tag(interpreter, abi, platform_) - - -def _py_interpreter_range(py_version: PythonVersion) -> Iterator[str]: - """ - Yields Python versions in descending order. - - After the latest version, the major-only version will be yielded, and then - all previous versions of that major version. - """ - if len(py_version) > 1: - yield f"py{_version_nodot(py_version[:2])}" - yield f"py{py_version[0]}" - if len(py_version) > 1: - for minor in range(py_version[1] - 1, -1, -1): - yield f"py{_version_nodot((py_version[0], minor))}" - - -def compatible_tags( - python_version: PythonVersion | None = None, - interpreter: str | None = None, - platforms: Iterable[str] | None = None, -) -> Iterator[Tag]: - """ - Yields the tags for an interpreter compatible with the Python version - specified by ``python_version``. - - The specific tags generated are: - - - ``py*-none-`` - - ``-none-any`` if ``interpreter`` is provided - - ``py*-none-any`` - - :param Sequence python_version: A one- or two-item sequence representing the - compatible version of Python. Defaults to - ``sys.version_info[:2]``. - :param str interpreter: The name of the interpreter (if known), e.g. - ``"cp38"``. Defaults to the current interpreter. - :param Iterable platforms: Iterable of compatible platforms. Defaults to the - platforms compatible with the current system. - """ - if not python_version: - python_version = sys.version_info[:2] - platforms = list(platforms or platform_tags()) - for version in _py_interpreter_range(python_version): - for platform_ in platforms: - yield Tag(version, "none", platform_) - if interpreter: - yield Tag(interpreter, "none", "any") - for version in _py_interpreter_range(python_version): - yield Tag(version, "none", "any") - - -def _mac_arch(arch: str, is_32bit: bool = _32_BIT_INTERPRETER) -> str: - if not is_32bit: - return arch - - if arch.startswith("ppc"): - return "ppc" - - return "i386" - - -def _mac_binary_formats(version: AppleVersion, cpu_arch: str) -> list[str]: - formats = [cpu_arch] - if cpu_arch == "x86_64": - if version < (10, 4): - return [] - formats.extend(["intel", "fat64", "fat32"]) - - elif cpu_arch == "i386": - if version < (10, 4): - return [] - formats.extend(["intel", "fat32", "fat"]) - - elif cpu_arch == "ppc64": - # TODO: Need to care about 32-bit PPC for ppc64 through 10.2? - if version > (10, 5) or version < (10, 4): - return [] - formats.append("fat64") - - elif cpu_arch == "ppc": - if version > (10, 6): - return [] - formats.extend(["fat32", "fat"]) - - if cpu_arch in {"arm64", "x86_64"}: - formats.append("universal2") - - if cpu_arch in {"x86_64", "i386", "ppc64", "ppc", "intel"}: - formats.append("universal") - - return formats - - -def mac_platforms( - version: AppleVersion | None = None, arch: str | None = None -) -> Iterator[str]: - """ - Yields the :attr:`~Tag.platform` tags for macOS. - - The `version` parameter is a two-item tuple specifying the macOS version to - generate platform tags for. The `arch` parameter is the CPU architecture to - generate platform tags for. Both parameters default to the appropriate value - for the current system. - - :param tuple version: A two-item tuple representing the version of macOS. - Defaults to the current system's version. - :param str arch: The CPU architecture. Defaults to the architecture of the - current system, e.g. ``"x86_64"``. - - .. note:: - Equivalent support for the other major platforms is purposefully not - provided: - - - On Windows, platform compatibility is statically specified - - On Linux, code must be run on the system itself to determine - compatibility - """ - version_str, _, cpu_arch = platform.mac_ver() - if version is None: - version = cast("AppleVersion", tuple(map(int, version_str.split(".")[:2]))) - if version == (10, 16): - # When built against an older macOS SDK, Python will report macOS 10.16 - # instead of the real version. - version_str = subprocess.run( - [ - sys.executable, - "-sS", - "-c", - "import platform; print(platform.mac_ver()[0])", - ], - check=True, - env={"SYSTEM_VERSION_COMPAT": "0"}, - stdout=subprocess.PIPE, - text=True, - ).stdout - version = cast("AppleVersion", tuple(map(int, version_str.split(".")[:2]))) - - if arch is None: - arch = _mac_arch(cpu_arch) - - if (10, 0) <= version < (11, 0): - # Prior to Mac OS 11, each yearly release of Mac OS bumped the - # "minor" version number. The major version was always 10. - major_version = 10 - for minor_version in range(version[1], -1, -1): - compat_version = major_version, minor_version - binary_formats = _mac_binary_formats(compat_version, arch) - for binary_format in binary_formats: - yield f"macosx_{major_version}_{minor_version}_{binary_format}" - - if version >= (11, 0): - # Starting with Mac OS 11, each yearly release bumps the major version - # number. The minor versions are now the midyear updates. - minor_version = 0 - for major_version in range(version[0], 10, -1): - compat_version = major_version, minor_version - binary_formats = _mac_binary_formats(compat_version, arch) - for binary_format in binary_formats: - yield f"macosx_{major_version}_{minor_version}_{binary_format}" - - if version >= (11, 0): - # Mac OS 11 on x86_64 is compatible with binaries from previous releases. - # Arm64 support was introduced in 11.0, so no Arm binaries from previous - # releases exist. - # - # However, the "universal2" binary format can have a - # macOS version earlier than 11.0 when the x86_64 part of the binary supports - # that version of macOS. - major_version = 10 - if arch == "x86_64": - for minor_version in range(16, 3, -1): - compat_version = major_version, minor_version - binary_formats = _mac_binary_formats(compat_version, arch) - for binary_format in binary_formats: - yield f"macosx_{major_version}_{minor_version}_{binary_format}" - else: - for minor_version in range(16, 3, -1): - compat_version = major_version, minor_version - binary_format = "universal2" - yield f"macosx_{major_version}_{minor_version}_{binary_format}" - - -def ios_platforms( - version: AppleVersion | None = None, multiarch: str | None = None -) -> Iterator[str]: - """ - - Yields the :attr:`~Tag.platform` tags for iOS. - - :param tuple version: A two-item tuple representing the version of iOS. - Defaults to the current system's version. - :param str multiarch: The CPU architecture+ABI to be used. This should be in - the format by ``sys.implementation._multiarch`` (e.g., - ``arm64_iphoneos`` or ``x86_64_iphonesimulator``). - Defaults to the current system's multiarch value. - - .. note:: - Behavior of this method is undefined if invoked on non-iOS platforms - without providing explicit version and multiarch arguments. - """ - if version is None: - # if iOS is the current platform, ios_ver *must* be defined. However, - # it won't exist for CPython versions before 3.13, which causes a mypy - # error. - _, release, _, _ = platform.ios_ver() # type: ignore[attr-defined, unused-ignore] - version = cast("AppleVersion", tuple(map(int, release.split(".")[:2]))) - - if multiarch is None: - multiarch = sys.implementation._multiarch - multiarch = multiarch.replace("-", "_") - - ios_platform_template = "ios_{major}_{minor}_{multiarch}" - - # Consider any iOS major.minor version from the version requested, down to - # 12.0. 12.0 is the first iOS version that is known to have enough features - # to support CPython. Consider every possible minor release up to X.9. There - # highest the minor has ever gone is 8 (14.8 and 15.8) but having some extra - # candidates that won't ever match doesn't really hurt, and it saves us from - # having to keep an explicit list of known iOS versions in the code. Return - # the results descending order of version number. - - # If the requested major version is less than 12, there won't be any matches. - if version[0] < 12: - return - - # Consider the actual X.Y version that was requested. - yield ios_platform_template.format( - major=version[0], minor=version[1], multiarch=multiarch - ) - - # Consider every minor version from X.0 to the minor version prior to the - # version requested by the platform. - for minor in range(version[1] - 1, -1, -1): - yield ios_platform_template.format( - major=version[0], minor=minor, multiarch=multiarch - ) - - for major in range(version[0] - 1, 11, -1): - for minor in range(9, -1, -1): - yield ios_platform_template.format( - major=major, minor=minor, multiarch=multiarch - ) - - -def android_platforms( - api_level: int | None = None, abi: str | None = None -) -> Iterator[str]: - """ - Yields the :attr:`~Tag.platform` tags for Android. If this function is invoked on - non-Android platforms, the ``api_level`` and ``abi`` arguments are required. - - :param int api_level: The maximum `API level - `__ to return. Defaults - to the current system's version, as returned by ``platform.android_ver``. - :param str abi: The `Android ABI `__, - e.g. ``arm64_v8a``. Defaults to the current system's ABI , as returned by - ``sysconfig.get_platform``. Hyphens and periods will be replaced with - underscores. - """ - if platform.system() != "Android" and (api_level is None or abi is None): - raise TypeError( - "on non-Android platforms, the api_level and abi arguments are required" - ) - - if api_level is None: - # Python 3.13 was the first version to return platform.system() == "Android", - # and also the first version to define platform.android_ver(). - api_level = platform.android_ver().api_level # type: ignore[attr-defined] - - if abi is None: - abi = sysconfig.get_platform().split("-")[-1] - abi = _normalize_string(abi) - - # 16 is the minimum API level known to have enough features to support CPython - # without major patching. Yield every API level from the maximum down to the - # minimum, inclusive. - min_api_level = 16 - for ver in range(api_level, min_api_level - 1, -1): - yield f"android_{ver}_{abi}" - - -def _linux_platforms(is_32bit: bool = _32_BIT_INTERPRETER) -> Iterator[str]: - linux = _normalize_string(sysconfig.get_platform()) - if not linux.startswith("linux_"): - # we should never be here, just yield the sysconfig one and return - yield linux - return - if is_32bit: - if linux == "linux_x86_64": - linux = "linux_i686" - elif linux == "linux_aarch64": - linux = "linux_armv8l" - _, arch = linux.split("_", 1) - archs = {"armv8l": ["armv8l", "armv7l"]}.get(arch, [arch]) - yield from _manylinux.platform_tags(archs) - yield from _musllinux.platform_tags(archs) - for arch in archs: - yield f"linux_{arch}" - - -def _emscripten_platforms() -> Iterator[str]: - pyemscripten_platform_version = sysconfig.get_config_var( - "PYEMSCRIPTEN_PLATFORM_VERSION" - ) - if pyemscripten_platform_version: - yield f"pyemscripten_{pyemscripten_platform_version}_wasm32" - yield from _generic_platforms() - - -def _generic_platforms() -> Iterator[str]: - yield _normalize_string(sysconfig.get_platform()) - - -def platform_tags() -> Iterator[str]: - """ - Yields the :attr:`~Tag.platform` tags for the running interpreter. - """ - if platform.system() == "Darwin": - return mac_platforms() - elif platform.system() == "iOS": - return ios_platforms() - elif platform.system() == "Android": - return android_platforms() - elif platform.system() == "Linux": - return _linux_platforms() - elif platform.system() == "Emscripten": - return _emscripten_platforms() - else: - return _generic_platforms() - - -def interpreter_name() -> str: - """ - Returns the name of the running interpreter. - - Some implementations have a reserved, two-letter abbreviation which will - be returned when appropriate. - - This typically acts as the prefix to the :attr:`~Tag.interpreter` tag. - """ - name = sys.implementation.name - return INTERPRETER_SHORT_NAMES.get(name) or name - - -def interpreter_version(*, warn: bool = False) -> str: - """ - Returns the running interpreter's version. - - This typically acts as the suffix to the :attr:`~Tag.interpreter` tag. - - :param bool warn: Whether warnings should be logged. Defaults to ``False``. - """ - version = _get_config_var("py_version_nodot", warn=warn) - return str(version) if version else _version_nodot(sys.version_info[:2]) - - -def _version_nodot(version: PythonVersion) -> str: - return "".join(map(str, version)) - - -def sys_tags(*, warn: bool = False) -> Iterator[Tag]: - """ - Yields the sequence of tag triples that the running interpreter supports. - - The iterable is ordered so that the best-matching tag is first in the - sequence. The exact preferential order to tags is interpreter-specific, but - in general the tag importance is in the order of: - - 1. Interpreter - 2. Platform - 3. ABI - - This order is due to the fact that an ABI is inherently tied to the - platform, but platform-specific code is not necessarily tied to the ABI. The - interpreter is the most important tag as it dictates basic support for any - wheel. - - The function returns an iterable in order to allow for the possible - short-circuiting of tag generation if the entire sequence is not necessary - and tag calculation happens to be expensive. - - :param bool warn: Whether warnings should be logged. Defaults to ``False``. - - .. versionchanged:: 21.3 - Added the `pp3-none-any` tag (:issue:`311`). - .. versionchanged:: 27.0 - Added the `abi3t` tag (:issue:`1099`). - """ - - interp_name = interpreter_name() - if interp_name == "cp": - yield from cpython_tags(warn=warn) - else: - yield from generic_tags() - - if interp_name == "pp": - interp = "pp3" - elif interp_name == "cp": - interp = "cp" + interpreter_version(warn=warn) - else: - interp = None - yield from compatible_tags(interpreter=interp) - - -def create_compatible_tags_selector( - tags: Iterable[Tag], -) -> Callable[[Iterable[tuple[_T, AbstractSet[Tag]]]], Iterator[_T]]: - """Create a callable to select things compatible with supported tags. - - This function accepts an ordered sequence of tags, with the preferred - tags first. - - The returned callable accepts an iterable of tuples (thing, set[Tag]), - and returns an iterator of things, with the things with the best - matching tags first. - - Example to select compatible wheel filenames: - - >>> from packaging import tags - >>> from packaging.utils import parse_wheel_filename - >>> selector = tags.create_compatible_tags_selector(tags.sys_tags()) - >>> filenames = ["foo-1.0-py3-none-any.whl", "foo-1.0-py2-none-any.whl"] - >>> list(selector([ - ... (filename, parse_wheel_filename(filename)[-1]) for filename in filenames - ... ])) - ['foo-1.0-py3-none-any.whl'] - - .. versionadded:: 26.1 - """ - tag_ranks: dict[Tag, int] = {} - for rank, tag in enumerate(tags): - tag_ranks.setdefault(tag, rank) # ignore duplicate tags, keep first - supported_tags = tag_ranks.keys() - - def selector( - tagged_things: Iterable[tuple[_T, AbstractSet[Tag]]], - ) -> Iterator[_T]: - ranked_things: list[tuple[_T, int]] = [] - for thing, thing_tags in tagged_things: - supported_thing_tags = thing_tags & supported_tags - if supported_thing_tags: - thing_rank = min(tag_ranks[t] for t in supported_thing_tags) - ranked_things.append((thing, thing_rank)) - return iter( - thing for thing, _ in sorted(ranked_things, key=operator.itemgetter(1)) - ) - - return selector diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/utils.py b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/utils.py deleted file mode 100755 index cbd3be2..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/utils.py +++ /dev/null @@ -1,296 +0,0 @@ -# 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 annotations - -import re -from typing import NewType, Tuple, Union, cast - -from .tags import Tag, UnsortedTagsError, parse_tag -from .version import InvalidVersion, Version, _TrimmedRelease - -__all__ = [ - "BuildTag", - "InvalidName", - "InvalidSdistFilename", - "InvalidWheelFilename", - "NormalizedName", - "canonicalize_name", - "canonicalize_version", - "is_normalized_name", - "parse_sdist_filename", - "parse_wheel_filename", -] - - -def __dir__() -> list[str]: - return __all__ - - -BuildTag = Union[Tuple[()], Tuple[int, str]] - -NormalizedName = NewType("NormalizedName", str) -""" -A :class:`typing.NewType` of :class:`str`, representing a normalized name. -""" - - -class InvalidName(ValueError): - """ - An invalid distribution name; users should refer to the packaging user guide. - """ - - -class InvalidWheelFilename(ValueError): - """ - An invalid wheel filename was found, users should refer to PEP 427. - """ - - -class InvalidSdistFilename(ValueError): - """ - An invalid sdist filename was found, users should refer to the packaging user guide. - """ - - -# Core metadata spec for `Name` -_validate_regex = re.compile( - r"[a-z0-9]|[a-z0-9][a-z0-9._-]*[a-z0-9]", re.IGNORECASE | re.ASCII -) -_normalized_regex = re.compile(r"[a-z0-9]|[a-z0-9]([a-z0-9-](?!--))*[a-z0-9]", re.ASCII) -# PEP 427: The build number must start with a digit. -_build_tag_regex = re.compile(r"(\d+)(.*)", re.ASCII) - - -def canonicalize_name(name: str, *, validate: bool = False) -> NormalizedName: - """ - This function takes a valid Python package or extra name, and returns the - normalized form of it. - - The return type is typed as :class:`NormalizedName`. This allows type - checkers to help require that a string has passed through this function - before use. - - If **validate** is true, then the function will check if **name** is a valid - distribution name before normalizing. - - :param str name: The name to normalize. - :param bool validate: Check whether the name is a valid distribution name. - :raises InvalidName: If **validate** is true and the name is not an - acceptable distribution name. - - >>> from packaging.utils import canonicalize_name - >>> canonicalize_name("Django") - 'django' - >>> canonicalize_name("oslo.concurrency") - 'oslo-concurrency' - >>> canonicalize_name("requests") - 'requests' - """ - if validate and not _validate_regex.fullmatch(name): - raise InvalidName(f"name is invalid: {name!r}") - # Ensure all ``.`` and ``_`` are ``-`` - # Emulates ``re.sub(r"[-_.]+", "-", name).lower()`` from PEP 503 - # Much faster than re, and even faster than str.translate - value = name.lower().replace("_", "-").replace(".", "-") - # Condense repeats (faster than regex) - while "--" in value: - value = value.replace("--", "-") - return cast("NormalizedName", value) - - -def is_normalized_name(name: str) -> bool: - """ - Check if a name is already normalized (i.e. :func:`canonicalize_name` would - roundtrip to the same value). - - :param str name: The name to check. - - >>> from packaging.utils import is_normalized_name - >>> is_normalized_name("requests") - True - >>> is_normalized_name("Django") - False - """ - return _normalized_regex.fullmatch(name) is not None - - -def canonicalize_version( - version: Version | str, *, strip_trailing_zero: bool = True -) -> str: - """Return a canonical form of a version as a string. - - This function takes a string representing a package version (or a - :class:`~packaging.version.Version` instance), and returns the - normalized form of it. By default, it strips trailing zeros from - the release segment. - - >>> from packaging.utils import canonicalize_version - >>> canonicalize_version('1.0.1') - '1.0.1' - - Per PEP 625, versions may have multiple canonical forms, differing - only by trailing zeros. - - >>> canonicalize_version('1.0.0') - '1' - >>> canonicalize_version('1.0.0', strip_trailing_zero=False) - '1.0.0' - - Invalid versions are returned unaltered. - - >>> canonicalize_version('foo bar baz') - 'foo bar baz' - - >>> canonicalize_version('1.4.0.0.0') - '1.4' - """ - if isinstance(version, str): - try: - version = Version(version) - except InvalidVersion: - return str(version) - return str(_TrimmedRelease(version) if strip_trailing_zero else version) - - -def parse_wheel_filename( - filename: str, - *, - validate_order: bool = False, -) -> tuple[NormalizedName, Version, BuildTag, frozenset[Tag]]: - """ - This function takes the filename of a wheel file, and parses it, - returning a tuple of name, version, build number, and tags. - - The name part of the tuple is normalized and typed as - :class:`NormalizedName`. The version portion is an instance of - :class:`~packaging.version.Version`. The build number is ``()`` if - there is no build number in the wheel filename, otherwise a - two-item tuple of an integer for the leading digits and - a string for the rest of the build number. The tags portion is a - frozen set of :class:`~packaging.tags.Tag` instances (as the tag - string format allows multiple tags to be combined into a single - string). - - If **validate_order** is true, compressed tag set components are - checked to be in sorted order as required by PEP 425. - - :param str filename: The name of the wheel file. - :param bool validate_order: Check whether compressed tag set components - are in sorted order. - :raises InvalidWheelFilename: If the filename in question - does not follow the :ref:`wheel specification - `. - - >>> from packaging.utils import parse_wheel_filename - >>> from packaging.tags import Tag - >>> from packaging.version import Version - >>> name, ver, build, tags = parse_wheel_filename("foo-1.0-py3-none-any.whl") - >>> name - 'foo' - >>> ver == Version('1.0') - True - >>> tags == {Tag("py3", "none", "any")} - True - >>> not build - True - - .. versionadded:: 26.1 - The *validate_order* parameter. - """ - if not filename.endswith(".whl"): - raise InvalidWheelFilename( - f"Invalid wheel filename (extension must be '.whl'): {filename!r}" - ) - - filename = filename[:-4] - dashes = filename.count("-") - if dashes not in (4, 5): - raise InvalidWheelFilename( - f"Invalid wheel filename (wrong number of parts): {filename!r}" - ) - - parts = filename.split("-", dashes - 2) - name_part = parts[0] - # See PEP 427 for the rules on escaping the project name. - if "__" in name_part or re.match(r"^[\w\d._]*$", name_part, re.UNICODE) is None: - raise InvalidWheelFilename(f"Invalid project name: {filename!r}") - name = canonicalize_name(name_part) - - try: - version = Version(parts[1]) - except InvalidVersion as e: - raise InvalidWheelFilename( - f"Invalid wheel filename (invalid version): {filename!r}" - ) from e - - if dashes == 5: - build_part = parts[2] - build_match = _build_tag_regex.match(build_part) - if build_match is None: - raise InvalidWheelFilename( - f"Invalid build number: {build_part} in {filename!r}" - ) - build = cast("BuildTag", (int(build_match.group(1)), build_match.group(2))) - else: - build = () - tag_str = parts[-1] - try: - tags = parse_tag(tag_str, validate_order=validate_order) - except UnsortedTagsError: - raise InvalidWheelFilename( - f"Invalid wheel filename (compressed tag set components must be in " - f"sorted order per PEP 425): {filename!r}" - ) from None - return (name, version, build, tags) - - -def parse_sdist_filename(filename: str) -> tuple[NormalizedName, Version]: - """ - This function takes the filename of a sdist file (as specified - in the `Source distribution format`_ documentation), and parses - it, returning a tuple of the normalized name and version as - represented by an instance of :class:`~packaging.version.Version`. - - :param str filename: The name of the sdist file. - :raises InvalidSdistFilename: If the filename does not end - with an sdist extension (``.zip`` or ``.tar.gz``), or if it does not - contain a dash separating the name and the version of the distribution. - - >>> from packaging.utils import parse_sdist_filename - >>> from packaging.version import Version - >>> name, ver = parse_sdist_filename("foo-1.0.tar.gz") - >>> name - 'foo' - >>> ver == Version('1.0') - True - - .. _Source distribution format: https://packaging.python.org/specifications/source-distribution-format/#source-distribution-file-name - """ - if filename.endswith(".tar.gz"): - file_stem = filename[: -len(".tar.gz")] - elif filename.endswith(".zip"): - file_stem = filename[: -len(".zip")] - else: - raise InvalidSdistFilename( - f"Invalid sdist filename (extension must be '.tar.gz' or '.zip'):" - f" {filename!r}" - ) - - # We are requiring a PEP 440 version, which cannot contain dashes, - # so we split on the last dash. - name_part, sep, version_part = file_stem.rpartition("-") - if not sep: - raise InvalidSdistFilename(f"Invalid sdist filename: {filename!r}") - - name = canonicalize_name(name_part) - - try: - version = Version(version_part) - except InvalidVersion as e: - raise InvalidSdistFilename( - f"Invalid sdist filename (invalid version): {filename!r}" - ) from e - - return (name, version) diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/version.py b/venv/lib/python3.11/site-packages/pip/_vendor/packaging/version.py deleted file mode 100755 index 905b47e..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/packaging/version.py +++ /dev/null @@ -1,1231 +0,0 @@ -# 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. -""" -.. testsetup:: - - from pip._vendor.packaging.version import parse, normalize_pre, Version, _cmpkey -""" - -from __future__ import annotations - -import re -import sys -import typing -from typing import ( - Any, - Callable, - Literal, - NamedTuple, - SupportsInt, - Tuple, - TypedDict, - Union, -) - -if typing.TYPE_CHECKING: - from typing_extensions import Self, Unpack - -if sys.version_info >= (3, 13): # pragma: no cover - from warnings import deprecated as _deprecated -elif typing.TYPE_CHECKING: - from typing_extensions import deprecated as _deprecated -else: # pragma: no cover - import functools - import warnings - - def _deprecated(message: str) -> object: - def decorator(func: Callable[[...], object]) -> object: - @functools.wraps(func) - def wrapper(*args: object, **kwargs: object) -> object: - warnings.warn( - message, - category=DeprecationWarning, - stacklevel=2, - ) - return func(*args, **kwargs) - - return wrapper - - return decorator - - -_LETTER_NORMALIZATION = { - "alpha": "a", - "beta": "b", - "c": "rc", - "pre": "rc", - "preview": "rc", - "rev": "post", - "r": "post", -} - -__all__ = ["VERSION_PATTERN", "InvalidVersion", "Version", "normalize_pre", "parse"] - - -def __dir__() -> list[str]: - return __all__ - - -LocalType = Tuple[Union[int, str], ...] - -CmpLocalType = Tuple[Tuple[int, str], ...] -CmpSuffix = Tuple[int, int, int, int, int, int] -CmpKey = Union[ - Tuple[int, Tuple[int, ...], CmpSuffix], - Tuple[int, Tuple[int, ...], CmpSuffix, CmpLocalType], -] -VersionComparisonMethod = Callable[[CmpKey, CmpKey], bool] - - -class _VersionReplace(TypedDict, total=False): - epoch: int | None - release: tuple[int, ...] | None - pre: tuple[str, int] | None - post: int | None - dev: int | None - local: str | None - - -def normalize_pre(letter: str, /) -> str: - """Normalize the pre-release segment of a version string. - - Returns a lowercase version of the string if not a known pre-release - identifier. - - >>> normalize_pre('alpha') - 'a' - >>> normalize_pre('BETA') - 'b' - >>> normalize_pre('rc') - 'rc' - - :param letter: - - .. versionadded:: 26.1 - """ - letter = letter.lower() - return _LETTER_NORMALIZATION.get(letter, letter) - - -def parse(version: str) -> Version: - """Parse the given version string. - - This is identical to the :class:`Version` constructor. - - >>> parse('1.0.dev1') - - - :param version: The version string to parse. - :raises InvalidVersion: When the version string is not a valid version. - """ - return Version(version) - - -class InvalidVersion(ValueError): - """Raised when a version string is not a valid version. - - >>> Version("invalid") - Traceback (most recent call last): - ... - packaging.version.InvalidVersion: Invalid version: 'invalid' - """ - - -class _BaseVersion: - __slots__ = () - - # This can also be a normal member (see the packaging_legacy package); - # we are just requiring it to be readable. Actually defining a property - # has runtime effect on subclasses, so it's typing only. - if typing.TYPE_CHECKING: - - @property - def _key(self) -> tuple[Any, ...]: ... - - def __hash__(self) -> int: - return hash(self._key) - - # Please keep the duplicated `isinstance` check - # in the six comparisons hereunder - # unless you find a way to avoid adding overhead function calls. - def __lt__(self, other: _BaseVersion) -> bool: - if not isinstance(other, _BaseVersion): - return NotImplemented - - return self._key < other._key - - def __le__(self, other: _BaseVersion) -> bool: - if not isinstance(other, _BaseVersion): - return NotImplemented - - return self._key <= other._key - - def __eq__(self, other: object) -> bool: - if not isinstance(other, _BaseVersion): - return NotImplemented - - return self._key == other._key - - def __ge__(self, other: _BaseVersion) -> bool: - if not isinstance(other, _BaseVersion): - return NotImplemented - - return self._key >= other._key - - def __gt__(self, other: _BaseVersion) -> bool: - if not isinstance(other, _BaseVersion): - return NotImplemented - - return self._key > other._key - - def __ne__(self, other: object) -> bool: - if not isinstance(other, _BaseVersion): - return NotImplemented - - return self._key != other._key - - -# Deliberately not anchored to the start and end of the string, to make it -# easier for 3rd party code to reuse - -# Note that ++ doesn't behave identically on CPython and PyPy, so not using it here -_VERSION_PATTERN = r""" - v?+ # optional leading v - (?a: - (?:(?P[0-9]+)!)?+ # epoch - (?P[0-9]+(?:\.[0-9]+)*+) # release segment - (?P

                                          # pre-release
-            [._-]?+
-            (?Palpha|a|beta|b|preview|pre|c|rc)
-            [._-]?+
-            (?P[0-9]+)?
-        )?+
-        (?P                                         # post release
-            (?:-(?P[0-9]+))
-            |
-            (?:
-                [._-]?
-                (?Ppost|rev|r)
-                [._-]?
-                (?P[0-9]+)?
-            )
-        )?+
-        (?P                                          # dev release
-            [._-]?+
-            (?Pdev)
-            [._-]?+
-            (?P[0-9]+)?
-        )?+
-    )
-    (?a:\+
-        (?P                                        # local version
-            [a-z0-9]+
-            (?:[._-][a-z0-9]+)*+
-        )
-    )?+
-"""
-
-_VERSION_PATTERN_OLD = _VERSION_PATTERN.replace("*+", "*").replace("?+", "?")
-
-# Possessive qualifiers were added in Python 3.11.
-# CPython 3.11.0-3.11.4 had a bug: https://github.com/python/cpython/pull/107795
-# Older PyPy also had a bug.
-VERSION_PATTERN = (
-    _VERSION_PATTERN_OLD
-    if (sys.implementation.name == "cpython" and sys.version_info < (3, 11, 5))
-    or (sys.implementation.name == "pypy" and sys.version_info < (3, 11, 13))
-    or sys.version_info < (3, 11)
-    else _VERSION_PATTERN
-)
-"""
-A string containing the regular expression used to match a valid version.
-
-The pattern is not anchored at either end, and is intended for embedding in larger
-expressions (for example, matching a version number as part of a file name). The
-regular expression should be compiled with the ``re.VERBOSE`` and ``re.IGNORECASE``
-flags set.
-
-.. versionchanged:: 26.0
-
-   The regex now uses possessive qualifiers on Python 3.11 if they are
-   supported (CPython 3.11.5+, PyPy 3.11.13+).
-
-:meta hide-value:
-"""
-
-
-# Validation pattern for local version in replace()
-_LOCAL_PATTERN = re.compile(r"[a-z0-9]+(?:[._-][a-z0-9]+)*", re.IGNORECASE | re.ASCII)
-
-# Fast path: If a version has only digits and dots then we
-# can skip the regex and parse it as a release segment
-_SIMPLE_VERSION_INDICATORS = frozenset(".0123456789")
-
-
-def _validate_epoch(value: object, /) -> int:
-    epoch = value or 0
-    if isinstance(epoch, int) and epoch >= 0:
-        return epoch
-    msg = f"epoch must be non-negative integer, got {epoch}"
-    raise InvalidVersion(msg)
-
-
-def _validate_release(value: object, /) -> tuple[int, ...]:
-    release = (0,) if value is None else value
-    if (
-        isinstance(release, tuple)
-        and len(release) > 0
-        and all(isinstance(i, int) and i >= 0 for i in release)
-    ):
-        return release
-    msg = f"release must be a non-empty tuple of non-negative integers, got {release}"
-    raise InvalidVersion(msg)
-
-
-def _validate_pre(value: object, /) -> tuple[Literal["a", "b", "rc"], int] | None:
-    if value is None:
-        return value
-    if isinstance(value, tuple) and len(value) == 2:
-        letter, number = value
-        letter = normalize_pre(letter)
-        if letter in {"a", "b", "rc"} and isinstance(number, int) and number >= 0:
-            # type checkers can't infer the Literal type here on letter
-            return (letter, number)  # type: ignore[return-value]
-    msg = f"pre must be a tuple of ('a'|'b'|'rc', non-negative int), got {value}"
-    raise InvalidVersion(msg)
-
-
-def _validate_post(value: object, /) -> tuple[Literal["post"], int] | None:
-    if value is None:
-        return value
-    if isinstance(value, int) and value >= 0:
-        return ("post", value)
-    msg = f"post must be non-negative integer, got {value}"
-    raise InvalidVersion(msg)
-
-
-def _validate_dev(value: object, /) -> tuple[Literal["dev"], int] | None:
-    if value is None:
-        return value
-    if isinstance(value, int) and value >= 0:
-        return ("dev", value)
-    msg = f"dev must be non-negative integer, got {value}"
-    raise InvalidVersion(msg)
-
-
-def _validate_local(value: object, /) -> LocalType | None:
-    if value is None:
-        return value
-    if isinstance(value, str) and _LOCAL_PATTERN.fullmatch(value):
-        return _parse_local_version(value)
-    msg = f"local must be a valid version string, got {value!r}"
-    raise InvalidVersion(msg)
-
-
-# Backward compatibility for internals before 26.0. Do not use.
-class _Version(NamedTuple):
-    epoch: int
-    release: tuple[int, ...]
-    dev: tuple[Literal["dev"], int] | None
-    pre: tuple[Literal["a", "b", "rc"], int] | None
-    post: tuple[Literal["post"], int] | None
-    local: LocalType | None
-
-
-class Version(_BaseVersion):
-    """This class abstracts handling of a project's versions.
-
-    A :class:`Version` instance is comparison aware and can be compared and
-    sorted using the standard Python interfaces.
-
-    >>> v1 = Version("1.0a5")
-    >>> v2 = Version("1.0")
-    >>> v1
-    
-    >>> v2
-    
-    >>> v1 < v2
-    True
-    >>> v1 == v2
-    False
-    >>> v1 > v2
-    False
-    >>> v1 >= v2
-    False
-    >>> v1 <= v2
-    True
-
-    :class:`Version` is immutable; use :meth:`__replace__` to change
-    part of a version.
-
-    Instances are safe to serialize with :mod:`pickle`. They use a stable
-    format so the same pickle can be loaded in future packaging releases.
-
-    .. versionchanged:: 26.2
-
-        Added a stable pickle format. Pickles created with packaging 26.2+ can
-        be unpickled with future releases.  Backward compatibility with pickles
-        from pip._vendor.packaging < 26.2 is supported but may be removed in a future
-        release.
-    """
-
-    __slots__ = (
-        "_dev",
-        "_epoch",
-        "_hash_cache",
-        "_key_cache",
-        "_local",
-        "_post",
-        "_pre",
-        "_release",
-    )
-    __match_args__ = ("_str",)
-    """
-    Pattern matching is supported on Python 3.10+.
-
-    .. versionadded:: 26.0
-
-    :meta hide-value:
-    """
-
-    _regex = re.compile(r"\s*" + VERSION_PATTERN + r"\s*", re.VERBOSE | re.IGNORECASE)
-
-    _epoch: int
-    _release: tuple[int, ...]
-    _dev: tuple[Literal["dev"], int] | None
-    _pre: tuple[Literal["a", "b", "rc"], int] | None
-    _post: tuple[Literal["post"], int] | None
-    _local: LocalType | None
-
-    _hash_cache: int | None
-    _key_cache: CmpKey | None
-
-    def __init__(self, version: str) -> None:
-        """Initialize a Version object.
-
-        :param version:
-            The string representation of a version which will be parsed and normalized
-            before use.
-        :raises InvalidVersion:
-            If the ``version`` does not conform to PEP 440 in any way then this
-            exception will be raised.
-        """
-        if _SIMPLE_VERSION_INDICATORS.issuperset(version):
-            try:
-                self._release = tuple(map(int, version.split(".")))
-            except ValueError:
-                # Empty parts (from "1..2", ".1", etc.) are invalid versions.
-                # Any other ValueError (e.g. int str-digits limit) should
-                # propagate to the caller.
-                if "" in version.split("."):
-                    raise InvalidVersion(f"Invalid version: {version!r}") from None
-                # TODO: remove "no cover" when Python 3.9 is dropped.
-                raise  # pragma: no cover
-
-            self._epoch = 0
-            self._pre = None
-            self._post = None
-            self._dev = None
-            self._local = None
-            self._key_cache = None
-            self._hash_cache = None
-            return
-
-        # Validate the version and parse it into pieces
-        match = self._regex.fullmatch(version)
-        if not match:
-            raise InvalidVersion(f"Invalid version: {version!r}")
-        self._epoch = int(match.group("epoch")) if match.group("epoch") else 0
-        self._release = tuple(map(int, match.group("release").split(".")))
-        # We can type ignore the assignments below because the regex guarantees
-        # the correct strings
-        self._pre = _parse_letter_version(match.group("pre_l"), match.group("pre_n"))  # type: ignore[assignment]
-        self._post = _parse_letter_version(  # type: ignore[assignment]
-            match.group("post_l"), match.group("post_n1") or match.group("post_n2")
-        )
-        self._dev = _parse_letter_version(match.group("dev_l"), match.group("dev_n"))  # type: ignore[assignment]
-        self._local = _parse_local_version(match.group("local"))
-
-        # Key which will be used for sorting
-        self._key_cache = None
-        self._hash_cache = None
-
-    @classmethod
-    def from_parts(
-        cls,
-        *,
-        epoch: int = 0,
-        release: tuple[int, ...],
-        pre: tuple[str, int] | None = None,
-        post: int | None = None,
-        dev: int | None = None,
-        local: str | None = None,
-    ) -> Self:
-        """
-        Return a new version composed of the various parts.
-
-        This allows you to build a version without going though a string and
-        running a regular expression. It normalizes pre-release strings. The
-        ``release=`` keyword argument is required.
-
-        >>> Version.from_parts(release=(1,2,3))
-        
-        >>> Version.from_parts(release=(0,1,0), pre=("b", 1))
-        
-
-        :param epoch:
-        :param release: This version tuple is required
-
-        .. versionadded:: 26.1
-        """
-        _epoch = _validate_epoch(epoch)
-        _release = _validate_release(release)
-        _pre = _validate_pre(pre) if pre is not None else None
-        _post = _validate_post(post) if post is not None else None
-        _dev = _validate_dev(dev) if dev is not None else None
-        _local = _validate_local(local) if local is not None else None
-
-        new_version = cls.__new__(cls)
-        new_version._key_cache = None
-        new_version._hash_cache = None
-        new_version._epoch = _epoch
-        new_version._release = _release
-        new_version._pre = _pre
-        new_version._post = _post
-        new_version._dev = _dev
-        new_version._local = _local
-
-        return new_version
-
-    def __replace__(self, **kwargs: Unpack[_VersionReplace]) -> Self:
-        """
-        __replace__(*, epoch=..., release=..., pre=..., post=..., dev=..., local=...)
-
-        Return a new version with parts replaced.
-
-        This returns a new version (unless no parts were changed). The
-        pre-release is normalized. Setting a value to ``None`` clears it.
-
-        >>> v = Version("1.2.3")
-        >>> v.__replace__(pre=("a", 1))
-        
-
-        :param int | None epoch:
-        :param tuple[int, ...] | None release:
-        :param tuple[str, int] | None pre:
-        :param int | None post:
-        :param int | None dev:
-        :param str | None local:
-
-        .. versionadded:: 26.0
-        .. versionchanged:: 26.1
-
-           The pre-release portion is now normalized.
-        """
-        epoch = _validate_epoch(kwargs["epoch"]) if "epoch" in kwargs else self._epoch
-        release = (
-            _validate_release(kwargs["release"])
-            if "release" in kwargs
-            else self._release
-        )
-        pre = _validate_pre(kwargs["pre"]) if "pre" in kwargs else self._pre
-        post = _validate_post(kwargs["post"]) if "post" in kwargs else self._post
-        dev = _validate_dev(kwargs["dev"]) if "dev" in kwargs else self._dev
-        local = _validate_local(kwargs["local"]) if "local" in kwargs else self._local
-
-        if (
-            epoch == self._epoch
-            and release == self._release
-            and pre == self._pre
-            and post == self._post
-            and dev == self._dev
-            and local == self._local
-        ):
-            return self
-
-        new_version = self.__class__.__new__(self.__class__)
-        new_version._key_cache = None
-        new_version._hash_cache = None
-        new_version._epoch = epoch
-        new_version._release = release
-        new_version._pre = pre
-        new_version._post = post
-        new_version._dev = dev
-        new_version._local = local
-
-        return new_version
-
-    @property
-    def _key(self) -> CmpKey:
-        if self._key_cache is None:
-            self._key_cache = _cmpkey(
-                self._epoch,
-                self._release,
-                self._pre,
-                self._post,
-                self._dev,
-                self._local,
-            )
-        return self._key_cache
-
-    # __hash__ must be defined when __eq__ is overridden,
-    # otherwise Python sets __hash__ to None.
-    def __hash__(self) -> int:
-        if (cached_hash := self._hash_cache) is not None:
-            return cached_hash
-
-        if (key := self._key_cache) is None:
-            self._key_cache = key = _cmpkey(
-                self._epoch,
-                self._release,
-                self._pre,
-                self._post,
-                self._dev,
-                self._local,
-            )
-        self._hash_cache = cached_hash = hash(key)
-        return cached_hash
-
-    # Override comparison methods to use direct _key_cache access
-    # This is faster than property access, especially before Python 3.12
-    def __lt__(self, other: _BaseVersion) -> bool:
-        if isinstance(other, Version):
-            if self._key_cache is None:
-                self._key_cache = _cmpkey(
-                    self._epoch,
-                    self._release,
-                    self._pre,
-                    self._post,
-                    self._dev,
-                    self._local,
-                )
-            if other._key_cache is None:
-                other._key_cache = _cmpkey(
-                    other._epoch,
-                    other._release,
-                    other._pre,
-                    other._post,
-                    other._dev,
-                    other._local,
-                )
-            return self._key_cache < other._key_cache
-
-        if not isinstance(other, _BaseVersion):
-            return NotImplemented
-
-        return super().__lt__(other)
-
-    def __le__(self, other: _BaseVersion) -> bool:
-        if isinstance(other, Version):
-            if self._key_cache is None:
-                self._key_cache = _cmpkey(
-                    self._epoch,
-                    self._release,
-                    self._pre,
-                    self._post,
-                    self._dev,
-                    self._local,
-                )
-            if other._key_cache is None:
-                other._key_cache = _cmpkey(
-                    other._epoch,
-                    other._release,
-                    other._pre,
-                    other._post,
-                    other._dev,
-                    other._local,
-                )
-            return self._key_cache <= other._key_cache
-
-        if not isinstance(other, _BaseVersion):
-            return NotImplemented
-
-        return super().__le__(other)
-
-    def __eq__(self, other: object) -> bool:
-        if isinstance(other, Version):
-            if self._key_cache is None:
-                self._key_cache = _cmpkey(
-                    self._epoch,
-                    self._release,
-                    self._pre,
-                    self._post,
-                    self._dev,
-                    self._local,
-                )
-            if other._key_cache is None:
-                other._key_cache = _cmpkey(
-                    other._epoch,
-                    other._release,
-                    other._pre,
-                    other._post,
-                    other._dev,
-                    other._local,
-                )
-            return self._key_cache == other._key_cache
-
-        if not isinstance(other, _BaseVersion):
-            return NotImplemented
-
-        return super().__eq__(other)
-
-    def __ge__(self, other: _BaseVersion) -> bool:
-        if isinstance(other, Version):
-            if self._key_cache is None:
-                self._key_cache = _cmpkey(
-                    self._epoch,
-                    self._release,
-                    self._pre,
-                    self._post,
-                    self._dev,
-                    self._local,
-                )
-            if other._key_cache is None:
-                other._key_cache = _cmpkey(
-                    other._epoch,
-                    other._release,
-                    other._pre,
-                    other._post,
-                    other._dev,
-                    other._local,
-                )
-            return self._key_cache >= other._key_cache
-
-        if not isinstance(other, _BaseVersion):
-            return NotImplemented
-
-        return super().__ge__(other)
-
-    def __gt__(self, other: _BaseVersion) -> bool:
-        if isinstance(other, Version):
-            if self._key_cache is None:
-                self._key_cache = _cmpkey(
-                    self._epoch,
-                    self._release,
-                    self._pre,
-                    self._post,
-                    self._dev,
-                    self._local,
-                )
-            if other._key_cache is None:
-                other._key_cache = _cmpkey(
-                    other._epoch,
-                    other._release,
-                    other._pre,
-                    other._post,
-                    other._dev,
-                    other._local,
-                )
-            return self._key_cache > other._key_cache
-
-        if not isinstance(other, _BaseVersion):
-            return NotImplemented
-
-        return super().__gt__(other)
-
-    def __ne__(self, other: object) -> bool:
-        if isinstance(other, Version):
-            if self._key_cache is None:
-                self._key_cache = _cmpkey(
-                    self._epoch,
-                    self._release,
-                    self._pre,
-                    self._post,
-                    self._dev,
-                    self._local,
-                )
-            if other._key_cache is None:
-                other._key_cache = _cmpkey(
-                    other._epoch,
-                    other._release,
-                    other._pre,
-                    other._post,
-                    other._dev,
-                    other._local,
-                )
-            return self._key_cache != other._key_cache
-
-        if not isinstance(other, _BaseVersion):
-            return NotImplemented
-
-        return super().__ne__(other)
-
-    def __getstate__(
-        self,
-    ) -> tuple[
-        int,
-        tuple[int, ...],
-        tuple[str, int] | None,
-        tuple[str, int] | None,
-        tuple[str, int] | None,
-        LocalType | None,
-    ]:
-        # Return state as a 6-item tuple for compactness:
-        #   (epoch, release, pre, post, dev, local)
-        # Cache members are excluded and will be recomputed on demand
-        return (
-            self._epoch,
-            self._release,
-            self._pre,
-            self._post,
-            self._dev,
-            self._local,
-        )
-
-    def __setstate__(self, state: object) -> None:
-        # Always discard cached values — they may contain stale references
-        # (e.g. packaging._structures.InfinityType from pre-26.1 pickles)
-        # and will be recomputed on demand from the core fields above.
-        self._key_cache = None
-        self._hash_cache = None
-
-        if isinstance(state, tuple):
-            if len(state) == 6:
-                # New format (26.2+): (epoch, release, pre, post, dev, local)
-                (
-                    self._epoch,
-                    self._release,
-                    self._pre,
-                    self._post,
-                    self._dev,
-                    self._local,
-                ) = state
-                return
-            if len(state) == 2:
-                # Format (packaging 26.0-26.1): (None, {slot: value}).
-                _, slot_dict = state
-                if isinstance(slot_dict, dict):
-                    self._epoch = slot_dict["_epoch"]
-                    self._release = slot_dict["_release"]
-                    self._pre = slot_dict.get("_pre")
-                    self._post = slot_dict.get("_post")
-                    self._dev = slot_dict.get("_dev")
-                    self._local = slot_dict.get("_local")
-                    return
-        if isinstance(state, dict):
-            # Old format (packaging <= 25.x, no __slots__): state is a plain
-            # dict with "_version" (_Version NamedTuple) and "_key" entries.
-            version_nt = state.get("_version")
-            if version_nt is not None:
-                self._epoch = version_nt.epoch
-                self._release = version_nt.release
-                self._pre = version_nt.pre
-                self._post = version_nt.post
-                self._dev = version_nt.dev
-                self._local = version_nt.local
-                return
-
-        raise TypeError(f"Cannot restore Version from {state!r}")
-
-    @property
-    @_deprecated("Version._version is private and will be removed soon")
-    def _version(self) -> _Version:
-        return _Version(
-            self._epoch, self._release, self._dev, self._pre, self._post, self._local
-        )
-
-    @_version.setter
-    @_deprecated("Version._version is private and will be removed soon")
-    def _version(self, value: _Version) -> None:
-        self._epoch = value.epoch
-        self._release = value.release
-        self._dev = value.dev
-        self._pre = value.pre
-        self._post = value.post
-        self._local = value.local
-        self._key_cache = None
-        self._hash_cache = None
-
-    def __repr__(self) -> str:
-        """A representation of the Version that shows all internal state.
-
-        >>> Version('1.0.0')
-        
-        """
-        return f"<{self.__class__.__name__}({str(self)!r})>"
-
-    def __str__(self) -> str:
-        """A string representation of the version that can be round-tripped.
-
-        >>> str(Version("1.0a5"))
-        '1.0a5'
-        """
-        # This is a hot function, so not calling self.base_version
-        version = ".".join(map(str, self.release))
-
-        # Epoch
-        if self.epoch:
-            version = f"{self.epoch}!{version}"
-
-        # Pre-release
-        if self.pre is not None:
-            version += "".join(map(str, self.pre))
-
-        # Post-release
-        if self.post is not None:
-            version += f".post{self.post}"
-
-        # Development release
-        if self.dev is not None:
-            version += f".dev{self.dev}"
-
-        # Local version segment
-        if self.local is not None:
-            version += f"+{self.local}"
-
-        return version
-
-    @property
-    def _str(self) -> str:
-        """Internal property for match_args"""
-        return str(self)
-
-    @property
-    def epoch(self) -> int:
-        """The epoch of the version.
-
-        >>> Version("2.0.0").epoch
-        0
-        >>> Version("1!2.0.0").epoch
-        1
-        """
-        return self._epoch
-
-    @property
-    def release(self) -> tuple[int, ...]:
-        """The components of the "release" segment of the version.
-
-        >>> Version("1.2.3").release
-        (1, 2, 3)
-        >>> Version("2.0.0").release
-        (2, 0, 0)
-        >>> Version("1!2.0.0.post0").release
-        (2, 0, 0)
-
-        Includes trailing zeroes but not the epoch or any pre-release / development /
-        post-release suffixes.
-        """
-        return self._release
-
-    @property
-    def pre(self) -> tuple[Literal["a", "b", "rc"], int] | None:
-        """The pre-release segment of the version.
-
-        >>> print(Version("1.2.3").pre)
-        None
-        >>> Version("1.2.3a1").pre
-        ('a', 1)
-        >>> Version("1.2.3b1").pre
-        ('b', 1)
-        >>> Version("1.2.3rc1").pre
-        ('rc', 1)
-        """
-        return self._pre
-
-    @property
-    def post(self) -> int | None:
-        """The post-release number of the version.
-
-        >>> print(Version("1.2.3").post)
-        None
-        >>> Version("1.2.3.post1").post
-        1
-        """
-        return self._post[1] if self._post else None
-
-    @property
-    def dev(self) -> int | None:
-        """The development number of the version.
-
-        >>> print(Version("1.2.3").dev)
-        None
-        >>> Version("1.2.3.dev1").dev
-        1
-        """
-        return self._dev[1] if self._dev else None
-
-    @property
-    def local(self) -> str | None:
-        """The local version segment of the version.
-
-        >>> print(Version("1.2.3").local)
-        None
-        >>> Version("1.2.3+abc").local
-        'abc'
-        """
-        if self._local:
-            return ".".join(str(x) for x in self._local)
-        else:
-            return None
-
-    @property
-    def public(self) -> str:
-        """The public portion of the version.
-
-        This returns a string. If you want a :class:`Version` again and care
-        about performance, use ``v.__replace__(local=None)`` instead.
-
-        >>> Version("1.2.3").public
-        '1.2.3'
-        >>> Version("1.2.3+abc").public
-        '1.2.3'
-        >>> Version("1!1.2.3dev1+abc").public
-        '1!1.2.3.dev1'
-        """
-        return str(self).split("+", 1)[0]
-
-    @property
-    def base_version(self) -> str:
-        """The "base version" of the version.
-
-        This returns a string. If you want a :class:`Version` again and care
-        about performance, use
-        ``v.__replace__(pre=None, post=None, dev=None, local=None)`` instead.
-
-        >>> Version("1.2.3").base_version
-        '1.2.3'
-        >>> Version("1.2.3+abc").base_version
-        '1.2.3'
-        >>> Version("1!1.2.3dev1+abc").base_version
-        '1!1.2.3'
-
-        The "base version" is the public version of the project without any pre or post
-        release markers.
-        """
-        release_segment = ".".join(map(str, self.release))
-        return f"{self.epoch}!{release_segment}" if self.epoch else release_segment
-
-    @property
-    def is_prerelease(self) -> bool:
-        """Whether this version is a pre-release.
-
-        >>> Version("1.2.3").is_prerelease
-        False
-        >>> Version("1.2.3a1").is_prerelease
-        True
-        >>> Version("1.2.3b1").is_prerelease
-        True
-        >>> Version("1.2.3rc1").is_prerelease
-        True
-        >>> Version("1.2.3dev1").is_prerelease
-        True
-        """
-        return self.dev is not None or self.pre is not None
-
-    @property
-    def is_postrelease(self) -> bool:
-        """Whether this version is a post-release.
-
-        >>> Version("1.2.3").is_postrelease
-        False
-        >>> Version("1.2.3.post1").is_postrelease
-        True
-        """
-        return self.post is not None
-
-    @property
-    def is_devrelease(self) -> bool:
-        """Whether this version is a development release.
-
-        >>> Version("1.2.3").is_devrelease
-        False
-        >>> Version("1.2.3.dev1").is_devrelease
-        True
-        """
-        return self.dev is not None
-
-    @property
-    def major(self) -> int:
-        """The first item of :attr:`release` or ``0`` if unavailable.
-
-        >>> Version("1.2.3").major
-        1
-        """
-        return self.release[0] if len(self.release) >= 1 else 0
-
-    @property
-    def minor(self) -> int:
-        """The second item of :attr:`release` or ``0`` if unavailable.
-
-        >>> Version("1.2.3").minor
-        2
-        >>> Version("1").minor
-        0
-        """
-        return self.release[1] if len(self.release) >= 2 else 0
-
-    @property
-    def micro(self) -> int:
-        """The third item of :attr:`release` or ``0`` if unavailable.
-
-        >>> Version("1.2.3").micro
-        3
-        >>> Version("1").micro
-        0
-        """
-        return self.release[2] if len(self.release) >= 3 else 0
-
-
-class _TrimmedRelease(Version):
-    __slots__ = ()
-
-    def __init__(self, version: str | Version) -> None:
-        if isinstance(version, Version):
-            self._epoch = version._epoch
-            self._release = version._release
-            self._dev = version._dev
-            self._pre = version._pre
-            self._post = version._post
-            self._local = version._local
-            self._key_cache = version._key_cache
-            return
-        super().__init__(version)  # pragma: no cover
-
-    @property
-    def release(self) -> tuple[int, ...]:
-        """
-        Release segment without any trailing zeros.
-
-        >>> _TrimmedRelease('1.0.0').release
-        (1,)
-        >>> _TrimmedRelease('0.0').release
-        (0,)
-        """
-        # This leaves one 0.
-        rel = super().release
-        len_release = len(rel)
-        i = len_release
-        while i > 1 and rel[i - 1] == 0:
-            i -= 1
-        return rel if i == len_release else rel[:i]
-
-
-def _parse_letter_version(
-    letter: str | None, number: str | bytes | SupportsInt | None
-) -> tuple[str, int] | None:
-    if letter:
-        # 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.
-        letter = _LETTER_NORMALIZATION.get(letter, letter)
-
-        # We consider there to be an implicit 0 in a pre-release if there is
-        # not a numeral associated with it.
-        return letter, int(number or 0)
-
-    if 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)
-        return "post", int(number)
-
-    return None
-
-
-_local_version_separators = re.compile(r"[\._-]")
-
-
-def _parse_local_version(local: str | None) -> LocalType | None:
-    """
-    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)
-        )
-    return None
-
-
-# Sort ranks for pre-release: dev-only < a < b < rc < stable (no pre-release).
-_PRE_RANK = {"a": 0, "b": 1, "rc": 2}
-_PRE_RANK_DEV_ONLY = -1  # sorts before a(0)
-_PRE_RANK_STABLE = 3  # sorts after rc(2)
-
-# In local version segments, strings sort before ints per PEP 440.
-_LOCAL_STR_RANK = -1  # sorts before all non-negative ints
-
-# Pre-computed suffix for stable releases (no pre, post, or dev segments).
-# See _cmpkey() for the suffix layout.
-_STABLE_SUFFIX = (_PRE_RANK_STABLE, 0, 0, 0, 1, 0)
-
-
-def _cmpkey(
-    epoch: int,
-    release: tuple[int, ...],
-    pre: tuple[str, int] | None,
-    post: tuple[str, int] | None,
-    dev: tuple[str, int] | None,
-    local: LocalType | None,
-) -> CmpKey:
-    """Build a comparison key for PEP 440 ordering.
-
-    Returns ``(epoch, release, suffix)`` or
-    ``(epoch, release, suffix, local)`` so that plain tuple
-    comparison gives the correct order.
-
-    Trailing zeros are stripped from the release so that ``1.0.0 == 1``.
-
-    The suffix is a flat 6-int tuple that encodes pre/post/dev:
-    ``(pre_rank, pre_n, post_rank, post_n, dev_rank, dev_n)``
-
-    pre_rank: dev-only=-1, a=0, b=1, rc=2, no-pre=3
-        Dev-only releases (no pre or post) get -1 so they sort before
-        any alpha/beta/rc.  Releases without a pre-release tag get 3
-        so they sort after rc.
-    post_rank: no-post=0, post=1
-        Releases without a post segment sort before those with one.
-    dev_rank: dev=0, no-dev=1
-        Releases without a dev segment sort after those with one.
-
-    Local segments use ``(n, "")`` for ints and ``(-1, s)`` for strings,
-    following PEP 440: strings sort before ints, strings compare
-    lexicographically, ints compare numerically, and shorter segments
-    sort before longer when prefixes match.  Versions without a local
-    segment sort before those with one (3-tuple < 4-tuple).
-
-    >>> _cmpkey(0, (1, 0, 0), None, None, None, None)
-    (0, (1,), (3, 0, 0, 0, 1, 0))
-    >>> _cmpkey(0, (1,), ("a", 1), None, None, None)
-    (0, (1,), (0, 1, 0, 0, 1, 0))
-    >>> _cmpkey(0, (1,), None, None, None, ("ubuntu", 1))
-    (0, (1,), (3, 0, 0, 0, 1, 0), ((-1, 'ubuntu'), (1, '')))
-    """
-    # Strip trailing zeros: 1.0.0 compares equal to 1.
-    len_release = len(release)
-    i = len_release
-    while i and release[i - 1] == 0:
-        i -= 1
-    trimmed = release if i == len_release else release[:i]
-
-    # Fast path: stable release with no local segment.
-    if pre is None and post is None and dev is None and local is None:
-        return epoch, trimmed, _STABLE_SUFFIX
-
-    if pre is None and post is None and dev is not None:
-        # dev-only (e.g. 1.0.dev1) sorts before all pre-releases.
-        pre_rank, pre_n = _PRE_RANK_DEV_ONLY, 0
-    elif pre is None:
-        pre_rank, pre_n = _PRE_RANK_STABLE, 0
-    else:
-        pre_rank, pre_n = _PRE_RANK[pre[0]], pre[1]
-
-    post_rank = 0 if post is None else 1
-    post_n = 0 if post is None else post[1]
-
-    dev_rank = 1 if dev is None else 0
-    dev_n = 0 if dev is None else dev[1]
-
-    suffix = (pre_rank, pre_n, post_rank, post_n, dev_rank, dev_n)
-
-    if local is None:
-        return epoch, trimmed, suffix
-
-    cmp_local: CmpLocalType = tuple(
-        (seg, "") if isinstance(seg, int) else (_LOCAL_STR_RANK, seg) for seg in local
-    )
-    return epoch, trimmed, suffix, cmp_local
diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/pkg_resources/LICENSE b/venv/lib/python3.11/site-packages/pip/_vendor/pkg_resources/LICENSE
deleted file mode 100755
index 1bb5a44..0000000
--- a/venv/lib/python3.11/site-packages/pip/_vendor/pkg_resources/LICENSE
+++ /dev/null
@@ -1,17 +0,0 @@
-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.

!I7S{BS4i1|@R7s@ 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 diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/distlib/t64.exe b/venv/lib/python3.11/site-packages/pip/_vendor/distlib/t64.exe deleted file mode 100755 index e8bebdba6d8f242244bf397ab067965d47c5093e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 108032 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%0AHbpwE%ZM zv;ObB_nxnOhUf4be31oc0dM$^jOKl6mZZNS9{+|}Z-wA{C}+@hgJ^i(tdnSH_mo-m z<7NxqQEs5Ja&cXdS09hRY`p~){DT^-MbI9Jo}dTF%WvN^J9nFY6Y{3`4-Hy_vtKnk zOEgUQyYd~Cig#}|>-@AAD@7LTR9Y%diY(9X+O=!6WMLk3XdOH~0UfmP5;=nZwb23J z;W=xB+#vthU7guHLPLcAdH<}Up}&5I*-yCk5)Fzc+a%Ei{$sY7o%UpvTGR=9@n3s} z1@<5L*M4NwU_EHTKag|epY=elkd1&AbR0QD?$M2)MK359zHfHEXh@O#4-~(lq3ry=avc)-y@psocEI`k&Ew#~syoawzAXl{TpZn|!z+z{@ z%kUl2QD}JAELk)R5Dmqjh4(n*=Pz{Uu0s&h^6Rg^HtjP9RcHumKu2wB63`M($G6{p zYnvZiV)xBTvAZV6+21C{d&DmJm)S)hnho1-mI@932H*d*yQHmRNT0DV3~ z@`O%*uRL2VG zWcKqkK)~-lGP^iL!_YFb!NO^fXsFg_Xb9=^nb;)R)V8uotwlrRx+>eMVdmDL!Q&qt z9bIkzwa2s1|6o1PU-pAwJXR%%CCAXJ`oY8JpDQCGq_^vyRXp{zpA#Hbizx<@MU|m%aD$FI`)JKZMQ&bOf}p z2J8pnYZA~x3;x*2HFFbe<+Z)7Ks4MZ8gj3$!asAj*&jX;4ZF;KD;m&eY*LDBQlQV! z5a=^B1p16k>hOfeUr!PpR9d2E>@V`Osw*@EwI&^bu7uOUXK0{2nstsnJgb+jyr#E3 zI72i{>uY<m}potrTN}$p{73nRW>PSe1gp%+uv>)lW5nEPPD8m zlI+&0m)LuM-(=7b?qhg;mQAA6hQI8+mw(~20NlZg7M#EveSpuwnqcF@{bT$gXhi;> zyQ!Z&B^uU=hSjr0gLDCXh6eN*n{=n_Dl{yFhO7G9jaQ0>QAsxEiUFPm@WjVpe-3<% z?%Ll}ejxwY4EA9B2fLtNg(JgMT3Zy?gg=2M*w=r$VY}U|quL zI2;#?A7;Xuhx)#E?ctZ+JAHO97D>42@_rcSM(7bm@{XNry*RvYSL13O}NG;pbI}% z{{H;RY99lA{!>VwYrq}W{{es2e$b#ntb;xH;Dg@x!lzMuz@|-`R!zg<=s4V(fDbll zH8$zT^jS1eYTZ@)3{P|w574q?R z2VbZ*THrl<1GWlZ2!E9G00n(6y??4zexvh7{xrWohx-_JhV*%%bb(SEvcY$XRWy~a z{~KL<{LeV!jI;G<&jkIc_D|$T`*q06%d;UvhM1l$vOoRlPo|ub-G2M+9v{y4@EaP~ z3)m-+D=KFgXuzH#hwO#$==ocd?2QM&f1kZ_@3aFxhI9cR1AWFO-8CZ>^ndjHrP$xi zN`=lvekAKTI`?%+C@oO90YdZx$6L6|$F%cf@(P0u8m zVp`U*V@H#3?QsDQ{H5>;4M7d)pk+KNG8K%CZGCOY<@V$sJWuJp154d?}NA8>`>A@sZFK;t?e}Px2i;68i+S)KbKPuis<6ero)Ov821p6r(J=_S$Q|2TwgW z>MJ@O(9o$KcfDZ5le`FpyIUCTT59kQ`5UdF;GKg;y>^+>lIX_EY zep37s-9r8)OSyVpY%6-IjJVC3HOsF9G+bp184{;Gz8~f&XoAr$US({ zB16y?$QR$^Q{i*Vmi$?y!{m2^OXXK77yp4 z&rdz|l&1my5I2;5cpB2v({1qJ!CtnMllS<;Yj_SV;Ef(&fB2p=0`h~eT_Qa|2ha(| z#Rd!a?={Z6h=_=It$Uv0PP>FOIUn*mbt&F|2xJidC*Ujil$Dive6+SE--4%#y*_BY zP4ebtfISL6)1S&UG+;;JDfa*2haa|;D_8nG@S%qu@^Him#HU@dZNJkVIZL=dtM6_U z(&Rnrn!jlYzW6`bf9c}_uF*GIaADoC3zAdsODIp`ZL4(M?{C-|d!O*eZjvXgYw`F8a!MO6!_W{^aDy&n2wk}G#v4sG%h;#G z3%CUp80-wTh=TlZCZd8nbS+)Flo;bO{k;CC;tq`-|G@tjzvn?iU>5^g0vc%HH?~Q8 zw?8K!Q|z_j`~_F8!JoAWd62{}IZ271js-_3_C+gwW z1pglY2fE11QIRd$7hinQ+g*5oz9R47j~+-K@744_S7yQ~XbC@q_^0edb^He!*gNrG zuz$z_`w@F5Jm$;^?^y?YfnXiD#^z&dv12+@_`HT_{!il$9bW#!WuvB?2iJk#hPTK% z*Ysg6ka_qFjmWy>=zIAHyR=s9t2|@zQ}!nC`>}GoI`9m_|I5l8Jo~_N8b7;OwlC-D+Bl|vX`tenxtPvvK}!Fa*=VR&aVysp=W+U-B5 z%?jaZRc*acTR+q`3bjo`ZDgp83$t*10>*szDrc9W&k71%TRoO@+&Khj?C zsqE6*^3U@WC%Z~MaFY7#O)M^2{>JXn%5jh?byo^Ab2vgB(W4=l@=I^()!jEwY=BGcY+*@{Q!V$gdC+CqMM&9AGL2DER&J!DLTKV%g-GS9sw?_KRz(Hu>U-9=Xf8}Cg)5{KA0aI zelHxzdy+r*@+ch0wUOgN9?4OW>m*Njv2;XbLugGR*~b-knV{d_UB%u^4RFBcfG7CY zE9WHoTp#%v;)oRHrjmOle@xCVTpoFrg&YmJK5|URW6VQSeoJR_rDNeZAdkaq$fKU$_d3C|G{|F(JY6L7E1#0CxWe#oJeV6f zr=^f@BS%8MkUZ7eJ0|^T&hX=J%%+qn=P4X`o(G*EXG;m_$FG<L8$>A z#7*D@h4?zTCUP9)%E&X3-yly$j)~j`IWqD~vqo0czg;)Rz`@I-@~%PdoAJWu#|BXG zZK&aRfD7yY%#CqIzUyJ(KunX^I5`&Nkvtdq6>^O}#}%4?_7ww}%IicRkA1}lmFo4! zH&Y%WUB9~=jxFH4kADu`-~tb5-^d^1^M>TB$la1NB=@{DlrKal$d8aK%vO#n-~p3` z+h}sPD%J9jZt1tZ6J-CdLKm?+oC`SH!4qr`{MfVWANI;$hWb1K@oD6d96qt>KqtsE zk?SK*mKDN*$%d9yriGPUl3~A7!DcX0j!4=VfskD6-(e(YP=4$h?-{%lqJyTg@8&Yq)UP8Y!HR7+} zFnRK1&v)zr`ygWnGQeEeg+N!ePgE)|Gg`8oDIZC1nQ=Vx^kZkLNO&dQFTC=~D_{SEiUe zdpUcx1kdm$s9?pN(fQs$K_OZ@-Cj|2M znc`tLYYgHiM_Tx;NwXuY=+}?gw?pDp8L8jw)~o)#Ze+H2p;}MX)uGZafQb|cHBR3J zHA|nVmR-v`Sh9ccyWJ>vsG?`J7`xUYc}!fobm?m4X!glQeXi$1{(S%a_a9_;lmpnU zF(wui6!`Der$K&xezM}(Pp??9!mnqrhq2DG>2HNkMm|l?KNDyDR%2|J{Ov&xIU6Id zD|H6BP<|cHHOA>|b+^ueDvt(Z&=;A;hYS3fK&P-}X*xG?W+I00hTNKNdahF?@Q)q& z1Li{4uuD|r63mF^T?$;KGrj`KZx?g4FkNt#rcD?2WKCAUCtXt zi*Gi@;2b_kc(8tY_l(bTW5eLX_UChLZFXOOp2T;@Z|B^=*=cshxqgld%gmPRT&v%C zTUJ(W^dm{CfiVLH4lq*d5kVzg_n{#a6SH?>(Dm4_|k#f1Z2EjPvZ3#~)z&H37VS zyW)K{>=$x_-Nxr)J+POsd@6QT{$4-Mc z5u_xi-1O*{!$&e`nU%EcT6%Q$ly6(uxNb@fBlsXbH;`p}=+l)m*8$c&0=rnZ59 z1DoDu*{te{_pkjz_vq8uzkRK~?p0m!?zIMbqY+n8{>^I*Lp^n+KEDk0jPh??YovFp z;qDE07rHe4J3#MYxlnJ98RE{@b+Y~)sLzzA8tj&DSkM25LE;l_95+=O=s%%#P#GmJ zvYy7fT7NBTjGN#_YqT-?i&_~Pd4e0|CaQOT->0+dsc`8zs@?P+8X@meln~Y{WJWWdM~zXqyB?+J=*t#Gn2#G{w60Zfg3QbqIaPnocBUUEN~O<~jLB0qOU4yLr;M4V zzm_^WBeVKu`0W8R1j^qh9-J{PV_eiY{_Pu`o|!yh+QhLLQ=+4$j!76fQh!FbZ}h12 zahVy>{rbdKk9{z3_4r{uelUBV*n@EG6I)HR!284o{OmV0VQ4~9Qu6udju@d2tQ0@W z-j=srf8VJ*uW^2}{Gs_H@?A5%V_M&DShj81u4NU=8s|pjcF66SJ1BQV?v=SSa&O9A zl)F54UG9e5ZMnO0D{>p>Mdb098@39@Eo-(c`@w|;iwc$%EH5Z7SXZ#VU_-&Cf^7xc z3w9Nh7gQ9u!p4Qo3L^@m3Of{bF6>ztUpT06XyJ&$KNMbBIH_<(VRqq7g$oN86)r1W zURYeXu5f+fhQdvS+X}ZARusCT#zoDFB8sAlIuvy->RA+DG^l83(TJiy6kS;~sc1$~ zcF|2m3yT&NEh}1HR9v*KXnoO!qD@8HinbT+Dk?9kC~_+ruV}U+Vnx)74l6pZ=(!?( z#h?}IR%}~Qu_9t+&y_P)E?l{2<+7E_R~D~azf!aeMa%W7le`&u*?BkREzDb#w=8dY zUUA;Ky!Ck-@;2pd^L(qwbNTQtB0nm>Lw@J{p8113AODblW&Wi68Tr}yFy_DIza04A H#ex3;_fXA_ diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/distlib/util.py b/venv/lib/python3.11/site-packages/pip/_vendor/distlib/util.py deleted file mode 100755 index b120ca8..0000000 --- a/venv/lib/python3.11/site-packages/pip/_vendor/distlib/util.py +++ /dev/null @@ -1,2021 +0,0 @@ -# -# Copyright (C) 2012-2026 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, 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() - # Some packages have a trailing comma which would break things - # See issue #148 - if not ver_remaining: - break - 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 - # Avoid normcasing: see issue #143 - # result = os.path.normcase(sys.executable) - result = 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: - if os.path.exists(path): - os.remove(path) - with open(path, 'wb') as f: - f.write(data) - self.record_as_written(path) - - def write_text_file(self, path, data, encoding): - self.write_binary_file(path, data.encode(encoding)) - - 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, hashed_invalidation=False): - if not optimize: - optimization = '' - else: - optimization = '1' - dpath = cache_from_source(path, optimization=optimization) - 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):] - compile_kwargs = {} - if hashed_invalidation and hasattr(py_compile, 'PycInvalidationMode'): - if not isinstance(hashed_invalidation, py_compile.PycInvalidationMode): - hashed_invalidation = py_compile.PycInvalidationMode.CHECKED_HASH - compile_kwargs['invalidation_mode'] = hashed_invalidation - py_compile.compile(path, dpath, diagpath, True, **compile_kwargs) # 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 '' % (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([^\[]\S*)) - \s*=\s*(?P(\w+)([:\.]\w+)*) - \s*(\[\s*(?P[\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, use_abspath=True): - """ - 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 use_abspath else 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.rsplit('@', 1) - if ':' not in prefix: - username = prefix - else: - username, password = prefix.split(':', 1) - if username: - username = unquote(username) - if password: - password = unquote(password) - 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[\w .-]+)\s*' - r'\(\s*(?P[^\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, use_abspath=True): - """ - Converts a resource prefix to a directory name in the cache. - """ - return path_to_cache_dir(prefix, use_abspath=use_abspath) - - 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, base=None): - if not isinstance(path, text_type): - path = path.decode('utf-8') - if base is None: - base = dest_dir - p = os.path.abspath(os.path.join(base, path)) - if not p.startswith(dest_dir) or p[plen] != os.sep: - raise ValueError('path outside destination: %r' % p) - - def check_link(member): - # A symlink/hardlink member's name is validated like any other - # member, but its target (linkname) is not covered by extractall's - # name-based handling. An unchecked target lets a later member be - # written through the link to a location outside dest_dir. Validate - # the resolved target stays within dest_dir. Symlink targets are - # relative to the member's own directory; hardlink targets are - # relative to the archive root (i.e. dest_dir). - if not (member.issym() or member.islnk()): - return - if member.issym(): - link_base = os.path.dirname(os.path.join(dest_dir, member.name)) - else: - link_base = dest_dir - check_path(member.linkname, base=link_base) - - 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: - for member in archive.getmembers(): - check_path(member.name) - check_link(member) - 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') - - # Limit extraction of dangerous items, if this Python - # allows it easily. If not, just trust the input. - # See: https://docs.python.org/3/library/tarfile.html#extraction-filters - def extraction_filter(member, path): - """Run tarfile.tar_filter, but raise the expected ValueError""" - # This is only called if the current Python has tarfile filters - try: - return tarfile.tar_filter(member, path) - except tarfile.FilterError as exc: - raise ValueError(str(exc)) - - archive.extraction_filter = extraction_filter - - 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() - - context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) - if hasattr(ssl, 'OP_NO_SSLv2'): - context.options |= ssl.OP_NO_SSLv2 - if getattr(self, 'cert_file', None): - 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 -# -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 not self._connection or host != self._connection[0]: - self._extra_headers = eh - self._connection = host, httplib.HTTPConnection(h) - return self._connection[1] - - -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 not self._connection or host != self._connection[0]: - self._extra_headers = eh - self._connection = host, httplib.HTTPSConnection(h, None, **kwargs) - return self._connection[1] - - -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) # deprecated as of Python 3.8 - scheme = urlparse(uri)[0] - 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://peps.python.org/pep-0503/#normalized-names - # Emulates re.sub(r"[-_.]+", "-", name).lower() - # Much faster than re, and even faster than str.translate - value = name.lower().replace("_", "-").replace(".", "-") - while "--" in value: - value = value.replace("--", "-") - return value - - -# def _get_pypirc_command(): -# """ -# 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) - - -class PyPIRCFile(object): - - DEFAULT_REPOSITORY = 'https://upload.pypi.org/legacy/' - DEFAULT_REALM = 'pypi' - - def __init__(self, fn=None, url=None): - if fn is None: - fn = os.path.join(os.path.expanduser('~'), '.pypirc') - self.filename = fn - self.url = url - - def read(self): - result = {} - - if os.path.exists(self.filename): - repository = self.url or self.DEFAULT_REPOSITORY - - config = configparser.RawConfigParser() - config.read(self.filename) - sections = config.sections() - if 'distutils' in sections: - # let's get the list of servers - index_servers = config.get('distutils', 'index-servers') - _servers = [server.strip() for server in index_servers.split('\n') if server.strip() != ''] - if _servers == []: - # nothing set, let's try to get the default pypi - if 'pypi' in sections: - _servers = ['pypi'] - else: - for server in _servers: - result = {'server': server} - result['username'] = config.get(server, 'username') - - # optional params - for key, default in (('repository', self.DEFAULT_REPOSITORY), ('realm', self.DEFAULT_REALM), - ('password', None)): - if config.has_option(server, key): - result[key] = config.get(server, key) - else: - result[key] = default - - # work around people having "repository" for the "pypi" - # section of their config set to the HTTP (rather than - # HTTPS) URL - if (server == 'pypi' and repository in (self.DEFAULT_REPOSITORY, 'pypi')): - result['repository'] = self.DEFAULT_REPOSITORY - elif (result['server'] != repository and result['repository'] != repository): - result = {} - elif 'server-login' in sections: - # old format - server = 'server-login' - if config.has_option(server, 'repository'): - repository = config.get(server, 'repository') - else: - repository = self.DEFAULT_REPOSITORY - result = { - 'username': config.get(server, 'username'), - 'password': config.get(server, 'password'), - 'repository': repository, - 'server': server, - 'realm': self.DEFAULT_REALM - } - return result - - def update(self, username, password): - # import pdb; pdb.set_trace() - config = configparser.RawConfigParser() - fn = self.filename - config.read(fn) - if not config.has_section('pypi'): - config.add_section('pypi') - config.set('pypi', 'username', username) - config.set('pypi', 'password', password) - with open(fn, 'w') as f: - config.write(f) - - -def _load_pypirc(index): - """ - Read the PyPI access configuration as supported by distutils. - """ - return PyPIRCFile(url=index.url).read() - - -def _store_pypirc(index): - PyPIRCFile().update(index.username, index.password) - - -# -# get_platform()/get_host_platform() copied from Python 3.10.a0 source, with some minor -# tweaks -# - - -def get_host_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. on Linux, the kernel version isn't - particularly important. - - Examples of returned values: - linux-i586 - linux-alpha (?) - solaris-2.6-sun4u - - Windows will return one of: - win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc) - win32 (all others - specifically, sys.platform is returned) - - For other non-POSIX platforms, currently just returns 'sys.platform'. - - """ - if os.name == 'nt': - if 'amd64' in sys.version.lower(): - return 'win-amd64' - if '(arm)' in sys.version.lower(): - return 'win-arm32' - if '(arm64)' in sys.version.lower(): - return 'win-arm64' - return sys.platform - - # Set for cross builds explicitly - if "_PYTHON_HOST_PLATFORM" in os.environ: - return os.environ["_PYTHON_HOST_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, and translate - # spaces (for "Power Macintosh") - osname = osname.lower().replace('/', '') - machine = machine.replace(' ', '_').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:]) - # We can't use 'platform.architecture()[0]' because a - # bootstrap problem. We use a dict to get an error - # if some suspicious happens. - bitness = {2147483647: '32bit', 9223372036854775807: '64bit'} - machine += '.%s' % bitness[sys.maxsize] - # fall through to standard osname-release-machine representation - elif osname[:3] == 'aix': - from _aix_support import aix_platform - return aix_platform() - elif osname[:6] == 'cygwin': - osname = 'cygwin' - rel_re = re.compile(r'[\d.]+', re.ASCII) - m = rel_re.match(release) - if m: - release = m.group() - elif osname[:6] == 'darwin': - import _osx_support - try: - from distutils import sysconfig - except ImportError: - import sysconfig - osname, release, machine = _osx_support.get_platform_osx(sysconfig.get_config_vars(), osname, release, machine) - - return '%s-%s-%s' % (osname, release, machine) - - -_TARGET_TO_PLAT = { - 'x86': 'win32', - 'x64': 'win-amd64', - 'arm': 'win-arm32', -} - - -def get_platform(): - if os.name != 'nt': - return get_host_platform() - cross_compilation_target = os.environ.get('VSCMD_ARG_TGT_ARCH') - if cross_compilation_target not in _TARGET_TO_PLAT: - return get_host_platform() - return _TARGET_TO_PLAT[cross_compilation_target] - - -def is_in_directory(path, target): - """ - Check if a path is inside a target directory. This doesn't check case (might be an issue on Windows) - """ - path = os.path.abspath(path) - target = os.path.abspath(target) - return path == target or path.startswith(target + os.sep) diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/distlib/w32.exe b/venv/lib/python3.11/site-packages/pip/_vendor/distlib/w32.exe deleted file mode 100755 index 4ee2d3a31b59e8b50f433ecdf0be9e496e8cc3b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 91648 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 diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/distlib/w64-arm.exe b/venv/lib/python3.11/site-packages/pip/_vendor/distlib/w64-arm.exe deleted file mode 100755 index 951d5817c9e6d81c94a173a0d9fead7f1f143331..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 168448 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 diff --git a/venv/lib/python3.11/site-packages/pip/_vendor/distlib/w64.exe b/venv/lib/python3.11/site-packages/pip/_vendor/distlib/w64.exe deleted file mode 100755 index 5763076d2878093971a0ef9870e1cde7f556b18b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 101888 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