Exemplo n.º 1
0
def test_to_dependency_for_file():
    path = Path(__file__).parent.parent.joinpath(
        "fixtures/distributions/demo-0.1.0.tar.gz")
    package = Package(
        "foo",
        "1.2.3",
        source_type="file",
        source_url=path.as_posix(),
        features=["baz", "bar"],
    )
    dep = package.to_dependency()

    assert "foo" == dep.name
    assert package.version == dep.constraint
    assert frozenset({"bar", "baz"}) == dep.features
    assert dep.is_file()
    assert path == dep.path
    assert "file" == dep.source_type
    assert path.as_posix() == dep.source_url
Exemplo n.º 2
0
    def install_git(self, package: Package) -> None:
        from poetry.core.packages.package import Package

        from poetry.vcs.git import Git

        source = Git.clone(
            url=package.source_url,
            source_root=self._env.path / "src",
            revision=package.source_resolved_reference
            or package.source_reference,
        )

        # Now we just need to install from the source directory
        pkg = Package(package.name, package.version)
        pkg._source_type = "directory"
        pkg._source_url = str(source.path)
        pkg.develop = package.develop

        self.install_directory(pkg)
Exemplo n.º 3
0
def test_to_dependency_for_directory() -> None:
    path = Path(__file__).parent.parent.joinpath("fixtures/simple_project")
    package = Package(
        "foo",
        "1.2.3",
        source_type="directory",
        source_url=path.as_posix(),
        features=["baz", "bar"],
    )
    dep = package.to_dependency()

    assert dep.name == "foo"
    assert dep.constraint == package.version
    assert dep.features == frozenset({"bar", "baz"})
    assert dep.is_directory()
    dep = cast(DirectoryDependency, dep)
    assert dep.path == path
    assert dep.source_type == "directory"
    assert dep.source_url == path.as_posix()
Exemplo n.º 4
0
def test_add_existing_plugin_updates_if_requested(
    tester: CommandTester,
    repo: TestRepository,
    installed: TestRepository,
):
    SelfCommand.get_default_system_pyproject_file().write_text(
        f"""\
[tool.poetry]
name = "poetry-instance"
version = "1.2.0"
description = "Python dependency management and packaging made easy."
authors = []

[tool.poetry.dependencies]
python = "^3.6"

[tool.poetry.group.{SelfCommand.ADDITIONAL_PACKAGE_GROUP}.dependencies]
poetry-plugin = "^1.2.3"
""",
        encoding="utf-8",
    )

    installed.add_package(Package("poetry-plugin", "1.2.3"))

    repo.add_package(Package("poetry-plugin", "1.2.3"))
    repo.add_package(Package("poetry-plugin", "2.3.4"))

    tester.execute("poetry-plugin@latest")

    expected = """\
Using version ^2.3.4 for poetry-plugin

Updating dependencies
Resolving dependencies...

Writing lock file

Package operations: 0 installs, 1 update, 0 removals

  • Updating poetry-plugin (1.2.3 -> 2.3.4)
"""

    assert_plugin_add_result(tester, expected, "^2.3.4")
Exemplo n.º 5
0
def package_git() -> Package:
    package = Package(
        "demo",
        "1.0.0",
        source_type="git",
        source_url="[email protected]:demo/demo.git",
        source_reference="master",
    )

    return package
Exemplo n.º 6
0
def test_requirement(installer: PipInstaller):
    package = Package("ipython", "7.5.0")
    package.files = [
        {"file": "foo-0.1.0.tar.gz", "hash": "md5:dbdc53e3918f28fa335a173432402a00"},
        {
            "file": "foo.0.1.0.whl",
            "hash": "e840810029224b56cd0d9e7719dc3b39cf84d577f8ac686547c8ba7a06eeab26",
        },
    ]

    result = installer.requirement(package, formatted=True)
    expected = (
        "ipython==7.5.0 "
        "--hash md5:dbdc53e3918f28fa335a173432402a00 "
        "--hash sha256:e840810029224b56cd0d9e7719dc3b39cf84d577f8ac686547c8ba7a06eeab26"
        "\n"
    )

    assert result == expected
Exemplo n.º 7
0
def package_with_groups():
    package = Package("foo", "1.2.3")

    optional_group = DependencyGroup("optional", optional=True)
    optional_group.add_dependency(Factory.create_dependency("bam", "^3.0.0"))

    package.add_dependency(Factory.create_dependency("bar", "^1.0.0"))
    package.add_dependency(Factory.create_dependency("baz", "^1.1.0"))
    package.add_dependency(Factory.create_dependency("bim", "^2.0.0", groups=["dev"]))
    package.add_dependency_group(optional_group)

    return package
Exemplo n.º 8
0
def test_package_authors():
    package = Package("foo", "0.1.0")

    package.authors.append("Sébastien Eustace <*****@*****.**>")
    assert package.author_name == "Sébastien Eustace"
    assert package.author_email == "*****@*****.**"

    package.authors.insert(0, "John Doe")
    assert package.author_name == "John Doe"
    assert package.author_email is None
Exemplo n.º 9
0
def test_remove_does_not_live_empty_groups(
    tester: CommandTester,
    app: PoetryTestApplication,
    repo: TestRepository,
    command_tester_factory: CommandTesterFactory,
    installed: Repository,
):
    """
    Empty groups are automatically discarded after package removal.
    """
    installed.add_package(Package("foo", "2.0.0"))
    repo.add_package(Package("foo", "2.0.0"))
    repo.add_package(Package("baz", "1.0.0"))

    content = app.poetry.file.read()

    groups_content = tomlkit.parse("""\
[tool.poetry.group.bar.dependencies]
foo = "^2.0.0"
baz = "^1.0.0"

""")
    content["tool"]["poetry"]["dependencies"]["foo"] = "^2.0.0"
    content["tool"]["poetry"].value._insert_after(
        "dependencies", "group", groups_content["tool"]["poetry"]["group"])
    app.poetry.file.write(content)

    app.poetry.package.add_dependency(
        Factory.create_dependency("foo", "^2.0.0"))
    app.poetry.package.add_dependency(
        Factory.create_dependency("foo", "^2.0.0", groups=["bar"]))
    app.poetry.package.add_dependency(
        Factory.create_dependency("baz", "^1.0.0", groups=["bar"]))

    tester.execute("foo baz --group bar")

    content = app.poetry.file.read()["tool"]["poetry"]
    assert "foo" in content["dependencies"]
    assert "foo" not in content["group"]["bar"]["dependencies"]
    assert "baz" not in content["group"]["bar"]["dependencies"]
    assert "[tool.poetry.group.bar]" not in content.as_string()
    assert "[tool.poetry.group]" not in content.as_string()
Exemplo n.º 10
0
def test_package_authors_invalid():
    package = Package("foo", "0.1.0")

    package.authors.insert(0, "<John Doe")
    with pytest.raises(ValueError) as e:
        package.author_name

    assert (
        str(e.value) ==
        "Invalid author string. Must be in the format: John Smith <*****@*****.**>"
    )
Exemplo n.º 11
0
def test_to_dependency_for_file() -> None:
    path = Path(__file__).parent.parent.joinpath(
        "fixtures/distributions/demo-0.1.0.tar.gz")
    package = Package(
        "foo",
        "1.2.3",
        source_type="file",
        source_url=path.as_posix(),
        features=["baz", "bar"],
    )
    dep = package.to_dependency()

    assert dep.name == "foo"
    assert dep.constraint == package.version
    assert dep.features == frozenset({"bar", "baz"})
    assert dep.is_file()
    dep = cast(FileDependency, dep)
    assert dep.path == path
    assert dep.source_type == "file"
    assert dep.source_url == path.as_posix()
Exemplo n.º 12
0
    def install_git(self, package: "Package") -> None:
        from poetry.core.packages.package import Package
        from poetry.core.vcs.git import Git

        src_dir = self._env.path / "src" / package.name
        if src_dir.exists():
            safe_rmtree(str(src_dir))

        src_dir.parent.mkdir(exist_ok=True)

        git = Git()
        git.clone(package.source_url, src_dir)
        git.checkout(package.source_reference, src_dir)

        # Now we just need to install from the source directory
        pkg = Package(package.name, package.version)
        pkg._source_type = "directory"
        pkg._source_url = str(src_dir)
        pkg.develop = package.develop

        self.install_directory(pkg)
Exemplo n.º 13
0
def test_add_with_constraint(
    tester: CommandTester,
    repo: TestRepository,
):
    repo.add_package(Package("poetry-plugin", "0.1.0"))
    repo.add_package(Package("poetry-plugin", "0.2.0"))

    tester.execute("poetry-plugin@^0.2.0")

    expected = """
Updating dependencies
Resolving dependencies...

Writing lock file

Package operations: 1 install, 0 updates, 0 removals

  • Installing poetry-plugin (0.2.0)
"""

    assert_plugin_add_result(tester, expected, "^0.2.0")
Exemplo n.º 14
0
def test_chooser_chooses_system_specific_wheel_link_if_available(
    mock_pypi, mock_legacy, source_type, pool
):
    env = MockEnv(
        supported_tags=[Tag("cp37", "cp37m", "win32"), Tag("py3", "none", "any")]
    )
    chooser = Chooser(pool, env)

    package = Package("pyyaml", "3.13.0")
    if source_type == "legacy":
        package = Package(
            package.name,
            package.version.text,
            source_type="legacy",
            source_reference="foo",
            source_url="https://foo.bar/simple/",
        )

    link = chooser.choose_for(package)

    assert "PyYAML-3.13-cp37-cp37m-win32.whl" == link.filename
Exemplo n.º 15
0
    def find_packages(self, dependency: Dependency) -> list[Package]:
        packages = []
        constraint, allow_prereleases = self._get_constraints_from_dependency(
            dependency)

        key = dependency.name
        if not constraint.is_any():
            key = f"{key}:{constraint!s}"

        ignored_pre_release_versions = []

        if self._cache.store("matches").has(key):
            versions = self._cache.store("matches").get(key)
        else:
            page = self._get_page(f"/{dependency.name.replace('.', '-')}/")
            if page is None:
                return []

            versions = []
            for version in page.versions(dependency.name):
                if version.is_unstable() and not allow_prereleases:
                    if constraint.is_any():
                        # we need this when all versions of the package are pre-releases
                        ignored_pre_release_versions.append(version)
                    continue

                if constraint.allows(version):
                    versions.append(version)

            self._cache.store("matches").put(key, versions, 5)

        for package_versions in (versions, ignored_pre_release_versions):
            for version in package_versions:
                package = Package(
                    dependency.name,
                    version,
                    source_type="legacy",
                    source_reference=self.name,
                    source_url=self._url,
                )

                packages.append(package)

            self._log(
                f"{len(packages)} packages found for {dependency.name} {constraint!s}",
                level="debug",
            )

            if packages or not constraint.is_any():
                # we have matching packages, or constraint is not (*)
                break

        return packages
Exemplo n.º 16
0
def test_add_existing_plugin_warns_about_no_operation(app, repo, tester, env,
                                                      installed):
    env.path.joinpath("pyproject.toml").write_text(
        """\
[tool.poetry]
name = "poetry"
version = "1.2.0"
description = "Python dependency management and packaging made easy."
authors = [
    "Sébastien Eustace <*****@*****.**>"
]

[tool.poetry.dependencies]
python = "^3.6"
poetry-plugin = "^1.2.3"
""",
        encoding="utf-8",
    )

    installed.add_package(Package("poetry-plugin", "1.2.3"))

    repo.add_package(Package("poetry-plugin", "1.2.3"))

    tester.execute("poetry-plugin")

    expected = """\
The following plugins are already present in the pyproject.toml file and will be skipped:

  • poetry-plugin

If you want to update it to the latest compatible version, you can use `poetry plugin update package`.
If you prefer to upgrade it to the latest available version, you can use `poetry plugin add package@latest`.

"""

    assert tester.io.fetch_output() == expected

    update_command = app.find("update")
    # The update command should not have been called
    assert update_command.poetry.file.parent != env.path
Exemplo n.º 17
0
def test_package_resolved_reference_is_relevant_for_equality_only_if_present_for_both_packages(
):
    a1 = Package(
        "a",
        "0.1.0",
        source_type="git",
        source_url="https://foo.bar",
        source_reference="master",
        source_resolved_reference="c01b317af582501c5ba07b23d5bef3fbada2d4ef",
    )
    a2 = Package(
        a1.name,
        a1.version,
        source_type="git",
        source_url="https://foo.bar",
        source_reference="master",
        source_resolved_reference="a444731cd243cb5cd04e4d5fb81f86e1fecf8a00",
    )
    a3 = Package(
        a1.name,
        a1.version,
        source_type="git",
        source_url="https://foo.bar",
        source_reference="master",
        source_resolved_reference="c01b317af582501c5ba07b23d5bef3fbada2d4ef",
    )
    a4 = Package(
        a1.name,
        a1.version,
        source_type="git",
        source_url="https://foo.bar",
        source_reference="master",
    )

    assert a1 == a1
    assert a1 == a3
    assert a1 != a2
    assert a2 != a3
    assert a1 == a4
    assert a2 == a4
Exemplo n.º 18
0
def test_it_should_calculate_operations_in_correct_order():
    transaction = Transaction(
        [Package("a", "1.0.0"), Package("b", "2.0.0"), Package("c", "3.0.0")],
        [
            (Package("a", "1.0.0"), 1),
            (Package("b", "2.1.0"), 2),
            (Package("d", "4.0.0"), 0),
        ],
    )

    check_operations(
        transaction.calculate_operations(),
        [
            {"job": "install", "package": Package("b", "2.1.0")},
            {"job": "install", "package": Package("a", "1.0.0")},
            {"job": "install", "package": Package("d", "4.0.0")},
        ],
    )
Exemplo n.º 19
0
def test_executor_should_write_pep610_url_references_for_directories(
    tmp_venv, pool, config, io
):
    url = Path(__file__).parent.parent.joinpath("fixtures/simple_project").resolve()
    package = Package(
        "simple-project", "1.2.3", source_type="directory", source_url=url.as_posix()
    )

    executor = Executor(tmp_venv, pool, config, io)
    executor.execute([Install(package)])
    verify_installed_distribution(
        tmp_venv, package, {"dir_info": {}, "url": url.as_uri()}
    )
Exemplo n.º 20
0
def test_add_existing_plugin_updates_if_requested(app, repo, tester, env,
                                                  installed, mocker):
    env.path.joinpath("pyproject.toml").write_text(
        """\
[tool.poetry]
name = "poetry"
version = "1.2.0"
description = "Python dependency management and packaging made easy."
authors = [
    "Sébastien Eustace <*****@*****.**>"
]

[tool.poetry.dependencies]
python = "^3.6"
poetry-plugin = "^1.2.3"
""",
        encoding="utf-8",
    )

    installed.add_package(Package("poetry-plugin", "1.2.3"))

    repo.add_package(Package("poetry-plugin", "1.2.3"))
    repo.add_package(Package("poetry-plugin", "2.3.4"))

    tester.execute("poetry-plugin@latest")

    expected = """\
Using version ^2.3.4 for poetry-plugin
Updating dependencies
Resolving dependencies...

Writing lock file

Package operations: 0 installs, 1 update, 0 removals

  • Updating poetry-plugin (1.2.3 -> 2.3.4)
"""

    assert_plugin_add_result(tester, app, env, expected, "^2.3.4")
Exemplo n.º 21
0
    def search(self, query: str) -> list[Package]:
        results = []

        search = {"q": query}

        response = requests.session().get(self._base_url + "search",
                                          params=search,
                                          timeout=REQUESTS_TIMEOUT)
        content = parse(response.content, namespaceHTMLElements=False)
        for result in content.findall(".//*[@class='package-snippet']"):
            name_element = result.find("h3/*[@class='package-snippet__name']")
            version_element = result.find(
                "h3/*[@class='package-snippet__version']")

            if (name_element is None or version_element is None
                    or not name_element.text or not version_element.text):
                continue

            name = name_element.text
            version = version_element.text

            description_element = result.find(
                "p[@class='package-snippet__description']")
            description = (description_element.text
                           if description_element is not None
                           and description_element.text else "")

            try:
                package = Package(name, version)
                package.description = to_str(description.strip())
                results.append(package)
            except InvalidVersion:
                self._log(
                    f'Unable to parse version "{version}" for the {name} package,'
                    " skipping",
                    level="debug",
                )

        return results
Exemplo n.º 22
0
def test_remove_command_should_not_write_changes_upon_installer_errors(
        tester, app, repo, command_tester_factory, mocker):
    repo.add_package(Package("foo", "2.0.0"))

    command_tester_factory("add").execute("foo")

    mocker.patch("poetry.installation.installer.Installer.run", return_value=1)

    original_content = app.poetry.file.read().as_string()

    tester.execute("foo")

    assert app.poetry.file.read().as_string() == original_content
Exemplo n.º 23
0
def test_chooser_chooses_sdist_if_no_compatible_wheel_link_is_available(
    env,
    mock_pypi,
    mock_legacy,
    source_type,
    pool,
):
    chooser = Chooser(pool, env)

    package = Package("pyyaml", "3.13.0")
    if source_type == "legacy":
        package = Package(
            package.name,
            package.version.text,
            source_type="legacy",
            source_reference="foo",
            source_url="https://foo.bar/simple/",
        )

    link = chooser.choose_for(package)

    assert "PyYAML-3.13.tar.gz" == link.filename
Exemplo n.º 24
0
def test_add_existing_plugin_warns_about_no_operation(
    tester: CommandTester,
    repo: TestRepository,
    installed: TestRepository,
):
    SelfCommand.get_default_system_pyproject_file().write_text(
        f"""\
[tool.poetry]
name = "poetry-instance"
version = "1.2.0"
description = "Python dependency management and packaging made easy."
authors = []

[tool.poetry.dependencies]
python = "^3.6"

[tool.poetry.group.{SelfCommand.ADDITIONAL_PACKAGE_GROUP}.dependencies]
poetry-plugin = "^1.2.3"
""",
        encoding="utf-8",
    )

    installed.add_package(Package("poetry-plugin", "1.2.3"))

    repo.add_package(Package("poetry-plugin", "1.2.3"))

    tester.execute("poetry-plugin")

    expected = f"""\
The following packages are already present in the pyproject.toml and will be\
 skipped:

  • poetry-plugin
{tester.command._hint_update_packages}
Nothing to add.
"""

    assert tester.io.fetch_output() == expected
Exemplo n.º 25
0
def test_executor_should_check_every_possible_hash_types_before_failing(
    config, io, pool, mocker, fixture_dir, tmp_dir
):
    mocker.patch.object(
        Chef, "get_cached_archive_for_link", side_effect=lambda link: link,
    )
    mocker.patch.object(
        Executor,
        "_download_archive",
        return_value=fixture_dir("distributions").joinpath(
            "demo-0.1.0-py2.py3-none-any.whl"
        ),
    )

    env = MockEnv(path=Path(tmp_dir))
    executor = Executor(env, pool, config, io)

    package = Package("demo", "0.1.0")
    package.files = [
        {"file": "demo-0.1.0-py2.py3-none-any.whl", "hash": "md5:123456"},
        {"file": "demo-0.1.0-py2.py3-none-any.whl", "hash": "sha256:123456"},
    ]

    expected_message = (
        "Invalid hashes "
        "("
        "md5:15507846fd4299596661d0197bfb4f90, "
        "sha256:70e704135718fffbcbf61ed1fc45933cfd86951a744b681000eaaa75da31f17a"
        ") "
        "for demo (0.1.0) using archive demo-0.1.0-py2.py3-none-any.whl. "
        "Expected one of md5:123456, sha256:123456."
    )

    with pytest.raises(RuntimeError, match=re.escape(expected_message)):
        executor._download_link(
            Install(package),
            Link("https://example.com/demo-0.1.0-py2.py3-none-any.whl"),
        )
Exemplo n.º 26
0
def test_self_update_can_update_from_recommended_installation(
    tester: CommandTester,
    repo: TestRepository,
    installed: TestRepository,
):
    new_version = Version.parse(__version__).next_minor().text

    old_poetry = Package("poetry", __version__)
    old_poetry.add_dependency(Factory.create_dependency("cleo", "^0.8.2"))

    new_poetry = Package("poetry", new_version)
    new_poetry.add_dependency(Factory.create_dependency("cleo", "^1.0.0"))

    installed.add_package(old_poetry)
    installed.add_package(Package("cleo", "0.8.2"))

    repo.add_package(new_poetry)
    repo.add_package(Package("cleo", "1.0.0"))

    tester.execute()

    expected_output = f"""\
Updating Poetry version ...

Using version ^{new_version} for poetry

Updating dependencies
Resolving dependencies...

Writing lock file

Package operations: 0 installs, 2 updates, 0 removals

  • Updating cleo (0.8.2 -> 1.0.0)
  • Updating poetry ({__version__} -> {new_version})
"""

    assert tester.io.fetch_output() == expected_output
Exemplo n.º 27
0
def test_requirement_source_type_url():
    installer = PipInstaller(NullEnv(), NullIO(), Pool())

    foo = Package(
        "foo",
        "0.0.0",
        source_type="url",
        source_url="https://somehwere.com/releases/foo-1.0.0.tar.gz",
    )

    result = installer.requirement(foo, formatted=True)
    expected = "{}#egg={}".format(foo.source_url, foo.name)

    assert expected == result
Exemplo n.º 28
0
def test_install_with_non_pypi_default_repository(pool, installer):
    default = LegacyRepository("default", "https://default.com")
    another = LegacyRepository("another", "https://another.com")

    pool.add_repository(default, default=True)
    pool.add_repository(another)

    foo = Package(
        "foo",
        "0.0.0",
        source_type="legacy",
        source_reference=default.name,
        source_url=default.url,
    )
    bar = Package(
        "bar",
        "0.1.0",
        source_type="legacy",
        source_reference=another.name,
        source_url=another.url,
    )

    installer.install(foo)
    installer.install(bar)
Exemplo n.º 29
0
def test_executor_should_write_pep610_url_references_for_files(
        tmp_venv, pool, config, io):
    url = (Path(__file__).parent.parent.joinpath(
        "fixtures/distributions/demo-0.1.0-py2.py3-none-any.whl").resolve())
    package = Package("demo",
                      "0.1.0",
                      source_type="file",
                      source_url=url.as_posix())

    executor = Executor(tmp_venv, pool, config, io)
    executor.execute([Install(package)])
    verify_installed_distribution(tmp_venv, package, {
        "archive_info": {},
        "url": url.as_uri()
    })
Exemplo n.º 30
0
def test_throw_on_invalid_package():
    invalid = next(
        filter(
            lambda e: str(e._path).endswith("invalid-0.0.1.dist-info"),
            sorted(
                metadata.distributions(path=[str(SITE_PURELIB)]),
                key=lambda d: str(d._path),
            ),
        )
    )
    name = invalid.metadata["name"]
    version = invalid.metadata["version"]
    with pytest.raises(TypeError) as error:
        Package(name, version, version)
    assert str(error.value) == "expected string or bytes-like object"