Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
keewenaw
GitHub Repository: keewenaw/ethereum-wallet-cracker
Path: blob/main/test/lib/python3.9/site-packages/setuptools/wheel.py
4798 views
1
"""Wheels support."""
2
3
from distutils.util import get_platform
4
from distutils import log
5
import email
6
import itertools
7
import os
8
import posixpath
9
import re
10
import zipfile
11
12
import pkg_resources
13
import setuptools
14
from pkg_resources import parse_version
15
from setuptools.extern.packaging.tags import sys_tags
16
from setuptools.extern.packaging.utils import canonicalize_name
17
from setuptools.command.egg_info import write_requirements
18
from setuptools.archive_util import _unpack_zipfile_obj
19
20
21
WHEEL_NAME = re.compile(
22
r"""^(?P<project_name>.+?)-(?P<version>\d.*?)
23
((-(?P<build>\d.*?))?-(?P<py_version>.+?)-(?P<abi>.+?)-(?P<platform>.+?)
24
)\.whl$""",
25
re.VERBOSE).match
26
27
NAMESPACE_PACKAGE_INIT = \
28
"__import__('pkg_resources').declare_namespace(__name__)\n"
29
30
31
def unpack(src_dir, dst_dir):
32
'''Move everything under `src_dir` to `dst_dir`, and delete the former.'''
33
for dirpath, dirnames, filenames in os.walk(src_dir):
34
subdir = os.path.relpath(dirpath, src_dir)
35
for f in filenames:
36
src = os.path.join(dirpath, f)
37
dst = os.path.join(dst_dir, subdir, f)
38
os.renames(src, dst)
39
for n, d in reversed(list(enumerate(dirnames))):
40
src = os.path.join(dirpath, d)
41
dst = os.path.join(dst_dir, subdir, d)
42
if not os.path.exists(dst):
43
# Directory does not exist in destination,
44
# rename it and prune it from os.walk list.
45
os.renames(src, dst)
46
del dirnames[n]
47
# Cleanup.
48
for dirpath, dirnames, filenames in os.walk(src_dir, topdown=True):
49
assert not filenames
50
os.rmdir(dirpath)
51
52
53
class Wheel:
54
55
def __init__(self, filename):
56
match = WHEEL_NAME(os.path.basename(filename))
57
if match is None:
58
raise ValueError('invalid wheel name: %r' % filename)
59
self.filename = filename
60
for k, v in match.groupdict().items():
61
setattr(self, k, v)
62
63
def tags(self):
64
'''List tags (py_version, abi, platform) supported by this wheel.'''
65
return itertools.product(
66
self.py_version.split('.'),
67
self.abi.split('.'),
68
self.platform.split('.'),
69
)
70
71
def is_compatible(self):
72
'''Is the wheel is compatible with the current platform?'''
73
supported_tags = set(
74
(t.interpreter, t.abi, t.platform) for t in sys_tags())
75
return next((True for t in self.tags() if t in supported_tags), False)
76
77
def egg_name(self):
78
return pkg_resources.Distribution(
79
project_name=self.project_name, version=self.version,
80
platform=(None if self.platform == 'any' else get_platform()),
81
).egg_name() + '.egg'
82
83
def get_dist_info(self, zf):
84
# find the correct name of the .dist-info dir in the wheel file
85
for member in zf.namelist():
86
dirname = posixpath.dirname(member)
87
if (dirname.endswith('.dist-info') and
88
canonicalize_name(dirname).startswith(
89
canonicalize_name(self.project_name))):
90
return dirname
91
raise ValueError("unsupported wheel format. .dist-info not found")
92
93
def install_as_egg(self, destination_eggdir):
94
'''Install wheel as an egg directory.'''
95
with zipfile.ZipFile(self.filename) as zf:
96
self._install_as_egg(destination_eggdir, zf)
97
98
def _install_as_egg(self, destination_eggdir, zf):
99
dist_basename = '%s-%s' % (self.project_name, self.version)
100
dist_info = self.get_dist_info(zf)
101
dist_data = '%s.data' % dist_basename
102
egg_info = os.path.join(destination_eggdir, 'EGG-INFO')
103
104
self._convert_metadata(zf, destination_eggdir, dist_info, egg_info)
105
self._move_data_entries(destination_eggdir, dist_data)
106
self._fix_namespace_packages(egg_info, destination_eggdir)
107
108
@staticmethod
109
def _convert_metadata(zf, destination_eggdir, dist_info, egg_info):
110
def get_metadata(name):
111
with zf.open(posixpath.join(dist_info, name)) as fp:
112
value = fp.read().decode('utf-8')
113
return email.parser.Parser().parsestr(value)
114
115
wheel_metadata = get_metadata('WHEEL')
116
# Check wheel format version is supported.
117
wheel_version = parse_version(wheel_metadata.get('Wheel-Version'))
118
wheel_v1 = (
119
parse_version('1.0') <= wheel_version < parse_version('2.0dev0')
120
)
121
if not wheel_v1:
122
raise ValueError(
123
'unsupported wheel format version: %s' % wheel_version)
124
# Extract to target directory.
125
_unpack_zipfile_obj(zf, destination_eggdir)
126
# Convert metadata.
127
dist_info = os.path.join(destination_eggdir, dist_info)
128
dist = pkg_resources.Distribution.from_location(
129
destination_eggdir, dist_info,
130
metadata=pkg_resources.PathMetadata(destination_eggdir, dist_info),
131
)
132
133
# Note: Evaluate and strip markers now,
134
# as it's difficult to convert back from the syntax:
135
# foobar; "linux" in sys_platform and extra == 'test'
136
def raw_req(req):
137
req.marker = None
138
return str(req)
139
install_requires = list(map(raw_req, dist.requires()))
140
extras_require = {
141
extra: [
142
req
143
for req in map(raw_req, dist.requires((extra,)))
144
if req not in install_requires
145
]
146
for extra in dist.extras
147
}
148
os.rename(dist_info, egg_info)
149
os.rename(
150
os.path.join(egg_info, 'METADATA'),
151
os.path.join(egg_info, 'PKG-INFO'),
152
)
153
setup_dist = setuptools.Distribution(
154
attrs=dict(
155
install_requires=install_requires,
156
extras_require=extras_require,
157
),
158
)
159
# Temporarily disable info traces.
160
log_threshold = log._global_log.threshold
161
log.set_threshold(log.WARN)
162
try:
163
write_requirements(
164
setup_dist.get_command_obj('egg_info'),
165
None,
166
os.path.join(egg_info, 'requires.txt'),
167
)
168
finally:
169
log.set_threshold(log_threshold)
170
171
@staticmethod
172
def _move_data_entries(destination_eggdir, dist_data):
173
"""Move data entries to their correct location."""
174
dist_data = os.path.join(destination_eggdir, dist_data)
175
dist_data_scripts = os.path.join(dist_data, 'scripts')
176
if os.path.exists(dist_data_scripts):
177
egg_info_scripts = os.path.join(
178
destination_eggdir, 'EGG-INFO', 'scripts')
179
os.mkdir(egg_info_scripts)
180
for entry in os.listdir(dist_data_scripts):
181
# Remove bytecode, as it's not properly handled
182
# during easy_install scripts install phase.
183
if entry.endswith('.pyc'):
184
os.unlink(os.path.join(dist_data_scripts, entry))
185
else:
186
os.rename(
187
os.path.join(dist_data_scripts, entry),
188
os.path.join(egg_info_scripts, entry),
189
)
190
os.rmdir(dist_data_scripts)
191
for subdir in filter(os.path.exists, (
192
os.path.join(dist_data, d)
193
for d in ('data', 'headers', 'purelib', 'platlib')
194
)):
195
unpack(subdir, destination_eggdir)
196
if os.path.exists(dist_data):
197
os.rmdir(dist_data)
198
199
@staticmethod
200
def _fix_namespace_packages(egg_info, destination_eggdir):
201
namespace_packages = os.path.join(
202
egg_info, 'namespace_packages.txt')
203
if os.path.exists(namespace_packages):
204
with open(namespace_packages) as fp:
205
namespace_packages = fp.read().split()
206
for mod in namespace_packages:
207
mod_dir = os.path.join(destination_eggdir, *mod.split('.'))
208
mod_init = os.path.join(mod_dir, '__init__.py')
209
if not os.path.exists(mod_dir):
210
os.mkdir(mod_dir)
211
if not os.path.exists(mod_init):
212
with open(mod_init, 'w') as fp:
213
fp.write(NAMESPACE_PACKAGE_INIT)
214
215