android13/external/python/setuptools/tools/vendored.py

188 lines
5.8 KiB
Python

import re
import sys
import string
import subprocess
import venv
from tempfile import TemporaryDirectory
from path import Path
def remove_all(paths):
for path in paths:
path.rmtree() if path.isdir() else path.remove()
def update_vendored():
update_pkg_resources()
update_setuptools()
def rewrite_packaging(pkg_files, new_root):
"""
Rewrite imports in packaging to redirect to vendored copies.
"""
for file in pkg_files.glob('*.py'):
text = file.text()
text = re.sub(r' (pyparsing)', rf' {new_root}.\1', text)
text = text.replace(
'from six.moves.urllib import parse',
'from urllib import parse',
)
file.write_text(text)
def rewrite_jaraco_text(pkg_files, new_root):
"""
Rewrite imports in jaraco.text to redirect to vendored copies.
"""
for file in pkg_files.glob('*.py'):
text = file.read_text()
text = re.sub(r' (jaraco\.)', rf' {new_root}.\1', text)
text = re.sub(r' (importlib_resources)', rf' {new_root}.\1', text)
# suppress loading of lorem_ipsum; ref #3072
text = re.sub(r'^lorem_ipsum.*\n$', '', text, flags=re.M)
file.write_text(text)
def rewrite_jaraco(pkg_files, new_root):
"""
Rewrite imports in jaraco.functools to redirect to vendored copies.
"""
for file in pkg_files.glob('*.py'):
text = file.read_text()
text = re.sub(r' (more_itertools)', rf' {new_root}.\1', text)
file.write_text(text)
# required for zip-packaged setuptools #3084
pkg_files.joinpath('__init__.py').write_text('')
def rewrite_importlib_resources(pkg_files, new_root):
"""
Rewrite imports in importlib_resources to redirect to vendored copies.
"""
for file in pkg_files.glob('*.py'):
text = file.read_text().replace('importlib_resources.abc', '.abc')
text = text.replace('zipp', '..zipp')
file.write_text(text)
def rewrite_importlib_metadata(pkg_files, new_root):
"""
Rewrite imports in importlib_metadata to redirect to vendored copies.
"""
for file in pkg_files.glob('*.py'):
text = file.read_text().replace('typing_extensions', '..typing_extensions')
text = text.replace('import zipp', 'from .. import zipp')
file.write_text(text)
def rewrite_more_itertools(pkg_files: Path):
"""
Defer import of concurrent.futures. Workaround for #3090.
"""
more_file = pkg_files.joinpath('more.py')
text = more_file.read_text()
text = re.sub(r'^.*concurrent.futures.*?\n', '', text, flags=re.MULTILINE)
text = re.sub(
'ThreadPoolExecutor',
'__import__("concurrent.futures").futures.ThreadPoolExecutor',
text,
)
more_file.write_text(text)
def rewrite_nspektr(pkg_files: Path, new_root):
for file in pkg_files.glob('*.py'):
text = file.read_text()
text = re.sub(r' (more_itertools)', rf' {new_root}.\1', text)
text = re.sub(r' (jaraco\.\w+)', rf' {new_root}.\1', text)
text = re.sub(r' (packaging)', rf' {new_root}.\1', text)
text = re.sub(r' (importlib_metadata)', rf' {new_root}.\1', text)
file.write_text(text)
def clean(vendor):
"""
Remove all files out of the vendor directory except the meta
data (as pip uninstall doesn't support -t).
"""
remove_all(
path
for path in vendor.glob('*')
if path.basename() != 'vendored.txt'
)
def install(vendor):
clean(vendor)
install_args = [
sys.executable,
'-m', 'pip',
'install',
'-r', str(vendor / 'vendored.txt'),
'-t', str(vendor),
]
subprocess.check_call(install_args)
(vendor / '__init__.py').write_text('')
def update_pkg_resources():
vendor = Path('pkg_resources/_vendor')
install(vendor)
rewrite_packaging(vendor / 'packaging', 'pkg_resources.extern')
rewrite_jaraco_text(vendor / 'jaraco/text', 'pkg_resources.extern')
rewrite_jaraco(vendor / 'jaraco', 'pkg_resources.extern')
rewrite_importlib_resources(vendor / 'importlib_resources', 'pkg_resources.extern')
rewrite_more_itertools(vendor / "more_itertools")
def update_setuptools():
vendor = Path('setuptools/_vendor')
install(vendor)
install_validate_pyproject(vendor)
rewrite_packaging(vendor / 'packaging', 'setuptools.extern')
rewrite_jaraco_text(vendor / 'jaraco/text', 'setuptools.extern')
rewrite_jaraco(vendor / 'jaraco', 'setuptools.extern')
rewrite_importlib_resources(vendor / 'importlib_resources', 'setuptools.extern')
rewrite_importlib_metadata(vendor / 'importlib_metadata', 'setuptools.extern')
rewrite_more_itertools(vendor / "more_itertools")
rewrite_nspektr(vendor / "nspektr", 'setuptools.extern')
def install_validate_pyproject(vendor):
"""``validate-pyproject`` can be vendorized to remove all dependencies"""
req = next(
(x for x in (vendor / "vendored.txt").lines() if 'validate-pyproject' in x),
"validate-pyproject[all]"
)
pkg, _, _ = req.strip(string.whitespace + "#").partition("#")
pkg = pkg.strip()
opts = {}
if sys.version_info[:2] >= (3, 10):
opts["ignore_cleanup_errors"] = True
with TemporaryDirectory(**opts) as tmp:
env_builder = venv.EnvBuilder(with_pip=True)
env_builder.create(tmp)
context = env_builder.ensure_directories(tmp)
venv_python = getattr(context, 'env_exec_cmd', context.env_exe)
subprocess.check_call([venv_python, "-m", "pip", "install", pkg])
cmd = [
venv_python,
"-m",
"validate_pyproject.vendoring",
f"--output-dir={vendor / '_validate_pyproject' !s}",
"--enable-plugins",
"setuptools",
"distutils",
"--very-verbose"
]
subprocess.check_call(cmd)
__name__ == '__main__' and update_vendored()