def install_requirements(): from pip.commands.install import InstallCommand from pkg_resources import ContextualVersionConflict requirements = [ os.path.abspath( os.path.join(os.path.dirname(__file__), 'requirements.txt')) ] options = InstallCommand().parse_args([])[0] options.use_user_site = root_check() and not virtualenv_check() options.requirements = requirements options.cache_dir = None options.upgrade = True options.quiet = 1 options.pre = True # install/upgrade all requirements for sickrage print("Installing SiCKRAGE requirement packages, please stand by ...") attempts = 0 while attempts < 3: try: options.ignore_dependencies = True InstallCommand().run(options, []) options.ignore_dependencies = False InstallCommand().run(options, []) except ContextualVersionConflict: attempts += 1 time.sleep(1) finally: break
def package_finder(argv): """Return a PackageFinder respecting command-line options. :arg argv: Everything after the subcommand """ # We instantiate an InstallCommand and then use some of its private # machinery--its arg parser--for our own purposes, like a virus. This # approach is portable across many pip versions, where more fine-grained # ones are not. Ignoring options that don't exist on the parser (for # instance, --use-wheel) gives us a straightforward method of backward # compatibility. try: command = InstallCommand() except TypeError: # This is likely pip 1.3.0's "__init__() takes exactly 2 arguments (1 # given)" error. In that version, InstallCommand takes a top=level # parser passed in from outside. from pip.baseparser import create_main_parser command = InstallCommand(create_main_parser()) # The downside is that it essentially ruins the InstallCommand class for # further use. Calling out to pip.main() within the same interpreter, for # example, would result in arguments parsed this time turning up there. # Thus, we deepcopy the arg parser so we don't trash its singletons. Of # course, deepcopy doesn't work on these objects, because they contain # uncopyable regex patterns, so we pickle and unpickle instead. Fun! options, _ = loads(dumps(command.parser)).parse_args(argv) # Carry over PackageFinder kwargs that have [about] the same names as # options attr names: possible_options = [ 'find_links', 'use_wheel', 'allow_external', 'allow_unverified', 'allow_all_external', ('allow_all_prereleases', 'pre'), 'process_dependency_links' ] kwargs = {} for option in possible_options: kw, attr = option if isinstance(option, tuple) else (option, option) value = getattr(options, attr, MARKER) if value is not MARKER: kwargs[kw] = value # Figure out index_urls: index_urls = [options.index_url] + options.extra_index_urls if options.no_index: index_urls = [] index_urls += getattr(options, 'mirrors', []) # If pip is new enough to have a PipSession, initialize one, since # PackageFinder requires it: if hasattr(command, '_build_session'): kwargs['session'] = command._build_session(options) return PackageFinder(index_urls=index_urls, **kwargs)
def install(reqs, index_urls=None, upgrade=False, pre_releases=False, no_cache=False, reinstall=False): _ensure_patch_pip_get_entry_points() cmd = InstallCommand() args = [] if pre_releases: args.append("--pre") if not virtualenv_no_global(): args.append("--user") if upgrade: args.append("--upgrade") if no_cache: args.append("--no-cache-dir") if reinstall: args.append("--force-reinstall") if index_urls: args.extend(["--index-url", index_urls[0]]) for url in index_urls[1:]: args.extend(["--extra-index-url", url]) args.extend(reqs) options, cmd_args = cmd.parse_args(args) try: cmd.run(options, cmd_args) except InstallationError as e: raise InstallError(str(e))
def install_missing_requirements(module): """ Some of the modules require external packages to be installed. This gets the list from the `REQUIREMENTS` module attribute and attempts to install the requirements using pip. :param module: GPIO module :type module: ModuleType :return: None :rtype: NoneType """ reqs = getattr(module, "REQUIREMENTS", []) if not reqs: _LOG.info("Module %r has no extra requirements to install." % module) return import pkg_resources pkgs_installed = pkg_resources.WorkingSet() pkgs_required = [] for req in reqs: if pkgs_installed.find(pkg_resources.Requirement.parse(req)) is None: pkgs_required.append(req) if pkgs_required: from pip.commands.install import InstallCommand from pip.status_codes import SUCCESS cmd = InstallCommand() result = cmd.main(pkgs_required) if result != SUCCESS: raise CannotInstallModuleRequirements( "Unable to install packages for module %r (%s)..." % (module, pkgs_required))
def activate(self, leaf): params = get_params() if 'name' in leaf.object: params.append(leaf.object['name']) else: params.append(str(leaf.object)) InstallCommand().main(params)
def check(): # find missing packages from importlib.util import find_spec missing = [ requirement for requirement in requirements if not (find_spec(requirement)) ] if not missing: return # install missing packages sys.stdout.write("Installing" + ','.join(missing) + ".\n") # redirect out to nothing so no installing messages will be seen. sys_stdout = sys.stdout sys_stderr = sys.stderr sys.stdout = None sys.stderr = None from pip.commands.install import InstallCommand from pip.status_codes import SUCCESS cmd = InstallCommand() for requirement in requirements: try: if cmd.main([requirement]) is not SUCCESS: sys_stderr.write("Can not install " + requirement + ", program aborts.\n") sys.exit() # this might occur because of redirection of stdout and stderr except AttributeError: pass # direct out back to normal sys.stdout = sys_stdout sys.stderr = sys_stderr sys.stdout.write("All packages are installed, starting game...") sys.stdout.flush()
def test_installed_files_tracking(self): """ Verify that tracking of installed files works correctly. This tests the :py:func:`~pip_accel.bdist.BinaryDistributionManager.update_installed_files()` method. When pip installs a Python package it also creates a file called ``installed-files.txt`` that contains the pathnames of the files that were installed. This file enables pip to uninstall Python packages later on. Because pip-accel implements its own package installation it also creates the ``installed-files.txt`` file, in order to enable the user to uninstall a package with pip even if the package was installed using pip-accel. """ # Prevent unsuspecting users from accidentally running the find_files() # tests below on their complete `/usr' or `/usr/local' tree :-). if not hasattr(sys, 'real_prefix'): logger.warning("Skipping installed files tracking test (not running in a recognized virtual environment).") return # Install the iPython 1.0 source distribution using pip. command = InstallCommand() opts, args = command.parse_args([ '--ignore-installed', '--no-use-wheel', 'ipython==1.0' ]) command.run(opts, args) # Make sure the iPython program works after installation using pip. try_program('ipython3' if sys.version_info[0] == 3 else 'ipython') # Find the iPython related files installed by pip. files_installed_using_pip = set(find_files(sys.prefix, 'ipython')) assert len(files_installed_using_pip) > 0, \ "It looks like pip didn't install iPython where we expected it to do so?!" logger.debug("Found %i files installed using pip: %s", len(files_installed_using_pip), files_installed_using_pip) # Remove the iPython installation. uninstall('ipython') # Install the iPython 1.0 source distribution using pip-accel. accelerator = self.initialize_pip_accel() num_installed = accelerator.install_from_arguments([ '--ignore-installed', '--no-use-wheel', 'ipython==1.0' ]) assert num_installed == 1, "Expected pip-accel to install exactly one package!" # Make sure the iPython program works after installation using pip-accel. try_program('ipython3' if sys.version_info[0] == 3 else 'ipython') # Find the iPython related files installed by pip-accel. files_installed_using_pip_accel = set(find_files(sys.prefix, 'ipython')) assert len(files_installed_using_pip_accel) > 0, \ "It looks like pip-accel didn't install iPython where we expected it to do so?!" logger.debug("Found %i files installed using pip-accel: %s", len(files_installed_using_pip_accel), files_installed_using_pip_accel) # Test that pip and pip-accel installed exactly the same files. assert files_installed_using_pip == files_installed_using_pip_accel, \ "It looks like pip and pip-accel installed different files for iPython!" # Test that pip knows how to uninstall iPython installed by pip-accel # due to the installed-files.txt file generated by pip-accel. uninstall('ipython') # Make sure all files related to iPython were uninstalled by pip. assert len(list(find_files(sys.prefix, 'ipython'))) == 0, \ "It looks like pip didn't properly uninstall iPython after installation using pip-accel!"
def _pip_needs_system(): """Determine whether pip3 defaults to --user, needing --system to turn it off.""" try: from pip.commands.install import InstallCommand return InstallCommand().cmd_opts.get_option('--system') is not None except (ImportError, AttributeError, TypeError): # probably not the bionic pip version then return False
def install(params): """ Install third-party Mod """ from pip import main as pip_main from pip.commands.install import InstallCommand params = [param for param in params] options, mod_list = InstallCommand().parse_args(params) params = ["install"] + params for mod_name in mod_list: mod_name_index = params.index(mod_name) if mod_name.startswith("rqalpha_mod_sys_"): six.print_('System Mod can not be installed or uninstalled') return if "rqalpha_mod_" in mod_name: lib_name = mod_name else: lib_name = "rqalpha_mod_" + mod_name params[mod_name_index] = lib_name # Install Mod installed_result = pip_main(params) # Export config mod_config_path = get_mod_config_path(generate=True) mod_config = load_mod_config(mod_config_path, loader=yaml.Loader) if installed_result == 0: # 如果为0,则说明安装成功 if len(mod_list) == 0: """ 主要是方便 `pip install -e .` 这种方式 本地调试 Mod 使用,需要满足以下条件: 1. `rqalpha mod install -e .` 命令是在对应 自定义 Mod 的根目录下 2. 该 Mod 必须包含 `setup.py` 文件(否则也不能正常的 `pip install -e .` 来安装) 3. 该 Mod 包名必须按照 RQAlpha 的规范来命名,具体规则如下 * 必须以 `rqalpha-mod-` 来开头,比如 `rqalpha-mod-xxx-yyy` * 对应import的库名必须要 `rqalpha_mod_` 来开头,并且需要和包名后半部分一致,但是 `-` 需要替换为 `_`, 比如 `rqalpha_mod_xxx_yyy` """ mod_name = _detect_package_name_from_dir() mod_name = mod_name.replace("-", "_").replace("rqalpha_mod_", "") mod_list.append(mod_name) for mod_name in mod_list: if "rqalpha_mod_" in mod_name: mod_name = mod_name.replace("rqalpha_mod_", "") if "==" in mod_name: mod_name = mod_name.split('==')[0] mod_config['mod'][mod_name] = {} mod_config['mod'][mod_name]['enabled'] = False dump_config(mod_config_path, mod_config) list({}) return installed_result
def install_requirements(self, requirements, **kw): """ Manually install a requirement set from binary and/or wheel distributions. :param requirements: A list of :class:`pip_accel.req.Requirement` objects. :param kw: Any keyword arguments are passed on to :func:`~pip_accel.bdist.BinaryDistributionManager.install_binary_dist()`. :returns: The number of packages that were just installed (an integer). """ install_timer = Timer() install_types = [] if any(not req.is_wheel for req in requirements): install_types.append('binary') if any(req.is_wheel for req in requirements): install_types.append('wheel') logger.info("Installing from %s distributions ..", concatenate(install_types)) # Track installed files by default (unless the caller specifically opted out). kw.setdefault('track_installed_files', True) num_installed = 0 for requirement in requirements: # If we're upgrading over an older version, first remove the # old version to make sure we don't leave files from old # versions around. if is_installed(requirement.name): uninstall(requirement.name) # When installing setuptools we need to uninstall distribute, # otherwise distribute will shadow setuptools and all sorts of # strange issues can occur (e.g. upgrading to the latest # setuptools to gain wheel support and then having everything # blow up because distribute doesn't know about wheels). if requirement.name == 'setuptools' and is_installed('distribute'): uninstall('distribute') if requirement.is_editable: logger.debug("Installing %s in editable form using pip.", requirement) command = InstallCommand() opts, args = command.parse_args( ['--no-deps', '--editable', requirement.source_directory]) command.run(opts, args) elif requirement.is_wheel: logger.info("Installing %s wheel distribution using pip ..", requirement) wheel_version = pip_wheel_module.wheel_version( requirement.source_directory) pip_wheel_module.check_compatibility(wheel_version, requirement.name) requirement.pip_requirement.move_wheel_files( requirement.source_directory) else: binary_distribution = self.bdists.get_binary_dist(requirement) self.bdists.install_binary_dist(binary_distribution, **kw) num_installed += 1 logger.info("Finished installing %s in %s.", pluralize(num_installed, "requirement"), install_timer) return num_installed
def install_package(self, packages, params=None): # type: (str, Optional[str]) -> int try: # For pip <= 19.1.1 install = InstallCommand() except TypeError: # For pip > 19.1.1 install = InstallCommand("Pippel", "Backend server for the Pippel service.") assert packages, "`packages` should not be an empty string." for package in packages.split(): if self.in_virtual_env(): args = [package, "--upgrade"] elif params: args = [package, "--upgrade", "--target", params] else: args = [package, "--upgrade", "--user"] k = install.main(args) return k
def install_package(self, packages): install = InstallCommand() pkg_list = packages.split(" ") for pkg in pkg_list: # virtualenv active ? if hasattr(sys, 'real_prefix'): options, args = install.parse_args([pkg, '--upgrade']) else: options, args = install.parse_args( [pkg, '--upgrade', '--user']) install.run(options, args)
def install(reqs, index_urls=None, upgrade=False): cmd = InstallCommand() args = ["--user"] if upgrade: args.append("--upgrade") if index_urls: args.append("--index-url", index_urls[0]) for url in index_urls[1:]: args.append("--extra-index-url", url) args.extend(reqs) cmd.run(*cmd.parse_args(args))
def update(self): """ Performs pip upgrade """ # Notify update successful sickrage.srCore.srLogger.info("Updating SiCKRAGE from PyPi servers") srNotifiers.notify_version_update(sickrage.srCore.NEWEST_VERSION_STRING) from pip.commands.install import InstallCommand options = InstallCommand().parse_args([])[0] options.use_user_site = all([not sickrage.isElevatedUser(), not sickrage.isVirtualEnv()]) options.cache_dir = None options.upgrade = True options.quiet = 1 options.ignore_dependencies = True InstallCommand().run(options, ['sickrage']) options.ignore_dependencies = False InstallCommand().run(options, ['sickrage']) return True
def test_missing_hash_with_require_hashes_in_reqs_file(self, data, tmpdir): """--require-hashes in a requirements file should make its way to the RequirementSet. """ req_set = self.basic_reqset(require_hashes=False) session = PipSession() finder = PackageFinder([data.find_links], [], session=session) command = InstallCommand() with requirements_file('--require-hashes', tmpdir) as reqs_file: options, args = command.parse_args(['-r', reqs_file]) command.populate_requirement_set( req_set, args, options, finder, session, command.name, wheel_cache=None) assert req_set.require_hashes
def install(params): """ Install third-party Mod """ from pip import main as pip_main from pip.commands.install import InstallCommand params = [param for param in params] options, mod_list = InstallCommand().parse_args(params) params = ["install"] + params for mod_name in mod_list: mod_name_index = params.index(mod_name) if mod_name in system_mod: print('System Mod can not be installed or uninstalled') return if "rqalpha_mod_" in mod_name: lib_name = mod_name mod_name = lib_name.replace("rqalpha_mod_", "") else: lib_name = "rqalpha_mod_" + mod_name params[mod_name_index] = lib_name # Install Mod pip_main(params) # Export config config_path = get_default_config_path() config = load_config(config_path, loader=yaml.RoundTripLoader) for mod_name in mod_list: if "rqalpha_mod_" in mod_name: lib_name = mod_name mod_name = lib_name.replace("rqalpha_mod_", "") else: lib_name = "rqalpha_mod_" + mod_name mod = import_module(lib_name) mod_config = yaml.load(mod.__mod_config__, yaml.RoundTripLoader) config['mod'][mod_name] = mod_config config['mod'][mod_name]['lib'] = lib_name config['mod'][mod_name]['enabled'] = False config['mod'][mod_name]['priority'] = 1000 dump_config(config_path, config)
def install(self, **opts): """Call on pip to install the package if not yet installed""" installed, new_style, ivers = self.test_installed() if installed: return True if not self.pip_url: raise Exception('The plugin author did not provide an automatic install link') from pip.commands.install import InstallCommand ic = InstallCommand() opts, args = ic.parser.parse_args() args.append(self.pip_url) for k, v in opts.__dict__.iteritems(): setattr(opts, k, v) req_set = ic.run(opts, args) req_set.install(opts) return self.test_installed()
def _update_pyxelrest(self): self.updating_queue.put((PYTHON_STEP, IN_PROGRESS)) result = InstallCommand().main([ 'pyxelrest', '--upgrade', '--disable-pip-version-check', '--log', default_log_file_path, '--pre' ]) create_logger() # PyxelRest logger is lost while trying to update if result == 0: self.updating_queue.put((PYTHON_STEP, DONE)) logger.info('PyxelRest package updated.') if self._update_addin(): # Only perform configuration update when we are sure that latest version is installed self._update_configuration() else: logger.warning('PyxelRest package update failed.') self.updating_queue.put((PYTHON_STEP, FAILURE))
def install_missing_requirements(module): """ Some of the modules require external packages to be installed. This gets the list from the `REQUIREMENTS` module attribute and attempts to install the requirements using pip. :param module: Backend module :type module: ModuleType :return: None :rtype: NoneType """ reqs = getattr(module, "REQUIREMENTS", []) if not reqs: print("Module %r has no extra requirements to install." % module) return import pkg_resources pkgs_installed = pkg_resources.WorkingSet() pkgs_required = [] for req in reqs: if req.startswith("git+"): url = urlparse(req) params = { x[0]: x[1] for x in map(lambda y: y.split('='), url.fragment.split('&')) } try: pkg = params["egg"] except KeyError: raise CannotInstallModuleRequirements( "Package %r in module %r must include '#egg=<pkgname>'" % (req, module)) else: pkg = req if pkgs_installed.find(pkg_resources.Requirement.parse(pkg)) is None: pkgs_required.append(req) if pkgs_required: from pip.commands.install import InstallCommand from pip.status_codes import SUCCESS cmd = InstallCommand() result = cmd.main(pkgs_required) if result != SUCCESS: raise CannotInstallModuleRequirements( "Unable to install packages for module %r (%s)..." % (module, pkgs_required))
def install(params): """ Install third-party Mod """ from pip import main as pip_main from pip.commands.install import InstallCommand params = [param for param in params] options, mod_list = InstallCommand().parse_args(params) params = ["install"] + params for mod_name in mod_list: mod_name_index = params.index(mod_name) if mod_name.startswith("rqalpha_mod_sys_"): print('System Mod can not be installed or uninstalled') return if "rqalpha_mod_" in mod_name: lib_name = mod_name mod_name = lib_name.replace("rqalpha_mod_", "") else: lib_name = "rqalpha_mod_" + mod_name params[mod_name_index] = lib_name # Install Mod pip_main(params) # Export config mod_config_path = get_default_config_path("mod_config") mod_config = load_config(mod_config_path, loader=yaml.RoundTripLoader, verify_version=False) for mod_name in mod_list: mod_config['mod'][mod_name] = {} mod_config['mod'][mod_name]['enabled'] = False dump_config(mod_config_path, mod_config) list({})
if installed_packages: pip = UninstallCommand() options, args = pip.parse_args(installed_packages) options.yes = True try: pip.run(options, args) except OSError as e: if e.errno != 13: raise e print("You lack permissions to uninstall this package. Perhaps run with sudo? Exiting.") exit(13) date = parse_iso8601(sys.argv[1]) packages = {p: select_version(date, p) for p in sys.argv[2:]} args = ['=='.join(a) for a in packages.items()] cmd = InstallCommand() options, args = cmd.parse_args(args) options.ignore_installed = True options.force_reinstall = True try: print(cmd.run(options, args)) except OSError as e: if e.errno != 13: raise e print("You lack permissions to uninstall this package. Perhaps run with sudo? Exiting.") exit(13)
def get_pip_requirement_set(self, arguments, use_remote_index, use_wheels=False): """ Get the unpacked requirement(s) specified by the caller by running pip. :param arguments: The command line arguments to ``pip install ..`` (a list of strings). :param use_remote_index: A boolean indicating whether pip is allowed to connect to the main package index (http://pypi.python.org by default). :param use_wheels: Whether pip and pip-accel are allowed to use wheels_ (``False`` by default for backwards compatibility with callers that use pip-accel as a Python API). :returns: A :py:class:`pip.req.RequirementSet` object created by pip. :raises: Any exceptions raised by pip. """ # Compose the pip command line arguments. This is where a lot of the # core logic of pip-accel is hidden and it uses some esoteric features # of pip so this method is heavily commented. command_line = [] # Use `--download' to instruct pip to download requirement(s) into # pip-accel's local source distribution index directory. This has the # following documented side effects (see `pip install --help'): # 1. It disables the installation of requirements (without using the # `--no-install' option which is deprecated and slated for removal # in pip 7.x). # 2. It ignores requirements that are already installed (because # pip-accel doesn't actually need to re-install requirements that # are already installed we will have work around this later, but # that seems fairly simple to do). command_line.append('--download=%s' % self.config.source_index) # Use `--find-links' to point pip at pip-accel's local source # distribution index directory. This ensures that source distribution # archives are never downloaded more than once (regardless of the HTTP # cache that was introduced in pip 6.x). command_line.append('--find-links=file://%s' % self.config.source_index) # Use `--no-use-wheel' to ignore wheel distributions by default in # order to preserve backwards compatibility with callers that expect a # requirement set consisting only of source distributions that can be # converted to `dumb binary distributions'. if not use_wheels and '--no-use-wheel' not in arguments: command_line.append('--no-use-wheel') # Use `--no-index' to force pip to only consider source distribution # archives contained in pip-accel's local source distribution index # directory. This enables pip-accel to ask pip "Can the local source # distribution index satisfy all requirements in the given requirement # set?" which enables pip-accel to keep pip off the internet unless # absolutely necessary :-). if not use_remote_index: command_line.append('--no-index') # Use `--no-clean' to instruct pip to unpack the source distribution # archives and *not* clean up the unpacked source distributions # afterwards. This enables pip-accel to replace pip's installation # logic with cached binary distribution archives. command_line.append('--no-clean') # Use `--build-directory' to instruct pip to unpack the source # distribution archives to a temporary directory managed by pip-accel. # We will clean up the build directory when we're done using the # unpacked source distributions. command_line.append('--build-directory=%s' % self.build_directory) # Append the user's `pip install ...' arguments to the command line # that we just assembled. command_line.extend(arguments) logger.info("Executing command: pip install %s", ' '.join(command_line)) # Clear the build directory to prevent PreviousBuildDirError exceptions. self.clear_build_directory() # During the pip 6.x upgrade pip-accel switched to using `pip install # --download' which can produce an interactive prompt as described in # issue 51 [1]. The documented way [2] to get rid of this interactive # prompt is pip's --exists-action option, but due to what is most # likely a bug in pip this doesn't actually work. The environment # variable $PIP_EXISTS_ACTION does work however, so if the user didn't # set it we will set a reasonable default for them. # [1] https://github.com/paylogic/pip-accel/issues/51 # [2] https://pip.pypa.io/en/latest/reference/pip.html#exists-action-option os.environ.setdefault('PIP_EXISTS_ACTION', 'w') # Initialize and run the `pip install' command. command = InstallCommand() opts, args = command.parse_args(command_line) if not opts.ignore_installed: # If the user didn't supply the -I, --ignore-installed option we # will forcefully disable the option. Refer to the documentation of # the AttributeOverrides class for further details. opts = AttributeOverrides(opts, ignore_installed=False) requirement_set = command.run(opts, args) # Make sure the output of pip and pip-accel are not intermingled. sys.stdout.flush() if requirement_set is None: raise NothingToDoError(""" pip didn't generate a requirement set, most likely you specified an empty requirements file? """) else: return self.transform_pip_requirement_set(requirement_set)