Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
installer.py156 linesDownload Raw Back to setuptools
1from __future__ import annotations2 3import glob4import itertools5import os6import subprocess7import sys8import tempfile9 10import packaging.requirements11import packaging.utils12 13from . import _reqs14from ._importlib import metadata15from .warnings import SetuptoolsDeprecationWarning16from .wheel import Wheel17 18from distutils import log19from distutils.errors import DistutilsError20 21 22def _fixup_find_links(find_links):23    """Ensure find-links option end-up being a list of strings."""24    if isinstance(find_links, str):25        return find_links.split()26    assert isinstance(find_links, (tuple, list))27    return find_links28 29 30def fetch_build_egg(dist, req) -> metadata.Distribution | metadata.PathDistribution:31    """Fetch an egg needed for building.32 33    Use pip/wheel to fetch/build a wheel."""34    _DeprecatedInstaller.emit()35    _warn_wheel_not_available(dist)36    return _fetch_build_egg_no_warn(dist, req)37 38 39def _present(req):40    return any(_dist_matches_req(dist, req) for dist in metadata.distributions())41 42 43def _fetch_build_eggs(dist, requires: _reqs._StrOrIter) -> list[metadata.Distribution]:44    _DeprecatedInstaller.emit(stacklevel=3)45    _warn_wheel_not_available(dist)46 47    parsed_reqs = _reqs.parse(requires)48 49    missing_reqs = itertools.filterfalse(_present, parsed_reqs)50 51    needed_reqs = (52        req for req in missing_reqs if not req.marker or req.marker.evaluate()53    )54    resolved_dists = [_fetch_build_egg_no_warn(dist, req) for req in needed_reqs]55    for dist in resolved_dists:56        # dist.locate_file('') is the directory containing EGG-INFO, where the importabl57        # contents can be found.58        sys.path.insert(0, str(dist.locate_file('')))59    return resolved_dists60 61 62def _dist_matches_req(egg_dist, req):63    return (64        packaging.utils.canonicalize_name(egg_dist.name)65        == packaging.utils.canonicalize_name(req.name)66        and egg_dist.version in req.specifier67    )68 69 70def _fetch_build_egg_no_warn(dist, req):  # noqa: C901  # is too complex (16)  # FIXME71    # Ignore environment markers; if supplied, it is required.72    req = strip_marker(req)73    # Take easy_install options into account, but do not override relevant74    # pip environment variables (like PIP_INDEX_URL or PIP_QUIET); they'll75    # take precedence.76    opts = dist.get_option_dict('easy_install')77    if 'allow_hosts' in opts:78        raise DistutilsError(79            'the `allow-hosts` option is not supported '80            'when using pip to install requirements.'81        )82    quiet = 'PIP_QUIET' not in os.environ and 'PIP_VERBOSE' not in os.environ83    if 'PIP_INDEX_URL' in os.environ:84        index_url = None85    elif 'index_url' in opts:86        index_url = opts['index_url'][1]87    else:88        index_url = None89    find_links = (90        _fixup_find_links(opts['find_links'][1])[:] if 'find_links' in opts else []91    )92    if dist.dependency_links:93        find_links.extend(dist.dependency_links)94    eggs_dir = os.path.realpath(dist.get_egg_cache_dir())95    cached_dists = metadata.Distribution.discover(path=glob.glob(f'{eggs_dir}/*.egg'))96    for egg_dist in cached_dists:97        if _dist_matches_req(egg_dist, req):98            return egg_dist99    with tempfile.TemporaryDirectory() as tmpdir:100        cmd = [101            sys.executable,102            '-m',103            'pip',104            '--disable-pip-version-check',105            'wheel',106            '--no-deps',107            '-w',108            tmpdir,109        ]110        if quiet:111            cmd.append('--quiet')112        if index_url is not None:113            cmd.extend(('--index-url', index_url))114        for link in find_links or []:115            cmd.extend(('--find-links', link))116        # If requirement is a PEP 508 direct URL, directly pass117        # the URL to pip, as `req @ url` does not work on the118        # command line.119        cmd.append(req.url or str(req))120        try:121            subprocess.check_call(cmd)122        except subprocess.CalledProcessError as e:123            raise DistutilsError(str(e)) from e124        wheel = Wheel(glob.glob(os.path.join(tmpdir, '*.whl'))[0])125        dist_location = os.path.join(eggs_dir, wheel.egg_name())126        wheel.install_as_egg(dist_location)127        return metadata.Distribution.at(dist_location + '/EGG-INFO')128 129 130def strip_marker(req) -> packaging.requirements.Requirement:131    """132    Return a new requirement without the environment marker to avoid133    calling pip with something like `babel; extra == "i18n"`, which134    would always be ignored.135    """136    # create a copy to avoid mutating the input137    req = packaging.requirements.Requirement(str(req))138    req.marker = None139    return req140 141 142def _warn_wheel_not_available(dist):143    try:144        metadata.distribution('wheel')145    except metadata.PackageNotFoundError:146        dist.announce('WARNING: The wheel package is not available.', log.WARN)147 148 149class _DeprecatedInstaller(SetuptoolsDeprecationWarning):150    _SUMMARY = "setuptools.installer and fetch_build_eggs are deprecated."151    _DETAILS = """152    Requirements should be satisfied by a PEP 517 installer.153    If you are using pip, you can try `pip install --use-pep517`.154    """155    _DUE_DATE = 2025, 10, 31156 
codekingpro/portable-devtools · Team Ai