def make_install_requirement(name, version, extras, markers, constraint=False): """make_install_requirement Generates an :class:`~pip._internal.req.req_install.InstallRequirement`. Create an InstallRequirement from the supplied metadata. :param name: The requirement's name. :type name: str :param version: The requirement version (must be pinned). :type version: str. :param extras: The desired extras. :type extras: list[str] :param markers: The desired markers, without a preceding semicolon. :type markers: str :param constraint: Whether to flag the requirement as a constraint, defaults to False. :param constraint: bool, optional :return: A generated InstallRequirement :rtype: :class:`~pip._internal.req.req_install.InstallRequirement` """ # If no extras are specified, the extras string is blank from pip_shims.shims import install_req_from_line extras_string = "" if extras: # Sort extras for stability extras_string = "[{}]".format(",".join(sorted(extras))) if not markers: return install_req_from_line(str('{}{}=={}'.format( name, extras_string, version)), constraint=constraint) else: return install_req_from_line(str('{}{}=={}; {}'.format( name, extras_string, version, str(markers))), constraint=constraint)
def uninstall(self, dist: Distribution) -> None: req = parse_requirement(dist.project_name) if _is_dist_editable(dist): ireq = shims.install_req_from_editable(dist.location) else: ireq = shims.install_req_from_line(dist.project_name) ireq.req = req with self.environment.activate(): pathset = ireq.uninstall(auto_confirm=self.auto_confirm) if pathset: pathset.commit()
def _iter_dependencies(self, ireq): """ Given a pinned, url, or editable InstallRequirement, collects all the secondary dependencies for them, either by looking them up in a local cache, or by reaching out to the repository. Editable requirements will never be looked up, as they may have changed at any time. """ # Pip does not resolve dependencies of constraints. We skip handling # constraints here as well to prevent the cache from being polluted. # Constraints that are later determined to be dependencies will be # marked as non-constraints in later rounds by # `combine_install_requirements`, and will be properly resolved. # See https://github.com/pypa/pip/ # blob/6896dfcd831330c13e076a74624d95fa55ff53f4/src/pip/_internal/ # legacy_resolve.py#L325 if ireq.constraint: return if ireq.editable or (is_url_requirement(ireq) and not ireq.link.is_wheel): for dependency in self.repository.get_dependencies(ireq): yield dependency return # fix our malformed extras if ireq.extras: if getattr(ireq, "extra", None): if ireq.extras: ireq.extras.extend(ireq.extra) else: ireq.extras = ireq.extra elif not is_pinned_requirement(ireq): raise TypeError( "Expected pinned or editable requirement, got {}".format(ireq)) # Now, either get the dependencies from the dependency cache (for # speed), or reach out to the external repository to # download and inspect the package version and get dependencies # from there if ireq not in self.dependency_cache: log.debug( " {} not in cache, need to check index".format( format_requirement(ireq)), fg="yellow", ) dependencies = self.repository.get_dependencies(ireq) self.dependency_cache[ireq] = sorted( set(format_requirement(ireq) for ireq in dependencies)) # Example: ['Werkzeug>=0.9', 'Jinja2>=2.4'] dependency_strings = self.dependency_cache[ireq] log.debug(" {:25} requires {}".format( format_requirement(ireq), ", ".join(sorted(dependency_strings, key=lambda s: s.lower())) or "-", )) for dependency_string in dependency_strings: yield install_req_from_line(dependency_string, constraint=ireq.constraint, comes_from=ireq)