예제 #1
0
def test_accepts_fails_with_python_versions_mismatch():
    dependency = Dependency("A", "^1.0")
    dependency.python_versions = "^3.6"
    package = Package("B", "1.4")
    package.python_versions = "~3.5"

    assert not dependency.accepts(package)
예제 #2
0
        def _get_min(dependency: Dependency) -> int:
            if dependency.name in self._use_latest:
                # If we're forced to use the latest version of a package, it effectively
                # only has one version to choose from.
                return 1

            locked = self._get_locked(dependency)
            if locked and (
                dependency.constraint.allows(locked.version)
                or locked.is_prerelease()
                and dependency.constraint.allows(locked.version.next_patch)
            ):
                return 1

            # VCS, URL, File or Directory dependencies
            # represent a single version
            if (
                dependency.is_vcs()
                or dependency.is_url()
                or dependency.is_file()
                or dependency.is_directory()
            ):
                return 1

            try:
                return len(self._provider.search_for(dependency))
            except ValueError:
                return 0
예제 #3
0
    def solve(self):  # type: () -> SolverResult
        """
        Finds a set of dependencies that match the root package's constraints,
        or raises an error if no such set is available.
        """
        start = time.time()
        root_dependency = Dependency(self._root.name, self._root.version)
        root_dependency.is_root = True

        self._add_incompatibility(
            Incompatibility([Term(root_dependency, False)], RootCause()))

        try:
            next = self._root.name
            while next is not None:
                self._propagate(next)
                next = self._choose_package_version()

            return self._result()
        except Exception:
            raise
        finally:
            self._log("Version solving took {:.3f} seconds.\n"
                      "Tried {} solutions.".format(
                          time.time() - start,
                          self._solution.attempted_solutions))
예제 #4
0
def test_accepts_python_versions():
    dependency = Dependency("A", "^1.0")
    dependency.python_versions = "^3.6"
    package = Package("A", "1.4")
    package.python_versions = "~3.6"

    assert dependency.accepts(package)
예제 #5
0
    def _non_empty_term(self, constraint, is_positive):
        if constraint.is_empty():
            return

        dep = Dependency(self.dependency.name, constraint)
        dep.python_versions = str(self.dependency.python_versions)

        return Term(dep, is_positive)
예제 #6
0
def test_to_pep_508_with_patch_python_version(python_versions, marker):
    dependency = Dependency("Django", "^1.23")
    dependency.python_versions = python_versions

    expected = "Django (>=1.23,<2.0); {}".format(marker)

    assert expected == dependency.to_pep_508()
    assert marker == str(dependency.marker)
예제 #7
0
def test_to_pep_508_in_extras():
    dependency = Dependency("Django", "^1.23")
    dependency.in_extras.append("foo")

    result = dependency.to_pep_508()
    assert result == 'Django (>=1.23,<2.0); extra == "foo"'

    result = dependency.to_pep_508(with_extras=False)
    assert result == "Django (>=1.23,<2.0)"

    dependency.in_extras.append("bar")

    result = dependency.to_pep_508()
    assert result == 'Django (>=1.23,<2.0); extra == "foo" or extra == "bar"'

    dependency.python_versions = "~2.7 || ^3.6"

    result = dependency.to_pep_508()
    assert result == ("Django (>=1.23,<2.0); "
                      "("
                      'python_version >= "2.7" and python_version < "2.8" '
                      'or python_version >= "3.6" and python_version < "4.0"'
                      ") "
                      'and (extra == "foo" or extra == "bar")')

    result = dependency.to_pep_508(with_extras=False)
    assert result == ("Django (>=1.23,<2.0); "
                      'python_version >= "2.7" and python_version < "2.8" '
                      'or python_version >= "3.6" and python_version < "4.0"')
예제 #8
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)
                    try:
                        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)
                    except OSError:
                        # compatibility Python < 3.8
                        # https://docs.python.org/3/library/pathlib.html#methods
                        pass

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

                self._dependencies.append(dependency)

        return self._dependencies
예제 #9
0
    def _update_with_new_method(self, version):
        from poetry.config.config import Config
        from poetry.core.packages.dependency import Dependency
        from poetry.core.packages.project_package import ProjectPackage
        from poetry.installation.installer import Installer
        from poetry.packages.locker import NullLocker
        from poetry.repositories.installed_repository import InstalledRepository
        from poetry.utils.env import EnvManager

        env = EnvManager.get_system_env(naive=True)
        installed = InstalledRepository.load(env)

        root = ProjectPackage("poetry-updater", "0.0.0")
        root.python_versions = ".".join(str(c) for c in env.version_info[:3])
        root.add_dependency(Dependency("poetry", version.text))

        installer = Installer(
            self.io,
            env,
            root,
            NullLocker(self.data_dir.joinpath("poetry.lock"), {}),
            self.pool,
            Config(),
            installed=installed,
        )
        installer.update(True)
        installer.run()
예제 #10
0
    def handle(self):
        from poetry.__version__ import __version__
        from poetry.core.semver import Version
        from poetry.utils.env import EnvManager

        new_update_method = False
        try:
            self._check_recommended_installation()
        except RuntimeError as e:
            env = EnvManager.get_system_env(naive=True)
            try:
                env.path.relative_to(self.data_dir)
            except ValueError:
                raise e

            new_update_method = True

        version = self.argument("version")
        if not version:
            version = ">=" + __version__

        repo = self.pool.repositories[0]
        packages = repo.find_packages(
            Dependency("poetry",
                       version,
                       allows_prereleases=self.option("preview")))
        if not packages:
            self.line("No release found for the specified version")
            return

        packages.sort(key=cmp_to_key(lambda x, y: 0 if x.version == y.version
                                     else int(x.version < y.version or -1)))

        release = None
        for package in packages:
            if package.is_prerelease():
                if self.option("preview"):
                    release = package

                    break

                continue

            release = package

            break

        if release is None:
            self.line("No new release found")
            return

        if release.version == Version.parse(__version__):
            self.line("You are using the latest version")
            return

        if new_update_method:
            return self.update_with_new_method(release.version)

        self.update(release)
예제 #11
0
def test_with_constraint():
    dependency = Dependency(
        "foo",
        "^1.2.3",
        optional=True,
        category="dev",
        allows_prereleases=True,
        extras=["bar", "baz"],
    )
    dependency.marker = parse_marker(
        'python_version >= "3.6" and python_version < "4.0"')
    dependency.transitive_marker = parse_marker(
        'python_version >= "3.7" and python_version < "4.0"')
    dependency.python_versions = "^3.6"
    dependency.transitive_python_versions = "^3.7"

    new = dependency.with_constraint("^1.2.6")

    assert new.name == dependency.name
    assert str(new.constraint) == ">=1.2.6,<2.0.0"
    assert new.is_optional()
    assert new.category == "dev"
    assert new.allows_prereleases()
    assert set(new.extras) == {"bar", "baz"}
    assert new.marker == dependency.marker
    assert new.transitive_marker == dependency.transitive_marker
    assert new.python_constraint == dependency.python_constraint
    assert new.transitive_python_constraint == dependency.transitive_python_constraint
예제 #12
0
    def find_best_candidate(
        self,
        package_name,  # type: str
        target_package_version=None,  # type:  Union[str, None]
        allow_prereleases=False,  # type: bool
        source=None,  # type: str
    ):  # type: (...) -> Union[Package, bool]
        """
        Given a package name and optional version,
        returns the latest Package that matches
        """
        if target_package_version:
            constraint = parse_constraint(target_package_version)
        else:
            constraint = parse_constraint("*")

        candidates = self._pool.find_packages(
            package_name, constraint, allow_prereleases=True, repository=source
        )
        only_prereleases = all([c.version.is_prerelease() for c in candidates])

        if not candidates:
            return False

        dependency = Dependency(package_name, constraint)

        package = None
        for candidate in candidates:
            if (
                candidate.is_prerelease()
                and not dependency.allows_prereleases()
                and not allow_prereleases
                and not only_prereleases
            ):
                continue

            # Select highest version of the two
            if package is None or package.version < candidate.version:
                package = candidate

        if package is None:
            return False
        return package
예제 #13
0
def test_get_package_information_chooses_correct_distribution():
    repo = MockRepository()

    package = repo.package("isort", "4.3.4")

    assert package.name == "isort"
    assert package.version.text == "4.3.4"

    assert package.requires == [Dependency("futures", "*")]
    futures_dep = package.requires[0]
    assert futures_dep.python_versions == "~2.7"
예제 #14
0
    def _get_locked(self, dependency: Dependency) -> Optional[Package]:
        if dependency.name in self._use_latest:
            return

        locked = self._locked.get(dependency.name)
        if not locked:
            return

        if not dependency.is_same_package_as(locked):
            return

        return locked
예제 #15
0
파일: helpers.py 프로젝트: yosmoc/poetry
def get_dependency(name,
                   constraint=None,
                   category="main",
                   optional=False,
                   allows_prereleases=False):
    return Dependency(
        name,
        constraint or "*",
        category=category,
        optional=optional,
        allows_prereleases=allows_prereleases,
    )
예제 #16
0
def test_to_pep_508_combination():
    dependency = Dependency("foo", "^1.2,!=1.3.5")

    assert "foo (>=1.2,<2.0,!=1.3.5)" == dependency.to_pep_508()

    dependency = Dependency("foo", "~1.2,!=1.2.5")

    assert "foo (>=1.2,<1.3,!=1.2.5)" == dependency.to_pep_508()
예제 #17
0
def test_fallback_can_read_setup_to_get_dependencies():
    repo = MockRepository(fallback=True)

    package = repo.package("sqlalchemy", "1.2.12")

    assert package.name == "sqlalchemy"
    assert len(package.requires) == 0

    assert package.extras == {
        "mssql_pymssql": [Dependency("pymssql", "*")],
        "mssql_pyodbc": [Dependency("pyodbc", "*")],
        "mysql": [Dependency("mysqlclient", "*")],
        "oracle": [Dependency("cx_oracle", "*")],
        "postgresql": [Dependency("psycopg2", "*")],
        "postgresql_pg8000": [Dependency("pg8000", "*")],
        "postgresql_psycopg2binary": [Dependency("psycopg2-binary", "*")],
        "postgresql_psycopg2cffi": [Dependency("psycopg2cffi", "*")],
        "pymysql": [Dependency("pymysql", "*")],
    }
예제 #18
0
    def handle(self):  # type: () -> None
        from poetry.__version__ import __version__
        from poetry.core.semver import Version
        from poetry.repositories.pypi_repository import PyPiRepository

        self._check_recommended_installation()

        version = self.argument("version")
        if not version:
            version = ">=" + __version__

        repo = PyPiRepository(fallback=False)
        packages = repo.find_packages(
            Dependency("poetry", version, allows_prereleases=self.option("preview"))
        )
        if not packages:
            self.line("No release found for the specified version")
            return

        packages.sort(
            key=cmp_to_key(
                lambda x, y: 0
                if x.version == y.version
                else int(x.version < y.version or -1)
            )
        )

        release = None
        for package in packages:
            if package.is_prerelease():
                if self.option("preview"):
                    release = package

                    break

                continue

            release = package

            break

        if release is None:
            self.line("No new release found")
            return

        if release.version == Version.parse(__version__):
            self.line("You are using the latest version")
            return

        self.update(release)
예제 #19
0
def test_to_pep_508():
    dependency = Dependency("Django", "^1.23")

    result = dependency.to_pep_508()
    assert result == "Django (>=1.23,<2.0)"

    dependency = Dependency("Django", "^1.23")
    dependency.python_versions = "~2.7 || ^3.6"

    result = dependency.to_pep_508()
    assert (result == "Django (>=1.23,<2.0); "
            'python_version >= "2.7" and python_version < "2.8" '
            'or python_version >= "3.6" and python_version < "4.0"')
예제 #20
0
def get_dependency(dep: src_parser.Dependency) -> Dependency:
    # FIXME: how do deal with extras?
    extras: List[str] = []
    if isinstance(dep, src_parser.VersionedDependency):
        return Dependency(name=dep.name,
                          constraint=dep.version or "*",
                          extras=dep.extras)
    elif isinstance(dep, src_parser.URLDependency):
        return URLDependency(
            name=dep.name,
            url=f"{dep.url}#{dep.hashes[0].replace(':','=')}",
            extras=extras,
        )
    else:
        raise ValueError(f"Unknown requirement {dep}")
예제 #21
0
def test_get_package_information_fallback_read_setup():
    repo = MockRepository()

    package = repo.package("jupyter", "1.0.0")

    assert package.source_type == "legacy"
    assert package.source_reference == repo.name
    assert package.source_url == repo.url
    assert package.name == "jupyter"
    assert package.version.text == "1.0.0"
    assert (
        package.description ==
        "Jupyter metapackage. Install all the Jupyter components in one go.")

    if PY35:
        assert package.requires == [
            Dependency("notebook", "*"),
            Dependency("qtconsole", "*"),
            Dependency("jupyter-console", "*"),
            Dependency("nbconvert", "*"),
            Dependency("ipykernel", "*"),
            Dependency("ipywidgets", "*"),
        ]
예제 #22
0
    def find_packages(self, dependency: Dependency) -> List[Package]:
        """
        Find packages on the remote server.
        """
        constraint = dependency.constraint
        if constraint is None:
            constraint = "*"

        if not isinstance(constraint, VersionConstraint):
            constraint = parse_constraint(constraint)

        allow_prereleases = dependency.allows_prereleases()
        if isinstance(constraint, VersionRange):
            if (constraint.max is not None and constraint.max.is_prerelease()
                    or constraint.min is not None
                    and constraint.min.is_prerelease()):
                allow_prereleases = True

        try:
            info = self.get_package_info(dependency.name)
        except PackageNotFound:
            self._log(
                "No packages found for {} {}".format(dependency.name,
                                                     str(constraint)),
                level="debug",
            )
            return []

        packages = []
        ignored_pre_release_packages = []

        for version, release in info["releases"].items():
            if not release:
                # Bad release
                self._log(
                    "No release information found for {}-{}, skipping".format(
                        dependency.name, version),
                    level="debug",
                )
                continue

            try:
                package = Package(info["info"]["name"], version)
            except ParseVersionError:
                self._log(
                    'Unable to parse version "{}" for the {} package, skipping'
                    .format(version, dependency.name),
                    level="debug",
                )
                continue

            if package.is_prerelease() and not allow_prereleases:
                if constraint.is_any():
                    # we need this when all versions of the package are pre-releases
                    ignored_pre_release_packages.append(package)
                continue

            if not constraint or (constraint
                                  and constraint.allows(package.version)):
                packages.append(package)

        self._log(
            "{} packages found for {} {}".format(len(packages),
                                                 dependency.name,
                                                 str(constraint)),
            level="debug",
        )

        return packages or ignored_pre_release_packages
예제 #23
0
def test_accepts_fails_with_version_mismatch():
    dependency = Dependency("A", "~1.0")
    package = Package("B", "1.4")

    assert not dependency.accepts(package)
예제 #24
0
def test_pypi_repository_supports_reading_bz2_files():
    repo = MockRepository(fallback=True)

    package = repo.package("twisted", "18.9.0")

    assert package.name == "twisted"
    assert sorted(package.requires, key=lambda r: r.name) == [
        Dependency("attrs", ">=17.4.0"),
        Dependency("Automat", ">=0.3.0"),
        Dependency("constantly", ">=15.1"),
        Dependency("hyperlink", ">=17.1.1"),
        Dependency("incremental", ">=16.10.1"),
        Dependency("PyHamcrest", ">=1.9.0"),
        Dependency("zope.interface", ">=4.4.2"),
    ]

    expected_extras = {
        "all_non_platform": [
            Dependency("appdirs", ">=1.4.0"),
            Dependency("cryptography", ">=1.5"),
            Dependency("h2", ">=3.0,<4.0"),
            Dependency("idna", ">=0.6,!=2.3"),
            Dependency("priority", ">=1.1.0,<2.0"),
            Dependency("pyasn1", "*"),
            Dependency("pyopenssl", ">=16.0.0"),
            Dependency("pyserial", ">=3.0"),
            Dependency("service_identity", "*"),
            Dependency("soappy", "*"),
        ]
    }

    for name, deps in expected_extras.items():
        assert expected_extras[name] == sorted(package.extras[name],
                                               key=lambda r: r.name)
예제 #25
0
def test_accepts_fails_with_prerelease_mismatch():
    dependency = Dependency("A", "^1.0")
    package = Package("B", "1.4-beta.1")

    assert not dependency.accepts(package)
예제 #26
0
def test_get_package_information_skips_dependencies_with_invalid_constraints():
    repo = MockRepository()

    package = repo.package("python-language-server", "0.21.2")

    assert package.name == "python-language-server"
    assert package.version.text == "0.21.2"
    assert (
        package.description == "Python Language Server for the Language Server Protocol"
    )

    assert 25 == len(package.requires)
    assert sorted(
        [r for r in package.requires if not r.is_optional()], key=lambda r: r.name
    ) == [
        Dependency("configparser", "*"),
        Dependency("future", ">=0.14.0"),
        Dependency("futures", "*"),
        Dependency("jedi", ">=0.12"),
        Dependency("pluggy", "*"),
        Dependency("python-jsonrpc-server", "*"),
    ]

    all_extra = package.extras["all"]

    # rope>-0.10.5 should be discarded
    assert sorted(all_extra, key=lambda r: r.name) == [
        Dependency("autopep8", "*"),
        Dependency("mccabe", "*"),
        Dependency("pycodestyle", "*"),
        Dependency("pydocstyle", ">=2.0.0"),
        Dependency("pyflakes", ">=1.6.0"),
        Dependency("yapf", "*"),
    ]
예제 #27
0
def test_get_package_with_dist_and_universal_py3_wheel():
    repo = MockRepository()

    package = repo.package("ipython", "7.5.0")

    assert "ipython" == package.name
    assert "7.5.0" == package.version.text
    assert ">=3.5" == package.python_versions

    expected = [
        Dependency("appnope", "*"),
        Dependency("backcall", "*"),
        Dependency("colorama", "*"),
        Dependency("decorator", "*"),
        Dependency("jedi", ">=0.10"),
        Dependency("pexpect", "*"),
        Dependency("pickleshare", "*"),
        Dependency("prompt-toolkit", ">=2.0.0,<2.1.0"),
        Dependency("pygments", "*"),
        Dependency("setuptools", ">=18.5"),
        Dependency("traitlets", ">=4.2"),
        Dependency("typing", "*"),
        Dependency("win-unicode-console", ">=0.5"),
    ]
    required = [r for r in package.requires if not r.is_optional()]
    assert expected == sorted(required, key=lambda dep: dep.name)
예제 #28
0
def test_get_package_from_both_py2_and_py3_specific_wheels():
    repo = MockRepository()

    package = repo.package("ipython", "5.7.0")

    assert "ipython" == package.name
    assert "5.7.0" == package.version.text
    assert "*" == package.python_versions
    assert 41 == len(package.requires)

    expected = [
        Dependency("appnope", "*"),
        Dependency("backports.shutil-get-terminal-size", "*"),
        Dependency("colorama", "*"),
        Dependency("decorator", "*"),
        Dependency("pathlib2", "*"),
        Dependency("pexpect", "*"),
        Dependency("pickleshare", "*"),
        Dependency("prompt-toolkit", ">=1.0.4,<2.0.0"),
        Dependency("pygments", "*"),
        Dependency("setuptools", ">=18.5"),
        Dependency("simplegeneric", ">0.8"),
        Dependency("traitlets", ">=4.2"),
        Dependency("win-unicode-console", ">=0.5"),
    ]
    required = [r for r in package.requires if not r.is_optional()]
    assert expected == required

    assert 'python_version == "2.7"' == str(required[1].marker)
    assert 'sys_platform == "win32" and python_version < "3.6"' == str(
        required[12].marker
    )
    assert 'python_version == "2.7" or python_version == "3.3"' == str(
        required[4].marker
    )
    assert 'sys_platform != "win32"' == str(required[5].marker)
예제 #29
0
def test_accepts():
    dependency = Dependency("A", "^1.0")
    package = Package("A", "1.4")

    assert dependency.accepts(package)
예제 #30
0
def test_to_pep_508_wilcard():
    dependency = Dependency("Django", "*")

    result = dependency.to_pep_508()
    assert result == "Django"