def get_dependencies(ireq, sources=None, parent=None): """Get all dependencies for a given install requirement. :param ireq: A single InstallRequirement :type ireq: :class:`~pip._internal.req.req_install.InstallRequirement` :param sources: Pipfile-formatted sources, defaults to None :type sources: list[dict], optional :param parent: The parent of this list of dependencies, defaults to None :type parent: :class:`~pip._internal.req.req_install.InstallRequirement` :return: A set of dependency lines for generating new InstallRequirements. :rtype: set(str) """ if not isinstance(ireq, InstallRequirement): name = getattr( ireq, "project_name", getattr(ireq, "project", ireq.name), ) version = getattr(ireq, "version", None) if not version: ireq = InstallRequirement.from_line("{0}".format(name)) else: ireq = InstallRequirement.from_line("{0}=={1}".format( name, version)) pip_options = get_pip_options(sources=sources) getters = [ get_dependencies_from_cache, get_dependencies_from_wheel_cache, get_dependencies_from_json, functools.partial(get_dependencies_from_index, pip_options=pip_options) ] for getter in getters: deps = getter(ireq) if deps is not None: return deps raise RuntimeError('failed to get dependencies for {}'.format(ireq))
def get_dependencies_from_cache(ireq): """Retrieves dependencies for the given install requirement from the dependency cache. :param ireq: A single InstallRequirement :type ireq: :class:`~pip._internal.req.req_install.InstallRequirement` :return: A set of dependency lines for generating new InstallRequirements. :rtype: set(str) or None """ if ireq.editable or not is_pinned_requirement(ireq): return if ireq not in DEPENDENCY_CACHE: return cached = set(DEPENDENCY_CACHE[ireq]) # Preserving sanity: Run through the cache and make sure every entry if # valid. If this fails, something is wrong with the cache. Drop it. try: broken = False for line in cached: dep_ireq = InstallRequirement.from_line(line) name = canonicalize_name(dep_ireq.name) if _marker_contains_extra(dep_ireq): broken = True # The "extra =" marker breaks everything. elif name == canonicalize_name(ireq.name): broken = True # A package cannot depend on itself. if broken: break except Exception: broken = True if broken: del DEPENDENCY_CACHE[ireq] return return cached
def get_abstract_deps(): r = Requirement.from_line("requests") deps = [InstallRequirement.from_line(d) for d in r.get_dependencies()] abstract_deps = r.get_abstract_dependencies() req_abstract_dep = AbstractDependency.from_requirement(r) assert r.abstract_dep == req_abstract_dep assert len(abstract_deps) > 0 deps_from_ireqs = get_abstract_dependencies(deps, parent=r) assert len(deps_from_ireqs) > 0 assert sorted(set(deps_from_ireqs)) == sorted(set(abstract_deps))
def gen(ireq): info = None info = session.get("https://pypi.org/pypi/{0}/{1}/json".format( ireq.req.name, version)).json()["info"] requires_dist = info.get("requires_dist", info.get("requires")) if not requires_dist: # The API can return None for this. return for requires in requires_dist: i = InstallRequirement.from_line(requires) # See above, we don't handle requirements with extras. if not _marker_contains_extra(i): yield format_requirement(i)
def test_build_wheel(): ireq = InstallRequirement.from_line( "https://files.pythonhosted.org/packages/6e/40/7434b2d9fe24107ada25ec90a1fc646e97f346130a2c51aa6a2b1aba28de/requests-2.12.1.tar.gz#egg=requests" ) with global_tempdir_manager(), ensure_resolution_dirs() as kwargs: ireq.ensure_has_source_dir(kwargs["src_dir"]) cmd = InstallCommand() options, _ = cmd.parser.parse_args([]) session = cmd._build_session(options) shim_unpack( download_dir=kwargs["download_dir"], ireq=ireq, location=ireq.source_dir, only_download=False, session=session, ) wheel = next(iter(build_wheel(req=ireq, **kwargs))) assert os.path.exists(wheel)
def test_get_packagefinder(): install_cmd = InstallCommand() finder = get_package_finder( install_cmd, python_versions=("27", "35", "36", "37", "38"), implementation="cp" ) ireq = InstallRequirement.from_line("requests>=2.18") if install_req_from_line: ireq2 = install_req_from_line("requests>=2.18") assert str(ireq) == str(ireq2) requests_candidates = finder.find_all_candidates(ireq.name) candidates = sorted( [ c for c in requests_candidates if c.version in ireq.specifier.filter( candidate.version for candidate in requests_candidates ) ], key=lambda c: c.version, ) best_version = candidates[-1] location = getattr(best_version, "location", getattr(best_version, "link", None)) assert "pythonhosted" in location.url
def test_resolve(): install_cmd = InstallCommand() ireq = InstallRequirement.from_line("requests>=2.18,<2.25.0") result = resolve(ireq, install_command=install_cmd) assert set(result.keys()) == {"requests", "chardet", "idna", "urllib3", "certifi"}
def test_resolution(tmpdir, PipCommand): pip_command = PipCommand() pip_command.parser.add_option_group( make_option_group(index_group, pip_command.parser) ) pip_options, _ = pip_command.parser.parse_args([]) CACHE_DIR = tmpdir.mkdir("CACHE_DIR") pip_options.cache_dir = CACHE_DIR.strpath session = pip_command._build_session(pip_options) assert session if parse_version(pip_version) > parse_version("19.1.1"): index_urls = [pip_options.index_url] + pip_options.extra_index_urls search_scope = SearchScope.create( find_links=pip_options.find_links, index_urls=index_urls ) selection_prefs = SelectionPreferences( True, allow_all_prereleases=False, format_control=None, prefer_binary=False, ignore_requires_python=False, ) target_python = TargetPython() candidate_prefs = CandidatePreferences( prefer_binary=selection_prefs.prefer_binary, allow_all_prereleases=selection_prefs.allow_all_prereleases, ) if parse_version(pip_version) > parse_version("19.2.3"): link_collector = LinkCollector(session=session, search_scope=search_scope) finder_args = {"link_collector": link_collector} else: finder_args = {"search_scope": search_scope, "session": session} finder_args.update( { "candidate_prefs": candidate_prefs, "target_python": target_python, "allow_yanked": selection_prefs.allow_yanked, "format_control": selection_prefs.format_control, "ignore_requires_python": selection_prefs.ignore_requires_python, } ) else: finder_args = { "find_links": pip_options.find_links, "index_urls": [pip_options.index_url], "trusted_hosts": pip_options.trusted_hosts, "session": session, "allow_all_prereleases": False, } # finder_args["allow_all_prereleases"] = False finder = PackageFinder(**finder_args) ireq = InstallRequirement.from_line("requests>=2.18") if install_req_from_line: ireq2 = install_req_from_line("requests>=2.18") assert str(ireq) == str(ireq2) requests_candidates = finder.find_all_candidates(ireq.name) candidates = sorted( [ c for c in requests_candidates if c.version in ireq.specifier.filter( candidate.version for candidate in requests_candidates ) ], key=lambda c: c.version, ) best_version = candidates[-1] location = getattr(best_version, "location", getattr(best_version, "link", None)) assert "pythonhosted" in location.url req_file = tmpdir.mkdir("req_dir").join("requirements.txt") req_file.write_text( textwrap.dedent( """ requests>=2.18 """ ), encoding="utf-8", ) build_dir = tmpdir.mkdir("build_dir") source_dir = tmpdir.mkdir("source_dir") download_dir = tmpdir.mkdir("download_dir") results = None with wheel_cache(USER_CACHE_DIR, FormatControl(None, None)) as wheelcache: preparer_kwargs = { "build_dir": build_dir.strpath, "src_dir": source_dir.strpath, "download_dir": download_dir.strpath, "progress_bar": "off", "build_isolation": False, "finder": finder, "session": session, "require_hashes": False, "use_user_site": False, } resolver_kwargs = { "finder": finder, "upgrade_strategy": "to-satisfy-only", "force_reinstall": False, "ignore_dependencies": False, "ignore_requires_python": False, "ignore_installed": True, "use_user_site": False, } if ( parse_version("19.3") <= parse_version(pip_version) <= parse_version("20.0.99999") ): make_install_req = partial( install_req_from_req_string, isolated=False, wheel_cache=wheelcache, # use_pep517=use_pep517, ) resolver_kwargs["make_install_req"] = make_install_req else: resolver_kwargs["wheel_cache"] = wheelcache if parse_version(pip_version) >= parse_version("20.1"): make_install_req = partial( install_req_from_req_string, isolated=False, use_pep517=True, ) resolver_kwargs["make_install_req"] = make_install_req else: resolver_kwargs["isolated"] = False resolver = None with make_preparer(**preparer_kwargs) as preparer: resolver_kwargs["preparer"] = preparer reqset = RequirementSet() ireq.is_direct = True reqset.add_requirement(ireq) resolver = get_resolver(**resolver_kwargs) resolver.require_hashes = False if parse_version(pip_version) > parse_version("20.0.9999999"): resolver._populate_link(ireq) results = resolver._resolve_one(reqset, ireq) try: reqset.cleanup_files() except AttributeError: pass results = set(results) result_names = [r.name for r in results] assert "urllib3" in result_names
def ireq_from_line(ireq): from pip_shims import InstallRequirement return InstallRequirement.from_line(ireq)