Beispiel #1
0
def test_build_env_allow_only_one_install(script):
    create_basic_wheel_for_package(script, 'foo', '1.0')
    create_basic_wheel_for_package(script, 'bar', '1.0')
    finder = PackageFinder([script.scratch_path], [], session=PipSession())
    build_env = BuildEnvironment()
    for prefix in ('normal', 'overlay'):
        build_env.install_requirements(finder, ['foo'], prefix,
                                       'installing foo in %s' % prefix)
        with pytest.raises(AssertionError):
            build_env.install_requirements(finder, ['bar'], prefix,
                                           'installing bar in %s' % prefix)
        with pytest.raises(AssertionError):
            build_env.install_requirements(finder, [], prefix,
                                           'installing in %s' % prefix)
Beispiel #2
0
def test_build_env_requirements_check(script):

    create_basic_wheel_for_package(script, 'foo', '2.0')
    create_basic_wheel_for_package(script, 'bar', '1.0')
    create_basic_wheel_for_package(script, 'bar', '3.0')
    create_basic_wheel_for_package(script, 'other', '0.5')

    script.pip_install_local('-f', script.scratch_path, 'foo', 'bar', 'other')

    run_with_build_env(
        script,
        '''
        r = build_env.check_requirements(['foo', 'bar', 'other'])
        assert r == (set(), {'foo', 'bar', 'other'}), repr(r)

        r = build_env.check_requirements(['foo>1.0', 'bar==3.0'])
        assert r == (set(), {'foo>1.0', 'bar==3.0'}), repr(r)

        r = build_env.check_requirements(['foo>3.0', 'bar>=2.5'])
        assert r == (set(), {'foo>3.0', 'bar>=2.5'}), repr(r)
        ''')

    run_with_build_env(
        script,
        '''
        build_env.install_requirements(finder, ['foo', 'bar==3.0'], 'normal',
                                       'installing foo in normal')

        r = build_env.check_requirements(['foo', 'bar', 'other'])
        assert r == (set(), {'other'}), repr(r)

        r = build_env.check_requirements(['foo>1.0', 'bar==3.0'])
        assert r == (set(), set()), repr(r)

        r = build_env.check_requirements(['foo>3.0', 'bar>=2.5'])
        assert r == ({('foo==2.0', 'foo>3.0')}, set()), repr(r)
        ''')

    run_with_build_env(
        script,
        '''
        build_env.install_requirements(finder, ['foo', 'bar==3.0'], 'normal',
                                       'installing foo in normal')
        build_env.install_requirements(finder, ['bar==1.0'], 'overlay',
                                       'installing foo in overlay')

        r = build_env.check_requirements(['foo', 'bar', 'other'])
        assert r == (set(), {'other'}), repr(r)

        r = build_env.check_requirements(['foo>1.0', 'bar==3.0'])
        assert r == ({('bar==1.0', 'bar==3.0')}, set()), repr(r)

        r = build_env.check_requirements(['foo>3.0', 'bar>=2.5'])
        assert r == ({('bar==1.0', 'bar>=2.5'), ('foo==2.0', 'foo>3.0')}, \
            set()), repr(r)
        ''')
Beispiel #3
0
def test_build_env_overlay_prefix_has_priority(script):
    create_basic_wheel_for_package(script, 'pkg', '2.0')
    create_basic_wheel_for_package(script, 'pkg', '4.3')
    result = run_with_build_env(
        script,
        '''
        build_env.install_requirements(finder, ['pkg==2.0'], 'overlay',
                                       'installing pkg==2.0 in overlay')
        build_env.install_requirements(finder, ['pkg==4.3'], 'normal',
                                       'installing pkg==4.3 in normal')
        ''',
        '''
        from __future__ import print_function

        print(__import__('pkg').__version__)
        ''')
    assert result.stdout.strip() == '2.0', str(result)
Beispiel #4
0
def test_yaml_based(script, case):
    available = case.get("available", [])
    requests = case.get("request", [])
    transaction = case.get("transaction", [])

    assert len(requests) == len(transaction), (
        "Expected requests and transaction counts to be same"
    )

    # Create a custom index of all the packages that are supposed to be
    # available
    # XXX: This doesn't work because this isn't making an index of files.
    for package in available:
        if isinstance(package, str):
            package = _convert_to_dict(package)

        assert isinstance(package, dict), "Needs to be a dictionary"

        create_basic_wheel_for_package(script, **package)

    available_actions = {
        "install": handle_install_request
    }

    # use scratch path for index
    for request, expected in zip(requests, transaction):
        # The name of the key is what action has to be taken
        assert len(request.keys()) == 1, "Expected only one action"

        # Get the only key
        action = list(request.keys())[0]

        assert action in available_actions.keys(), (
            "Unsupported action {!r}".format(action)
        )

        # Perform the requested action
        effect = available_actions[action](script, request[action])

        assert effect == expected, "Fixture did not succeed."
Beispiel #5
0
def test_build_env_isolation(script):

    # Create dummy `pkg` wheel.
    pkg_whl = create_basic_wheel_for_package(script, 'pkg', '1.0')

    # Install it to site packages.
    script.pip_install_local(pkg_whl)

    # And a copy in the user site.
    script.pip_install_local('--ignore-installed', '--user', pkg_whl)

    # And to another directory available through a .pth file.
    target = script.scratch_path / 'pth_install'
    script.pip_install_local('-t', target, pkg_whl)
    (script.site_packages_path / 'build_requires.pth').write(
        str(target) + '\n'
    )

    # And finally to yet another directory available through PYTHONPATH.
    target = script.scratch_path / 'pypath_install'
    script.pip_install_local('-t', target, pkg_whl)
    script.environ["PYTHONPATH"] = target

    run_with_build_env(
        script, '',
        r'''
        from __future__ import print_function
        from distutils.sysconfig import get_python_lib
        import sys

        try:
            import pkg
        except ImportError:
            pass
        else:
            print('imported `pkg` from `%s`' % pkg.__file__, file=sys.stderr)
            print('system sites:\n  ' + '\n  '.join(sorted({
                          get_python_lib(plat_specific=0),
                          get_python_lib(plat_specific=1),
                    })), file=sys.stderr)
            print('sys.path:\n  ' + '\n  '.join(sys.path), file=sys.stderr)
            sys.exit(1)
        ''')
Beispiel #6
0
def test_new_resolver_presents_messages_when_backtracking_a_lot(script, N):
    # Generate a set of wheels that will definitely cause backtracking.
    for index in range(1, N+1):
        A_version = "{index}.0.0".format(index=index)
        B_version = "{index}.0.0".format(index=index)
        C_version = "{index_minus_one}.0.0".format(index_minus_one=index - 1)

        depends = ["B == " + B_version]
        if index != 1:
            depends.append("C == " + C_version)

        print("A", A_version, "B", B_version, "C", C_version)
        create_basic_wheel_for_package(script, "A", A_version, depends=depends)

    for index in range(1, N+1):
        B_version = "{index}.0.0".format(index=index)
        C_version = "{index}.0.0".format(index=index)
        depends = ["C == " + C_version]

        print("B", B_version, "C", C_version)
        create_basic_wheel_for_package(script, "B", B_version, depends=depends)

    for index in range(1, N+1):
        C_version = "{index}.0.0".format(index=index)
        print("C", C_version)
        create_basic_wheel_for_package(script, "C", C_version)

    # Install A
    result = script.pip(
        "install",
        "--no-cache-dir",
        "--no-index",
        "--find-links", script.scratch_path,
        "A"
    )

    assert_installed(script, A="1.0.0", B="1.0.0", C="1.0.0")
    # These numbers are hard-coded in the code.
    if N >= 1:
        assert "This could take a while." in result.stdout
    if N >= 8:
        assert result.stdout.count("This could take a while.") >= 2
    if N >= 13:
        assert "press Ctrl + C" in result.stdout
Beispiel #7
0
def test_new_resolver_build_directory_error_zazo_19(script):
    """https://github.com/pradyunsg/zazo/issues/19#issuecomment-631615674

    This will first resolve like this:

    1. Pin pkg-b==2.0.0 (since pkg-b has fewer choices)
    2. Pin pkg-a==3.0.0 -> Conflict due to dependency pkg-b<2
    3. Pin pkg-b==1.0.0

    Since pkg-b is only available as sdist, both the first and third steps
    would trigger building from source. This ensures the preparer can build
    different versions of a package for the resolver.

    The preparer would fail with the following message if the different
    versions end up using the same build directory::

        ERROR: pip can't proceed with requirements 'pkg-b ...' due to a
        pre-existing build directory (...). This is likely due to a previous
        installation that failed. pip is being responsible and not assuming it
        can delete this. Please delete it and try again.
    """
    create_basic_wheel_for_package(
        script,
        "pkg_a",
        "3.0.0",
        depends=["pkg-b<2"],
    )
    create_basic_wheel_for_package(script, "pkg_a", "2.0.0")
    create_basic_wheel_for_package(script, "pkg_a", "1.0.0")

    create_basic_sdist_for_package(script, "pkg_b", "2.0.0")
    create_basic_sdist_for_package(script, "pkg_b", "1.0.0")

    script.pip(
        "install",
        "--use-feature=2020-resolver",
        "--no-cache-dir",
        "--no-index",
        "--find-links",
        script.scratch_path,
        "pkg-a",
        "pkg-b",
    )
    assert_installed(script, pkg_a="3.0.0", pkg_b="1.0.0")
Beispiel #8
0
def test_new_resolver_requires_python(
    script,
    requires_python,
    ignore_requires_python,
    dep_version,
):
    create_basic_wheel_for_package(
        script,
        "base",
        "0.1.0",
        depends=["dep"],
    )
    create_basic_wheel_for_package(
        script,
        "dep",
        "0.1.0",
    )
    create_basic_wheel_for_package(
        script,
        "dep",
        "0.2.0",
        requires_python=requires_python,
    )

    args = [
        "install",
        "--unstable-feature=resolver",
        "--no-cache-dir",
        "--no-index",
        "--find-links",
        script.scratch_path,
    ]
    if ignore_requires_python:
        args.append("--ignore-requires-python")
    args.append("base")

    script.pip(*args)

    assert_installed(script, base="0.1.0", dep=dep_version)
Beispiel #9
0
def test_new_resolver_lazy_fetch_candidates(script, upgrade):
    create_basic_wheel_for_package(script, "myuberpkg", "1")
    create_basic_wheel_for_package(script, "myuberpkg", "2")
    create_basic_wheel_for_package(script, "myuberpkg", "3")

    # Install an old version first.
    script.pip(
        "install",
        "--no-cache-dir",
        "--no-index",
        "--find-links",
        script.scratch_path,
        "myuberpkg==1",
    )

    # Now install the same package again, maybe with the upgrade flag.
    if upgrade:
        pip_upgrade_args = ["--upgrade"]
    else:
        pip_upgrade_args = []
    result = script.pip(
        "install",
        "--no-cache-dir",
        "--no-index",
        "--find-links",
        script.scratch_path,
        "myuberpkg",
        *pip_upgrade_args  # Trailing comma fails on Python 2.
    )

    # pip should install the version preferred by the strategy...
    if upgrade:
        assert_installed(script, myuberpkg="3")
    else:
        assert_installed(script, myuberpkg="1")

    # But should reach there in the best route possible, without trying
    # candidates it does not need to.
    assert "myuberpkg-2" not in result.stdout, str(result)
Beispiel #10
0
def test_new_resolver_constraint_only_marker_match(script):
    create_basic_wheel_for_package(script, "pkg", "1.0")
    create_basic_wheel_for_package(script, "pkg", "2.0")
    create_basic_wheel_for_package(script, "pkg", "3.0")

    constrants_content = textwrap.dedent(
        """
        pkg==1.0; python_version == "{ver[0]}.{ver[1]}"  # Always satisfies.
        pkg==2.0; python_version < "0"  # Never satisfies.
        """
    ).format(ver=sys.version_info)
    constraints_txt = script.scratch_path / "constraints.txt"
    constraints_txt.write_text(constrants_content)

    script.pip(
        "install",
        "--no-cache-dir", "--no-index",
        "-c", constraints_txt,
        "--find-links", script.scratch_path,
        "pkg",
    )
    assert_installed(script, pkg="1.0")
Beispiel #11
0
def test_build_env_requirements_check(script: PipTestEnvironment) -> None:

    create_basic_wheel_for_package(script, "foo", "2.0")
    create_basic_wheel_for_package(script, "bar", "1.0")
    create_basic_wheel_for_package(script, "bar", "3.0")
    create_basic_wheel_for_package(script, "other", "0.5")

    script.pip_install_local("-f", script.scratch_path, "foo", "bar", "other")

    run_with_build_env(
        script,
        """
        r = build_env.check_requirements(['foo', 'bar', 'other'])
        assert r == (set(), {'foo', 'bar', 'other'}), repr(r)

        r = build_env.check_requirements(['foo>1.0', 'bar==3.0'])
        assert r == (set(), {'foo>1.0', 'bar==3.0'}), repr(r)

        r = build_env.check_requirements(['foo>3.0', 'bar>=2.5'])
        assert r == (set(), {'foo>3.0', 'bar>=2.5'}), repr(r)
        """,
    )

    run_with_build_env(
        script,
        """
        build_env.install_requirements(finder, ['foo', 'bar==3.0'], 'normal',
                                       kind='installing foo in normal')

        r = build_env.check_requirements(['foo', 'bar', 'other'])
        assert r == (set(), {'other'}), repr(r)

        r = build_env.check_requirements(['foo>1.0', 'bar==3.0'])
        assert r == (set(), set()), repr(r)

        r = build_env.check_requirements(['foo>3.0', 'bar>=2.5'])
        assert r == ({('foo==2.0', 'foo>3.0')}, set()), repr(r)
        """,
    )

    run_with_build_env(
        script,
        """
        build_env.install_requirements(finder, ['foo', 'bar==3.0'], 'normal',
                                       kind='installing foo in normal')
        build_env.install_requirements(finder, ['bar==1.0'], 'overlay',
                                       kind='installing foo in overlay')

        r = build_env.check_requirements(['foo', 'bar', 'other'])
        assert r == (set(), {'other'}), repr(r)

        r = build_env.check_requirements(['foo>1.0', 'bar==3.0'])
        assert r == ({('bar==1.0', 'bar==3.0')}, set()), repr(r)

        r = build_env.check_requirements(['foo>3.0', 'bar>=2.5'])
        assert r == ({('bar==1.0', 'bar>=2.5'), ('foo==2.0', 'foo>3.0')}, \
            set()), repr(r)
        """,
    )

    run_with_build_env(
        script,
        """
        build_env.install_requirements(
            finder,
            ["bar==3.0"],
            "normal",
            kind="installing bar in normal",
        )
        r = build_env.check_requirements(
            [
                "bar==2.0; python_version < '3.0'",
                "bar==3.0; python_version >= '3.0'",
                "foo==4.0; extra == 'dev'",
            ],
        )
        assert r == (set(), set()), repr(r)
        """,
    )