def install_editable( install_options, # type: List[str] global_options, # type: Sequence[str] prefix, # type: Optional[str] home, # type: Optional[str] use_user_site, # type: bool name, # type: str setup_py_path, # type: str isolated, # type: bool build_env, # type: BuildEnvironment unpacked_source_directory, # type: str ): # type: (...) -> None """Install a package in editable mode. Most arguments are pass-through to setuptools. """ logger.info('Running setup.py develop for %s', name) args = make_setuptools_develop_args( setup_py_path, global_options=global_options, install_options=install_options, no_user_config=isolated, prefix=prefix, home=home, use_user_site=use_user_site, ) with indent_log(): with build_env: call_subprocess( args, cwd=unpacked_source_directory, )
def install_editable( self, install_options, # type: List[str] global_options=(), # type: Sequence[str] prefix=None # type: Optional[str] ): # type: (...) -> None logger.info('Running setup.py develop for %s', self.name) if prefix: prefix_param = ['--prefix={}'.format(prefix)] install_options = list(install_options) + prefix_param base_cmd = make_setuptools_shim_args( self.setup_py_path, global_options=global_options, no_user_config=self.isolated ) with indent_log(): with self.build_env: call_subprocess( base_cmd + ['develop', '--no-deps'] + list(install_options), cwd=self.unpacked_source_directory, ) self.install_succeeded = True
def install_editable( install_options: List[str], global_options: Sequence[str], prefix: Optional[str], home: Optional[str], use_user_site: bool, name: str, setup_py_path: str, isolated: bool, build_env: BuildEnvironment, unpacked_source_directory: str, ) -> None: """Install a package in editable mode. Most arguments are pass-through to setuptools. """ logger.info("Running setup.py develop for %s", name) args = make_setuptools_develop_args( setup_py_path, global_options=global_options, install_options=install_options, no_user_config=isolated, prefix=prefix, home=home, use_user_site=use_user_site, ) with indent_log(): with build_env: call_subprocess( args, command_desc="python setup.py develop", cwd=unpacked_source_directory, )
def _clean_one(self, req): base_args = self._base_setup_args(req) logger.info('Running setup.py clean for %s', req.name) clean_args = base_args + ['clean', '--all'] try: call_subprocess(clean_args, cwd=req.source_dir) return True except Exception: logger.error('Failed cleaning build dir for %s', req.name) return False
def _install_requirements( pip_runnable: str, finder: "PackageFinder", requirements: Iterable[str], prefix: _Prefix, *, kind: str, ) -> None: sys_executable = os.environ.get('PIP_PYTHON_PATH', sys.executable) args: List[str] = [ sys_executable, pip_runnable, "install", "--ignore-installed", "--no-user", "--prefix", prefix.path, "--no-warn-script-location", ] if logger.getEffectiveLevel() <= logging.DEBUG: args.append("-v") for format_control in ("no_binary", "only_binary"): formats = getattr(finder.format_control, format_control) args.extend(( "--" + format_control.replace("_", "-"), ",".join(sorted(formats or {":none:"})), )) index_urls = finder.index_urls if index_urls: args.extend(["-i", index_urls[0]]) for extra_index in index_urls[1:]: args.extend(["--extra-index-url", extra_index]) else: args.append("--no-index") for link in finder.find_links: args.extend(["--find-links", link]) for host in finder.trusted_hosts: args.extend(["--trusted-host", host]) if finder.allow_all_prereleases: args.append("--pre") if finder.prefer_binary: args.append("--prefer-binary") args.append("--") args.extend(requirements) extra_environ = {"_PIP_STANDALONE_CERT": where()} with open_spinner(f"Installing {kind}") as spinner: call_subprocess( args, command_desc=f"pip subprocess to install {kind}", spinner=spinner, extra_environ=extra_environ, )
def _clean_one_legacy(req, global_options): # type: (InstallRequirement, List[str]) -> bool clean_args = make_setuptools_clean_args( req.setup_py_path, global_options=global_options, ) logger.info('Running setup.py clean for %s', req.name) try: call_subprocess(clean_args, cwd=req.source_dir) return True except Exception: logger.error('Failed cleaning build dir for %s', req.name) return False
def install_requirements( self, finder, # type: PackageFinder requirements, # type: Iterable[str] prefix_as_string, # type: str message # type: Optional[str] ): # type: (...) -> None prefix = self._prefixes[prefix_as_string] assert not prefix.setup prefix.setup = True if not requirements: return sys_executable = os.environ.get('PIP_PYTHON_PATH', sys.executable) args = [ sys_executable, os.path.dirname(pip_location), 'install', '--ignore-installed', '--no-user', '--prefix', prefix.path, '--no-warn-script-location', ] # type: List[str] if logger.getEffectiveLevel() <= logging.DEBUG: args.append('-v') for format_control in ('no_binary', 'only_binary'): formats = getattr(finder.format_control, format_control) args.extend(('--' + format_control.replace('_', '-'), ','.join(sorted(formats or {':none:'})))) index_urls = finder.index_urls if index_urls: args.extend(['-i', index_urls[0]]) for extra_index in index_urls[1:]: args.extend(['--extra-index-url', extra_index]) else: args.append('--no-index') for link in finder.find_links: args.extend(['--find-links', link]) for host in finder.trusted_hosts: args.extend(['--trusted-host', host]) if finder.allow_all_prereleases: args.append('--pre') args.append('--') args.extend(requirements) with open_spinner(message) as spinner: call_subprocess(args, spinner=spinner)
def _clean_one_legacy(req: InstallRequirement, global_options: List[str]) -> bool: clean_args = make_setuptools_clean_args( req.setup_py_path, global_options=global_options, ) logger.info("Running setup.py clean for %s", req.name) try: call_subprocess(clean_args, command_desc="python setup.py clean", cwd=req.source_dir) return True except Exception: logger.error("Failed cleaning build dir for %s", req.name) return False
def _install_requirements( pip_runnable: str, finder: "PackageFinder", requirements: Iterable[str], prefix: _Prefix, message: str, ) -> None: sys_executable = os.environ.get('PIP_PYTHON_PATH', sys.executable) args = [ sys_executable, pip_runnable, 'install', '--ignore-installed', '--no-user', '--prefix', prefix.path, '--no-warn-script-location', ] # type: List[str] if logger.getEffectiveLevel() <= logging.DEBUG: args.append('-v') for format_control in ('no_binary', 'only_binary'): formats = getattr(finder.format_control, format_control) args.extend(('--' + format_control.replace('_', '-'), ','.join(sorted(formats or {':none:'})))) index_urls = finder.index_urls if index_urls: args.extend(['-i', index_urls[0]]) for extra_index in index_urls[1:]: args.extend(['--extra-index-url', extra_index]) else: args.append('--no-index') for link in finder.find_links: args.extend(['--find-links', link]) for host in finder.trusted_hosts: args.extend(['--trusted-host', host]) if finder.allow_all_prereleases: args.append('--pre') if finder.prefer_binary: args.append('--prefer-binary') args.append('--') args.extend(requirements) extra_environ = {"_PIP_STANDALONE_CERT": where()} with open_spinner(message) as spinner: call_subprocess(args, spinner=spinner, extra_environ=extra_environ)
def generate_metadata( build_env, # type: BuildEnvironment setup_py_path, # type: str source_dir, # type: str editable, # type: bool isolated, # type: bool details, # type: str ): # type: (...) -> str """Generate metadata using setup.py-based defacto mechanisms. Returns the generated metadata directory. """ logger.debug( 'Running setup.py (path:%s) egg_info for package %s', setup_py_path, details, ) egg_info_dir = None # type: Optional[str] # For non-editable installs, don't put the .egg-info files at the root, # to avoid confusion due to the source code being considered an installed # egg. if not editable: egg_info_dir = os.path.join(source_dir, 'pip-egg-info') # setuptools complains if the target directory does not exist. ensure_dir(egg_info_dir) args = make_setuptools_egg_info_args( setup_py_path, egg_info_dir=egg_info_dir, no_user_config=isolated, ) with build_env: call_subprocess( args, cwd=source_dir, command_desc='python setup.py egg_info', ) # Return the .egg-info directory. return _find_egg_info(source_dir, editable)
def generate_metadata( build_env: BuildEnvironment, setup_py_path: str, source_dir: str, isolated: bool, details: str, ) -> str: """Generate metadata using setup.py-based defacto mechanisms. Returns the generated metadata directory. """ logger.debug( "Running setup.py (path:%s) egg_info for package %s", setup_py_path, details, ) egg_info_dir = TempDirectory(kind="pip-egg-info", globally_managed=True).path args = make_setuptools_egg_info_args( setup_py_path, egg_info_dir=egg_info_dir, no_user_config=isolated, ) with build_env: with open_spinner("Preparing metadata (setup.py)") as spinner: try: call_subprocess( args, cwd=source_dir, command_desc="python setup.py egg_info", spinner=spinner, ) except InstallationSubprocessError as error: raise MetadataGenerationFailed(package_details=details) from error # Return the .egg-info directory. return _find_egg_info(egg_info_dir)
def generate_metadata( build_env, # type: BuildEnvironment setup_py_path, # type: str source_dir, # type: str isolated, # type: bool details, # type: str ): # type: (...) -> str """Generate metadata using setup.py-based defacto mechanisms. Returns the generated metadata directory. """ logger.debug( 'Running setup.py (path:%s) egg_info for package %s', setup_py_path, details, ) egg_info_dir = TempDirectory(kind="pip-egg-info", globally_managed=True).path args = make_setuptools_egg_info_args( setup_py_path, egg_info_dir=egg_info_dir, no_user_config=isolated, ) with build_env: call_subprocess( args, cwd=source_dir, command_desc='python setup.py egg_info', ) # Return the .egg-info directory. return _find_egg_info(egg_info_dir)
def run_command( cls, cmd, # type: Union[List[str], CommandArgs] show_stdout=True, # type: bool cwd=None, # type: Optional[str] on_returncode='raise', # type: str extra_ok_returncodes=None, # type: Optional[Iterable[int]] command_desc=None, # type: Optional[str] extra_environ=None, # type: Optional[Mapping[str, Any]] spinner=None, # type: Optional[SpinnerInterface] log_failed_cmd=True, # type: bool stdout_only=False, # type: bool ): # type: (...) -> str """ Run a VCS subcommand This is simply a wrapper around call_subprocess that adds the VCS command name, and checks that the VCS is available """ cmd = make_command(cls.name, *cmd) try: return call_subprocess(cmd, show_stdout, cwd, on_returncode=on_returncode, extra_ok_returncodes=extra_ok_returncodes, command_desc=command_desc, extra_environ=extra_environ, unset_environ=cls.unset_environ, spinner=spinner, log_failed_cmd=log_failed_cmd, stdout_only=stdout_only) except FileNotFoundError: # errno.ENOENT = no such file or directory # In other words, the VCS executable isn't available raise BadCommand( f'Cannot find command {cls.name!r} - do you have ' f'{cls.name!r} installed and in your PATH?') except PermissionError: # errno.EACCES = Permission denied # This error occurs, for instance, when the command is installed # only for another user. So, the current user don't have # permission to call the other user command. raise BadCommand( f"No permission to execute {cls.name!r} - install it " f"locally, globally (ask admin), or check your PATH. " f"See possible solutions at " f"https://pip.pypa.io/en/latest/reference/pip_freeze/" f"#fixing-permission-denied." )
def build_wheel_legacy( name: str, setup_py_path: str, source_dir: str, global_options: List[str], build_options: List[str], tempd: str, ) -> Optional[str]: """Build one unpacked package using the "legacy" build process. Returns path to wheel if successfully built. Otherwise, returns None. """ wheel_args = make_setuptools_bdist_wheel_args( setup_py_path, global_options=global_options, build_options=build_options, destination_dir=tempd, ) spin_message = f"Building wheel for {name} (setup.py)" with open_spinner(spin_message) as spinner: logger.debug("Destination directory: %s", tempd) try: output = call_subprocess( wheel_args, command_desc="python setup.py bdist_wheel", cwd=source_dir, spinner=spinner, ) except Exception: spinner.finish("error") logger.error("Failed building wheel for %s", name) return None names = os.listdir(tempd) wheel_path = get_legacy_build_wheel_path( names=names, temp_dir=tempd, name=name, command_args=wheel_args, command_output=output, ) return wheel_path
def run_command( cls, cmd, # type: Union[List[str], CommandArgs] show_stdout=True, # type: bool cwd=None, # type: Optional[str] on_returncode='raise', # type: str extra_ok_returncodes=None, # type: Optional[Iterable[int]] command_desc=None, # type: Optional[str] extra_environ=None, # type: Optional[Mapping[str, Any]] spinner=None, # type: Optional[SpinnerInterface] log_failed_cmd=True # type: bool ): # type: (...) -> Text """ Run a VCS subcommand This is simply a wrapper around call_subprocess that adds the VCS command name, and checks that the VCS is available """ cmd = make_command(cls.name, *cmd) try: return call_subprocess(cmd, show_stdout, cwd, on_returncode=on_returncode, extra_ok_returncodes=extra_ok_returncodes, command_desc=command_desc, extra_environ=extra_environ, unset_environ=cls.unset_environ, spinner=spinner, log_failed_cmd=log_failed_cmd) except OSError as e: # errno.ENOENT = no such file or directory # In other words, the VCS executable isn't available if e.errno == errno.ENOENT: raise BadCommand('Cannot find command %r - do you have ' '%r installed and in your ' 'PATH?' % (cls.name, cls.name)) else: raise # re-raise exception if a different error occurred
def _build_one_legacy(self, req, tempd, python_tag=None): """Build one InstallRequirement using the "legacy" build process. Returns path to wheel if successfully built. Otherwise, returns None. """ base_args = self._base_setup_args(req) spin_message = 'Building wheel for %s (setup.py)' % (req.name, ) with open_spinner(spin_message) as spinner: logger.debug('Destination directory: %s', tempd) wheel_args = base_args + ['bdist_wheel', '-d', tempd] \ + self.build_options if python_tag is not None: wheel_args += ["--python-tag", python_tag] try: output = call_subprocess( wheel_args, cwd=req.unpacked_source_directory, spinner=spinner, ) except Exception: spinner.finish("error") logger.error('Failed building wheel for %s', req.name) return None names = os.listdir(tempd) wheel_path = get_legacy_build_wheel_path( names=names, temp_dir=tempd, req=req, command_args=wheel_args, command_output=output, ) return wheel_path