Path: blob/master/ invest-robot-contest_TinkoffBotTwitch-main/venv/lib/python3.8/site-packages/setuptools/build_meta.py
7763 views
"""A PEP 517 interface to setuptools12Previously, when a user or a command line tool (let's call it a "frontend")3needed to make a request of setuptools to take a certain action, for4example, generating a list of installation requirements, the frontend would5would call "setup.py egg_info" or "setup.py bdist_wheel" on the command line.67PEP 517 defines a different method of interfacing with setuptools. Rather8than calling "setup.py" directly, the frontend should:9101. Set the current directory to the directory with a setup.py file112. Import this module into a safe python interpreter (one in which12setuptools can potentially set global variables or crash hard).133. Call one of the functions defined in PEP 517.1415What each function does is defined in PEP 517. However, here is a "casual"16definition of the functions (this definition should not be relied on for17bug reports or API stability):1819- `build_wheel`: build a wheel in the folder and return the basename20- `get_requires_for_build_wheel`: get the `setup_requires` to build21- `prepare_metadata_for_build_wheel`: get the `install_requires`22- `build_sdist`: build an sdist in the folder and return the basename23- `get_requires_for_build_sdist`: get the `setup_requires` to build2425Again, this is not a formal definition! Just a "taste" of the module.26"""2728import io29import os30import sys31import tokenize32import shutil33import contextlib3435import setuptools36import distutils37from setuptools.py31compat import TemporaryDirectory3839from pkg_resources import parse_requirements4041__all__ = ['get_requires_for_build_sdist',42'get_requires_for_build_wheel',43'prepare_metadata_for_build_wheel',44'build_wheel',45'build_sdist',46'__legacy__',47'SetupRequirementsError']484950class SetupRequirementsError(BaseException):51def __init__(self, specifiers):52self.specifiers = specifiers535455class Distribution(setuptools.dist.Distribution):56def fetch_build_eggs(self, specifiers):57specifier_list = list(map(str, parse_requirements(specifiers)))5859raise SetupRequirementsError(specifier_list)6061@classmethod62@contextlib.contextmanager63def patch(cls):64"""65Replace66distutils.dist.Distribution with this class67for the duration of this context.68"""69orig = distutils.core.Distribution70distutils.core.Distribution = cls71try:72yield73finally:74distutils.core.Distribution = orig757677def _to_str(s):78"""79Convert a filename to a string (on Python 2, explicitly80a byte string, not Unicode) as distutils checks for the81exact type str.82"""83if sys.version_info[0] == 2 and not isinstance(s, str):84# Assume it's Unicode, as that's what the PEP says85# should be provided.86return s.encode(sys.getfilesystemencoding())87return s888990def _get_immediate_subdirectories(a_dir):91return [name for name in os.listdir(a_dir)92if os.path.isdir(os.path.join(a_dir, name))]939495def _file_with_extension(directory, extension):96matching = (97f for f in os.listdir(directory)98if f.endswith(extension)99)100file, = matching101return file102103104def _open_setup_script(setup_script):105if not os.path.exists(setup_script):106# Supply a default setup.py107return io.StringIO(u"from setuptools import setup; setup()")108109return getattr(tokenize, 'open', open)(setup_script)110111112class _BuildMetaBackend(object):113114def _fix_config(self, config_settings):115config_settings = config_settings or {}116config_settings.setdefault('--global-option', [])117return config_settings118119def _get_build_requires(self, config_settings, requirements):120config_settings = self._fix_config(config_settings)121122sys.argv = sys.argv[:1] + ['egg_info'] + \123config_settings["--global-option"]124try:125with Distribution.patch():126self.run_setup()127except SetupRequirementsError as e:128requirements += e.specifiers129130return requirements131132def run_setup(self, setup_script='setup.py'):133# Note that we can reuse our build directory between calls134# Correctness comes first, then optimization later135__file__ = setup_script136__name__ = '__main__'137138with _open_setup_script(__file__) as f:139code = f.read().replace(r'\r\n', r'\n')140141exec(compile(code, __file__, 'exec'), locals())142143def get_requires_for_build_wheel(self, config_settings=None):144config_settings = self._fix_config(config_settings)145return self._get_build_requires(146config_settings, requirements=['wheel'])147148def get_requires_for_build_sdist(self, config_settings=None):149config_settings = self._fix_config(config_settings)150return self._get_build_requires(config_settings, requirements=[])151152def prepare_metadata_for_build_wheel(self, metadata_directory,153config_settings=None):154sys.argv = sys.argv[:1] + ['dist_info', '--egg-base',155_to_str(metadata_directory)]156self.run_setup()157158dist_info_directory = metadata_directory159while True:160dist_infos = [f for f in os.listdir(dist_info_directory)161if f.endswith('.dist-info')]162163if (164len(dist_infos) == 0 and165len(_get_immediate_subdirectories(dist_info_directory)) == 1166):167168dist_info_directory = os.path.join(169dist_info_directory, os.listdir(dist_info_directory)[0])170continue171172assert len(dist_infos) == 1173break174175# PEP 517 requires that the .dist-info directory be placed in the176# metadata_directory. To comply, we MUST copy the directory to the root177if dist_info_directory != metadata_directory:178shutil.move(179os.path.join(dist_info_directory, dist_infos[0]),180metadata_directory)181shutil.rmtree(dist_info_directory, ignore_errors=True)182183return dist_infos[0]184185def _build_with_temp_dir(self, setup_command, result_extension,186result_directory, config_settings):187config_settings = self._fix_config(config_settings)188result_directory = os.path.abspath(result_directory)189190# Build in a temporary directory, then copy to the target.191os.makedirs(result_directory, exist_ok=True)192with TemporaryDirectory(dir=result_directory) as tmp_dist_dir:193sys.argv = (sys.argv[:1] + setup_command +194['--dist-dir', tmp_dist_dir] +195config_settings["--global-option"])196self.run_setup()197198result_basename = _file_with_extension(199tmp_dist_dir, result_extension)200result_path = os.path.join(result_directory, result_basename)201if os.path.exists(result_path):202# os.rename will fail overwriting on non-Unix.203os.remove(result_path)204os.rename(os.path.join(tmp_dist_dir, result_basename), result_path)205206return result_basename207208def build_wheel(self, wheel_directory, config_settings=None,209metadata_directory=None):210return self._build_with_temp_dir(['bdist_wheel'], '.whl',211wheel_directory, config_settings)212213def build_sdist(self, sdist_directory, config_settings=None):214return self._build_with_temp_dir(['sdist', '--formats', 'gztar'],215'.tar.gz', sdist_directory,216config_settings)217218219class _BuildMetaLegacyBackend(_BuildMetaBackend):220"""Compatibility backend for setuptools221222This is a version of setuptools.build_meta that endeavors223to maintain backwards224compatibility with pre-PEP 517 modes of invocation. It225exists as a temporary226bridge between the old packaging mechanism and the new227packaging mechanism,228and will eventually be removed.229"""230def run_setup(self, setup_script='setup.py'):231# In order to maintain compatibility with scripts assuming that232# the setup.py script is in a directory on the PYTHONPATH, inject233# '' into sys.path. (pypa/setuptools#1642)234sys_path = list(sys.path) # Save the original path235236script_dir = os.path.dirname(os.path.abspath(setup_script))237if script_dir not in sys.path:238sys.path.insert(0, script_dir)239240# Some setup.py scripts (e.g. in pygame and numpy) use sys.argv[0] to241# get the directory of the source code. They expect it to refer to the242# setup.py script.243sys_argv_0 = sys.argv[0]244sys.argv[0] = setup_script245246try:247super(_BuildMetaLegacyBackend,248self).run_setup(setup_script=setup_script)249finally:250# While PEP 517 frontends should be calling each hook in a fresh251# subprocess according to the standard (and thus it should not be252# strictly necessary to restore the old sys.path), we'll restore253# the original path so that the path manipulation does not persist254# within the hook after run_setup is called.255sys.path[:] = sys_path256sys.argv[0] = sys_argv_0257258259# The primary backend260_BACKEND = _BuildMetaBackend()261262get_requires_for_build_wheel = _BACKEND.get_requires_for_build_wheel263get_requires_for_build_sdist = _BACKEND.get_requires_for_build_sdist264prepare_metadata_for_build_wheel = _BACKEND.prepare_metadata_for_build_wheel265build_wheel = _BACKEND.build_wheel266build_sdist = _BACKEND.build_sdist267268269# The legacy backend270__legacy__ = _BuildMetaLegacyBackend()271272273