pip 25.1.1__py3-none-any.whl → 25.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pip/__init__.py +3 -3
- pip/_internal/__init__.py +2 -2
- pip/_internal/build_env.py +118 -94
- pip/_internal/cache.py +16 -14
- pip/_internal/cli/autocompletion.py +13 -4
- pip/_internal/cli/base_command.py +18 -7
- pip/_internal/cli/cmdoptions.py +14 -9
- pip/_internal/cli/command_context.py +4 -3
- pip/_internal/cli/index_command.py +11 -9
- pip/_internal/cli/main.py +3 -2
- pip/_internal/cli/main_parser.py +4 -3
- pip/_internal/cli/parser.py +26 -22
- pip/_internal/cli/progress_bars.py +19 -12
- pip/_internal/cli/req_command.py +16 -12
- pip/_internal/cli/spinners.py +81 -5
- pip/_internal/commands/__init__.py +5 -3
- pip/_internal/commands/cache.py +18 -15
- pip/_internal/commands/check.py +1 -2
- pip/_internal/commands/completion.py +1 -2
- pip/_internal/commands/configuration.py +26 -18
- pip/_internal/commands/debug.py +8 -6
- pip/_internal/commands/download.py +2 -3
- pip/_internal/commands/freeze.py +2 -3
- pip/_internal/commands/hash.py +1 -2
- pip/_internal/commands/help.py +1 -2
- pip/_internal/commands/index.py +15 -9
- pip/_internal/commands/inspect.py +4 -4
- pip/_internal/commands/install.py +44 -39
- pip/_internal/commands/list.py +35 -26
- pip/_internal/commands/lock.py +1 -2
- pip/_internal/commands/search.py +14 -12
- pip/_internal/commands/show.py +14 -11
- pip/_internal/commands/uninstall.py +1 -2
- pip/_internal/commands/wheel.py +2 -3
- pip/_internal/configuration.py +39 -25
- pip/_internal/distributions/base.py +6 -4
- pip/_internal/distributions/installed.py +8 -4
- pip/_internal/distributions/sdist.py +20 -13
- pip/_internal/distributions/wheel.py +6 -4
- pip/_internal/exceptions.py +58 -39
- pip/_internal/index/collector.py +24 -29
- pip/_internal/index/package_finder.py +70 -61
- pip/_internal/index/sources.py +17 -14
- pip/_internal/locations/__init__.py +18 -16
- pip/_internal/locations/_distutils.py +12 -11
- pip/_internal/locations/_sysconfig.py +5 -4
- pip/_internal/locations/base.py +4 -3
- pip/_internal/main.py +2 -2
- pip/_internal/metadata/__init__.py +8 -6
- pip/_internal/metadata/_json.py +5 -4
- pip/_internal/metadata/base.py +22 -27
- pip/_internal/metadata/importlib/_compat.py +6 -4
- pip/_internal/metadata/importlib/_dists.py +12 -17
- pip/_internal/metadata/importlib/_envs.py +9 -6
- pip/_internal/metadata/pkg_resources.py +11 -14
- pip/_internal/models/direct_url.py +24 -21
- pip/_internal/models/format_control.py +5 -5
- pip/_internal/models/installation_report.py +4 -3
- pip/_internal/models/link.py +39 -34
- pip/_internal/models/pylock.py +27 -22
- pip/_internal/models/search_scope.py +6 -7
- pip/_internal/models/selection_prefs.py +3 -3
- pip/_internal/models/target_python.py +10 -9
- pip/_internal/models/wheel.py +7 -5
- pip/_internal/network/auth.py +20 -22
- pip/_internal/network/cache.py +22 -6
- pip/_internal/network/download.py +169 -141
- pip/_internal/network/lazy_wheel.py +10 -7
- pip/_internal/network/session.py +32 -27
- pip/_internal/network/utils.py +2 -2
- pip/_internal/network/xmlrpc.py +2 -2
- pip/_internal/operations/build/build_tracker.py +10 -8
- pip/_internal/operations/build/wheel.py +3 -2
- pip/_internal/operations/build/wheel_editable.py +3 -2
- pip/_internal/operations/build/wheel_legacy.py +9 -8
- pip/_internal/operations/check.py +21 -26
- pip/_internal/operations/freeze.py +12 -9
- pip/_internal/operations/install/editable_legacy.py +5 -3
- pip/_internal/operations/install/wheel.py +49 -41
- pip/_internal/operations/prepare.py +35 -30
- pip/_internal/pyproject.py +7 -10
- pip/_internal/req/__init__.py +12 -10
- pip/_internal/req/constructors.py +33 -31
- pip/_internal/req/req_dependency_group.py +7 -11
- pip/_internal/req/req_file.py +32 -35
- pip/_internal/req/req_install.py +37 -34
- pip/_internal/req/req_set.py +4 -5
- pip/_internal/req/req_uninstall.py +20 -17
- pip/_internal/resolution/base.py +3 -3
- pip/_internal/resolution/legacy/resolver.py +21 -20
- pip/_internal/resolution/resolvelib/base.py +16 -13
- pip/_internal/resolution/resolvelib/candidates.py +29 -26
- pip/_internal/resolution/resolvelib/factory.py +41 -50
- pip/_internal/resolution/resolvelib/found_candidates.py +11 -9
- pip/_internal/resolution/resolvelib/provider.py +15 -20
- pip/_internal/resolution/resolvelib/reporter.py +5 -3
- pip/_internal/resolution/resolvelib/requirements.py +8 -6
- pip/_internal/resolution/resolvelib/resolver.py +39 -23
- pip/_internal/self_outdated_check.py +8 -6
- pip/_internal/utils/appdirs.py +1 -2
- pip/_internal/utils/compat.py +7 -1
- pip/_internal/utils/compatibility_tags.py +17 -16
- pip/_internal/utils/deprecation.py +11 -9
- pip/_internal/utils/direct_url_helpers.py +2 -2
- pip/_internal/utils/egg_link.py +6 -5
- pip/_internal/utils/entrypoints.py +3 -2
- pip/_internal/utils/filesystem.py +8 -5
- pip/_internal/utils/filetypes.py +4 -6
- pip/_internal/utils/glibc.py +6 -5
- pip/_internal/utils/hashes.py +9 -6
- pip/_internal/utils/logging.py +8 -5
- pip/_internal/utils/misc.py +37 -45
- pip/_internal/utils/packaging.py +3 -2
- pip/_internal/utils/retry.py +7 -4
- pip/_internal/utils/setuptools_build.py +12 -10
- pip/_internal/utils/subprocess.py +20 -17
- pip/_internal/utils/temp_dir.py +10 -12
- pip/_internal/utils/unpacking.py +6 -4
- pip/_internal/utils/urls.py +1 -1
- pip/_internal/utils/virtualenv.py +3 -2
- pip/_internal/utils/wheel.py +3 -4
- pip/_internal/vcs/bazaar.py +26 -8
- pip/_internal/vcs/git.py +59 -24
- pip/_internal/vcs/mercurial.py +34 -11
- pip/_internal/vcs/subversion.py +27 -16
- pip/_internal/vcs/versioncontrol.py +56 -51
- pip/_internal/wheel_builder.py +14 -12
- pip/_vendor/cachecontrol/__init__.py +1 -1
- pip/_vendor/certifi/__init__.py +1 -1
- pip/_vendor/certifi/cacert.pem +102 -221
- pip/_vendor/certifi/core.py +1 -32
- pip/_vendor/distlib/__init__.py +2 -2
- pip/_vendor/distlib/scripts.py +1 -1
- pip/_vendor/msgpack/__init__.py +2 -2
- pip/_vendor/pkg_resources/__init__.py +1 -1
- pip/_vendor/platformdirs/version.py +2 -2
- pip/_vendor/pygments/__init__.py +1 -1
- pip/_vendor/requests/__version__.py +2 -2
- pip/_vendor/requests/compat.py +12 -0
- pip/_vendor/requests/models.py +3 -1
- pip/_vendor/requests/utils.py +6 -16
- pip/_vendor/resolvelib/__init__.py +3 -3
- pip/_vendor/resolvelib/reporters.py +1 -1
- pip/_vendor/resolvelib/resolvers/__init__.py +4 -4
- pip/_vendor/resolvelib/resolvers/resolution.py +91 -10
- pip/_vendor/rich/__main__.py +12 -40
- pip/_vendor/rich/_inspect.py +1 -1
- pip/_vendor/rich/_ratio.py +1 -7
- pip/_vendor/rich/align.py +1 -7
- pip/_vendor/rich/box.py +1 -7
- pip/_vendor/rich/console.py +25 -20
- pip/_vendor/rich/control.py +1 -7
- pip/_vendor/rich/diagnose.py +1 -0
- pip/_vendor/rich/emoji.py +1 -6
- pip/_vendor/rich/live.py +32 -7
- pip/_vendor/rich/live_render.py +1 -7
- pip/_vendor/rich/logging.py +1 -1
- pip/_vendor/rich/panel.py +3 -4
- pip/_vendor/rich/progress.py +15 -15
- pip/_vendor/rich/spinner.py +7 -13
- pip/_vendor/rich/syntax.py +24 -5
- pip/_vendor/rich/traceback.py +32 -17
- pip/_vendor/truststore/_api.py +1 -1
- pip/_vendor/vendor.txt +9 -10
- {pip-25.1.1.dist-info → pip-25.2.dist-info}/METADATA +26 -4
- {pip-25.1.1.dist-info → pip-25.2.dist-info}/RECORD +193 -180
- {pip-25.1.1.dist-info → pip-25.2.dist-info}/WHEEL +1 -1
- {pip-25.1.1.dist-info → pip-25.2.dist-info}/licenses/AUTHORS.txt +12 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/cachecontrol/LICENSE.txt +13 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/certifi/LICENSE +20 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/dependency_groups/LICENSE.txt +9 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/distlib/LICENSE.txt +284 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/distro/LICENSE +202 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/idna/LICENSE.md +31 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/msgpack/COPYING +14 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/packaging/LICENSE +3 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/packaging/LICENSE.APACHE +177 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/packaging/LICENSE.BSD +23 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/pkg_resources/LICENSE +17 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/platformdirs/LICENSE +21 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/pygments/LICENSE +25 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/pyproject_hooks/LICENSE +21 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/requests/LICENSE +175 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/resolvelib/LICENSE +13 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/rich/LICENSE +19 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/tomli/LICENSE +21 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/tomli/LICENSE-HEADER +3 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/tomli_w/LICENSE +21 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/truststore/LICENSE +21 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/urllib3/LICENSE.txt +21 -0
- pip/_vendor/distlib/database.py +0 -1329
- pip/_vendor/distlib/index.py +0 -508
- pip/_vendor/distlib/locators.py +0 -1295
- pip/_vendor/distlib/manifest.py +0 -384
- pip/_vendor/distlib/markers.py +0 -162
- pip/_vendor/distlib/metadata.py +0 -1031
- pip/_vendor/distlib/version.py +0 -750
- pip/_vendor/distlib/wheel.py +0 -1100
- pip/_vendor/typing_extensions.py +0 -4584
- {pip-25.1.1.dist-info → pip-25.2.dist-info}/entry_points.txt +0 -0
- {pip-25.1.1.dist-info → pip-25.2.dist-info}/licenses/LICENSE.txt +0 -0
- {pip-25.1.1.dist-info → pip-25.2.dist-info}/top_level.txt +0 -0
pip/_vendor/distlib/manifest.py
DELETED
|
@@ -1,384 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
#
|
|
3
|
-
# Copyright (C) 2012-2023 Python Software Foundation.
|
|
4
|
-
# See LICENSE.txt and CONTRIBUTORS.txt.
|
|
5
|
-
#
|
|
6
|
-
"""
|
|
7
|
-
Class representing the list of files in a distribution.
|
|
8
|
-
|
|
9
|
-
Equivalent to distutils.filelist, but fixes some problems.
|
|
10
|
-
"""
|
|
11
|
-
import fnmatch
|
|
12
|
-
import logging
|
|
13
|
-
import os
|
|
14
|
-
import re
|
|
15
|
-
import sys
|
|
16
|
-
|
|
17
|
-
from . import DistlibException
|
|
18
|
-
from .compat import fsdecode
|
|
19
|
-
from .util import convert_path
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
__all__ = ['Manifest']
|
|
23
|
-
|
|
24
|
-
logger = logging.getLogger(__name__)
|
|
25
|
-
|
|
26
|
-
# a \ followed by some spaces + EOL
|
|
27
|
-
_COLLAPSE_PATTERN = re.compile('\\\\w*\n', re.M)
|
|
28
|
-
_COMMENTED_LINE = re.compile('#.*?(?=\n)|\n(?=$)', re.M | re.S)
|
|
29
|
-
|
|
30
|
-
#
|
|
31
|
-
# Due to the different results returned by fnmatch.translate, we need
|
|
32
|
-
# to do slightly different processing for Python 2.7 and 3.2 ... this needed
|
|
33
|
-
# to be brought in for Python 3.6 onwards.
|
|
34
|
-
#
|
|
35
|
-
_PYTHON_VERSION = sys.version_info[:2]
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
class Manifest(object):
|
|
39
|
-
"""
|
|
40
|
-
A list of files built by exploring the filesystem and filtered by applying various
|
|
41
|
-
patterns to what we find there.
|
|
42
|
-
"""
|
|
43
|
-
|
|
44
|
-
def __init__(self, base=None):
|
|
45
|
-
"""
|
|
46
|
-
Initialise an instance.
|
|
47
|
-
|
|
48
|
-
:param base: The base directory to explore under.
|
|
49
|
-
"""
|
|
50
|
-
self.base = os.path.abspath(os.path.normpath(base or os.getcwd()))
|
|
51
|
-
self.prefix = self.base + os.sep
|
|
52
|
-
self.allfiles = None
|
|
53
|
-
self.files = set()
|
|
54
|
-
|
|
55
|
-
#
|
|
56
|
-
# Public API
|
|
57
|
-
#
|
|
58
|
-
|
|
59
|
-
def findall(self):
|
|
60
|
-
"""Find all files under the base and set ``allfiles`` to the absolute
|
|
61
|
-
pathnames of files found.
|
|
62
|
-
"""
|
|
63
|
-
from stat import S_ISREG, S_ISDIR, S_ISLNK
|
|
64
|
-
|
|
65
|
-
self.allfiles = allfiles = []
|
|
66
|
-
root = self.base
|
|
67
|
-
stack = [root]
|
|
68
|
-
pop = stack.pop
|
|
69
|
-
push = stack.append
|
|
70
|
-
|
|
71
|
-
while stack:
|
|
72
|
-
root = pop()
|
|
73
|
-
names = os.listdir(root)
|
|
74
|
-
|
|
75
|
-
for name in names:
|
|
76
|
-
fullname = os.path.join(root, name)
|
|
77
|
-
|
|
78
|
-
# Avoid excess stat calls -- just one will do, thank you!
|
|
79
|
-
stat = os.stat(fullname)
|
|
80
|
-
mode = stat.st_mode
|
|
81
|
-
if S_ISREG(mode):
|
|
82
|
-
allfiles.append(fsdecode(fullname))
|
|
83
|
-
elif S_ISDIR(mode) and not S_ISLNK(mode):
|
|
84
|
-
push(fullname)
|
|
85
|
-
|
|
86
|
-
def add(self, item):
|
|
87
|
-
"""
|
|
88
|
-
Add a file to the manifest.
|
|
89
|
-
|
|
90
|
-
:param item: The pathname to add. This can be relative to the base.
|
|
91
|
-
"""
|
|
92
|
-
if not item.startswith(self.prefix):
|
|
93
|
-
item = os.path.join(self.base, item)
|
|
94
|
-
self.files.add(os.path.normpath(item))
|
|
95
|
-
|
|
96
|
-
def add_many(self, items):
|
|
97
|
-
"""
|
|
98
|
-
Add a list of files to the manifest.
|
|
99
|
-
|
|
100
|
-
:param items: The pathnames to add. These can be relative to the base.
|
|
101
|
-
"""
|
|
102
|
-
for item in items:
|
|
103
|
-
self.add(item)
|
|
104
|
-
|
|
105
|
-
def sorted(self, wantdirs=False):
|
|
106
|
-
"""
|
|
107
|
-
Return sorted files in directory order
|
|
108
|
-
"""
|
|
109
|
-
|
|
110
|
-
def add_dir(dirs, d):
|
|
111
|
-
dirs.add(d)
|
|
112
|
-
logger.debug('add_dir added %s', d)
|
|
113
|
-
if d != self.base:
|
|
114
|
-
parent, _ = os.path.split(d)
|
|
115
|
-
assert parent not in ('', '/')
|
|
116
|
-
add_dir(dirs, parent)
|
|
117
|
-
|
|
118
|
-
result = set(self.files) # make a copy!
|
|
119
|
-
if wantdirs:
|
|
120
|
-
dirs = set()
|
|
121
|
-
for f in result:
|
|
122
|
-
add_dir(dirs, os.path.dirname(f))
|
|
123
|
-
result |= dirs
|
|
124
|
-
return [os.path.join(*path_tuple) for path_tuple in
|
|
125
|
-
sorted(os.path.split(path) for path in result)]
|
|
126
|
-
|
|
127
|
-
def clear(self):
|
|
128
|
-
"""Clear all collected files."""
|
|
129
|
-
self.files = set()
|
|
130
|
-
self.allfiles = []
|
|
131
|
-
|
|
132
|
-
def process_directive(self, directive):
|
|
133
|
-
"""
|
|
134
|
-
Process a directive which either adds some files from ``allfiles`` to
|
|
135
|
-
``files``, or removes some files from ``files``.
|
|
136
|
-
|
|
137
|
-
:param directive: The directive to process. This should be in a format
|
|
138
|
-
compatible with distutils ``MANIFEST.in`` files:
|
|
139
|
-
|
|
140
|
-
http://docs.python.org/distutils/sourcedist.html#commands
|
|
141
|
-
"""
|
|
142
|
-
# Parse the line: split it up, make sure the right number of words
|
|
143
|
-
# is there, and return the relevant words. 'action' is always
|
|
144
|
-
# defined: it's the first word of the line. Which of the other
|
|
145
|
-
# three are defined depends on the action; it'll be either
|
|
146
|
-
# patterns, (dir and patterns), or (dirpattern).
|
|
147
|
-
action, patterns, thedir, dirpattern = self._parse_directive(directive)
|
|
148
|
-
|
|
149
|
-
# OK, now we know that the action is valid and we have the
|
|
150
|
-
# right number of words on the line for that action -- so we
|
|
151
|
-
# can proceed with minimal error-checking.
|
|
152
|
-
if action == 'include':
|
|
153
|
-
for pattern in patterns:
|
|
154
|
-
if not self._include_pattern(pattern, anchor=True):
|
|
155
|
-
logger.warning('no files found matching %r', pattern)
|
|
156
|
-
|
|
157
|
-
elif action == 'exclude':
|
|
158
|
-
for pattern in patterns:
|
|
159
|
-
self._exclude_pattern(pattern, anchor=True)
|
|
160
|
-
|
|
161
|
-
elif action == 'global-include':
|
|
162
|
-
for pattern in patterns:
|
|
163
|
-
if not self._include_pattern(pattern, anchor=False):
|
|
164
|
-
logger.warning('no files found matching %r '
|
|
165
|
-
'anywhere in distribution', pattern)
|
|
166
|
-
|
|
167
|
-
elif action == 'global-exclude':
|
|
168
|
-
for pattern in patterns:
|
|
169
|
-
self._exclude_pattern(pattern, anchor=False)
|
|
170
|
-
|
|
171
|
-
elif action == 'recursive-include':
|
|
172
|
-
for pattern in patterns:
|
|
173
|
-
if not self._include_pattern(pattern, prefix=thedir):
|
|
174
|
-
logger.warning('no files found matching %r '
|
|
175
|
-
'under directory %r', pattern, thedir)
|
|
176
|
-
|
|
177
|
-
elif action == 'recursive-exclude':
|
|
178
|
-
for pattern in patterns:
|
|
179
|
-
self._exclude_pattern(pattern, prefix=thedir)
|
|
180
|
-
|
|
181
|
-
elif action == 'graft':
|
|
182
|
-
if not self._include_pattern(None, prefix=dirpattern):
|
|
183
|
-
logger.warning('no directories found matching %r',
|
|
184
|
-
dirpattern)
|
|
185
|
-
|
|
186
|
-
elif action == 'prune':
|
|
187
|
-
if not self._exclude_pattern(None, prefix=dirpattern):
|
|
188
|
-
logger.warning('no previously-included directories found '
|
|
189
|
-
'matching %r', dirpattern)
|
|
190
|
-
else: # pragma: no cover
|
|
191
|
-
# This should never happen, as it should be caught in
|
|
192
|
-
# _parse_template_line
|
|
193
|
-
raise DistlibException(
|
|
194
|
-
'invalid action %r' % action)
|
|
195
|
-
|
|
196
|
-
#
|
|
197
|
-
# Private API
|
|
198
|
-
#
|
|
199
|
-
|
|
200
|
-
def _parse_directive(self, directive):
|
|
201
|
-
"""
|
|
202
|
-
Validate a directive.
|
|
203
|
-
:param directive: The directive to validate.
|
|
204
|
-
:return: A tuple of action, patterns, thedir, dir_patterns
|
|
205
|
-
"""
|
|
206
|
-
words = directive.split()
|
|
207
|
-
if len(words) == 1 and words[0] not in ('include', 'exclude',
|
|
208
|
-
'global-include',
|
|
209
|
-
'global-exclude',
|
|
210
|
-
'recursive-include',
|
|
211
|
-
'recursive-exclude',
|
|
212
|
-
'graft', 'prune'):
|
|
213
|
-
# no action given, let's use the default 'include'
|
|
214
|
-
words.insert(0, 'include')
|
|
215
|
-
|
|
216
|
-
action = words[0]
|
|
217
|
-
patterns = thedir = dir_pattern = None
|
|
218
|
-
|
|
219
|
-
if action in ('include', 'exclude',
|
|
220
|
-
'global-include', 'global-exclude'):
|
|
221
|
-
if len(words) < 2:
|
|
222
|
-
raise DistlibException(
|
|
223
|
-
'%r expects <pattern1> <pattern2> ...' % action)
|
|
224
|
-
|
|
225
|
-
patterns = [convert_path(word) for word in words[1:]]
|
|
226
|
-
|
|
227
|
-
elif action in ('recursive-include', 'recursive-exclude'):
|
|
228
|
-
if len(words) < 3:
|
|
229
|
-
raise DistlibException(
|
|
230
|
-
'%r expects <dir> <pattern1> <pattern2> ...' % action)
|
|
231
|
-
|
|
232
|
-
thedir = convert_path(words[1])
|
|
233
|
-
patterns = [convert_path(word) for word in words[2:]]
|
|
234
|
-
|
|
235
|
-
elif action in ('graft', 'prune'):
|
|
236
|
-
if len(words) != 2:
|
|
237
|
-
raise DistlibException(
|
|
238
|
-
'%r expects a single <dir_pattern>' % action)
|
|
239
|
-
|
|
240
|
-
dir_pattern = convert_path(words[1])
|
|
241
|
-
|
|
242
|
-
else:
|
|
243
|
-
raise DistlibException('unknown action %r' % action)
|
|
244
|
-
|
|
245
|
-
return action, patterns, thedir, dir_pattern
|
|
246
|
-
|
|
247
|
-
def _include_pattern(self, pattern, anchor=True, prefix=None,
|
|
248
|
-
is_regex=False):
|
|
249
|
-
"""Select strings (presumably filenames) from 'self.files' that
|
|
250
|
-
match 'pattern', a Unix-style wildcard (glob) pattern.
|
|
251
|
-
|
|
252
|
-
Patterns are not quite the same as implemented by the 'fnmatch'
|
|
253
|
-
module: '*' and '?' match non-special characters, where "special"
|
|
254
|
-
is platform-dependent: slash on Unix; colon, slash, and backslash on
|
|
255
|
-
DOS/Windows; and colon on Mac OS.
|
|
256
|
-
|
|
257
|
-
If 'anchor' is true (the default), then the pattern match is more
|
|
258
|
-
stringent: "*.py" will match "foo.py" but not "foo/bar.py". If
|
|
259
|
-
'anchor' is false, both of these will match.
|
|
260
|
-
|
|
261
|
-
If 'prefix' is supplied, then only filenames starting with 'prefix'
|
|
262
|
-
(itself a pattern) and ending with 'pattern', with anything in between
|
|
263
|
-
them, will match. 'anchor' is ignored in this case.
|
|
264
|
-
|
|
265
|
-
If 'is_regex' is true, 'anchor' and 'prefix' are ignored, and
|
|
266
|
-
'pattern' is assumed to be either a string containing a regex or a
|
|
267
|
-
regex object -- no translation is done, the regex is just compiled
|
|
268
|
-
and used as-is.
|
|
269
|
-
|
|
270
|
-
Selected strings will be added to self.files.
|
|
271
|
-
|
|
272
|
-
Return True if files are found.
|
|
273
|
-
"""
|
|
274
|
-
# XXX docstring lying about what the special chars are?
|
|
275
|
-
found = False
|
|
276
|
-
pattern_re = self._translate_pattern(pattern, anchor, prefix, is_regex)
|
|
277
|
-
|
|
278
|
-
# delayed loading of allfiles list
|
|
279
|
-
if self.allfiles is None:
|
|
280
|
-
self.findall()
|
|
281
|
-
|
|
282
|
-
for name in self.allfiles:
|
|
283
|
-
if pattern_re.search(name):
|
|
284
|
-
self.files.add(name)
|
|
285
|
-
found = True
|
|
286
|
-
return found
|
|
287
|
-
|
|
288
|
-
def _exclude_pattern(self, pattern, anchor=True, prefix=None,
|
|
289
|
-
is_regex=False):
|
|
290
|
-
"""Remove strings (presumably filenames) from 'files' that match
|
|
291
|
-
'pattern'.
|
|
292
|
-
|
|
293
|
-
Other parameters are the same as for 'include_pattern()', above.
|
|
294
|
-
The list 'self.files' is modified in place. Return True if files are
|
|
295
|
-
found.
|
|
296
|
-
|
|
297
|
-
This API is public to allow e.g. exclusion of SCM subdirs, e.g. when
|
|
298
|
-
packaging source distributions
|
|
299
|
-
"""
|
|
300
|
-
found = False
|
|
301
|
-
pattern_re = self._translate_pattern(pattern, anchor, prefix, is_regex)
|
|
302
|
-
for f in list(self.files):
|
|
303
|
-
if pattern_re.search(f):
|
|
304
|
-
self.files.remove(f)
|
|
305
|
-
found = True
|
|
306
|
-
return found
|
|
307
|
-
|
|
308
|
-
def _translate_pattern(self, pattern, anchor=True, prefix=None,
|
|
309
|
-
is_regex=False):
|
|
310
|
-
"""Translate a shell-like wildcard pattern to a compiled regular
|
|
311
|
-
expression.
|
|
312
|
-
|
|
313
|
-
Return the compiled regex. If 'is_regex' true,
|
|
314
|
-
then 'pattern' is directly compiled to a regex (if it's a string)
|
|
315
|
-
or just returned as-is (assumes it's a regex object).
|
|
316
|
-
"""
|
|
317
|
-
if is_regex:
|
|
318
|
-
if isinstance(pattern, str):
|
|
319
|
-
return re.compile(pattern)
|
|
320
|
-
else:
|
|
321
|
-
return pattern
|
|
322
|
-
|
|
323
|
-
if _PYTHON_VERSION > (3, 2):
|
|
324
|
-
# ditch start and end characters
|
|
325
|
-
start, _, end = self._glob_to_re('_').partition('_')
|
|
326
|
-
|
|
327
|
-
if pattern:
|
|
328
|
-
pattern_re = self._glob_to_re(pattern)
|
|
329
|
-
if _PYTHON_VERSION > (3, 2):
|
|
330
|
-
assert pattern_re.startswith(start) and pattern_re.endswith(end)
|
|
331
|
-
else:
|
|
332
|
-
pattern_re = ''
|
|
333
|
-
|
|
334
|
-
base = re.escape(os.path.join(self.base, ''))
|
|
335
|
-
if prefix is not None:
|
|
336
|
-
# ditch end of pattern character
|
|
337
|
-
if _PYTHON_VERSION <= (3, 2):
|
|
338
|
-
empty_pattern = self._glob_to_re('')
|
|
339
|
-
prefix_re = self._glob_to_re(prefix)[:-len(empty_pattern)]
|
|
340
|
-
else:
|
|
341
|
-
prefix_re = self._glob_to_re(prefix)
|
|
342
|
-
assert prefix_re.startswith(start) and prefix_re.endswith(end)
|
|
343
|
-
prefix_re = prefix_re[len(start): len(prefix_re) - len(end)]
|
|
344
|
-
sep = os.sep
|
|
345
|
-
if os.sep == '\\':
|
|
346
|
-
sep = r'\\'
|
|
347
|
-
if _PYTHON_VERSION <= (3, 2):
|
|
348
|
-
pattern_re = '^' + base + sep.join((prefix_re,
|
|
349
|
-
'.*' + pattern_re))
|
|
350
|
-
else:
|
|
351
|
-
pattern_re = pattern_re[len(start): len(pattern_re) - len(end)]
|
|
352
|
-
pattern_re = r'%s%s%s%s.*%s%s' % (start, base, prefix_re, sep,
|
|
353
|
-
pattern_re, end)
|
|
354
|
-
else: # no prefix -- respect anchor flag
|
|
355
|
-
if anchor:
|
|
356
|
-
if _PYTHON_VERSION <= (3, 2):
|
|
357
|
-
pattern_re = '^' + base + pattern_re
|
|
358
|
-
else:
|
|
359
|
-
pattern_re = r'%s%s%s' % (start, base, pattern_re[len(start):])
|
|
360
|
-
|
|
361
|
-
return re.compile(pattern_re)
|
|
362
|
-
|
|
363
|
-
def _glob_to_re(self, pattern):
|
|
364
|
-
"""Translate a shell-like glob pattern to a regular expression.
|
|
365
|
-
|
|
366
|
-
Return a string containing the regex. Differs from
|
|
367
|
-
'fnmatch.translate()' in that '*' does not match "special characters"
|
|
368
|
-
(which are platform-specific).
|
|
369
|
-
"""
|
|
370
|
-
pattern_re = fnmatch.translate(pattern)
|
|
371
|
-
|
|
372
|
-
# '?' and '*' in the glob pattern become '.' and '.*' in the RE, which
|
|
373
|
-
# IMHO is wrong -- '?' and '*' aren't supposed to match slash in Unix,
|
|
374
|
-
# and by extension they shouldn't match such "special characters" under
|
|
375
|
-
# any OS. So change all non-escaped dots in the RE to match any
|
|
376
|
-
# character except the special characters (currently: just os.sep).
|
|
377
|
-
sep = os.sep
|
|
378
|
-
if os.sep == '\\':
|
|
379
|
-
# we're using a regex to manipulate a regex, so we need
|
|
380
|
-
# to escape the backslash twice
|
|
381
|
-
sep = r'\\\\'
|
|
382
|
-
escaped = r'\1[^%s]' % sep
|
|
383
|
-
pattern_re = re.sub(r'((?<!\\)(\\\\)*)\.', escaped, pattern_re)
|
|
384
|
-
return pattern_re
|
pip/_vendor/distlib/markers.py
DELETED
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
#
|
|
3
|
-
# Copyright (C) 2012-2023 Vinay Sajip.
|
|
4
|
-
# Licensed to the Python Software Foundation under a contributor agreement.
|
|
5
|
-
# See LICENSE.txt and CONTRIBUTORS.txt.
|
|
6
|
-
#
|
|
7
|
-
"""
|
|
8
|
-
Parser for the environment markers micro-language defined in PEP 508.
|
|
9
|
-
"""
|
|
10
|
-
|
|
11
|
-
# Note: In PEP 345, the micro-language was Python compatible, so the ast
|
|
12
|
-
# module could be used to parse it. However, PEP 508 introduced operators such
|
|
13
|
-
# as ~= and === which aren't in Python, necessitating a different approach.
|
|
14
|
-
|
|
15
|
-
import os
|
|
16
|
-
import re
|
|
17
|
-
import sys
|
|
18
|
-
import platform
|
|
19
|
-
|
|
20
|
-
from .compat import string_types
|
|
21
|
-
from .util import in_venv, parse_marker
|
|
22
|
-
from .version import LegacyVersion as LV
|
|
23
|
-
|
|
24
|
-
__all__ = ['interpret']
|
|
25
|
-
|
|
26
|
-
_VERSION_PATTERN = re.compile(r'((\d+(\.\d+)*\w*)|\'(\d+(\.\d+)*\w*)\'|\"(\d+(\.\d+)*\w*)\")')
|
|
27
|
-
_VERSION_MARKERS = {'python_version', 'python_full_version'}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
def _is_version_marker(s):
|
|
31
|
-
return isinstance(s, string_types) and s in _VERSION_MARKERS
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
def _is_literal(o):
|
|
35
|
-
if not isinstance(o, string_types) or not o:
|
|
36
|
-
return False
|
|
37
|
-
return o[0] in '\'"'
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
def _get_versions(s):
|
|
41
|
-
return {LV(m.groups()[0]) for m in _VERSION_PATTERN.finditer(s)}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
class Evaluator(object):
|
|
45
|
-
"""
|
|
46
|
-
This class is used to evaluate marker expressions.
|
|
47
|
-
"""
|
|
48
|
-
|
|
49
|
-
operations = {
|
|
50
|
-
'==': lambda x, y: x == y,
|
|
51
|
-
'===': lambda x, y: x == y,
|
|
52
|
-
'~=': lambda x, y: x == y or x > y,
|
|
53
|
-
'!=': lambda x, y: x != y,
|
|
54
|
-
'<': lambda x, y: x < y,
|
|
55
|
-
'<=': lambda x, y: x == y or x < y,
|
|
56
|
-
'>': lambda x, y: x > y,
|
|
57
|
-
'>=': lambda x, y: x == y or x > y,
|
|
58
|
-
'and': lambda x, y: x and y,
|
|
59
|
-
'or': lambda x, y: x or y,
|
|
60
|
-
'in': lambda x, y: x in y,
|
|
61
|
-
'not in': lambda x, y: x not in y,
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
def evaluate(self, expr, context):
|
|
65
|
-
"""
|
|
66
|
-
Evaluate a marker expression returned by the :func:`parse_requirement`
|
|
67
|
-
function in the specified context.
|
|
68
|
-
"""
|
|
69
|
-
if isinstance(expr, string_types):
|
|
70
|
-
if expr[0] in '\'"':
|
|
71
|
-
result = expr[1:-1]
|
|
72
|
-
else:
|
|
73
|
-
if expr not in context:
|
|
74
|
-
raise SyntaxError('unknown variable: %s' % expr)
|
|
75
|
-
result = context[expr]
|
|
76
|
-
else:
|
|
77
|
-
assert isinstance(expr, dict)
|
|
78
|
-
op = expr['op']
|
|
79
|
-
if op not in self.operations:
|
|
80
|
-
raise NotImplementedError('op not implemented: %s' % op)
|
|
81
|
-
elhs = expr['lhs']
|
|
82
|
-
erhs = expr['rhs']
|
|
83
|
-
if _is_literal(expr['lhs']) and _is_literal(expr['rhs']):
|
|
84
|
-
raise SyntaxError('invalid comparison: %s %s %s' % (elhs, op, erhs))
|
|
85
|
-
|
|
86
|
-
lhs = self.evaluate(elhs, context)
|
|
87
|
-
rhs = self.evaluate(erhs, context)
|
|
88
|
-
if ((_is_version_marker(elhs) or _is_version_marker(erhs)) and
|
|
89
|
-
op in ('<', '<=', '>', '>=', '===', '==', '!=', '~=')):
|
|
90
|
-
lhs = LV(lhs)
|
|
91
|
-
rhs = LV(rhs)
|
|
92
|
-
elif _is_version_marker(elhs) and op in ('in', 'not in'):
|
|
93
|
-
lhs = LV(lhs)
|
|
94
|
-
rhs = _get_versions(rhs)
|
|
95
|
-
result = self.operations[op](lhs, rhs)
|
|
96
|
-
return result
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
_DIGITS = re.compile(r'\d+\.\d+')
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
def default_context():
|
|
103
|
-
|
|
104
|
-
def format_full_version(info):
|
|
105
|
-
version = '%s.%s.%s' % (info.major, info.minor, info.micro)
|
|
106
|
-
kind = info.releaselevel
|
|
107
|
-
if kind != 'final':
|
|
108
|
-
version += kind[0] + str(info.serial)
|
|
109
|
-
return version
|
|
110
|
-
|
|
111
|
-
if hasattr(sys, 'implementation'):
|
|
112
|
-
implementation_version = format_full_version(sys.implementation.version)
|
|
113
|
-
implementation_name = sys.implementation.name
|
|
114
|
-
else:
|
|
115
|
-
implementation_version = '0'
|
|
116
|
-
implementation_name = ''
|
|
117
|
-
|
|
118
|
-
ppv = platform.python_version()
|
|
119
|
-
m = _DIGITS.match(ppv)
|
|
120
|
-
pv = m.group(0)
|
|
121
|
-
result = {
|
|
122
|
-
'implementation_name': implementation_name,
|
|
123
|
-
'implementation_version': implementation_version,
|
|
124
|
-
'os_name': os.name,
|
|
125
|
-
'platform_machine': platform.machine(),
|
|
126
|
-
'platform_python_implementation': platform.python_implementation(),
|
|
127
|
-
'platform_release': platform.release(),
|
|
128
|
-
'platform_system': platform.system(),
|
|
129
|
-
'platform_version': platform.version(),
|
|
130
|
-
'platform_in_venv': str(in_venv()),
|
|
131
|
-
'python_full_version': ppv,
|
|
132
|
-
'python_version': pv,
|
|
133
|
-
'sys_platform': sys.platform,
|
|
134
|
-
}
|
|
135
|
-
return result
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
DEFAULT_CONTEXT = default_context()
|
|
139
|
-
del default_context
|
|
140
|
-
|
|
141
|
-
evaluator = Evaluator()
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
def interpret(marker, execution_context=None):
|
|
145
|
-
"""
|
|
146
|
-
Interpret a marker and return a result depending on environment.
|
|
147
|
-
|
|
148
|
-
:param marker: The marker to interpret.
|
|
149
|
-
:type marker: str
|
|
150
|
-
:param execution_context: The context used for name lookup.
|
|
151
|
-
:type execution_context: mapping
|
|
152
|
-
"""
|
|
153
|
-
try:
|
|
154
|
-
expr, rest = parse_marker(marker)
|
|
155
|
-
except Exception as e:
|
|
156
|
-
raise SyntaxError('Unable to interpret marker syntax: %s: %s' % (marker, e))
|
|
157
|
-
if rest and rest[0] != '#':
|
|
158
|
-
raise SyntaxError('unexpected trailing data in marker: %s: %s' % (marker, rest))
|
|
159
|
-
context = dict(DEFAULT_CONTEXT)
|
|
160
|
-
if execution_context:
|
|
161
|
-
context.update(execution_context)
|
|
162
|
-
return evaluator.evaluate(expr, context)
|