Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
__init__.py272 linesDownload Raw Back to setuptools
1"""Extensions to the 'distutils' for large or complex distributions"""2 3import functools4import os5import re6from typing import TYPE_CHECKING7 8import _distutils_hack.override  # noqa: F4019import distutils.core10from distutils.errors import DistutilsOptionError11from distutils.util import convert_path as _convert_path12 13from . import logging, monkey14from . import version as _version_module15from .depends import Require16from .discovery import PackageFinder, PEP420PackageFinder17from .dist import Distribution18from .extension import Extension19from .warnings import SetuptoolsDeprecationWarning20 21__all__ = [22    'setup',23    'Distribution',24    'Command',25    'Extension',26    'Require',27    'SetuptoolsDeprecationWarning',28    'find_packages',29    'find_namespace_packages',30]31 32__version__ = _version_module.__version__33 34bootstrap_install_from = None35 36 37find_packages = PackageFinder.find38find_namespace_packages = PEP420PackageFinder.find39 40 41def _install_setup_requires(attrs):42    # Note: do not use `setuptools.Distribution` directly, as43    # our PEP 517 backend patch `distutils.core.Distribution`.44    class MinimalDistribution(distutils.core.Distribution):45        """46        A minimal version of a distribution for supporting the47        fetch_build_eggs interface.48        """49 50        def __init__(self, attrs):51            _incl = 'dependency_links', 'setup_requires'52            filtered = {k: attrs[k] for k in set(_incl) & set(attrs)}53            super().__init__(filtered)54            # Prevent accidentally triggering discovery with incomplete set of attrs55            self.set_defaults._disable()56 57        def _get_project_config_files(self, filenames=None):58            """Ignore ``pyproject.toml``, they are not related to setup_requires"""59            try:60                cfg, toml = super()._split_standard_project_metadata(filenames)61                return cfg, ()62            except Exception:63                return filenames, ()64 65        def finalize_options(self):66            """67            Disable finalize_options to avoid building the working set.68            Ref #2158.69            """70 71    dist = MinimalDistribution(attrs)72 73    # Honor setup.cfg's options.74    dist.parse_config_files(ignore_option_errors=True)75    if dist.setup_requires:76        _fetch_build_eggs(dist)77 78 79def _fetch_build_eggs(dist):80    try:81        dist.fetch_build_eggs(dist.setup_requires)82    except Exception as ex:83        msg = """84        It is possible a package already installed in your system85        contains an version that is invalid according to PEP 440.86        You can try `pip install --use-pep517` as a workaround for this problem,87        or rely on a new virtual environment.88 89        If the problem refers to a package that is not installed yet,90        please contact that package's maintainers or distributors.91        """92        if "InvalidVersion" in ex.__class__.__name__:93            if hasattr(ex, "add_note"):94                ex.add_note(msg)  # PEP 67895            else:96                dist.announce(f"\n{msg}\n")97        raise98 99 100def setup(**attrs):101    # Make sure we have any requirements needed to interpret 'attrs'.102    logging.configure()103    _install_setup_requires(attrs)104    return distutils.core.setup(**attrs)105 106 107setup.__doc__ = distutils.core.setup.__doc__108 109if TYPE_CHECKING:110    # Work around a mypy issue where type[T] can't be used as a base: https://github.com/python/mypy/issues/10962111    _Command = distutils.core.Command112else:113    _Command = monkey.get_unpatched(distutils.core.Command)114 115 116class Command(_Command):117    """118    Setuptools internal actions are organized using a *command design pattern*.119    This means that each action (or group of closely related actions) executed during120    the build should be implemented as a ``Command`` subclass.121 122    These commands are abstractions and do not necessarily correspond to a command that123    can (or should) be executed via a terminal, in a CLI fashion (although historically124    they would).125 126    When creating a new command from scratch, custom defined classes **SHOULD** inherit127    from ``setuptools.Command`` and implement a few mandatory methods.128    Between these mandatory methods, are listed:129 130    .. method:: initialize_options(self)131 132        Set or (reset) all options/attributes/caches used by the command133        to their default values. Note that these values may be overwritten during134        the build.135 136    .. method:: finalize_options(self)137 138        Set final values for all options/attributes used by the command.139        Most of the time, each option/attribute/cache should only be set if it does not140        have any value yet (e.g. ``if self.attr is None: self.attr = val``).141 142    .. method:: run(self)143 144        Execute the actions intended by the command.145        (Side effects **SHOULD** only take place when ``run`` is executed,146        for example, creating new files or writing to the terminal output).147 148    A useful analogy for command classes is to think of them as subroutines with local149    variables called "options".  The options are "declared" in ``initialize_options()``150    and "defined" (given their final values, aka "finalized") in ``finalize_options()``,151    both of which must be defined by every command class. The "body" of the subroutine,152    (where it does all the work) is the ``run()`` method.153    Between ``initialize_options()`` and ``finalize_options()``, ``setuptools`` may set154    the values for options/attributes based on user's input (or circumstance),155    which means that the implementation should be careful to not overwrite values in156    ``finalize_options`` unless necessary.157 158    Please note that other commands (or other parts of setuptools) may also overwrite159    the values of the command's options/attributes multiple times during the build160    process.161    Therefore it is important to consistently implement ``initialize_options()`` and162    ``finalize_options()``. For example, all derived attributes (or attributes that163    depend on the value of other attributes) **SHOULD** be recomputed in164    ``finalize_options``.165 166    When overwriting existing commands, custom defined classes **MUST** abide by the167    same APIs implemented by the original class. They also **SHOULD** inherit from the168    original class.169    """170 171    command_consumes_arguments = False172    distribution: Distribution  # override distutils.dist.Distribution with setuptools.dist.Distribution173 174    def __init__(self, dist: Distribution, **kw):175        """176        Construct the command for dist, updating177        vars(self) with any keyword parameters.178        """179        super().__init__(dist)180        vars(self).update(kw)181 182    def _ensure_stringlike(self, option, what, default=None):183        val = getattr(self, option)184        if val is None:185            setattr(self, option, default)186            return default187        elif not isinstance(val, str):188            raise DistutilsOptionError(189                "'%s' must be a %s (got `%s`)" % (option, what, val)190            )191        return val192 193    def ensure_string_list(self, option):194        r"""Ensure that 'option' is a list of strings.  If 'option' is195        currently a string, we split it either on /,\s*/ or /\s+/, so196        "foo bar baz", "foo,bar,baz", and "foo,   bar baz" all become197        ["foo", "bar", "baz"].198 199        ..200           TODO: This method seems to be similar to the one in ``distutils.cmd``201           Probably it is just here for backward compatibility with old Python versions?202 203        :meta private:204        """205        val = getattr(self, option)206        if val is None:207            return208        elif isinstance(val, str):209            setattr(self, option, re.split(r',\s*|\s+', val))210        else:211            if isinstance(val, list):212                ok = all(isinstance(v, str) for v in val)213            else:214                ok = False215            if not ok:216                raise DistutilsOptionError(217                    "'%s' must be a list of strings (got %r)" % (option, val)218                )219 220    def reinitialize_command(self, command, reinit_subcommands=0, **kw):221        cmd = _Command.reinitialize_command(self, command, reinit_subcommands)222        vars(cmd).update(kw)223        return cmd224 225 226def _find_all_simple(path):227    """228    Find all files under 'path'229    """230    results = (231        os.path.join(base, file)232        for base, dirs, files in os.walk(path, followlinks=True)233        for file in files234    )235    return filter(os.path.isfile, results)236 237 238def findall(dir=os.curdir):239    """240    Find all files under 'dir' and return the list of full filenames.241    Unless dir is '.', return full filenames with dir prepended.242    """243    files = _find_all_simple(dir)244    if dir == os.curdir:245        make_rel = functools.partial(os.path.relpath, start=dir)246        files = map(make_rel, files)247    return list(files)248 249 250@functools.wraps(_convert_path)251def convert_path(pathname):252    SetuptoolsDeprecationWarning.emit(253        "Access to implementation detail",254        """255        The function `convert_path` is not provided by setuptools itself,256        and therefore not part of the public API.257 258        Its direct usage by 3rd-party packages is considered improper and the function259        may be removed in the future.260        """,261        due_date=(2023, 12, 13),  # initial deprecation 2022-03-25, see #3201262    )263    return _convert_path(pathname)264 265 266class sic(str):267    """Treat this string as-is (https://en.wikipedia.org/wiki/Sic)"""268 269 270# Apply monkey patches271monkey.patch_all()272 
codekingpro/portable-devtools · Team Ai