ZhengyangZhang commited on
Commit
3847113
·
verified ·
1 Parent(s): bd71d55

Add files using upload-large-folder tool

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. lib/python3.12/site-packages/packaging/__init__.py +15 -0
  2. lib/python3.12/site-packages/packaging/__pycache__/__init__.cpython-312.pyc +0 -0
  3. lib/python3.12/site-packages/packaging/__pycache__/_elffile.cpython-312.pyc +0 -0
  4. lib/python3.12/site-packages/packaging/__pycache__/_manylinux.cpython-312.pyc +0 -0
  5. lib/python3.12/site-packages/packaging/__pycache__/_musllinux.cpython-312.pyc +0 -0
  6. lib/python3.12/site-packages/packaging/__pycache__/_parser.cpython-312.pyc +0 -0
  7. lib/python3.12/site-packages/packaging/__pycache__/_structures.cpython-312.pyc +0 -0
  8. lib/python3.12/site-packages/packaging/__pycache__/_tokenizer.cpython-312.pyc +0 -0
  9. lib/python3.12/site-packages/packaging/__pycache__/markers.cpython-312.pyc +0 -0
  10. lib/python3.12/site-packages/packaging/__pycache__/metadata.cpython-312.pyc +0 -0
  11. lib/python3.12/site-packages/packaging/__pycache__/requirements.cpython-312.pyc +0 -0
  12. lib/python3.12/site-packages/packaging/__pycache__/specifiers.cpython-312.pyc +0 -0
  13. lib/python3.12/site-packages/packaging/__pycache__/tags.cpython-312.pyc +0 -0
  14. lib/python3.12/site-packages/packaging/__pycache__/utils.cpython-312.pyc +0 -0
  15. lib/python3.12/site-packages/packaging/__pycache__/version.cpython-312.pyc +0 -0
  16. lib/python3.12/site-packages/packaging/_elffile.py +109 -0
  17. lib/python3.12/site-packages/packaging/_manylinux.py +262 -0
  18. lib/python3.12/site-packages/packaging/_musllinux.py +85 -0
  19. lib/python3.12/site-packages/packaging/_parser.py +353 -0
  20. lib/python3.12/site-packages/packaging/_structures.py +61 -0
  21. lib/python3.12/site-packages/packaging/_tokenizer.py +195 -0
  22. lib/python3.12/site-packages/packaging/licenses/__init__.py +145 -0
  23. lib/python3.12/site-packages/packaging/licenses/__pycache__/__init__.cpython-312.pyc +0 -0
  24. lib/python3.12/site-packages/packaging/licenses/__pycache__/_spdx.cpython-312.pyc +0 -0
  25. lib/python3.12/site-packages/packaging/licenses/_spdx.py +759 -0
  26. lib/python3.12/site-packages/packaging/markers.py +362 -0
  27. lib/python3.12/site-packages/packaging/metadata.py +862 -0
  28. lib/python3.12/site-packages/packaging/py.typed +0 -0
  29. lib/python3.12/site-packages/packaging/requirements.py +91 -0
  30. lib/python3.12/site-packages/packaging/specifiers.py +1019 -0
  31. lib/python3.12/site-packages/packaging/tags.py +656 -0
  32. lib/python3.12/site-packages/packaging/utils.py +163 -0
  33. lib/python3.12/site-packages/packaging/version.py +582 -0
  34. lib/python3.12/site-packages/pip-25.0.1.dist-info/AUTHORS.txt +806 -0
  35. lib/python3.12/site-packages/pip-25.0.1.dist-info/INSTALLER +1 -0
  36. lib/python3.12/site-packages/pip-25.0.1.dist-info/LICENSE.txt +20 -0
  37. lib/python3.12/site-packages/pip-25.0.1.dist-info/METADATA +90 -0
  38. lib/python3.12/site-packages/pip-25.0.1.dist-info/RECORD +854 -0
  39. lib/python3.12/site-packages/pip-25.0.1.dist-info/REQUESTED +0 -0
  40. lib/python3.12/site-packages/pip-25.0.1.dist-info/WHEEL +5 -0
  41. lib/python3.12/site-packages/pip-25.0.1.dist-info/entry_points.txt +3 -0
  42. lib/python3.12/site-packages/pip-25.0.1.dist-info/top_level.txt +1 -0
  43. lib/python3.12/site-packages/sentry_sdk/__pycache__/__init__.cpython-312.pyc +0 -0
  44. lib/python3.12/site-packages/sentry_sdk/__pycache__/_batcher.cpython-312.pyc +0 -0
  45. lib/python3.12/site-packages/sentry_sdk/__pycache__/_compat.cpython-312.pyc +0 -0
  46. lib/python3.12/site-packages/sentry_sdk/__pycache__/_init_implementation.cpython-312.pyc +0 -0
  47. lib/python3.12/site-packages/sentry_sdk/__pycache__/_log_batcher.cpython-312.pyc +0 -0
  48. lib/python3.12/site-packages/sentry_sdk/__pycache__/_lru_cache.cpython-312.pyc +0 -0
  49. lib/python3.12/site-packages/sentry_sdk/__pycache__/_metrics_batcher.cpython-312.pyc +0 -0
  50. lib/python3.12/site-packages/sentry_sdk/__pycache__/_queue.cpython-312.pyc +0 -0
lib/python3.12/site-packages/packaging/__init__.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This file is dual licensed under the terms of the Apache License, Version
2
+ # 2.0, and the BSD License. See the LICENSE file in the root of this repository
3
+ # for complete details.
4
+
5
+ __title__ = "packaging"
6
+ __summary__ = "Core utilities for Python packages"
7
+ __uri__ = "https://github.com/pypa/packaging"
8
+
9
+ __version__ = "25.0"
10
+
11
+ __author__ = "Donald Stufft and individual contributors"
12
+ __email__ = "donald@stufft.io"
13
+
14
+ __license__ = "BSD-2-Clause or Apache-2.0"
15
+ __copyright__ = f"2014 {__author__}"
lib/python3.12/site-packages/packaging/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (553 Bytes). View file
 
lib/python3.12/site-packages/packaging/__pycache__/_elffile.cpython-312.pyc ADDED
Binary file (5.01 kB). View file
 
lib/python3.12/site-packages/packaging/__pycache__/_manylinux.cpython-312.pyc ADDED
Binary file (9.7 kB). View file
 
lib/python3.12/site-packages/packaging/__pycache__/_musllinux.cpython-312.pyc ADDED
Binary file (4.55 kB). View file
 
lib/python3.12/site-packages/packaging/__pycache__/_parser.cpython-312.pyc ADDED
Binary file (14 kB). View file
 
lib/python3.12/site-packages/packaging/__pycache__/_structures.cpython-312.pyc ADDED
Binary file (3.24 kB). View file
 
lib/python3.12/site-packages/packaging/__pycache__/_tokenizer.cpython-312.pyc ADDED
Binary file (7.95 kB). View file
 
lib/python3.12/site-packages/packaging/__pycache__/markers.cpython-312.pyc ADDED
Binary file (12.8 kB). View file
 
lib/python3.12/site-packages/packaging/__pycache__/metadata.cpython-312.pyc ADDED
Binary file (27.2 kB). View file
 
lib/python3.12/site-packages/packaging/__pycache__/requirements.cpython-312.pyc ADDED
Binary file (4.41 kB). View file
 
lib/python3.12/site-packages/packaging/__pycache__/specifiers.cpython-312.pyc ADDED
Binary file (39 kB). View file
 
lib/python3.12/site-packages/packaging/__pycache__/tags.cpython-312.pyc ADDED
Binary file (24.7 kB). View file
 
lib/python3.12/site-packages/packaging/__pycache__/utils.cpython-312.pyc ADDED
Binary file (6.63 kB). View file
 
lib/python3.12/site-packages/packaging/__pycache__/version.cpython-312.pyc ADDED
Binary file (20.5 kB). View file
 
lib/python3.12/site-packages/packaging/_elffile.py ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ ELF file parser.
3
+
4
+ This provides a class ``ELFFile`` that parses an ELF executable in a similar
5
+ interface to ``ZipFile``. Only the read interface is implemented.
6
+
7
+ Based on: https://gist.github.com/lyssdod/f51579ae8d93c8657a5564aefc2ffbca
8
+ ELF header: https://refspecs.linuxfoundation.org/elf/gabi4+/ch4.eheader.html
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import enum
14
+ import os
15
+ import struct
16
+ from typing import IO
17
+
18
+
19
+ class ELFInvalid(ValueError):
20
+ pass
21
+
22
+
23
+ class EIClass(enum.IntEnum):
24
+ C32 = 1
25
+ C64 = 2
26
+
27
+
28
+ class EIData(enum.IntEnum):
29
+ Lsb = 1
30
+ Msb = 2
31
+
32
+
33
+ class EMachine(enum.IntEnum):
34
+ I386 = 3
35
+ S390 = 22
36
+ Arm = 40
37
+ X8664 = 62
38
+ AArc64 = 183
39
+
40
+
41
+ class ELFFile:
42
+ """
43
+ Representation of an ELF executable.
44
+ """
45
+
46
+ def __init__(self, f: IO[bytes]) -> None:
47
+ self._f = f
48
+
49
+ try:
50
+ ident = self._read("16B")
51
+ except struct.error as e:
52
+ raise ELFInvalid("unable to parse identification") from e
53
+ magic = bytes(ident[:4])
54
+ if magic != b"\x7fELF":
55
+ raise ELFInvalid(f"invalid magic: {magic!r}")
56
+
57
+ self.capacity = ident[4] # Format for program header (bitness).
58
+ self.encoding = ident[5] # Data structure encoding (endianness).
59
+
60
+ try:
61
+ # e_fmt: Format for program header.
62
+ # p_fmt: Format for section header.
63
+ # p_idx: Indexes to find p_type, p_offset, and p_filesz.
64
+ e_fmt, self._p_fmt, self._p_idx = {
65
+ (1, 1): ("<HHIIIIIHHH", "<IIIIIIII", (0, 1, 4)), # 32-bit LSB.
66
+ (1, 2): (">HHIIIIIHHH", ">IIIIIIII", (0, 1, 4)), # 32-bit MSB.
67
+ (2, 1): ("<HHIQQQIHHH", "<IIQQQQQQ", (0, 2, 5)), # 64-bit LSB.
68
+ (2, 2): (">HHIQQQIHHH", ">IIQQQQQQ", (0, 2, 5)), # 64-bit MSB.
69
+ }[(self.capacity, self.encoding)]
70
+ except KeyError as e:
71
+ raise ELFInvalid(
72
+ f"unrecognized capacity ({self.capacity}) or encoding ({self.encoding})"
73
+ ) from e
74
+
75
+ try:
76
+ (
77
+ _,
78
+ self.machine, # Architecture type.
79
+ _,
80
+ _,
81
+ self._e_phoff, # Offset of program header.
82
+ _,
83
+ self.flags, # Processor-specific flags.
84
+ _,
85
+ self._e_phentsize, # Size of section.
86
+ self._e_phnum, # Number of sections.
87
+ ) = self._read(e_fmt)
88
+ except struct.error as e:
89
+ raise ELFInvalid("unable to parse machine and section information") from e
90
+
91
+ def _read(self, fmt: str) -> tuple[int, ...]:
92
+ return struct.unpack(fmt, self._f.read(struct.calcsize(fmt)))
93
+
94
+ @property
95
+ def interpreter(self) -> str | None:
96
+ """
97
+ The path recorded in the ``PT_INTERP`` section header.
98
+ """
99
+ for index in range(self._e_phnum):
100
+ self._f.seek(self._e_phoff + self._e_phentsize * index)
101
+ try:
102
+ data = self._read(self._p_fmt)
103
+ except struct.error:
104
+ continue
105
+ if data[self._p_idx[0]] != 3: # Not PT_INTERP.
106
+ continue
107
+ self._f.seek(data[self._p_idx[1]])
108
+ return os.fsdecode(self._f.read(data[self._p_idx[2]])).strip("\0")
109
+ return None
lib/python3.12/site-packages/packaging/_manylinux.py ADDED
@@ -0,0 +1,262 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import collections
4
+ import contextlib
5
+ import functools
6
+ import os
7
+ import re
8
+ import sys
9
+ import warnings
10
+ from typing import Generator, Iterator, NamedTuple, Sequence
11
+
12
+ from ._elffile import EIClass, EIData, ELFFile, EMachine
13
+
14
+ EF_ARM_ABIMASK = 0xFF000000
15
+ EF_ARM_ABI_VER5 = 0x05000000
16
+ EF_ARM_ABI_FLOAT_HARD = 0x00000400
17
+
18
+
19
+ # `os.PathLike` not a generic type until Python 3.9, so sticking with `str`
20
+ # as the type for `path` until then.
21
+ @contextlib.contextmanager
22
+ def _parse_elf(path: str) -> Generator[ELFFile | None, None, None]:
23
+ try:
24
+ with open(path, "rb") as f:
25
+ yield ELFFile(f)
26
+ except (OSError, TypeError, ValueError):
27
+ yield None
28
+
29
+
30
+ def _is_linux_armhf(executable: str) -> bool:
31
+ # hard-float ABI can be detected from the ELF header of the running
32
+ # process
33
+ # https://static.docs.arm.com/ihi0044/g/aaelf32.pdf
34
+ with _parse_elf(executable) as f:
35
+ return (
36
+ f is not None
37
+ and f.capacity == EIClass.C32
38
+ and f.encoding == EIData.Lsb
39
+ and f.machine == EMachine.Arm
40
+ and f.flags & EF_ARM_ABIMASK == EF_ARM_ABI_VER5
41
+ and f.flags & EF_ARM_ABI_FLOAT_HARD == EF_ARM_ABI_FLOAT_HARD
42
+ )
43
+
44
+
45
+ def _is_linux_i686(executable: str) -> bool:
46
+ with _parse_elf(executable) as f:
47
+ return (
48
+ f is not None
49
+ and f.capacity == EIClass.C32
50
+ and f.encoding == EIData.Lsb
51
+ and f.machine == EMachine.I386
52
+ )
53
+
54
+
55
+ def _have_compatible_abi(executable: str, archs: Sequence[str]) -> bool:
56
+ if "armv7l" in archs:
57
+ return _is_linux_armhf(executable)
58
+ if "i686" in archs:
59
+ return _is_linux_i686(executable)
60
+ allowed_archs = {
61
+ "x86_64",
62
+ "aarch64",
63
+ "ppc64",
64
+ "ppc64le",
65
+ "s390x",
66
+ "loongarch64",
67
+ "riscv64",
68
+ }
69
+ return any(arch in allowed_archs for arch in archs)
70
+
71
+
72
+ # If glibc ever changes its major version, we need to know what the last
73
+ # minor version was, so we can build the complete list of all versions.
74
+ # For now, guess what the highest minor version might be, assume it will
75
+ # be 50 for testing. Once this actually happens, update the dictionary
76
+ # with the actual value.
77
+ _LAST_GLIBC_MINOR: dict[int, int] = collections.defaultdict(lambda: 50)
78
+
79
+
80
+ class _GLibCVersion(NamedTuple):
81
+ major: int
82
+ minor: int
83
+
84
+
85
+ def _glibc_version_string_confstr() -> str | None:
86
+ """
87
+ Primary implementation of glibc_version_string using os.confstr.
88
+ """
89
+ # os.confstr is quite a bit faster than ctypes.DLL. It's also less likely
90
+ # to be broken or missing. This strategy is used in the standard library
91
+ # platform module.
92
+ # https://github.com/python/cpython/blob/fcf1d003bf4f0100c/Lib/platform.py#L175-L183
93
+ try:
94
+ # Should be a string like "glibc 2.17".
95
+ version_string: str | None = os.confstr("CS_GNU_LIBC_VERSION")
96
+ assert version_string is not None
97
+ _, version = version_string.rsplit()
98
+ except (AssertionError, AttributeError, OSError, ValueError):
99
+ # os.confstr() or CS_GNU_LIBC_VERSION not available (or a bad value)...
100
+ return None
101
+ return version
102
+
103
+
104
+ def _glibc_version_string_ctypes() -> str | None:
105
+ """
106
+ Fallback implementation of glibc_version_string using ctypes.
107
+ """
108
+ try:
109
+ import ctypes
110
+ except ImportError:
111
+ return None
112
+
113
+ # ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen
114
+ # manpage says, "If filename is NULL, then the returned handle is for the
115
+ # main program". This way we can let the linker do the work to figure out
116
+ # which libc our process is actually using.
117
+ #
118
+ # We must also handle the special case where the executable is not a
119
+ # dynamically linked executable. This can occur when using musl libc,
120
+ # for example. In this situation, dlopen() will error, leading to an
121
+ # OSError. Interestingly, at least in the case of musl, there is no
122
+ # errno set on the OSError. The single string argument used to construct
123
+ # OSError comes from libc itself and is therefore not portable to
124
+ # hard code here. In any case, failure to call dlopen() means we
125
+ # can proceed, so we bail on our attempt.
126
+ try:
127
+ process_namespace = ctypes.CDLL(None)
128
+ except OSError:
129
+ return None
130
+
131
+ try:
132
+ gnu_get_libc_version = process_namespace.gnu_get_libc_version
133
+ except AttributeError:
134
+ # Symbol doesn't exist -> therefore, we are not linked to
135
+ # glibc.
136
+ return None
137
+
138
+ # Call gnu_get_libc_version, which returns a string like "2.5"
139
+ gnu_get_libc_version.restype = ctypes.c_char_p
140
+ version_str: str = gnu_get_libc_version()
141
+ # py2 / py3 compatibility:
142
+ if not isinstance(version_str, str):
143
+ version_str = version_str.decode("ascii")
144
+
145
+ return version_str
146
+
147
+
148
+ def _glibc_version_string() -> str | None:
149
+ """Returns glibc version string, or None if not using glibc."""
150
+ return _glibc_version_string_confstr() or _glibc_version_string_ctypes()
151
+
152
+
153
+ def _parse_glibc_version(version_str: str) -> tuple[int, int]:
154
+ """Parse glibc version.
155
+
156
+ We use a regexp instead of str.split because we want to discard any
157
+ random junk that might come after the minor version -- this might happen
158
+ in patched/forked versions of glibc (e.g. Linaro's version of glibc
159
+ uses version strings like "2.20-2014.11"). See gh-3588.
160
+ """
161
+ m = re.match(r"(?P<major>[0-9]+)\.(?P<minor>[0-9]+)", version_str)
162
+ if not m:
163
+ warnings.warn(
164
+ f"Expected glibc version with 2 components major.minor, got: {version_str}",
165
+ RuntimeWarning,
166
+ stacklevel=2,
167
+ )
168
+ return -1, -1
169
+ return int(m.group("major")), int(m.group("minor"))
170
+
171
+
172
+ @functools.lru_cache
173
+ def _get_glibc_version() -> tuple[int, int]:
174
+ version_str = _glibc_version_string()
175
+ if version_str is None:
176
+ return (-1, -1)
177
+ return _parse_glibc_version(version_str)
178
+
179
+
180
+ # From PEP 513, PEP 600
181
+ def _is_compatible(arch: str, version: _GLibCVersion) -> bool:
182
+ sys_glibc = _get_glibc_version()
183
+ if sys_glibc < version:
184
+ return False
185
+ # Check for presence of _manylinux module.
186
+ try:
187
+ import _manylinux
188
+ except ImportError:
189
+ return True
190
+ if hasattr(_manylinux, "manylinux_compatible"):
191
+ result = _manylinux.manylinux_compatible(version[0], version[1], arch)
192
+ if result is not None:
193
+ return bool(result)
194
+ return True
195
+ if version == _GLibCVersion(2, 5):
196
+ if hasattr(_manylinux, "manylinux1_compatible"):
197
+ return bool(_manylinux.manylinux1_compatible)
198
+ if version == _GLibCVersion(2, 12):
199
+ if hasattr(_manylinux, "manylinux2010_compatible"):
200
+ return bool(_manylinux.manylinux2010_compatible)
201
+ if version == _GLibCVersion(2, 17):
202
+ if hasattr(_manylinux, "manylinux2014_compatible"):
203
+ return bool(_manylinux.manylinux2014_compatible)
204
+ return True
205
+
206
+
207
+ _LEGACY_MANYLINUX_MAP = {
208
+ # CentOS 7 w/ glibc 2.17 (PEP 599)
209
+ (2, 17): "manylinux2014",
210
+ # CentOS 6 w/ glibc 2.12 (PEP 571)
211
+ (2, 12): "manylinux2010",
212
+ # CentOS 5 w/ glibc 2.5 (PEP 513)
213
+ (2, 5): "manylinux1",
214
+ }
215
+
216
+
217
+ def platform_tags(archs: Sequence[str]) -> Iterator[str]:
218
+ """Generate manylinux tags compatible to the current platform.
219
+
220
+ :param archs: Sequence of compatible architectures.
221
+ The first one shall be the closest to the actual architecture and be the part of
222
+ platform tag after the ``linux_`` prefix, e.g. ``x86_64``.
223
+ The ``linux_`` prefix is assumed as a prerequisite for the current platform to
224
+ be manylinux-compatible.
225
+
226
+ :returns: An iterator of compatible manylinux tags.
227
+ """
228
+ if not _have_compatible_abi(sys.executable, archs):
229
+ return
230
+ # Oldest glibc to be supported regardless of architecture is (2, 17).
231
+ too_old_glibc2 = _GLibCVersion(2, 16)
232
+ if set(archs) & {"x86_64", "i686"}:
233
+ # On x86/i686 also oldest glibc to be supported is (2, 5).
234
+ too_old_glibc2 = _GLibCVersion(2, 4)
235
+ current_glibc = _GLibCVersion(*_get_glibc_version())
236
+ glibc_max_list = [current_glibc]
237
+ # We can assume compatibility across glibc major versions.
238
+ # https://sourceware.org/bugzilla/show_bug.cgi?id=24636
239
+ #
240
+ # Build a list of maximum glibc versions so that we can
241
+ # output the canonical list of all glibc from current_glibc
242
+ # down to too_old_glibc2, including all intermediary versions.
243
+ for glibc_major in range(current_glibc.major - 1, 1, -1):
244
+ glibc_minor = _LAST_GLIBC_MINOR[glibc_major]
245
+ glibc_max_list.append(_GLibCVersion(glibc_major, glibc_minor))
246
+ for arch in archs:
247
+ for glibc_max in glibc_max_list:
248
+ if glibc_max.major == too_old_glibc2.major:
249
+ min_minor = too_old_glibc2.minor
250
+ else:
251
+ # For other glibc major versions oldest supported is (x, 0).
252
+ min_minor = -1
253
+ for glibc_minor in range(glibc_max.minor, min_minor, -1):
254
+ glibc_version = _GLibCVersion(glibc_max.major, glibc_minor)
255
+ tag = "manylinux_{}_{}".format(*glibc_version)
256
+ if _is_compatible(arch, glibc_version):
257
+ yield f"{tag}_{arch}"
258
+ # Handle the legacy manylinux1, manylinux2010, manylinux2014 tags.
259
+ if glibc_version in _LEGACY_MANYLINUX_MAP:
260
+ legacy_tag = _LEGACY_MANYLINUX_MAP[glibc_version]
261
+ if _is_compatible(arch, glibc_version):
262
+ yield f"{legacy_tag}_{arch}"
lib/python3.12/site-packages/packaging/_musllinux.py ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """PEP 656 support.
2
+
3
+ This module implements logic to detect if the currently running Python is
4
+ linked against musl, and what musl version is used.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import functools
10
+ import re
11
+ import subprocess
12
+ import sys
13
+ from typing import Iterator, NamedTuple, Sequence
14
+
15
+ from ._elffile import ELFFile
16
+
17
+
18
+ class _MuslVersion(NamedTuple):
19
+ major: int
20
+ minor: int
21
+
22
+
23
+ def _parse_musl_version(output: str) -> _MuslVersion | None:
24
+ lines = [n for n in (n.strip() for n in output.splitlines()) if n]
25
+ if len(lines) < 2 or lines[0][:4] != "musl":
26
+ return None
27
+ m = re.match(r"Version (\d+)\.(\d+)", lines[1])
28
+ if not m:
29
+ return None
30
+ return _MuslVersion(major=int(m.group(1)), minor=int(m.group(2)))
31
+
32
+
33
+ @functools.lru_cache
34
+ def _get_musl_version(executable: str) -> _MuslVersion | None:
35
+ """Detect currently-running musl runtime version.
36
+
37
+ This is done by checking the specified executable's dynamic linking
38
+ information, and invoking the loader to parse its output for a version
39
+ string. If the loader is musl, the output would be something like::
40
+
41
+ musl libc (x86_64)
42
+ Version 1.2.2
43
+ Dynamic Program Loader
44
+ """
45
+ try:
46
+ with open(executable, "rb") as f:
47
+ ld = ELFFile(f).interpreter
48
+ except (OSError, TypeError, ValueError):
49
+ return None
50
+ if ld is None or "musl" not in ld:
51
+ return None
52
+ proc = subprocess.run([ld], stderr=subprocess.PIPE, text=True)
53
+ return _parse_musl_version(proc.stderr)
54
+
55
+
56
+ def platform_tags(archs: Sequence[str]) -> Iterator[str]:
57
+ """Generate musllinux tags compatible to the current platform.
58
+
59
+ :param archs: Sequence of compatible architectures.
60
+ The first one shall be the closest to the actual architecture and be the part of
61
+ platform tag after the ``linux_`` prefix, e.g. ``x86_64``.
62
+ The ``linux_`` prefix is assumed as a prerequisite for the current platform to
63
+ be musllinux-compatible.
64
+
65
+ :returns: An iterator of compatible musllinux tags.
66
+ """
67
+ sys_musl = _get_musl_version(sys.executable)
68
+ if sys_musl is None: # Python not dynamically linked against musl.
69
+ return
70
+ for arch in archs:
71
+ for minor in range(sys_musl.minor, -1, -1):
72
+ yield f"musllinux_{sys_musl.major}_{minor}_{arch}"
73
+
74
+
75
+ if __name__ == "__main__": # pragma: no cover
76
+ import sysconfig
77
+
78
+ plat = sysconfig.get_platform()
79
+ assert plat.startswith("linux-"), "not linux"
80
+
81
+ print("plat:", plat)
82
+ print("musl:", _get_musl_version(sys.executable))
83
+ print("tags:", end=" ")
84
+ for t in platform_tags(re.sub(r"[.-]", "_", plat.split("-", 1)[-1])):
85
+ print(t, end="\n ")
lib/python3.12/site-packages/packaging/_parser.py ADDED
@@ -0,0 +1,353 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Handwritten parser of dependency specifiers.
2
+
3
+ The docstring for each __parse_* function contains EBNF-inspired grammar representing
4
+ the implementation.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import ast
10
+ from typing import NamedTuple, Sequence, Tuple, Union
11
+
12
+ from ._tokenizer import DEFAULT_RULES, Tokenizer
13
+
14
+
15
+ class Node:
16
+ def __init__(self, value: str) -> None:
17
+ self.value = value
18
+
19
+ def __str__(self) -> str:
20
+ return self.value
21
+
22
+ def __repr__(self) -> str:
23
+ return f"<{self.__class__.__name__}('{self}')>"
24
+
25
+ def serialize(self) -> str:
26
+ raise NotImplementedError
27
+
28
+
29
+ class Variable(Node):
30
+ def serialize(self) -> str:
31
+ return str(self)
32
+
33
+
34
+ class Value(Node):
35
+ def serialize(self) -> str:
36
+ return f'"{self}"'
37
+
38
+
39
+ class Op(Node):
40
+ def serialize(self) -> str:
41
+ return str(self)
42
+
43
+
44
+ MarkerVar = Union[Variable, Value]
45
+ MarkerItem = Tuple[MarkerVar, Op, MarkerVar]
46
+ MarkerAtom = Union[MarkerItem, Sequence["MarkerAtom"]]
47
+ MarkerList = Sequence[Union["MarkerList", MarkerAtom, str]]
48
+
49
+
50
+ class ParsedRequirement(NamedTuple):
51
+ name: str
52
+ url: str
53
+ extras: list[str]
54
+ specifier: str
55
+ marker: MarkerList | None
56
+
57
+
58
+ # --------------------------------------------------------------------------------------
59
+ # Recursive descent parser for dependency specifier
60
+ # --------------------------------------------------------------------------------------
61
+ def parse_requirement(source: str) -> ParsedRequirement:
62
+ return _parse_requirement(Tokenizer(source, rules=DEFAULT_RULES))
63
+
64
+
65
+ def _parse_requirement(tokenizer: Tokenizer) -> ParsedRequirement:
66
+ """
67
+ requirement = WS? IDENTIFIER WS? extras WS? requirement_details
68
+ """
69
+ tokenizer.consume("WS")
70
+
71
+ name_token = tokenizer.expect(
72
+ "IDENTIFIER", expected="package name at the start of dependency specifier"
73
+ )
74
+ name = name_token.text
75
+ tokenizer.consume("WS")
76
+
77
+ extras = _parse_extras(tokenizer)
78
+ tokenizer.consume("WS")
79
+
80
+ url, specifier, marker = _parse_requirement_details(tokenizer)
81
+ tokenizer.expect("END", expected="end of dependency specifier")
82
+
83
+ return ParsedRequirement(name, url, extras, specifier, marker)
84
+
85
+
86
+ def _parse_requirement_details(
87
+ tokenizer: Tokenizer,
88
+ ) -> tuple[str, str, MarkerList | None]:
89
+ """
90
+ requirement_details = AT URL (WS requirement_marker?)?
91
+ | specifier WS? (requirement_marker)?
92
+ """
93
+
94
+ specifier = ""
95
+ url = ""
96
+ marker = None
97
+
98
+ if tokenizer.check("AT"):
99
+ tokenizer.read()
100
+ tokenizer.consume("WS")
101
+
102
+ url_start = tokenizer.position
103
+ url = tokenizer.expect("URL", expected="URL after @").text
104
+ if tokenizer.check("END", peek=True):
105
+ return (url, specifier, marker)
106
+
107
+ tokenizer.expect("WS", expected="whitespace after URL")
108
+
109
+ # The input might end after whitespace.
110
+ if tokenizer.check("END", peek=True):
111
+ return (url, specifier, marker)
112
+
113
+ marker = _parse_requirement_marker(
114
+ tokenizer, span_start=url_start, after="URL and whitespace"
115
+ )
116
+ else:
117
+ specifier_start = tokenizer.position
118
+ specifier = _parse_specifier(tokenizer)
119
+ tokenizer.consume("WS")
120
+
121
+ if tokenizer.check("END", peek=True):
122
+ return (url, specifier, marker)
123
+
124
+ marker = _parse_requirement_marker(
125
+ tokenizer,
126
+ span_start=specifier_start,
127
+ after=(
128
+ "version specifier"
129
+ if specifier
130
+ else "name and no valid version specifier"
131
+ ),
132
+ )
133
+
134
+ return (url, specifier, marker)
135
+
136
+
137
+ def _parse_requirement_marker(
138
+ tokenizer: Tokenizer, *, span_start: int, after: str
139
+ ) -> MarkerList:
140
+ """
141
+ requirement_marker = SEMICOLON marker WS?
142
+ """
143
+
144
+ if not tokenizer.check("SEMICOLON"):
145
+ tokenizer.raise_syntax_error(
146
+ f"Expected end or semicolon (after {after})",
147
+ span_start=span_start,
148
+ )
149
+ tokenizer.read()
150
+
151
+ marker = _parse_marker(tokenizer)
152
+ tokenizer.consume("WS")
153
+
154
+ return marker
155
+
156
+
157
+ def _parse_extras(tokenizer: Tokenizer) -> list[str]:
158
+ """
159
+ extras = (LEFT_BRACKET wsp* extras_list? wsp* RIGHT_BRACKET)?
160
+ """
161
+ if not tokenizer.check("LEFT_BRACKET", peek=True):
162
+ return []
163
+
164
+ with tokenizer.enclosing_tokens(
165
+ "LEFT_BRACKET",
166
+ "RIGHT_BRACKET",
167
+ around="extras",
168
+ ):
169
+ tokenizer.consume("WS")
170
+ extras = _parse_extras_list(tokenizer)
171
+ tokenizer.consume("WS")
172
+
173
+ return extras
174
+
175
+
176
+ def _parse_extras_list(tokenizer: Tokenizer) -> list[str]:
177
+ """
178
+ extras_list = identifier (wsp* ',' wsp* identifier)*
179
+ """
180
+ extras: list[str] = []
181
+
182
+ if not tokenizer.check("IDENTIFIER"):
183
+ return extras
184
+
185
+ extras.append(tokenizer.read().text)
186
+
187
+ while True:
188
+ tokenizer.consume("WS")
189
+ if tokenizer.check("IDENTIFIER", peek=True):
190
+ tokenizer.raise_syntax_error("Expected comma between extra names")
191
+ elif not tokenizer.check("COMMA"):
192
+ break
193
+
194
+ tokenizer.read()
195
+ tokenizer.consume("WS")
196
+
197
+ extra_token = tokenizer.expect("IDENTIFIER", expected="extra name after comma")
198
+ extras.append(extra_token.text)
199
+
200
+ return extras
201
+
202
+
203
+ def _parse_specifier(tokenizer: Tokenizer) -> str:
204
+ """
205
+ specifier = LEFT_PARENTHESIS WS? version_many WS? RIGHT_PARENTHESIS
206
+ | WS? version_many WS?
207
+ """
208
+ with tokenizer.enclosing_tokens(
209
+ "LEFT_PARENTHESIS",
210
+ "RIGHT_PARENTHESIS",
211
+ around="version specifier",
212
+ ):
213
+ tokenizer.consume("WS")
214
+ parsed_specifiers = _parse_version_many(tokenizer)
215
+ tokenizer.consume("WS")
216
+
217
+ return parsed_specifiers
218
+
219
+
220
+ def _parse_version_many(tokenizer: Tokenizer) -> str:
221
+ """
222
+ version_many = (SPECIFIER (WS? COMMA WS? SPECIFIER)*)?
223
+ """
224
+ parsed_specifiers = ""
225
+ while tokenizer.check("SPECIFIER"):
226
+ span_start = tokenizer.position
227
+ parsed_specifiers += tokenizer.read().text
228
+ if tokenizer.check("VERSION_PREFIX_TRAIL", peek=True):
229
+ tokenizer.raise_syntax_error(
230
+ ".* suffix can only be used with `==` or `!=` operators",
231
+ span_start=span_start,
232
+ span_end=tokenizer.position + 1,
233
+ )
234
+ if tokenizer.check("VERSION_LOCAL_LABEL_TRAIL", peek=True):
235
+ tokenizer.raise_syntax_error(
236
+ "Local version label can only be used with `==` or `!=` operators",
237
+ span_start=span_start,
238
+ span_end=tokenizer.position,
239
+ )
240
+ tokenizer.consume("WS")
241
+ if not tokenizer.check("COMMA"):
242
+ break
243
+ parsed_specifiers += tokenizer.read().text
244
+ tokenizer.consume("WS")
245
+
246
+ return parsed_specifiers
247
+
248
+
249
+ # --------------------------------------------------------------------------------------
250
+ # Recursive descent parser for marker expression
251
+ # --------------------------------------------------------------------------------------
252
+ def parse_marker(source: str) -> MarkerList:
253
+ return _parse_full_marker(Tokenizer(source, rules=DEFAULT_RULES))
254
+
255
+
256
+ def _parse_full_marker(tokenizer: Tokenizer) -> MarkerList:
257
+ retval = _parse_marker(tokenizer)
258
+ tokenizer.expect("END", expected="end of marker expression")
259
+ return retval
260
+
261
+
262
+ def _parse_marker(tokenizer: Tokenizer) -> MarkerList:
263
+ """
264
+ marker = marker_atom (BOOLOP marker_atom)+
265
+ """
266
+ expression = [_parse_marker_atom(tokenizer)]
267
+ while tokenizer.check("BOOLOP"):
268
+ token = tokenizer.read()
269
+ expr_right = _parse_marker_atom(tokenizer)
270
+ expression.extend((token.text, expr_right))
271
+ return expression
272
+
273
+
274
+ def _parse_marker_atom(tokenizer: Tokenizer) -> MarkerAtom:
275
+ """
276
+ marker_atom = WS? LEFT_PARENTHESIS WS? marker WS? RIGHT_PARENTHESIS WS?
277
+ | WS? marker_item WS?
278
+ """
279
+
280
+ tokenizer.consume("WS")
281
+ if tokenizer.check("LEFT_PARENTHESIS", peek=True):
282
+ with tokenizer.enclosing_tokens(
283
+ "LEFT_PARENTHESIS",
284
+ "RIGHT_PARENTHESIS",
285
+ around="marker expression",
286
+ ):
287
+ tokenizer.consume("WS")
288
+ marker: MarkerAtom = _parse_marker(tokenizer)
289
+ tokenizer.consume("WS")
290
+ else:
291
+ marker = _parse_marker_item(tokenizer)
292
+ tokenizer.consume("WS")
293
+ return marker
294
+
295
+
296
+ def _parse_marker_item(tokenizer: Tokenizer) -> MarkerItem:
297
+ """
298
+ marker_item = WS? marker_var WS? marker_op WS? marker_var WS?
299
+ """
300
+ tokenizer.consume("WS")
301
+ marker_var_left = _parse_marker_var(tokenizer)
302
+ tokenizer.consume("WS")
303
+ marker_op = _parse_marker_op(tokenizer)
304
+ tokenizer.consume("WS")
305
+ marker_var_right = _parse_marker_var(tokenizer)
306
+ tokenizer.consume("WS")
307
+ return (marker_var_left, marker_op, marker_var_right)
308
+
309
+
310
+ def _parse_marker_var(tokenizer: Tokenizer) -> MarkerVar:
311
+ """
312
+ marker_var = VARIABLE | QUOTED_STRING
313
+ """
314
+ if tokenizer.check("VARIABLE"):
315
+ return process_env_var(tokenizer.read().text.replace(".", "_"))
316
+ elif tokenizer.check("QUOTED_STRING"):
317
+ return process_python_str(tokenizer.read().text)
318
+ else:
319
+ tokenizer.raise_syntax_error(
320
+ message="Expected a marker variable or quoted string"
321
+ )
322
+
323
+
324
+ def process_env_var(env_var: str) -> Variable:
325
+ if env_var in ("platform_python_implementation", "python_implementation"):
326
+ return Variable("platform_python_implementation")
327
+ else:
328
+ return Variable(env_var)
329
+
330
+
331
+ def process_python_str(python_str: str) -> Value:
332
+ value = ast.literal_eval(python_str)
333
+ return Value(str(value))
334
+
335
+
336
+ def _parse_marker_op(tokenizer: Tokenizer) -> Op:
337
+ """
338
+ marker_op = IN | NOT IN | OP
339
+ """
340
+ if tokenizer.check("IN"):
341
+ tokenizer.read()
342
+ return Op("in")
343
+ elif tokenizer.check("NOT"):
344
+ tokenizer.read()
345
+ tokenizer.expect("WS", expected="whitespace after 'not'")
346
+ tokenizer.expect("IN", expected="'in' after 'not'")
347
+ return Op("not in")
348
+ elif tokenizer.check("OP"):
349
+ return Op(tokenizer.read().text)
350
+ else:
351
+ return tokenizer.raise_syntax_error(
352
+ "Expected marker operator, one of <=, <, !=, ==, >=, >, ~=, ===, in, not in"
353
+ )
lib/python3.12/site-packages/packaging/_structures.py ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This file is dual licensed under the terms of the Apache License, Version
2
+ # 2.0, and the BSD License. See the LICENSE file in the root of this repository
3
+ # for complete details.
4
+
5
+
6
+ class InfinityType:
7
+ def __repr__(self) -> str:
8
+ return "Infinity"
9
+
10
+ def __hash__(self) -> int:
11
+ return hash(repr(self))
12
+
13
+ def __lt__(self, other: object) -> bool:
14
+ return False
15
+
16
+ def __le__(self, other: object) -> bool:
17
+ return False
18
+
19
+ def __eq__(self, other: object) -> bool:
20
+ return isinstance(other, self.__class__)
21
+
22
+ def __gt__(self, other: object) -> bool:
23
+ return True
24
+
25
+ def __ge__(self, other: object) -> bool:
26
+ return True
27
+
28
+ def __neg__(self: object) -> "NegativeInfinityType":
29
+ return NegativeInfinity
30
+
31
+
32
+ Infinity = InfinityType()
33
+
34
+
35
+ class NegativeInfinityType:
36
+ def __repr__(self) -> str:
37
+ return "-Infinity"
38
+
39
+ def __hash__(self) -> int:
40
+ return hash(repr(self))
41
+
42
+ def __lt__(self, other: object) -> bool:
43
+ return True
44
+
45
+ def __le__(self, other: object) -> bool:
46
+ return True
47
+
48
+ def __eq__(self, other: object) -> bool:
49
+ return isinstance(other, self.__class__)
50
+
51
+ def __gt__(self, other: object) -> bool:
52
+ return False
53
+
54
+ def __ge__(self, other: object) -> bool:
55
+ return False
56
+
57
+ def __neg__(self: object) -> InfinityType:
58
+ return Infinity
59
+
60
+
61
+ NegativeInfinity = NegativeInfinityType()
lib/python3.12/site-packages/packaging/_tokenizer.py ADDED
@@ -0,0 +1,195 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import contextlib
4
+ import re
5
+ from dataclasses import dataclass
6
+ from typing import Iterator, NoReturn
7
+
8
+ from .specifiers import Specifier
9
+
10
+
11
+ @dataclass
12
+ class Token:
13
+ name: str
14
+ text: str
15
+ position: int
16
+
17
+
18
+ class ParserSyntaxError(Exception):
19
+ """The provided source text could not be parsed correctly."""
20
+
21
+ def __init__(
22
+ self,
23
+ message: str,
24
+ *,
25
+ source: str,
26
+ span: tuple[int, int],
27
+ ) -> None:
28
+ self.span = span
29
+ self.message = message
30
+ self.source = source
31
+
32
+ super().__init__()
33
+
34
+ def __str__(self) -> str:
35
+ marker = " " * self.span[0] + "~" * (self.span[1] - self.span[0]) + "^"
36
+ return "\n ".join([self.message, self.source, marker])
37
+
38
+
39
+ DEFAULT_RULES: dict[str, str | re.Pattern[str]] = {
40
+ "LEFT_PARENTHESIS": r"\(",
41
+ "RIGHT_PARENTHESIS": r"\)",
42
+ "LEFT_BRACKET": r"\[",
43
+ "RIGHT_BRACKET": r"\]",
44
+ "SEMICOLON": r";",
45
+ "COMMA": r",",
46
+ "QUOTED_STRING": re.compile(
47
+ r"""
48
+ (
49
+ ('[^']*')
50
+ |
51
+ ("[^"]*")
52
+ )
53
+ """,
54
+ re.VERBOSE,
55
+ ),
56
+ "OP": r"(===|==|~=|!=|<=|>=|<|>)",
57
+ "BOOLOP": r"\b(or|and)\b",
58
+ "IN": r"\bin\b",
59
+ "NOT": r"\bnot\b",
60
+ "VARIABLE": re.compile(
61
+ r"""
62
+ \b(
63
+ python_version
64
+ |python_full_version
65
+ |os[._]name
66
+ |sys[._]platform
67
+ |platform_(release|system)
68
+ |platform[._](version|machine|python_implementation)
69
+ |python_implementation
70
+ |implementation_(name|version)
71
+ |extras?
72
+ |dependency_groups
73
+ )\b
74
+ """,
75
+ re.VERBOSE,
76
+ ),
77
+ "SPECIFIER": re.compile(
78
+ Specifier._operator_regex_str + Specifier._version_regex_str,
79
+ re.VERBOSE | re.IGNORECASE,
80
+ ),
81
+ "AT": r"\@",
82
+ "URL": r"[^ \t]+",
83
+ "IDENTIFIER": r"\b[a-zA-Z0-9][a-zA-Z0-9._-]*\b",
84
+ "VERSION_PREFIX_TRAIL": r"\.\*",
85
+ "VERSION_LOCAL_LABEL_TRAIL": r"\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*",
86
+ "WS": r"[ \t]+",
87
+ "END": r"$",
88
+ }
89
+
90
+
91
+ class Tokenizer:
92
+ """Context-sensitive token parsing.
93
+
94
+ Provides methods to examine the input stream to check whether the next token
95
+ matches.
96
+ """
97
+
98
+ def __init__(
99
+ self,
100
+ source: str,
101
+ *,
102
+ rules: dict[str, str | re.Pattern[str]],
103
+ ) -> None:
104
+ self.source = source
105
+ self.rules: dict[str, re.Pattern[str]] = {
106
+ name: re.compile(pattern) for name, pattern in rules.items()
107
+ }
108
+ self.next_token: Token | None = None
109
+ self.position = 0
110
+
111
+ def consume(self, name: str) -> None:
112
+ """Move beyond provided token name, if at current position."""
113
+ if self.check(name):
114
+ self.read()
115
+
116
+ def check(self, name: str, *, peek: bool = False) -> bool:
117
+ """Check whether the next token has the provided name.
118
+
119
+ By default, if the check succeeds, the token *must* be read before
120
+ another check. If `peek` is set to `True`, the token is not loaded and
121
+ would need to be checked again.
122
+ """
123
+ assert self.next_token is None, (
124
+ f"Cannot check for {name!r}, already have {self.next_token!r}"
125
+ )
126
+ assert name in self.rules, f"Unknown token name: {name!r}"
127
+
128
+ expression = self.rules[name]
129
+
130
+ match = expression.match(self.source, self.position)
131
+ if match is None:
132
+ return False
133
+ if not peek:
134
+ self.next_token = Token(name, match[0], self.position)
135
+ return True
136
+
137
+ def expect(self, name: str, *, expected: str) -> Token:
138
+ """Expect a certain token name next, failing with a syntax error otherwise.
139
+
140
+ The token is *not* read.
141
+ """
142
+ if not self.check(name):
143
+ raise self.raise_syntax_error(f"Expected {expected}")
144
+ return self.read()
145
+
146
+ def read(self) -> Token:
147
+ """Consume the next token and return it."""
148
+ token = self.next_token
149
+ assert token is not None
150
+
151
+ self.position += len(token.text)
152
+ self.next_token = None
153
+
154
+ return token
155
+
156
+ def raise_syntax_error(
157
+ self,
158
+ message: str,
159
+ *,
160
+ span_start: int | None = None,
161
+ span_end: int | None = None,
162
+ ) -> NoReturn:
163
+ """Raise ParserSyntaxError at the given position."""
164
+ span = (
165
+ self.position if span_start is None else span_start,
166
+ self.position if span_end is None else span_end,
167
+ )
168
+ raise ParserSyntaxError(
169
+ message,
170
+ source=self.source,
171
+ span=span,
172
+ )
173
+
174
+ @contextlib.contextmanager
175
+ def enclosing_tokens(
176
+ self, open_token: str, close_token: str, *, around: str
177
+ ) -> Iterator[None]:
178
+ if self.check(open_token):
179
+ open_position = self.position
180
+ self.read()
181
+ else:
182
+ open_position = None
183
+
184
+ yield
185
+
186
+ if open_position is None:
187
+ return
188
+
189
+ if not self.check(close_token):
190
+ self.raise_syntax_error(
191
+ f"Expected matching {close_token} for {open_token}, after {around}",
192
+ span_start=open_position,
193
+ )
194
+
195
+ self.read()
lib/python3.12/site-packages/packaging/licenses/__init__.py ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #######################################################################################
2
+ #
3
+ # Adapted from:
4
+ # https://github.com/pypa/hatch/blob/5352e44/backend/src/hatchling/licenses/parse.py
5
+ #
6
+ # MIT License
7
+ #
8
+ # Copyright (c) 2017-present Ofek Lev <oss@ofek.dev>
9
+ #
10
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of this
11
+ # software and associated documentation files (the "Software"), to deal in the Software
12
+ # without restriction, including without limitation the rights to use, copy, modify,
13
+ # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
14
+ # permit persons to whom the Software is furnished to do so, subject to the following
15
+ # conditions:
16
+ #
17
+ # The above copyright notice and this permission notice shall be included in all copies
18
+ # or substantial portions of the Software.
19
+ #
20
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
21
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
22
+ # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23
+ # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
24
+ # CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
25
+ # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
+ #
27
+ #
28
+ # With additional allowance of arbitrary `LicenseRef-` identifiers, not just
29
+ # `LicenseRef-Public-Domain` and `LicenseRef-Proprietary`.
30
+ #
31
+ #######################################################################################
32
+ from __future__ import annotations
33
+
34
+ import re
35
+ from typing import NewType, cast
36
+
37
+ from packaging.licenses._spdx import EXCEPTIONS, LICENSES
38
+
39
+ __all__ = [
40
+ "InvalidLicenseExpression",
41
+ "NormalizedLicenseExpression",
42
+ "canonicalize_license_expression",
43
+ ]
44
+
45
+ license_ref_allowed = re.compile("^[A-Za-z0-9.-]*$")
46
+
47
+ NormalizedLicenseExpression = NewType("NormalizedLicenseExpression", str)
48
+
49
+
50
+ class InvalidLicenseExpression(ValueError):
51
+ """Raised when a license-expression string is invalid
52
+
53
+ >>> canonicalize_license_expression("invalid")
54
+ Traceback (most recent call last):
55
+ ...
56
+ packaging.licenses.InvalidLicenseExpression: Invalid license expression: 'invalid'
57
+ """
58
+
59
+
60
+ def canonicalize_license_expression(
61
+ raw_license_expression: str,
62
+ ) -> NormalizedLicenseExpression:
63
+ if not raw_license_expression:
64
+ message = f"Invalid license expression: {raw_license_expression!r}"
65
+ raise InvalidLicenseExpression(message)
66
+
67
+ # Pad any parentheses so tokenization can be achieved by merely splitting on
68
+ # whitespace.
69
+ license_expression = raw_license_expression.replace("(", " ( ").replace(")", " ) ")
70
+ licenseref_prefix = "LicenseRef-"
71
+ license_refs = {
72
+ ref.lower(): "LicenseRef-" + ref[len(licenseref_prefix) :]
73
+ for ref in license_expression.split()
74
+ if ref.lower().startswith(licenseref_prefix.lower())
75
+ }
76
+
77
+ # Normalize to lower case so we can look up licenses/exceptions
78
+ # and so boolean operators are Python-compatible.
79
+ license_expression = license_expression.lower()
80
+
81
+ tokens = license_expression.split()
82
+
83
+ # Rather than implementing boolean logic, we create an expression that Python can
84
+ # parse. Everything that is not involved with the grammar itself is treated as
85
+ # `False` and the expression should evaluate as such.
86
+ python_tokens = []
87
+ for token in tokens:
88
+ if token not in {"or", "and", "with", "(", ")"}:
89
+ python_tokens.append("False")
90
+ elif token == "with":
91
+ python_tokens.append("or")
92
+ elif token == "(" and python_tokens and python_tokens[-1] not in {"or", "and"}:
93
+ message = f"Invalid license expression: {raw_license_expression!r}"
94
+ raise InvalidLicenseExpression(message)
95
+ else:
96
+ python_tokens.append(token)
97
+
98
+ python_expression = " ".join(python_tokens)
99
+ try:
100
+ invalid = eval(python_expression, globals(), locals())
101
+ except Exception:
102
+ invalid = True
103
+
104
+ if invalid is not False:
105
+ message = f"Invalid license expression: {raw_license_expression!r}"
106
+ raise InvalidLicenseExpression(message) from None
107
+
108
+ # Take a final pass to check for unknown licenses/exceptions.
109
+ normalized_tokens = []
110
+ for token in tokens:
111
+ if token in {"or", "and", "with", "(", ")"}:
112
+ normalized_tokens.append(token.upper())
113
+ continue
114
+
115
+ if normalized_tokens and normalized_tokens[-1] == "WITH":
116
+ if token not in EXCEPTIONS:
117
+ message = f"Unknown license exception: {token!r}"
118
+ raise InvalidLicenseExpression(message)
119
+
120
+ normalized_tokens.append(EXCEPTIONS[token]["id"])
121
+ else:
122
+ if token.endswith("+"):
123
+ final_token = token[:-1]
124
+ suffix = "+"
125
+ else:
126
+ final_token = token
127
+ suffix = ""
128
+
129
+ if final_token.startswith("licenseref-"):
130
+ if not license_ref_allowed.match(final_token):
131
+ message = f"Invalid licenseref: {final_token!r}"
132
+ raise InvalidLicenseExpression(message)
133
+ normalized_tokens.append(license_refs[final_token] + suffix)
134
+ else:
135
+ if final_token not in LICENSES:
136
+ message = f"Unknown license: {final_token!r}"
137
+ raise InvalidLicenseExpression(message)
138
+ normalized_tokens.append(LICENSES[final_token]["id"] + suffix)
139
+
140
+ normalized_expression = " ".join(normalized_tokens)
141
+
142
+ return cast(
143
+ NormalizedLicenseExpression,
144
+ normalized_expression.replace("( ", "(").replace(" )", ")"),
145
+ )
lib/python3.12/site-packages/packaging/licenses/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (4.1 kB). View file
 
lib/python3.12/site-packages/packaging/licenses/__pycache__/_spdx.cpython-312.pyc ADDED
Binary file (47.4 kB). View file
 
lib/python3.12/site-packages/packaging/licenses/_spdx.py ADDED
@@ -0,0 +1,759 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ from __future__ import annotations
3
+
4
+ from typing import TypedDict
5
+
6
+ class SPDXLicense(TypedDict):
7
+ id: str
8
+ deprecated: bool
9
+
10
+ class SPDXException(TypedDict):
11
+ id: str
12
+ deprecated: bool
13
+
14
+
15
+ VERSION = '3.25.0'
16
+
17
+ LICENSES: dict[str, SPDXLicense] = {
18
+ '0bsd': {'id': '0BSD', 'deprecated': False},
19
+ '3d-slicer-1.0': {'id': '3D-Slicer-1.0', 'deprecated': False},
20
+ 'aal': {'id': 'AAL', 'deprecated': False},
21
+ 'abstyles': {'id': 'Abstyles', 'deprecated': False},
22
+ 'adacore-doc': {'id': 'AdaCore-doc', 'deprecated': False},
23
+ 'adobe-2006': {'id': 'Adobe-2006', 'deprecated': False},
24
+ 'adobe-display-postscript': {'id': 'Adobe-Display-PostScript', 'deprecated': False},
25
+ 'adobe-glyph': {'id': 'Adobe-Glyph', 'deprecated': False},
26
+ 'adobe-utopia': {'id': 'Adobe-Utopia', 'deprecated': False},
27
+ 'adsl': {'id': 'ADSL', 'deprecated': False},
28
+ 'afl-1.1': {'id': 'AFL-1.1', 'deprecated': False},
29
+ 'afl-1.2': {'id': 'AFL-1.2', 'deprecated': False},
30
+ 'afl-2.0': {'id': 'AFL-2.0', 'deprecated': False},
31
+ 'afl-2.1': {'id': 'AFL-2.1', 'deprecated': False},
32
+ 'afl-3.0': {'id': 'AFL-3.0', 'deprecated': False},
33
+ 'afmparse': {'id': 'Afmparse', 'deprecated': False},
34
+ 'agpl-1.0': {'id': 'AGPL-1.0', 'deprecated': True},
35
+ 'agpl-1.0-only': {'id': 'AGPL-1.0-only', 'deprecated': False},
36
+ 'agpl-1.0-or-later': {'id': 'AGPL-1.0-or-later', 'deprecated': False},
37
+ 'agpl-3.0': {'id': 'AGPL-3.0', 'deprecated': True},
38
+ 'agpl-3.0-only': {'id': 'AGPL-3.0-only', 'deprecated': False},
39
+ 'agpl-3.0-or-later': {'id': 'AGPL-3.0-or-later', 'deprecated': False},
40
+ 'aladdin': {'id': 'Aladdin', 'deprecated': False},
41
+ 'amd-newlib': {'id': 'AMD-newlib', 'deprecated': False},
42
+ 'amdplpa': {'id': 'AMDPLPA', 'deprecated': False},
43
+ 'aml': {'id': 'AML', 'deprecated': False},
44
+ 'aml-glslang': {'id': 'AML-glslang', 'deprecated': False},
45
+ 'ampas': {'id': 'AMPAS', 'deprecated': False},
46
+ 'antlr-pd': {'id': 'ANTLR-PD', 'deprecated': False},
47
+ 'antlr-pd-fallback': {'id': 'ANTLR-PD-fallback', 'deprecated': False},
48
+ 'any-osi': {'id': 'any-OSI', 'deprecated': False},
49
+ 'apache-1.0': {'id': 'Apache-1.0', 'deprecated': False},
50
+ 'apache-1.1': {'id': 'Apache-1.1', 'deprecated': False},
51
+ 'apache-2.0': {'id': 'Apache-2.0', 'deprecated': False},
52
+ 'apafml': {'id': 'APAFML', 'deprecated': False},
53
+ 'apl-1.0': {'id': 'APL-1.0', 'deprecated': False},
54
+ 'app-s2p': {'id': 'App-s2p', 'deprecated': False},
55
+ 'apsl-1.0': {'id': 'APSL-1.0', 'deprecated': False},
56
+ 'apsl-1.1': {'id': 'APSL-1.1', 'deprecated': False},
57
+ 'apsl-1.2': {'id': 'APSL-1.2', 'deprecated': False},
58
+ 'apsl-2.0': {'id': 'APSL-2.0', 'deprecated': False},
59
+ 'arphic-1999': {'id': 'Arphic-1999', 'deprecated': False},
60
+ 'artistic-1.0': {'id': 'Artistic-1.0', 'deprecated': False},
61
+ 'artistic-1.0-cl8': {'id': 'Artistic-1.0-cl8', 'deprecated': False},
62
+ 'artistic-1.0-perl': {'id': 'Artistic-1.0-Perl', 'deprecated': False},
63
+ 'artistic-2.0': {'id': 'Artistic-2.0', 'deprecated': False},
64
+ 'aswf-digital-assets-1.0': {'id': 'ASWF-Digital-Assets-1.0', 'deprecated': False},
65
+ 'aswf-digital-assets-1.1': {'id': 'ASWF-Digital-Assets-1.1', 'deprecated': False},
66
+ 'baekmuk': {'id': 'Baekmuk', 'deprecated': False},
67
+ 'bahyph': {'id': 'Bahyph', 'deprecated': False},
68
+ 'barr': {'id': 'Barr', 'deprecated': False},
69
+ 'bcrypt-solar-designer': {'id': 'bcrypt-Solar-Designer', 'deprecated': False},
70
+ 'beerware': {'id': 'Beerware', 'deprecated': False},
71
+ 'bitstream-charter': {'id': 'Bitstream-Charter', 'deprecated': False},
72
+ 'bitstream-vera': {'id': 'Bitstream-Vera', 'deprecated': False},
73
+ 'bittorrent-1.0': {'id': 'BitTorrent-1.0', 'deprecated': False},
74
+ 'bittorrent-1.1': {'id': 'BitTorrent-1.1', 'deprecated': False},
75
+ 'blessing': {'id': 'blessing', 'deprecated': False},
76
+ 'blueoak-1.0.0': {'id': 'BlueOak-1.0.0', 'deprecated': False},
77
+ 'boehm-gc': {'id': 'Boehm-GC', 'deprecated': False},
78
+ 'borceux': {'id': 'Borceux', 'deprecated': False},
79
+ 'brian-gladman-2-clause': {'id': 'Brian-Gladman-2-Clause', 'deprecated': False},
80
+ 'brian-gladman-3-clause': {'id': 'Brian-Gladman-3-Clause', 'deprecated': False},
81
+ 'bsd-1-clause': {'id': 'BSD-1-Clause', 'deprecated': False},
82
+ 'bsd-2-clause': {'id': 'BSD-2-Clause', 'deprecated': False},
83
+ 'bsd-2-clause-darwin': {'id': 'BSD-2-Clause-Darwin', 'deprecated': False},
84
+ 'bsd-2-clause-first-lines': {'id': 'BSD-2-Clause-first-lines', 'deprecated': False},
85
+ 'bsd-2-clause-freebsd': {'id': 'BSD-2-Clause-FreeBSD', 'deprecated': True},
86
+ 'bsd-2-clause-netbsd': {'id': 'BSD-2-Clause-NetBSD', 'deprecated': True},
87
+ 'bsd-2-clause-patent': {'id': 'BSD-2-Clause-Patent', 'deprecated': False},
88
+ 'bsd-2-clause-views': {'id': 'BSD-2-Clause-Views', 'deprecated': False},
89
+ 'bsd-3-clause': {'id': 'BSD-3-Clause', 'deprecated': False},
90
+ 'bsd-3-clause-acpica': {'id': 'BSD-3-Clause-acpica', 'deprecated': False},
91
+ 'bsd-3-clause-attribution': {'id': 'BSD-3-Clause-Attribution', 'deprecated': False},
92
+ 'bsd-3-clause-clear': {'id': 'BSD-3-Clause-Clear', 'deprecated': False},
93
+ 'bsd-3-clause-flex': {'id': 'BSD-3-Clause-flex', 'deprecated': False},
94
+ 'bsd-3-clause-hp': {'id': 'BSD-3-Clause-HP', 'deprecated': False},
95
+ 'bsd-3-clause-lbnl': {'id': 'BSD-3-Clause-LBNL', 'deprecated': False},
96
+ 'bsd-3-clause-modification': {'id': 'BSD-3-Clause-Modification', 'deprecated': False},
97
+ 'bsd-3-clause-no-military-license': {'id': 'BSD-3-Clause-No-Military-License', 'deprecated': False},
98
+ 'bsd-3-clause-no-nuclear-license': {'id': 'BSD-3-Clause-No-Nuclear-License', 'deprecated': False},
99
+ 'bsd-3-clause-no-nuclear-license-2014': {'id': 'BSD-3-Clause-No-Nuclear-License-2014', 'deprecated': False},
100
+ 'bsd-3-clause-no-nuclear-warranty': {'id': 'BSD-3-Clause-No-Nuclear-Warranty', 'deprecated': False},
101
+ 'bsd-3-clause-open-mpi': {'id': 'BSD-3-Clause-Open-MPI', 'deprecated': False},
102
+ 'bsd-3-clause-sun': {'id': 'BSD-3-Clause-Sun', 'deprecated': False},
103
+ 'bsd-4-clause': {'id': 'BSD-4-Clause', 'deprecated': False},
104
+ 'bsd-4-clause-shortened': {'id': 'BSD-4-Clause-Shortened', 'deprecated': False},
105
+ 'bsd-4-clause-uc': {'id': 'BSD-4-Clause-UC', 'deprecated': False},
106
+ 'bsd-4.3reno': {'id': 'BSD-4.3RENO', 'deprecated': False},
107
+ 'bsd-4.3tahoe': {'id': 'BSD-4.3TAHOE', 'deprecated': False},
108
+ 'bsd-advertising-acknowledgement': {'id': 'BSD-Advertising-Acknowledgement', 'deprecated': False},
109
+ 'bsd-attribution-hpnd-disclaimer': {'id': 'BSD-Attribution-HPND-disclaimer', 'deprecated': False},
110
+ 'bsd-inferno-nettverk': {'id': 'BSD-Inferno-Nettverk', 'deprecated': False},
111
+ 'bsd-protection': {'id': 'BSD-Protection', 'deprecated': False},
112
+ 'bsd-source-beginning-file': {'id': 'BSD-Source-beginning-file', 'deprecated': False},
113
+ 'bsd-source-code': {'id': 'BSD-Source-Code', 'deprecated': False},
114
+ 'bsd-systemics': {'id': 'BSD-Systemics', 'deprecated': False},
115
+ 'bsd-systemics-w3works': {'id': 'BSD-Systemics-W3Works', 'deprecated': False},
116
+ 'bsl-1.0': {'id': 'BSL-1.0', 'deprecated': False},
117
+ 'busl-1.1': {'id': 'BUSL-1.1', 'deprecated': False},
118
+ 'bzip2-1.0.5': {'id': 'bzip2-1.0.5', 'deprecated': True},
119
+ 'bzip2-1.0.6': {'id': 'bzip2-1.0.6', 'deprecated': False},
120
+ 'c-uda-1.0': {'id': 'C-UDA-1.0', 'deprecated': False},
121
+ 'cal-1.0': {'id': 'CAL-1.0', 'deprecated': False},
122
+ 'cal-1.0-combined-work-exception': {'id': 'CAL-1.0-Combined-Work-Exception', 'deprecated': False},
123
+ 'caldera': {'id': 'Caldera', 'deprecated': False},
124
+ 'caldera-no-preamble': {'id': 'Caldera-no-preamble', 'deprecated': False},
125
+ 'catharon': {'id': 'Catharon', 'deprecated': False},
126
+ 'catosl-1.1': {'id': 'CATOSL-1.1', 'deprecated': False},
127
+ 'cc-by-1.0': {'id': 'CC-BY-1.0', 'deprecated': False},
128
+ 'cc-by-2.0': {'id': 'CC-BY-2.0', 'deprecated': False},
129
+ 'cc-by-2.5': {'id': 'CC-BY-2.5', 'deprecated': False},
130
+ 'cc-by-2.5-au': {'id': 'CC-BY-2.5-AU', 'deprecated': False},
131
+ 'cc-by-3.0': {'id': 'CC-BY-3.0', 'deprecated': False},
132
+ 'cc-by-3.0-at': {'id': 'CC-BY-3.0-AT', 'deprecated': False},
133
+ 'cc-by-3.0-au': {'id': 'CC-BY-3.0-AU', 'deprecated': False},
134
+ 'cc-by-3.0-de': {'id': 'CC-BY-3.0-DE', 'deprecated': False},
135
+ 'cc-by-3.0-igo': {'id': 'CC-BY-3.0-IGO', 'deprecated': False},
136
+ 'cc-by-3.0-nl': {'id': 'CC-BY-3.0-NL', 'deprecated': False},
137
+ 'cc-by-3.0-us': {'id': 'CC-BY-3.0-US', 'deprecated': False},
138
+ 'cc-by-4.0': {'id': 'CC-BY-4.0', 'deprecated': False},
139
+ 'cc-by-nc-1.0': {'id': 'CC-BY-NC-1.0', 'deprecated': False},
140
+ 'cc-by-nc-2.0': {'id': 'CC-BY-NC-2.0', 'deprecated': False},
141
+ 'cc-by-nc-2.5': {'id': 'CC-BY-NC-2.5', 'deprecated': False},
142
+ 'cc-by-nc-3.0': {'id': 'CC-BY-NC-3.0', 'deprecated': False},
143
+ 'cc-by-nc-3.0-de': {'id': 'CC-BY-NC-3.0-DE', 'deprecated': False},
144
+ 'cc-by-nc-4.0': {'id': 'CC-BY-NC-4.0', 'deprecated': False},
145
+ 'cc-by-nc-nd-1.0': {'id': 'CC-BY-NC-ND-1.0', 'deprecated': False},
146
+ 'cc-by-nc-nd-2.0': {'id': 'CC-BY-NC-ND-2.0', 'deprecated': False},
147
+ 'cc-by-nc-nd-2.5': {'id': 'CC-BY-NC-ND-2.5', 'deprecated': False},
148
+ 'cc-by-nc-nd-3.0': {'id': 'CC-BY-NC-ND-3.0', 'deprecated': False},
149
+ 'cc-by-nc-nd-3.0-de': {'id': 'CC-BY-NC-ND-3.0-DE', 'deprecated': False},
150
+ 'cc-by-nc-nd-3.0-igo': {'id': 'CC-BY-NC-ND-3.0-IGO', 'deprecated': False},
151
+ 'cc-by-nc-nd-4.0': {'id': 'CC-BY-NC-ND-4.0', 'deprecated': False},
152
+ 'cc-by-nc-sa-1.0': {'id': 'CC-BY-NC-SA-1.0', 'deprecated': False},
153
+ 'cc-by-nc-sa-2.0': {'id': 'CC-BY-NC-SA-2.0', 'deprecated': False},
154
+ 'cc-by-nc-sa-2.0-de': {'id': 'CC-BY-NC-SA-2.0-DE', 'deprecated': False},
155
+ 'cc-by-nc-sa-2.0-fr': {'id': 'CC-BY-NC-SA-2.0-FR', 'deprecated': False},
156
+ 'cc-by-nc-sa-2.0-uk': {'id': 'CC-BY-NC-SA-2.0-UK', 'deprecated': False},
157
+ 'cc-by-nc-sa-2.5': {'id': 'CC-BY-NC-SA-2.5', 'deprecated': False},
158
+ 'cc-by-nc-sa-3.0': {'id': 'CC-BY-NC-SA-3.0', 'deprecated': False},
159
+ 'cc-by-nc-sa-3.0-de': {'id': 'CC-BY-NC-SA-3.0-DE', 'deprecated': False},
160
+ 'cc-by-nc-sa-3.0-igo': {'id': 'CC-BY-NC-SA-3.0-IGO', 'deprecated': False},
161
+ 'cc-by-nc-sa-4.0': {'id': 'CC-BY-NC-SA-4.0', 'deprecated': False},
162
+ 'cc-by-nd-1.0': {'id': 'CC-BY-ND-1.0', 'deprecated': False},
163
+ 'cc-by-nd-2.0': {'id': 'CC-BY-ND-2.0', 'deprecated': False},
164
+ 'cc-by-nd-2.5': {'id': 'CC-BY-ND-2.5', 'deprecated': False},
165
+ 'cc-by-nd-3.0': {'id': 'CC-BY-ND-3.0', 'deprecated': False},
166
+ 'cc-by-nd-3.0-de': {'id': 'CC-BY-ND-3.0-DE', 'deprecated': False},
167
+ 'cc-by-nd-4.0': {'id': 'CC-BY-ND-4.0', 'deprecated': False},
168
+ 'cc-by-sa-1.0': {'id': 'CC-BY-SA-1.0', 'deprecated': False},
169
+ 'cc-by-sa-2.0': {'id': 'CC-BY-SA-2.0', 'deprecated': False},
170
+ 'cc-by-sa-2.0-uk': {'id': 'CC-BY-SA-2.0-UK', 'deprecated': False},
171
+ 'cc-by-sa-2.1-jp': {'id': 'CC-BY-SA-2.1-JP', 'deprecated': False},
172
+ 'cc-by-sa-2.5': {'id': 'CC-BY-SA-2.5', 'deprecated': False},
173
+ 'cc-by-sa-3.0': {'id': 'CC-BY-SA-3.0', 'deprecated': False},
174
+ 'cc-by-sa-3.0-at': {'id': 'CC-BY-SA-3.0-AT', 'deprecated': False},
175
+ 'cc-by-sa-3.0-de': {'id': 'CC-BY-SA-3.0-DE', 'deprecated': False},
176
+ 'cc-by-sa-3.0-igo': {'id': 'CC-BY-SA-3.0-IGO', 'deprecated': False},
177
+ 'cc-by-sa-4.0': {'id': 'CC-BY-SA-4.0', 'deprecated': False},
178
+ 'cc-pddc': {'id': 'CC-PDDC', 'deprecated': False},
179
+ 'cc0-1.0': {'id': 'CC0-1.0', 'deprecated': False},
180
+ 'cddl-1.0': {'id': 'CDDL-1.0', 'deprecated': False},
181
+ 'cddl-1.1': {'id': 'CDDL-1.1', 'deprecated': False},
182
+ 'cdl-1.0': {'id': 'CDL-1.0', 'deprecated': False},
183
+ 'cdla-permissive-1.0': {'id': 'CDLA-Permissive-1.0', 'deprecated': False},
184
+ 'cdla-permissive-2.0': {'id': 'CDLA-Permissive-2.0', 'deprecated': False},
185
+ 'cdla-sharing-1.0': {'id': 'CDLA-Sharing-1.0', 'deprecated': False},
186
+ 'cecill-1.0': {'id': 'CECILL-1.0', 'deprecated': False},
187
+ 'cecill-1.1': {'id': 'CECILL-1.1', 'deprecated': False},
188
+ 'cecill-2.0': {'id': 'CECILL-2.0', 'deprecated': False},
189
+ 'cecill-2.1': {'id': 'CECILL-2.1', 'deprecated': False},
190
+ 'cecill-b': {'id': 'CECILL-B', 'deprecated': False},
191
+ 'cecill-c': {'id': 'CECILL-C', 'deprecated': False},
192
+ 'cern-ohl-1.1': {'id': 'CERN-OHL-1.1', 'deprecated': False},
193
+ 'cern-ohl-1.2': {'id': 'CERN-OHL-1.2', 'deprecated': False},
194
+ 'cern-ohl-p-2.0': {'id': 'CERN-OHL-P-2.0', 'deprecated': False},
195
+ 'cern-ohl-s-2.0': {'id': 'CERN-OHL-S-2.0', 'deprecated': False},
196
+ 'cern-ohl-w-2.0': {'id': 'CERN-OHL-W-2.0', 'deprecated': False},
197
+ 'cfitsio': {'id': 'CFITSIO', 'deprecated': False},
198
+ 'check-cvs': {'id': 'check-cvs', 'deprecated': False},
199
+ 'checkmk': {'id': 'checkmk', 'deprecated': False},
200
+ 'clartistic': {'id': 'ClArtistic', 'deprecated': False},
201
+ 'clips': {'id': 'Clips', 'deprecated': False},
202
+ 'cmu-mach': {'id': 'CMU-Mach', 'deprecated': False},
203
+ 'cmu-mach-nodoc': {'id': 'CMU-Mach-nodoc', 'deprecated': False},
204
+ 'cnri-jython': {'id': 'CNRI-Jython', 'deprecated': False},
205
+ 'cnri-python': {'id': 'CNRI-Python', 'deprecated': False},
206
+ 'cnri-python-gpl-compatible': {'id': 'CNRI-Python-GPL-Compatible', 'deprecated': False},
207
+ 'coil-1.0': {'id': 'COIL-1.0', 'deprecated': False},
208
+ 'community-spec-1.0': {'id': 'Community-Spec-1.0', 'deprecated': False},
209
+ 'condor-1.1': {'id': 'Condor-1.1', 'deprecated': False},
210
+ 'copyleft-next-0.3.0': {'id': 'copyleft-next-0.3.0', 'deprecated': False},
211
+ 'copyleft-next-0.3.1': {'id': 'copyleft-next-0.3.1', 'deprecated': False},
212
+ 'cornell-lossless-jpeg': {'id': 'Cornell-Lossless-JPEG', 'deprecated': False},
213
+ 'cpal-1.0': {'id': 'CPAL-1.0', 'deprecated': False},
214
+ 'cpl-1.0': {'id': 'CPL-1.0', 'deprecated': False},
215
+ 'cpol-1.02': {'id': 'CPOL-1.02', 'deprecated': False},
216
+ 'cronyx': {'id': 'Cronyx', 'deprecated': False},
217
+ 'crossword': {'id': 'Crossword', 'deprecated': False},
218
+ 'crystalstacker': {'id': 'CrystalStacker', 'deprecated': False},
219
+ 'cua-opl-1.0': {'id': 'CUA-OPL-1.0', 'deprecated': False},
220
+ 'cube': {'id': 'Cube', 'deprecated': False},
221
+ 'curl': {'id': 'curl', 'deprecated': False},
222
+ 'cve-tou': {'id': 'cve-tou', 'deprecated': False},
223
+ 'd-fsl-1.0': {'id': 'D-FSL-1.0', 'deprecated': False},
224
+ 'dec-3-clause': {'id': 'DEC-3-Clause', 'deprecated': False},
225
+ 'diffmark': {'id': 'diffmark', 'deprecated': False},
226
+ 'dl-de-by-2.0': {'id': 'DL-DE-BY-2.0', 'deprecated': False},
227
+ 'dl-de-zero-2.0': {'id': 'DL-DE-ZERO-2.0', 'deprecated': False},
228
+ 'doc': {'id': 'DOC', 'deprecated': False},
229
+ 'docbook-schema': {'id': 'DocBook-Schema', 'deprecated': False},
230
+ 'docbook-xml': {'id': 'DocBook-XML', 'deprecated': False},
231
+ 'dotseqn': {'id': 'Dotseqn', 'deprecated': False},
232
+ 'drl-1.0': {'id': 'DRL-1.0', 'deprecated': False},
233
+ 'drl-1.1': {'id': 'DRL-1.1', 'deprecated': False},
234
+ 'dsdp': {'id': 'DSDP', 'deprecated': False},
235
+ 'dtoa': {'id': 'dtoa', 'deprecated': False},
236
+ 'dvipdfm': {'id': 'dvipdfm', 'deprecated': False},
237
+ 'ecl-1.0': {'id': 'ECL-1.0', 'deprecated': False},
238
+ 'ecl-2.0': {'id': 'ECL-2.0', 'deprecated': False},
239
+ 'ecos-2.0': {'id': 'eCos-2.0', 'deprecated': True},
240
+ 'efl-1.0': {'id': 'EFL-1.0', 'deprecated': False},
241
+ 'efl-2.0': {'id': 'EFL-2.0', 'deprecated': False},
242
+ 'egenix': {'id': 'eGenix', 'deprecated': False},
243
+ 'elastic-2.0': {'id': 'Elastic-2.0', 'deprecated': False},
244
+ 'entessa': {'id': 'Entessa', 'deprecated': False},
245
+ 'epics': {'id': 'EPICS', 'deprecated': False},
246
+ 'epl-1.0': {'id': 'EPL-1.0', 'deprecated': False},
247
+ 'epl-2.0': {'id': 'EPL-2.0', 'deprecated': False},
248
+ 'erlpl-1.1': {'id': 'ErlPL-1.1', 'deprecated': False},
249
+ 'etalab-2.0': {'id': 'etalab-2.0', 'deprecated': False},
250
+ 'eudatagrid': {'id': 'EUDatagrid', 'deprecated': False},
251
+ 'eupl-1.0': {'id': 'EUPL-1.0', 'deprecated': False},
252
+ 'eupl-1.1': {'id': 'EUPL-1.1', 'deprecated': False},
253
+ 'eupl-1.2': {'id': 'EUPL-1.2', 'deprecated': False},
254
+ 'eurosym': {'id': 'Eurosym', 'deprecated': False},
255
+ 'fair': {'id': 'Fair', 'deprecated': False},
256
+ 'fbm': {'id': 'FBM', 'deprecated': False},
257
+ 'fdk-aac': {'id': 'FDK-AAC', 'deprecated': False},
258
+ 'ferguson-twofish': {'id': 'Ferguson-Twofish', 'deprecated': False},
259
+ 'frameworx-1.0': {'id': 'Frameworx-1.0', 'deprecated': False},
260
+ 'freebsd-doc': {'id': 'FreeBSD-DOC', 'deprecated': False},
261
+ 'freeimage': {'id': 'FreeImage', 'deprecated': False},
262
+ 'fsfap': {'id': 'FSFAP', 'deprecated': False},
263
+ 'fsfap-no-warranty-disclaimer': {'id': 'FSFAP-no-warranty-disclaimer', 'deprecated': False},
264
+ 'fsful': {'id': 'FSFUL', 'deprecated': False},
265
+ 'fsfullr': {'id': 'FSFULLR', 'deprecated': False},
266
+ 'fsfullrwd': {'id': 'FSFULLRWD', 'deprecated': False},
267
+ 'ftl': {'id': 'FTL', 'deprecated': False},
268
+ 'furuseth': {'id': 'Furuseth', 'deprecated': False},
269
+ 'fwlw': {'id': 'fwlw', 'deprecated': False},
270
+ 'gcr-docs': {'id': 'GCR-docs', 'deprecated': False},
271
+ 'gd': {'id': 'GD', 'deprecated': False},
272
+ 'gfdl-1.1': {'id': 'GFDL-1.1', 'deprecated': True},
273
+ 'gfdl-1.1-invariants-only': {'id': 'GFDL-1.1-invariants-only', 'deprecated': False},
274
+ 'gfdl-1.1-invariants-or-later': {'id': 'GFDL-1.1-invariants-or-later', 'deprecated': False},
275
+ 'gfdl-1.1-no-invariants-only': {'id': 'GFDL-1.1-no-invariants-only', 'deprecated': False},
276
+ 'gfdl-1.1-no-invariants-or-later': {'id': 'GFDL-1.1-no-invariants-or-later', 'deprecated': False},
277
+ 'gfdl-1.1-only': {'id': 'GFDL-1.1-only', 'deprecated': False},
278
+ 'gfdl-1.1-or-later': {'id': 'GFDL-1.1-or-later', 'deprecated': False},
279
+ 'gfdl-1.2': {'id': 'GFDL-1.2', 'deprecated': True},
280
+ 'gfdl-1.2-invariants-only': {'id': 'GFDL-1.2-invariants-only', 'deprecated': False},
281
+ 'gfdl-1.2-invariants-or-later': {'id': 'GFDL-1.2-invariants-or-later', 'deprecated': False},
282
+ 'gfdl-1.2-no-invariants-only': {'id': 'GFDL-1.2-no-invariants-only', 'deprecated': False},
283
+ 'gfdl-1.2-no-invariants-or-later': {'id': 'GFDL-1.2-no-invariants-or-later', 'deprecated': False},
284
+ 'gfdl-1.2-only': {'id': 'GFDL-1.2-only', 'deprecated': False},
285
+ 'gfdl-1.2-or-later': {'id': 'GFDL-1.2-or-later', 'deprecated': False},
286
+ 'gfdl-1.3': {'id': 'GFDL-1.3', 'deprecated': True},
287
+ 'gfdl-1.3-invariants-only': {'id': 'GFDL-1.3-invariants-only', 'deprecated': False},
288
+ 'gfdl-1.3-invariants-or-later': {'id': 'GFDL-1.3-invariants-or-later', 'deprecated': False},
289
+ 'gfdl-1.3-no-invariants-only': {'id': 'GFDL-1.3-no-invariants-only', 'deprecated': False},
290
+ 'gfdl-1.3-no-invariants-or-later': {'id': 'GFDL-1.3-no-invariants-or-later', 'deprecated': False},
291
+ 'gfdl-1.3-only': {'id': 'GFDL-1.3-only', 'deprecated': False},
292
+ 'gfdl-1.3-or-later': {'id': 'GFDL-1.3-or-later', 'deprecated': False},
293
+ 'giftware': {'id': 'Giftware', 'deprecated': False},
294
+ 'gl2ps': {'id': 'GL2PS', 'deprecated': False},
295
+ 'glide': {'id': 'Glide', 'deprecated': False},
296
+ 'glulxe': {'id': 'Glulxe', 'deprecated': False},
297
+ 'glwtpl': {'id': 'GLWTPL', 'deprecated': False},
298
+ 'gnuplot': {'id': 'gnuplot', 'deprecated': False},
299
+ 'gpl-1.0': {'id': 'GPL-1.0', 'deprecated': True},
300
+ 'gpl-1.0+': {'id': 'GPL-1.0+', 'deprecated': True},
301
+ 'gpl-1.0-only': {'id': 'GPL-1.0-only', 'deprecated': False},
302
+ 'gpl-1.0-or-later': {'id': 'GPL-1.0-or-later', 'deprecated': False},
303
+ 'gpl-2.0': {'id': 'GPL-2.0', 'deprecated': True},
304
+ 'gpl-2.0+': {'id': 'GPL-2.0+', 'deprecated': True},
305
+ 'gpl-2.0-only': {'id': 'GPL-2.0-only', 'deprecated': False},
306
+ 'gpl-2.0-or-later': {'id': 'GPL-2.0-or-later', 'deprecated': False},
307
+ 'gpl-2.0-with-autoconf-exception': {'id': 'GPL-2.0-with-autoconf-exception', 'deprecated': True},
308
+ 'gpl-2.0-with-bison-exception': {'id': 'GPL-2.0-with-bison-exception', 'deprecated': True},
309
+ 'gpl-2.0-with-classpath-exception': {'id': 'GPL-2.0-with-classpath-exception', 'deprecated': True},
310
+ 'gpl-2.0-with-font-exception': {'id': 'GPL-2.0-with-font-exception', 'deprecated': True},
311
+ 'gpl-2.0-with-gcc-exception': {'id': 'GPL-2.0-with-GCC-exception', 'deprecated': True},
312
+ 'gpl-3.0': {'id': 'GPL-3.0', 'deprecated': True},
313
+ 'gpl-3.0+': {'id': 'GPL-3.0+', 'deprecated': True},
314
+ 'gpl-3.0-only': {'id': 'GPL-3.0-only', 'deprecated': False},
315
+ 'gpl-3.0-or-later': {'id': 'GPL-3.0-or-later', 'deprecated': False},
316
+ 'gpl-3.0-with-autoconf-exception': {'id': 'GPL-3.0-with-autoconf-exception', 'deprecated': True},
317
+ 'gpl-3.0-with-gcc-exception': {'id': 'GPL-3.0-with-GCC-exception', 'deprecated': True},
318
+ 'graphics-gems': {'id': 'Graphics-Gems', 'deprecated': False},
319
+ 'gsoap-1.3b': {'id': 'gSOAP-1.3b', 'deprecated': False},
320
+ 'gtkbook': {'id': 'gtkbook', 'deprecated': False},
321
+ 'gutmann': {'id': 'Gutmann', 'deprecated': False},
322
+ 'haskellreport': {'id': 'HaskellReport', 'deprecated': False},
323
+ 'hdparm': {'id': 'hdparm', 'deprecated': False},
324
+ 'hidapi': {'id': 'HIDAPI', 'deprecated': False},
325
+ 'hippocratic-2.1': {'id': 'Hippocratic-2.1', 'deprecated': False},
326
+ 'hp-1986': {'id': 'HP-1986', 'deprecated': False},
327
+ 'hp-1989': {'id': 'HP-1989', 'deprecated': False},
328
+ 'hpnd': {'id': 'HPND', 'deprecated': False},
329
+ 'hpnd-dec': {'id': 'HPND-DEC', 'deprecated': False},
330
+ 'hpnd-doc': {'id': 'HPND-doc', 'deprecated': False},
331
+ 'hpnd-doc-sell': {'id': 'HPND-doc-sell', 'deprecated': False},
332
+ 'hpnd-export-us': {'id': 'HPND-export-US', 'deprecated': False},
333
+ 'hpnd-export-us-acknowledgement': {'id': 'HPND-export-US-acknowledgement', 'deprecated': False},
334
+ 'hpnd-export-us-modify': {'id': 'HPND-export-US-modify', 'deprecated': False},
335
+ 'hpnd-export2-us': {'id': 'HPND-export2-US', 'deprecated': False},
336
+ 'hpnd-fenneberg-livingston': {'id': 'HPND-Fenneberg-Livingston', 'deprecated': False},
337
+ 'hpnd-inria-imag': {'id': 'HPND-INRIA-IMAG', 'deprecated': False},
338
+ 'hpnd-intel': {'id': 'HPND-Intel', 'deprecated': False},
339
+ 'hpnd-kevlin-henney': {'id': 'HPND-Kevlin-Henney', 'deprecated': False},
340
+ 'hpnd-markus-kuhn': {'id': 'HPND-Markus-Kuhn', 'deprecated': False},
341
+ 'hpnd-merchantability-variant': {'id': 'HPND-merchantability-variant', 'deprecated': False},
342
+ 'hpnd-mit-disclaimer': {'id': 'HPND-MIT-disclaimer', 'deprecated': False},
343
+ 'hpnd-netrek': {'id': 'HPND-Netrek', 'deprecated': False},
344
+ 'hpnd-pbmplus': {'id': 'HPND-Pbmplus', 'deprecated': False},
345
+ 'hpnd-sell-mit-disclaimer-xserver': {'id': 'HPND-sell-MIT-disclaimer-xserver', 'deprecated': False},
346
+ 'hpnd-sell-regexpr': {'id': 'HPND-sell-regexpr', 'deprecated': False},
347
+ 'hpnd-sell-variant': {'id': 'HPND-sell-variant', 'deprecated': False},
348
+ 'hpnd-sell-variant-mit-disclaimer': {'id': 'HPND-sell-variant-MIT-disclaimer', 'deprecated': False},
349
+ 'hpnd-sell-variant-mit-disclaimer-rev': {'id': 'HPND-sell-variant-MIT-disclaimer-rev', 'deprecated': False},
350
+ 'hpnd-uc': {'id': 'HPND-UC', 'deprecated': False},
351
+ 'hpnd-uc-export-us': {'id': 'HPND-UC-export-US', 'deprecated': False},
352
+ 'htmltidy': {'id': 'HTMLTIDY', 'deprecated': False},
353
+ 'ibm-pibs': {'id': 'IBM-pibs', 'deprecated': False},
354
+ 'icu': {'id': 'ICU', 'deprecated': False},
355
+ 'iec-code-components-eula': {'id': 'IEC-Code-Components-EULA', 'deprecated': False},
356
+ 'ijg': {'id': 'IJG', 'deprecated': False},
357
+ 'ijg-short': {'id': 'IJG-short', 'deprecated': False},
358
+ 'imagemagick': {'id': 'ImageMagick', 'deprecated': False},
359
+ 'imatix': {'id': 'iMatix', 'deprecated': False},
360
+ 'imlib2': {'id': 'Imlib2', 'deprecated': False},
361
+ 'info-zip': {'id': 'Info-ZIP', 'deprecated': False},
362
+ 'inner-net-2.0': {'id': 'Inner-Net-2.0', 'deprecated': False},
363
+ 'intel': {'id': 'Intel', 'deprecated': False},
364
+ 'intel-acpi': {'id': 'Intel-ACPI', 'deprecated': False},
365
+ 'interbase-1.0': {'id': 'Interbase-1.0', 'deprecated': False},
366
+ 'ipa': {'id': 'IPA', 'deprecated': False},
367
+ 'ipl-1.0': {'id': 'IPL-1.0', 'deprecated': False},
368
+ 'isc': {'id': 'ISC', 'deprecated': False},
369
+ 'isc-veillard': {'id': 'ISC-Veillard', 'deprecated': False},
370
+ 'jam': {'id': 'Jam', 'deprecated': False},
371
+ 'jasper-2.0': {'id': 'JasPer-2.0', 'deprecated': False},
372
+ 'jpl-image': {'id': 'JPL-image', 'deprecated': False},
373
+ 'jpnic': {'id': 'JPNIC', 'deprecated': False},
374
+ 'json': {'id': 'JSON', 'deprecated': False},
375
+ 'kastrup': {'id': 'Kastrup', 'deprecated': False},
376
+ 'kazlib': {'id': 'Kazlib', 'deprecated': False},
377
+ 'knuth-ctan': {'id': 'Knuth-CTAN', 'deprecated': False},
378
+ 'lal-1.2': {'id': 'LAL-1.2', 'deprecated': False},
379
+ 'lal-1.3': {'id': 'LAL-1.3', 'deprecated': False},
380
+ 'latex2e': {'id': 'Latex2e', 'deprecated': False},
381
+ 'latex2e-translated-notice': {'id': 'Latex2e-translated-notice', 'deprecated': False},
382
+ 'leptonica': {'id': 'Leptonica', 'deprecated': False},
383
+ 'lgpl-2.0': {'id': 'LGPL-2.0', 'deprecated': True},
384
+ 'lgpl-2.0+': {'id': 'LGPL-2.0+', 'deprecated': True},
385
+ 'lgpl-2.0-only': {'id': 'LGPL-2.0-only', 'deprecated': False},
386
+ 'lgpl-2.0-or-later': {'id': 'LGPL-2.0-or-later', 'deprecated': False},
387
+ 'lgpl-2.1': {'id': 'LGPL-2.1', 'deprecated': True},
388
+ 'lgpl-2.1+': {'id': 'LGPL-2.1+', 'deprecated': True},
389
+ 'lgpl-2.1-only': {'id': 'LGPL-2.1-only', 'deprecated': False},
390
+ 'lgpl-2.1-or-later': {'id': 'LGPL-2.1-or-later', 'deprecated': False},
391
+ 'lgpl-3.0': {'id': 'LGPL-3.0', 'deprecated': True},
392
+ 'lgpl-3.0+': {'id': 'LGPL-3.0+', 'deprecated': True},
393
+ 'lgpl-3.0-only': {'id': 'LGPL-3.0-only', 'deprecated': False},
394
+ 'lgpl-3.0-or-later': {'id': 'LGPL-3.0-or-later', 'deprecated': False},
395
+ 'lgpllr': {'id': 'LGPLLR', 'deprecated': False},
396
+ 'libpng': {'id': 'Libpng', 'deprecated': False},
397
+ 'libpng-2.0': {'id': 'libpng-2.0', 'deprecated': False},
398
+ 'libselinux-1.0': {'id': 'libselinux-1.0', 'deprecated': False},
399
+ 'libtiff': {'id': 'libtiff', 'deprecated': False},
400
+ 'libutil-david-nugent': {'id': 'libutil-David-Nugent', 'deprecated': False},
401
+ 'liliq-p-1.1': {'id': 'LiLiQ-P-1.1', 'deprecated': False},
402
+ 'liliq-r-1.1': {'id': 'LiLiQ-R-1.1', 'deprecated': False},
403
+ 'liliq-rplus-1.1': {'id': 'LiLiQ-Rplus-1.1', 'deprecated': False},
404
+ 'linux-man-pages-1-para': {'id': 'Linux-man-pages-1-para', 'deprecated': False},
405
+ 'linux-man-pages-copyleft': {'id': 'Linux-man-pages-copyleft', 'deprecated': False},
406
+ 'linux-man-pages-copyleft-2-para': {'id': 'Linux-man-pages-copyleft-2-para', 'deprecated': False},
407
+ 'linux-man-pages-copyleft-var': {'id': 'Linux-man-pages-copyleft-var', 'deprecated': False},
408
+ 'linux-openib': {'id': 'Linux-OpenIB', 'deprecated': False},
409
+ 'loop': {'id': 'LOOP', 'deprecated': False},
410
+ 'lpd-document': {'id': 'LPD-document', 'deprecated': False},
411
+ 'lpl-1.0': {'id': 'LPL-1.0', 'deprecated': False},
412
+ 'lpl-1.02': {'id': 'LPL-1.02', 'deprecated': False},
413
+ 'lppl-1.0': {'id': 'LPPL-1.0', 'deprecated': False},
414
+ 'lppl-1.1': {'id': 'LPPL-1.1', 'deprecated': False},
415
+ 'lppl-1.2': {'id': 'LPPL-1.2', 'deprecated': False},
416
+ 'lppl-1.3a': {'id': 'LPPL-1.3a', 'deprecated': False},
417
+ 'lppl-1.3c': {'id': 'LPPL-1.3c', 'deprecated': False},
418
+ 'lsof': {'id': 'lsof', 'deprecated': False},
419
+ 'lucida-bitmap-fonts': {'id': 'Lucida-Bitmap-Fonts', 'deprecated': False},
420
+ 'lzma-sdk-9.11-to-9.20': {'id': 'LZMA-SDK-9.11-to-9.20', 'deprecated': False},
421
+ 'lzma-sdk-9.22': {'id': 'LZMA-SDK-9.22', 'deprecated': False},
422
+ 'mackerras-3-clause': {'id': 'Mackerras-3-Clause', 'deprecated': False},
423
+ 'mackerras-3-clause-acknowledgment': {'id': 'Mackerras-3-Clause-acknowledgment', 'deprecated': False},
424
+ 'magaz': {'id': 'magaz', 'deprecated': False},
425
+ 'mailprio': {'id': 'mailprio', 'deprecated': False},
426
+ 'makeindex': {'id': 'MakeIndex', 'deprecated': False},
427
+ 'martin-birgmeier': {'id': 'Martin-Birgmeier', 'deprecated': False},
428
+ 'mcphee-slideshow': {'id': 'McPhee-slideshow', 'deprecated': False},
429
+ 'metamail': {'id': 'metamail', 'deprecated': False},
430
+ 'minpack': {'id': 'Minpack', 'deprecated': False},
431
+ 'miros': {'id': 'MirOS', 'deprecated': False},
432
+ 'mit': {'id': 'MIT', 'deprecated': False},
433
+ 'mit-0': {'id': 'MIT-0', 'deprecated': False},
434
+ 'mit-advertising': {'id': 'MIT-advertising', 'deprecated': False},
435
+ 'mit-cmu': {'id': 'MIT-CMU', 'deprecated': False},
436
+ 'mit-enna': {'id': 'MIT-enna', 'deprecated': False},
437
+ 'mit-feh': {'id': 'MIT-feh', 'deprecated': False},
438
+ 'mit-festival': {'id': 'MIT-Festival', 'deprecated': False},
439
+ 'mit-khronos-old': {'id': 'MIT-Khronos-old', 'deprecated': False},
440
+ 'mit-modern-variant': {'id': 'MIT-Modern-Variant', 'deprecated': False},
441
+ 'mit-open-group': {'id': 'MIT-open-group', 'deprecated': False},
442
+ 'mit-testregex': {'id': 'MIT-testregex', 'deprecated': False},
443
+ 'mit-wu': {'id': 'MIT-Wu', 'deprecated': False},
444
+ 'mitnfa': {'id': 'MITNFA', 'deprecated': False},
445
+ 'mmixware': {'id': 'MMIXware', 'deprecated': False},
446
+ 'motosoto': {'id': 'Motosoto', 'deprecated': False},
447
+ 'mpeg-ssg': {'id': 'MPEG-SSG', 'deprecated': False},
448
+ 'mpi-permissive': {'id': 'mpi-permissive', 'deprecated': False},
449
+ 'mpich2': {'id': 'mpich2', 'deprecated': False},
450
+ 'mpl-1.0': {'id': 'MPL-1.0', 'deprecated': False},
451
+ 'mpl-1.1': {'id': 'MPL-1.1', 'deprecated': False},
452
+ 'mpl-2.0': {'id': 'MPL-2.0', 'deprecated': False},
453
+ 'mpl-2.0-no-copyleft-exception': {'id': 'MPL-2.0-no-copyleft-exception', 'deprecated': False},
454
+ 'mplus': {'id': 'mplus', 'deprecated': False},
455
+ 'ms-lpl': {'id': 'MS-LPL', 'deprecated': False},
456
+ 'ms-pl': {'id': 'MS-PL', 'deprecated': False},
457
+ 'ms-rl': {'id': 'MS-RL', 'deprecated': False},
458
+ 'mtll': {'id': 'MTLL', 'deprecated': False},
459
+ 'mulanpsl-1.0': {'id': 'MulanPSL-1.0', 'deprecated': False},
460
+ 'mulanpsl-2.0': {'id': 'MulanPSL-2.0', 'deprecated': False},
461
+ 'multics': {'id': 'Multics', 'deprecated': False},
462
+ 'mup': {'id': 'Mup', 'deprecated': False},
463
+ 'naist-2003': {'id': 'NAIST-2003', 'deprecated': False},
464
+ 'nasa-1.3': {'id': 'NASA-1.3', 'deprecated': False},
465
+ 'naumen': {'id': 'Naumen', 'deprecated': False},
466
+ 'nbpl-1.0': {'id': 'NBPL-1.0', 'deprecated': False},
467
+ 'ncbi-pd': {'id': 'NCBI-PD', 'deprecated': False},
468
+ 'ncgl-uk-2.0': {'id': 'NCGL-UK-2.0', 'deprecated': False},
469
+ 'ncl': {'id': 'NCL', 'deprecated': False},
470
+ 'ncsa': {'id': 'NCSA', 'deprecated': False},
471
+ 'net-snmp': {'id': 'Net-SNMP', 'deprecated': True},
472
+ 'netcdf': {'id': 'NetCDF', 'deprecated': False},
473
+ 'newsletr': {'id': 'Newsletr', 'deprecated': False},
474
+ 'ngpl': {'id': 'NGPL', 'deprecated': False},
475
+ 'nicta-1.0': {'id': 'NICTA-1.0', 'deprecated': False},
476
+ 'nist-pd': {'id': 'NIST-PD', 'deprecated': False},
477
+ 'nist-pd-fallback': {'id': 'NIST-PD-fallback', 'deprecated': False},
478
+ 'nist-software': {'id': 'NIST-Software', 'deprecated': False},
479
+ 'nlod-1.0': {'id': 'NLOD-1.0', 'deprecated': False},
480
+ 'nlod-2.0': {'id': 'NLOD-2.0', 'deprecated': False},
481
+ 'nlpl': {'id': 'NLPL', 'deprecated': False},
482
+ 'nokia': {'id': 'Nokia', 'deprecated': False},
483
+ 'nosl': {'id': 'NOSL', 'deprecated': False},
484
+ 'noweb': {'id': 'Noweb', 'deprecated': False},
485
+ 'npl-1.0': {'id': 'NPL-1.0', 'deprecated': False},
486
+ 'npl-1.1': {'id': 'NPL-1.1', 'deprecated': False},
487
+ 'nposl-3.0': {'id': 'NPOSL-3.0', 'deprecated': False},
488
+ 'nrl': {'id': 'NRL', 'deprecated': False},
489
+ 'ntp': {'id': 'NTP', 'deprecated': False},
490
+ 'ntp-0': {'id': 'NTP-0', 'deprecated': False},
491
+ 'nunit': {'id': 'Nunit', 'deprecated': True},
492
+ 'o-uda-1.0': {'id': 'O-UDA-1.0', 'deprecated': False},
493
+ 'oar': {'id': 'OAR', 'deprecated': False},
494
+ 'occt-pl': {'id': 'OCCT-PL', 'deprecated': False},
495
+ 'oclc-2.0': {'id': 'OCLC-2.0', 'deprecated': False},
496
+ 'odbl-1.0': {'id': 'ODbL-1.0', 'deprecated': False},
497
+ 'odc-by-1.0': {'id': 'ODC-By-1.0', 'deprecated': False},
498
+ 'offis': {'id': 'OFFIS', 'deprecated': False},
499
+ 'ofl-1.0': {'id': 'OFL-1.0', 'deprecated': False},
500
+ 'ofl-1.0-no-rfn': {'id': 'OFL-1.0-no-RFN', 'deprecated': False},
501
+ 'ofl-1.0-rfn': {'id': 'OFL-1.0-RFN', 'deprecated': False},
502
+ 'ofl-1.1': {'id': 'OFL-1.1', 'deprecated': False},
503
+ 'ofl-1.1-no-rfn': {'id': 'OFL-1.1-no-RFN', 'deprecated': False},
504
+ 'ofl-1.1-rfn': {'id': 'OFL-1.1-RFN', 'deprecated': False},
505
+ 'ogc-1.0': {'id': 'OGC-1.0', 'deprecated': False},
506
+ 'ogdl-taiwan-1.0': {'id': 'OGDL-Taiwan-1.0', 'deprecated': False},
507
+ 'ogl-canada-2.0': {'id': 'OGL-Canada-2.0', 'deprecated': False},
508
+ 'ogl-uk-1.0': {'id': 'OGL-UK-1.0', 'deprecated': False},
509
+ 'ogl-uk-2.0': {'id': 'OGL-UK-2.0', 'deprecated': False},
510
+ 'ogl-uk-3.0': {'id': 'OGL-UK-3.0', 'deprecated': False},
511
+ 'ogtsl': {'id': 'OGTSL', 'deprecated': False},
512
+ 'oldap-1.1': {'id': 'OLDAP-1.1', 'deprecated': False},
513
+ 'oldap-1.2': {'id': 'OLDAP-1.2', 'deprecated': False},
514
+ 'oldap-1.3': {'id': 'OLDAP-1.3', 'deprecated': False},
515
+ 'oldap-1.4': {'id': 'OLDAP-1.4', 'deprecated': False},
516
+ 'oldap-2.0': {'id': 'OLDAP-2.0', 'deprecated': False},
517
+ 'oldap-2.0.1': {'id': 'OLDAP-2.0.1', 'deprecated': False},
518
+ 'oldap-2.1': {'id': 'OLDAP-2.1', 'deprecated': False},
519
+ 'oldap-2.2': {'id': 'OLDAP-2.2', 'deprecated': False},
520
+ 'oldap-2.2.1': {'id': 'OLDAP-2.2.1', 'deprecated': False},
521
+ 'oldap-2.2.2': {'id': 'OLDAP-2.2.2', 'deprecated': False},
522
+ 'oldap-2.3': {'id': 'OLDAP-2.3', 'deprecated': False},
523
+ 'oldap-2.4': {'id': 'OLDAP-2.4', 'deprecated': False},
524
+ 'oldap-2.5': {'id': 'OLDAP-2.5', 'deprecated': False},
525
+ 'oldap-2.6': {'id': 'OLDAP-2.6', 'deprecated': False},
526
+ 'oldap-2.7': {'id': 'OLDAP-2.7', 'deprecated': False},
527
+ 'oldap-2.8': {'id': 'OLDAP-2.8', 'deprecated': False},
528
+ 'olfl-1.3': {'id': 'OLFL-1.3', 'deprecated': False},
529
+ 'oml': {'id': 'OML', 'deprecated': False},
530
+ 'openpbs-2.3': {'id': 'OpenPBS-2.3', 'deprecated': False},
531
+ 'openssl': {'id': 'OpenSSL', 'deprecated': False},
532
+ 'openssl-standalone': {'id': 'OpenSSL-standalone', 'deprecated': False},
533
+ 'openvision': {'id': 'OpenVision', 'deprecated': False},
534
+ 'opl-1.0': {'id': 'OPL-1.0', 'deprecated': False},
535
+ 'opl-uk-3.0': {'id': 'OPL-UK-3.0', 'deprecated': False},
536
+ 'opubl-1.0': {'id': 'OPUBL-1.0', 'deprecated': False},
537
+ 'oset-pl-2.1': {'id': 'OSET-PL-2.1', 'deprecated': False},
538
+ 'osl-1.0': {'id': 'OSL-1.0', 'deprecated': False},
539
+ 'osl-1.1': {'id': 'OSL-1.1', 'deprecated': False},
540
+ 'osl-2.0': {'id': 'OSL-2.0', 'deprecated': False},
541
+ 'osl-2.1': {'id': 'OSL-2.1', 'deprecated': False},
542
+ 'osl-3.0': {'id': 'OSL-3.0', 'deprecated': False},
543
+ 'padl': {'id': 'PADL', 'deprecated': False},
544
+ 'parity-6.0.0': {'id': 'Parity-6.0.0', 'deprecated': False},
545
+ 'parity-7.0.0': {'id': 'Parity-7.0.0', 'deprecated': False},
546
+ 'pddl-1.0': {'id': 'PDDL-1.0', 'deprecated': False},
547
+ 'php-3.0': {'id': 'PHP-3.0', 'deprecated': False},
548
+ 'php-3.01': {'id': 'PHP-3.01', 'deprecated': False},
549
+ 'pixar': {'id': 'Pixar', 'deprecated': False},
550
+ 'pkgconf': {'id': 'pkgconf', 'deprecated': False},
551
+ 'plexus': {'id': 'Plexus', 'deprecated': False},
552
+ 'pnmstitch': {'id': 'pnmstitch', 'deprecated': False},
553
+ 'polyform-noncommercial-1.0.0': {'id': 'PolyForm-Noncommercial-1.0.0', 'deprecated': False},
554
+ 'polyform-small-business-1.0.0': {'id': 'PolyForm-Small-Business-1.0.0', 'deprecated': False},
555
+ 'postgresql': {'id': 'PostgreSQL', 'deprecated': False},
556
+ 'ppl': {'id': 'PPL', 'deprecated': False},
557
+ 'psf-2.0': {'id': 'PSF-2.0', 'deprecated': False},
558
+ 'psfrag': {'id': 'psfrag', 'deprecated': False},
559
+ 'psutils': {'id': 'psutils', 'deprecated': False},
560
+ 'python-2.0': {'id': 'Python-2.0', 'deprecated': False},
561
+ 'python-2.0.1': {'id': 'Python-2.0.1', 'deprecated': False},
562
+ 'python-ldap': {'id': 'python-ldap', 'deprecated': False},
563
+ 'qhull': {'id': 'Qhull', 'deprecated': False},
564
+ 'qpl-1.0': {'id': 'QPL-1.0', 'deprecated': False},
565
+ 'qpl-1.0-inria-2004': {'id': 'QPL-1.0-INRIA-2004', 'deprecated': False},
566
+ 'radvd': {'id': 'radvd', 'deprecated': False},
567
+ 'rdisc': {'id': 'Rdisc', 'deprecated': False},
568
+ 'rhecos-1.1': {'id': 'RHeCos-1.1', 'deprecated': False},
569
+ 'rpl-1.1': {'id': 'RPL-1.1', 'deprecated': False},
570
+ 'rpl-1.5': {'id': 'RPL-1.5', 'deprecated': False},
571
+ 'rpsl-1.0': {'id': 'RPSL-1.0', 'deprecated': False},
572
+ 'rsa-md': {'id': 'RSA-MD', 'deprecated': False},
573
+ 'rscpl': {'id': 'RSCPL', 'deprecated': False},
574
+ 'ruby': {'id': 'Ruby', 'deprecated': False},
575
+ 'ruby-pty': {'id': 'Ruby-pty', 'deprecated': False},
576
+ 'sax-pd': {'id': 'SAX-PD', 'deprecated': False},
577
+ 'sax-pd-2.0': {'id': 'SAX-PD-2.0', 'deprecated': False},
578
+ 'saxpath': {'id': 'Saxpath', 'deprecated': False},
579
+ 'scea': {'id': 'SCEA', 'deprecated': False},
580
+ 'schemereport': {'id': 'SchemeReport', 'deprecated': False},
581
+ 'sendmail': {'id': 'Sendmail', 'deprecated': False},
582
+ 'sendmail-8.23': {'id': 'Sendmail-8.23', 'deprecated': False},
583
+ 'sgi-b-1.0': {'id': 'SGI-B-1.0', 'deprecated': False},
584
+ 'sgi-b-1.1': {'id': 'SGI-B-1.1', 'deprecated': False},
585
+ 'sgi-b-2.0': {'id': 'SGI-B-2.0', 'deprecated': False},
586
+ 'sgi-opengl': {'id': 'SGI-OpenGL', 'deprecated': False},
587
+ 'sgp4': {'id': 'SGP4', 'deprecated': False},
588
+ 'shl-0.5': {'id': 'SHL-0.5', 'deprecated': False},
589
+ 'shl-0.51': {'id': 'SHL-0.51', 'deprecated': False},
590
+ 'simpl-2.0': {'id': 'SimPL-2.0', 'deprecated': False},
591
+ 'sissl': {'id': 'SISSL', 'deprecated': False},
592
+ 'sissl-1.2': {'id': 'SISSL-1.2', 'deprecated': False},
593
+ 'sl': {'id': 'SL', 'deprecated': False},
594
+ 'sleepycat': {'id': 'Sleepycat', 'deprecated': False},
595
+ 'smlnj': {'id': 'SMLNJ', 'deprecated': False},
596
+ 'smppl': {'id': 'SMPPL', 'deprecated': False},
597
+ 'snia': {'id': 'SNIA', 'deprecated': False},
598
+ 'snprintf': {'id': 'snprintf', 'deprecated': False},
599
+ 'softsurfer': {'id': 'softSurfer', 'deprecated': False},
600
+ 'soundex': {'id': 'Soundex', 'deprecated': False},
601
+ 'spencer-86': {'id': 'Spencer-86', 'deprecated': False},
602
+ 'spencer-94': {'id': 'Spencer-94', 'deprecated': False},
603
+ 'spencer-99': {'id': 'Spencer-99', 'deprecated': False},
604
+ 'spl-1.0': {'id': 'SPL-1.0', 'deprecated': False},
605
+ 'ssh-keyscan': {'id': 'ssh-keyscan', 'deprecated': False},
606
+ 'ssh-openssh': {'id': 'SSH-OpenSSH', 'deprecated': False},
607
+ 'ssh-short': {'id': 'SSH-short', 'deprecated': False},
608
+ 'ssleay-standalone': {'id': 'SSLeay-standalone', 'deprecated': False},
609
+ 'sspl-1.0': {'id': 'SSPL-1.0', 'deprecated': False},
610
+ 'standardml-nj': {'id': 'StandardML-NJ', 'deprecated': True},
611
+ 'sugarcrm-1.1.3': {'id': 'SugarCRM-1.1.3', 'deprecated': False},
612
+ 'sun-ppp': {'id': 'Sun-PPP', 'deprecated': False},
613
+ 'sun-ppp-2000': {'id': 'Sun-PPP-2000', 'deprecated': False},
614
+ 'sunpro': {'id': 'SunPro', 'deprecated': False},
615
+ 'swl': {'id': 'SWL', 'deprecated': False},
616
+ 'swrule': {'id': 'swrule', 'deprecated': False},
617
+ 'symlinks': {'id': 'Symlinks', 'deprecated': False},
618
+ 'tapr-ohl-1.0': {'id': 'TAPR-OHL-1.0', 'deprecated': False},
619
+ 'tcl': {'id': 'TCL', 'deprecated': False},
620
+ 'tcp-wrappers': {'id': 'TCP-wrappers', 'deprecated': False},
621
+ 'termreadkey': {'id': 'TermReadKey', 'deprecated': False},
622
+ 'tgppl-1.0': {'id': 'TGPPL-1.0', 'deprecated': False},
623
+ 'threeparttable': {'id': 'threeparttable', 'deprecated': False},
624
+ 'tmate': {'id': 'TMate', 'deprecated': False},
625
+ 'torque-1.1': {'id': 'TORQUE-1.1', 'deprecated': False},
626
+ 'tosl': {'id': 'TOSL', 'deprecated': False},
627
+ 'tpdl': {'id': 'TPDL', 'deprecated': False},
628
+ 'tpl-1.0': {'id': 'TPL-1.0', 'deprecated': False},
629
+ 'ttwl': {'id': 'TTWL', 'deprecated': False},
630
+ 'ttyp0': {'id': 'TTYP0', 'deprecated': False},
631
+ 'tu-berlin-1.0': {'id': 'TU-Berlin-1.0', 'deprecated': False},
632
+ 'tu-berlin-2.0': {'id': 'TU-Berlin-2.0', 'deprecated': False},
633
+ 'ubuntu-font-1.0': {'id': 'Ubuntu-font-1.0', 'deprecated': False},
634
+ 'ucar': {'id': 'UCAR', 'deprecated': False},
635
+ 'ucl-1.0': {'id': 'UCL-1.0', 'deprecated': False},
636
+ 'ulem': {'id': 'ulem', 'deprecated': False},
637
+ 'umich-merit': {'id': 'UMich-Merit', 'deprecated': False},
638
+ 'unicode-3.0': {'id': 'Unicode-3.0', 'deprecated': False},
639
+ 'unicode-dfs-2015': {'id': 'Unicode-DFS-2015', 'deprecated': False},
640
+ 'unicode-dfs-2016': {'id': 'Unicode-DFS-2016', 'deprecated': False},
641
+ 'unicode-tou': {'id': 'Unicode-TOU', 'deprecated': False},
642
+ 'unixcrypt': {'id': 'UnixCrypt', 'deprecated': False},
643
+ 'unlicense': {'id': 'Unlicense', 'deprecated': False},
644
+ 'upl-1.0': {'id': 'UPL-1.0', 'deprecated': False},
645
+ 'urt-rle': {'id': 'URT-RLE', 'deprecated': False},
646
+ 'vim': {'id': 'Vim', 'deprecated': False},
647
+ 'vostrom': {'id': 'VOSTROM', 'deprecated': False},
648
+ 'vsl-1.0': {'id': 'VSL-1.0', 'deprecated': False},
649
+ 'w3c': {'id': 'W3C', 'deprecated': False},
650
+ 'w3c-19980720': {'id': 'W3C-19980720', 'deprecated': False},
651
+ 'w3c-20150513': {'id': 'W3C-20150513', 'deprecated': False},
652
+ 'w3m': {'id': 'w3m', 'deprecated': False},
653
+ 'watcom-1.0': {'id': 'Watcom-1.0', 'deprecated': False},
654
+ 'widget-workshop': {'id': 'Widget-Workshop', 'deprecated': False},
655
+ 'wsuipa': {'id': 'Wsuipa', 'deprecated': False},
656
+ 'wtfpl': {'id': 'WTFPL', 'deprecated': False},
657
+ 'wxwindows': {'id': 'wxWindows', 'deprecated': True},
658
+ 'x11': {'id': 'X11', 'deprecated': False},
659
+ 'x11-distribute-modifications-variant': {'id': 'X11-distribute-modifications-variant', 'deprecated': False},
660
+ 'x11-swapped': {'id': 'X11-swapped', 'deprecated': False},
661
+ 'xdebug-1.03': {'id': 'Xdebug-1.03', 'deprecated': False},
662
+ 'xerox': {'id': 'Xerox', 'deprecated': False},
663
+ 'xfig': {'id': 'Xfig', 'deprecated': False},
664
+ 'xfree86-1.1': {'id': 'XFree86-1.1', 'deprecated': False},
665
+ 'xinetd': {'id': 'xinetd', 'deprecated': False},
666
+ 'xkeyboard-config-zinoviev': {'id': 'xkeyboard-config-Zinoviev', 'deprecated': False},
667
+ 'xlock': {'id': 'xlock', 'deprecated': False},
668
+ 'xnet': {'id': 'Xnet', 'deprecated': False},
669
+ 'xpp': {'id': 'xpp', 'deprecated': False},
670
+ 'xskat': {'id': 'XSkat', 'deprecated': False},
671
+ 'xzoom': {'id': 'xzoom', 'deprecated': False},
672
+ 'ypl-1.0': {'id': 'YPL-1.0', 'deprecated': False},
673
+ 'ypl-1.1': {'id': 'YPL-1.1', 'deprecated': False},
674
+ 'zed': {'id': 'Zed', 'deprecated': False},
675
+ 'zeeff': {'id': 'Zeeff', 'deprecated': False},
676
+ 'zend-2.0': {'id': 'Zend-2.0', 'deprecated': False},
677
+ 'zimbra-1.3': {'id': 'Zimbra-1.3', 'deprecated': False},
678
+ 'zimbra-1.4': {'id': 'Zimbra-1.4', 'deprecated': False},
679
+ 'zlib': {'id': 'Zlib', 'deprecated': False},
680
+ 'zlib-acknowledgement': {'id': 'zlib-acknowledgement', 'deprecated': False},
681
+ 'zpl-1.1': {'id': 'ZPL-1.1', 'deprecated': False},
682
+ 'zpl-2.0': {'id': 'ZPL-2.0', 'deprecated': False},
683
+ 'zpl-2.1': {'id': 'ZPL-2.1', 'deprecated': False},
684
+ }
685
+
686
+ EXCEPTIONS: dict[str, SPDXException] = {
687
+ '389-exception': {'id': '389-exception', 'deprecated': False},
688
+ 'asterisk-exception': {'id': 'Asterisk-exception', 'deprecated': False},
689
+ 'asterisk-linking-protocols-exception': {'id': 'Asterisk-linking-protocols-exception', 'deprecated': False},
690
+ 'autoconf-exception-2.0': {'id': 'Autoconf-exception-2.0', 'deprecated': False},
691
+ 'autoconf-exception-3.0': {'id': 'Autoconf-exception-3.0', 'deprecated': False},
692
+ 'autoconf-exception-generic': {'id': 'Autoconf-exception-generic', 'deprecated': False},
693
+ 'autoconf-exception-generic-3.0': {'id': 'Autoconf-exception-generic-3.0', 'deprecated': False},
694
+ 'autoconf-exception-macro': {'id': 'Autoconf-exception-macro', 'deprecated': False},
695
+ 'bison-exception-1.24': {'id': 'Bison-exception-1.24', 'deprecated': False},
696
+ 'bison-exception-2.2': {'id': 'Bison-exception-2.2', 'deprecated': False},
697
+ 'bootloader-exception': {'id': 'Bootloader-exception', 'deprecated': False},
698
+ 'classpath-exception-2.0': {'id': 'Classpath-exception-2.0', 'deprecated': False},
699
+ 'clisp-exception-2.0': {'id': 'CLISP-exception-2.0', 'deprecated': False},
700
+ 'cryptsetup-openssl-exception': {'id': 'cryptsetup-OpenSSL-exception', 'deprecated': False},
701
+ 'digirule-foss-exception': {'id': 'DigiRule-FOSS-exception', 'deprecated': False},
702
+ 'ecos-exception-2.0': {'id': 'eCos-exception-2.0', 'deprecated': False},
703
+ 'erlang-otp-linking-exception': {'id': 'erlang-otp-linking-exception', 'deprecated': False},
704
+ 'fawkes-runtime-exception': {'id': 'Fawkes-Runtime-exception', 'deprecated': False},
705
+ 'fltk-exception': {'id': 'FLTK-exception', 'deprecated': False},
706
+ 'fmt-exception': {'id': 'fmt-exception', 'deprecated': False},
707
+ 'font-exception-2.0': {'id': 'Font-exception-2.0', 'deprecated': False},
708
+ 'freertos-exception-2.0': {'id': 'freertos-exception-2.0', 'deprecated': False},
709
+ 'gcc-exception-2.0': {'id': 'GCC-exception-2.0', 'deprecated': False},
710
+ 'gcc-exception-2.0-note': {'id': 'GCC-exception-2.0-note', 'deprecated': False},
711
+ 'gcc-exception-3.1': {'id': 'GCC-exception-3.1', 'deprecated': False},
712
+ 'gmsh-exception': {'id': 'Gmsh-exception', 'deprecated': False},
713
+ 'gnat-exception': {'id': 'GNAT-exception', 'deprecated': False},
714
+ 'gnome-examples-exception': {'id': 'GNOME-examples-exception', 'deprecated': False},
715
+ 'gnu-compiler-exception': {'id': 'GNU-compiler-exception', 'deprecated': False},
716
+ 'gnu-javamail-exception': {'id': 'gnu-javamail-exception', 'deprecated': False},
717
+ 'gpl-3.0-interface-exception': {'id': 'GPL-3.0-interface-exception', 'deprecated': False},
718
+ 'gpl-3.0-linking-exception': {'id': 'GPL-3.0-linking-exception', 'deprecated': False},
719
+ 'gpl-3.0-linking-source-exception': {'id': 'GPL-3.0-linking-source-exception', 'deprecated': False},
720
+ 'gpl-cc-1.0': {'id': 'GPL-CC-1.0', 'deprecated': False},
721
+ 'gstreamer-exception-2005': {'id': 'GStreamer-exception-2005', 'deprecated': False},
722
+ 'gstreamer-exception-2008': {'id': 'GStreamer-exception-2008', 'deprecated': False},
723
+ 'i2p-gpl-java-exception': {'id': 'i2p-gpl-java-exception', 'deprecated': False},
724
+ 'kicad-libraries-exception': {'id': 'KiCad-libraries-exception', 'deprecated': False},
725
+ 'lgpl-3.0-linking-exception': {'id': 'LGPL-3.0-linking-exception', 'deprecated': False},
726
+ 'libpri-openh323-exception': {'id': 'libpri-OpenH323-exception', 'deprecated': False},
727
+ 'libtool-exception': {'id': 'Libtool-exception', 'deprecated': False},
728
+ 'linux-syscall-note': {'id': 'Linux-syscall-note', 'deprecated': False},
729
+ 'llgpl': {'id': 'LLGPL', 'deprecated': False},
730
+ 'llvm-exception': {'id': 'LLVM-exception', 'deprecated': False},
731
+ 'lzma-exception': {'id': 'LZMA-exception', 'deprecated': False},
732
+ 'mif-exception': {'id': 'mif-exception', 'deprecated': False},
733
+ 'nokia-qt-exception-1.1': {'id': 'Nokia-Qt-exception-1.1', 'deprecated': True},
734
+ 'ocaml-lgpl-linking-exception': {'id': 'OCaml-LGPL-linking-exception', 'deprecated': False},
735
+ 'occt-exception-1.0': {'id': 'OCCT-exception-1.0', 'deprecated': False},
736
+ 'openjdk-assembly-exception-1.0': {'id': 'OpenJDK-assembly-exception-1.0', 'deprecated': False},
737
+ 'openvpn-openssl-exception': {'id': 'openvpn-openssl-exception', 'deprecated': False},
738
+ 'pcre2-exception': {'id': 'PCRE2-exception', 'deprecated': False},
739
+ 'ps-or-pdf-font-exception-20170817': {'id': 'PS-or-PDF-font-exception-20170817', 'deprecated': False},
740
+ 'qpl-1.0-inria-2004-exception': {'id': 'QPL-1.0-INRIA-2004-exception', 'deprecated': False},
741
+ 'qt-gpl-exception-1.0': {'id': 'Qt-GPL-exception-1.0', 'deprecated': False},
742
+ 'qt-lgpl-exception-1.1': {'id': 'Qt-LGPL-exception-1.1', 'deprecated': False},
743
+ 'qwt-exception-1.0': {'id': 'Qwt-exception-1.0', 'deprecated': False},
744
+ 'romic-exception': {'id': 'romic-exception', 'deprecated': False},
745
+ 'rrdtool-floss-exception-2.0': {'id': 'RRDtool-FLOSS-exception-2.0', 'deprecated': False},
746
+ 'sane-exception': {'id': 'SANE-exception', 'deprecated': False},
747
+ 'shl-2.0': {'id': 'SHL-2.0', 'deprecated': False},
748
+ 'shl-2.1': {'id': 'SHL-2.1', 'deprecated': False},
749
+ 'stunnel-exception': {'id': 'stunnel-exception', 'deprecated': False},
750
+ 'swi-exception': {'id': 'SWI-exception', 'deprecated': False},
751
+ 'swift-exception': {'id': 'Swift-exception', 'deprecated': False},
752
+ 'texinfo-exception': {'id': 'Texinfo-exception', 'deprecated': False},
753
+ 'u-boot-exception-2.0': {'id': 'u-boot-exception-2.0', 'deprecated': False},
754
+ 'ubdl-exception': {'id': 'UBDL-exception', 'deprecated': False},
755
+ 'universal-foss-exception-1.0': {'id': 'Universal-FOSS-exception-1.0', 'deprecated': False},
756
+ 'vsftpd-openssl-exception': {'id': 'vsftpd-openssl-exception', 'deprecated': False},
757
+ 'wxwindows-exception-3.1': {'id': 'WxWindows-exception-3.1', 'deprecated': False},
758
+ 'x11vnc-openssl-exception': {'id': 'x11vnc-openssl-exception', 'deprecated': False},
759
+ }
lib/python3.12/site-packages/packaging/markers.py ADDED
@@ -0,0 +1,362 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This file is dual licensed under the terms of the Apache License, Version
2
+ # 2.0, and the BSD License. See the LICENSE file in the root of this repository
3
+ # for complete details.
4
+
5
+ from __future__ import annotations
6
+
7
+ import operator
8
+ import os
9
+ import platform
10
+ import sys
11
+ from typing import AbstractSet, Any, Callable, Literal, TypedDict, Union, cast
12
+
13
+ from ._parser import MarkerAtom, MarkerList, Op, Value, Variable
14
+ from ._parser import parse_marker as _parse_marker
15
+ from ._tokenizer import ParserSyntaxError
16
+ from .specifiers import InvalidSpecifier, Specifier
17
+ from .utils import canonicalize_name
18
+
19
+ __all__ = [
20
+ "EvaluateContext",
21
+ "InvalidMarker",
22
+ "Marker",
23
+ "UndefinedComparison",
24
+ "UndefinedEnvironmentName",
25
+ "default_environment",
26
+ ]
27
+
28
+ Operator = Callable[[str, Union[str, AbstractSet[str]]], bool]
29
+ EvaluateContext = Literal["metadata", "lock_file", "requirement"]
30
+ MARKERS_ALLOWING_SET = {"extras", "dependency_groups"}
31
+
32
+
33
+ class InvalidMarker(ValueError):
34
+ """
35
+ An invalid marker was found, users should refer to PEP 508.
36
+ """
37
+
38
+
39
+ class UndefinedComparison(ValueError):
40
+ """
41
+ An invalid operation was attempted on a value that doesn't support it.
42
+ """
43
+
44
+
45
+ class UndefinedEnvironmentName(ValueError):
46
+ """
47
+ A name was attempted to be used that does not exist inside of the
48
+ environment.
49
+ """
50
+
51
+
52
+ class Environment(TypedDict):
53
+ implementation_name: str
54
+ """The implementation's identifier, e.g. ``'cpython'``."""
55
+
56
+ implementation_version: str
57
+ """
58
+ The implementation's version, e.g. ``'3.13.0a2'`` for CPython 3.13.0a2, or
59
+ ``'7.3.13'`` for PyPy3.10 v7.3.13.
60
+ """
61
+
62
+ os_name: str
63
+ """
64
+ The value of :py:data:`os.name`. The name of the operating system dependent module
65
+ imported, e.g. ``'posix'``.
66
+ """
67
+
68
+ platform_machine: str
69
+ """
70
+ Returns the machine type, e.g. ``'i386'``.
71
+
72
+ An empty string if the value cannot be determined.
73
+ """
74
+
75
+ platform_release: str
76
+ """
77
+ The system's release, e.g. ``'2.2.0'`` or ``'NT'``.
78
+
79
+ An empty string if the value cannot be determined.
80
+ """
81
+
82
+ platform_system: str
83
+ """
84
+ The system/OS name, e.g. ``'Linux'``, ``'Windows'`` or ``'Java'``.
85
+
86
+ An empty string if the value cannot be determined.
87
+ """
88
+
89
+ platform_version: str
90
+ """
91
+ The system's release version, e.g. ``'#3 on degas'``.
92
+
93
+ An empty string if the value cannot be determined.
94
+ """
95
+
96
+ python_full_version: str
97
+ """
98
+ The Python version as string ``'major.minor.patchlevel'``.
99
+
100
+ Note that unlike the Python :py:data:`sys.version`, this value will always include
101
+ the patchlevel (it defaults to 0).
102
+ """
103
+
104
+ platform_python_implementation: str
105
+ """
106
+ A string identifying the Python implementation, e.g. ``'CPython'``.
107
+ """
108
+
109
+ python_version: str
110
+ """The Python version as string ``'major.minor'``."""
111
+
112
+ sys_platform: str
113
+ """
114
+ This string contains a platform identifier that can be used to append
115
+ platform-specific components to :py:data:`sys.path`, for instance.
116
+
117
+ For Unix systems, except on Linux and AIX, this is the lowercased OS name as
118
+ returned by ``uname -s`` with the first part of the version as returned by
119
+ ``uname -r`` appended, e.g. ``'sunos5'`` or ``'freebsd8'``, at the time when Python
120
+ was built.
121
+ """
122
+
123
+
124
+ def _normalize_extra_values(results: Any) -> Any:
125
+ """
126
+ Normalize extra values.
127
+ """
128
+ if isinstance(results[0], tuple):
129
+ lhs, op, rhs = results[0]
130
+ if isinstance(lhs, Variable) and lhs.value == "extra":
131
+ normalized_extra = canonicalize_name(rhs.value)
132
+ rhs = Value(normalized_extra)
133
+ elif isinstance(rhs, Variable) and rhs.value == "extra":
134
+ normalized_extra = canonicalize_name(lhs.value)
135
+ lhs = Value(normalized_extra)
136
+ results[0] = lhs, op, rhs
137
+ return results
138
+
139
+
140
+ def _format_marker(
141
+ marker: list[str] | MarkerAtom | str, first: bool | None = True
142
+ ) -> str:
143
+ assert isinstance(marker, (list, tuple, str))
144
+
145
+ # Sometimes we have a structure like [[...]] which is a single item list
146
+ # where the single item is itself it's own list. In that case we want skip
147
+ # the rest of this function so that we don't get extraneous () on the
148
+ # outside.
149
+ if (
150
+ isinstance(marker, list)
151
+ and len(marker) == 1
152
+ and isinstance(marker[0], (list, tuple))
153
+ ):
154
+ return _format_marker(marker[0])
155
+
156
+ if isinstance(marker, list):
157
+ inner = (_format_marker(m, first=False) for m in marker)
158
+ if first:
159
+ return " ".join(inner)
160
+ else:
161
+ return "(" + " ".join(inner) + ")"
162
+ elif isinstance(marker, tuple):
163
+ return " ".join([m.serialize() for m in marker])
164
+ else:
165
+ return marker
166
+
167
+
168
+ _operators: dict[str, Operator] = {
169
+ "in": lambda lhs, rhs: lhs in rhs,
170
+ "not in": lambda lhs, rhs: lhs not in rhs,
171
+ "<": operator.lt,
172
+ "<=": operator.le,
173
+ "==": operator.eq,
174
+ "!=": operator.ne,
175
+ ">=": operator.ge,
176
+ ">": operator.gt,
177
+ }
178
+
179
+
180
+ def _eval_op(lhs: str, op: Op, rhs: str | AbstractSet[str]) -> bool:
181
+ if isinstance(rhs, str):
182
+ try:
183
+ spec = Specifier("".join([op.serialize(), rhs]))
184
+ except InvalidSpecifier:
185
+ pass
186
+ else:
187
+ return spec.contains(lhs, prereleases=True)
188
+
189
+ oper: Operator | None = _operators.get(op.serialize())
190
+ if oper is None:
191
+ raise UndefinedComparison(f"Undefined {op!r} on {lhs!r} and {rhs!r}.")
192
+
193
+ return oper(lhs, rhs)
194
+
195
+
196
+ def _normalize(
197
+ lhs: str, rhs: str | AbstractSet[str], key: str
198
+ ) -> tuple[str, str | AbstractSet[str]]:
199
+ # PEP 685 – Comparison of extra names for optional distribution dependencies
200
+ # https://peps.python.org/pep-0685/
201
+ # > When comparing extra names, tools MUST normalize the names being
202
+ # > compared using the semantics outlined in PEP 503 for names
203
+ if key == "extra":
204
+ assert isinstance(rhs, str), "extra value must be a string"
205
+ return (canonicalize_name(lhs), canonicalize_name(rhs))
206
+ if key in MARKERS_ALLOWING_SET:
207
+ if isinstance(rhs, str): # pragma: no cover
208
+ return (canonicalize_name(lhs), canonicalize_name(rhs))
209
+ else:
210
+ return (canonicalize_name(lhs), {canonicalize_name(v) for v in rhs})
211
+
212
+ # other environment markers don't have such standards
213
+ return lhs, rhs
214
+
215
+
216
+ def _evaluate_markers(
217
+ markers: MarkerList, environment: dict[str, str | AbstractSet[str]]
218
+ ) -> bool:
219
+ groups: list[list[bool]] = [[]]
220
+
221
+ for marker in markers:
222
+ assert isinstance(marker, (list, tuple, str))
223
+
224
+ if isinstance(marker, list):
225
+ groups[-1].append(_evaluate_markers(marker, environment))
226
+ elif isinstance(marker, tuple):
227
+ lhs, op, rhs = marker
228
+
229
+ if isinstance(lhs, Variable):
230
+ environment_key = lhs.value
231
+ lhs_value = environment[environment_key]
232
+ rhs_value = rhs.value
233
+ else:
234
+ lhs_value = lhs.value
235
+ environment_key = rhs.value
236
+ rhs_value = environment[environment_key]
237
+ assert isinstance(lhs_value, str), "lhs must be a string"
238
+ lhs_value, rhs_value = _normalize(lhs_value, rhs_value, key=environment_key)
239
+ groups[-1].append(_eval_op(lhs_value, op, rhs_value))
240
+ else:
241
+ assert marker in ["and", "or"]
242
+ if marker == "or":
243
+ groups.append([])
244
+
245
+ return any(all(item) for item in groups)
246
+
247
+
248
+ def format_full_version(info: sys._version_info) -> str:
249
+ version = f"{info.major}.{info.minor}.{info.micro}"
250
+ kind = info.releaselevel
251
+ if kind != "final":
252
+ version += kind[0] + str(info.serial)
253
+ return version
254
+
255
+
256
+ def default_environment() -> Environment:
257
+ iver = format_full_version(sys.implementation.version)
258
+ implementation_name = sys.implementation.name
259
+ return {
260
+ "implementation_name": implementation_name,
261
+ "implementation_version": iver,
262
+ "os_name": os.name,
263
+ "platform_machine": platform.machine(),
264
+ "platform_release": platform.release(),
265
+ "platform_system": platform.system(),
266
+ "platform_version": platform.version(),
267
+ "python_full_version": platform.python_version(),
268
+ "platform_python_implementation": platform.python_implementation(),
269
+ "python_version": ".".join(platform.python_version_tuple()[:2]),
270
+ "sys_platform": sys.platform,
271
+ }
272
+
273
+
274
+ class Marker:
275
+ def __init__(self, marker: str) -> None:
276
+ # Note: We create a Marker object without calling this constructor in
277
+ # packaging.requirements.Requirement. If any additional logic is
278
+ # added here, make sure to mirror/adapt Requirement.
279
+ try:
280
+ self._markers = _normalize_extra_values(_parse_marker(marker))
281
+ # The attribute `_markers` can be described in terms of a recursive type:
282
+ # MarkerList = List[Union[Tuple[Node, ...], str, MarkerList]]
283
+ #
284
+ # For example, the following expression:
285
+ # python_version > "3.6" or (python_version == "3.6" and os_name == "unix")
286
+ #
287
+ # is parsed into:
288
+ # [
289
+ # (<Variable('python_version')>, <Op('>')>, <Value('3.6')>),
290
+ # 'and',
291
+ # [
292
+ # (<Variable('python_version')>, <Op('==')>, <Value('3.6')>),
293
+ # 'or',
294
+ # (<Variable('os_name')>, <Op('==')>, <Value('unix')>)
295
+ # ]
296
+ # ]
297
+ except ParserSyntaxError as e:
298
+ raise InvalidMarker(str(e)) from e
299
+
300
+ def __str__(self) -> str:
301
+ return _format_marker(self._markers)
302
+
303
+ def __repr__(self) -> str:
304
+ return f"<Marker('{self}')>"
305
+
306
+ def __hash__(self) -> int:
307
+ return hash((self.__class__.__name__, str(self)))
308
+
309
+ def __eq__(self, other: Any) -> bool:
310
+ if not isinstance(other, Marker):
311
+ return NotImplemented
312
+
313
+ return str(self) == str(other)
314
+
315
+ def evaluate(
316
+ self,
317
+ environment: dict[str, str] | None = None,
318
+ context: EvaluateContext = "metadata",
319
+ ) -> bool:
320
+ """Evaluate a marker.
321
+
322
+ Return the boolean from evaluating the given marker against the
323
+ environment. environment is an optional argument to override all or
324
+ part of the determined environment. The *context* parameter specifies what
325
+ context the markers are being evaluated for, which influences what markers
326
+ are considered valid. Acceptable values are "metadata" (for core metadata;
327
+ default), "lock_file", and "requirement" (i.e. all other situations).
328
+
329
+ The environment is determined from the current Python process.
330
+ """
331
+ current_environment = cast(
332
+ "dict[str, str | AbstractSet[str]]", default_environment()
333
+ )
334
+ if context == "lock_file":
335
+ current_environment.update(
336
+ extras=frozenset(), dependency_groups=frozenset()
337
+ )
338
+ elif context == "metadata":
339
+ current_environment["extra"] = ""
340
+ if environment is not None:
341
+ current_environment.update(environment)
342
+ # The API used to allow setting extra to None. We need to handle this
343
+ # case for backwards compatibility.
344
+ if "extra" in current_environment and current_environment["extra"] is None:
345
+ current_environment["extra"] = ""
346
+
347
+ return _evaluate_markers(
348
+ self._markers, _repair_python_full_version(current_environment)
349
+ )
350
+
351
+
352
+ def _repair_python_full_version(
353
+ env: dict[str, str | AbstractSet[str]],
354
+ ) -> dict[str, str | AbstractSet[str]]:
355
+ """
356
+ Work around platform.python_version() returning something that is not PEP 440
357
+ compliant for non-tagged Python builds.
358
+ """
359
+ python_full_version = cast(str, env["python_full_version"])
360
+ if python_full_version.endswith("+"):
361
+ env["python_full_version"] = f"{python_full_version}local"
362
+ return env
lib/python3.12/site-packages/packaging/metadata.py ADDED
@@ -0,0 +1,862 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import email.feedparser
4
+ import email.header
5
+ import email.message
6
+ import email.parser
7
+ import email.policy
8
+ import pathlib
9
+ import sys
10
+ import typing
11
+ from typing import (
12
+ Any,
13
+ Callable,
14
+ Generic,
15
+ Literal,
16
+ TypedDict,
17
+ cast,
18
+ )
19
+
20
+ from . import licenses, requirements, specifiers, utils
21
+ from . import version as version_module
22
+ from .licenses import NormalizedLicenseExpression
23
+
24
+ T = typing.TypeVar("T")
25
+
26
+
27
+ if sys.version_info >= (3, 11): # pragma: no cover
28
+ ExceptionGroup = ExceptionGroup
29
+ else: # pragma: no cover
30
+
31
+ class ExceptionGroup(Exception):
32
+ """A minimal implementation of :external:exc:`ExceptionGroup` from Python 3.11.
33
+
34
+ If :external:exc:`ExceptionGroup` is already defined by Python itself,
35
+ that version is used instead.
36
+ """
37
+
38
+ message: str
39
+ exceptions: list[Exception]
40
+
41
+ def __init__(self, message: str, exceptions: list[Exception]) -> None:
42
+ self.message = message
43
+ self.exceptions = exceptions
44
+
45
+ def __repr__(self) -> str:
46
+ return f"{self.__class__.__name__}({self.message!r}, {self.exceptions!r})"
47
+
48
+
49
+ class InvalidMetadata(ValueError):
50
+ """A metadata field contains invalid data."""
51
+
52
+ field: str
53
+ """The name of the field that contains invalid data."""
54
+
55
+ def __init__(self, field: str, message: str) -> None:
56
+ self.field = field
57
+ super().__init__(message)
58
+
59
+
60
+ # The RawMetadata class attempts to make as few assumptions about the underlying
61
+ # serialization formats as possible. The idea is that as long as a serialization
62
+ # formats offer some very basic primitives in *some* way then we can support
63
+ # serializing to and from that format.
64
+ class RawMetadata(TypedDict, total=False):
65
+ """A dictionary of raw core metadata.
66
+
67
+ Each field in core metadata maps to a key of this dictionary (when data is
68
+ provided). The key is lower-case and underscores are used instead of dashes
69
+ compared to the equivalent core metadata field. Any core metadata field that
70
+ can be specified multiple times or can hold multiple values in a single
71
+ field have a key with a plural name. See :class:`Metadata` whose attributes
72
+ match the keys of this dictionary.
73
+
74
+ Core metadata fields that can be specified multiple times are stored as a
75
+ list or dict depending on which is appropriate for the field. Any fields
76
+ which hold multiple values in a single field are stored as a list.
77
+
78
+ """
79
+
80
+ # Metadata 1.0 - PEP 241
81
+ metadata_version: str
82
+ name: str
83
+ version: str
84
+ platforms: list[str]
85
+ summary: str
86
+ description: str
87
+ keywords: list[str]
88
+ home_page: str
89
+ author: str
90
+ author_email: str
91
+ license: str
92
+
93
+ # Metadata 1.1 - PEP 314
94
+ supported_platforms: list[str]
95
+ download_url: str
96
+ classifiers: list[str]
97
+ requires: list[str]
98
+ provides: list[str]
99
+ obsoletes: list[str]
100
+
101
+ # Metadata 1.2 - PEP 345
102
+ maintainer: str
103
+ maintainer_email: str
104
+ requires_dist: list[str]
105
+ provides_dist: list[str]
106
+ obsoletes_dist: list[str]
107
+ requires_python: str
108
+ requires_external: list[str]
109
+ project_urls: dict[str, str]
110
+
111
+ # Metadata 2.0
112
+ # PEP 426 attempted to completely revamp the metadata format
113
+ # but got stuck without ever being able to build consensus on
114
+ # it and ultimately ended up withdrawn.
115
+ #
116
+ # However, a number of tools had started emitting METADATA with
117
+ # `2.0` Metadata-Version, so for historical reasons, this version
118
+ # was skipped.
119
+
120
+ # Metadata 2.1 - PEP 566
121
+ description_content_type: str
122
+ provides_extra: list[str]
123
+
124
+ # Metadata 2.2 - PEP 643
125
+ dynamic: list[str]
126
+
127
+ # Metadata 2.3 - PEP 685
128
+ # No new fields were added in PEP 685, just some edge case were
129
+ # tightened up to provide better interoptability.
130
+
131
+ # Metadata 2.4 - PEP 639
132
+ license_expression: str
133
+ license_files: list[str]
134
+
135
+
136
+ _STRING_FIELDS = {
137
+ "author",
138
+ "author_email",
139
+ "description",
140
+ "description_content_type",
141
+ "download_url",
142
+ "home_page",
143
+ "license",
144
+ "license_expression",
145
+ "maintainer",
146
+ "maintainer_email",
147
+ "metadata_version",
148
+ "name",
149
+ "requires_python",
150
+ "summary",
151
+ "version",
152
+ }
153
+
154
+ _LIST_FIELDS = {
155
+ "classifiers",
156
+ "dynamic",
157
+ "license_files",
158
+ "obsoletes",
159
+ "obsoletes_dist",
160
+ "platforms",
161
+ "provides",
162
+ "provides_dist",
163
+ "provides_extra",
164
+ "requires",
165
+ "requires_dist",
166
+ "requires_external",
167
+ "supported_platforms",
168
+ }
169
+
170
+ _DICT_FIELDS = {
171
+ "project_urls",
172
+ }
173
+
174
+
175
+ def _parse_keywords(data: str) -> list[str]:
176
+ """Split a string of comma-separated keywords into a list of keywords."""
177
+ return [k.strip() for k in data.split(",")]
178
+
179
+
180
+ def _parse_project_urls(data: list[str]) -> dict[str, str]:
181
+ """Parse a list of label/URL string pairings separated by a comma."""
182
+ urls = {}
183
+ for pair in data:
184
+ # Our logic is slightly tricky here as we want to try and do
185
+ # *something* reasonable with malformed data.
186
+ #
187
+ # The main thing that we have to worry about, is data that does
188
+ # not have a ',' at all to split the label from the Value. There
189
+ # isn't a singular right answer here, and we will fail validation
190
+ # later on (if the caller is validating) so it doesn't *really*
191
+ # matter, but since the missing value has to be an empty str
192
+ # and our return value is dict[str, str], if we let the key
193
+ # be the missing value, then they'd have multiple '' values that
194
+ # overwrite each other in a accumulating dict.
195
+ #
196
+ # The other potentional issue is that it's possible to have the
197
+ # same label multiple times in the metadata, with no solid "right"
198
+ # answer with what to do in that case. As such, we'll do the only
199
+ # thing we can, which is treat the field as unparseable and add it
200
+ # to our list of unparsed fields.
201
+ parts = [p.strip() for p in pair.split(",", 1)]
202
+ parts.extend([""] * (max(0, 2 - len(parts)))) # Ensure 2 items
203
+
204
+ # TODO: The spec doesn't say anything about if the keys should be
205
+ # considered case sensitive or not... logically they should
206
+ # be case-preserving and case-insensitive, but doing that
207
+ # would open up more cases where we might have duplicate
208
+ # entries.
209
+ label, url = parts
210
+ if label in urls:
211
+ # The label already exists in our set of urls, so this field
212
+ # is unparseable, and we can just add the whole thing to our
213
+ # unparseable data and stop processing it.
214
+ raise KeyError("duplicate labels in project urls")
215
+ urls[label] = url
216
+
217
+ return urls
218
+
219
+
220
+ def _get_payload(msg: email.message.Message, source: bytes | str) -> str:
221
+ """Get the body of the message."""
222
+ # If our source is a str, then our caller has managed encodings for us,
223
+ # and we don't need to deal with it.
224
+ if isinstance(source, str):
225
+ payload = msg.get_payload()
226
+ assert isinstance(payload, str)
227
+ return payload
228
+ # If our source is a bytes, then we're managing the encoding and we need
229
+ # to deal with it.
230
+ else:
231
+ bpayload = msg.get_payload(decode=True)
232
+ assert isinstance(bpayload, bytes)
233
+ try:
234
+ return bpayload.decode("utf8", "strict")
235
+ except UnicodeDecodeError as exc:
236
+ raise ValueError("payload in an invalid encoding") from exc
237
+
238
+
239
+ # The various parse_FORMAT functions here are intended to be as lenient as
240
+ # possible in their parsing, while still returning a correctly typed
241
+ # RawMetadata.
242
+ #
243
+ # To aid in this, we also generally want to do as little touching of the
244
+ # data as possible, except where there are possibly some historic holdovers
245
+ # that make valid data awkward to work with.
246
+ #
247
+ # While this is a lower level, intermediate format than our ``Metadata``
248
+ # class, some light touch ups can make a massive difference in usability.
249
+
250
+ # Map METADATA fields to RawMetadata.
251
+ _EMAIL_TO_RAW_MAPPING = {
252
+ "author": "author",
253
+ "author-email": "author_email",
254
+ "classifier": "classifiers",
255
+ "description": "description",
256
+ "description-content-type": "description_content_type",
257
+ "download-url": "download_url",
258
+ "dynamic": "dynamic",
259
+ "home-page": "home_page",
260
+ "keywords": "keywords",
261
+ "license": "license",
262
+ "license-expression": "license_expression",
263
+ "license-file": "license_files",
264
+ "maintainer": "maintainer",
265
+ "maintainer-email": "maintainer_email",
266
+ "metadata-version": "metadata_version",
267
+ "name": "name",
268
+ "obsoletes": "obsoletes",
269
+ "obsoletes-dist": "obsoletes_dist",
270
+ "platform": "platforms",
271
+ "project-url": "project_urls",
272
+ "provides": "provides",
273
+ "provides-dist": "provides_dist",
274
+ "provides-extra": "provides_extra",
275
+ "requires": "requires",
276
+ "requires-dist": "requires_dist",
277
+ "requires-external": "requires_external",
278
+ "requires-python": "requires_python",
279
+ "summary": "summary",
280
+ "supported-platform": "supported_platforms",
281
+ "version": "version",
282
+ }
283
+ _RAW_TO_EMAIL_MAPPING = {raw: email for email, raw in _EMAIL_TO_RAW_MAPPING.items()}
284
+
285
+
286
+ def parse_email(data: bytes | str) -> tuple[RawMetadata, dict[str, list[str]]]:
287
+ """Parse a distribution's metadata stored as email headers (e.g. from ``METADATA``).
288
+
289
+ This function returns a two-item tuple of dicts. The first dict is of
290
+ recognized fields from the core metadata specification. Fields that can be
291
+ parsed and translated into Python's built-in types are converted
292
+ appropriately. All other fields are left as-is. Fields that are allowed to
293
+ appear multiple times are stored as lists.
294
+
295
+ The second dict contains all other fields from the metadata. This includes
296
+ any unrecognized fields. It also includes any fields which are expected to
297
+ be parsed into a built-in type but were not formatted appropriately. Finally,
298
+ any fields that are expected to appear only once but are repeated are
299
+ included in this dict.
300
+
301
+ """
302
+ raw: dict[str, str | list[str] | dict[str, str]] = {}
303
+ unparsed: dict[str, list[str]] = {}
304
+
305
+ if isinstance(data, str):
306
+ parsed = email.parser.Parser(policy=email.policy.compat32).parsestr(data)
307
+ else:
308
+ parsed = email.parser.BytesParser(policy=email.policy.compat32).parsebytes(data)
309
+
310
+ # We have to wrap parsed.keys() in a set, because in the case of multiple
311
+ # values for a key (a list), the key will appear multiple times in the
312
+ # list of keys, but we're avoiding that by using get_all().
313
+ for name in frozenset(parsed.keys()):
314
+ # Header names in RFC are case insensitive, so we'll normalize to all
315
+ # lower case to make comparisons easier.
316
+ name = name.lower()
317
+
318
+ # We use get_all() here, even for fields that aren't multiple use,
319
+ # because otherwise someone could have e.g. two Name fields, and we
320
+ # would just silently ignore it rather than doing something about it.
321
+ headers = parsed.get_all(name) or []
322
+
323
+ # The way the email module works when parsing bytes is that it
324
+ # unconditionally decodes the bytes as ascii using the surrogateescape
325
+ # handler. When you pull that data back out (such as with get_all() ),
326
+ # it looks to see if the str has any surrogate escapes, and if it does
327
+ # it wraps it in a Header object instead of returning the string.
328
+ #
329
+ # As such, we'll look for those Header objects, and fix up the encoding.
330
+ value = []
331
+ # Flag if we have run into any issues processing the headers, thus
332
+ # signalling that the data belongs in 'unparsed'.
333
+ valid_encoding = True
334
+ for h in headers:
335
+ # It's unclear if this can return more types than just a Header or
336
+ # a str, so we'll just assert here to make sure.
337
+ assert isinstance(h, (email.header.Header, str))
338
+
339
+ # If it's a header object, we need to do our little dance to get
340
+ # the real data out of it. In cases where there is invalid data
341
+ # we're going to end up with mojibake, but there's no obvious, good
342
+ # way around that without reimplementing parts of the Header object
343
+ # ourselves.
344
+ #
345
+ # That should be fine since, if mojibacked happens, this key is
346
+ # going into the unparsed dict anyways.
347
+ if isinstance(h, email.header.Header):
348
+ # The Header object stores it's data as chunks, and each chunk
349
+ # can be independently encoded, so we'll need to check each
350
+ # of them.
351
+ chunks: list[tuple[bytes, str | None]] = []
352
+ for bin, encoding in email.header.decode_header(h):
353
+ try:
354
+ bin.decode("utf8", "strict")
355
+ except UnicodeDecodeError:
356
+ # Enable mojibake.
357
+ encoding = "latin1"
358
+ valid_encoding = False
359
+ else:
360
+ encoding = "utf8"
361
+ chunks.append((bin, encoding))
362
+
363
+ # Turn our chunks back into a Header object, then let that
364
+ # Header object do the right thing to turn them into a
365
+ # string for us.
366
+ value.append(str(email.header.make_header(chunks)))
367
+ # This is already a string, so just add it.
368
+ else:
369
+ value.append(h)
370
+
371
+ # We've processed all of our values to get them into a list of str,
372
+ # but we may have mojibake data, in which case this is an unparsed
373
+ # field.
374
+ if not valid_encoding:
375
+ unparsed[name] = value
376
+ continue
377
+
378
+ raw_name = _EMAIL_TO_RAW_MAPPING.get(name)
379
+ if raw_name is None:
380
+ # This is a bit of a weird situation, we've encountered a key that
381
+ # we don't know what it means, so we don't know whether it's meant
382
+ # to be a list or not.
383
+ #
384
+ # Since we can't really tell one way or another, we'll just leave it
385
+ # as a list, even though it may be a single item list, because that's
386
+ # what makes the most sense for email headers.
387
+ unparsed[name] = value
388
+ continue
389
+
390
+ # If this is one of our string fields, then we'll check to see if our
391
+ # value is a list of a single item. If it is then we'll assume that
392
+ # it was emitted as a single string, and unwrap the str from inside
393
+ # the list.
394
+ #
395
+ # If it's any other kind of data, then we haven't the faintest clue
396
+ # what we should parse it as, and we have to just add it to our list
397
+ # of unparsed stuff.
398
+ if raw_name in _STRING_FIELDS and len(value) == 1:
399
+ raw[raw_name] = value[0]
400
+ # If this is one of our list of string fields, then we can just assign
401
+ # the value, since email *only* has strings, and our get_all() call
402
+ # above ensures that this is a list.
403
+ elif raw_name in _LIST_FIELDS:
404
+ raw[raw_name] = value
405
+ # Special Case: Keywords
406
+ # The keywords field is implemented in the metadata spec as a str,
407
+ # but it conceptually is a list of strings, and is serialized using
408
+ # ", ".join(keywords), so we'll do some light data massaging to turn
409
+ # this into what it logically is.
410
+ elif raw_name == "keywords" and len(value) == 1:
411
+ raw[raw_name] = _parse_keywords(value[0])
412
+ # Special Case: Project-URL
413
+ # The project urls is implemented in the metadata spec as a list of
414
+ # specially-formatted strings that represent a key and a value, which
415
+ # is fundamentally a mapping, however the email format doesn't support
416
+ # mappings in a sane way, so it was crammed into a list of strings
417
+ # instead.
418
+ #
419
+ # We will do a little light data massaging to turn this into a map as
420
+ # it logically should be.
421
+ elif raw_name == "project_urls":
422
+ try:
423
+ raw[raw_name] = _parse_project_urls(value)
424
+ except KeyError:
425
+ unparsed[name] = value
426
+ # Nothing that we've done has managed to parse this, so it'll just
427
+ # throw it in our unparseable data and move on.
428
+ else:
429
+ unparsed[name] = value
430
+
431
+ # We need to support getting the Description from the message payload in
432
+ # addition to getting it from the the headers. This does mean, though, there
433
+ # is the possibility of it being set both ways, in which case we put both
434
+ # in 'unparsed' since we don't know which is right.
435
+ try:
436
+ payload = _get_payload(parsed, data)
437
+ except ValueError:
438
+ unparsed.setdefault("description", []).append(
439
+ parsed.get_payload(decode=isinstance(data, bytes)) # type: ignore[call-overload]
440
+ )
441
+ else:
442
+ if payload:
443
+ # Check to see if we've already got a description, if so then both
444
+ # it, and this body move to unparseable.
445
+ if "description" in raw:
446
+ description_header = cast(str, raw.pop("description"))
447
+ unparsed.setdefault("description", []).extend(
448
+ [description_header, payload]
449
+ )
450
+ elif "description" in unparsed:
451
+ unparsed["description"].append(payload)
452
+ else:
453
+ raw["description"] = payload
454
+
455
+ # We need to cast our `raw` to a metadata, because a TypedDict only support
456
+ # literal key names, but we're computing our key names on purpose, but the
457
+ # way this function is implemented, our `TypedDict` can only have valid key
458
+ # names.
459
+ return cast(RawMetadata, raw), unparsed
460
+
461
+
462
+ _NOT_FOUND = object()
463
+
464
+
465
+ # Keep the two values in sync.
466
+ _VALID_METADATA_VERSIONS = ["1.0", "1.1", "1.2", "2.1", "2.2", "2.3", "2.4"]
467
+ _MetadataVersion = Literal["1.0", "1.1", "1.2", "2.1", "2.2", "2.3", "2.4"]
468
+
469
+ _REQUIRED_ATTRS = frozenset(["metadata_version", "name", "version"])
470
+
471
+
472
+ class _Validator(Generic[T]):
473
+ """Validate a metadata field.
474
+
475
+ All _process_*() methods correspond to a core metadata field. The method is
476
+ called with the field's raw value. If the raw value is valid it is returned
477
+ in its "enriched" form (e.g. ``version.Version`` for the ``Version`` field).
478
+ If the raw value is invalid, :exc:`InvalidMetadata` is raised (with a cause
479
+ as appropriate).
480
+ """
481
+
482
+ name: str
483
+ raw_name: str
484
+ added: _MetadataVersion
485
+
486
+ def __init__(
487
+ self,
488
+ *,
489
+ added: _MetadataVersion = "1.0",
490
+ ) -> None:
491
+ self.added = added
492
+
493
+ def __set_name__(self, _owner: Metadata, name: str) -> None:
494
+ self.name = name
495
+ self.raw_name = _RAW_TO_EMAIL_MAPPING[name]
496
+
497
+ def __get__(self, instance: Metadata, _owner: type[Metadata]) -> T:
498
+ # With Python 3.8, the caching can be replaced with functools.cached_property().
499
+ # No need to check the cache as attribute lookup will resolve into the
500
+ # instance's __dict__ before __get__ is called.
501
+ cache = instance.__dict__
502
+ value = instance._raw.get(self.name)
503
+
504
+ # To make the _process_* methods easier, we'll check if the value is None
505
+ # and if this field is NOT a required attribute, and if both of those
506
+ # things are true, we'll skip the the converter. This will mean that the
507
+ # converters never have to deal with the None union.
508
+ if self.name in _REQUIRED_ATTRS or value is not None:
509
+ try:
510
+ converter: Callable[[Any], T] = getattr(self, f"_process_{self.name}")
511
+ except AttributeError:
512
+ pass
513
+ else:
514
+ value = converter(value)
515
+
516
+ cache[self.name] = value
517
+ try:
518
+ del instance._raw[self.name] # type: ignore[misc]
519
+ except KeyError:
520
+ pass
521
+
522
+ return cast(T, value)
523
+
524
+ def _invalid_metadata(
525
+ self, msg: str, cause: Exception | None = None
526
+ ) -> InvalidMetadata:
527
+ exc = InvalidMetadata(
528
+ self.raw_name, msg.format_map({"field": repr(self.raw_name)})
529
+ )
530
+ exc.__cause__ = cause
531
+ return exc
532
+
533
+ def _process_metadata_version(self, value: str) -> _MetadataVersion:
534
+ # Implicitly makes Metadata-Version required.
535
+ if value not in _VALID_METADATA_VERSIONS:
536
+ raise self._invalid_metadata(f"{value!r} is not a valid metadata version")
537
+ return cast(_MetadataVersion, value)
538
+
539
+ def _process_name(self, value: str) -> str:
540
+ if not value:
541
+ raise self._invalid_metadata("{field} is a required field")
542
+ # Validate the name as a side-effect.
543
+ try:
544
+ utils.canonicalize_name(value, validate=True)
545
+ except utils.InvalidName as exc:
546
+ raise self._invalid_metadata(
547
+ f"{value!r} is invalid for {{field}}", cause=exc
548
+ ) from exc
549
+ else:
550
+ return value
551
+
552
+ def _process_version(self, value: str) -> version_module.Version:
553
+ if not value:
554
+ raise self._invalid_metadata("{field} is a required field")
555
+ try:
556
+ return version_module.parse(value)
557
+ except version_module.InvalidVersion as exc:
558
+ raise self._invalid_metadata(
559
+ f"{value!r} is invalid for {{field}}", cause=exc
560
+ ) from exc
561
+
562
+ def _process_summary(self, value: str) -> str:
563
+ """Check the field contains no newlines."""
564
+ if "\n" in value:
565
+ raise self._invalid_metadata("{field} must be a single line")
566
+ return value
567
+
568
+ def _process_description_content_type(self, value: str) -> str:
569
+ content_types = {"text/plain", "text/x-rst", "text/markdown"}
570
+ message = email.message.EmailMessage()
571
+ message["content-type"] = value
572
+
573
+ content_type, parameters = (
574
+ # Defaults to `text/plain` if parsing failed.
575
+ message.get_content_type().lower(),
576
+ message["content-type"].params,
577
+ )
578
+ # Check if content-type is valid or defaulted to `text/plain` and thus was
579
+ # not parseable.
580
+ if content_type not in content_types or content_type not in value.lower():
581
+ raise self._invalid_metadata(
582
+ f"{{field}} must be one of {list(content_types)}, not {value!r}"
583
+ )
584
+
585
+ charset = parameters.get("charset", "UTF-8")
586
+ if charset != "UTF-8":
587
+ raise self._invalid_metadata(
588
+ f"{{field}} can only specify the UTF-8 charset, not {list(charset)}"
589
+ )
590
+
591
+ markdown_variants = {"GFM", "CommonMark"}
592
+ variant = parameters.get("variant", "GFM") # Use an acceptable default.
593
+ if content_type == "text/markdown" and variant not in markdown_variants:
594
+ raise self._invalid_metadata(
595
+ f"valid Markdown variants for {{field}} are {list(markdown_variants)}, "
596
+ f"not {variant!r}",
597
+ )
598
+ return value
599
+
600
+ def _process_dynamic(self, value: list[str]) -> list[str]:
601
+ for dynamic_field in map(str.lower, value):
602
+ if dynamic_field in {"name", "version", "metadata-version"}:
603
+ raise self._invalid_metadata(
604
+ f"{dynamic_field!r} is not allowed as a dynamic field"
605
+ )
606
+ elif dynamic_field not in _EMAIL_TO_RAW_MAPPING:
607
+ raise self._invalid_metadata(
608
+ f"{dynamic_field!r} is not a valid dynamic field"
609
+ )
610
+ return list(map(str.lower, value))
611
+
612
+ def _process_provides_extra(
613
+ self,
614
+ value: list[str],
615
+ ) -> list[utils.NormalizedName]:
616
+ normalized_names = []
617
+ try:
618
+ for name in value:
619
+ normalized_names.append(utils.canonicalize_name(name, validate=True))
620
+ except utils.InvalidName as exc:
621
+ raise self._invalid_metadata(
622
+ f"{name!r} is invalid for {{field}}", cause=exc
623
+ ) from exc
624
+ else:
625
+ return normalized_names
626
+
627
+ def _process_requires_python(self, value: str) -> specifiers.SpecifierSet:
628
+ try:
629
+ return specifiers.SpecifierSet(value)
630
+ except specifiers.InvalidSpecifier as exc:
631
+ raise self._invalid_metadata(
632
+ f"{value!r} is invalid for {{field}}", cause=exc
633
+ ) from exc
634
+
635
+ def _process_requires_dist(
636
+ self,
637
+ value: list[str],
638
+ ) -> list[requirements.Requirement]:
639
+ reqs = []
640
+ try:
641
+ for req in value:
642
+ reqs.append(requirements.Requirement(req))
643
+ except requirements.InvalidRequirement as exc:
644
+ raise self._invalid_metadata(
645
+ f"{req!r} is invalid for {{field}}", cause=exc
646
+ ) from exc
647
+ else:
648
+ return reqs
649
+
650
+ def _process_license_expression(
651
+ self, value: str
652
+ ) -> NormalizedLicenseExpression | None:
653
+ try:
654
+ return licenses.canonicalize_license_expression(value)
655
+ except ValueError as exc:
656
+ raise self._invalid_metadata(
657
+ f"{value!r} is invalid for {{field}}", cause=exc
658
+ ) from exc
659
+
660
+ def _process_license_files(self, value: list[str]) -> list[str]:
661
+ paths = []
662
+ for path in value:
663
+ if ".." in path:
664
+ raise self._invalid_metadata(
665
+ f"{path!r} is invalid for {{field}}, "
666
+ "parent directory indicators are not allowed"
667
+ )
668
+ if "*" in path:
669
+ raise self._invalid_metadata(
670
+ f"{path!r} is invalid for {{field}}, paths must be resolved"
671
+ )
672
+ if (
673
+ pathlib.PurePosixPath(path).is_absolute()
674
+ or pathlib.PureWindowsPath(path).is_absolute()
675
+ ):
676
+ raise self._invalid_metadata(
677
+ f"{path!r} is invalid for {{field}}, paths must be relative"
678
+ )
679
+ if pathlib.PureWindowsPath(path).as_posix() != path:
680
+ raise self._invalid_metadata(
681
+ f"{path!r} is invalid for {{field}}, paths must use '/' delimiter"
682
+ )
683
+ paths.append(path)
684
+ return paths
685
+
686
+
687
+ class Metadata:
688
+ """Representation of distribution metadata.
689
+
690
+ Compared to :class:`RawMetadata`, this class provides objects representing
691
+ metadata fields instead of only using built-in types. Any invalid metadata
692
+ will cause :exc:`InvalidMetadata` to be raised (with a
693
+ :py:attr:`~BaseException.__cause__` attribute as appropriate).
694
+ """
695
+
696
+ _raw: RawMetadata
697
+
698
+ @classmethod
699
+ def from_raw(cls, data: RawMetadata, *, validate: bool = True) -> Metadata:
700
+ """Create an instance from :class:`RawMetadata`.
701
+
702
+ If *validate* is true, all metadata will be validated. All exceptions
703
+ related to validation will be gathered and raised as an :class:`ExceptionGroup`.
704
+ """
705
+ ins = cls()
706
+ ins._raw = data.copy() # Mutations occur due to caching enriched values.
707
+
708
+ if validate:
709
+ exceptions: list[Exception] = []
710
+ try:
711
+ metadata_version = ins.metadata_version
712
+ metadata_age = _VALID_METADATA_VERSIONS.index(metadata_version)
713
+ except InvalidMetadata as metadata_version_exc:
714
+ exceptions.append(metadata_version_exc)
715
+ metadata_version = None
716
+
717
+ # Make sure to check for the fields that are present, the required
718
+ # fields (so their absence can be reported).
719
+ fields_to_check = frozenset(ins._raw) | _REQUIRED_ATTRS
720
+ # Remove fields that have already been checked.
721
+ fields_to_check -= {"metadata_version"}
722
+
723
+ for key in fields_to_check:
724
+ try:
725
+ if metadata_version:
726
+ # Can't use getattr() as that triggers descriptor protocol which
727
+ # will fail due to no value for the instance argument.
728
+ try:
729
+ field_metadata_version = cls.__dict__[key].added
730
+ except KeyError:
731
+ exc = InvalidMetadata(key, f"unrecognized field: {key!r}")
732
+ exceptions.append(exc)
733
+ continue
734
+ field_age = _VALID_METADATA_VERSIONS.index(
735
+ field_metadata_version
736
+ )
737
+ if field_age > metadata_age:
738
+ field = _RAW_TO_EMAIL_MAPPING[key]
739
+ exc = InvalidMetadata(
740
+ field,
741
+ f"{field} introduced in metadata version "
742
+ f"{field_metadata_version}, not {metadata_version}",
743
+ )
744
+ exceptions.append(exc)
745
+ continue
746
+ getattr(ins, key)
747
+ except InvalidMetadata as exc:
748
+ exceptions.append(exc)
749
+
750
+ if exceptions:
751
+ raise ExceptionGroup("invalid metadata", exceptions)
752
+
753
+ return ins
754
+
755
+ @classmethod
756
+ def from_email(cls, data: bytes | str, *, validate: bool = True) -> Metadata:
757
+ """Parse metadata from email headers.
758
+
759
+ If *validate* is true, the metadata will be validated. All exceptions
760
+ related to validation will be gathered and raised as an :class:`ExceptionGroup`.
761
+ """
762
+ raw, unparsed = parse_email(data)
763
+
764
+ if validate:
765
+ exceptions: list[Exception] = []
766
+ for unparsed_key in unparsed:
767
+ if unparsed_key in _EMAIL_TO_RAW_MAPPING:
768
+ message = f"{unparsed_key!r} has invalid data"
769
+ else:
770
+ message = f"unrecognized field: {unparsed_key!r}"
771
+ exceptions.append(InvalidMetadata(unparsed_key, message))
772
+
773
+ if exceptions:
774
+ raise ExceptionGroup("unparsed", exceptions)
775
+
776
+ try:
777
+ return cls.from_raw(raw, validate=validate)
778
+ except ExceptionGroup as exc_group:
779
+ raise ExceptionGroup(
780
+ "invalid or unparsed metadata", exc_group.exceptions
781
+ ) from None
782
+
783
+ metadata_version: _Validator[_MetadataVersion] = _Validator()
784
+ """:external:ref:`core-metadata-metadata-version`
785
+ (required; validated to be a valid metadata version)"""
786
+ # `name` is not normalized/typed to NormalizedName so as to provide access to
787
+ # the original/raw name.
788
+ name: _Validator[str] = _Validator()
789
+ """:external:ref:`core-metadata-name`
790
+ (required; validated using :func:`~packaging.utils.canonicalize_name` and its
791
+ *validate* parameter)"""
792
+ version: _Validator[version_module.Version] = _Validator()
793
+ """:external:ref:`core-metadata-version` (required)"""
794
+ dynamic: _Validator[list[str] | None] = _Validator(
795
+ added="2.2",
796
+ )
797
+ """:external:ref:`core-metadata-dynamic`
798
+ (validated against core metadata field names and lowercased)"""
799
+ platforms: _Validator[list[str] | None] = _Validator()
800
+ """:external:ref:`core-metadata-platform`"""
801
+ supported_platforms: _Validator[list[str] | None] = _Validator(added="1.1")
802
+ """:external:ref:`core-metadata-supported-platform`"""
803
+ summary: _Validator[str | None] = _Validator()
804
+ """:external:ref:`core-metadata-summary` (validated to contain no newlines)"""
805
+ description: _Validator[str | None] = _Validator() # TODO 2.1: can be in body
806
+ """:external:ref:`core-metadata-description`"""
807
+ description_content_type: _Validator[str | None] = _Validator(added="2.1")
808
+ """:external:ref:`core-metadata-description-content-type` (validated)"""
809
+ keywords: _Validator[list[str] | None] = _Validator()
810
+ """:external:ref:`core-metadata-keywords`"""
811
+ home_page: _Validator[str | None] = _Validator()
812
+ """:external:ref:`core-metadata-home-page`"""
813
+ download_url: _Validator[str | None] = _Validator(added="1.1")
814
+ """:external:ref:`core-metadata-download-url`"""
815
+ author: _Validator[str | None] = _Validator()
816
+ """:external:ref:`core-metadata-author`"""
817
+ author_email: _Validator[str | None] = _Validator()
818
+ """:external:ref:`core-metadata-author-email`"""
819
+ maintainer: _Validator[str | None] = _Validator(added="1.2")
820
+ """:external:ref:`core-metadata-maintainer`"""
821
+ maintainer_email: _Validator[str | None] = _Validator(added="1.2")
822
+ """:external:ref:`core-metadata-maintainer-email`"""
823
+ license: _Validator[str | None] = _Validator()
824
+ """:external:ref:`core-metadata-license`"""
825
+ license_expression: _Validator[NormalizedLicenseExpression | None] = _Validator(
826
+ added="2.4"
827
+ )
828
+ """:external:ref:`core-metadata-license-expression`"""
829
+ license_files: _Validator[list[str] | None] = _Validator(added="2.4")
830
+ """:external:ref:`core-metadata-license-file`"""
831
+ classifiers: _Validator[list[str] | None] = _Validator(added="1.1")
832
+ """:external:ref:`core-metadata-classifier`"""
833
+ requires_dist: _Validator[list[requirements.Requirement] | None] = _Validator(
834
+ added="1.2"
835
+ )
836
+ """:external:ref:`core-metadata-requires-dist`"""
837
+ requires_python: _Validator[specifiers.SpecifierSet | None] = _Validator(
838
+ added="1.2"
839
+ )
840
+ """:external:ref:`core-metadata-requires-python`"""
841
+ # Because `Requires-External` allows for non-PEP 440 version specifiers, we
842
+ # don't do any processing on the values.
843
+ requires_external: _Validator[list[str] | None] = _Validator(added="1.2")
844
+ """:external:ref:`core-metadata-requires-external`"""
845
+ project_urls: _Validator[dict[str, str] | None] = _Validator(added="1.2")
846
+ """:external:ref:`core-metadata-project-url`"""
847
+ # PEP 685 lets us raise an error if an extra doesn't pass `Name` validation
848
+ # regardless of metadata version.
849
+ provides_extra: _Validator[list[utils.NormalizedName] | None] = _Validator(
850
+ added="2.1",
851
+ )
852
+ """:external:ref:`core-metadata-provides-extra`"""
853
+ provides_dist: _Validator[list[str] | None] = _Validator(added="1.2")
854
+ """:external:ref:`core-metadata-provides-dist`"""
855
+ obsoletes_dist: _Validator[list[str] | None] = _Validator(added="1.2")
856
+ """:external:ref:`core-metadata-obsoletes-dist`"""
857
+ requires: _Validator[list[str] | None] = _Validator(added="1.1")
858
+ """``Requires`` (deprecated)"""
859
+ provides: _Validator[list[str] | None] = _Validator(added="1.1")
860
+ """``Provides`` (deprecated)"""
861
+ obsoletes: _Validator[list[str] | None] = _Validator(added="1.1")
862
+ """``Obsoletes`` (deprecated)"""
lib/python3.12/site-packages/packaging/py.typed ADDED
File without changes
lib/python3.12/site-packages/packaging/requirements.py ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This file is dual licensed under the terms of the Apache License, Version
2
+ # 2.0, and the BSD License. See the LICENSE file in the root of this repository
3
+ # for complete details.
4
+ from __future__ import annotations
5
+
6
+ from typing import Any, Iterator
7
+
8
+ from ._parser import parse_requirement as _parse_requirement
9
+ from ._tokenizer import ParserSyntaxError
10
+ from .markers import Marker, _normalize_extra_values
11
+ from .specifiers import SpecifierSet
12
+ from .utils import canonicalize_name
13
+
14
+
15
+ class InvalidRequirement(ValueError):
16
+ """
17
+ An invalid requirement was found, users should refer to PEP 508.
18
+ """
19
+
20
+
21
+ class Requirement:
22
+ """Parse a requirement.
23
+
24
+ Parse a given requirement string into its parts, such as name, specifier,
25
+ URL, and extras. Raises InvalidRequirement on a badly-formed requirement
26
+ string.
27
+ """
28
+
29
+ # TODO: Can we test whether something is contained within a requirement?
30
+ # If so how do we do that? Do we need to test against the _name_ of
31
+ # the thing as well as the version? What about the markers?
32
+ # TODO: Can we normalize the name and extra name?
33
+
34
+ def __init__(self, requirement_string: str) -> None:
35
+ try:
36
+ parsed = _parse_requirement(requirement_string)
37
+ except ParserSyntaxError as e:
38
+ raise InvalidRequirement(str(e)) from e
39
+
40
+ self.name: str = parsed.name
41
+ self.url: str | None = parsed.url or None
42
+ self.extras: set[str] = set(parsed.extras or [])
43
+ self.specifier: SpecifierSet = SpecifierSet(parsed.specifier)
44
+ self.marker: Marker | None = None
45
+ if parsed.marker is not None:
46
+ self.marker = Marker.__new__(Marker)
47
+ self.marker._markers = _normalize_extra_values(parsed.marker)
48
+
49
+ def _iter_parts(self, name: str) -> Iterator[str]:
50
+ yield name
51
+
52
+ if self.extras:
53
+ formatted_extras = ",".join(sorted(self.extras))
54
+ yield f"[{formatted_extras}]"
55
+
56
+ if self.specifier:
57
+ yield str(self.specifier)
58
+
59
+ if self.url:
60
+ yield f"@ {self.url}"
61
+ if self.marker:
62
+ yield " "
63
+
64
+ if self.marker:
65
+ yield f"; {self.marker}"
66
+
67
+ def __str__(self) -> str:
68
+ return "".join(self._iter_parts(self.name))
69
+
70
+ def __repr__(self) -> str:
71
+ return f"<Requirement('{self}')>"
72
+
73
+ def __hash__(self) -> int:
74
+ return hash(
75
+ (
76
+ self.__class__.__name__,
77
+ *self._iter_parts(canonicalize_name(self.name)),
78
+ )
79
+ )
80
+
81
+ def __eq__(self, other: Any) -> bool:
82
+ if not isinstance(other, Requirement):
83
+ return NotImplemented
84
+
85
+ return (
86
+ canonicalize_name(self.name) == canonicalize_name(other.name)
87
+ and self.extras == other.extras
88
+ and self.specifier == other.specifier
89
+ and self.url == other.url
90
+ and self.marker == other.marker
91
+ )
lib/python3.12/site-packages/packaging/specifiers.py ADDED
@@ -0,0 +1,1019 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This file is dual licensed under the terms of the Apache License, Version
2
+ # 2.0, and the BSD License. See the LICENSE file in the root of this repository
3
+ # for complete details.
4
+ """
5
+ .. testsetup::
6
+
7
+ from packaging.specifiers import Specifier, SpecifierSet, InvalidSpecifier
8
+ from packaging.version import Version
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import abc
14
+ import itertools
15
+ import re
16
+ from typing import Callable, Iterable, Iterator, TypeVar, Union
17
+
18
+ from .utils import canonicalize_version
19
+ from .version import Version
20
+
21
+ UnparsedVersion = Union[Version, str]
22
+ UnparsedVersionVar = TypeVar("UnparsedVersionVar", bound=UnparsedVersion)
23
+ CallableOperator = Callable[[Version, str], bool]
24
+
25
+
26
+ def _coerce_version(version: UnparsedVersion) -> Version:
27
+ if not isinstance(version, Version):
28
+ version = Version(version)
29
+ return version
30
+
31
+
32
+ class InvalidSpecifier(ValueError):
33
+ """
34
+ Raised when attempting to create a :class:`Specifier` with a specifier
35
+ string that is invalid.
36
+
37
+ >>> Specifier("lolwat")
38
+ Traceback (most recent call last):
39
+ ...
40
+ packaging.specifiers.InvalidSpecifier: Invalid specifier: 'lolwat'
41
+ """
42
+
43
+
44
+ class BaseSpecifier(metaclass=abc.ABCMeta):
45
+ @abc.abstractmethod
46
+ def __str__(self) -> str:
47
+ """
48
+ Returns the str representation of this Specifier-like object. This
49
+ should be representative of the Specifier itself.
50
+ """
51
+
52
+ @abc.abstractmethod
53
+ def __hash__(self) -> int:
54
+ """
55
+ Returns a hash value for this Specifier-like object.
56
+ """
57
+
58
+ @abc.abstractmethod
59
+ def __eq__(self, other: object) -> bool:
60
+ """
61
+ Returns a boolean representing whether or not the two Specifier-like
62
+ objects are equal.
63
+
64
+ :param other: The other object to check against.
65
+ """
66
+
67
+ @property
68
+ @abc.abstractmethod
69
+ def prereleases(self) -> bool | None:
70
+ """Whether or not pre-releases as a whole are allowed.
71
+
72
+ This can be set to either ``True`` or ``False`` to explicitly enable or disable
73
+ prereleases or it can be set to ``None`` (the default) to use default semantics.
74
+ """
75
+
76
+ @prereleases.setter
77
+ def prereleases(self, value: bool) -> None:
78
+ """Setter for :attr:`prereleases`.
79
+
80
+ :param value: The value to set.
81
+ """
82
+
83
+ @abc.abstractmethod
84
+ def contains(self, item: str, prereleases: bool | None = None) -> bool:
85
+ """
86
+ Determines if the given item is contained within this specifier.
87
+ """
88
+
89
+ @abc.abstractmethod
90
+ def filter(
91
+ self, iterable: Iterable[UnparsedVersionVar], prereleases: bool | None = None
92
+ ) -> Iterator[UnparsedVersionVar]:
93
+ """
94
+ Takes an iterable of items and filters them so that only items which
95
+ are contained within this specifier are allowed in it.
96
+ """
97
+
98
+
99
+ class Specifier(BaseSpecifier):
100
+ """This class abstracts handling of version specifiers.
101
+
102
+ .. tip::
103
+
104
+ It is generally not required to instantiate this manually. You should instead
105
+ prefer to work with :class:`SpecifierSet` instead, which can parse
106
+ comma-separated version specifiers (which is what package metadata contains).
107
+ """
108
+
109
+ _operator_regex_str = r"""
110
+ (?P<operator>(~=|==|!=|<=|>=|<|>|===))
111
+ """
112
+ _version_regex_str = r"""
113
+ (?P<version>
114
+ (?:
115
+ # The identity operators allow for an escape hatch that will
116
+ # do an exact string match of the version you wish to install.
117
+ # This will not be parsed by PEP 440 and we cannot determine
118
+ # any semantic meaning from it. This operator is discouraged
119
+ # but included entirely as an escape hatch.
120
+ (?<====) # Only match for the identity operator
121
+ \s*
122
+ [^\s;)]* # The arbitrary version can be just about anything,
123
+ # we match everything except for whitespace, a
124
+ # semi-colon for marker support, and a closing paren
125
+ # since versions can be enclosed in them.
126
+ )
127
+ |
128
+ (?:
129
+ # The (non)equality operators allow for wild card and local
130
+ # versions to be specified so we have to define these two
131
+ # operators separately to enable that.
132
+ (?<===|!=) # Only match for equals and not equals
133
+
134
+ \s*
135
+ v?
136
+ (?:[0-9]+!)? # epoch
137
+ [0-9]+(?:\.[0-9]+)* # release
138
+
139
+ # You cannot use a wild card and a pre-release, post-release, a dev or
140
+ # local version together so group them with a | and make them optional.
141
+ (?:
142
+ \.\* # Wild card syntax of .*
143
+ |
144
+ (?: # pre release
145
+ [-_\.]?
146
+ (alpha|beta|preview|pre|a|b|c|rc)
147
+ [-_\.]?
148
+ [0-9]*
149
+ )?
150
+ (?: # post release
151
+ (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*)
152
+ )?
153
+ (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release
154
+ (?:\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*)? # local
155
+ )?
156
+ )
157
+ |
158
+ (?:
159
+ # The compatible operator requires at least two digits in the
160
+ # release segment.
161
+ (?<=~=) # Only match for the compatible operator
162
+
163
+ \s*
164
+ v?
165
+ (?:[0-9]+!)? # epoch
166
+ [0-9]+(?:\.[0-9]+)+ # release (We have a + instead of a *)
167
+ (?: # pre release
168
+ [-_\.]?
169
+ (alpha|beta|preview|pre|a|b|c|rc)
170
+ [-_\.]?
171
+ [0-9]*
172
+ )?
173
+ (?: # post release
174
+ (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*)
175
+ )?
176
+ (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release
177
+ )
178
+ |
179
+ (?:
180
+ # All other operators only allow a sub set of what the
181
+ # (non)equality operators do. Specifically they do not allow
182
+ # local versions to be specified nor do they allow the prefix
183
+ # matching wild cards.
184
+ (?<!==|!=|~=) # We have special cases for these
185
+ # operators so we want to make sure they
186
+ # don't match here.
187
+
188
+ \s*
189
+ v?
190
+ (?:[0-9]+!)? # epoch
191
+ [0-9]+(?:\.[0-9]+)* # release
192
+ (?: # pre release
193
+ [-_\.]?
194
+ (alpha|beta|preview|pre|a|b|c|rc)
195
+ [-_\.]?
196
+ [0-9]*
197
+ )?
198
+ (?: # post release
199
+ (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*)
200
+ )?
201
+ (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release
202
+ )
203
+ )
204
+ """
205
+
206
+ _regex = re.compile(
207
+ r"^\s*" + _operator_regex_str + _version_regex_str + r"\s*$",
208
+ re.VERBOSE | re.IGNORECASE,
209
+ )
210
+
211
+ _operators = {
212
+ "~=": "compatible",
213
+ "==": "equal",
214
+ "!=": "not_equal",
215
+ "<=": "less_than_equal",
216
+ ">=": "greater_than_equal",
217
+ "<": "less_than",
218
+ ">": "greater_than",
219
+ "===": "arbitrary",
220
+ }
221
+
222
+ def __init__(self, spec: str = "", prereleases: bool | None = None) -> None:
223
+ """Initialize a Specifier instance.
224
+
225
+ :param spec:
226
+ The string representation of a specifier which will be parsed and
227
+ normalized before use.
228
+ :param prereleases:
229
+ This tells the specifier if it should accept prerelease versions if
230
+ applicable or not. The default of ``None`` will autodetect it from the
231
+ given specifiers.
232
+ :raises InvalidSpecifier:
233
+ If the given specifier is invalid (i.e. bad syntax).
234
+ """
235
+ match = self._regex.search(spec)
236
+ if not match:
237
+ raise InvalidSpecifier(f"Invalid specifier: {spec!r}")
238
+
239
+ self._spec: tuple[str, str] = (
240
+ match.group("operator").strip(),
241
+ match.group("version").strip(),
242
+ )
243
+
244
+ # Store whether or not this Specifier should accept prereleases
245
+ self._prereleases = prereleases
246
+
247
+ # https://github.com/python/mypy/pull/13475#pullrequestreview-1079784515
248
+ @property # type: ignore[override]
249
+ def prereleases(self) -> bool:
250
+ # If there is an explicit prereleases set for this, then we'll just
251
+ # blindly use that.
252
+ if self._prereleases is not None:
253
+ return self._prereleases
254
+
255
+ # Look at all of our specifiers and determine if they are inclusive
256
+ # operators, and if they are if they are including an explicit
257
+ # prerelease.
258
+ operator, version = self._spec
259
+ if operator in ["==", ">=", "<=", "~=", "===", ">", "<"]:
260
+ # The == specifier can include a trailing .*, if it does we
261
+ # want to remove before parsing.
262
+ if operator == "==" and version.endswith(".*"):
263
+ version = version[:-2]
264
+
265
+ # Parse the version, and if it is a pre-release than this
266
+ # specifier allows pre-releases.
267
+ if Version(version).is_prerelease:
268
+ return True
269
+
270
+ return False
271
+
272
+ @prereleases.setter
273
+ def prereleases(self, value: bool) -> None:
274
+ self._prereleases = value
275
+
276
+ @property
277
+ def operator(self) -> str:
278
+ """The operator of this specifier.
279
+
280
+ >>> Specifier("==1.2.3").operator
281
+ '=='
282
+ """
283
+ return self._spec[0]
284
+
285
+ @property
286
+ def version(self) -> str:
287
+ """The version of this specifier.
288
+
289
+ >>> Specifier("==1.2.3").version
290
+ '1.2.3'
291
+ """
292
+ return self._spec[1]
293
+
294
+ def __repr__(self) -> str:
295
+ """A representation of the Specifier that shows all internal state.
296
+
297
+ >>> Specifier('>=1.0.0')
298
+ <Specifier('>=1.0.0')>
299
+ >>> Specifier('>=1.0.0', prereleases=False)
300
+ <Specifier('>=1.0.0', prereleases=False)>
301
+ >>> Specifier('>=1.0.0', prereleases=True)
302
+ <Specifier('>=1.0.0', prereleases=True)>
303
+ """
304
+ pre = (
305
+ f", prereleases={self.prereleases!r}"
306
+ if self._prereleases is not None
307
+ else ""
308
+ )
309
+
310
+ return f"<{self.__class__.__name__}({str(self)!r}{pre})>"
311
+
312
+ def __str__(self) -> str:
313
+ """A string representation of the Specifier that can be round-tripped.
314
+
315
+ >>> str(Specifier('>=1.0.0'))
316
+ '>=1.0.0'
317
+ >>> str(Specifier('>=1.0.0', prereleases=False))
318
+ '>=1.0.0'
319
+ """
320
+ return "{}{}".format(*self._spec)
321
+
322
+ @property
323
+ def _canonical_spec(self) -> tuple[str, str]:
324
+ canonical_version = canonicalize_version(
325
+ self._spec[1],
326
+ strip_trailing_zero=(self._spec[0] != "~="),
327
+ )
328
+ return self._spec[0], canonical_version
329
+
330
+ def __hash__(self) -> int:
331
+ return hash(self._canonical_spec)
332
+
333
+ def __eq__(self, other: object) -> bool:
334
+ """Whether or not the two Specifier-like objects are equal.
335
+
336
+ :param other: The other object to check against.
337
+
338
+ The value of :attr:`prereleases` is ignored.
339
+
340
+ >>> Specifier("==1.2.3") == Specifier("== 1.2.3.0")
341
+ True
342
+ >>> (Specifier("==1.2.3", prereleases=False) ==
343
+ ... Specifier("==1.2.3", prereleases=True))
344
+ True
345
+ >>> Specifier("==1.2.3") == "==1.2.3"
346
+ True
347
+ >>> Specifier("==1.2.3") == Specifier("==1.2.4")
348
+ False
349
+ >>> Specifier("==1.2.3") == Specifier("~=1.2.3")
350
+ False
351
+ """
352
+ if isinstance(other, str):
353
+ try:
354
+ other = self.__class__(str(other))
355
+ except InvalidSpecifier:
356
+ return NotImplemented
357
+ elif not isinstance(other, self.__class__):
358
+ return NotImplemented
359
+
360
+ return self._canonical_spec == other._canonical_spec
361
+
362
+ def _get_operator(self, op: str) -> CallableOperator:
363
+ operator_callable: CallableOperator = getattr(
364
+ self, f"_compare_{self._operators[op]}"
365
+ )
366
+ return operator_callable
367
+
368
+ def _compare_compatible(self, prospective: Version, spec: str) -> bool:
369
+ # Compatible releases have an equivalent combination of >= and ==. That
370
+ # is that ~=2.2 is equivalent to >=2.2,==2.*. This allows us to
371
+ # implement this in terms of the other specifiers instead of
372
+ # implementing it ourselves. The only thing we need to do is construct
373
+ # the other specifiers.
374
+
375
+ # We want everything but the last item in the version, but we want to
376
+ # ignore suffix segments.
377
+ prefix = _version_join(
378
+ list(itertools.takewhile(_is_not_suffix, _version_split(spec)))[:-1]
379
+ )
380
+
381
+ # Add the prefix notation to the end of our string
382
+ prefix += ".*"
383
+
384
+ return self._get_operator(">=")(prospective, spec) and self._get_operator("==")(
385
+ prospective, prefix
386
+ )
387
+
388
+ def _compare_equal(self, prospective: Version, spec: str) -> bool:
389
+ # We need special logic to handle prefix matching
390
+ if spec.endswith(".*"):
391
+ # In the case of prefix matching we want to ignore local segment.
392
+ normalized_prospective = canonicalize_version(
393
+ prospective.public, strip_trailing_zero=False
394
+ )
395
+ # Get the normalized version string ignoring the trailing .*
396
+ normalized_spec = canonicalize_version(spec[:-2], strip_trailing_zero=False)
397
+ # Split the spec out by bangs and dots, and pretend that there is
398
+ # an implicit dot in between a release segment and a pre-release segment.
399
+ split_spec = _version_split(normalized_spec)
400
+
401
+ # Split the prospective version out by bangs and dots, and pretend
402
+ # that there is an implicit dot in between a release segment and
403
+ # a pre-release segment.
404
+ split_prospective = _version_split(normalized_prospective)
405
+
406
+ # 0-pad the prospective version before shortening it to get the correct
407
+ # shortened version.
408
+ padded_prospective, _ = _pad_version(split_prospective, split_spec)
409
+
410
+ # Shorten the prospective version to be the same length as the spec
411
+ # so that we can determine if the specifier is a prefix of the
412
+ # prospective version or not.
413
+ shortened_prospective = padded_prospective[: len(split_spec)]
414
+
415
+ return shortened_prospective == split_spec
416
+ else:
417
+ # Convert our spec string into a Version
418
+ spec_version = Version(spec)
419
+
420
+ # If the specifier does not have a local segment, then we want to
421
+ # act as if the prospective version also does not have a local
422
+ # segment.
423
+ if not spec_version.local:
424
+ prospective = Version(prospective.public)
425
+
426
+ return prospective == spec_version
427
+
428
+ def _compare_not_equal(self, prospective: Version, spec: str) -> bool:
429
+ return not self._compare_equal(prospective, spec)
430
+
431
+ def _compare_less_than_equal(self, prospective: Version, spec: str) -> bool:
432
+ # NB: Local version identifiers are NOT permitted in the version
433
+ # specifier, so local version labels can be universally removed from
434
+ # the prospective version.
435
+ return Version(prospective.public) <= Version(spec)
436
+
437
+ def _compare_greater_than_equal(self, prospective: Version, spec: str) -> bool:
438
+ # NB: Local version identifiers are NOT permitted in the version
439
+ # specifier, so local version labels can be universally removed from
440
+ # the prospective version.
441
+ return Version(prospective.public) >= Version(spec)
442
+
443
+ def _compare_less_than(self, prospective: Version, spec_str: str) -> bool:
444
+ # Convert our spec to a Version instance, since we'll want to work with
445
+ # it as a version.
446
+ spec = Version(spec_str)
447
+
448
+ # Check to see if the prospective version is less than the spec
449
+ # version. If it's not we can short circuit and just return False now
450
+ # instead of doing extra unneeded work.
451
+ if not prospective < spec:
452
+ return False
453
+
454
+ # This special case is here so that, unless the specifier itself
455
+ # includes is a pre-release version, that we do not accept pre-release
456
+ # versions for the version mentioned in the specifier (e.g. <3.1 should
457
+ # not match 3.1.dev0, but should match 3.0.dev0).
458
+ if not spec.is_prerelease and prospective.is_prerelease:
459
+ if Version(prospective.base_version) == Version(spec.base_version):
460
+ return False
461
+
462
+ # If we've gotten to here, it means that prospective version is both
463
+ # less than the spec version *and* it's not a pre-release of the same
464
+ # version in the spec.
465
+ return True
466
+
467
+ def _compare_greater_than(self, prospective: Version, spec_str: str) -> bool:
468
+ # Convert our spec to a Version instance, since we'll want to work with
469
+ # it as a version.
470
+ spec = Version(spec_str)
471
+
472
+ # Check to see if the prospective version is greater than the spec
473
+ # version. If it's not we can short circuit and just return False now
474
+ # instead of doing extra unneeded work.
475
+ if not prospective > spec:
476
+ return False
477
+
478
+ # This special case is here so that, unless the specifier itself
479
+ # includes is a post-release version, that we do not accept
480
+ # post-release versions for the version mentioned in the specifier
481
+ # (e.g. >3.1 should not match 3.0.post0, but should match 3.2.post0).
482
+ if not spec.is_postrelease and prospective.is_postrelease:
483
+ if Version(prospective.base_version) == Version(spec.base_version):
484
+ return False
485
+
486
+ # Ensure that we do not allow a local version of the version mentioned
487
+ # in the specifier, which is technically greater than, to match.
488
+ if prospective.local is not None:
489
+ if Version(prospective.base_version) == Version(spec.base_version):
490
+ return False
491
+
492
+ # If we've gotten to here, it means that prospective version is both
493
+ # greater than the spec version *and* it's not a pre-release of the
494
+ # same version in the spec.
495
+ return True
496
+
497
+ def _compare_arbitrary(self, prospective: Version, spec: str) -> bool:
498
+ return str(prospective).lower() == str(spec).lower()
499
+
500
+ def __contains__(self, item: str | Version) -> bool:
501
+ """Return whether or not the item is contained in this specifier.
502
+
503
+ :param item: The item to check for.
504
+
505
+ This is used for the ``in`` operator and behaves the same as
506
+ :meth:`contains` with no ``prereleases`` argument passed.
507
+
508
+ >>> "1.2.3" in Specifier(">=1.2.3")
509
+ True
510
+ >>> Version("1.2.3") in Specifier(">=1.2.3")
511
+ True
512
+ >>> "1.0.0" in Specifier(">=1.2.3")
513
+ False
514
+ >>> "1.3.0a1" in Specifier(">=1.2.3")
515
+ False
516
+ >>> "1.3.0a1" in Specifier(">=1.2.3", prereleases=True)
517
+ True
518
+ """
519
+ return self.contains(item)
520
+
521
+ def contains(self, item: UnparsedVersion, prereleases: bool | None = None) -> bool:
522
+ """Return whether or not the item is contained in this specifier.
523
+
524
+ :param item:
525
+ The item to check for, which can be a version string or a
526
+ :class:`Version` instance.
527
+ :param prereleases:
528
+ Whether or not to match prereleases with this Specifier. If set to
529
+ ``None`` (the default), it uses :attr:`prereleases` to determine
530
+ whether or not prereleases are allowed.
531
+
532
+ >>> Specifier(">=1.2.3").contains("1.2.3")
533
+ True
534
+ >>> Specifier(">=1.2.3").contains(Version("1.2.3"))
535
+ True
536
+ >>> Specifier(">=1.2.3").contains("1.0.0")
537
+ False
538
+ >>> Specifier(">=1.2.3").contains("1.3.0a1")
539
+ False
540
+ >>> Specifier(">=1.2.3", prereleases=True).contains("1.3.0a1")
541
+ True
542
+ >>> Specifier(">=1.2.3").contains("1.3.0a1", prereleases=True)
543
+ True
544
+ """
545
+
546
+ # Determine if prereleases are to be allowed or not.
547
+ if prereleases is None:
548
+ prereleases = self.prereleases
549
+
550
+ # Normalize item to a Version, this allows us to have a shortcut for
551
+ # "2.0" in Specifier(">=2")
552
+ normalized_item = _coerce_version(item)
553
+
554
+ # Determine if we should be supporting prereleases in this specifier
555
+ # or not, if we do not support prereleases than we can short circuit
556
+ # logic if this version is a prereleases.
557
+ if normalized_item.is_prerelease and not prereleases:
558
+ return False
559
+
560
+ # Actually do the comparison to determine if this item is contained
561
+ # within this Specifier or not.
562
+ operator_callable: CallableOperator = self._get_operator(self.operator)
563
+ return operator_callable(normalized_item, self.version)
564
+
565
+ def filter(
566
+ self, iterable: Iterable[UnparsedVersionVar], prereleases: bool | None = None
567
+ ) -> Iterator[UnparsedVersionVar]:
568
+ """Filter items in the given iterable, that match the specifier.
569
+
570
+ :param iterable:
571
+ An iterable that can contain version strings and :class:`Version` instances.
572
+ The items in the iterable will be filtered according to the specifier.
573
+ :param prereleases:
574
+ Whether or not to allow prereleases in the returned iterator. If set to
575
+ ``None`` (the default), it will be intelligently decide whether to allow
576
+ prereleases or not (based on the :attr:`prereleases` attribute, and
577
+ whether the only versions matching are prereleases).
578
+
579
+ This method is smarter than just ``filter(Specifier().contains, [...])``
580
+ because it implements the rule from :pep:`440` that a prerelease item
581
+ SHOULD be accepted if no other versions match the given specifier.
582
+
583
+ >>> list(Specifier(">=1.2.3").filter(["1.2", "1.3", "1.5a1"]))
584
+ ['1.3']
585
+ >>> list(Specifier(">=1.2.3").filter(["1.2", "1.2.3", "1.3", Version("1.4")]))
586
+ ['1.2.3', '1.3', <Version('1.4')>]
587
+ >>> list(Specifier(">=1.2.3").filter(["1.2", "1.5a1"]))
588
+ ['1.5a1']
589
+ >>> list(Specifier(">=1.2.3").filter(["1.3", "1.5a1"], prereleases=True))
590
+ ['1.3', '1.5a1']
591
+ >>> list(Specifier(">=1.2.3", prereleases=True).filter(["1.3", "1.5a1"]))
592
+ ['1.3', '1.5a1']
593
+ """
594
+
595
+ yielded = False
596
+ found_prereleases = []
597
+
598
+ kw = {"prereleases": prereleases if prereleases is not None else True}
599
+
600
+ # Attempt to iterate over all the values in the iterable and if any of
601
+ # them match, yield them.
602
+ for version in iterable:
603
+ parsed_version = _coerce_version(version)
604
+
605
+ if self.contains(parsed_version, **kw):
606
+ # If our version is a prerelease, and we were not set to allow
607
+ # prereleases, then we'll store it for later in case nothing
608
+ # else matches this specifier.
609
+ if parsed_version.is_prerelease and not (
610
+ prereleases or self.prereleases
611
+ ):
612
+ found_prereleases.append(version)
613
+ # Either this is not a prerelease, or we should have been
614
+ # accepting prereleases from the beginning.
615
+ else:
616
+ yielded = True
617
+ yield version
618
+
619
+ # Now that we've iterated over everything, determine if we've yielded
620
+ # any values, and if we have not and we have any prereleases stored up
621
+ # then we will go ahead and yield the prereleases.
622
+ if not yielded and found_prereleases:
623
+ for version in found_prereleases:
624
+ yield version
625
+
626
+
627
+ _prefix_regex = re.compile(r"^([0-9]+)((?:a|b|c|rc)[0-9]+)$")
628
+
629
+
630
+ def _version_split(version: str) -> list[str]:
631
+ """Split version into components.
632
+
633
+ The split components are intended for version comparison. The logic does
634
+ not attempt to retain the original version string, so joining the
635
+ components back with :func:`_version_join` may not produce the original
636
+ version string.
637
+ """
638
+ result: list[str] = []
639
+
640
+ epoch, _, rest = version.rpartition("!")
641
+ result.append(epoch or "0")
642
+
643
+ for item in rest.split("."):
644
+ match = _prefix_regex.search(item)
645
+ if match:
646
+ result.extend(match.groups())
647
+ else:
648
+ result.append(item)
649
+ return result
650
+
651
+
652
+ def _version_join(components: list[str]) -> str:
653
+ """Join split version components into a version string.
654
+
655
+ This function assumes the input came from :func:`_version_split`, where the
656
+ first component must be the epoch (either empty or numeric), and all other
657
+ components numeric.
658
+ """
659
+ epoch, *rest = components
660
+ return f"{epoch}!{'.'.join(rest)}"
661
+
662
+
663
+ def _is_not_suffix(segment: str) -> bool:
664
+ return not any(
665
+ segment.startswith(prefix) for prefix in ("dev", "a", "b", "rc", "post")
666
+ )
667
+
668
+
669
+ def _pad_version(left: list[str], right: list[str]) -> tuple[list[str], list[str]]:
670
+ left_split, right_split = [], []
671
+
672
+ # Get the release segment of our versions
673
+ left_split.append(list(itertools.takewhile(lambda x: x.isdigit(), left)))
674
+ right_split.append(list(itertools.takewhile(lambda x: x.isdigit(), right)))
675
+
676
+ # Get the rest of our versions
677
+ left_split.append(left[len(left_split[0]) :])
678
+ right_split.append(right[len(right_split[0]) :])
679
+
680
+ # Insert our padding
681
+ left_split.insert(1, ["0"] * max(0, len(right_split[0]) - len(left_split[0])))
682
+ right_split.insert(1, ["0"] * max(0, len(left_split[0]) - len(right_split[0])))
683
+
684
+ return (
685
+ list(itertools.chain.from_iterable(left_split)),
686
+ list(itertools.chain.from_iterable(right_split)),
687
+ )
688
+
689
+
690
+ class SpecifierSet(BaseSpecifier):
691
+ """This class abstracts handling of a set of version specifiers.
692
+
693
+ It can be passed a single specifier (``>=3.0``), a comma-separated list of
694
+ specifiers (``>=3.0,!=3.1``), or no specifier at all.
695
+ """
696
+
697
+ def __init__(
698
+ self,
699
+ specifiers: str | Iterable[Specifier] = "",
700
+ prereleases: bool | None = None,
701
+ ) -> None:
702
+ """Initialize a SpecifierSet instance.
703
+
704
+ :param specifiers:
705
+ The string representation of a specifier or a comma-separated list of
706
+ specifiers which will be parsed and normalized before use.
707
+ May also be an iterable of ``Specifier`` instances, which will be used
708
+ as is.
709
+ :param prereleases:
710
+ This tells the SpecifierSet if it should accept prerelease versions if
711
+ applicable or not. The default of ``None`` will autodetect it from the
712
+ given specifiers.
713
+
714
+ :raises InvalidSpecifier:
715
+ If the given ``specifiers`` are not parseable than this exception will be
716
+ raised.
717
+ """
718
+
719
+ if isinstance(specifiers, str):
720
+ # Split on `,` to break each individual specifier into its own item, and
721
+ # strip each item to remove leading/trailing whitespace.
722
+ split_specifiers = [s.strip() for s in specifiers.split(",") if s.strip()]
723
+
724
+ # Make each individual specifier a Specifier and save in a frozen set
725
+ # for later.
726
+ self._specs = frozenset(map(Specifier, split_specifiers))
727
+ else:
728
+ # Save the supplied specifiers in a frozen set.
729
+ self._specs = frozenset(specifiers)
730
+
731
+ # Store our prereleases value so we can use it later to determine if
732
+ # we accept prereleases or not.
733
+ self._prereleases = prereleases
734
+
735
+ @property
736
+ def prereleases(self) -> bool | None:
737
+ # If we have been given an explicit prerelease modifier, then we'll
738
+ # pass that through here.
739
+ if self._prereleases is not None:
740
+ return self._prereleases
741
+
742
+ # If we don't have any specifiers, and we don't have a forced value,
743
+ # then we'll just return None since we don't know if this should have
744
+ # pre-releases or not.
745
+ if not self._specs:
746
+ return None
747
+
748
+ # Otherwise we'll see if any of the given specifiers accept
749
+ # prereleases, if any of them do we'll return True, otherwise False.
750
+ return any(s.prereleases for s in self._specs)
751
+
752
+ @prereleases.setter
753
+ def prereleases(self, value: bool) -> None:
754
+ self._prereleases = value
755
+
756
+ def __repr__(self) -> str:
757
+ """A representation of the specifier set that shows all internal state.
758
+
759
+ Note that the ordering of the individual specifiers within the set may not
760
+ match the input string.
761
+
762
+ >>> SpecifierSet('>=1.0.0,!=2.0.0')
763
+ <SpecifierSet('!=2.0.0,>=1.0.0')>
764
+ >>> SpecifierSet('>=1.0.0,!=2.0.0', prereleases=False)
765
+ <SpecifierSet('!=2.0.0,>=1.0.0', prereleases=False)>
766
+ >>> SpecifierSet('>=1.0.0,!=2.0.0', prereleases=True)
767
+ <SpecifierSet('!=2.0.0,>=1.0.0', prereleases=True)>
768
+ """
769
+ pre = (
770
+ f", prereleases={self.prereleases!r}"
771
+ if self._prereleases is not None
772
+ else ""
773
+ )
774
+
775
+ return f"<SpecifierSet({str(self)!r}{pre})>"
776
+
777
+ def __str__(self) -> str:
778
+ """A string representation of the specifier set that can be round-tripped.
779
+
780
+ Note that the ordering of the individual specifiers within the set may not
781
+ match the input string.
782
+
783
+ >>> str(SpecifierSet(">=1.0.0,!=1.0.1"))
784
+ '!=1.0.1,>=1.0.0'
785
+ >>> str(SpecifierSet(">=1.0.0,!=1.0.1", prereleases=False))
786
+ '!=1.0.1,>=1.0.0'
787
+ """
788
+ return ",".join(sorted(str(s) for s in self._specs))
789
+
790
+ def __hash__(self) -> int:
791
+ return hash(self._specs)
792
+
793
+ def __and__(self, other: SpecifierSet | str) -> SpecifierSet:
794
+ """Return a SpecifierSet which is a combination of the two sets.
795
+
796
+ :param other: The other object to combine with.
797
+
798
+ >>> SpecifierSet(">=1.0.0,!=1.0.1") & '<=2.0.0,!=2.0.1'
799
+ <SpecifierSet('!=1.0.1,!=2.0.1,<=2.0.0,>=1.0.0')>
800
+ >>> SpecifierSet(">=1.0.0,!=1.0.1") & SpecifierSet('<=2.0.0,!=2.0.1')
801
+ <SpecifierSet('!=1.0.1,!=2.0.1,<=2.0.0,>=1.0.0')>
802
+ """
803
+ if isinstance(other, str):
804
+ other = SpecifierSet(other)
805
+ elif not isinstance(other, SpecifierSet):
806
+ return NotImplemented
807
+
808
+ specifier = SpecifierSet()
809
+ specifier._specs = frozenset(self._specs | other._specs)
810
+
811
+ if self._prereleases is None and other._prereleases is not None:
812
+ specifier._prereleases = other._prereleases
813
+ elif self._prereleases is not None and other._prereleases is None:
814
+ specifier._prereleases = self._prereleases
815
+ elif self._prereleases == other._prereleases:
816
+ specifier._prereleases = self._prereleases
817
+ else:
818
+ raise ValueError(
819
+ "Cannot combine SpecifierSets with True and False prerelease overrides."
820
+ )
821
+
822
+ return specifier
823
+
824
+ def __eq__(self, other: object) -> bool:
825
+ """Whether or not the two SpecifierSet-like objects are equal.
826
+
827
+ :param other: The other object to check against.
828
+
829
+ The value of :attr:`prereleases` is ignored.
830
+
831
+ >>> SpecifierSet(">=1.0.0,!=1.0.1") == SpecifierSet(">=1.0.0,!=1.0.1")
832
+ True
833
+ >>> (SpecifierSet(">=1.0.0,!=1.0.1", prereleases=False) ==
834
+ ... SpecifierSet(">=1.0.0,!=1.0.1", prereleases=True))
835
+ True
836
+ >>> SpecifierSet(">=1.0.0,!=1.0.1") == ">=1.0.0,!=1.0.1"
837
+ True
838
+ >>> SpecifierSet(">=1.0.0,!=1.0.1") == SpecifierSet(">=1.0.0")
839
+ False
840
+ >>> SpecifierSet(">=1.0.0,!=1.0.1") == SpecifierSet(">=1.0.0,!=1.0.2")
841
+ False
842
+ """
843
+ if isinstance(other, (str, Specifier)):
844
+ other = SpecifierSet(str(other))
845
+ elif not isinstance(other, SpecifierSet):
846
+ return NotImplemented
847
+
848
+ return self._specs == other._specs
849
+
850
+ def __len__(self) -> int:
851
+ """Returns the number of specifiers in this specifier set."""
852
+ return len(self._specs)
853
+
854
+ def __iter__(self) -> Iterator[Specifier]:
855
+ """
856
+ Returns an iterator over all the underlying :class:`Specifier` instances
857
+ in this specifier set.
858
+
859
+ >>> sorted(SpecifierSet(">=1.0.0,!=1.0.1"), key=str)
860
+ [<Specifier('!=1.0.1')>, <Specifier('>=1.0.0')>]
861
+ """
862
+ return iter(self._specs)
863
+
864
+ def __contains__(self, item: UnparsedVersion) -> bool:
865
+ """Return whether or not the item is contained in this specifier.
866
+
867
+ :param item: The item to check for.
868
+
869
+ This is used for the ``in`` operator and behaves the same as
870
+ :meth:`contains` with no ``prereleases`` argument passed.
871
+
872
+ >>> "1.2.3" in SpecifierSet(">=1.0.0,!=1.0.1")
873
+ True
874
+ >>> Version("1.2.3") in SpecifierSet(">=1.0.0,!=1.0.1")
875
+ True
876
+ >>> "1.0.1" in SpecifierSet(">=1.0.0,!=1.0.1")
877
+ False
878
+ >>> "1.3.0a1" in SpecifierSet(">=1.0.0,!=1.0.1")
879
+ False
880
+ >>> "1.3.0a1" in SpecifierSet(">=1.0.0,!=1.0.1", prereleases=True)
881
+ True
882
+ """
883
+ return self.contains(item)
884
+
885
+ def contains(
886
+ self,
887
+ item: UnparsedVersion,
888
+ prereleases: bool | None = None,
889
+ installed: bool | None = None,
890
+ ) -> bool:
891
+ """Return whether or not the item is contained in this SpecifierSet.
892
+
893
+ :param item:
894
+ The item to check for, which can be a version string or a
895
+ :class:`Version` instance.
896
+ :param prereleases:
897
+ Whether or not to match prereleases with this SpecifierSet. If set to
898
+ ``None`` (the default), it uses :attr:`prereleases` to determine
899
+ whether or not prereleases are allowed.
900
+
901
+ >>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.2.3")
902
+ True
903
+ >>> SpecifierSet(">=1.0.0,!=1.0.1").contains(Version("1.2.3"))
904
+ True
905
+ >>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.0.1")
906
+ False
907
+ >>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.3.0a1")
908
+ False
909
+ >>> SpecifierSet(">=1.0.0,!=1.0.1", prereleases=True).contains("1.3.0a1")
910
+ True
911
+ >>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.3.0a1", prereleases=True)
912
+ True
913
+ """
914
+ # Ensure that our item is a Version instance.
915
+ if not isinstance(item, Version):
916
+ item = Version(item)
917
+
918
+ # Determine if we're forcing a prerelease or not, if we're not forcing
919
+ # one for this particular filter call, then we'll use whatever the
920
+ # SpecifierSet thinks for whether or not we should support prereleases.
921
+ if prereleases is None:
922
+ prereleases = self.prereleases
923
+
924
+ # We can determine if we're going to allow pre-releases by looking to
925
+ # see if any of the underlying items supports them. If none of them do
926
+ # and this item is a pre-release then we do not allow it and we can
927
+ # short circuit that here.
928
+ # Note: This means that 1.0.dev1 would not be contained in something
929
+ # like >=1.0.devabc however it would be in >=1.0.debabc,>0.0.dev0
930
+ if not prereleases and item.is_prerelease:
931
+ return False
932
+
933
+ if installed and item.is_prerelease:
934
+ item = Version(item.base_version)
935
+
936
+ # We simply dispatch to the underlying specs here to make sure that the
937
+ # given version is contained within all of them.
938
+ # Note: This use of all() here means that an empty set of specifiers
939
+ # will always return True, this is an explicit design decision.
940
+ return all(s.contains(item, prereleases=prereleases) for s in self._specs)
941
+
942
+ def filter(
943
+ self, iterable: Iterable[UnparsedVersionVar], prereleases: bool | None = None
944
+ ) -> Iterator[UnparsedVersionVar]:
945
+ """Filter items in the given iterable, that match the specifiers in this set.
946
+
947
+ :param iterable:
948
+ An iterable that can contain version strings and :class:`Version` instances.
949
+ The items in the iterable will be filtered according to the specifier.
950
+ :param prereleases:
951
+ Whether or not to allow prereleases in the returned iterator. If set to
952
+ ``None`` (the default), it will be intelligently decide whether to allow
953
+ prereleases or not (based on the :attr:`prereleases` attribute, and
954
+ whether the only versions matching are prereleases).
955
+
956
+ This method is smarter than just ``filter(SpecifierSet(...).contains, [...])``
957
+ because it implements the rule from :pep:`440` that a prerelease item
958
+ SHOULD be accepted if no other versions match the given specifier.
959
+
960
+ >>> list(SpecifierSet(">=1.2.3").filter(["1.2", "1.3", "1.5a1"]))
961
+ ['1.3']
962
+ >>> list(SpecifierSet(">=1.2.3").filter(["1.2", "1.3", Version("1.4")]))
963
+ ['1.3', <Version('1.4')>]
964
+ >>> list(SpecifierSet(">=1.2.3").filter(["1.2", "1.5a1"]))
965
+ []
966
+ >>> list(SpecifierSet(">=1.2.3").filter(["1.3", "1.5a1"], prereleases=True))
967
+ ['1.3', '1.5a1']
968
+ >>> list(SpecifierSet(">=1.2.3", prereleases=True).filter(["1.3", "1.5a1"]))
969
+ ['1.3', '1.5a1']
970
+
971
+ An "empty" SpecifierSet will filter items based on the presence of prerelease
972
+ versions in the set.
973
+
974
+ >>> list(SpecifierSet("").filter(["1.3", "1.5a1"]))
975
+ ['1.3']
976
+ >>> list(SpecifierSet("").filter(["1.5a1"]))
977
+ ['1.5a1']
978
+ >>> list(SpecifierSet("", prereleases=True).filter(["1.3", "1.5a1"]))
979
+ ['1.3', '1.5a1']
980
+ >>> list(SpecifierSet("").filter(["1.3", "1.5a1"], prereleases=True))
981
+ ['1.3', '1.5a1']
982
+ """
983
+ # Determine if we're forcing a prerelease or not, if we're not forcing
984
+ # one for this particular filter call, then we'll use whatever the
985
+ # SpecifierSet thinks for whether or not we should support prereleases.
986
+ if prereleases is None:
987
+ prereleases = self.prereleases
988
+
989
+ # If we have any specifiers, then we want to wrap our iterable in the
990
+ # filter method for each one, this will act as a logical AND amongst
991
+ # each specifier.
992
+ if self._specs:
993
+ for spec in self._specs:
994
+ iterable = spec.filter(iterable, prereleases=bool(prereleases))
995
+ return iter(iterable)
996
+ # If we do not have any specifiers, then we need to have a rough filter
997
+ # which will filter out any pre-releases, unless there are no final
998
+ # releases.
999
+ else:
1000
+ filtered: list[UnparsedVersionVar] = []
1001
+ found_prereleases: list[UnparsedVersionVar] = []
1002
+
1003
+ for item in iterable:
1004
+ parsed_version = _coerce_version(item)
1005
+
1006
+ # Store any item which is a pre-release for later unless we've
1007
+ # already found a final version or we are accepting prereleases
1008
+ if parsed_version.is_prerelease and not prereleases:
1009
+ if not filtered:
1010
+ found_prereleases.append(item)
1011
+ else:
1012
+ filtered.append(item)
1013
+
1014
+ # If we've found no items except for pre-releases, then we'll go
1015
+ # ahead and use the pre-releases
1016
+ if not filtered and found_prereleases and prereleases is None:
1017
+ return iter(found_prereleases)
1018
+
1019
+ return iter(filtered)
lib/python3.12/site-packages/packaging/tags.py ADDED
@@ -0,0 +1,656 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This file is dual licensed under the terms of the Apache License, Version
2
+ # 2.0, and the BSD License. See the LICENSE file in the root of this repository
3
+ # for complete details.
4
+
5
+ from __future__ import annotations
6
+
7
+ import logging
8
+ import platform
9
+ import re
10
+ import struct
11
+ import subprocess
12
+ import sys
13
+ import sysconfig
14
+ from importlib.machinery import EXTENSION_SUFFIXES
15
+ from typing import (
16
+ Iterable,
17
+ Iterator,
18
+ Sequence,
19
+ Tuple,
20
+ cast,
21
+ )
22
+
23
+ from . import _manylinux, _musllinux
24
+
25
+ logger = logging.getLogger(__name__)
26
+
27
+ PythonVersion = Sequence[int]
28
+ AppleVersion = Tuple[int, int]
29
+
30
+ INTERPRETER_SHORT_NAMES: dict[str, str] = {
31
+ "python": "py", # Generic.
32
+ "cpython": "cp",
33
+ "pypy": "pp",
34
+ "ironpython": "ip",
35
+ "jython": "jy",
36
+ }
37
+
38
+
39
+ _32_BIT_INTERPRETER = struct.calcsize("P") == 4
40
+
41
+
42
+ class Tag:
43
+ """
44
+ A representation of the tag triple for a wheel.
45
+
46
+ Instances are considered immutable and thus are hashable. Equality checking
47
+ is also supported.
48
+ """
49
+
50
+ __slots__ = ["_abi", "_hash", "_interpreter", "_platform"]
51
+
52
+ def __init__(self, interpreter: str, abi: str, platform: str) -> None:
53
+ self._interpreter = interpreter.lower()
54
+ self._abi = abi.lower()
55
+ self._platform = platform.lower()
56
+ # The __hash__ of every single element in a Set[Tag] will be evaluated each time
57
+ # that a set calls its `.disjoint()` method, which may be called hundreds of
58
+ # times when scanning a page of links for packages with tags matching that
59
+ # Set[Tag]. Pre-computing the value here produces significant speedups for
60
+ # downstream consumers.
61
+ self._hash = hash((self._interpreter, self._abi, self._platform))
62
+
63
+ @property
64
+ def interpreter(self) -> str:
65
+ return self._interpreter
66
+
67
+ @property
68
+ def abi(self) -> str:
69
+ return self._abi
70
+
71
+ @property
72
+ def platform(self) -> str:
73
+ return self._platform
74
+
75
+ def __eq__(self, other: object) -> bool:
76
+ if not isinstance(other, Tag):
77
+ return NotImplemented
78
+
79
+ return (
80
+ (self._hash == other._hash) # Short-circuit ASAP for perf reasons.
81
+ and (self._platform == other._platform)
82
+ and (self._abi == other._abi)
83
+ and (self._interpreter == other._interpreter)
84
+ )
85
+
86
+ def __hash__(self) -> int:
87
+ return self._hash
88
+
89
+ def __str__(self) -> str:
90
+ return f"{self._interpreter}-{self._abi}-{self._platform}"
91
+
92
+ def __repr__(self) -> str:
93
+ return f"<{self} @ {id(self)}>"
94
+
95
+
96
+ def parse_tag(tag: str) -> frozenset[Tag]:
97
+ """
98
+ Parses the provided tag (e.g. `py3-none-any`) into a frozenset of Tag instances.
99
+
100
+ Returning a set is required due to the possibility that the tag is a
101
+ compressed tag set.
102
+ """
103
+ tags = set()
104
+ interpreters, abis, platforms = tag.split("-")
105
+ for interpreter in interpreters.split("."):
106
+ for abi in abis.split("."):
107
+ for platform_ in platforms.split("."):
108
+ tags.add(Tag(interpreter, abi, platform_))
109
+ return frozenset(tags)
110
+
111
+
112
+ def _get_config_var(name: str, warn: bool = False) -> int | str | None:
113
+ value: int | str | None = sysconfig.get_config_var(name)
114
+ if value is None and warn:
115
+ logger.debug(
116
+ "Config variable '%s' is unset, Python ABI tag may be incorrect", name
117
+ )
118
+ return value
119
+
120
+
121
+ def _normalize_string(string: str) -> str:
122
+ return string.replace(".", "_").replace("-", "_").replace(" ", "_")
123
+
124
+
125
+ def _is_threaded_cpython(abis: list[str]) -> bool:
126
+ """
127
+ Determine if the ABI corresponds to a threaded (`--disable-gil`) build.
128
+
129
+ The threaded builds are indicated by a "t" in the abiflags.
130
+ """
131
+ if len(abis) == 0:
132
+ return False
133
+ # expect e.g., cp313
134
+ m = re.match(r"cp\d+(.*)", abis[0])
135
+ if not m:
136
+ return False
137
+ abiflags = m.group(1)
138
+ return "t" in abiflags
139
+
140
+
141
+ def _abi3_applies(python_version: PythonVersion, threading: bool) -> bool:
142
+ """
143
+ Determine if the Python version supports abi3.
144
+
145
+ PEP 384 was first implemented in Python 3.2. The threaded (`--disable-gil`)
146
+ builds do not support abi3.
147
+ """
148
+ return len(python_version) > 1 and tuple(python_version) >= (3, 2) and not threading
149
+
150
+
151
+ def _cpython_abis(py_version: PythonVersion, warn: bool = False) -> list[str]:
152
+ py_version = tuple(py_version) # To allow for version comparison.
153
+ abis = []
154
+ version = _version_nodot(py_version[:2])
155
+ threading = debug = pymalloc = ucs4 = ""
156
+ with_debug = _get_config_var("Py_DEBUG", warn)
157
+ has_refcount = hasattr(sys, "gettotalrefcount")
158
+ # Windows doesn't set Py_DEBUG, so checking for support of debug-compiled
159
+ # extension modules is the best option.
160
+ # https://github.com/pypa/pip/issues/3383#issuecomment-173267692
161
+ has_ext = "_d.pyd" in EXTENSION_SUFFIXES
162
+ if with_debug or (with_debug is None and (has_refcount or has_ext)):
163
+ debug = "d"
164
+ if py_version >= (3, 13) and _get_config_var("Py_GIL_DISABLED", warn):
165
+ threading = "t"
166
+ if py_version < (3, 8):
167
+ with_pymalloc = _get_config_var("WITH_PYMALLOC", warn)
168
+ if with_pymalloc or with_pymalloc is None:
169
+ pymalloc = "m"
170
+ if py_version < (3, 3):
171
+ unicode_size = _get_config_var("Py_UNICODE_SIZE", warn)
172
+ if unicode_size == 4 or (
173
+ unicode_size is None and sys.maxunicode == 0x10FFFF
174
+ ):
175
+ ucs4 = "u"
176
+ elif debug:
177
+ # Debug builds can also load "normal" extension modules.
178
+ # We can also assume no UCS-4 or pymalloc requirement.
179
+ abis.append(f"cp{version}{threading}")
180
+ abis.insert(0, f"cp{version}{threading}{debug}{pymalloc}{ucs4}")
181
+ return abis
182
+
183
+
184
+ def cpython_tags(
185
+ python_version: PythonVersion | None = None,
186
+ abis: Iterable[str] | None = None,
187
+ platforms: Iterable[str] | None = None,
188
+ *,
189
+ warn: bool = False,
190
+ ) -> Iterator[Tag]:
191
+ """
192
+ Yields the tags for a CPython interpreter.
193
+
194
+ The tags consist of:
195
+ - cp<python_version>-<abi>-<platform>
196
+ - cp<python_version>-abi3-<platform>
197
+ - cp<python_version>-none-<platform>
198
+ - cp<less than python_version>-abi3-<platform> # Older Python versions down to 3.2.
199
+
200
+ If python_version only specifies a major version then user-provided ABIs and
201
+ the 'none' ABItag will be used.
202
+
203
+ If 'abi3' or 'none' are specified in 'abis' then they will be yielded at
204
+ their normal position and not at the beginning.
205
+ """
206
+ if not python_version:
207
+ python_version = sys.version_info[:2]
208
+
209
+ interpreter = f"cp{_version_nodot(python_version[:2])}"
210
+
211
+ if abis is None:
212
+ if len(python_version) > 1:
213
+ abis = _cpython_abis(python_version, warn)
214
+ else:
215
+ abis = []
216
+ abis = list(abis)
217
+ # 'abi3' and 'none' are explicitly handled later.
218
+ for explicit_abi in ("abi3", "none"):
219
+ try:
220
+ abis.remove(explicit_abi)
221
+ except ValueError:
222
+ pass
223
+
224
+ platforms = list(platforms or platform_tags())
225
+ for abi in abis:
226
+ for platform_ in platforms:
227
+ yield Tag(interpreter, abi, platform_)
228
+
229
+ threading = _is_threaded_cpython(abis)
230
+ use_abi3 = _abi3_applies(python_version, threading)
231
+ if use_abi3:
232
+ yield from (Tag(interpreter, "abi3", platform_) for platform_ in platforms)
233
+ yield from (Tag(interpreter, "none", platform_) for platform_ in platforms)
234
+
235
+ if use_abi3:
236
+ for minor_version in range(python_version[1] - 1, 1, -1):
237
+ for platform_ in platforms:
238
+ version = _version_nodot((python_version[0], minor_version))
239
+ interpreter = f"cp{version}"
240
+ yield Tag(interpreter, "abi3", platform_)
241
+
242
+
243
+ def _generic_abi() -> list[str]:
244
+ """
245
+ Return the ABI tag based on EXT_SUFFIX.
246
+ """
247
+ # The following are examples of `EXT_SUFFIX`.
248
+ # We want to keep the parts which are related to the ABI and remove the
249
+ # parts which are related to the platform:
250
+ # - linux: '.cpython-310-x86_64-linux-gnu.so' => cp310
251
+ # - mac: '.cpython-310-darwin.so' => cp310
252
+ # - win: '.cp310-win_amd64.pyd' => cp310
253
+ # - win: '.pyd' => cp37 (uses _cpython_abis())
254
+ # - pypy: '.pypy38-pp73-x86_64-linux-gnu.so' => pypy38_pp73
255
+ # - graalpy: '.graalpy-38-native-x86_64-darwin.dylib'
256
+ # => graalpy_38_native
257
+
258
+ ext_suffix = _get_config_var("EXT_SUFFIX", warn=True)
259
+ if not isinstance(ext_suffix, str) or ext_suffix[0] != ".":
260
+ raise SystemError("invalid sysconfig.get_config_var('EXT_SUFFIX')")
261
+ parts = ext_suffix.split(".")
262
+ if len(parts) < 3:
263
+ # CPython3.7 and earlier uses ".pyd" on Windows.
264
+ return _cpython_abis(sys.version_info[:2])
265
+ soabi = parts[1]
266
+ if soabi.startswith("cpython"):
267
+ # non-windows
268
+ abi = "cp" + soabi.split("-")[1]
269
+ elif soabi.startswith("cp"):
270
+ # windows
271
+ abi = soabi.split("-")[0]
272
+ elif soabi.startswith("pypy"):
273
+ abi = "-".join(soabi.split("-")[:2])
274
+ elif soabi.startswith("graalpy"):
275
+ abi = "-".join(soabi.split("-")[:3])
276
+ elif soabi:
277
+ # pyston, ironpython, others?
278
+ abi = soabi
279
+ else:
280
+ return []
281
+ return [_normalize_string(abi)]
282
+
283
+
284
+ def generic_tags(
285
+ interpreter: str | None = None,
286
+ abis: Iterable[str] | None = None,
287
+ platforms: Iterable[str] | None = None,
288
+ *,
289
+ warn: bool = False,
290
+ ) -> Iterator[Tag]:
291
+ """
292
+ Yields the tags for a generic interpreter.
293
+
294
+ The tags consist of:
295
+ - <interpreter>-<abi>-<platform>
296
+
297
+ The "none" ABI will be added if it was not explicitly provided.
298
+ """
299
+ if not interpreter:
300
+ interp_name = interpreter_name()
301
+ interp_version = interpreter_version(warn=warn)
302
+ interpreter = "".join([interp_name, interp_version])
303
+ if abis is None:
304
+ abis = _generic_abi()
305
+ else:
306
+ abis = list(abis)
307
+ platforms = list(platforms or platform_tags())
308
+ if "none" not in abis:
309
+ abis.append("none")
310
+ for abi in abis:
311
+ for platform_ in platforms:
312
+ yield Tag(interpreter, abi, platform_)
313
+
314
+
315
+ def _py_interpreter_range(py_version: PythonVersion) -> Iterator[str]:
316
+ """
317
+ Yields Python versions in descending order.
318
+
319
+ After the latest version, the major-only version will be yielded, and then
320
+ all previous versions of that major version.
321
+ """
322
+ if len(py_version) > 1:
323
+ yield f"py{_version_nodot(py_version[:2])}"
324
+ yield f"py{py_version[0]}"
325
+ if len(py_version) > 1:
326
+ for minor in range(py_version[1] - 1, -1, -1):
327
+ yield f"py{_version_nodot((py_version[0], minor))}"
328
+
329
+
330
+ def compatible_tags(
331
+ python_version: PythonVersion | None = None,
332
+ interpreter: str | None = None,
333
+ platforms: Iterable[str] | None = None,
334
+ ) -> Iterator[Tag]:
335
+ """
336
+ Yields the sequence of tags that are compatible with a specific version of Python.
337
+
338
+ The tags consist of:
339
+ - py*-none-<platform>
340
+ - <interpreter>-none-any # ... if `interpreter` is provided.
341
+ - py*-none-any
342
+ """
343
+ if not python_version:
344
+ python_version = sys.version_info[:2]
345
+ platforms = list(platforms or platform_tags())
346
+ for version in _py_interpreter_range(python_version):
347
+ for platform_ in platforms:
348
+ yield Tag(version, "none", platform_)
349
+ if interpreter:
350
+ yield Tag(interpreter, "none", "any")
351
+ for version in _py_interpreter_range(python_version):
352
+ yield Tag(version, "none", "any")
353
+
354
+
355
+ def _mac_arch(arch: str, is_32bit: bool = _32_BIT_INTERPRETER) -> str:
356
+ if not is_32bit:
357
+ return arch
358
+
359
+ if arch.startswith("ppc"):
360
+ return "ppc"
361
+
362
+ return "i386"
363
+
364
+
365
+ def _mac_binary_formats(version: AppleVersion, cpu_arch: str) -> list[str]:
366
+ formats = [cpu_arch]
367
+ if cpu_arch == "x86_64":
368
+ if version < (10, 4):
369
+ return []
370
+ formats.extend(["intel", "fat64", "fat32"])
371
+
372
+ elif cpu_arch == "i386":
373
+ if version < (10, 4):
374
+ return []
375
+ formats.extend(["intel", "fat32", "fat"])
376
+
377
+ elif cpu_arch == "ppc64":
378
+ # TODO: Need to care about 32-bit PPC for ppc64 through 10.2?
379
+ if version > (10, 5) or version < (10, 4):
380
+ return []
381
+ formats.append("fat64")
382
+
383
+ elif cpu_arch == "ppc":
384
+ if version > (10, 6):
385
+ return []
386
+ formats.extend(["fat32", "fat"])
387
+
388
+ if cpu_arch in {"arm64", "x86_64"}:
389
+ formats.append("universal2")
390
+
391
+ if cpu_arch in {"x86_64", "i386", "ppc64", "ppc", "intel"}:
392
+ formats.append("universal")
393
+
394
+ return formats
395
+
396
+
397
+ def mac_platforms(
398
+ version: AppleVersion | None = None, arch: str | None = None
399
+ ) -> Iterator[str]:
400
+ """
401
+ Yields the platform tags for a macOS system.
402
+
403
+ The `version` parameter is a two-item tuple specifying the macOS version to
404
+ generate platform tags for. The `arch` parameter is the CPU architecture to
405
+ generate platform tags for. Both parameters default to the appropriate value
406
+ for the current system.
407
+ """
408
+ version_str, _, cpu_arch = platform.mac_ver()
409
+ if version is None:
410
+ version = cast("AppleVersion", tuple(map(int, version_str.split(".")[:2])))
411
+ if version == (10, 16):
412
+ # When built against an older macOS SDK, Python will report macOS 10.16
413
+ # instead of the real version.
414
+ version_str = subprocess.run(
415
+ [
416
+ sys.executable,
417
+ "-sS",
418
+ "-c",
419
+ "import platform; print(platform.mac_ver()[0])",
420
+ ],
421
+ check=True,
422
+ env={"SYSTEM_VERSION_COMPAT": "0"},
423
+ stdout=subprocess.PIPE,
424
+ text=True,
425
+ ).stdout
426
+ version = cast("AppleVersion", tuple(map(int, version_str.split(".")[:2])))
427
+ else:
428
+ version = version
429
+ if arch is None:
430
+ arch = _mac_arch(cpu_arch)
431
+ else:
432
+ arch = arch
433
+
434
+ if (10, 0) <= version and version < (11, 0):
435
+ # Prior to Mac OS 11, each yearly release of Mac OS bumped the
436
+ # "minor" version number. The major version was always 10.
437
+ major_version = 10
438
+ for minor_version in range(version[1], -1, -1):
439
+ compat_version = major_version, minor_version
440
+ binary_formats = _mac_binary_formats(compat_version, arch)
441
+ for binary_format in binary_formats:
442
+ yield f"macosx_{major_version}_{minor_version}_{binary_format}"
443
+
444
+ if version >= (11, 0):
445
+ # Starting with Mac OS 11, each yearly release bumps the major version
446
+ # number. The minor versions are now the midyear updates.
447
+ minor_version = 0
448
+ for major_version in range(version[0], 10, -1):
449
+ compat_version = major_version, minor_version
450
+ binary_formats = _mac_binary_formats(compat_version, arch)
451
+ for binary_format in binary_formats:
452
+ yield f"macosx_{major_version}_{minor_version}_{binary_format}"
453
+
454
+ if version >= (11, 0):
455
+ # Mac OS 11 on x86_64 is compatible with binaries from previous releases.
456
+ # Arm64 support was introduced in 11.0, so no Arm binaries from previous
457
+ # releases exist.
458
+ #
459
+ # However, the "universal2" binary format can have a
460
+ # macOS version earlier than 11.0 when the x86_64 part of the binary supports
461
+ # that version of macOS.
462
+ major_version = 10
463
+ if arch == "x86_64":
464
+ for minor_version in range(16, 3, -1):
465
+ compat_version = major_version, minor_version
466
+ binary_formats = _mac_binary_formats(compat_version, arch)
467
+ for binary_format in binary_formats:
468
+ yield f"macosx_{major_version}_{minor_version}_{binary_format}"
469
+ else:
470
+ for minor_version in range(16, 3, -1):
471
+ compat_version = major_version, minor_version
472
+ binary_format = "universal2"
473
+ yield f"macosx_{major_version}_{minor_version}_{binary_format}"
474
+
475
+
476
+ def ios_platforms(
477
+ version: AppleVersion | None = None, multiarch: str | None = None
478
+ ) -> Iterator[str]:
479
+ """
480
+ Yields the platform tags for an iOS system.
481
+
482
+ :param version: A two-item tuple specifying the iOS version to generate
483
+ platform tags for. Defaults to the current iOS version.
484
+ :param multiarch: The CPU architecture+ABI to generate platform tags for -
485
+ (the value used by `sys.implementation._multiarch` e.g.,
486
+ `arm64_iphoneos` or `x84_64_iphonesimulator`). Defaults to the current
487
+ multiarch value.
488
+ """
489
+ if version is None:
490
+ # if iOS is the current platform, ios_ver *must* be defined. However,
491
+ # it won't exist for CPython versions before 3.13, which causes a mypy
492
+ # error.
493
+ _, release, _, _ = platform.ios_ver() # type: ignore[attr-defined, unused-ignore]
494
+ version = cast("AppleVersion", tuple(map(int, release.split(".")[:2])))
495
+
496
+ if multiarch is None:
497
+ multiarch = sys.implementation._multiarch
498
+ multiarch = multiarch.replace("-", "_")
499
+
500
+ ios_platform_template = "ios_{major}_{minor}_{multiarch}"
501
+
502
+ # Consider any iOS major.minor version from the version requested, down to
503
+ # 12.0. 12.0 is the first iOS version that is known to have enough features
504
+ # to support CPython. Consider every possible minor release up to X.9. There
505
+ # highest the minor has ever gone is 8 (14.8 and 15.8) but having some extra
506
+ # candidates that won't ever match doesn't really hurt, and it saves us from
507
+ # having to keep an explicit list of known iOS versions in the code. Return
508
+ # the results descending order of version number.
509
+
510
+ # If the requested major version is less than 12, there won't be any matches.
511
+ if version[0] < 12:
512
+ return
513
+
514
+ # Consider the actual X.Y version that was requested.
515
+ yield ios_platform_template.format(
516
+ major=version[0], minor=version[1], multiarch=multiarch
517
+ )
518
+
519
+ # Consider every minor version from X.0 to the minor version prior to the
520
+ # version requested by the platform.
521
+ for minor in range(version[1] - 1, -1, -1):
522
+ yield ios_platform_template.format(
523
+ major=version[0], minor=minor, multiarch=multiarch
524
+ )
525
+
526
+ for major in range(version[0] - 1, 11, -1):
527
+ for minor in range(9, -1, -1):
528
+ yield ios_platform_template.format(
529
+ major=major, minor=minor, multiarch=multiarch
530
+ )
531
+
532
+
533
+ def android_platforms(
534
+ api_level: int | None = None, abi: str | None = None
535
+ ) -> Iterator[str]:
536
+ """
537
+ Yields the :attr:`~Tag.platform` tags for Android. If this function is invoked on
538
+ non-Android platforms, the ``api_level`` and ``abi`` arguments are required.
539
+
540
+ :param int api_level: The maximum `API level
541
+ <https://developer.android.com/tools/releases/platforms>`__ to return. Defaults
542
+ to the current system's version, as returned by ``platform.android_ver``.
543
+ :param str abi: The `Android ABI <https://developer.android.com/ndk/guides/abis>`__,
544
+ e.g. ``arm64_v8a``. Defaults to the current system's ABI , as returned by
545
+ ``sysconfig.get_platform``. Hyphens and periods will be replaced with
546
+ underscores.
547
+ """
548
+ if platform.system() != "Android" and (api_level is None or abi is None):
549
+ raise TypeError(
550
+ "on non-Android platforms, the api_level and abi arguments are required"
551
+ )
552
+
553
+ if api_level is None:
554
+ # Python 3.13 was the first version to return platform.system() == "Android",
555
+ # and also the first version to define platform.android_ver().
556
+ api_level = platform.android_ver().api_level # type: ignore[attr-defined]
557
+
558
+ if abi is None:
559
+ abi = sysconfig.get_platform().split("-")[-1]
560
+ abi = _normalize_string(abi)
561
+
562
+ # 16 is the minimum API level known to have enough features to support CPython
563
+ # without major patching. Yield every API level from the maximum down to the
564
+ # minimum, inclusive.
565
+ min_api_level = 16
566
+ for ver in range(api_level, min_api_level - 1, -1):
567
+ yield f"android_{ver}_{abi}"
568
+
569
+
570
+ def _linux_platforms(is_32bit: bool = _32_BIT_INTERPRETER) -> Iterator[str]:
571
+ linux = _normalize_string(sysconfig.get_platform())
572
+ if not linux.startswith("linux_"):
573
+ # we should never be here, just yield the sysconfig one and return
574
+ yield linux
575
+ return
576
+ if is_32bit:
577
+ if linux == "linux_x86_64":
578
+ linux = "linux_i686"
579
+ elif linux == "linux_aarch64":
580
+ linux = "linux_armv8l"
581
+ _, arch = linux.split("_", 1)
582
+ archs = {"armv8l": ["armv8l", "armv7l"]}.get(arch, [arch])
583
+ yield from _manylinux.platform_tags(archs)
584
+ yield from _musllinux.platform_tags(archs)
585
+ for arch in archs:
586
+ yield f"linux_{arch}"
587
+
588
+
589
+ def _generic_platforms() -> Iterator[str]:
590
+ yield _normalize_string(sysconfig.get_platform())
591
+
592
+
593
+ def platform_tags() -> Iterator[str]:
594
+ """
595
+ Provides the platform tags for this installation.
596
+ """
597
+ if platform.system() == "Darwin":
598
+ return mac_platforms()
599
+ elif platform.system() == "iOS":
600
+ return ios_platforms()
601
+ elif platform.system() == "Android":
602
+ return android_platforms()
603
+ elif platform.system() == "Linux":
604
+ return _linux_platforms()
605
+ else:
606
+ return _generic_platforms()
607
+
608
+
609
+ def interpreter_name() -> str:
610
+ """
611
+ Returns the name of the running interpreter.
612
+
613
+ Some implementations have a reserved, two-letter abbreviation which will
614
+ be returned when appropriate.
615
+ """
616
+ name = sys.implementation.name
617
+ return INTERPRETER_SHORT_NAMES.get(name) or name
618
+
619
+
620
+ def interpreter_version(*, warn: bool = False) -> str:
621
+ """
622
+ Returns the version of the running interpreter.
623
+ """
624
+ version = _get_config_var("py_version_nodot", warn=warn)
625
+ if version:
626
+ version = str(version)
627
+ else:
628
+ version = _version_nodot(sys.version_info[:2])
629
+ return version
630
+
631
+
632
+ def _version_nodot(version: PythonVersion) -> str:
633
+ return "".join(map(str, version))
634
+
635
+
636
+ def sys_tags(*, warn: bool = False) -> Iterator[Tag]:
637
+ """
638
+ Returns the sequence of tag triples for the running interpreter.
639
+
640
+ The order of the sequence corresponds to priority order for the
641
+ interpreter, from most to least important.
642
+ """
643
+
644
+ interp_name = interpreter_name()
645
+ if interp_name == "cp":
646
+ yield from cpython_tags(warn=warn)
647
+ else:
648
+ yield from generic_tags()
649
+
650
+ if interp_name == "pp":
651
+ interp = "pp3"
652
+ elif interp_name == "cp":
653
+ interp = "cp" + interpreter_version(warn=warn)
654
+ else:
655
+ interp = None
656
+ yield from compatible_tags(interpreter=interp)
lib/python3.12/site-packages/packaging/utils.py ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This file is dual licensed under the terms of the Apache License, Version
2
+ # 2.0, and the BSD License. See the LICENSE file in the root of this repository
3
+ # for complete details.
4
+
5
+ from __future__ import annotations
6
+
7
+ import functools
8
+ import re
9
+ from typing import NewType, Tuple, Union, cast
10
+
11
+ from .tags import Tag, parse_tag
12
+ from .version import InvalidVersion, Version, _TrimmedRelease
13
+
14
+ BuildTag = Union[Tuple[()], Tuple[int, str]]
15
+ NormalizedName = NewType("NormalizedName", str)
16
+
17
+
18
+ class InvalidName(ValueError):
19
+ """
20
+ An invalid distribution name; users should refer to the packaging user guide.
21
+ """
22
+
23
+
24
+ class InvalidWheelFilename(ValueError):
25
+ """
26
+ An invalid wheel filename was found, users should refer to PEP 427.
27
+ """
28
+
29
+
30
+ class InvalidSdistFilename(ValueError):
31
+ """
32
+ An invalid sdist filename was found, users should refer to the packaging user guide.
33
+ """
34
+
35
+
36
+ # Core metadata spec for `Name`
37
+ _validate_regex = re.compile(
38
+ r"^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$", re.IGNORECASE
39
+ )
40
+ _canonicalize_regex = re.compile(r"[-_.]+")
41
+ _normalized_regex = re.compile(r"^([a-z0-9]|[a-z0-9]([a-z0-9-](?!--))*[a-z0-9])$")
42
+ # PEP 427: The build number must start with a digit.
43
+ _build_tag_regex = re.compile(r"(\d+)(.*)")
44
+
45
+
46
+ def canonicalize_name(name: str, *, validate: bool = False) -> NormalizedName:
47
+ if validate and not _validate_regex.match(name):
48
+ raise InvalidName(f"name is invalid: {name!r}")
49
+ # This is taken from PEP 503.
50
+ value = _canonicalize_regex.sub("-", name).lower()
51
+ return cast(NormalizedName, value)
52
+
53
+
54
+ def is_normalized_name(name: str) -> bool:
55
+ return _normalized_regex.match(name) is not None
56
+
57
+
58
+ @functools.singledispatch
59
+ def canonicalize_version(
60
+ version: Version | str, *, strip_trailing_zero: bool = True
61
+ ) -> str:
62
+ """
63
+ Return a canonical form of a version as a string.
64
+
65
+ >>> canonicalize_version('1.0.1')
66
+ '1.0.1'
67
+
68
+ Per PEP 625, versions may have multiple canonical forms, differing
69
+ only by trailing zeros.
70
+
71
+ >>> canonicalize_version('1.0.0')
72
+ '1'
73
+ >>> canonicalize_version('1.0.0', strip_trailing_zero=False)
74
+ '1.0.0'
75
+
76
+ Invalid versions are returned unaltered.
77
+
78
+ >>> canonicalize_version('foo bar baz')
79
+ 'foo bar baz'
80
+ """
81
+ return str(_TrimmedRelease(str(version)) if strip_trailing_zero else version)
82
+
83
+
84
+ @canonicalize_version.register
85
+ def _(version: str, *, strip_trailing_zero: bool = True) -> str:
86
+ try:
87
+ parsed = Version(version)
88
+ except InvalidVersion:
89
+ # Legacy versions cannot be normalized
90
+ return version
91
+ return canonicalize_version(parsed, strip_trailing_zero=strip_trailing_zero)
92
+
93
+
94
+ def parse_wheel_filename(
95
+ filename: str,
96
+ ) -> tuple[NormalizedName, Version, BuildTag, frozenset[Tag]]:
97
+ if not filename.endswith(".whl"):
98
+ raise InvalidWheelFilename(
99
+ f"Invalid wheel filename (extension must be '.whl'): {filename!r}"
100
+ )
101
+
102
+ filename = filename[:-4]
103
+ dashes = filename.count("-")
104
+ if dashes not in (4, 5):
105
+ raise InvalidWheelFilename(
106
+ f"Invalid wheel filename (wrong number of parts): {filename!r}"
107
+ )
108
+
109
+ parts = filename.split("-", dashes - 2)
110
+ name_part = parts[0]
111
+ # See PEP 427 for the rules on escaping the project name.
112
+ if "__" in name_part or re.match(r"^[\w\d._]*$", name_part, re.UNICODE) is None:
113
+ raise InvalidWheelFilename(f"Invalid project name: {filename!r}")
114
+ name = canonicalize_name(name_part)
115
+
116
+ try:
117
+ version = Version(parts[1])
118
+ except InvalidVersion as e:
119
+ raise InvalidWheelFilename(
120
+ f"Invalid wheel filename (invalid version): {filename!r}"
121
+ ) from e
122
+
123
+ if dashes == 5:
124
+ build_part = parts[2]
125
+ build_match = _build_tag_regex.match(build_part)
126
+ if build_match is None:
127
+ raise InvalidWheelFilename(
128
+ f"Invalid build number: {build_part} in {filename!r}"
129
+ )
130
+ build = cast(BuildTag, (int(build_match.group(1)), build_match.group(2)))
131
+ else:
132
+ build = ()
133
+ tags = parse_tag(parts[-1])
134
+ return (name, version, build, tags)
135
+
136
+
137
+ def parse_sdist_filename(filename: str) -> tuple[NormalizedName, Version]:
138
+ if filename.endswith(".tar.gz"):
139
+ file_stem = filename[: -len(".tar.gz")]
140
+ elif filename.endswith(".zip"):
141
+ file_stem = filename[: -len(".zip")]
142
+ else:
143
+ raise InvalidSdistFilename(
144
+ f"Invalid sdist filename (extension must be '.tar.gz' or '.zip'):"
145
+ f" {filename!r}"
146
+ )
147
+
148
+ # We are requiring a PEP 440 version, which cannot contain dashes,
149
+ # so we split on the last dash.
150
+ name_part, sep, version_part = file_stem.rpartition("-")
151
+ if not sep:
152
+ raise InvalidSdistFilename(f"Invalid sdist filename: {filename!r}")
153
+
154
+ name = canonicalize_name(name_part)
155
+
156
+ try:
157
+ version = Version(version_part)
158
+ except InvalidVersion as e:
159
+ raise InvalidSdistFilename(
160
+ f"Invalid sdist filename (invalid version): {filename!r}"
161
+ ) from e
162
+
163
+ return (name, version)
lib/python3.12/site-packages/packaging/version.py ADDED
@@ -0,0 +1,582 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This file is dual licensed under the terms of the Apache License, Version
2
+ # 2.0, and the BSD License. See the LICENSE file in the root of this repository
3
+ # for complete details.
4
+ """
5
+ .. testsetup::
6
+
7
+ from packaging.version import parse, Version
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import itertools
13
+ import re
14
+ from typing import Any, Callable, NamedTuple, SupportsInt, Tuple, Union
15
+
16
+ from ._structures import Infinity, InfinityType, NegativeInfinity, NegativeInfinityType
17
+
18
+ __all__ = ["VERSION_PATTERN", "InvalidVersion", "Version", "parse"]
19
+
20
+ LocalType = Tuple[Union[int, str], ...]
21
+
22
+ CmpPrePostDevType = Union[InfinityType, NegativeInfinityType, Tuple[str, int]]
23
+ CmpLocalType = Union[
24
+ NegativeInfinityType,
25
+ Tuple[Union[Tuple[int, str], Tuple[NegativeInfinityType, Union[int, str]]], ...],
26
+ ]
27
+ CmpKey = Tuple[
28
+ int,
29
+ Tuple[int, ...],
30
+ CmpPrePostDevType,
31
+ CmpPrePostDevType,
32
+ CmpPrePostDevType,
33
+ CmpLocalType,
34
+ ]
35
+ VersionComparisonMethod = Callable[[CmpKey, CmpKey], bool]
36
+
37
+
38
+ class _Version(NamedTuple):
39
+ epoch: int
40
+ release: tuple[int, ...]
41
+ dev: tuple[str, int] | None
42
+ pre: tuple[str, int] | None
43
+ post: tuple[str, int] | None
44
+ local: LocalType | None
45
+
46
+
47
+ def parse(version: str) -> Version:
48
+ """Parse the given version string.
49
+
50
+ >>> parse('1.0.dev1')
51
+ <Version('1.0.dev1')>
52
+
53
+ :param version: The version string to parse.
54
+ :raises InvalidVersion: When the version string is not a valid version.
55
+ """
56
+ return Version(version)
57
+
58
+
59
+ class InvalidVersion(ValueError):
60
+ """Raised when a version string is not a valid version.
61
+
62
+ >>> Version("invalid")
63
+ Traceback (most recent call last):
64
+ ...
65
+ packaging.version.InvalidVersion: Invalid version: 'invalid'
66
+ """
67
+
68
+
69
+ class _BaseVersion:
70
+ _key: tuple[Any, ...]
71
+
72
+ def __hash__(self) -> int:
73
+ return hash(self._key)
74
+
75
+ # Please keep the duplicated `isinstance` check
76
+ # in the six comparisons hereunder
77
+ # unless you find a way to avoid adding overhead function calls.
78
+ def __lt__(self, other: _BaseVersion) -> bool:
79
+ if not isinstance(other, _BaseVersion):
80
+ return NotImplemented
81
+
82
+ return self._key < other._key
83
+
84
+ def __le__(self, other: _BaseVersion) -> bool:
85
+ if not isinstance(other, _BaseVersion):
86
+ return NotImplemented
87
+
88
+ return self._key <= other._key
89
+
90
+ def __eq__(self, other: object) -> bool:
91
+ if not isinstance(other, _BaseVersion):
92
+ return NotImplemented
93
+
94
+ return self._key == other._key
95
+
96
+ def __ge__(self, other: _BaseVersion) -> bool:
97
+ if not isinstance(other, _BaseVersion):
98
+ return NotImplemented
99
+
100
+ return self._key >= other._key
101
+
102
+ def __gt__(self, other: _BaseVersion) -> bool:
103
+ if not isinstance(other, _BaseVersion):
104
+ return NotImplemented
105
+
106
+ return self._key > other._key
107
+
108
+ def __ne__(self, other: object) -> bool:
109
+ if not isinstance(other, _BaseVersion):
110
+ return NotImplemented
111
+
112
+ return self._key != other._key
113
+
114
+
115
+ # Deliberately not anchored to the start and end of the string, to make it
116
+ # easier for 3rd party code to reuse
117
+ _VERSION_PATTERN = r"""
118
+ v?
119
+ (?:
120
+ (?:(?P<epoch>[0-9]+)!)? # epoch
121
+ (?P<release>[0-9]+(?:\.[0-9]+)*) # release segment
122
+ (?P<pre> # pre-release
123
+ [-_\.]?
124
+ (?P<pre_l>alpha|a|beta|b|preview|pre|c|rc)
125
+ [-_\.]?
126
+ (?P<pre_n>[0-9]+)?
127
+ )?
128
+ (?P<post> # post release
129
+ (?:-(?P<post_n1>[0-9]+))
130
+ |
131
+ (?:
132
+ [-_\.]?
133
+ (?P<post_l>post|rev|r)
134
+ [-_\.]?
135
+ (?P<post_n2>[0-9]+)?
136
+ )
137
+ )?
138
+ (?P<dev> # dev release
139
+ [-_\.]?
140
+ (?P<dev_l>dev)
141
+ [-_\.]?
142
+ (?P<dev_n>[0-9]+)?
143
+ )?
144
+ )
145
+ (?:\+(?P<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))? # local version
146
+ """
147
+
148
+ VERSION_PATTERN = _VERSION_PATTERN
149
+ """
150
+ A string containing the regular expression used to match a valid version.
151
+
152
+ The pattern is not anchored at either end, and is intended for embedding in larger
153
+ expressions (for example, matching a version number as part of a file name). The
154
+ regular expression should be compiled with the ``re.VERBOSE`` and ``re.IGNORECASE``
155
+ flags set.
156
+
157
+ :meta hide-value:
158
+ """
159
+
160
+
161
+ class Version(_BaseVersion):
162
+ """This class abstracts handling of a project's versions.
163
+
164
+ A :class:`Version` instance is comparison aware and can be compared and
165
+ sorted using the standard Python interfaces.
166
+
167
+ >>> v1 = Version("1.0a5")
168
+ >>> v2 = Version("1.0")
169
+ >>> v1
170
+ <Version('1.0a5')>
171
+ >>> v2
172
+ <Version('1.0')>
173
+ >>> v1 < v2
174
+ True
175
+ >>> v1 == v2
176
+ False
177
+ >>> v1 > v2
178
+ False
179
+ >>> v1 >= v2
180
+ False
181
+ >>> v1 <= v2
182
+ True
183
+ """
184
+
185
+ _regex = re.compile(r"^\s*" + VERSION_PATTERN + r"\s*$", re.VERBOSE | re.IGNORECASE)
186
+ _key: CmpKey
187
+
188
+ def __init__(self, version: str) -> None:
189
+ """Initialize a Version object.
190
+
191
+ :param version:
192
+ The string representation of a version which will be parsed and normalized
193
+ before use.
194
+ :raises InvalidVersion:
195
+ If the ``version`` does not conform to PEP 440 in any way then this
196
+ exception will be raised.
197
+ """
198
+
199
+ # Validate the version and parse it into pieces
200
+ match = self._regex.search(version)
201
+ if not match:
202
+ raise InvalidVersion(f"Invalid version: {version!r}")
203
+
204
+ # Store the parsed out pieces of the version
205
+ self._version = _Version(
206
+ epoch=int(match.group("epoch")) if match.group("epoch") else 0,
207
+ release=tuple(int(i) for i in match.group("release").split(".")),
208
+ pre=_parse_letter_version(match.group("pre_l"), match.group("pre_n")),
209
+ post=_parse_letter_version(
210
+ match.group("post_l"), match.group("post_n1") or match.group("post_n2")
211
+ ),
212
+ dev=_parse_letter_version(match.group("dev_l"), match.group("dev_n")),
213
+ local=_parse_local_version(match.group("local")),
214
+ )
215
+
216
+ # Generate a key which will be used for sorting
217
+ self._key = _cmpkey(
218
+ self._version.epoch,
219
+ self._version.release,
220
+ self._version.pre,
221
+ self._version.post,
222
+ self._version.dev,
223
+ self._version.local,
224
+ )
225
+
226
+ def __repr__(self) -> str:
227
+ """A representation of the Version that shows all internal state.
228
+
229
+ >>> Version('1.0.0')
230
+ <Version('1.0.0')>
231
+ """
232
+ return f"<Version('{self}')>"
233
+
234
+ def __str__(self) -> str:
235
+ """A string representation of the version that can be round-tripped.
236
+
237
+ >>> str(Version("1.0a5"))
238
+ '1.0a5'
239
+ """
240
+ parts = []
241
+
242
+ # Epoch
243
+ if self.epoch != 0:
244
+ parts.append(f"{self.epoch}!")
245
+
246
+ # Release segment
247
+ parts.append(".".join(str(x) for x in self.release))
248
+
249
+ # Pre-release
250
+ if self.pre is not None:
251
+ parts.append("".join(str(x) for x in self.pre))
252
+
253
+ # Post-release
254
+ if self.post is not None:
255
+ parts.append(f".post{self.post}")
256
+
257
+ # Development release
258
+ if self.dev is not None:
259
+ parts.append(f".dev{self.dev}")
260
+
261
+ # Local version segment
262
+ if self.local is not None:
263
+ parts.append(f"+{self.local}")
264
+
265
+ return "".join(parts)
266
+
267
+ @property
268
+ def epoch(self) -> int:
269
+ """The epoch of the version.
270
+
271
+ >>> Version("2.0.0").epoch
272
+ 0
273
+ >>> Version("1!2.0.0").epoch
274
+ 1
275
+ """
276
+ return self._version.epoch
277
+
278
+ @property
279
+ def release(self) -> tuple[int, ...]:
280
+ """The components of the "release" segment of the version.
281
+
282
+ >>> Version("1.2.3").release
283
+ (1, 2, 3)
284
+ >>> Version("2.0.0").release
285
+ (2, 0, 0)
286
+ >>> Version("1!2.0.0.post0").release
287
+ (2, 0, 0)
288
+
289
+ Includes trailing zeroes but not the epoch or any pre-release / development /
290
+ post-release suffixes.
291
+ """
292
+ return self._version.release
293
+
294
+ @property
295
+ def pre(self) -> tuple[str, int] | None:
296
+ """The pre-release segment of the version.
297
+
298
+ >>> print(Version("1.2.3").pre)
299
+ None
300
+ >>> Version("1.2.3a1").pre
301
+ ('a', 1)
302
+ >>> Version("1.2.3b1").pre
303
+ ('b', 1)
304
+ >>> Version("1.2.3rc1").pre
305
+ ('rc', 1)
306
+ """
307
+ return self._version.pre
308
+
309
+ @property
310
+ def post(self) -> int | None:
311
+ """The post-release number of the version.
312
+
313
+ >>> print(Version("1.2.3").post)
314
+ None
315
+ >>> Version("1.2.3.post1").post
316
+ 1
317
+ """
318
+ return self._version.post[1] if self._version.post else None
319
+
320
+ @property
321
+ def dev(self) -> int | None:
322
+ """The development number of the version.
323
+
324
+ >>> print(Version("1.2.3").dev)
325
+ None
326
+ >>> Version("1.2.3.dev1").dev
327
+ 1
328
+ """
329
+ return self._version.dev[1] if self._version.dev else None
330
+
331
+ @property
332
+ def local(self) -> str | None:
333
+ """The local version segment of the version.
334
+
335
+ >>> print(Version("1.2.3").local)
336
+ None
337
+ >>> Version("1.2.3+abc").local
338
+ 'abc'
339
+ """
340
+ if self._version.local:
341
+ return ".".join(str(x) for x in self._version.local)
342
+ else:
343
+ return None
344
+
345
+ @property
346
+ def public(self) -> str:
347
+ """The public portion of the version.
348
+
349
+ >>> Version("1.2.3").public
350
+ '1.2.3'
351
+ >>> Version("1.2.3+abc").public
352
+ '1.2.3'
353
+ >>> Version("1!1.2.3dev1+abc").public
354
+ '1!1.2.3.dev1'
355
+ """
356
+ return str(self).split("+", 1)[0]
357
+
358
+ @property
359
+ def base_version(self) -> str:
360
+ """The "base version" of the version.
361
+
362
+ >>> Version("1.2.3").base_version
363
+ '1.2.3'
364
+ >>> Version("1.2.3+abc").base_version
365
+ '1.2.3'
366
+ >>> Version("1!1.2.3dev1+abc").base_version
367
+ '1!1.2.3'
368
+
369
+ The "base version" is the public version of the project without any pre or post
370
+ release markers.
371
+ """
372
+ parts = []
373
+
374
+ # Epoch
375
+ if self.epoch != 0:
376
+ parts.append(f"{self.epoch}!")
377
+
378
+ # Release segment
379
+ parts.append(".".join(str(x) for x in self.release))
380
+
381
+ return "".join(parts)
382
+
383
+ @property
384
+ def is_prerelease(self) -> bool:
385
+ """Whether this version is a pre-release.
386
+
387
+ >>> Version("1.2.3").is_prerelease
388
+ False
389
+ >>> Version("1.2.3a1").is_prerelease
390
+ True
391
+ >>> Version("1.2.3b1").is_prerelease
392
+ True
393
+ >>> Version("1.2.3rc1").is_prerelease
394
+ True
395
+ >>> Version("1.2.3dev1").is_prerelease
396
+ True
397
+ """
398
+ return self.dev is not None or self.pre is not None
399
+
400
+ @property
401
+ def is_postrelease(self) -> bool:
402
+ """Whether this version is a post-release.
403
+
404
+ >>> Version("1.2.3").is_postrelease
405
+ False
406
+ >>> Version("1.2.3.post1").is_postrelease
407
+ True
408
+ """
409
+ return self.post is not None
410
+
411
+ @property
412
+ def is_devrelease(self) -> bool:
413
+ """Whether this version is a development release.
414
+
415
+ >>> Version("1.2.3").is_devrelease
416
+ False
417
+ >>> Version("1.2.3.dev1").is_devrelease
418
+ True
419
+ """
420
+ return self.dev is not None
421
+
422
+ @property
423
+ def major(self) -> int:
424
+ """The first item of :attr:`release` or ``0`` if unavailable.
425
+
426
+ >>> Version("1.2.3").major
427
+ 1
428
+ """
429
+ return self.release[0] if len(self.release) >= 1 else 0
430
+
431
+ @property
432
+ def minor(self) -> int:
433
+ """The second item of :attr:`release` or ``0`` if unavailable.
434
+
435
+ >>> Version("1.2.3").minor
436
+ 2
437
+ >>> Version("1").minor
438
+ 0
439
+ """
440
+ return self.release[1] if len(self.release) >= 2 else 0
441
+
442
+ @property
443
+ def micro(self) -> int:
444
+ """The third item of :attr:`release` or ``0`` if unavailable.
445
+
446
+ >>> Version("1.2.3").micro
447
+ 3
448
+ >>> Version("1").micro
449
+ 0
450
+ """
451
+ return self.release[2] if len(self.release) >= 3 else 0
452
+
453
+
454
+ class _TrimmedRelease(Version):
455
+ @property
456
+ def release(self) -> tuple[int, ...]:
457
+ """
458
+ Release segment without any trailing zeros.
459
+
460
+ >>> _TrimmedRelease('1.0.0').release
461
+ (1,)
462
+ >>> _TrimmedRelease('0.0').release
463
+ (0,)
464
+ """
465
+ rel = super().release
466
+ nonzeros = (index for index, val in enumerate(rel) if val)
467
+ last_nonzero = max(nonzeros, default=0)
468
+ return rel[: last_nonzero + 1]
469
+
470
+
471
+ def _parse_letter_version(
472
+ letter: str | None, number: str | bytes | SupportsInt | None
473
+ ) -> tuple[str, int] | None:
474
+ if letter:
475
+ # We consider there to be an implicit 0 in a pre-release if there is
476
+ # not a numeral associated with it.
477
+ if number is None:
478
+ number = 0
479
+
480
+ # We normalize any letters to their lower case form
481
+ letter = letter.lower()
482
+
483
+ # We consider some words to be alternate spellings of other words and
484
+ # in those cases we want to normalize the spellings to our preferred
485
+ # spelling.
486
+ if letter == "alpha":
487
+ letter = "a"
488
+ elif letter == "beta":
489
+ letter = "b"
490
+ elif letter in ["c", "pre", "preview"]:
491
+ letter = "rc"
492
+ elif letter in ["rev", "r"]:
493
+ letter = "post"
494
+
495
+ return letter, int(number)
496
+
497
+ assert not letter
498
+ if number:
499
+ # We assume if we are given a number, but we are not given a letter
500
+ # then this is using the implicit post release syntax (e.g. 1.0-1)
501
+ letter = "post"
502
+
503
+ return letter, int(number)
504
+
505
+ return None
506
+
507
+
508
+ _local_version_separators = re.compile(r"[\._-]")
509
+
510
+
511
+ def _parse_local_version(local: str | None) -> LocalType | None:
512
+ """
513
+ Takes a string like abc.1.twelve and turns it into ("abc", 1, "twelve").
514
+ """
515
+ if local is not None:
516
+ return tuple(
517
+ part.lower() if not part.isdigit() else int(part)
518
+ for part in _local_version_separators.split(local)
519
+ )
520
+ return None
521
+
522
+
523
+ def _cmpkey(
524
+ epoch: int,
525
+ release: tuple[int, ...],
526
+ pre: tuple[str, int] | None,
527
+ post: tuple[str, int] | None,
528
+ dev: tuple[str, int] | None,
529
+ local: LocalType | None,
530
+ ) -> CmpKey:
531
+ # When we compare a release version, we want to compare it with all of the
532
+ # trailing zeros removed. So we'll use a reverse the list, drop all the now
533
+ # leading zeros until we come to something non zero, then take the rest
534
+ # re-reverse it back into the correct order and make it a tuple and use
535
+ # that for our sorting key.
536
+ _release = tuple(
537
+ reversed(list(itertools.dropwhile(lambda x: x == 0, reversed(release))))
538
+ )
539
+
540
+ # We need to "trick" the sorting algorithm to put 1.0.dev0 before 1.0a0.
541
+ # We'll do this by abusing the pre segment, but we _only_ want to do this
542
+ # if there is not a pre or a post segment. If we have one of those then
543
+ # the normal sorting rules will handle this case correctly.
544
+ if pre is None and post is None and dev is not None:
545
+ _pre: CmpPrePostDevType = NegativeInfinity
546
+ # Versions without a pre-release (except as noted above) should sort after
547
+ # those with one.
548
+ elif pre is None:
549
+ _pre = Infinity
550
+ else:
551
+ _pre = pre
552
+
553
+ # Versions without a post segment should sort before those with one.
554
+ if post is None:
555
+ _post: CmpPrePostDevType = NegativeInfinity
556
+
557
+ else:
558
+ _post = post
559
+
560
+ # Versions without a development segment should sort after those with one.
561
+ if dev is None:
562
+ _dev: CmpPrePostDevType = Infinity
563
+
564
+ else:
565
+ _dev = dev
566
+
567
+ if local is None:
568
+ # Versions without a local segment should sort before those with one.
569
+ _local: CmpLocalType = NegativeInfinity
570
+ else:
571
+ # Versions with a local segment need that segment parsed to implement
572
+ # the sorting rules in PEP440.
573
+ # - Alpha numeric segments sort before numeric segments
574
+ # - Alpha numeric segments sort lexicographically
575
+ # - Numeric segments sort numerically
576
+ # - Shorter versions sort before longer versions when the prefixes
577
+ # match exactly
578
+ _local = tuple(
579
+ (i, "") if isinstance(i, int) else (NegativeInfinity, i) for i in local
580
+ )
581
+
582
+ return epoch, _release, _pre, _post, _dev, _local
lib/python3.12/site-packages/pip-25.0.1.dist-info/AUTHORS.txt ADDED
@@ -0,0 +1,806 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @Switch01
2
+ A_Rog
3
+ Aakanksha Agrawal
4
+ Abhinav Sagar
5
+ ABHYUDAY PRATAP SINGH
6
+ abs51295
7
+ AceGentile
8
+ Adam Chainz
9
+ Adam Tse
10
+ Adam Wentz
11
+ admin
12
+ Adolfo Ochagavía
13
+ Adrien Morison
14
+ Agus
15
+ ahayrapetyan
16
+ Ahilya
17
+ AinsworthK
18
+ Akash Srivastava
19
+ Alan Yee
20
+ Albert Tugushev
21
+ Albert-Guan
22
+ albertg
23
+ Alberto Sottile
24
+ Aleks Bunin
25
+ Ales Erjavec
26
+ Alethea Flowers
27
+ Alex Gaynor
28
+ Alex Grönholm
29
+ Alex Hedges
30
+ Alex Loosley
31
+ Alex Morega
32
+ Alex Stachowiak
33
+ Alexander Shtyrov
34
+ Alexandre Conrad
35
+ Alexey Popravka
36
+ Aleš Erjavec
37
+ Alli
38
+ Ami Fischman
39
+ Ananya Maiti
40
+ Anatoly Techtonik
41
+ Anders Kaseorg
42
+ Andre Aguiar
43
+ Andreas Lutro
44
+ Andrei Geacar
45
+ Andrew Gaul
46
+ Andrew Shymanel
47
+ Andrey Bienkowski
48
+ Andrey Bulgakov
49
+ Andrés Delfino
50
+ Andy Freeland
51
+ Andy Kluger
52
+ Ani Hayrapetyan
53
+ Aniruddha Basak
54
+ Anish Tambe
55
+ Anrs Hu
56
+ Anthony Sottile
57
+ Antoine Musso
58
+ Anton Ovchinnikov
59
+ Anton Patrushev
60
+ Anton Zelenov
61
+ Antonio Alvarado Hernandez
62
+ Antony Lee
63
+ Antti Kaihola
64
+ Anubhav Patel
65
+ Anudit Nagar
66
+ Anuj Godase
67
+ AQNOUCH Mohammed
68
+ AraHaan
69
+ arena
70
+ arenasys
71
+ Arindam Choudhury
72
+ Armin Ronacher
73
+ Arnon Yaari
74
+ Artem
75
+ Arun Babu Neelicattu
76
+ Ashley Manton
77
+ Ashwin Ramaswami
78
+ atse
79
+ Atsushi Odagiri
80
+ Avinash Karhana
81
+ Avner Cohen
82
+ Awit (Ah-Wit) Ghirmai
83
+ Baptiste Mispelon
84
+ Barney Gale
85
+ barneygale
86
+ Bartek Ogryczak
87
+ Bastian Venthur
88
+ Ben Bodenmiller
89
+ Ben Darnell
90
+ Ben Hoyt
91
+ Ben Mares
92
+ Ben Rosser
93
+ Bence Nagy
94
+ Benjamin Peterson
95
+ Benjamin VanEvery
96
+ Benoit Pierre
97
+ Berker Peksag
98
+ Bernard
99
+ Bernard Tyers
100
+ Bernardo B. Marques
101
+ Bernhard M. Wiedemann
102
+ Bertil Hatt
103
+ Bhavam Vidyarthi
104
+ Blazej Michalik
105
+ Bogdan Opanchuk
106
+ BorisZZZ
107
+ Brad Erickson
108
+ Bradley Ayers
109
+ Branch Vincent
110
+ Brandon L. Reiss
111
+ Brandt Bucher
112
+ Brannon Dorsey
113
+ Brett Randall
114
+ Brett Rosen
115
+ Brian Cristante
116
+ Brian Rosner
117
+ briantracy
118
+ BrownTruck
119
+ Bruno Oliveira
120
+ Bruno Renié
121
+ Bruno S
122
+ Bstrdsmkr
123
+ Buck Golemon
124
+ burrows
125
+ Bussonnier Matthias
126
+ bwoodsend
127
+ c22
128
+ Caleb Brown
129
+ Caleb Martinez
130
+ Calvin Smith
131
+ Carl Meyer
132
+ Carlos Liam
133
+ Carol Willing
134
+ Carter Thayer
135
+ Cass
136
+ Chandrasekhar Atina
137
+ Charlie Marsh
138
+ charwick
139
+ Chih-Hsuan Yen
140
+ Chris Brinker
141
+ Chris Hunt
142
+ Chris Jerdonek
143
+ Chris Kuehl
144
+ Chris Markiewicz
145
+ Chris McDonough
146
+ Chris Pawley
147
+ Chris Pryer
148
+ Chris Wolfe
149
+ Christian Clauss
150
+ Christian Heimes
151
+ Christian Oudard
152
+ Christoph Reiter
153
+ Christopher Hunt
154
+ Christopher Snyder
155
+ chrysle
156
+ cjc7373
157
+ Clark Boylan
158
+ Claudio Jolowicz
159
+ Clay McClure
160
+ Cody
161
+ Cody Soyland
162
+ Colin Watson
163
+ Collin Anderson
164
+ Connor Osborn
165
+ Cooper Lees
166
+ Cooper Ry Lees
167
+ Cory Benfield
168
+ Cory Wright
169
+ Craig Kerstiens
170
+ Cristian Sorinel
171
+ Cristina
172
+ Cristina Muñoz
173
+ ctg123
174
+ Curtis Doty
175
+ cytolentino
176
+ Daan De Meyer
177
+ Dale
178
+ Damian
179
+ Damian Quiroga
180
+ Damian Shaw
181
+ Dan Black
182
+ Dan Savilonis
183
+ Dan Sully
184
+ Dane Hillard
185
+ daniel
186
+ Daniel Collins
187
+ Daniel Hahler
188
+ Daniel Holth
189
+ Daniel Jost
190
+ Daniel Katz
191
+ Daniel Shaulov
192
+ Daniele Esposti
193
+ Daniele Nicolodi
194
+ Daniele Procida
195
+ Daniil Konovalenko
196
+ Danny Hermes
197
+ Danny McClanahan
198
+ Darren Kavanagh
199
+ Dav Clark
200
+ Dave Abrahams
201
+ Dave Jones
202
+ David Aguilar
203
+ David Black
204
+ David Bordeynik
205
+ David Caro
206
+ David D Lowe
207
+ David Evans
208
+ David Hewitt
209
+ David Linke
210
+ David Poggi
211
+ David Poznik
212
+ David Pursehouse
213
+ David Runge
214
+ David Tucker
215
+ David Wales
216
+ Davidovich
217
+ ddelange
218
+ Deepak Sharma
219
+ Deepyaman Datta
220
+ Denise Yu
221
+ dependabot[bot]
222
+ derwolfe
223
+ Desetude
224
+ Devesh Kumar Singh
225
+ devsagul
226
+ Diego Caraballo
227
+ Diego Ramirez
228
+ DiegoCaraballo
229
+ Dimitri Merejkowsky
230
+ Dimitri Papadopoulos
231
+ Dimitri Papadopoulos Orfanos
232
+ Dirk Stolle
233
+ Dmitry Gladkov
234
+ Dmitry Volodin
235
+ Domen Kožar
236
+ Dominic Davis-Foster
237
+ Donald Stufft
238
+ Dongweiming
239
+ doron zarhi
240
+ Dos Moonen
241
+ Douglas Thor
242
+ DrFeathers
243
+ Dustin Ingram
244
+ Dustin Rodrigues
245
+ Dwayne Bailey
246
+ Ed Morley
247
+ Edgar Ramírez
248
+ Edgar Ramírez Mondragón
249
+ Ee Durbin
250
+ Efflam Lemaillet
251
+ efflamlemaillet
252
+ Eitan Adler
253
+ ekristina
254
+ elainechan
255
+ Eli Schwartz
256
+ Elisha Hollander
257
+ Ellen Marie Dash
258
+ Emil Burzo
259
+ Emil Styrke
260
+ Emmanuel Arias
261
+ Endoh Takanao
262
+ enoch
263
+ Erdinc Mutlu
264
+ Eric Cousineau
265
+ Eric Gillingham
266
+ Eric Hanchrow
267
+ Eric Hopper
268
+ Erik M. Bray
269
+ Erik Rose
270
+ Erwin Janssen
271
+ Eugene Vereshchagin
272
+ everdimension
273
+ Federico
274
+ Felipe Peter
275
+ Felix Yan
276
+ fiber-space
277
+ Filip Kokosiński
278
+ Filipe Laíns
279
+ Finn Womack
280
+ finnagin
281
+ Flavio Amurrio
282
+ Florian Briand
283
+ Florian Rathgeber
284
+ Francesco
285
+ Francesco Montesano
286
+ Fredrik Orderud
287
+ Frost Ming
288
+ Gabriel Curio
289
+ Gabriel de Perthuis
290
+ Garry Polley
291
+ gavin
292
+ gdanielson
293
+ Geoffrey Sneddon
294
+ George Song
295
+ Georgi Valkov
296
+ Georgy Pchelkin
297
+ ghost
298
+ Giftlin Rajaiah
299
+ gizmoguy1
300
+ gkdoc
301
+ Godefroid Chapelle
302
+ Gopinath M
303
+ GOTO Hayato
304
+ gousaiyang
305
+ gpiks
306
+ Greg Roodt
307
+ Greg Ward
308
+ Guilherme Espada
309
+ Guillaume Seguin
310
+ gutsytechster
311
+ Guy Rozendorn
312
+ Guy Tuval
313
+ gzpan123
314
+ Hanjun Kim
315
+ Hari Charan
316
+ Harsh Vardhan
317
+ harupy
318
+ Harutaka Kawamura
319
+ hauntsaninja
320
+ Henrich Hartzer
321
+ Henry Schreiner
322
+ Herbert Pfennig
323
+ Holly Stotelmyer
324
+ Honnix
325
+ Hsiaoming Yang
326
+ Hugo Lopes Tavares
327
+ Hugo van Kemenade
328
+ Hugues Bruant
329
+ Hynek Schlawack
330
+ Ian Bicking
331
+ Ian Cordasco
332
+ Ian Lee
333
+ Ian Stapleton Cordasco
334
+ Ian Wienand
335
+ Igor Kuzmitshov
336
+ Igor Sobreira
337
+ Ikko Ashimine
338
+ Ilan Schnell
339
+ Illia Volochii
340
+ Ilya Baryshev
341
+ Inada Naoki
342
+ Ionel Cristian Mărieș
343
+ Ionel Maries Cristian
344
+ Itamar Turner-Trauring
345
+ Ivan Pozdeev
346
+ J. Nick Koston
347
+ Jacob Kim
348
+ Jacob Walls
349
+ Jaime Sanz
350
+ jakirkham
351
+ Jakub Kuczys
352
+ Jakub Stasiak
353
+ Jakub Vysoky
354
+ Jakub Wilk
355
+ James Cleveland
356
+ James Curtin
357
+ James Firth
358
+ James Gerity
359
+ James Polley
360
+ Jan Pokorný
361
+ Jannis Leidel
362
+ Jarek Potiuk
363
+ jarondl
364
+ Jason Curtis
365
+ Jason R. Coombs
366
+ JasonMo
367
+ JasonMo1
368
+ Jay Graves
369
+ Jean Abou Samra
370
+ Jean-Christophe Fillion-Robin
371
+ Jeff Barber
372
+ Jeff Dairiki
373
+ Jeff Widman
374
+ Jelmer Vernooij
375
+ jenix21
376
+ Jeremy Fleischman
377
+ Jeremy Stanley
378
+ Jeremy Zafran
379
+ Jesse Rittner
380
+ Jiashuo Li
381
+ Jim Fisher
382
+ Jim Garrison
383
+ Jinzhe Zeng
384
+ Jiun Bae
385
+ Jivan Amara
386
+ Joe Bylund
387
+ Joe Michelini
388
+ John Paton
389
+ John Sirois
390
+ John T. Wodder II
391
+ John-Scott Atlakson
392
+ johnthagen
393
+ Jon Banafato
394
+ Jon Dufresne
395
+ Jon Parise
396
+ Jonas Nockert
397
+ Jonathan Herbert
398
+ Joonatan Partanen
399
+ Joost Molenaar
400
+ Jorge Niedbalski
401
+ Joseph Bylund
402
+ Joseph Long
403
+ Josh Bronson
404
+ Josh Cannon
405
+ Josh Hansen
406
+ Josh Schneier
407
+ Joshua
408
+ JoshuaPerdue
409
+ Juan Luis Cano Rodríguez
410
+ Juanjo Bazán
411
+ Judah Rand
412
+ Julian Berman
413
+ Julian Gethmann
414
+ Julien Demoor
415
+ July Tikhonov
416
+ Jussi Kukkonen
417
+ Justin van Heek
418
+ jwg4
419
+ Jyrki Pulliainen
420
+ Kai Chen
421
+ Kai Mueller
422
+ Kamal Bin Mustafa
423
+ Karolina Surma
424
+ kasium
425
+ kaustav haldar
426
+ keanemind
427
+ Keith Maxwell
428
+ Kelsey Hightower
429
+ Kenneth Belitzky
430
+ Kenneth Reitz
431
+ Kevin Burke
432
+ Kevin Carter
433
+ Kevin Frommelt
434
+ Kevin R Patterson
435
+ Kexuan Sun
436
+ Kit Randel
437
+ Klaas van Schelven
438
+ KOLANICH
439
+ konstin
440
+ kpinc
441
+ Krishna Oza
442
+ Kumar McMillan
443
+ Kuntal Majumder
444
+ Kurt McKee
445
+ Kyle Persohn
446
+ lakshmanaram
447
+ Laszlo Kiss-Kollar
448
+ Laurent Bristiel
449
+ Laurent LAPORTE
450
+ Laurie O
451
+ Laurie Opperman
452
+ layday
453
+ Leon Sasson
454
+ Lev Givon
455
+ Lincoln de Sousa
456
+ Lipis
457
+ lorddavidiii
458
+ Loren Carvalho
459
+ Lucas Cimon
460
+ Ludovic Gasc
461
+ Luis Medel
462
+ Lukas Geiger
463
+ Lukas Juhrich
464
+ Luke Macken
465
+ Luo Jiebin
466
+ luojiebin
467
+ luz.paz
468
+ László Kiss Kollár
469
+ M00nL1ght
470
+ Marc Abramowitz
471
+ Marc Tamlyn
472
+ Marcus Smith
473
+ Mariatta
474
+ Mark Kohler
475
+ Mark McLoughlin
476
+ Mark Williams
477
+ Markus Hametner
478
+ Martey Dodoo
479
+ Martin Fischer
480
+ Martin Häcker
481
+ Martin Pavlasek
482
+ Masaki
483
+ Masklinn
484
+ Matej Stuchlik
485
+ Mathew Jennings
486
+ Mathieu Bridon
487
+ Mathieu Kniewallner
488
+ Matt Bacchi
489
+ Matt Good
490
+ Matt Maker
491
+ Matt Robenolt
492
+ Matt Wozniski
493
+ matthew
494
+ Matthew Einhorn
495
+ Matthew Feickert
496
+ Matthew Gilliard
497
+ Matthew Hughes
498
+ Matthew Iversen
499
+ Matthew Treinish
500
+ Matthew Trumbell
501
+ Matthew Willson
502
+ Matthias Bussonnier
503
+ mattip
504
+ Maurits van Rees
505
+ Max W Chase
506
+ Maxim Kurnikov
507
+ Maxime Rouyrre
508
+ mayeut
509
+ mbaluna
510
+ mdebi
511
+ memoselyk
512
+ meowmeowcat
513
+ Michael
514
+ Michael Aquilina
515
+ Michael E. Karpeles
516
+ Michael Klich
517
+ Michael Mintz
518
+ Michael Williamson
519
+ michaelpacer
520
+ Michał Górny
521
+ Mickaël Schoentgen
522
+ Miguel Araujo Perez
523
+ Mihir Singh
524
+ Mike
525
+ Mike Hendricks
526
+ Min RK
527
+ MinRK
528
+ Miro Hrončok
529
+ Monica Baluna
530
+ montefra
531
+ Monty Taylor
532
+ morotti
533
+ mrKazzila
534
+ Muha Ajjan
535
+ Nadav Wexler
536
+ Nahuel Ambrosini
537
+ Nate Coraor
538
+ Nate Prewitt
539
+ Nathan Houghton
540
+ Nathaniel J. Smith
541
+ Nehal J Wani
542
+ Neil Botelho
543
+ Nguyễn Gia Phong
544
+ Nicholas Serra
545
+ Nick Coghlan
546
+ Nick Stenning
547
+ Nick Timkovich
548
+ Nicolas Bock
549
+ Nicole Harris
550
+ Nikhil Benesch
551
+ Nikhil Ladha
552
+ Nikita Chepanov
553
+ Nikolay Korolev
554
+ Nipunn Koorapati
555
+ Nitesh Sharma
556
+ Niyas Sait
557
+ Noah
558
+ Noah Gorny
559
+ Nowell Strite
560
+ NtaleGrey
561
+ nvdv
562
+ OBITORASU
563
+ Ofek Lev
564
+ ofrinevo
565
+ Oliver Freund
566
+ Oliver Jeeves
567
+ Oliver Mannion
568
+ Oliver Tonnhofer
569
+ Olivier Girardot
570
+ Olivier Grisel
571
+ Ollie Rutherfurd
572
+ OMOTO Kenji
573
+ Omry Yadan
574
+ onlinejudge95
575
+ Oren Held
576
+ Oscar Benjamin
577
+ Oz N Tiram
578
+ Pachwenko
579
+ Patrick Dubroy
580
+ Patrick Jenkins
581
+ Patrick Lawson
582
+ patricktokeeffe
583
+ Patrik Kopkan
584
+ Paul Ganssle
585
+ Paul Kehrer
586
+ Paul Moore
587
+ Paul Nasrat
588
+ Paul Oswald
589
+ Paul van der Linden
590
+ Paulus Schoutsen
591
+ Pavel Safronov
592
+ Pavithra Eswaramoorthy
593
+ Pawel Jasinski
594
+ Paweł Szramowski
595
+ Pekka Klärck
596
+ Peter Gessler
597
+ Peter Lisák
598
+ Peter Shen
599
+ Peter Waller
600
+ Petr Viktorin
601
+ petr-tik
602
+ Phaneendra Chiruvella
603
+ Phil Elson
604
+ Phil Freo
605
+ Phil Pennock
606
+ Phil Whelan
607
+ Philip Jägenstedt
608
+ Philip Molloy
609
+ Philippe Ombredanne
610
+ Pi Delport
611
+ Pierre-Yves Rofes
612
+ Pieter Degroote
613
+ pip
614
+ Prabakaran Kumaresshan
615
+ Prabhjyotsing Surjit Singh Sodhi
616
+ Prabhu Marappan
617
+ Pradyun Gedam
618
+ Prashant Sharma
619
+ Pratik Mallya
620
+ pre-commit-ci[bot]
621
+ Preet Thakkar
622
+ Preston Holmes
623
+ Przemek Wrzos
624
+ Pulkit Goyal
625
+ q0w
626
+ Qiangning Hong
627
+ Qiming Xu
628
+ Quentin Lee
629
+ Quentin Pradet
630
+ R. David Murray
631
+ Rafael Caricio
632
+ Ralf Schmitt
633
+ Ran Benita
634
+ Randy Döring
635
+ Razzi Abuissa
636
+ rdb
637
+ Reece Dunham
638
+ Remi Rampin
639
+ Rene Dudfield
640
+ Riccardo Magliocchetti
641
+ Riccardo Schirone
642
+ Richard Jones
643
+ Richard Si
644
+ Ricky Ng-Adam
645
+ Rishi
646
+ rmorotti
647
+ RobberPhex
648
+ Robert Collins
649
+ Robert McGibbon
650
+ Robert Pollak
651
+ Robert T. McGibbon
652
+ robin elisha robinson
653
+ Roey Berman
654
+ Rohan Jain
655
+ Roman Bogorodskiy
656
+ Roman Donchenko
657
+ Romuald Brunet
658
+ ronaudinho
659
+ Ronny Pfannschmidt
660
+ Rory McCann
661
+ Ross Brattain
662
+ Roy Wellington Ⅳ
663
+ Ruairidh MacLeod
664
+ Russell Keith-Magee
665
+ Ryan Shepherd
666
+ Ryan Wooden
667
+ ryneeverett
668
+ S. Guliaev
669
+ Sachi King
670
+ Salvatore Rinchiera
671
+ sandeepkiran-js
672
+ Sander Van Balen
673
+ Savio Jomton
674
+ schlamar
675
+ Scott Kitterman
676
+ Sean
677
+ seanj
678
+ Sebastian Jordan
679
+ Sebastian Schaetz
680
+ Segev Finer
681
+ SeongSoo Cho
682
+ Sergey Vasilyev
683
+ Seth Michael Larson
684
+ Seth Woodworth
685
+ Shahar Epstein
686
+ Shantanu
687
+ shenxianpeng
688
+ shireenrao
689
+ Shivansh-007
690
+ Shixian Sheng
691
+ Shlomi Fish
692
+ Shovan Maity
693
+ Simeon Visser
694
+ Simon Cross
695
+ Simon Pichugin
696
+ sinoroc
697
+ sinscary
698
+ snook92
699
+ socketubs
700
+ Sorin Sbarnea
701
+ Srinivas Nyayapati
702
+ Srishti Hegde
703
+ Stavros Korokithakis
704
+ Stefan Scherfke
705
+ Stefano Rivera
706
+ Stephan Erb
707
+ Stephen Rosen
708
+ stepshal
709
+ Steve (Gadget) Barnes
710
+ Steve Barnes
711
+ Steve Dower
712
+ Steve Kowalik
713
+ Steven Myint
714
+ Steven Silvester
715
+ stonebig
716
+ studioj
717
+ Stéphane Bidoul
718
+ Stéphane Bidoul (ACSONE)
719
+ Stéphane Klein
720
+ Sumana Harihareswara
721
+ Surbhi Sharma
722
+ Sviatoslav Sydorenko
723
+ Sviatoslav Sydorenko (Святослав Сидоренко)
724
+ Swat009
725
+ Sylvain
726
+ Takayuki SHIMIZUKAWA
727
+ Taneli Hukkinen
728
+ tbeswick
729
+ Thiago
730
+ Thijs Triemstra
731
+ Thomas Fenzl
732
+ Thomas Grainger
733
+ Thomas Guettler
734
+ Thomas Johansson
735
+ Thomas Kluyver
736
+ Thomas Smith
737
+ Thomas VINCENT
738
+ Tim D. Smith
739
+ Tim Gates
740
+ Tim Harder
741
+ Tim Heap
742
+ tim smith
743
+ tinruufu
744
+ Tobias Hermann
745
+ Tom Forbes
746
+ Tom Freudenheim
747
+ Tom V
748
+ Tomas Hrnciar
749
+ Tomas Orsava
750
+ Tomer Chachamu
751
+ Tommi Enenkel | AnB
752
+ Tomáš Hrnčiar
753
+ Tony Beswick
754
+ Tony Narlock
755
+ Tony Zhaocheng Tan
756
+ TonyBeswick
757
+ toonarmycaptain
758
+ Toshio Kuratomi
759
+ toxinu
760
+ Travis Swicegood
761
+ Tushar Sadhwani
762
+ Tzu-ping Chung
763
+ Valentin Haenel
764
+ Victor Stinner
765
+ victorvpaulo
766
+ Vikram - Google
767
+ Viktor Szépe
768
+ Ville Skyttä
769
+ Vinay Sajip
770
+ Vincent Philippon
771
+ Vinicyus Macedo
772
+ Vipul Kumar
773
+ Vitaly Babiy
774
+ Vladimir Fokow
775
+ Vladimir Rutsky
776
+ W. Trevor King
777
+ Wil Tan
778
+ Wilfred Hughes
779
+ William Edwards
780
+ William ML Leslie
781
+ William T Olson
782
+ William Woodruff
783
+ Wilson Mo
784
+ wim glenn
785
+ Winson Luk
786
+ Wolfgang Maier
787
+ Wu Zhenyu
788
+ XAMES3
789
+ Xavier Fernandez
790
+ Xianpeng Shen
791
+ xoviat
792
+ xtreak
793
+ YAMAMOTO Takashi
794
+ Yen Chi Hsuan
795
+ Yeray Diaz Diaz
796
+ Yoval P
797
+ Yu Jian
798
+ Yuan Jing Vincent Yan
799
+ Yusuke Hayashi
800
+ Zearin
801
+ Zhiping Deng
802
+ ziebam
803
+ Zvezdan Petkovic
804
+ Łukasz Langa
805
+ Роман Донченко
806
+ Семён Марьясин
lib/python3.12/site-packages/pip-25.0.1.dist-info/INSTALLER ADDED
@@ -0,0 +1 @@
 
 
1
+ pip
lib/python3.12/site-packages/pip-25.0.1.dist-info/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (c) 2008-present The pip developers (see AUTHORS.txt file)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
lib/python3.12/site-packages/pip-25.0.1.dist-info/METADATA ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Metadata-Version: 2.2
2
+ Name: pip
3
+ Version: 25.0.1
4
+ Summary: The PyPA recommended tool for installing Python packages.
5
+ Author-email: The pip developers <distutils-sig@python.org>
6
+ License: MIT
7
+ Project-URL: Homepage, https://pip.pypa.io/
8
+ Project-URL: Documentation, https://pip.pypa.io
9
+ Project-URL: Source, https://github.com/pypa/pip
10
+ Project-URL: Changelog, https://pip.pypa.io/en/stable/news/
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Topic :: Software Development :: Build Tools
15
+ Classifier: Programming Language :: Python
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3 :: Only
18
+ Classifier: Programming Language :: Python :: 3.8
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Programming Language :: Python :: Implementation :: CPython
25
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
26
+ Requires-Python: >=3.8
27
+ Description-Content-Type: text/x-rst
28
+ License-File: LICENSE.txt
29
+ License-File: AUTHORS.txt
30
+
31
+ pip - The Python Package Installer
32
+ ==================================
33
+
34
+ .. |pypi-version| image:: https://img.shields.io/pypi/v/pip.svg
35
+ :target: https://pypi.org/project/pip/
36
+ :alt: PyPI
37
+
38
+ .. |python-versions| image:: https://img.shields.io/pypi/pyversions/pip
39
+ :target: https://pypi.org/project/pip
40
+ :alt: PyPI - Python Version
41
+
42
+ .. |docs-badge| image:: https://readthedocs.org/projects/pip/badge/?version=latest
43
+ :target: https://pip.pypa.io/en/latest
44
+ :alt: Documentation
45
+
46
+ |pypi-version| |python-versions| |docs-badge|
47
+
48
+ pip is the `package installer`_ for Python. You can use pip to install packages from the `Python Package Index`_ and other indexes.
49
+
50
+ Please take a look at our documentation for how to install and use pip:
51
+
52
+ * `Installation`_
53
+ * `Usage`_
54
+
55
+ We release updates regularly, with a new version every 3 months. Find more details in our documentation:
56
+
57
+ * `Release notes`_
58
+ * `Release process`_
59
+
60
+ If you find bugs, need help, or want to talk to the developers, please use our mailing lists or chat rooms:
61
+
62
+ * `Issue tracking`_
63
+ * `Discourse channel`_
64
+ * `User IRC`_
65
+
66
+ If you want to get involved head over to GitHub to get the source code, look at our development documentation and feel free to jump on the developer mailing lists and chat rooms:
67
+
68
+ * `GitHub page`_
69
+ * `Development documentation`_
70
+ * `Development IRC`_
71
+
72
+ Code of Conduct
73
+ ---------------
74
+
75
+ Everyone interacting in the pip project's codebases, issue trackers, chat
76
+ rooms, and mailing lists is expected to follow the `PSF Code of Conduct`_.
77
+
78
+ .. _package installer: https://packaging.python.org/guides/tool-recommendations/
79
+ .. _Python Package Index: https://pypi.org
80
+ .. _Installation: https://pip.pypa.io/en/stable/installation/
81
+ .. _Usage: https://pip.pypa.io/en/stable/
82
+ .. _Release notes: https://pip.pypa.io/en/stable/news.html
83
+ .. _Release process: https://pip.pypa.io/en/latest/development/release-process/
84
+ .. _GitHub page: https://github.com/pypa/pip
85
+ .. _Development documentation: https://pip.pypa.io/en/latest/development
86
+ .. _Issue tracking: https://github.com/pypa/pip/issues
87
+ .. _Discourse channel: https://discuss.python.org/c/packaging
88
+ .. _User IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa
89
+ .. _Development IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa-dev
90
+ .. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md
lib/python3.12/site-packages/pip-25.0.1.dist-info/RECORD ADDED
@@ -0,0 +1,854 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ../../../bin/pip,sha256=DtWiF5XVBFx0GL9DgcTAnRKEChG_TADzYDEZLiZCMfQ,257
2
+ ../../../bin/pip3,sha256=DtWiF5XVBFx0GL9DgcTAnRKEChG_TADzYDEZLiZCMfQ,257
3
+ ../../../bin/pip3.12,sha256=DtWiF5XVBFx0GL9DgcTAnRKEChG_TADzYDEZLiZCMfQ,257
4
+ pip-25.0.1.dist-info/AUTHORS.txt,sha256=HqzpBVLfT1lBthqQfiDlVeFkg65hJ7ZQvvWhoq-BAsA,11018
5
+ pip-25.0.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
6
+ pip-25.0.1.dist-info/LICENSE.txt,sha256=Y0MApmnUmurmWxLGxIySTFGkzfPR_whtw0VtyLyqIQQ,1093
7
+ pip-25.0.1.dist-info/METADATA,sha256=T6cxjPMPl523zsRcEsu8K0-IoV8S7vv1mmKR0KA6-SY,3677
8
+ pip-25.0.1.dist-info/RECORD,,
9
+ pip-25.0.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ pip-25.0.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
11
+ pip-25.0.1.dist-info/entry_points.txt,sha256=eeIjuzfnfR2PrhbjnbzFU6MnSS70kZLxwaHHq6M-bD0,87
12
+ pip-25.0.1.dist-info/top_level.txt,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
13
+ pip/__init__.py,sha256=aKiv_sTe7UbE7qmtCinJutFjqN0MndZQZ1fKLNwFFLE,357
14
+ pip/__main__.py,sha256=WzbhHXTbSE6gBY19mNN9m4s5o_365LOvTYSgqgbdBhE,854
15
+ pip/__pip-runner__.py,sha256=cPPWuJ6NK_k-GzfvlejLFgwzmYUROmpAR6QC3Q-vkXQ,1450
16
+ pip/__pycache__/__init__.cpython-312.pyc,,
17
+ pip/__pycache__/__main__.cpython-312.pyc,,
18
+ pip/__pycache__/__pip-runner__.cpython-312.pyc,,
19
+ pip/_internal/__init__.py,sha256=MfcoOluDZ8QMCFYal04IqOJ9q6m2V7a0aOsnI-WOxUo,513
20
+ pip/_internal/__pycache__/__init__.cpython-312.pyc,,
21
+ pip/_internal/__pycache__/build_env.cpython-312.pyc,,
22
+ pip/_internal/__pycache__/cache.cpython-312.pyc,,
23
+ pip/_internal/__pycache__/configuration.cpython-312.pyc,,
24
+ pip/_internal/__pycache__/exceptions.cpython-312.pyc,,
25
+ pip/_internal/__pycache__/main.cpython-312.pyc,,
26
+ pip/_internal/__pycache__/pyproject.cpython-312.pyc,,
27
+ pip/_internal/__pycache__/self_outdated_check.cpython-312.pyc,,
28
+ pip/_internal/__pycache__/wheel_builder.cpython-312.pyc,,
29
+ pip/_internal/build_env.py,sha256=Dv4UCClSg4uNaal_hL-trg5-zl3Is9CuIDxkChCkXF4,10700
30
+ pip/_internal/cache.py,sha256=Jb698p5PNigRtpW5o26wQNkkUv4MnQ94mc471wL63A0,10369
31
+ pip/_internal/cli/__init__.py,sha256=FkHBgpxxb-_gd6r1FjnNhfMOzAUYyXoXKJ6abijfcFU,132
32
+ pip/_internal/cli/__pycache__/__init__.cpython-312.pyc,,
33
+ pip/_internal/cli/__pycache__/autocompletion.cpython-312.pyc,,
34
+ pip/_internal/cli/__pycache__/base_command.cpython-312.pyc,,
35
+ pip/_internal/cli/__pycache__/cmdoptions.cpython-312.pyc,,
36
+ pip/_internal/cli/__pycache__/command_context.cpython-312.pyc,,
37
+ pip/_internal/cli/__pycache__/index_command.cpython-312.pyc,,
38
+ pip/_internal/cli/__pycache__/main.cpython-312.pyc,,
39
+ pip/_internal/cli/__pycache__/main_parser.cpython-312.pyc,,
40
+ pip/_internal/cli/__pycache__/parser.cpython-312.pyc,,
41
+ pip/_internal/cli/__pycache__/progress_bars.cpython-312.pyc,,
42
+ pip/_internal/cli/__pycache__/req_command.cpython-312.pyc,,
43
+ pip/_internal/cli/__pycache__/spinners.cpython-312.pyc,,
44
+ pip/_internal/cli/__pycache__/status_codes.cpython-312.pyc,,
45
+ pip/_internal/cli/autocompletion.py,sha256=Lli3Mr6aDNu7ZkJJFFvwD2-hFxNI6Avz8OwMyS5TVrs,6865
46
+ pip/_internal/cli/base_command.py,sha256=NZin6KMzW9NSYzKk4Tc8isb_TQYKR4CKd5j9mSm46PI,8625
47
+ pip/_internal/cli/cmdoptions.py,sha256=V3BB22F4_v_RkHaZ5onWnszhbBtjYZvNhbn9M0NO0HI,30116
48
+ pip/_internal/cli/command_context.py,sha256=RHgIPwtObh5KhMrd3YZTkl8zbVG-6Okml7YbFX4Ehg0,774
49
+ pip/_internal/cli/index_command.py,sha256=i_sgNlPmXC5iHUaY-dmmrHKKTgc5O4hWzisr5Al1rr0,5677
50
+ pip/_internal/cli/main.py,sha256=BDZef-bWe9g9Jpr4OVs4dDf-845HJsKw835T7AqEnAc,2817
51
+ pip/_internal/cli/main_parser.py,sha256=laDpsuBDl6kyfywp9eMMA9s84jfH2TJJn-vmL0GG90w,4338
52
+ pip/_internal/cli/parser.py,sha256=VCMtduzECUV87KaHNu-xJ-wLNL82yT3x16V4XBxOAqI,10825
53
+ pip/_internal/cli/progress_bars.py,sha256=9GcgusWtwfqou2zhAQp1XNbQHIDslqyyz9UwLzw7Jgc,2717
54
+ pip/_internal/cli/req_command.py,sha256=DqeFhmUMs6o6Ev8qawAcOoYNdAZsfyKS0MZI5jsJYwQ,12250
55
+ pip/_internal/cli/spinners.py,sha256=hIJ83GerdFgFCdobIA23Jggetegl_uC4Sp586nzFbPE,5118
56
+ pip/_internal/cli/status_codes.py,sha256=sEFHUaUJbqv8iArL3HAtcztWZmGOFX01hTesSytDEh0,116
57
+ pip/_internal/commands/__init__.py,sha256=5oRO9O3dM2vGuh0bFw4HOVletryrz5HHMmmPWwJrH9U,3882
58
+ pip/_internal/commands/__pycache__/__init__.cpython-312.pyc,,
59
+ pip/_internal/commands/__pycache__/cache.cpython-312.pyc,,
60
+ pip/_internal/commands/__pycache__/check.cpython-312.pyc,,
61
+ pip/_internal/commands/__pycache__/completion.cpython-312.pyc,,
62
+ pip/_internal/commands/__pycache__/configuration.cpython-312.pyc,,
63
+ pip/_internal/commands/__pycache__/debug.cpython-312.pyc,,
64
+ pip/_internal/commands/__pycache__/download.cpython-312.pyc,,
65
+ pip/_internal/commands/__pycache__/freeze.cpython-312.pyc,,
66
+ pip/_internal/commands/__pycache__/hash.cpython-312.pyc,,
67
+ pip/_internal/commands/__pycache__/help.cpython-312.pyc,,
68
+ pip/_internal/commands/__pycache__/index.cpython-312.pyc,,
69
+ pip/_internal/commands/__pycache__/inspect.cpython-312.pyc,,
70
+ pip/_internal/commands/__pycache__/install.cpython-312.pyc,,
71
+ pip/_internal/commands/__pycache__/list.cpython-312.pyc,,
72
+ pip/_internal/commands/__pycache__/search.cpython-312.pyc,,
73
+ pip/_internal/commands/__pycache__/show.cpython-312.pyc,,
74
+ pip/_internal/commands/__pycache__/uninstall.cpython-312.pyc,,
75
+ pip/_internal/commands/__pycache__/wheel.cpython-312.pyc,,
76
+ pip/_internal/commands/cache.py,sha256=IOezTicHjGE5sWdBx2nwPVgbjuJHM3s-BZEkpZLemuY,8107
77
+ pip/_internal/commands/check.py,sha256=Hr_4eiMd9cgVDgEvjtIdw915NmL7ROIWW8enkr8slPQ,2268
78
+ pip/_internal/commands/completion.py,sha256=HT4lD0bgsflHq2IDgYfiEdp7IGGtE7s6MgI3xn0VQEw,4287
79
+ pip/_internal/commands/configuration.py,sha256=n98enwp6y0b5G6fiRQjaZo43FlJKYve_daMhN-4BRNc,9766
80
+ pip/_internal/commands/debug.py,sha256=DNDRgE9YsKrbYzU0s3VKi8rHtKF4X13CJ_br_8PUXO0,6797
81
+ pip/_internal/commands/download.py,sha256=0qB0nys6ZEPsog451lDsjL5Bx7Z97t-B80oFZKhpzKM,5273
82
+ pip/_internal/commands/freeze.py,sha256=2Vt72BYTSm9rzue6d8dNzt8idxWK4Db6Hd-anq7GQ80,3203
83
+ pip/_internal/commands/hash.py,sha256=EVVOuvGtoPEdFi8SNnmdqlCQrhCxV-kJsdwtdcCnXGQ,1703
84
+ pip/_internal/commands/help.py,sha256=gcc6QDkcgHMOuAn5UxaZwAStsRBrnGSn_yxjS57JIoM,1132
85
+ pip/_internal/commands/index.py,sha256=RAXxmJwFhVb5S1BYzb5ifX3sn9Na8v2CCVYwSMP8pao,4731
86
+ pip/_internal/commands/inspect.py,sha256=PGrY9TRTRCM3y5Ml8Bdk8DEOXquWRfscr4DRo1LOTPc,3189
87
+ pip/_internal/commands/install.py,sha256=r3yHQUxvxt7gD5j9n6zRDslAvtx9CT_whLuQJcktp6M,29390
88
+ pip/_internal/commands/list.py,sha256=oiIzSjLP6__d7dIS3q0Xb5ywsaOThBWRqMyjjKzkPdM,12769
89
+ pip/_internal/commands/search.py,sha256=fWkUQVx_gm8ebbFAlCgqtxKXT9rNahpJ-BI__3HNZpg,5626
90
+ pip/_internal/commands/show.py,sha256=0YBhCga3PAd81vT3l7UWflktSpB5-aYqQcJxBVPazVM,7857
91
+ pip/_internal/commands/uninstall.py,sha256=7pOR7enK76gimyxQbzxcG1OsyLXL3DvX939xmM8Fvtg,3892
92
+ pip/_internal/commands/wheel.py,sha256=eJRhr_qoNNxWAkkdJCNiQM7CXd4E1_YyQhsqJnBPGGg,6414
93
+ pip/_internal/configuration.py,sha256=-KOok6jh3hFzXMPQFPJ1_EFjBpAsge-RSreQuLHLmzo,14005
94
+ pip/_internal/distributions/__init__.py,sha256=Hq6kt6gXBgjNit5hTTWLAzeCNOKoB-N0pGYSqehrli8,858
95
+ pip/_internal/distributions/__pycache__/__init__.cpython-312.pyc,,
96
+ pip/_internal/distributions/__pycache__/base.cpython-312.pyc,,
97
+ pip/_internal/distributions/__pycache__/installed.cpython-312.pyc,,
98
+ pip/_internal/distributions/__pycache__/sdist.cpython-312.pyc,,
99
+ pip/_internal/distributions/__pycache__/wheel.cpython-312.pyc,,
100
+ pip/_internal/distributions/base.py,sha256=QeB9qvKXDIjLdPBDE5fMgpfGqMMCr-govnuoQnGuiF8,1783
101
+ pip/_internal/distributions/installed.py,sha256=QinHFbWAQ8oE0pbD8MFZWkwlnfU1QYTccA1vnhrlYOU,842
102
+ pip/_internal/distributions/sdist.py,sha256=PlcP4a6-R6c98XnOM-b6Lkb3rsvh9iG4ok8shaanrzs,6751
103
+ pip/_internal/distributions/wheel.py,sha256=THBYfnv7VVt8mYhMYUtH13S1E7FDwtDyDfmUcl8ai0E,1317
104
+ pip/_internal/exceptions.py,sha256=2_byISIv3kSnI_9T-Esfxrt0LnTRgcUHyxu0twsHjQY,26481
105
+ pip/_internal/index/__init__.py,sha256=vpt-JeTZefh8a-FC22ZeBSXFVbuBcXSGiILhQZJaNpQ,30
106
+ pip/_internal/index/__pycache__/__init__.cpython-312.pyc,,
107
+ pip/_internal/index/__pycache__/collector.cpython-312.pyc,,
108
+ pip/_internal/index/__pycache__/package_finder.cpython-312.pyc,,
109
+ pip/_internal/index/__pycache__/sources.cpython-312.pyc,,
110
+ pip/_internal/index/collector.py,sha256=RdPO0JLAlmyBWPAWYHPyRoGjz3GNAeTngCNkbGey_mE,16265
111
+ pip/_internal/index/package_finder.py,sha256=mJHAljlHeHuclyuxtjvBZO6DtovKjsZjF_tCh_wux5E,38076
112
+ pip/_internal/index/sources.py,sha256=lPBLK5Xiy8Q6IQMio26Wl7ocfZOKkgGklIBNyUJ23fI,8632
113
+ pip/_internal/locations/__init__.py,sha256=UaAxeZ_f93FyouuFf4p7SXYF-4WstXuEvd3LbmPCAno,14925
114
+ pip/_internal/locations/__pycache__/__init__.cpython-312.pyc,,
115
+ pip/_internal/locations/__pycache__/_distutils.cpython-312.pyc,,
116
+ pip/_internal/locations/__pycache__/_sysconfig.cpython-312.pyc,,
117
+ pip/_internal/locations/__pycache__/base.cpython-312.pyc,,
118
+ pip/_internal/locations/_distutils.py,sha256=x6nyVLj7X11Y4khIdf-mFlxMl2FWadtVEgeb8upc_WI,6013
119
+ pip/_internal/locations/_sysconfig.py,sha256=IGzds60qsFneRogC-oeBaY7bEh3lPt_v47kMJChQXsU,7724
120
+ pip/_internal/locations/base.py,sha256=RQiPi1d4FVM2Bxk04dQhXZ2PqkeljEL2fZZ9SYqIQ78,2556
121
+ pip/_internal/main.py,sha256=r-UnUe8HLo5XFJz8inTcOOTiu_sxNhgHb6VwlGUllOI,340
122
+ pip/_internal/metadata/__init__.py,sha256=CU8jK1TZso7jOLdr0sX9xDjrcs5iy8d7IRK-hvaIO5Y,4337
123
+ pip/_internal/metadata/__pycache__/__init__.cpython-312.pyc,,
124
+ pip/_internal/metadata/__pycache__/_json.cpython-312.pyc,,
125
+ pip/_internal/metadata/__pycache__/base.cpython-312.pyc,,
126
+ pip/_internal/metadata/__pycache__/pkg_resources.cpython-312.pyc,,
127
+ pip/_internal/metadata/_json.py,sha256=ezrIYazHCINM2QUk1eA9wEAMj3aeGWeDVgGalgUzKpc,2707
128
+ pip/_internal/metadata/base.py,sha256=ft0K5XNgI4ETqZnRv2-CtvgYiMOMAeGMAzxT-f6VLJA,25298
129
+ pip/_internal/metadata/importlib/__init__.py,sha256=jUUidoxnHcfITHHaAWG1G2i5fdBYklv_uJcjo2x7VYE,135
130
+ pip/_internal/metadata/importlib/__pycache__/__init__.cpython-312.pyc,,
131
+ pip/_internal/metadata/importlib/__pycache__/_compat.cpython-312.pyc,,
132
+ pip/_internal/metadata/importlib/__pycache__/_dists.cpython-312.pyc,,
133
+ pip/_internal/metadata/importlib/__pycache__/_envs.cpython-312.pyc,,
134
+ pip/_internal/metadata/importlib/_compat.py,sha256=c6av8sP8BBjAZuFSJow1iWfygUXNM3xRTCn5nqw6B9M,2796
135
+ pip/_internal/metadata/importlib/_dists.py,sha256=ftmYiyfUGUIjnVwt6W-Ijsimy5c28KgmXly5Q5IQ2P4,8279
136
+ pip/_internal/metadata/importlib/_envs.py,sha256=UUB980XSrDWrMpQ1_G45i0r8Hqlg_tg3IPQ63mEqbNc,7431
137
+ pip/_internal/metadata/pkg_resources.py,sha256=U07ETAINSGeSRBfWUG93E4tZZbaW_f7PGzEqZN0hulc,10542
138
+ pip/_internal/models/__init__.py,sha256=3DHUd_qxpPozfzouoqa9g9ts1Czr5qaHfFxbnxriepM,63
139
+ pip/_internal/models/__pycache__/__init__.cpython-312.pyc,,
140
+ pip/_internal/models/__pycache__/candidate.cpython-312.pyc,,
141
+ pip/_internal/models/__pycache__/direct_url.cpython-312.pyc,,
142
+ pip/_internal/models/__pycache__/format_control.cpython-312.pyc,,
143
+ pip/_internal/models/__pycache__/index.cpython-312.pyc,,
144
+ pip/_internal/models/__pycache__/installation_report.cpython-312.pyc,,
145
+ pip/_internal/models/__pycache__/link.cpython-312.pyc,,
146
+ pip/_internal/models/__pycache__/scheme.cpython-312.pyc,,
147
+ pip/_internal/models/__pycache__/search_scope.cpython-312.pyc,,
148
+ pip/_internal/models/__pycache__/selection_prefs.cpython-312.pyc,,
149
+ pip/_internal/models/__pycache__/target_python.cpython-312.pyc,,
150
+ pip/_internal/models/__pycache__/wheel.cpython-312.pyc,,
151
+ pip/_internal/models/candidate.py,sha256=zzgFRuw_kWPjKpGw7LC0ZUMD2CQ2EberUIYs8izjdCA,753
152
+ pip/_internal/models/direct_url.py,sha256=uBtY2HHd3TO9cKQJWh0ThvE5FRr-MWRYChRU4IG9HZE,6578
153
+ pip/_internal/models/format_control.py,sha256=wtsQqSK9HaUiNxQEuB-C62eVimw6G4_VQFxV9-_KDBE,2486
154
+ pip/_internal/models/index.py,sha256=tYnL8oxGi4aSNWur0mG8DAP7rC6yuha_MwJO8xw0crI,1030
155
+ pip/_internal/models/installation_report.py,sha256=zRVZoaz-2vsrezj_H3hLOhMZCK9c7TbzWgC-jOalD00,2818
156
+ pip/_internal/models/link.py,sha256=GQ8hq7x-FDFPv25Nbn2veIM-MlBrGZDGLd7aZeF4Xrg,21448
157
+ pip/_internal/models/scheme.py,sha256=PakmHJM3e8OOWSZFtfz1Az7f1meONJnkGuQxFlt3wBE,575
158
+ pip/_internal/models/search_scope.py,sha256=67NEnsYY84784S-MM7ekQuo9KXLH-7MzFntXjapvAo0,4531
159
+ pip/_internal/models/selection_prefs.py,sha256=qaFfDs3ciqoXPg6xx45N1jPLqccLJw4N0s4P0PyHTQ8,2015
160
+ pip/_internal/models/target_python.py,sha256=2XaH2rZ5ZF-K5wcJbEMGEl7SqrTToDDNkrtQ2v_v_-Q,4271
161
+ pip/_internal/models/wheel.py,sha256=G7dND_s4ebPkEL7RJ1qCY0QhUUWIIK6AnjWgRATF5no,4539
162
+ pip/_internal/network/__init__.py,sha256=jf6Tt5nV_7zkARBrKojIXItgejvoegVJVKUbhAa5Ioc,50
163
+ pip/_internal/network/__pycache__/__init__.cpython-312.pyc,,
164
+ pip/_internal/network/__pycache__/auth.cpython-312.pyc,,
165
+ pip/_internal/network/__pycache__/cache.cpython-312.pyc,,
166
+ pip/_internal/network/__pycache__/download.cpython-312.pyc,,
167
+ pip/_internal/network/__pycache__/lazy_wheel.cpython-312.pyc,,
168
+ pip/_internal/network/__pycache__/session.cpython-312.pyc,,
169
+ pip/_internal/network/__pycache__/utils.cpython-312.pyc,,
170
+ pip/_internal/network/__pycache__/xmlrpc.cpython-312.pyc,,
171
+ pip/_internal/network/auth.py,sha256=D4gASjUrqoDFlSt6gQ767KAAjv6PUyJU0puDlhXNVRE,20809
172
+ pip/_internal/network/cache.py,sha256=0yGMA3Eet59xBSLtbPAenvI53dl29oUOeqZ2c0QL2Ss,4614
173
+ pip/_internal/network/download.py,sha256=FLOP29dPYECBiAi7eEjvAbNkyzaKNqbyjOT2m8HPW8U,6048
174
+ pip/_internal/network/lazy_wheel.py,sha256=PBdoMoNQQIA84Fhgne38jWF52W4x_KtsHjxgv4dkRKA,7622
175
+ pip/_internal/network/session.py,sha256=msM4es16LmmNEYNkrYyg8fTc7gAHbKFltawfKP27LOI,18771
176
+ pip/_internal/network/utils.py,sha256=Inaxel-NxBu4PQWkjyErdnfewsFCcgHph7dzR1-FboY,4088
177
+ pip/_internal/network/xmlrpc.py,sha256=sAxzOacJ-N1NXGPvap9jC3zuYWSnnv3GXtgR2-E2APA,1838
178
+ pip/_internal/operations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
179
+ pip/_internal/operations/__pycache__/__init__.cpython-312.pyc,,
180
+ pip/_internal/operations/__pycache__/check.cpython-312.pyc,,
181
+ pip/_internal/operations/__pycache__/freeze.cpython-312.pyc,,
182
+ pip/_internal/operations/__pycache__/prepare.cpython-312.pyc,,
183
+ pip/_internal/operations/build/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
184
+ pip/_internal/operations/build/__pycache__/__init__.cpython-312.pyc,,
185
+ pip/_internal/operations/build/__pycache__/build_tracker.cpython-312.pyc,,
186
+ pip/_internal/operations/build/__pycache__/metadata.cpython-312.pyc,,
187
+ pip/_internal/operations/build/__pycache__/metadata_editable.cpython-312.pyc,,
188
+ pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-312.pyc,,
189
+ pip/_internal/operations/build/__pycache__/wheel.cpython-312.pyc,,
190
+ pip/_internal/operations/build/__pycache__/wheel_editable.cpython-312.pyc,,
191
+ pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-312.pyc,,
192
+ pip/_internal/operations/build/build_tracker.py,sha256=-ARW_TcjHCOX7D2NUOGntB4Fgc6b4aolsXkAK6BWL7w,4774
193
+ pip/_internal/operations/build/metadata.py,sha256=9S0CUD8U3QqZeXp-Zyt8HxwU90lE4QrnYDgrqZDzBnc,1422
194
+ pip/_internal/operations/build/metadata_editable.py,sha256=xlAwcP9q_8_fmv_3I39w9EZ7SQV9hnJZr9VuTsq2Y68,1510
195
+ pip/_internal/operations/build/metadata_legacy.py,sha256=8i6i1QZX9m_lKPStEFsHKM0MT4a-CD408JOw99daLmo,2190
196
+ pip/_internal/operations/build/wheel.py,sha256=sT12FBLAxDC6wyrDorh8kvcZ1jG5qInCRWzzP-UkJiQ,1075
197
+ pip/_internal/operations/build/wheel_editable.py,sha256=yOtoH6zpAkoKYEUtr8FhzrYnkNHQaQBjWQ2HYae1MQg,1417
198
+ pip/_internal/operations/build/wheel_legacy.py,sha256=K-6kNhmj-1xDF45ny1yheMerF0ui4EoQCLzEoHh6-tc,3045
199
+ pip/_internal/operations/check.py,sha256=L24vRL8VWbyywdoeAhM89WCd8zLTnjIbULlKelUgIec,5912
200
+ pip/_internal/operations/freeze.py,sha256=1_M79jAQKnCxWr-KCCmHuVXOVFGaUJHmoWLfFzgh7K4,9843
201
+ pip/_internal/operations/install/__init__.py,sha256=mX7hyD2GNBO2mFGokDQ30r_GXv7Y_PLdtxcUv144e-s,51
202
+ pip/_internal/operations/install/__pycache__/__init__.cpython-312.pyc,,
203
+ pip/_internal/operations/install/__pycache__/editable_legacy.cpython-312.pyc,,
204
+ pip/_internal/operations/install/__pycache__/wheel.cpython-312.pyc,,
205
+ pip/_internal/operations/install/editable_legacy.py,sha256=PoEsNEPGbIZ2yQphPsmYTKLOCMs4gv5OcCdzW124NcA,1283
206
+ pip/_internal/operations/install/wheel.py,sha256=X5Iz9yUg5LlK5VNQ9g2ikc6dcRu8EPi_SUi5iuEDRgo,27615
207
+ pip/_internal/operations/prepare.py,sha256=joWJwPkuqGscQgVNImLK71e9hRapwKvRCM8HclysmvU,28118
208
+ pip/_internal/pyproject.py,sha256=GLJ6rWRS5_2noKdajohoLyDty57Z7QXhcUAYghmTnWc,7286
209
+ pip/_internal/req/__init__.py,sha256=HxBFtZy_BbCclLgr26waMtpzYdO5T3vxePvpGAXSt5s,2653
210
+ pip/_internal/req/__pycache__/__init__.cpython-312.pyc,,
211
+ pip/_internal/req/__pycache__/constructors.cpython-312.pyc,,
212
+ pip/_internal/req/__pycache__/req_file.cpython-312.pyc,,
213
+ pip/_internal/req/__pycache__/req_install.cpython-312.pyc,,
214
+ pip/_internal/req/__pycache__/req_set.cpython-312.pyc,,
215
+ pip/_internal/req/__pycache__/req_uninstall.cpython-312.pyc,,
216
+ pip/_internal/req/constructors.py,sha256=v1qzCN1mIldwx-nCrPc8JO4lxkm3Fv8M5RWvt8LISjc,18430
217
+ pip/_internal/req/req_file.py,sha256=eys82McgaICOGic2UZRHjD720piKJPwmeSYdXlWwl6w,20234
218
+ pip/_internal/req/req_install.py,sha256=BMptxHYg2uG_b-7HFEULPb3nuw0FMAbuea8zTq2rE7w,35786
219
+ pip/_internal/req/req_set.py,sha256=j3esG0s6SzoVReX9rWn4rpYNtyET_fwxbwJPRimvRxo,2858
220
+ pip/_internal/req/req_uninstall.py,sha256=qzDIxJo-OETWqGais7tSMCDcWbATYABT-Tid3ityF0s,23853
221
+ pip/_internal/resolution/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
222
+ pip/_internal/resolution/__pycache__/__init__.cpython-312.pyc,,
223
+ pip/_internal/resolution/__pycache__/base.cpython-312.pyc,,
224
+ pip/_internal/resolution/base.py,sha256=qlmh325SBVfvG6Me9gc5Nsh5sdwHBwzHBq6aEXtKsLA,583
225
+ pip/_internal/resolution/legacy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
226
+ pip/_internal/resolution/legacy/__pycache__/__init__.cpython-312.pyc,,
227
+ pip/_internal/resolution/legacy/__pycache__/resolver.cpython-312.pyc,,
228
+ pip/_internal/resolution/legacy/resolver.py,sha256=3HZiJBRd1FTN6jQpI4qRO8-TbLYeIbUTS6PFvXnXs2w,24068
229
+ pip/_internal/resolution/resolvelib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
230
+ pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-312.pyc,,
231
+ pip/_internal/resolution/resolvelib/__pycache__/base.cpython-312.pyc,,
232
+ pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-312.pyc,,
233
+ pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-312.pyc,,
234
+ pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-312.pyc,,
235
+ pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-312.pyc,,
236
+ pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-312.pyc,,
237
+ pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-312.pyc,,
238
+ pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-312.pyc,,
239
+ pip/_internal/resolution/resolvelib/base.py,sha256=DCf669FsqyQY5uqXeePDHQY1e4QO-pBzWH8O0s9-K94,5023
240
+ pip/_internal/resolution/resolvelib/candidates.py,sha256=5UZ1upNnmqsP-nmEZaDYxaBgCoejw_e2WVGmmAvBxXc,20001
241
+ pip/_internal/resolution/resolvelib/factory.py,sha256=MJOLSZJY8_28PPdcutoQ6gjJ_1eBDt6Z1edtfTJyR4E,32659
242
+ pip/_internal/resolution/resolvelib/found_candidates.py,sha256=9hrTyQqFvl9I7Tji79F1AxHv39Qh1rkJ_7deSHSMfQc,6383
243
+ pip/_internal/resolution/resolvelib/provider.py,sha256=bcsFnYvlmtB80cwVdW1fIwgol8ZNr1f1VHyRTkz47SM,9935
244
+ pip/_internal/resolution/resolvelib/reporter.py,sha256=00JtoXEkTlw0-rl_sl54d71avwOsJHt9GGHcrj5Sza0,3168
245
+ pip/_internal/resolution/resolvelib/requirements.py,sha256=7JG4Z72e5Yk4vU0S5ulGvbqTy4FMQGYhY5zQhX9zTtY,8065
246
+ pip/_internal/resolution/resolvelib/resolver.py,sha256=nLJOsVMEVi2gQUVJoUFKMZAeu2f7GRMjGMvNSWyz0Bc,12592
247
+ pip/_internal/self_outdated_check.py,sha256=1PFtttvLAeyCVR3tPoBq2sOlPD0IJ-KSqU6bc1HUk9c,8318
248
+ pip/_internal/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
249
+ pip/_internal/utils/__pycache__/__init__.cpython-312.pyc,,
250
+ pip/_internal/utils/__pycache__/_jaraco_text.cpython-312.pyc,,
251
+ pip/_internal/utils/__pycache__/_log.cpython-312.pyc,,
252
+ pip/_internal/utils/__pycache__/appdirs.cpython-312.pyc,,
253
+ pip/_internal/utils/__pycache__/compat.cpython-312.pyc,,
254
+ pip/_internal/utils/__pycache__/compatibility_tags.cpython-312.pyc,,
255
+ pip/_internal/utils/__pycache__/datetime.cpython-312.pyc,,
256
+ pip/_internal/utils/__pycache__/deprecation.cpython-312.pyc,,
257
+ pip/_internal/utils/__pycache__/direct_url_helpers.cpython-312.pyc,,
258
+ pip/_internal/utils/__pycache__/egg_link.cpython-312.pyc,,
259
+ pip/_internal/utils/__pycache__/entrypoints.cpython-312.pyc,,
260
+ pip/_internal/utils/__pycache__/filesystem.cpython-312.pyc,,
261
+ pip/_internal/utils/__pycache__/filetypes.cpython-312.pyc,,
262
+ pip/_internal/utils/__pycache__/glibc.cpython-312.pyc,,
263
+ pip/_internal/utils/__pycache__/hashes.cpython-312.pyc,,
264
+ pip/_internal/utils/__pycache__/logging.cpython-312.pyc,,
265
+ pip/_internal/utils/__pycache__/misc.cpython-312.pyc,,
266
+ pip/_internal/utils/__pycache__/packaging.cpython-312.pyc,,
267
+ pip/_internal/utils/__pycache__/retry.cpython-312.pyc,,
268
+ pip/_internal/utils/__pycache__/setuptools_build.cpython-312.pyc,,
269
+ pip/_internal/utils/__pycache__/subprocess.cpython-312.pyc,,
270
+ pip/_internal/utils/__pycache__/temp_dir.cpython-312.pyc,,
271
+ pip/_internal/utils/__pycache__/unpacking.cpython-312.pyc,,
272
+ pip/_internal/utils/__pycache__/urls.cpython-312.pyc,,
273
+ pip/_internal/utils/__pycache__/virtualenv.cpython-312.pyc,,
274
+ pip/_internal/utils/__pycache__/wheel.cpython-312.pyc,,
275
+ pip/_internal/utils/_jaraco_text.py,sha256=M15uUPIh5NpP1tdUGBxRau6q1ZAEtI8-XyLEETscFfE,3350
276
+ pip/_internal/utils/_log.py,sha256=-jHLOE_THaZz5BFcCnoSL9EYAtJ0nXem49s9of4jvKw,1015
277
+ pip/_internal/utils/appdirs.py,sha256=swgcTKOm3daLeXTW6v5BUS2Ti2RvEnGRQYH_yDXklAo,1665
278
+ pip/_internal/utils/compat.py,sha256=ckkFveBiYQjRWjkNsajt_oWPS57tJvE8XxoC4OIYgCY,2399
279
+ pip/_internal/utils/compatibility_tags.py,sha256=OWq5axHpW-MEEPztGdvgADrgJPAcV9a88Rxm4Z8VBs8,6272
280
+ pip/_internal/utils/datetime.py,sha256=m21Y3wAtQc-ji6Veb6k_M5g6A0ZyFI4egchTdnwh-pQ,242
281
+ pip/_internal/utils/deprecation.py,sha256=k7Qg_UBAaaTdyq82YVARA6D7RmcGTXGv7fnfcgigj4Q,3707
282
+ pip/_internal/utils/direct_url_helpers.py,sha256=r2MRtkVDACv9AGqYODBUC9CjwgtsUU1s68hmgfCJMtA,3196
283
+ pip/_internal/utils/egg_link.py,sha256=0FePZoUYKv4RGQ2t6x7w5Z427wbA_Uo3WZnAkrgsuqo,2463
284
+ pip/_internal/utils/entrypoints.py,sha256=YlhLTRl2oHBAuqhc-zmL7USS67TPWVHImjeAQHreZTQ,3064
285
+ pip/_internal/utils/filesystem.py,sha256=ajvA-q4ocliW9kPp8Yquh-4vssXbu-UKbo5FV9V4X64,4950
286
+ pip/_internal/utils/filetypes.py,sha256=i8XAQ0eFCog26Fw9yV0Yb1ygAqKYB1w9Cz9n0fj8gZU,716
287
+ pip/_internal/utils/glibc.py,sha256=vUkWq_1pJuzcYNcGKLlQmABoUiisK8noYY1yc8Wq4w4,3734
288
+ pip/_internal/utils/hashes.py,sha256=XGGLL0AG8-RhWnyz87xF6MFZ--BKadHU35D47eApCKI,4972
289
+ pip/_internal/utils/logging.py,sha256=ONfbrhaD248akkosK79if97n20EABxwjOxp5dE5RCRY,11845
290
+ pip/_internal/utils/misc.py,sha256=DWnYxBUItjRp7hhxEg4ih6P6YpKrykM86dbi_EcU8SQ,23450
291
+ pip/_internal/utils/packaging.py,sha256=cm-X_0HVHV_jRwUVZh6AuEWqSitzf8EpaJ7Uv2UGu6A,2142
292
+ pip/_internal/utils/retry.py,sha256=mhFbykXjhTnZfgzeuy-vl9c8nECnYn_CMtwNJX2tYzQ,1392
293
+ pip/_internal/utils/setuptools_build.py,sha256=ouXpud-jeS8xPyTPsXJ-m34NPvK5os45otAzdSV_IJE,4435
294
+ pip/_internal/utils/subprocess.py,sha256=EsvqSRiSMHF98T8Txmu6NLU3U--MpTTQjtNgKP0P--M,8988
295
+ pip/_internal/utils/temp_dir.py,sha256=5qOXe8M4JeY6vaFQM867d5zkp1bSwMZ-KT5jymmP0Zg,9310
296
+ pip/_internal/utils/unpacking.py,sha256=_gVdyzTRDMYktpnYljn4OoxrZTtMCf4xknSm4rK0WaA,11967
297
+ pip/_internal/utils/urls.py,sha256=qceSOZb5lbNDrHNsv7_S4L4Ytszja5NwPKUMnZHbYnM,1599
298
+ pip/_internal/utils/virtualenv.py,sha256=S6f7csYorRpiD6cvn3jISZYc3I8PJC43H5iMFpRAEDU,3456
299
+ pip/_internal/utils/wheel.py,sha256=b442jkydFHjXzDy6cMR7MpzWBJ1Q82hR5F33cmcHV3g,4494
300
+ pip/_internal/vcs/__init__.py,sha256=UAqvzpbi0VbZo3Ub6skEeZAw-ooIZR-zX_WpCbxyCoU,596
301
+ pip/_internal/vcs/__pycache__/__init__.cpython-312.pyc,,
302
+ pip/_internal/vcs/__pycache__/bazaar.cpython-312.pyc,,
303
+ pip/_internal/vcs/__pycache__/git.cpython-312.pyc,,
304
+ pip/_internal/vcs/__pycache__/mercurial.cpython-312.pyc,,
305
+ pip/_internal/vcs/__pycache__/subversion.cpython-312.pyc,,
306
+ pip/_internal/vcs/__pycache__/versioncontrol.cpython-312.pyc,,
307
+ pip/_internal/vcs/bazaar.py,sha256=EKStcQaKpNu0NK4p5Q10Oc4xb3DUxFw024XrJy40bFQ,3528
308
+ pip/_internal/vcs/git.py,sha256=3tpc9LQA_J4IVW5r5NvWaaSeDzcmJOrSFZN0J8vIKfU,18177
309
+ pip/_internal/vcs/mercurial.py,sha256=oULOhzJ2Uie-06d1omkL-_Gc6meGaUkyogvqG9ZCyPs,5249
310
+ pip/_internal/vcs/subversion.py,sha256=ddTugHBqHzV3ebKlU5QXHPN4gUqlyXbOx8q8NgXKvs8,11735
311
+ pip/_internal/vcs/versioncontrol.py,sha256=cvf_-hnTAjQLXJ3d17FMNhQfcO1AcKWUF10tfrYyP-c,22440
312
+ pip/_internal/wheel_builder.py,sha256=DL3A8LKeRj_ACp11WS5wSgASgPFqeyAeXJKdXfmaWXU,11799
313
+ pip/_vendor/__init__.py,sha256=JYuAXvClhInxIrA2FTp5p-uuWVL7WV6-vEpTs46-Qh4,4873
314
+ pip/_vendor/__pycache__/__init__.cpython-312.pyc,,
315
+ pip/_vendor/__pycache__/typing_extensions.cpython-312.pyc,,
316
+ pip/_vendor/cachecontrol/__init__.py,sha256=LMC5CBe94ZRL5xhlzwyPDmHXvBD0p7lT4R3Z73D6a_I,677
317
+ pip/_vendor/cachecontrol/__pycache__/__init__.cpython-312.pyc,,
318
+ pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-312.pyc,,
319
+ pip/_vendor/cachecontrol/__pycache__/adapter.cpython-312.pyc,,
320
+ pip/_vendor/cachecontrol/__pycache__/cache.cpython-312.pyc,,
321
+ pip/_vendor/cachecontrol/__pycache__/controller.cpython-312.pyc,,
322
+ pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-312.pyc,,
323
+ pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-312.pyc,,
324
+ pip/_vendor/cachecontrol/__pycache__/serialize.cpython-312.pyc,,
325
+ pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-312.pyc,,
326
+ pip/_vendor/cachecontrol/_cmd.py,sha256=iist2EpzJvDVIhMAxXq8iFnTBsiZAd6iplxfmNboNyk,1737
327
+ pip/_vendor/cachecontrol/adapter.py,sha256=febjY4LV87iiCIK3jcl8iH58iaSA7b9WkovsByIDK0Y,6348
328
+ pip/_vendor/cachecontrol/cache.py,sha256=OXwv7Fn2AwnKNiahJHnjtvaKLndvVLv_-zO-ltlV9qI,1953
329
+ pip/_vendor/cachecontrol/caches/__init__.py,sha256=dtrrroK5BnADR1GWjCZ19aZ0tFsMfvFBtLQQU1sp_ag,303
330
+ pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-312.pyc,,
331
+ pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-312.pyc,,
332
+ pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-312.pyc,,
333
+ pip/_vendor/cachecontrol/caches/file_cache.py,sha256=b7oMgsRSqPmEsonVJw6uFEYUlFgD6GF8TyacOGG1x3M,5399
334
+ pip/_vendor/cachecontrol/caches/redis_cache.py,sha256=9rmqwtYu_ljVkW6_oLqbC7EaX_a8YT_yLuna-eS0dgo,1386
335
+ pip/_vendor/cachecontrol/controller.py,sha256=glbPj2iZlGqdBg8z09D2DtQOzoOGXnWvy7K2LEyBsEQ,18576
336
+ pip/_vendor/cachecontrol/filewrapper.py,sha256=2ktXNPE0KqnyzF24aOsKCA58HQq1xeC6l2g6_zwjghc,4291
337
+ pip/_vendor/cachecontrol/heuristics.py,sha256=gqMXU8w0gQuEQiSdu3Yg-0vd9kW7nrWKbLca75rheGE,4881
338
+ pip/_vendor/cachecontrol/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
339
+ pip/_vendor/cachecontrol/serialize.py,sha256=HQd2IllQ05HzPkVLMXTF2uX5mjEQjDBkxCqUJUODpZk,5163
340
+ pip/_vendor/cachecontrol/wrapper.py,sha256=hsGc7g8QGQTT-4f8tgz3AM5qwScg6FO0BSdLSRdEvpU,1417
341
+ pip/_vendor/certifi/__init__.py,sha256=p_GYZrjUwPBUhpLlCZoGb0miKBKSqDAyZC5DvIuqbHQ,94
342
+ pip/_vendor/certifi/__main__.py,sha256=1k3Cr95vCxxGRGDljrW3wMdpZdL3Nhf0u1n-k2qdsCY,255
343
+ pip/_vendor/certifi/__pycache__/__init__.cpython-312.pyc,,
344
+ pip/_vendor/certifi/__pycache__/__main__.cpython-312.pyc,,
345
+ pip/_vendor/certifi/__pycache__/core.cpython-312.pyc,,
346
+ pip/_vendor/certifi/cacert.pem,sha256=lO3rZukXdPyuk6BWUJFOKQliWaXH6HGh9l1GGrUgG0c,299427
347
+ pip/_vendor/certifi/core.py,sha256=2SRT5rIcQChFDbe37BQa-kULxAgJ8qN6l1jfqTp4HIs,4486
348
+ pip/_vendor/certifi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
349
+ pip/_vendor/distlib/__init__.py,sha256=dcwgYGYGQqAEawBXPDtIx80DO_3cOmFv8HTc8JMzknQ,625
350
+ pip/_vendor/distlib/__pycache__/__init__.cpython-312.pyc,,
351
+ pip/_vendor/distlib/__pycache__/compat.cpython-312.pyc,,
352
+ pip/_vendor/distlib/__pycache__/database.cpython-312.pyc,,
353
+ pip/_vendor/distlib/__pycache__/index.cpython-312.pyc,,
354
+ pip/_vendor/distlib/__pycache__/locators.cpython-312.pyc,,
355
+ pip/_vendor/distlib/__pycache__/manifest.cpython-312.pyc,,
356
+ pip/_vendor/distlib/__pycache__/markers.cpython-312.pyc,,
357
+ pip/_vendor/distlib/__pycache__/metadata.cpython-312.pyc,,
358
+ pip/_vendor/distlib/__pycache__/resources.cpython-312.pyc,,
359
+ pip/_vendor/distlib/__pycache__/scripts.cpython-312.pyc,,
360
+ pip/_vendor/distlib/__pycache__/util.cpython-312.pyc,,
361
+ pip/_vendor/distlib/__pycache__/version.cpython-312.pyc,,
362
+ pip/_vendor/distlib/__pycache__/wheel.cpython-312.pyc,,
363
+ pip/_vendor/distlib/compat.py,sha256=2jRSjRI4o-vlXeTK2BCGIUhkc6e9ZGhSsacRM5oseTw,41467
364
+ pip/_vendor/distlib/database.py,sha256=mHy_LxiXIsIVRb-T0-idBrVLw3Ffij5teHCpbjmJ9YU,51160
365
+ pip/_vendor/distlib/index.py,sha256=lTbw268rRhj8dw1sib3VZ_0EhSGgoJO3FKJzSFMOaeA,20797
366
+ pip/_vendor/distlib/locators.py,sha256=oBeAZpFuPQSY09MgNnLfQGGAXXvVO96BFpZyKMuK4tM,51026
367
+ pip/_vendor/distlib/manifest.py,sha256=3qfmAmVwxRqU1o23AlfXrQGZzh6g_GGzTAP_Hb9C5zQ,14168
368
+ pip/_vendor/distlib/markers.py,sha256=X6sDvkFGcYS8gUW8hfsWuKEKAqhQZAJ7iXOMLxRYjYk,5164
369
+ pip/_vendor/distlib/metadata.py,sha256=zil3sg2EUfLXVigljY2d_03IJt-JSs7nX-73fECMX2s,38724
370
+ pip/_vendor/distlib/resources.py,sha256=LwbPksc0A1JMbi6XnuPdMBUn83X7BPuFNWqPGEKI698,10820
371
+ pip/_vendor/distlib/scripts.py,sha256=BJliaDAZaVB7WAkwokgC3HXwLD2iWiHaVI50H7C6eG8,18608
372
+ pip/_vendor/distlib/t32.exe,sha256=a0GV5kCoWsMutvliiCKmIgV98eRZ33wXoS-XrqvJQVs,97792
373
+ pip/_vendor/distlib/t64-arm.exe,sha256=68TAa32V504xVBnufojh0PcenpR3U4wAqTqf-MZqbPw,182784
374
+ pip/_vendor/distlib/t64.exe,sha256=gaYY8hy4fbkHYTTnA4i26ct8IQZzkBG2pRdy0iyuBrc,108032
375
+ pip/_vendor/distlib/util.py,sha256=vMPGvsS4j9hF6Y9k3Tyom1aaHLb0rFmZAEyzeAdel9w,66682
376
+ pip/_vendor/distlib/version.py,sha256=s5VIs8wBn0fxzGxWM_aA2ZZyx525HcZbMvcTlTyZ3Rg,23727
377
+ pip/_vendor/distlib/w32.exe,sha256=R4csx3-OGM9kL4aPIzQKRo5TfmRSHZo6QWyLhDhNBks,91648
378
+ pip/_vendor/distlib/w64-arm.exe,sha256=xdyYhKj0WDcVUOCb05blQYvzdYIKMbmJn2SZvzkcey4,168448
379
+ pip/_vendor/distlib/w64.exe,sha256=ejGf-rojoBfXseGLpya6bFTFPWRG21X5KvU8J5iU-K0,101888
380
+ pip/_vendor/distlib/wheel.py,sha256=DFIVguEQHCdxnSdAO0dfFsgMcvVZitg7bCOuLwZ7A_s,43979
381
+ pip/_vendor/distro/__init__.py,sha256=2fHjF-SfgPvjyNZ1iHh_wjqWdR_Yo5ODHwZC0jLBPhc,981
382
+ pip/_vendor/distro/__main__.py,sha256=bu9d3TifoKciZFcqRBuygV3GSuThnVD_m2IK4cz96Vs,64
383
+ pip/_vendor/distro/__pycache__/__init__.cpython-312.pyc,,
384
+ pip/_vendor/distro/__pycache__/__main__.cpython-312.pyc,,
385
+ pip/_vendor/distro/__pycache__/distro.cpython-312.pyc,,
386
+ pip/_vendor/distro/distro.py,sha256=XqbefacAhDT4zr_trnbA15eY8vdK4GTghgmvUGrEM_4,49430
387
+ pip/_vendor/distro/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
388
+ pip/_vendor/idna/__init__.py,sha256=MPqNDLZbXqGaNdXxAFhiqFPKEQXju2jNQhCey6-5eJM,868
389
+ pip/_vendor/idna/__pycache__/__init__.cpython-312.pyc,,
390
+ pip/_vendor/idna/__pycache__/codec.cpython-312.pyc,,
391
+ pip/_vendor/idna/__pycache__/compat.cpython-312.pyc,,
392
+ pip/_vendor/idna/__pycache__/core.cpython-312.pyc,,
393
+ pip/_vendor/idna/__pycache__/idnadata.cpython-312.pyc,,
394
+ pip/_vendor/idna/__pycache__/intranges.cpython-312.pyc,,
395
+ pip/_vendor/idna/__pycache__/package_data.cpython-312.pyc,,
396
+ pip/_vendor/idna/__pycache__/uts46data.cpython-312.pyc,,
397
+ pip/_vendor/idna/codec.py,sha256=PEew3ItwzjW4hymbasnty2N2OXvNcgHB-JjrBuxHPYY,3422
398
+ pip/_vendor/idna/compat.py,sha256=RzLy6QQCdl9784aFhb2EX9EKGCJjg0P3PilGdeXXcx8,316
399
+ pip/_vendor/idna/core.py,sha256=YJYyAMnwiQEPjVC4-Fqu_p4CJ6yKKuDGmppBNQNQpFs,13239
400
+ pip/_vendor/idna/idnadata.py,sha256=W30GcIGvtOWYwAjZj4ZjuouUutC6ffgNuyjJy7fZ-lo,78306
401
+ pip/_vendor/idna/intranges.py,sha256=amUtkdhYcQG8Zr-CoMM_kVRacxkivC1WgxN1b63KKdU,1898
402
+ pip/_vendor/idna/package_data.py,sha256=q59S3OXsc5VI8j6vSD0sGBMyk6zZ4vWFREE88yCJYKs,21
403
+ pip/_vendor/idna/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
404
+ pip/_vendor/idna/uts46data.py,sha256=rt90K9J40gUSwppDPCrhjgi5AA6pWM65dEGRSf6rIhM,239289
405
+ pip/_vendor/msgpack/__init__.py,sha256=reRaiOtEzSjPnr7TpxjgIvbfln5pV66FhricAs2eC-g,1109
406
+ pip/_vendor/msgpack/__pycache__/__init__.cpython-312.pyc,,
407
+ pip/_vendor/msgpack/__pycache__/exceptions.cpython-312.pyc,,
408
+ pip/_vendor/msgpack/__pycache__/ext.cpython-312.pyc,,
409
+ pip/_vendor/msgpack/__pycache__/fallback.cpython-312.pyc,,
410
+ pip/_vendor/msgpack/exceptions.py,sha256=dCTWei8dpkrMsQDcjQk74ATl9HsIBH0ybt8zOPNqMYc,1081
411
+ pip/_vendor/msgpack/ext.py,sha256=kteJv03n9tYzd5oo3xYopVTo4vRaAxonBQQJhXohZZo,5726
412
+ pip/_vendor/msgpack/fallback.py,sha256=0g1Pzp0vtmBEmJ5w9F3s_-JMVURP8RS4G1cc5TRaAsI,32390
413
+ pip/_vendor/packaging/__init__.py,sha256=dk4Ta_vmdVJxYHDcfyhvQNw8V3PgSBomKNXqg-D2JDY,494
414
+ pip/_vendor/packaging/__pycache__/__init__.cpython-312.pyc,,
415
+ pip/_vendor/packaging/__pycache__/_elffile.cpython-312.pyc,,
416
+ pip/_vendor/packaging/__pycache__/_manylinux.cpython-312.pyc,,
417
+ pip/_vendor/packaging/__pycache__/_musllinux.cpython-312.pyc,,
418
+ pip/_vendor/packaging/__pycache__/_parser.cpython-312.pyc,,
419
+ pip/_vendor/packaging/__pycache__/_structures.cpython-312.pyc,,
420
+ pip/_vendor/packaging/__pycache__/_tokenizer.cpython-312.pyc,,
421
+ pip/_vendor/packaging/__pycache__/markers.cpython-312.pyc,,
422
+ pip/_vendor/packaging/__pycache__/metadata.cpython-312.pyc,,
423
+ pip/_vendor/packaging/__pycache__/requirements.cpython-312.pyc,,
424
+ pip/_vendor/packaging/__pycache__/specifiers.cpython-312.pyc,,
425
+ pip/_vendor/packaging/__pycache__/tags.cpython-312.pyc,,
426
+ pip/_vendor/packaging/__pycache__/utils.cpython-312.pyc,,
427
+ pip/_vendor/packaging/__pycache__/version.cpython-312.pyc,,
428
+ pip/_vendor/packaging/_elffile.py,sha256=cflAQAkE25tzhYmq_aCi72QfbT_tn891tPzfpbeHOwE,3306
429
+ pip/_vendor/packaging/_manylinux.py,sha256=vl5OCoz4kx80H5rwXKeXWjl9WNISGmr4ZgTpTP9lU9c,9612
430
+ pip/_vendor/packaging/_musllinux.py,sha256=p9ZqNYiOItGee8KcZFeHF_YcdhVwGHdK6r-8lgixvGQ,2694
431
+ pip/_vendor/packaging/_parser.py,sha256=s_TvTvDNK0NrM2QB3VKThdWFM4Nc0P6JnkObkl3MjpM,10236
432
+ pip/_vendor/packaging/_structures.py,sha256=q3eVNmbWJGG_S0Dit_S3Ao8qQqz_5PYTXFAKBZe5yr4,1431
433
+ pip/_vendor/packaging/_tokenizer.py,sha256=J6v5H7Jzvb-g81xp_2QACKwO7LxHQA6ikryMU7zXwN8,5273
434
+ pip/_vendor/packaging/licenses/__init__.py,sha256=A116-FU49_Dz4162M4y1uAiZN4Rgdc83FxNd8EjlfqI,5727
435
+ pip/_vendor/packaging/licenses/__pycache__/__init__.cpython-312.pyc,,
436
+ pip/_vendor/packaging/licenses/__pycache__/_spdx.cpython-312.pyc,,
437
+ pip/_vendor/packaging/licenses/_spdx.py,sha256=oAm1ztPFwlsmCKe7lAAsv_OIOfS1cWDu9bNBkeu-2ns,48398
438
+ pip/_vendor/packaging/markers.py,sha256=c89TNzB7ZdGYhkovm6PYmqGyHxXlYVaLW591PHUNKD8,10561
439
+ pip/_vendor/packaging/metadata.py,sha256=YJibM7GYe4re8-0a3OlXmGS-XDgTEoO4tlBt2q25Bng,34762
440
+ pip/_vendor/packaging/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
441
+ pip/_vendor/packaging/requirements.py,sha256=gYyRSAdbrIyKDY66ugIDUQjRMvxkH2ALioTmX3tnL6o,2947
442
+ pip/_vendor/packaging/specifiers.py,sha256=hGU6kuCd77bL-msIL6yLCp6MNT75RSMUKZDuju26c8U,40098
443
+ pip/_vendor/packaging/tags.py,sha256=CFqrJzAzc2XNGexerH__T-Y5Iwq7WbsYXsiLERLWxY0,21014
444
+ pip/_vendor/packaging/utils.py,sha256=0F3Hh9OFuRgrhTgGZUl5K22Fv1YP2tZl1z_2gO6kJiA,5050
445
+ pip/_vendor/packaging/version.py,sha256=oiHqzTUv_p12hpjgsLDVcaF5hT7pDaSOViUNMD4GTW0,16688
446
+ pip/_vendor/pkg_resources/__init__.py,sha256=jrhDRbOubP74QuPXxd7U7Po42PH2l-LZ2XfcO7llpZ4,124463
447
+ pip/_vendor/pkg_resources/__pycache__/__init__.cpython-312.pyc,,
448
+ pip/_vendor/platformdirs/__init__.py,sha256=JueR2cRLkxY7iwik-qNWJCwKOrAlBgVgcZ_IHQzqGLE,22344
449
+ pip/_vendor/platformdirs/__main__.py,sha256=jBJ8zb7Mpx5ebcqF83xrpO94MaeCpNGHVf9cvDN2JLg,1505
450
+ pip/_vendor/platformdirs/__pycache__/__init__.cpython-312.pyc,,
451
+ pip/_vendor/platformdirs/__pycache__/__main__.cpython-312.pyc,,
452
+ pip/_vendor/platformdirs/__pycache__/android.cpython-312.pyc,,
453
+ pip/_vendor/platformdirs/__pycache__/api.cpython-312.pyc,,
454
+ pip/_vendor/platformdirs/__pycache__/macos.cpython-312.pyc,,
455
+ pip/_vendor/platformdirs/__pycache__/unix.cpython-312.pyc,,
456
+ pip/_vendor/platformdirs/__pycache__/version.cpython-312.pyc,,
457
+ pip/_vendor/platformdirs/__pycache__/windows.cpython-312.pyc,,
458
+ pip/_vendor/platformdirs/android.py,sha256=kV5oL3V3DZ6WZKu9yFiQupv18yp_jlSV2ChH1TmPcds,9007
459
+ pip/_vendor/platformdirs/api.py,sha256=2dfUDNbEXeDhDKarqtR5NY7oUikUZ4RZhs3ozstmhBQ,9246
460
+ pip/_vendor/platformdirs/macos.py,sha256=UlbyFZ8Rzu3xndCqQEHrfsYTeHwYdFap1Ioz-yxveT4,6154
461
+ pip/_vendor/platformdirs/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
462
+ pip/_vendor/platformdirs/unix.py,sha256=uRPJWRyQEtv7yOSvU94rUmsblo5XKDLA1SzFg55kbK0,10393
463
+ pip/_vendor/platformdirs/version.py,sha256=oH4KgTfK4AklbTYVcV_yynvJ9JLI3pyvDVay0hRsLCs,411
464
+ pip/_vendor/platformdirs/windows.py,sha256=IFpiohUBwxPtCzlyKwNtxyW4Jk8haa6W8o59mfrDXVo,10125
465
+ pip/_vendor/pygments/__init__.py,sha256=7N1oiaWulw_nCsTY4EEixYLz15pWY5u4uPAFFi-ielU,2983
466
+ pip/_vendor/pygments/__main__.py,sha256=isIhBxLg65nLlXukG4VkMuPfNdd7gFzTZ_R_z3Q8diY,353
467
+ pip/_vendor/pygments/__pycache__/__init__.cpython-312.pyc,,
468
+ pip/_vendor/pygments/__pycache__/__main__.cpython-312.pyc,,
469
+ pip/_vendor/pygments/__pycache__/cmdline.cpython-312.pyc,,
470
+ pip/_vendor/pygments/__pycache__/console.cpython-312.pyc,,
471
+ pip/_vendor/pygments/__pycache__/filter.cpython-312.pyc,,
472
+ pip/_vendor/pygments/__pycache__/formatter.cpython-312.pyc,,
473
+ pip/_vendor/pygments/__pycache__/lexer.cpython-312.pyc,,
474
+ pip/_vendor/pygments/__pycache__/modeline.cpython-312.pyc,,
475
+ pip/_vendor/pygments/__pycache__/plugin.cpython-312.pyc,,
476
+ pip/_vendor/pygments/__pycache__/regexopt.cpython-312.pyc,,
477
+ pip/_vendor/pygments/__pycache__/scanner.cpython-312.pyc,,
478
+ pip/_vendor/pygments/__pycache__/sphinxext.cpython-312.pyc,,
479
+ pip/_vendor/pygments/__pycache__/style.cpython-312.pyc,,
480
+ pip/_vendor/pygments/__pycache__/token.cpython-312.pyc,,
481
+ pip/_vendor/pygments/__pycache__/unistring.cpython-312.pyc,,
482
+ pip/_vendor/pygments/__pycache__/util.cpython-312.pyc,,
483
+ pip/_vendor/pygments/cmdline.py,sha256=LIVzmAunlk9sRJJp54O4KRy9GDIN4Wu13v9p9QzfGPM,23656
484
+ pip/_vendor/pygments/console.py,sha256=yhP9UsLAVmWKVQf2446JJewkA7AiXeeTf4Ieg3Oi2fU,1718
485
+ pip/_vendor/pygments/filter.py,sha256=_ADNPCskD8_GmodHi6_LoVgPU3Zh336aBCT5cOeTMs0,1910
486
+ pip/_vendor/pygments/filters/__init__.py,sha256=RdedK2KWKXlKwR7cvkfr3NUj9YiZQgMgilRMFUg2jPA,40392
487
+ pip/_vendor/pygments/filters/__pycache__/__init__.cpython-312.pyc,,
488
+ pip/_vendor/pygments/formatter.py,sha256=jDWBTndlBH2Z5IYZFVDnP0qn1CaTQjTWt7iAGtCnJEg,4390
489
+ pip/_vendor/pygments/formatters/__init__.py,sha256=8No-NUs8rBTSSBJIv4hSEQt2M0cFB4hwAT0snVc2QGE,5385
490
+ pip/_vendor/pygments/formatters/__pycache__/__init__.cpython-312.pyc,,
491
+ pip/_vendor/pygments/formatters/__pycache__/_mapping.cpython-312.pyc,,
492
+ pip/_vendor/pygments/formatters/__pycache__/bbcode.cpython-312.pyc,,
493
+ pip/_vendor/pygments/formatters/__pycache__/groff.cpython-312.pyc,,
494
+ pip/_vendor/pygments/formatters/__pycache__/html.cpython-312.pyc,,
495
+ pip/_vendor/pygments/formatters/__pycache__/img.cpython-312.pyc,,
496
+ pip/_vendor/pygments/formatters/__pycache__/irc.cpython-312.pyc,,
497
+ pip/_vendor/pygments/formatters/__pycache__/latex.cpython-312.pyc,,
498
+ pip/_vendor/pygments/formatters/__pycache__/other.cpython-312.pyc,,
499
+ pip/_vendor/pygments/formatters/__pycache__/pangomarkup.cpython-312.pyc,,
500
+ pip/_vendor/pygments/formatters/__pycache__/rtf.cpython-312.pyc,,
501
+ pip/_vendor/pygments/formatters/__pycache__/svg.cpython-312.pyc,,
502
+ pip/_vendor/pygments/formatters/__pycache__/terminal.cpython-312.pyc,,
503
+ pip/_vendor/pygments/formatters/__pycache__/terminal256.cpython-312.pyc,,
504
+ pip/_vendor/pygments/formatters/_mapping.py,sha256=1Cw37FuQlNacnxRKmtlPX4nyLoX9_ttko5ZwscNUZZ4,4176
505
+ pip/_vendor/pygments/formatters/bbcode.py,sha256=3JQLI45tcrQ_kRUMjuab6C7Hb0XUsbVWqqbSn9cMjkI,3320
506
+ pip/_vendor/pygments/formatters/groff.py,sha256=M39k0PaSSZRnxWjqBSVPkF0mu1-Vr7bm6RsFvs-CNN4,5106
507
+ pip/_vendor/pygments/formatters/html.py,sha256=SE2jc3YCqbMS3rZW9EAmDlAUhdVxJ52gA4dileEvCGU,35669
508
+ pip/_vendor/pygments/formatters/img.py,sha256=MwA4xWPLOwh6j7Yc6oHzjuqSPt0M1fh5r-5BTIIUfsU,23287
509
+ pip/_vendor/pygments/formatters/irc.py,sha256=dp1Z0l_ObJ5NFh9MhqLGg5ptG5hgJqedT2Vkutt9v0M,4981
510
+ pip/_vendor/pygments/formatters/latex.py,sha256=XMmhOCqUKDBQtG5mGJNAFYxApqaC5puo5cMmPfK3944,19306
511
+ pip/_vendor/pygments/formatters/other.py,sha256=56PMJOliin-rAUdnRM0i1wsV1GdUPd_dvQq0_UPfF9c,5034
512
+ pip/_vendor/pygments/formatters/pangomarkup.py,sha256=y16U00aVYYEFpeCfGXlYBSMacG425CbfoG8oKbKegIg,2218
513
+ pip/_vendor/pygments/formatters/rtf.py,sha256=ZT90dmcKyJboIB0mArhL7IhE467GXRN0G7QAUgG03To,11957
514
+ pip/_vendor/pygments/formatters/svg.py,sha256=KKsiophPupHuxm0So-MsbQEWOT54IAiSF7hZPmxtKXE,7174
515
+ pip/_vendor/pygments/formatters/terminal.py,sha256=AojNG4MlKq2L6IsC_VnXHu4AbHCBn9Otog6u45XvxeI,4674
516
+ pip/_vendor/pygments/formatters/terminal256.py,sha256=kGkNUVo3FpwjytIDS0if79EuUoroAprcWt3igrcIqT0,11753
517
+ pip/_vendor/pygments/lexer.py,sha256=TYHDt___gNW4axTl2zvPZff-VQi8fPaIh5OKRcVSjUM,35349
518
+ pip/_vendor/pygments/lexers/__init__.py,sha256=pIlxyQJuu_syh9lE080cq8ceVbEVcKp0osAFU5fawJU,12115
519
+ pip/_vendor/pygments/lexers/__pycache__/__init__.cpython-312.pyc,,
520
+ pip/_vendor/pygments/lexers/__pycache__/_mapping.cpython-312.pyc,,
521
+ pip/_vendor/pygments/lexers/__pycache__/python.cpython-312.pyc,,
522
+ pip/_vendor/pygments/lexers/_mapping.py,sha256=61-h3zr103m01OS5BUq_AfUiL9YI06Ves9ipQ7k4vr4,76097
523
+ pip/_vendor/pygments/lexers/python.py,sha256=2J_YJrPTr_A6fJY_qKiKv0GpgPwHMrlMSeo59qN3fe4,53687
524
+ pip/_vendor/pygments/modeline.py,sha256=gtRYZBS-CKOCDXHhGZqApboHBaZwGH8gznN3O6nuxj4,1005
525
+ pip/_vendor/pygments/plugin.py,sha256=ioeJ3QeoJ-UQhZpY9JL7vbxsTVuwwM7BCu-Jb8nN0AU,1891
526
+ pip/_vendor/pygments/regexopt.py,sha256=Hky4EB13rIXEHQUNkwmCrYqtIlnXDehNR3MztafZ43w,3072
527
+ pip/_vendor/pygments/scanner.py,sha256=NDy3ofK_fHRFK4hIDvxpamG871aewqcsIb6sgTi7Fhk,3092
528
+ pip/_vendor/pygments/sphinxext.py,sha256=iOptJBcqOGPwMEJ2p70PvwpZPIGdvdZ8dxvq6kzxDgA,7981
529
+ pip/_vendor/pygments/style.py,sha256=rSCZWFpg1_DwFMXDU0nEVmAcBHpuQGf9RxvOPPQvKLQ,6420
530
+ pip/_vendor/pygments/styles/__init__.py,sha256=qUk6_1z5KmT8EdJFZYgESmG6P_HJF_2vVrDD7HSCGYY,2042
531
+ pip/_vendor/pygments/styles/__pycache__/__init__.cpython-312.pyc,,
532
+ pip/_vendor/pygments/styles/__pycache__/_mapping.cpython-312.pyc,,
533
+ pip/_vendor/pygments/styles/_mapping.py,sha256=6lovFUE29tz6EsV3XYY4hgozJ7q1JL7cfO3UOlgnS8w,3312
534
+ pip/_vendor/pygments/token.py,sha256=qZwT7LSPy5YBY3JgDjut642CCy7JdQzAfmqD9NmT5j0,6226
535
+ pip/_vendor/pygments/unistring.py,sha256=p5c1i-HhoIhWemy9CUsaN9o39oomYHNxXll0Xfw6tEA,63208
536
+ pip/_vendor/pygments/util.py,sha256=2tj2nS1X9_OpcuSjf8dOET2bDVZhs8cEKd_uT6-Fgg8,10031
537
+ pip/_vendor/pyproject_hooks/__init__.py,sha256=cPB_a9LXz5xvsRbX1o2qyAdjLatZJdQ_Lc5McNX-X7Y,691
538
+ pip/_vendor/pyproject_hooks/__pycache__/__init__.cpython-312.pyc,,
539
+ pip/_vendor/pyproject_hooks/__pycache__/_impl.cpython-312.pyc,,
540
+ pip/_vendor/pyproject_hooks/_impl.py,sha256=jY-raxnmyRyB57ruAitrJRUzEexuAhGTpgMygqx67Z4,14936
541
+ pip/_vendor/pyproject_hooks/_in_process/__init__.py,sha256=MJNPpfIxcO-FghxpBbxkG1rFiQf6HOUbV4U5mq0HFns,557
542
+ pip/_vendor/pyproject_hooks/_in_process/__pycache__/__init__.cpython-312.pyc,,
543
+ pip/_vendor/pyproject_hooks/_in_process/__pycache__/_in_process.cpython-312.pyc,,
544
+ pip/_vendor/pyproject_hooks/_in_process/_in_process.py,sha256=qcXMhmx__MIJq10gGHW3mA4Tl8dy8YzHMccwnNoKlw0,12216
545
+ pip/_vendor/pyproject_hooks/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
546
+ pip/_vendor/requests/__init__.py,sha256=HlB_HzhrzGtfD_aaYUwUh1zWXLZ75_YCLyit75d0Vz8,5057
547
+ pip/_vendor/requests/__pycache__/__init__.cpython-312.pyc,,
548
+ pip/_vendor/requests/__pycache__/__version__.cpython-312.pyc,,
549
+ pip/_vendor/requests/__pycache__/_internal_utils.cpython-312.pyc,,
550
+ pip/_vendor/requests/__pycache__/adapters.cpython-312.pyc,,
551
+ pip/_vendor/requests/__pycache__/api.cpython-312.pyc,,
552
+ pip/_vendor/requests/__pycache__/auth.cpython-312.pyc,,
553
+ pip/_vendor/requests/__pycache__/certs.cpython-312.pyc,,
554
+ pip/_vendor/requests/__pycache__/compat.cpython-312.pyc,,
555
+ pip/_vendor/requests/__pycache__/cookies.cpython-312.pyc,,
556
+ pip/_vendor/requests/__pycache__/exceptions.cpython-312.pyc,,
557
+ pip/_vendor/requests/__pycache__/help.cpython-312.pyc,,
558
+ pip/_vendor/requests/__pycache__/hooks.cpython-312.pyc,,
559
+ pip/_vendor/requests/__pycache__/models.cpython-312.pyc,,
560
+ pip/_vendor/requests/__pycache__/packages.cpython-312.pyc,,
561
+ pip/_vendor/requests/__pycache__/sessions.cpython-312.pyc,,
562
+ pip/_vendor/requests/__pycache__/status_codes.cpython-312.pyc,,
563
+ pip/_vendor/requests/__pycache__/structures.cpython-312.pyc,,
564
+ pip/_vendor/requests/__pycache__/utils.cpython-312.pyc,,
565
+ pip/_vendor/requests/__version__.py,sha256=FVfglgZmNQnmYPXpOohDU58F5EUb_-VnSTaAesS187g,435
566
+ pip/_vendor/requests/_internal_utils.py,sha256=nMQymr4hs32TqVo5AbCrmcJEhvPUh7xXlluyqwslLiQ,1495
567
+ pip/_vendor/requests/adapters.py,sha256=J7VeVxKBvawbtlX2DERVo05J9BXTcWYLMHNd1Baa-bk,27607
568
+ pip/_vendor/requests/api.py,sha256=_Zb9Oa7tzVIizTKwFrPjDEY9ejtm_OnSRERnADxGsQs,6449
569
+ pip/_vendor/requests/auth.py,sha256=kF75tqnLctZ9Mf_hm9TZIj4cQWnN5uxRz8oWsx5wmR0,10186
570
+ pip/_vendor/requests/certs.py,sha256=kHDlkK_beuHXeMPc5jta2wgl8gdKeUWt5f2nTDVrvt8,441
571
+ pip/_vendor/requests/compat.py,sha256=Mo9f9xZpefod8Zm-n9_StJcVTmwSukXR2p3IQyyVXvU,1485
572
+ pip/_vendor/requests/cookies.py,sha256=bNi-iqEj4NPZ00-ob-rHvzkvObzN3lEpgw3g6paS3Xw,18590
573
+ pip/_vendor/requests/exceptions.py,sha256=D1wqzYWne1mS2rU43tP9CeN1G7QAy7eqL9o1god6Ejw,4272
574
+ pip/_vendor/requests/help.py,sha256=hRKaf9u0G7fdwrqMHtF3oG16RKktRf6KiwtSq2Fo1_0,3813
575
+ pip/_vendor/requests/hooks.py,sha256=CiuysiHA39V5UfcCBXFIx83IrDpuwfN9RcTUgv28ftQ,733
576
+ pip/_vendor/requests/models.py,sha256=x4K4CmH-lC0l2Kb-iPfMN4dRXxHEcbOaEWBL_i09AwI,35483
577
+ pip/_vendor/requests/packages.py,sha256=_ZQDCJTJ8SP3kVWunSqBsRZNPzj2c1WFVqbdr08pz3U,1057
578
+ pip/_vendor/requests/sessions.py,sha256=ykTI8UWGSltOfH07HKollH7kTBGw4WhiBVaQGmckTw4,30495
579
+ pip/_vendor/requests/status_codes.py,sha256=iJUAeA25baTdw-6PfD0eF4qhpINDJRJI-yaMqxs4LEI,4322
580
+ pip/_vendor/requests/structures.py,sha256=-IbmhVz06S-5aPSZuUthZ6-6D9XOjRuTXHOabY041XM,2912
581
+ pip/_vendor/requests/utils.py,sha256=L79vnFbzJ3SFLKtJwpoWe41Tozi3RlZv94pY1TFIyow,33631
582
+ pip/_vendor/resolvelib/__init__.py,sha256=h509TdEcpb5-44JonaU3ex2TM15GVBLjM9CNCPwnTTs,537
583
+ pip/_vendor/resolvelib/__pycache__/__init__.cpython-312.pyc,,
584
+ pip/_vendor/resolvelib/__pycache__/providers.cpython-312.pyc,,
585
+ pip/_vendor/resolvelib/__pycache__/reporters.cpython-312.pyc,,
586
+ pip/_vendor/resolvelib/__pycache__/resolvers.cpython-312.pyc,,
587
+ pip/_vendor/resolvelib/__pycache__/structs.cpython-312.pyc,,
588
+ pip/_vendor/resolvelib/compat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
589
+ pip/_vendor/resolvelib/compat/__pycache__/__init__.cpython-312.pyc,,
590
+ pip/_vendor/resolvelib/compat/__pycache__/collections_abc.cpython-312.pyc,,
591
+ pip/_vendor/resolvelib/compat/collections_abc.py,sha256=uy8xUZ-NDEw916tugUXm8HgwCGiMO0f-RcdnpkfXfOs,156
592
+ pip/_vendor/resolvelib/providers.py,sha256=fuuvVrCetu5gsxPB43ERyjfO8aReS3rFQHpDgiItbs4,5871
593
+ pip/_vendor/resolvelib/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
594
+ pip/_vendor/resolvelib/reporters.py,sha256=TSbRmWzTc26w0ggsV1bxVpeWDB8QNIre6twYl7GIZBE,1601
595
+ pip/_vendor/resolvelib/resolvers.py,sha256=G8rsLZSq64g5VmIq-lB7UcIJ1gjAxIQJmTF4REZleQ0,20511
596
+ pip/_vendor/resolvelib/structs.py,sha256=0_1_XO8z_CLhegP3Vpf9VJ3zJcfLm0NOHRM-i0Ykz3o,4963
597
+ pip/_vendor/rich/__init__.py,sha256=dRxjIL-SbFVY0q3IjSMrfgBTHrm1LZDgLOygVBwiYZc,6090
598
+ pip/_vendor/rich/__main__.py,sha256=eO7Cq8JnrgG8zVoeImiAs92q3hXNMIfp0w5lMsO7Q2Y,8477
599
+ pip/_vendor/rich/__pycache__/__init__.cpython-312.pyc,,
600
+ pip/_vendor/rich/__pycache__/__main__.cpython-312.pyc,,
601
+ pip/_vendor/rich/__pycache__/_cell_widths.cpython-312.pyc,,
602
+ pip/_vendor/rich/__pycache__/_emoji_codes.cpython-312.pyc,,
603
+ pip/_vendor/rich/__pycache__/_emoji_replace.cpython-312.pyc,,
604
+ pip/_vendor/rich/__pycache__/_export_format.cpython-312.pyc,,
605
+ pip/_vendor/rich/__pycache__/_extension.cpython-312.pyc,,
606
+ pip/_vendor/rich/__pycache__/_fileno.cpython-312.pyc,,
607
+ pip/_vendor/rich/__pycache__/_inspect.cpython-312.pyc,,
608
+ pip/_vendor/rich/__pycache__/_log_render.cpython-312.pyc,,
609
+ pip/_vendor/rich/__pycache__/_loop.cpython-312.pyc,,
610
+ pip/_vendor/rich/__pycache__/_null_file.cpython-312.pyc,,
611
+ pip/_vendor/rich/__pycache__/_palettes.cpython-312.pyc,,
612
+ pip/_vendor/rich/__pycache__/_pick.cpython-312.pyc,,
613
+ pip/_vendor/rich/__pycache__/_ratio.cpython-312.pyc,,
614
+ pip/_vendor/rich/__pycache__/_spinners.cpython-312.pyc,,
615
+ pip/_vendor/rich/__pycache__/_stack.cpython-312.pyc,,
616
+ pip/_vendor/rich/__pycache__/_timer.cpython-312.pyc,,
617
+ pip/_vendor/rich/__pycache__/_win32_console.cpython-312.pyc,,
618
+ pip/_vendor/rich/__pycache__/_windows.cpython-312.pyc,,
619
+ pip/_vendor/rich/__pycache__/_windows_renderer.cpython-312.pyc,,
620
+ pip/_vendor/rich/__pycache__/_wrap.cpython-312.pyc,,
621
+ pip/_vendor/rich/__pycache__/abc.cpython-312.pyc,,
622
+ pip/_vendor/rich/__pycache__/align.cpython-312.pyc,,
623
+ pip/_vendor/rich/__pycache__/ansi.cpython-312.pyc,,
624
+ pip/_vendor/rich/__pycache__/bar.cpython-312.pyc,,
625
+ pip/_vendor/rich/__pycache__/box.cpython-312.pyc,,
626
+ pip/_vendor/rich/__pycache__/cells.cpython-312.pyc,,
627
+ pip/_vendor/rich/__pycache__/color.cpython-312.pyc,,
628
+ pip/_vendor/rich/__pycache__/color_triplet.cpython-312.pyc,,
629
+ pip/_vendor/rich/__pycache__/columns.cpython-312.pyc,,
630
+ pip/_vendor/rich/__pycache__/console.cpython-312.pyc,,
631
+ pip/_vendor/rich/__pycache__/constrain.cpython-312.pyc,,
632
+ pip/_vendor/rich/__pycache__/containers.cpython-312.pyc,,
633
+ pip/_vendor/rich/__pycache__/control.cpython-312.pyc,,
634
+ pip/_vendor/rich/__pycache__/default_styles.cpython-312.pyc,,
635
+ pip/_vendor/rich/__pycache__/diagnose.cpython-312.pyc,,
636
+ pip/_vendor/rich/__pycache__/emoji.cpython-312.pyc,,
637
+ pip/_vendor/rich/__pycache__/errors.cpython-312.pyc,,
638
+ pip/_vendor/rich/__pycache__/file_proxy.cpython-312.pyc,,
639
+ pip/_vendor/rich/__pycache__/filesize.cpython-312.pyc,,
640
+ pip/_vendor/rich/__pycache__/highlighter.cpython-312.pyc,,
641
+ pip/_vendor/rich/__pycache__/json.cpython-312.pyc,,
642
+ pip/_vendor/rich/__pycache__/jupyter.cpython-312.pyc,,
643
+ pip/_vendor/rich/__pycache__/layout.cpython-312.pyc,,
644
+ pip/_vendor/rich/__pycache__/live.cpython-312.pyc,,
645
+ pip/_vendor/rich/__pycache__/live_render.cpython-312.pyc,,
646
+ pip/_vendor/rich/__pycache__/logging.cpython-312.pyc,,
647
+ pip/_vendor/rich/__pycache__/markup.cpython-312.pyc,,
648
+ pip/_vendor/rich/__pycache__/measure.cpython-312.pyc,,
649
+ pip/_vendor/rich/__pycache__/padding.cpython-312.pyc,,
650
+ pip/_vendor/rich/__pycache__/pager.cpython-312.pyc,,
651
+ pip/_vendor/rich/__pycache__/palette.cpython-312.pyc,,
652
+ pip/_vendor/rich/__pycache__/panel.cpython-312.pyc,,
653
+ pip/_vendor/rich/__pycache__/pretty.cpython-312.pyc,,
654
+ pip/_vendor/rich/__pycache__/progress.cpython-312.pyc,,
655
+ pip/_vendor/rich/__pycache__/progress_bar.cpython-312.pyc,,
656
+ pip/_vendor/rich/__pycache__/prompt.cpython-312.pyc,,
657
+ pip/_vendor/rich/__pycache__/protocol.cpython-312.pyc,,
658
+ pip/_vendor/rich/__pycache__/region.cpython-312.pyc,,
659
+ pip/_vendor/rich/__pycache__/repr.cpython-312.pyc,,
660
+ pip/_vendor/rich/__pycache__/rule.cpython-312.pyc,,
661
+ pip/_vendor/rich/__pycache__/scope.cpython-312.pyc,,
662
+ pip/_vendor/rich/__pycache__/screen.cpython-312.pyc,,
663
+ pip/_vendor/rich/__pycache__/segment.cpython-312.pyc,,
664
+ pip/_vendor/rich/__pycache__/spinner.cpython-312.pyc,,
665
+ pip/_vendor/rich/__pycache__/status.cpython-312.pyc,,
666
+ pip/_vendor/rich/__pycache__/style.cpython-312.pyc,,
667
+ pip/_vendor/rich/__pycache__/styled.cpython-312.pyc,,
668
+ pip/_vendor/rich/__pycache__/syntax.cpython-312.pyc,,
669
+ pip/_vendor/rich/__pycache__/table.cpython-312.pyc,,
670
+ pip/_vendor/rich/__pycache__/terminal_theme.cpython-312.pyc,,
671
+ pip/_vendor/rich/__pycache__/text.cpython-312.pyc,,
672
+ pip/_vendor/rich/__pycache__/theme.cpython-312.pyc,,
673
+ pip/_vendor/rich/__pycache__/themes.cpython-312.pyc,,
674
+ pip/_vendor/rich/__pycache__/traceback.cpython-312.pyc,,
675
+ pip/_vendor/rich/__pycache__/tree.cpython-312.pyc,,
676
+ pip/_vendor/rich/_cell_widths.py,sha256=fbmeyetEdHjzE_Vx2l1uK7tnPOhMs2X1lJfO3vsKDpA,10209
677
+ pip/_vendor/rich/_emoji_codes.py,sha256=hu1VL9nbVdppJrVoijVshRlcRRe_v3dju3Mmd2sKZdY,140235
678
+ pip/_vendor/rich/_emoji_replace.py,sha256=n-kcetsEUx2ZUmhQrfeMNc-teeGhpuSQ5F8VPBsyvDo,1064
679
+ pip/_vendor/rich/_export_format.py,sha256=RI08pSrm5tBSzPMvnbTqbD9WIalaOoN5d4M1RTmLq1Y,2128
680
+ pip/_vendor/rich/_extension.py,sha256=Xt47QacCKwYruzjDi-gOBq724JReDj9Cm9xUi5fr-34,265
681
+ pip/_vendor/rich/_fileno.py,sha256=HWZxP5C2ajMbHryvAQZseflVfQoGzsKOHzKGsLD8ynQ,799
682
+ pip/_vendor/rich/_inspect.py,sha256=QM05lEFnFoTaFqpnbx-zBEI6k8oIKrD3cvjEOQNhKig,9655
683
+ pip/_vendor/rich/_log_render.py,sha256=1ByI0PA1ZpxZY3CGJOK54hjlq4X-Bz_boIjIqCd8Kns,3225
684
+ pip/_vendor/rich/_loop.py,sha256=hV_6CLdoPm0va22Wpw4zKqM0RYsz3TZxXj0PoS-9eDQ,1236
685
+ pip/_vendor/rich/_null_file.py,sha256=ADGKp1yt-k70FMKV6tnqCqecB-rSJzp-WQsD7LPL-kg,1394
686
+ pip/_vendor/rich/_palettes.py,sha256=cdev1JQKZ0JvlguV9ipHgznTdnvlIzUFDBb0It2PzjI,7063
687
+ pip/_vendor/rich/_pick.py,sha256=evDt8QN4lF5CiwrUIXlOJCntitBCOsI3ZLPEIAVRLJU,423
688
+ pip/_vendor/rich/_ratio.py,sha256=Zt58apszI6hAAcXPpgdWKpu3c31UBWebOeR4mbyptvU,5471
689
+ pip/_vendor/rich/_spinners.py,sha256=U2r1_g_1zSjsjiUdAESc2iAMc3i4ri_S8PYP6kQ5z1I,19919
690
+ pip/_vendor/rich/_stack.py,sha256=-C8OK7rxn3sIUdVwxZBBpeHhIzX0eI-VM3MemYfaXm0,351
691
+ pip/_vendor/rich/_timer.py,sha256=zelxbT6oPFZnNrwWPpc1ktUeAT-Vc4fuFcRZLQGLtMI,417
692
+ pip/_vendor/rich/_win32_console.py,sha256=BSaDRIMwBLITn_m0mTRLPqME5q-quGdSMuYMpYeYJwc,22755
693
+ pip/_vendor/rich/_windows.py,sha256=aBwaD_S56SbgopIvayVmpk0Y28uwY2C5Bab1wl3Bp-I,1925
694
+ pip/_vendor/rich/_windows_renderer.py,sha256=t74ZL3xuDCP3nmTp9pH1L5LiI2cakJuQRQleHCJerlk,2783
695
+ pip/_vendor/rich/_wrap.py,sha256=FlSsom5EX0LVkA3KWy34yHnCfLtqX-ZIepXKh-70rpc,3404
696
+ pip/_vendor/rich/abc.py,sha256=ON-E-ZqSSheZ88VrKX2M3PXpFbGEUUZPMa_Af0l-4f0,890
697
+ pip/_vendor/rich/align.py,sha256=Rh-3adnDaN1Ao07EjR2PhgE62PGLPgO8SMwJBku1urQ,10469
698
+ pip/_vendor/rich/ansi.py,sha256=Avs1LHbSdcyOvDOdpELZUoULcBiYewY76eNBp6uFBhs,6921
699
+ pip/_vendor/rich/bar.py,sha256=ldbVHOzKJOnflVNuv1xS7g6dLX2E3wMnXkdPbpzJTcs,3263
700
+ pip/_vendor/rich/box.py,sha256=nr5fYIUghB_iUCEq6y0Z3LlCT8gFPDrzN9u2kn7tJl4,10831
701
+ pip/_vendor/rich/cells.py,sha256=KrQkj5-LghCCpJLSNQIyAZjndc4bnEqOEmi5YuZ9UCY,5130
702
+ pip/_vendor/rich/color.py,sha256=3HSULVDj7qQkXUdFWv78JOiSZzfy5y1nkcYhna296V0,18211
703
+ pip/_vendor/rich/color_triplet.py,sha256=3lhQkdJbvWPoLDO-AnYImAWmJvV5dlgYNCVZ97ORaN4,1054
704
+ pip/_vendor/rich/columns.py,sha256=HUX0KcMm9dsKNi11fTbiM_h2iDtl8ySCaVcxlalEzq8,7131
705
+ pip/_vendor/rich/console.py,sha256=nKjrEx_7xy8KGmDVT-BgNII0R5hm1cexhAHDwdwNVqg,100156
706
+ pip/_vendor/rich/constrain.py,sha256=1VIPuC8AgtKWrcncQrjBdYqA3JVWysu6jZo1rrh7c7Q,1288
707
+ pip/_vendor/rich/containers.py,sha256=c_56TxcedGYqDepHBMTuZdUIijitAQgnox-Qde0Z1qo,5502
708
+ pip/_vendor/rich/control.py,sha256=DSkHTUQLorfSERAKE_oTAEUFefZnZp4bQb4q8rHbKws,6630
709
+ pip/_vendor/rich/default_styles.py,sha256=dZxgaSD9VUy7SXQShO33aLYiAWspCr2sCQZFX_JK1j4,8159
710
+ pip/_vendor/rich/diagnose.py,sha256=an6uouwhKPAlvQhYpNNpGq9EJysfMIOvvCbO3oSoR24,972
711
+ pip/_vendor/rich/emoji.py,sha256=omTF9asaAnsM4yLY94eR_9dgRRSm1lHUszX20D1yYCQ,2501
712
+ pip/_vendor/rich/errors.py,sha256=5pP3Kc5d4QJ_c0KFsxrfyhjiPVe7J1zOqSFbFAzcV-Y,642
713
+ pip/_vendor/rich/file_proxy.py,sha256=Tl9THMDZ-Pk5Wm8sI1gGg_U5DhusmxD-FZ0fUbcU0W0,1683
714
+ pip/_vendor/rich/filesize.py,sha256=_iz9lIpRgvW7MNSeCZnLg-HwzbP4GETg543WqD8SFs0,2484
715
+ pip/_vendor/rich/highlighter.py,sha256=G_sn-8DKjM1sEjLG_oc4ovkWmiUpWvj8bXi0yed2LnY,9586
716
+ pip/_vendor/rich/json.py,sha256=vVEoKdawoJRjAFayPwXkMBPLy7RSTs-f44wSQDR2nJ0,5031
717
+ pip/_vendor/rich/jupyter.py,sha256=QyoKoE_8IdCbrtiSHp9TsTSNyTHY0FO5whE7jOTd9UE,3252
718
+ pip/_vendor/rich/layout.py,sha256=ajkSFAtEVv9EFTcFs-w4uZfft7nEXhNzL7ZVdgrT5rI,14004
719
+ pip/_vendor/rich/live.py,sha256=DhzAPEnjTxQuq9_0Y2xh2MUwQcP_aGPkenLfKETslwM,14270
720
+ pip/_vendor/rich/live_render.py,sha256=zJtB471jGziBtEwxc54x12wEQtH4BuQr1SA8v9kU82w,3666
721
+ pip/_vendor/rich/logging.py,sha256=ZgpKMMBY_BuMAI_BYzo-UtXak6t5oH9VK8m9Q2Lm0f4,12458
722
+ pip/_vendor/rich/markup.py,sha256=3euGKP5s41NCQwaSjTnJxus5iZMHjxpIM0W6fCxra38,8451
723
+ pip/_vendor/rich/measure.py,sha256=HmrIJX8sWRTHbgh8MxEay_83VkqNW_70s8aKP5ZcYI8,5305
724
+ pip/_vendor/rich/padding.py,sha256=KVEI3tOwo9sgK1YNSuH__M1_jUWmLZwRVV_KmOtVzyM,4908
725
+ pip/_vendor/rich/pager.py,sha256=SO_ETBFKbg3n_AgOzXm41Sv36YxXAyI3_R-KOY2_uSc,828
726
+ pip/_vendor/rich/palette.py,sha256=lInvR1ODDT2f3UZMfL1grq7dY_pDdKHw4bdUgOGaM4Y,3396
727
+ pip/_vendor/rich/panel.py,sha256=fFRHcviXvWhk3V3zx5Zwmsb_RL9KJ3esD-sU0NYEVyw,11235
728
+ pip/_vendor/rich/pretty.py,sha256=gy3S72u4FRg2ytoo7N1ZDWDIvB4unbzd5iUGdgm-8fc,36391
729
+ pip/_vendor/rich/progress.py,sha256=MtmCjTk5zYU_XtRHxRHTAEHG6hF9PeF7EMWbEPleIC0,60357
730
+ pip/_vendor/rich/progress_bar.py,sha256=mZTPpJUwcfcdgQCTTz3kyY-fc79ddLwtx6Ghhxfo064,8162
731
+ pip/_vendor/rich/prompt.py,sha256=l0RhQU-0UVTV9e08xW1BbIj0Jq2IXyChX4lC0lFNzt4,12447
732
+ pip/_vendor/rich/protocol.py,sha256=5hHHDDNHckdk8iWH5zEbi-zuIVSF5hbU2jIo47R7lTE,1391
733
+ pip/_vendor/rich/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
734
+ pip/_vendor/rich/region.py,sha256=rNT9xZrVZTYIXZC0NYn41CJQwYNbR-KecPOxTgQvB8Y,166
735
+ pip/_vendor/rich/repr.py,sha256=5MZJZmONgC6kud-QW-_m1okXwL2aR6u6y-pUcUCJz28,4431
736
+ pip/_vendor/rich/rule.py,sha256=0fNaS_aERa3UMRc3T5WMpN_sumtDxfaor2y3of1ftBk,4602
737
+ pip/_vendor/rich/scope.py,sha256=TMUU8qo17thyqQCPqjDLYpg_UU1k5qVd-WwiJvnJVas,2843
738
+ pip/_vendor/rich/screen.py,sha256=YoeReESUhx74grqb0mSSb9lghhysWmFHYhsbMVQjXO8,1591
739
+ pip/_vendor/rich/segment.py,sha256=otnKeKGEV-WRlQVosfJVeFDcDxAKHpvJ_hLzSu5lumM,24743
740
+ pip/_vendor/rich/spinner.py,sha256=PT5qgXPG3ZpqRj7n3EZQ6NW56mx3ldZqZCU7gEMyZk4,4364
741
+ pip/_vendor/rich/status.py,sha256=kkPph3YeAZBo-X-4wPp8gTqZyU466NLwZBA4PZTTewo,4424
742
+ pip/_vendor/rich/style.py,sha256=aSoUNbVgfP1PAnduAqgbbl4AMQy668qs2S1FEwr3Oqs,27067
743
+ pip/_vendor/rich/styled.py,sha256=eZNnzGrI4ki_54pgY3Oj0T-x3lxdXTYh4_ryDB24wBU,1258
744
+ pip/_vendor/rich/syntax.py,sha256=qqAnEUZ4K57Po81_5RBxnsuU4KRzSdvDPAhKw8ma_3E,35763
745
+ pip/_vendor/rich/table.py,sha256=yXYUr0YsPpG466N50HCAw2bpb5ZUuuzdc-G66Zk-oTc,40103
746
+ pip/_vendor/rich/terminal_theme.py,sha256=1j5-ufJfnvlAo5Qsi_ACZiXDmwMXzqgmFByObT9-yJY,3370
747
+ pip/_vendor/rich/text.py,sha256=AO7JPCz6-gaN1thVLXMBntEmDPVYFgFNG1oM61_sanU,47552
748
+ pip/_vendor/rich/theme.py,sha256=oNyhXhGagtDlbDye3tVu3esWOWk0vNkuxFw-_unlaK0,3771
749
+ pip/_vendor/rich/themes.py,sha256=0xgTLozfabebYtcJtDdC5QkX5IVUEaviqDUJJh4YVFk,102
750
+ pip/_vendor/rich/traceback.py,sha256=z8UoN7NbTQKW6YDDUVwOh7F8snZf6gYnUWtOrKsLE1w,31797
751
+ pip/_vendor/rich/tree.py,sha256=yWnQ6rAvRGJ3qZGqBrxS2SW2TKBTNrP0SdY8QxOFPuw,9451
752
+ pip/_vendor/tomli/__init__.py,sha256=PhNw_eyLgdn7McJ6nrAN8yIm3dXC75vr1sVGVVwDSpA,314
753
+ pip/_vendor/tomli/__pycache__/__init__.cpython-312.pyc,,
754
+ pip/_vendor/tomli/__pycache__/_parser.cpython-312.pyc,,
755
+ pip/_vendor/tomli/__pycache__/_re.cpython-312.pyc,,
756
+ pip/_vendor/tomli/__pycache__/_types.cpython-312.pyc,,
757
+ pip/_vendor/tomli/_parser.py,sha256=9w8LG0jB7fwmZZWB0vVXbeejDHcl4ANIJxB2scEnDlA,25591
758
+ pip/_vendor/tomli/_re.py,sha256=sh4sBDRgO94KJZwNIrgdcyV_qQast50YvzOAUGpRDKA,3171
759
+ pip/_vendor/tomli/_types.py,sha256=-GTG2VUqkpxwMqzmVO4F7ybKddIbAnuAHXfmWQcTi3Q,254
760
+ pip/_vendor/tomli/py.typed,sha256=8PjyZ1aVoQpRVvt71muvuq5qE-jTFZkK-GLHkhdebmc,26
761
+ pip/_vendor/truststore/__init__.py,sha256=WIDeyzWm7EVX44g354M25vpRXbeY1lsPH6EmUJUcq4o,1264
762
+ pip/_vendor/truststore/__pycache__/__init__.cpython-312.pyc,,
763
+ pip/_vendor/truststore/__pycache__/_api.cpython-312.pyc,,
764
+ pip/_vendor/truststore/__pycache__/_macos.cpython-312.pyc,,
765
+ pip/_vendor/truststore/__pycache__/_openssl.cpython-312.pyc,,
766
+ pip/_vendor/truststore/__pycache__/_ssl_constants.cpython-312.pyc,,
767
+ pip/_vendor/truststore/__pycache__/_windows.cpython-312.pyc,,
768
+ pip/_vendor/truststore/_api.py,sha256=GeXRNTlxPZ3kif4kNoh6JY0oE4QRzTGcgXr6l_X_Gk0,10555
769
+ pip/_vendor/truststore/_macos.py,sha256=nZlLkOmszUE0g6ryRwBVGY5COzPyudcsiJtDWarM5LQ,20503
770
+ pip/_vendor/truststore/_openssl.py,sha256=LLUZ7ZGaio-i5dpKKjKCSeSufmn6T8pi9lDcFnvSyq0,2324
771
+ pip/_vendor/truststore/_ssl_constants.py,sha256=NUD4fVKdSD02ri7-db0tnO0VqLP9aHuzmStcW7tAl08,1130
772
+ pip/_vendor/truststore/_windows.py,sha256=rAHyKYD8M7t-bXfG8VgOVa3TpfhVhbt4rZQlO45YuP8,17993
773
+ pip/_vendor/truststore/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
774
+ pip/_vendor/typing_extensions.py,sha256=78hFl0HpDY-ylHUVCnWdU5nTHxUP2-S-3wEZk6CQmLk,134499
775
+ pip/_vendor/urllib3/__init__.py,sha256=iXLcYiJySn0GNbWOOZDDApgBL1JgP44EZ8i1760S8Mc,3333
776
+ pip/_vendor/urllib3/__pycache__/__init__.cpython-312.pyc,,
777
+ pip/_vendor/urllib3/__pycache__/_collections.cpython-312.pyc,,
778
+ pip/_vendor/urllib3/__pycache__/_version.cpython-312.pyc,,
779
+ pip/_vendor/urllib3/__pycache__/connection.cpython-312.pyc,,
780
+ pip/_vendor/urllib3/__pycache__/connectionpool.cpython-312.pyc,,
781
+ pip/_vendor/urllib3/__pycache__/exceptions.cpython-312.pyc,,
782
+ pip/_vendor/urllib3/__pycache__/fields.cpython-312.pyc,,
783
+ pip/_vendor/urllib3/__pycache__/filepost.cpython-312.pyc,,
784
+ pip/_vendor/urllib3/__pycache__/poolmanager.cpython-312.pyc,,
785
+ pip/_vendor/urllib3/__pycache__/request.cpython-312.pyc,,
786
+ pip/_vendor/urllib3/__pycache__/response.cpython-312.pyc,,
787
+ pip/_vendor/urllib3/_collections.py,sha256=pyASJJhW7wdOpqJj9QJA8FyGRfr8E8uUUhqUvhF0728,11372
788
+ pip/_vendor/urllib3/_version.py,sha256=t9wGB6ooOTXXgiY66K1m6BZS1CJyXHAU8EoWDTe6Shk,64
789
+ pip/_vendor/urllib3/connection.py,sha256=ttIA909BrbTUzwkqEe_TzZVh4JOOj7g61Ysei2mrwGg,20314
790
+ pip/_vendor/urllib3/connectionpool.py,sha256=e2eiAwNbFNCKxj4bwDKNK-w7HIdSz3OmMxU_TIt-evQ,40408
791
+ pip/_vendor/urllib3/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
792
+ pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-312.pyc,,
793
+ pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-312.pyc,,
794
+ pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-312.pyc,,
795
+ pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-312.pyc,,
796
+ pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-312.pyc,,
797
+ pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-312.pyc,,
798
+ pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-312.pyc,,
799
+ pip/_vendor/urllib3/contrib/_appengine_environ.py,sha256=bDbyOEhW2CKLJcQqAKAyrEHN-aklsyHFKq6vF8ZFsmk,957
800
+ pip/_vendor/urllib3/contrib/_securetransport/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
801
+ pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-312.pyc,,
802
+ pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-312.pyc,,
803
+ pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-312.pyc,,
804
+ pip/_vendor/urllib3/contrib/_securetransport/bindings.py,sha256=4Xk64qIkPBt09A5q-RIFUuDhNc9mXilVapm7WnYnzRw,17632
805
+ pip/_vendor/urllib3/contrib/_securetransport/low_level.py,sha256=B2JBB2_NRP02xK6DCa1Pa9IuxrPwxzDzZbixQkb7U9M,13922
806
+ pip/_vendor/urllib3/contrib/appengine.py,sha256=VR68eAVE137lxTgjBDwCna5UiBZTOKa01Aj_-5BaCz4,11036
807
+ pip/_vendor/urllib3/contrib/ntlmpool.py,sha256=NlfkW7WMdW8ziqudopjHoW299og1BTWi0IeIibquFwk,4528
808
+ pip/_vendor/urllib3/contrib/pyopenssl.py,sha256=hDJh4MhyY_p-oKlFcYcQaVQRDv6GMmBGuW9yjxyeejM,17081
809
+ pip/_vendor/urllib3/contrib/securetransport.py,sha256=Fef1IIUUFHqpevzXiDPbIGkDKchY2FVKeVeLGR1Qq3g,34446
810
+ pip/_vendor/urllib3/contrib/socks.py,sha256=aRi9eWXo9ZEb95XUxef4Z21CFlnnjbEiAo9HOseoMt4,7097
811
+ pip/_vendor/urllib3/exceptions.py,sha256=0Mnno3KHTNfXRfY7638NufOPkUb6mXOm-Lqj-4x2w8A,8217
812
+ pip/_vendor/urllib3/fields.py,sha256=kvLDCg_JmH1lLjUUEY_FLS8UhY7hBvDPuVETbY8mdrM,8579
813
+ pip/_vendor/urllib3/filepost.py,sha256=5b_qqgRHVlL7uLtdAYBzBh-GHmU5AfJVt_2N0XS3PeY,2440
814
+ pip/_vendor/urllib3/packages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
815
+ pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-312.pyc,,
816
+ pip/_vendor/urllib3/packages/__pycache__/six.cpython-312.pyc,,
817
+ pip/_vendor/urllib3/packages/backports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
818
+ pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-312.pyc,,
819
+ pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-312.pyc,,
820
+ pip/_vendor/urllib3/packages/backports/__pycache__/weakref_finalize.cpython-312.pyc,,
821
+ pip/_vendor/urllib3/packages/backports/makefile.py,sha256=nbzt3i0agPVP07jqqgjhaYjMmuAi_W5E0EywZivVO8E,1417
822
+ pip/_vendor/urllib3/packages/backports/weakref_finalize.py,sha256=tRCal5OAhNSRyb0DhHp-38AtIlCsRP8BxF3NX-6rqIA,5343
823
+ pip/_vendor/urllib3/packages/six.py,sha256=b9LM0wBXv7E7SrbCjAm4wwN-hrH-iNxv18LgWNMMKPo,34665
824
+ pip/_vendor/urllib3/poolmanager.py,sha256=aWyhXRtNO4JUnCSVVqKTKQd8EXTvUm1VN9pgs2bcONo,19990
825
+ pip/_vendor/urllib3/request.py,sha256=YTWFNr7QIwh7E1W9dde9LM77v2VWTJ5V78XuTTw7D1A,6691
826
+ pip/_vendor/urllib3/response.py,sha256=fmDJAFkG71uFTn-sVSTh2Iw0WmcXQYqkbRjihvwBjU8,30641
827
+ pip/_vendor/urllib3/util/__init__.py,sha256=JEmSmmqqLyaw8P51gUImZh8Gwg9i1zSe-DoqAitn2nc,1155
828
+ pip/_vendor/urllib3/util/__pycache__/__init__.cpython-312.pyc,,
829
+ pip/_vendor/urllib3/util/__pycache__/connection.cpython-312.pyc,,
830
+ pip/_vendor/urllib3/util/__pycache__/proxy.cpython-312.pyc,,
831
+ pip/_vendor/urllib3/util/__pycache__/queue.cpython-312.pyc,,
832
+ pip/_vendor/urllib3/util/__pycache__/request.cpython-312.pyc,,
833
+ pip/_vendor/urllib3/util/__pycache__/response.cpython-312.pyc,,
834
+ pip/_vendor/urllib3/util/__pycache__/retry.cpython-312.pyc,,
835
+ pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-312.pyc,,
836
+ pip/_vendor/urllib3/util/__pycache__/ssl_match_hostname.cpython-312.pyc,,
837
+ pip/_vendor/urllib3/util/__pycache__/ssltransport.cpython-312.pyc,,
838
+ pip/_vendor/urllib3/util/__pycache__/timeout.cpython-312.pyc,,
839
+ pip/_vendor/urllib3/util/__pycache__/url.cpython-312.pyc,,
840
+ pip/_vendor/urllib3/util/__pycache__/wait.cpython-312.pyc,,
841
+ pip/_vendor/urllib3/util/connection.py,sha256=5Lx2B1PW29KxBn2T0xkN1CBgRBa3gGVJBKoQoRogEVk,4901
842
+ pip/_vendor/urllib3/util/proxy.py,sha256=zUvPPCJrp6dOF0N4GAVbOcl6o-4uXKSrGiTkkr5vUS4,1605
843
+ pip/_vendor/urllib3/util/queue.py,sha256=nRgX8_eX-_VkvxoX096QWoz8Ps0QHUAExILCY_7PncM,498
844
+ pip/_vendor/urllib3/util/request.py,sha256=C0OUt2tcU6LRiQJ7YYNP9GvPrSvl7ziIBekQ-5nlBZk,3997
845
+ pip/_vendor/urllib3/util/response.py,sha256=GJpg3Egi9qaJXRwBh5wv-MNuRWan5BIu40oReoxWP28,3510
846
+ pip/_vendor/urllib3/util/retry.py,sha256=6ENvOZ8PBDzh8kgixpql9lIrb2dxH-k7ZmBanJF2Ng4,22050
847
+ pip/_vendor/urllib3/util/ssl_.py,sha256=QDuuTxPSCj1rYtZ4xpD7Ux-r20TD50aHyqKyhQ7Bq4A,17460
848
+ pip/_vendor/urllib3/util/ssl_match_hostname.py,sha256=Ir4cZVEjmAk8gUAIHWSi7wtOO83UCYABY2xFD1Ql_WA,5758
849
+ pip/_vendor/urllib3/util/ssltransport.py,sha256=NA-u5rMTrDFDFC8QzRKUEKMG0561hOD4qBTr3Z4pv6E,6895
850
+ pip/_vendor/urllib3/util/timeout.py,sha256=cwq4dMk87mJHSBktK1miYJ-85G-3T3RmT20v7SFCpno,10168
851
+ pip/_vendor/urllib3/util/url.py,sha256=lCAE7M5myA8EDdW0sJuyyZhVB9K_j38ljWhHAnFaWoE,14296
852
+ pip/_vendor/urllib3/util/wait.py,sha256=fOX0_faozG2P7iVojQoE1mbydweNyTcm-hXEfFrTtLI,5403
853
+ pip/_vendor/vendor.txt,sha256=EW-E3cE5XEAtVFzGInikArOMDxGP0DLUWzXpY4RZfFY,333
854
+ pip/py.typed,sha256=EBVvvPRTn_eIpz5e5QztSCdrMX7Qwd7VP93RSoIlZ2I,286
lib/python3.12/site-packages/pip-25.0.1.dist-info/REQUESTED ADDED
File without changes
lib/python3.12/site-packages/pip-25.0.1.dist-info/WHEEL ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (75.8.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
lib/python3.12/site-packages/pip-25.0.1.dist-info/entry_points.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ [console_scripts]
2
+ pip = pip._internal.cli.main:main
3
+ pip3 = pip._internal.cli.main:main
lib/python3.12/site-packages/pip-25.0.1.dist-info/top_level.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ pip
lib/python3.12/site-packages/sentry_sdk/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (1.26 kB). View file
 
lib/python3.12/site-packages/sentry_sdk/__pycache__/_batcher.cpython-312.pyc ADDED
Binary file (6.19 kB). View file
 
lib/python3.12/site-packages/sentry_sdk/__pycache__/_compat.cpython-312.pyc ADDED
Binary file (3.51 kB). View file
 
lib/python3.12/site-packages/sentry_sdk/__pycache__/_init_implementation.cpython-312.pyc ADDED
Binary file (2.89 kB). View file
 
lib/python3.12/site-packages/sentry_sdk/__pycache__/_log_batcher.cpython-312.pyc ADDED
Binary file (2.52 kB). View file
 
lib/python3.12/site-packages/sentry_sdk/__pycache__/_lru_cache.cpython-312.pyc ADDED
Binary file (2.39 kB). View file
 
lib/python3.12/site-packages/sentry_sdk/__pycache__/_metrics_batcher.cpython-312.pyc ADDED
Binary file (1.95 kB). View file
 
lib/python3.12/site-packages/sentry_sdk/__pycache__/_queue.cpython-312.pyc ADDED
Binary file (13.4 kB). View file