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
Beispiel #3
0
def test_link_and_ireq():
    url = "git+https://github.com/requests/[email protected]#egg=requests"
    link = Link(url)
    ireq = InstallRequirement.from_editable(url)
    if install_req_from_editable:
        ireq2 = install_req_from_editable(url)
        assert ireq2.link == link
    assert ireq.link == link
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)
Beispiel #6
0
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)
Beispiel #7
0
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
Beispiel #8
0
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"}
Beispiel #9
0
def test_wheelbuilder(tmpdir, PipCommand):
    output_dir = tmpdir.join("output")
    output_dir.mkdir()
    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)
    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] + pip_options.extra_index_urls,
            "trusted_hosts": pip_options.trusted_hosts,
            "session": session,
            "allow_all_prereleases": False,
        }
        # finder_args["allow_all_prereleases"] = False
    finder = PackageFinder(**finder_args)
    build_dir = tmpdir.mkdir("build_dir")
    source_dir = tmpdir.mkdir("source_dir")
    download_dir = tmpdir.mkdir("download_dir")
    wheel_download_dir = CACHE_DIR.mkdir("wheels")
    with wheel_cache(USER_CACHE_DIR, FormatControl(None, None)) as wheelcache:
        kwargs = {
            "build_dir": build_dir.strpath,
            "src_dir": source_dir.strpath,
            "download_dir": download_dir.strpath,
            "wheel_download_dir": wheel_download_dir.strpath,
            "finder": finder,
            "require_hashes": False,
            "use_user_site": False,
            "progress_bar": "off",
            "build_isolation": False,
        }
        ireq = InstallRequirement.from_editable(
            "git+https://github.com/urllib3/[email protected]#egg=urllib3"
        )
        if parse_version(pip_version) <= parse_version("20.0.9999999"):
            ireq.populate_link(finder, False, False)
        ireq.ensure_has_source_dir(kwargs["src_dir"])
        # Ensure the remote artifact is downloaded locally. For wheels, it is
        # enough to just download because we'll use them directly. For an sdist,
        # we need to unpack so we can build it.
        unpack_kwargs = {
            "session": session,
            "hashes": ireq.hashes(True),
            "link": ireq.link,
            "location": ireq.source_dir,
            "download_dir": kwargs["download_dir"],
        }
        if parse_version(pip_version) < parse_version("19.2.0"):
            unpack_kwargs["only_download"] = ireq.is_wheel
        if parse_version(pip_version) >= parse_version("10"):
            unpack_kwargs["progress_bar"] = "off"
        if not is_file_url(ireq.link):
            shim_unpack(**unpack_kwargs)
        output_file = None
        ireq.is_direct = True
        build_args = {
            "req": ireq,
            "output_dir": output_dir.strpath,
            "verify": False,
            "build_options": [],
            "global_options": [],
            "editable": False,
        }
        output_file = call_function_with_correct_args(build_one, **build_args)
    # XXX: skipping to here is functionally the same and should pass all tests
    # output_file = build_wheel(**build_wheel_kwargs)
    assert output_file, output_file
Beispiel #10
0
def test_abstract_dist():
    ireq = InstallRequirement.from_editable(
        "git+https://github.com/requests/[email protected]#egg=requests"
    )
    abs_dist = make_abstract_dist(ireq)
    assert abs_dist.__class__.__name__ == SourceDistribution.__name__
Beispiel #11
0
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 test_get_editable_from_index():
    r = InstallRequirement.from_editable(
        "git+https://github.com/requests/requests.git#egg=requests[security]")
    deps = get_dependencies_from_index(r)
    assert len(deps) > 0
Beispiel #13
0
def ireq_from_editable(ireq):
    from pip_shims import InstallRequirement
    return InstallRequirement.from_editable(ireq)