Example #1
0
def plugin_package(plugin_package_requires_dist: list[str]) -> Package:
    package = Package("poetry-plugin", "1.2.3")

    for requirement in plugin_package_requires_dist:
        package.add_dependency(Dependency.create_from_pep_508(requirement))

    return package
Example #2
0
def test_dependency_from_pep_508_with_python_full_version_pep440_compatible_release_tilde():
    name = 'pathlib2 ; python_version ~= "3.4" or python_version < "3"'
    dep = Dependency.create_from_pep_508(name)

    assert dep.name == "pathlib2"
    assert str(dep.constraint) == "*"
    assert dep.python_versions == "~=3.4 || <3"
Example #3
0
def test_dependency_platform_in():
    name = "requests (==2.18.0); sys_platform in 'win32 darwin'"
    dep = Dependency.create_from_pep_508(name)

    assert dep.name == "requests"
    assert str(dep.constraint) == "2.18.0"
    assert str(dep.marker) == 'sys_platform in "win32 darwin"'
Example #4
0
    def dependencies(self) -> list[Dependency]:
        if self._dependencies is None:
            # avoid circular dependency when loading DirectoryDependency
            from poetry.core.packages.dependency import Dependency
            from poetry.core.packages.directory_dependency import DirectoryDependency
            from poetry.core.packages.file_dependency import FileDependency

            self._dependencies = []
            for requirement in self.requires:
                dependency = None
                try:
                    dependency = Dependency.create_from_pep_508(requirement)
                except ValueError:
                    # PEP 517 requires can be path if not PEP 508
                    path = Path(requirement)
                    # compatibility Python < 3.8
                    # https://docs.python.org/3/library/pathlib.html#methods
                    with suppress(OSError):
                        if path.is_file():
                            dependency = FileDependency(name=canonicalize_name(
                                path.name),
                                                        path=path)
                        elif path.is_dir():
                            dependency = DirectoryDependency(
                                name=canonicalize_name(path.name), path=path)

                if dependency is None:
                    # skip since we could not determine requirement
                    continue

                self._dependencies.append(dependency)

        return self._dependencies
Example #5
0
def test_dependency_from_pep_508_with_url():
    name = "django-utils @ https://example.com/django-utils-1.0.0.tar.gz"

    dep = Dependency.create_from_pep_508(name)

    assert "django-utils" == dep.name
    assert dep.is_url()
    assert "https://example.com/django-utils-1.0.0.tar.gz" == dep.url
Example #6
0
def test_dependency_from_pep_508_with_extras():
    name = 'requests==2.18.0; extra == "foo" or extra == "bar"'
    dep = Dependency.create_from_pep_508(name)

    assert dep.name == "requests"
    assert str(dep.constraint) == "2.18.0"
    assert dep.in_extras == ["foo", "bar"]
    assert str(dep.marker) == 'extra == "foo" or extra == "bar"'
Example #7
0
def test_dependency_from_pep_508_with_python_full_version_pep440_compatible_release_astrix(
) -> None:
    name = 'pathlib2 ; python_version == "3.4.*" or python_version < "3"'
    dep = Dependency.create_from_pep_508(name)

    assert dep.name == "pathlib2"
    assert str(dep.constraint) == "*"
    assert dep.python_versions == "==3.4.* || <3"
Example #8
0
def test_dependency_python_version_in():
    name = "requests (==2.18.0); python_version in '3.3 3.4 3.5'"
    dep = Dependency.create_from_pep_508(name)

    assert dep.name == "requests"
    assert str(dep.constraint) == "2.18.0"
    assert dep.python_versions == "3.3.* || 3.4.* || 3.5.*"
    assert str(dep.marker) == 'python_version in "3.3 3.4 3.5"'
Example #9
0
def test_dependency_with_extra():
    name = "requests[security] (==2.18.0)"
    dep = Dependency.create_from_pep_508(name)

    assert dep.name == "requests"
    assert str(dep.constraint) == "2.18.0"

    assert len(dep.extras) == 1
    assert "security" in dep.extras
Example #10
0
def test_dependency_from_pep_508_with_platform():
    name = 'requests (==2.18.0); sys_platform == "win32" or sys_platform == "darwin"'
    dep = Dependency.create_from_pep_508(name)

    assert dep.name == "requests"
    assert str(dep.constraint) == "2.18.0"
    assert dep.extras == frozenset()
    assert dep.python_versions == "*"
    assert str(dep.marker) == 'sys_platform == "win32" or sys_platform == "darwin"'
Example #11
0
def test_dependency_from_pep_508_with_wheel_url():
    name = (
        "example_wheel @ https://example.com/example_wheel-14.0.2-py2.py3-none-any.whl"
    )

    dep = Dependency.create_from_pep_508(name)

    assert "example-wheel" == dep.name
    assert str(dep.constraint) == "14.0.2"
Example #12
0
def test_to_pep_508_in_extras_parsed() -> None:
    dependency = Dependency.create_from_pep_508(
        'foo[baz,bar] (>=1.23,<2.0) ; extra == "baz"')

    result = dependency.to_pep_508()
    assert result == 'foo[bar,baz] (>=1.23,<2.0); extra == "baz"'

    result = dependency.to_pep_508(with_extras=False)
    assert result == "foo[bar,baz] (>=1.23,<2.0)"
Example #13
0
def test_dependency_from_pep_508_with_single_python_version():
    name = 'requests (==2.18.0); python_version == "2.7"'
    dep = Dependency.create_from_pep_508(name)

    assert dep.name == "requests"
    assert str(dep.constraint) == "2.18.0"
    assert dep.extras == frozenset()
    assert dep.python_versions == "~2.7"
    assert str(dep.marker) == 'python_version == "2.7"'
Example #14
0
def test_dependency_from_pep_508_with_url() -> None:
    name = "django-utils @ https://example.com/django-utils-1.0.0.tar.gz"

    dep = Dependency.create_from_pep_508(name)

    assert dep.name == "django-utils"
    assert dep.is_url()
    dep = cast(URLDependency, dep)
    assert dep.url == "https://example.com/django-utils-1.0.0.tar.gz"
Example #15
0
def test_dependency_from_pep_508_with_git_url():
    name = "django-utils @ git+ssh://[email protected]/[email protected]"

    dep = Dependency.create_from_pep_508(name)

    assert "django-utils" == dep.name
    assert dep.is_vcs()
    assert "git" == dep.vcs
    assert "ssh://[email protected]/corp-utils.git" == dep.source
    assert "1.2" == dep.reference
def _test_directory_dependency_pep_508(name,
                                       path,
                                       pep_508_input,
                                       pep_508_output=None):
    dep = Dependency.create_from_pep_508(pep_508_input,
                                         relative_to=Path(__file__).parent)

    assert dep.is_directory()
    assert dep.name == name
    assert dep.path == path
    assert dep.to_pep_508() == pep_508_output or pep_508_input
Example #17
0
def test_dependency_from_pep_508_with_git_url() -> None:
    name = "django-utils @ git+ssh://[email protected]/[email protected]"

    dep = Dependency.create_from_pep_508(name)

    assert dep.name == "django-utils"
    assert dep.is_vcs()
    dep = cast(VCSDependency, dep)
    assert dep.vcs == "git"
    assert dep.source == "ssh://[email protected]/corp-utils.git"
    assert dep.reference == "1.2"
Example #18
0
def test_dependency_from_pep_508_with_not_in_op_marker():
    name = ("jinja2 (>=2.7,<2.8)"
            '; python_version not in "3.0,3.1,3.2" and extra == "export"')

    dep = Dependency.create_from_pep_508(name)

    assert dep.name == "jinja2"
    assert str(dep.constraint) == ">=2.7,<2.8"
    assert dep.in_extras == ["export"]
    assert dep.python_versions == "!=3.0.*, !=3.1.*, !=3.2.*"
    assert (str(dep.marker) ==
            'python_version not in "3.0,3.1,3.2" and extra == "export"')
def _test_directory_dependency_pep_508(
        name: str,
        path: Path,
        pep_508_input: str,
        pep_508_output: str | None = None) -> None:
    dep = Dependency.create_from_pep_508(pep_508_input,
                                         relative_to=Path(__file__).parent)

    assert dep.is_directory()
    dep = cast(DirectoryDependency, dep)
    assert dep.name == name
    assert dep.path == path
    assert dep.to_pep_508() == pep_508_output or pep_508_input
Example #20
0
def test_dependency_from_pep_508_with_git_url_and_comment_and_extra():
    name = (
        "poetry @ git+https://github.com/python-poetry/poetry.git@b;ar;#egg=poetry"
        ' ; extra == "foo;"')

    dep = Dependency.create_from_pep_508(name)

    assert "poetry" == dep.name
    assert dep.is_vcs()
    assert "git" == dep.vcs
    assert "https://github.com/python-poetry/poetry.git" == dep.source
    assert "b;ar;" == dep.reference
    assert dep.in_extras == ["foo;"]
Example #21
0
def test_dependency_from_pep_508_with_python_version_union_of_multi():
    name = ("requests (==2.18.0); "
            '(python_version >= "2.7" and python_version < "2.8") '
            'or (python_version >= "3.4" and python_version < "3.5")')
    dep = Dependency.create_from_pep_508(name)

    assert dep.name == "requests"
    assert str(dep.constraint) == "2.18.0"
    assert dep.extras == frozenset()
    assert dep.python_versions == ">=2.7 <2.8 || >=3.4 <3.5"
    assert str(dep.marker) == (
        'python_version >= "2.7" and python_version < "2.8" '
        'or python_version >= "3.4" and python_version < "3.5"')
Example #22
0
def test_dependency_from_pep_508_with_git_url_and_comment_and_extra() -> None:
    name = (
        "poetry @ git+https://github.com/python-poetry/poetry.git@b;ar;#egg=poetry"
        ' ; extra == "foo;"')

    dep = Dependency.create_from_pep_508(name)

    assert dep.name == "poetry"
    assert dep.is_vcs()
    dep = cast(VCSDependency, dep)
    assert dep.vcs == "git"
    assert dep.source == "https://github.com/python-poetry/poetry.git"
    assert dep.reference == "b;ar;"
    assert dep.in_extras == ["foo;"]
Example #23
0
def test_dependency_from_pep_508_complex():
    name = ("requests (==2.18.0); "
            'python_version >= "2.7" and python_version != "3.2" '
            'and (sys_platform == "win32" or sys_platform == "darwin") '
            'and extra == "foo"')
    dep = Dependency.create_from_pep_508(name)

    assert dep.name == "requests"
    assert str(dep.constraint) == "2.18.0"
    assert dep.in_extras == ["foo"]
    assert dep.python_versions == ">=2.7 !=3.2.*"
    assert str(dep.marker) == (
        'python_version >= "2.7" and python_version != "3.2" '
        'and (sys_platform == "win32" or sys_platform == "darwin") '
        'and extra == "foo"')
Example #24
0
def test_dependency_from_pep_508_should_not_produce_empty_constraints_for_correct_markers():
    name = 'pytest-mypy; python_implementation != "PyPy" and python_version <= "3.10" and python_version > "3"'
    dep = Dependency.create_from_pep_508(name)

    assert dep.name == "pytest-mypy"
    assert str(dep.constraint) == "*"
    assert dep.python_versions == "<=3.10 >3"
    assert dep.python_constraint.allows(Version.parse("3.6"))
    assert dep.python_constraint.allows(Version.parse("3.10"))
    assert not dep.python_constraint.allows(Version.parse("3"))
    assert dep.python_constraint.allows(Version.parse("3.0.1"))
    assert (
        str(dep.marker)
        == 'platform_python_implementation != "PyPy" and python_version <= "3.10" and python_version > "3"'
    )
def _test_file_dependency_pep_508(mocker,
                                  name,
                                  path,
                                  pep_508_input,
                                  pep_508_output=None):
    mocker.patch.object(Path, "exists").return_value = True
    mocker.patch.object(Path, "is_file").return_value = True

    dep = Dependency.create_from_pep_508(pep_508_input,
                                         relative_to=Path(__file__).parent)

    assert dep.is_file()
    assert dep.name == name
    assert dep.path == path
    assert dep.to_pep_508() == pep_508_output or pep_508_input
Example #26
0
def test_dependency_from_pep_508_with_git_url_and_subdirectory() -> None:
    name = (
        "django-utils @"
        " git+ssh://[email protected]/[email protected]#subdirectory=package-dir"
    )

    dep = Dependency.create_from_pep_508(name)

    assert dep.name == "django-utils"
    assert dep.is_vcs()
    dep = cast(VCSDependency, dep)
    assert dep.vcs == "git"
    assert dep.source == "ssh://[email protected]/corp-utils.git"
    assert dep.reference == "1.2"
    assert dep.directory == "package-dir"
def pep508_to_dependency_specification(
        requirement: str) -> DependencySpec | None:
    if " ; " not in requirement and re.search(r"@[\^~!=<>\d]", requirement):
        # this is of the form package@<semver>, do not attempt to parse it
        return None

    with contextlib.suppress(ValueError):
        dependency = Dependency.create_from_pep_508(requirement)
        specification: DependencySpec = {}
        specification = dependency_to_specification(dependency, specification)

        if specification:
            specification["name"] = dependency.name
            return specification

    return None
Example #28
0
    def load(cls,
             env: Env,
             with_dependencies: bool = False) -> "InstalledRepository":
        """
        Load installed packages.
        """
        from poetry.core.packages.dependency import Dependency

        repo = cls()
        seen = set()

        for entry in reversed(env.sys_path):
            for distribution in sorted(
                    metadata.distributions(path=[entry]),
                    key=lambda d: str(d._path),
            ):
                name = canonicalize_name(distribution.metadata["name"])

                if name in seen:
                    continue

                path = Path(str(distribution._path))

                try:
                    path.relative_to(_VENDORS)
                except ValueError:
                    pass
                else:
                    continue

                package = cls.create_package_from_distribution(
                    distribution, env)

                if with_dependencies:
                    for require in distribution.metadata.get_all(
                            "requires-dist", []):
                        dep = Dependency.create_from_pep_508(require)
                        package.add_dependency(dep)

                seen.add(package.name)
                repo.add_package(package)

        return repo
def _test_file_dependency_pep_508(
    mocker: MockerFixture,
    name: str,
    path: Path,
    pep_508_input: str,
    pep_508_output: str | None = None,
    marker: BaseMarker | None = None,
) -> None:
    mocker.patch.object(Path, "exists").return_value = True
    mocker.patch.object(Path, "is_file").return_value = True

    dep = Dependency.create_from_pep_508(pep_508_input,
                                         relative_to=Path(__file__).parent)
    if marker:
        dep.marker = marker

    assert dep.is_file()
    dep = cast(FileDependency, dep)
    assert dep.name == name
    assert dep.path == path
    assert dep.to_pep_508() == pep_508_output or pep_508_input
Example #30
0
    def locked_repository(
            self,
            with_dev_reqs: bool = False) -> poetry.repositories.Repository:
        """
        Searches and returns a repository of locked packages.
        """
        from poetry.factory import Factory

        if not self.is_locked():
            return poetry.repositories.Repository()

        lock_data = self.lock_data
        packages = poetry.repositories.Repository()

        if with_dev_reqs:
            locked_packages = lock_data["package"]
        else:
            locked_packages = [
                p for p in lock_data["package"] if p["category"] == "main"
            ]

        if not locked_packages:
            return packages

        for info in locked_packages:
            source = info.get("source", {})
            source_type = source.get("type")
            url = source.get("url")
            if source_type in ["directory", "file"]:
                url = self._lock.path.parent.joinpath(url).resolve().as_posix()

            package = Package(
                info["name"],
                info["version"],
                info["version"],
                source_type=source_type,
                source_url=url,
                source_reference=source.get("reference"),
                source_resolved_reference=source.get("resolved_reference"),
            )
            package.description = info.get("description", "")
            package.category = info.get("category", "main")
            package.groups = info.get("groups", ["default"])
            package.optional = info["optional"]
            if "hashes" in lock_data["metadata"]:
                # Old lock so we create dummy files from the hashes
                package.files = [{
                    "name": h,
                    "hash": h
                } for h in lock_data["metadata"]["hashes"][info["name"]]]
            else:
                package.files = lock_data["metadata"]["files"][info["name"]]

            package.python_versions = info["python-versions"]
            extras = info.get("extras", {})
            if extras:
                for name, deps in extras.items():
                    package.extras[name] = []

                    for dep in deps:
                        try:
                            dependency = Dependency.create_from_pep_508(dep)
                        except InvalidRequirement:
                            # handle lock files with invalid PEP 508
                            m = re.match(
                                r"^(.+?)(?:\[(.+?)])?(?:\s+\((.+)\))?$", dep)
                            dep_name = m.group(1)
                            extras = m.group(2) or ""
                            constraint = m.group(3) or "*"
                            dependency = Dependency(dep_name,
                                                    constraint,
                                                    extras=extras.split(","))
                        package.extras[name].append(dependency)

            if "marker" in info:
                package.marker = parse_marker(info["marker"])
            else:
                # Compatibility for old locks
                if "requirements" in info:
                    dep = Dependency("foo", "0.0.0")
                    for name, value in info["requirements"].items():
                        if name == "python":
                            dep.python_versions = value
                        elif name == "platform":
                            dep.platform = value

                    split_dep = dep.to_pep_508(False).split(";")
                    if len(split_dep) > 1:
                        package.marker = parse_marker(split_dep[1].strip())

            for dep_name, constraint in info.get("dependencies", {}).items():

                root_dir = self._lock.path.parent
                if package.source_type == "directory":
                    # root dir should be the source of the package relative to the lock path
                    root_dir = Path(package.source_url)

                if isinstance(constraint, list):
                    for c in constraint:
                        package.add_dependency(
                            Factory.create_dependency(dep_name,
                                                      c,
                                                      root_dir=root_dir))

                    continue

                package.add_dependency(
                    Factory.create_dependency(dep_name,
                                              constraint,
                                              root_dir=root_dir))

            if "develop" in info:
                package.develop = info["develop"]

            packages.add_package(package)

        return packages